Here are the steps for another inherent bug (fixed):
- record midi cc, for example 7
- open in matrix (or notation) editor
- horizontal zoom
- add the control ruler for the recorded cc (the events are moved)
The attached patch fixes all the discovered bugs with control rulers.
The tricky method is EventControlItem::updateFromEvent() because some
events have x-values not scaled during that call (i.e. events from
midi recording). It is necessary to rescale the x-values within
updateFromEvent(), therefore the start/end points for addControlLine()
are initially adapted to hzoom. The walk for addControlItem() is
different (sic).
Note: setViewSegment(segment) is moved from the constructor for
ControllerEventsRuler to the end of ControlRulerWidget::slotAddControlRuler()
because pannedRect (and consequently m_xScaler) is updated during
ControlRulerWidget::addRuler(). slotAddControlRuler() is the only to
use that constructor.
Note: `getXMax() - 1' instead of `getXMax()' otherwise the event at
the last useful position is visible but doesn't play. The alternative
is to put -1 inside getXMax().
Now we can add and/or move control items and control-lines without
problems after horizontal zoom. Recorded midi cc are correct after
hzoom. Besides, it is impossible to add control items outside the
related segment.
Index: src/gui/rulers/ControlMover.cpp
===================================================================
--- src/gui/rulers/ControlMover.cpp (revision 14088)
+++ src/gui/rulers/ControlMover.cpp (working copy)
@@ -111,8 +111,10 @@
float deltaX = (e->x-m_mouseStartX);
float deltaY = (e->y-m_mouseStartY);
- float dScreenX = deltaX/m_ruler->getXScale();
- float dScreenY = deltaY/m_ruler->getYScale();
+ double xscale = m_ruler->getXScale();
+ double yscale = m_ruler->getYScale();
+ float dScreenX = deltaX / xscale;
+ float dScreenY = deltaY / yscale;
if (e->modifiers & Qt::ControlModifier) {
// If the control key is held down, restrict movement to either
horizontal or vertical
@@ -143,8 +145,10 @@
item = dynamic_cast <EventControlItem*> (*it);
float x = pIt->x()+deltaX;
- x = std::max(x,m_ruler->getXMin());
- x = std::min(x,m_ruler->getXMax());
+ float xmin = m_ruler->getXMin() * xscale;
+ float xmax = (m_ruler->getXMax() - 1) * xscale;
+ x = std::max(x,xmin);
+ x = std::min(x,xmax);
float y = pIt->y()+deltaY;
y = std::max(y,0.0f);
Index: src/gui/rulers/ControlPainter.cpp
===================================================================
--- src/gui/rulers/ControlPainter.cpp (revision 14088)
+++ src/gui/rulers/ControlPainter.cpp (working copy)
@@ -72,7 +72,17 @@
ControllerEventsRuler* ruler = dynamic_cast
<ControllerEventsRuler*>(m_ruler);
//if (ruler) ruler->insertControllerEvent(e->x,e->y);
if (ruler) {
+ double xscale = m_ruler->getXScale();
+ float xmin = m_ruler->getXMin() * xscale;
+ float xmax = (m_ruler->getXMax() - 1) * xscale;
+ float x = e->x;
+ if (x < xmin) {
+ x = xmin;
+ } else if (x > xmax) {
+ x = xmax;
+ }
+
// If shift was pressed, draw a line of controllers between the new
// control event and the previous one
if (e->modifiers & Qt::ShiftModifier) {
@@ -82,15 +92,15 @@
// if no origin point was set, do not draw a line
if (m_controlLineOrigin.first != -1 &&
m_controlLineOrigin.second != -1) {
- ruler->addControlLine(m_controlLineOrigin.first,
+ ruler->addControlLine(m_controlLineOrigin.first / xscale,
m_controlLineOrigin.second,
- e->x,
+ x / xscale,
e->y,
eraseExistingControllers);
}
} else {
- ControlItem *item = ruler->addControlItem(e->x,e->y);
+ ControlItem *item = ruler->addControlItem(x,e->y);
ControlMouseEvent *newevent = new ControlMouseEvent(e);
newevent->itemList.push_back(item);
m_overItem = true;
@@ -98,7 +108,7 @@
}
// Save these coordinates for next time
- m_controlLineOrigin.first = e->x;
+ m_controlLineOrigin.first = x;
m_controlLineOrigin.second = e->y;
}
}
Index: src/gui/rulers/ControlRuler.cpp
===================================================================
--- src/gui/rulers/ControlRuler.cpp (revision 14088)
+++ src/gui/rulers/ControlRuler.cpp (working copy)
@@ -82,8 +82,8 @@
m_nextItemLeft(m_controlItemMap.end()),
m_currentIndex(0),
m_currentTool(0),
- m_xScale(0),
- m_yScale(0),
+ m_xScale(1.0),
+ m_yScale(1.0),
m_maxItemValue(127),
m_minItemValue(0),
m_viewSegmentOffset(0),
Index: src/gui/rulers/ControlRulerWidget.cpp
===================================================================
--- src/gui/rulers/ControlRulerWidget.cpp (revision 14088)
+++ src/gui/rulers/ControlRulerWidget.cpp (working copy)
@@ -306,6 +306,7 @@
this, SLOT(slotChildRulerSelectionChanged(EventSelection *)));
addRuler(controlruler,QString::fromStdString(controlParameter.getName()));
+ controlruler->setViewSegment(m_viewSegment);
}
void
Index: src/gui/rulers/ControllerEventsRuler.cpp
===================================================================
--- src/gui/rulers/ControllerEventsRuler.cpp (revision 14088)
+++ src/gui/rulers/ControllerEventsRuler.cpp (working copy)
@@ -79,9 +79,6 @@
m_controller = 0;
}
- // This is necessary to run the overloaded method, the base method has
already run
- setViewSegment(segment);
-
setMenuName("controller_events_ruler_menu");
// drawBackground(); Now in paintEvent
// init();
Index: src/gui/rulers/EventControlItem.cpp
===================================================================
--- src/gui/rulers/EventControlItem.cpp (revision 14088)
+++ src/gui/rulers/EventControlItem.cpp (working copy)
@@ -57,8 +57,9 @@
long value = 0;
m_eventAdapter->getValue(value);
-
reconfigure(m_controlRuler->getRulerScale()->getXForTime(m_eventAdapter->getTime()),
- m_controlRuler->valueToY(value));
+ double xscale = m_controlRuler->getXScale();
+
reconfigure(m_controlRuler->getRulerScale()->getXForTime(m_eventAdapter->getTime())*xscale,
+ m_controlRuler->valueToY(value));
}
void EventControlItem::setY(float y)
------------------------------------------------------------------------------
_______________________________________________
Rosegarden-devel mailing list
[email protected] - use the link below to unsubscribe
https://lists.sourceforge.net/lists/listinfo/rosegarden-devel