summaryrefslogtreecommitdiff
path: root/attic/muse2-oom/muse2/muse/widgets/canvas.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'attic/muse2-oom/muse2/muse/widgets/canvas.cpp')
-rw-r--r--attic/muse2-oom/muse2/muse/widgets/canvas.cpp1463
1 files changed, 1463 insertions, 0 deletions
diff --git a/attic/muse2-oom/muse2/muse/widgets/canvas.cpp b/attic/muse2-oom/muse2/muse/widgets/canvas.cpp
new file mode 100644
index 00000000..4ea5f568
--- /dev/null
+++ b/attic/muse2-oom/muse2/muse/widgets/canvas.cpp
@@ -0,0 +1,1463 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: canvas.cpp,v 1.10.2.17 2009/05/03 04:14:01 terminator356 Exp $
+// (C) Copyright 1999 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#include <stdio.h>
+
+#include "canvas.h"
+
+#include <QApplication>
+#include <QMenu>
+#include <QPainter>
+#include <QCursor>
+#include <QTimer>
+#include <QKeyEvent>
+#include <QMouseEvent>
+#include <QWheelEvent>
+
+#include "song.h"
+#include "event.h"
+#include "citem.h"
+#include "icons.h"
+#include "../marker/marker.h"
+#include "part.h"
+
+#define ABS(x) ((x) < 0) ? -(x) : (x)
+
+//---------------------------------------------------------
+// Canvas
+//---------------------------------------------------------
+
+Canvas::Canvas(QWidget* parent, int sx, int sy, const char* name)
+ : View(parent, sx, sy, name)
+ {
+ canvasTools = 0;
+ itemPopupMenu = 0;
+
+ button = Qt::NoButton;
+ keyState = 0;
+
+ canScrollLeft = true;
+ canScrollRight = true;
+ canScrollUp = true;
+ canScrollDown = true;
+ hscrollDir = HSCROLL_NONE;
+ vscrollDir = VSCROLL_NONE;
+ scrollTimer=NULL;
+
+ scrollSpeed=10; // hardcoded scroll jump
+
+ drag = DRAG_OFF;
+ _tool = PointerTool;
+ pos[0] = song->cpos();
+ pos[1] = song->lpos();
+ pos[2] = song->rpos();
+ curPart = NULL;
+ curPartId = -1;
+ curItem = NULL;
+ connect(song, SIGNAL(posChanged(int, unsigned, bool)), this, SLOT(setPos(int, unsigned, bool)));
+ }
+
+//---------------------------------------------------------
+// setPos
+// set one of three markers
+// idx - 0-cpos 1-lpos 2-rpos
+// flag - emit followEvent()
+//---------------------------------------------------------
+
+void Canvas::setPos(int idx, unsigned val, bool adjustScrollbar)
+ {
+ //if (pos[idx] == val) // Seems to be some refresh problems here, pos[idx] might be val but the gui not updated.
+ // return; // skipping this return forces update even if values match. Matching values only seem
+ // to occur when initializing
+ int opos = mapx(pos[idx]);
+ int npos = mapx(val);
+
+ if (adjustScrollbar && idx == 0) {
+ switch (song->follow()) {
+ case Song::NO:
+ break;
+ case Song::JUMP:
+ if (npos >= width()) {
+ int ppos = val - xorg - rmapxDev(width()/8);
+ if (ppos < 0)
+ ppos = 0;
+ emit followEvent(ppos);
+ opos = mapx(pos[idx]);
+ npos = mapx(val);
+ }
+ else if (npos < 0) {
+ int ppos = val - xorg - rmapxDev(width()*3/4);
+ if (ppos < 0)
+ ppos = 0;
+ emit followEvent(ppos);
+ opos = mapx(pos[idx]);
+ npos = mapx(val);
+ }
+ break;
+ case Song::CONTINUOUS:
+ if (npos > (width()/2)) {
+ int ppos = pos[idx] - xorg - rmapxDev(width()/2);
+ if (ppos < 0)
+ ppos = 0;
+ emit followEvent(ppos);
+ opos = mapx(pos[idx]);
+ npos = mapx(val);
+ }
+ else if (npos < (width()/2)) {
+ int ppos = pos[idx] - xorg - rmapxDev(width()/2);
+ if (ppos < 0)
+ ppos = 0;
+ emit followEvent(ppos);
+ opos = mapx(pos[idx]);
+ npos = mapx(val);
+ }
+ break;
+ }
+ }
+
+ int x;
+ int w = 1;
+ if (opos > npos) {
+ w += opos - npos;
+ x = npos;
+ }
+ else {
+ w += npos - opos;
+ x = opos;
+ }
+ pos[idx] = val;
+ redraw(QRect(x-1, 0, w+2, height()));
+ }
+
+//---------------------------------------------------------
+// draw
+//---------------------------------------------------------
+
+void Canvas::draw(QPainter& p, const QRect& rect)
+{
+// printf("draw canvas %x virt %d\n", this, virt());
+
+ int x = rect.x();
+ int y = rect.y();
+ int w = rect.width();
+ int h = rect.height();
+ int x2 = x + w;
+
+ if (virt()) {
+ drawCanvas(p, rect);
+
+ //---------------------------------------------------
+ // draw Canvas Items
+ //---------------------------------------------------
+
+ iCItem to(items.lower_bound(x2));
+
+ // Draw items from other parts behind all others.
+ // Only for items with events (not arranger parts).
+ for(iCItem i = items.begin(); i != to; ++i)
+ {
+ CItem* ci = i->second;
+ if(!ci->event().empty() && ci->part() != curPart)
+ {
+ drawItem(p, ci, rect);
+ }
+ }
+
+ for (iCItem i = items.begin(); i != to; ++i)
+ {
+ CItem* ci = i->second;
+ // Draw unselected parts behind selected.
+ if(!ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart))
+ {
+ drawItem(p, ci, rect);
+ }
+ }
+
+ // Draw selected parts in front of unselected.
+ for (iCItem i = items.begin(); i != to; ++i)
+ {
+ CItem* ci = i->second;
+ if(ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart))
+ {
+ drawItem(p, ci, rect);
+ }
+ }
+ to = moving.lower_bound(x2);
+ for (iCItem i = moving.begin(); i != to; ++i)
+ {
+ drawItem(p, i->second, rect);
+ }
+ }
+ else {
+ p.save();
+ setPainter(p);
+
+ if (xmag <= 0) {
+ x -= 1;
+ w += 2;
+ x = (x + xpos + rmapx(xorg)) * (-xmag);
+ w = w * (-xmag);
+ }
+ else {
+ x = (x + xpos + rmapx(xorg)) / xmag;
+ w = (w + xmag - 1) / xmag;
+ x -= 1;
+ w += 2;
+ }
+ if (ymag <= 0) {
+ y -= 1;
+ h += 2;
+ y = (y + ypos + rmapy(yorg)) * (-ymag);
+ h = h * (-ymag);
+ }
+ else {
+ y = (rect.y() + ypos + rmapy(yorg))/ymag;
+ h = (rect.height()+ymag-1)/ymag;
+ y -= 1;
+ h += 2;
+ }
+
+ if (x < 0)
+ x = 0;
+ if (y < 0)
+ y = 0;
+ x2 = x + w;
+
+ drawCanvas(p, QRect(x, y, w, h));
+ p.restore();
+
+ //---------------------------------------------------
+ // draw Canvas Items
+ //---------------------------------------------------
+
+ // Draw items from other parts behind all others.
+ // Only for items with events (not arranger parts).
+ for(iCItem i = items.begin(); i != items.end(); ++i)
+ {
+ CItem* ci = i->second;
+ if(!ci->event().empty() && ci->part() != curPart)
+ {
+ drawItem(p, ci, rect);
+ }
+ }
+
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ CItem* ci = i->second;
+ // Draw unselected parts behind selected.
+ if(!ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart))
+ {
+ drawItem(p, ci, rect);
+ }
+ }
+
+ // Draw selected parts in front of unselected.
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ CItem* ci = i->second;
+ if(ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart))
+ {
+ drawItem(p, ci, rect);
+ }
+ }
+ for (iCItem i = moving.begin(); i != moving.end(); ++i)
+ {
+ drawItem(p, i->second, rect);
+ }
+ p.save();
+ setPainter(p);
+ }
+
+ //---------------------------------------------------
+ // draw marker
+ //---------------------------------------------------
+
+ int y2 = y + h;
+ MarkerList* marker = song->marker();
+ for (iMarker m = marker->begin(); m != marker->end(); ++m) {
+ int xp = m->second.tick();
+ if (xp >= x && xp < x+w) {
+ p.setPen(Qt::green);
+ p.drawLine(xp, y, xp, y2);
+ }
+ }
+
+ // //---------------------------------------------------
+ // // draw location marker
+ // //---------------------------------------------------
+
+ // p.setPen(Qt::blue);
+ // if (pos[1] >= unsigned(x) && pos[1] < unsigned(x2))
+ // {
+ // p.drawLine(pos[1], y, pos[1], y2);
+ // }
+ // if (pos[2] >= unsigned(x) && pos[2] < unsigned(x2))
+ // p.drawLine(pos[2], y, pos[2], y2);
+ //
+ // QPen playbackPen(QColor(51,56,55), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
+ // p.setPen(playbackPen);
+ // //p.setPen(Qt::red);
+
+ // if (pos[0] >= unsigned(x) && pos[0] < unsigned(x2))
+ // {
+ // p.drawLine(pos[0], y, pos[0], y2);
+ // }
+ //
+
+ //---------------------------------------------------
+ // draw lasso
+ //---------------------------------------------------
+
+ if (drag == DRAG_LASSO)
+ {
+ p.setPen(QColor(181,109,16));
+ p.setBrush(Qt::NoBrush);
+ p.drawRect(lasso);
+ }
+
+ //---------------------------------------------------
+ // draw moving items
+ //---------------------------------------------------
+
+ if(virt())
+ {
+ for(iCItem i = moving.begin(); i != moving.end(); ++i)
+ drawMoving(p, i->second, rect);
+ }
+ else
+ {
+ p.restore();
+ for(iCItem i = moving.begin(); i != moving.end(); ++i)
+ drawMoving(p, i->second, rect);
+ setPainter(p);
+ }
+ //---------------------------------------------------
+ // draw location marker
+ //---------------------------------------------------
+
+ //p.setPen(Qt::blue);
+ p.setPen(QColor(139,225,69));
+ if (pos[1] >= unsigned(x) && pos[1] < unsigned(x2))
+ {
+ p.drawLine(pos[1], y, pos[1], y2);
+ }
+ if (pos[2] >= unsigned(x) && pos[2] < unsigned(x2))
+ p.drawLine(pos[2], y, pos[2], y2);
+
+ //QPen playbackPen(QColor(8,193,156), 1);
+ //p.setPen(playbackPen);
+ //p.setPen(Qt::green);
+ p.setPen(QColor(0,186,255));
+
+ if (pos[0] >= unsigned(x) && pos[0] < unsigned(x2))
+ {
+ p.drawLine(pos[0], y, pos[0], y2);
+ }
+
+}
+
+#define WHEEL_STEPSIZE 40
+#define WHEEL_DELTA 120
+
+//---------------------------------------------------------
+// wheelEvent
+//---------------------------------------------------------
+void Canvas::wheelEvent(QWheelEvent* ev)
+ {
+ int delta = ev->delta() / WHEEL_DELTA;
+ int ypixelscale = rmapyDev(1);
+
+ if (ypixelscale <= 0)
+ ypixelscale = 1;
+
+ int scrollstep = WHEEL_STEPSIZE * (-delta);
+ ///if (ev->state() == Qt::ShiftModifier)
+ if (((QInputEvent*)ev)->modifiers() == Qt::ShiftModifier)
+ scrollstep = scrollstep / 10;
+
+ int newYpos = ypos + ypixelscale * scrollstep;
+
+ if (newYpos < 0)
+ newYpos = 0;
+
+ //setYPos(newYpos);
+ emit verticalScroll((unsigned)newYpos);
+
+}
+
+void Canvas::redirectedWheelEvent(QWheelEvent* ev)
+{
+ wheelEvent(ev);
+}
+
+//---------------------------------------------------------
+// deselectAll
+//---------------------------------------------------------
+
+void Canvas::deselectAll()
+{
+ for (iCItem i = items.begin(); i != items.end(); ++i)
+ i->second->setSelected(false);
+}
+
+//---------------------------------------------------------
+// selectItem
+//---------------------------------------------------------
+
+void Canvas::selectItem(CItem* e, bool flag)
+{
+ e->setSelected(flag);
+}
+
+//---------------------------------------------------------
+// startMoving
+// copy selection-List to moving-List
+//---------------------------------------------------------
+
+void Canvas::startMoving(const QPoint& pos, DragType)
+{
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ if (i->second->isSelected()) {
+ i->second->setMoving(true);
+ moving.add(i->second);
+ }
+ }
+ moveItems(pos, 0);
+}
+
+//---------------------------------------------------------
+// moveItems
+// dir = 0 move in all directions
+// 1 move only horizontal
+// 2 move only vertical
+//---------------------------------------------------------
+
+void Canvas::moveItems(const QPoint& pos, int dir = 0, bool rasterize)
+{
+ int dp;
+ if(rasterize)
+ dp = y2pitch(pos.y()) - y2pitch(start.y());
+ else
+ dp = pos.y() - start.y();
+ int dx = pos.x() - start.x();
+ if (dir == 1)
+ dp = 0;
+ else if (dir == 2)
+ dx = 0;
+ for (iCItem i = moving.begin(); i != moving.end(); ++i) {
+ int x = i->second->pos().x();
+ int y = i->second->pos().y();
+ int nx = x + dx;
+ int ny;
+ QPoint mp;
+ if(rasterize)
+ {
+ ny = pitch2y(y2pitch(y) + dp);
+ mp = raster(QPoint(nx, ny));
+ }
+ else
+ {
+ ny = y + dp;
+ mp = QPoint(nx, ny);
+ }
+ if (i->second->mp() != mp)
+ {
+ i->second->setMp(mp);
+ itemMoved(i->second, mp);
+ }
+ }
+ redraw();
+}
+
+//---------------------------------------------------------
+// viewKeyPressEvent
+//---------------------------------------------------------
+
+void Canvas::viewKeyPressEvent(QKeyEvent* event)
+ {
+ keyPress(event);
+ }
+
+//---------------------------------------------------------
+// viewMousePressEvent
+//---------------------------------------------------------
+
+void Canvas::viewMousePressEvent(QMouseEvent* event)
+ {
+ ///keyState = event->state();
+ keyState = ((QInputEvent*)event)->modifiers();
+ button = event->button();
+
+ //printf("viewMousePressEvent buttons:%x mods:%x button:%x\n", (int)event->buttons(), (int)keyState, event->button());
+
+ // special events if right button is clicked while operations
+ // like moving or drawing lasso is performed.
+ ///if (event->stateAfter() & Qt::RightButton) {
+ if (event->buttons() & Qt::RightButton & ~(event->button())) {
+ //printf("viewMousePressEvent special buttons:%x mods:%x button:%x\n", (int)event->buttons(), (int)keyState, event->button());
+ switch (drag) {
+ case DRAG_LASSO:
+ drag = DRAG_OFF;
+ redraw();
+ return;
+ case DRAG_MOVE:
+ drag = DRAG_OFF;
+ endMoveItems (start, MOVE_MOVE, 0);
+ return;
+ default:
+ break;
+ }
+ }
+
+ // ignore event if (another) button is already active:
+ ///if (keyState & (Qt::LeftButton|Qt::RightButton|Qt::MidButton)) {
+ if (event->buttons() & (Qt::LeftButton|Qt::RightButton|Qt::MidButton) & ~(event->button())) {
+ //printf("viewMousePressEvent ignoring buttons:%x mods:%x button:%x\n", (int)event->buttons(), (int)keyState, event->button());
+ return;
+ }
+ bool shift = keyState & Qt::ShiftModifier;
+ bool alt = keyState & Qt::AltModifier;
+ bool ctrl = keyState & Qt::ControlModifier;
+ start = event->pos();
+
+ //---------------------------------------------------
+ // set curItem to item mouse is pointing
+ // (if any)
+ //---------------------------------------------------
+
+ if (virt())
+ curItem = items.find(start);
+ else {
+ curItem = 0;
+ iCItem ius;
+ bool usfound = false;
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ QRect box = i->second->bbox();
+ int x = rmapxDev(box.x());
+ int y = rmapyDev(box.y());
+ int w = rmapxDev(box.width());
+ int h = rmapyDev(box.height());
+ QRect r(x, y, w, h);
+ ///r.moveBy(i->second->pos().x(), i->second->pos().y());
+ r.translate(i->second->pos().x(), i->second->pos().y());
+ if (r.contains(start)) {
+ if(i->second->isSelected())
+ {
+ curItem = i->second;
+ break;
+ }
+ else
+ if(!usfound)
+ {
+ ius = i;
+ usfound = true;
+ }
+ }
+ }
+ if(!curItem && usfound)
+ curItem = ius->second;
+ }
+
+ if (curItem && (event->button() == Qt::MidButton)) {
+ if (!curItem->isSelected()) {
+ selectItem(curItem, true);
+ updateSelection();
+ redraw();
+ }
+ startDrag(curItem, shift);
+ }
+ else if (event->button() == Qt::RightButton) {
+ if (curItem) {
+ if (shift) {
+ drag = DRAG_RESIZE;
+ setCursor();
+ int dx = start.x() - curItem->x();
+ curItem->setWidth(dx);
+ start.setX(curItem->x());
+ deselectAll();
+ selectItem(curItem, true);
+ updateSelection();
+ redraw();
+ }
+ else {
+ itemPopupMenu = genItemPopup(curItem);
+ if (itemPopupMenu) {
+ QAction *act = itemPopupMenu->exec(QCursor::pos());
+ if (act)
+ itemPopup(curItem, act->data().toInt(), start);
+ delete itemPopupMenu;
+ }
+ }
+ }
+ else {
+ canvasPopupMenu = genCanvasPopup();
+ if (canvasPopupMenu) {
+ QAction *act = canvasPopupMenu->exec(QCursor::pos(), 0);
+ if (act)
+ canvasPopup(act->data().toInt());
+ delete canvasPopupMenu;
+ }
+ }
+ }
+ else if (event->button() == Qt::LeftButton) {
+ switch (_tool) {
+ case PointerTool:
+ if (curItem) {
+ if (curItem->part() != curPart) {
+ curPart = curItem->part();
+ curPartId = curPart->sn();
+ curPartChanged();
+ }
+ itemPressed(curItem);
+ // Changed by T356. Alt is default reserved for moving the whole window in KDE. Changed to Shift-Alt.
+ // Hmm, nope, shift-alt is also reserved sometimes. Must find a way to bypass,
+ // why make user turn off setting? Left alone for now...
+ if (shift)
+ drag = DRAG_COPY_START;
+ else if (alt) {
+ drag = DRAG_CLONE_START;
+ }
+ //
+ //if (shift)
+ //{
+ // if (alt)
+ // drag = DRAG_CLONE_START;
+ // else
+ // drag = DRAG_COPY_START;
+ //}
+ else if (ctrl) { //Select all on the same pitch (e.g. same y-value)
+ deselectAll();
+ //printf("Yes, ctrl and press\n");
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ if (i->second->y() == curItem->y() )
+ selectItem(i->second, true);
+ }
+ updateSelection();
+ redraw();
+ }
+ else
+ drag = DRAG_MOVE_START;
+ }
+ else
+ drag = DRAG_LASSO_START;
+ setCursor();
+ break;
+
+ case RubberTool:
+ deleteItem(start);
+ drag = DRAG_DELETE;
+ setCursor();
+ break;
+
+ case PencilTool:
+ if (curItem) {
+ drag = DRAG_RESIZE;
+ setCursor();
+ int dx = start.x() - curItem->x();
+ curItem->setWidth(dx);
+ start.setX(curItem->x());
+ }
+ else {
+ drag = DRAG_NEW;
+ setCursor();
+ curItem = newItem(start, event->modifiers());
+ if (curItem)
+ items.add(curItem);
+ else {
+ drag = DRAG_OFF;
+ setCursor();
+ }
+ }
+ deselectAll();
+ if (curItem)
+ selectItem(curItem, true);
+ updateSelection();
+ redraw();
+ break;
+
+ default:
+ break;
+ }
+ }
+ mousePress(event);
+ }
+
+void Canvas::scrollTimerDone()
+{
+ //printf("Canvas::scrollTimerDone drag:%d doScroll:%d\n", drag, doScroll);
+
+ if (drag != DRAG_OFF && doScroll)
+ {
+ //printf("Canvas::scrollTimerDone drag != DRAG_OFF && doScroll\n");
+
+ bool doHMove = false;
+ bool doVMove = false;
+ int hoff = rmapx(xOffset())+mapx(xorg)-1;
+ int curxpos;
+ switch(hscrollDir)
+ {
+ case HSCROLL_RIGHT:
+ hoff += scrollSpeed;
+ switch(drag)
+ {
+ case DRAG_NEW:
+ case DRAG_RESIZE:
+ case DRAGX_MOVE:
+ case DRAGX_COPY:
+ case DRAGX_CLONE:
+ case DRAGY_MOVE:
+ case DRAGY_COPY:
+ case DRAGY_CLONE:
+ case DRAG_MOVE:
+ case DRAG_COPY:
+ case DRAG_CLONE:
+ emit horizontalScrollNoLimit(hoff);
+ canScrollLeft = true;
+ ev_pos.setX(rmapxDev(rmapx(ev_pos.x()) + scrollSpeed));
+ doHMove = true;
+ break;
+ default:
+ if(canScrollRight)
+ {
+ curxpos = xpos;
+ emit horizontalScroll(hoff);
+ if(xpos <= curxpos)
+ {
+ canScrollRight = false;
+ }
+ else
+ {
+ canScrollLeft = true;
+ ev_pos.setX(rmapxDev(rmapx(ev_pos.x()) + scrollSpeed));
+ doHMove = true;
+ }
+ }
+ else
+ {
+ }
+ break;
+ }
+ break;
+ case HSCROLL_LEFT:
+ if(canScrollLeft)
+ {
+ curxpos = xpos;
+ hoff -= scrollSpeed;
+ emit horizontalScroll(hoff);
+ if(xpos >= curxpos)
+ {
+ canScrollLeft = false;
+ }
+ else
+ {
+ canScrollRight = true;
+ ev_pos.setX(rmapxDev(rmapx(ev_pos.x()) - scrollSpeed));
+ doHMove = true;
+ }
+ }
+ else
+ {
+ }
+ break;
+ default:
+ break;
+ }
+ int voff = rmapy(yOffset())+mapy(yorg);
+ int curypos;
+ switch(vscrollDir)
+ {
+ case VSCROLL_DOWN:
+ if(canScrollDown)
+ {
+ curypos = ypos;
+ voff += scrollSpeed;
+ emit verticalScroll(voff);
+ if(ypos <= curypos)
+ {
+ canScrollDown = false;
+ }
+ else
+ {
+ canScrollUp = true;
+ ev_pos.setY(rmapyDev(rmapy(ev_pos.y()) + scrollSpeed));
+ doVMove = true;
+ }
+ }
+ else
+ {
+ }
+ break;
+ case VSCROLL_UP:
+ if(canScrollUp)
+ {
+ curypos = ypos;
+ voff -= scrollSpeed;
+ emit verticalScroll(voff);
+ if(ypos >= curypos)
+ {
+ canScrollUp = false;
+ }
+ else
+ {
+ canScrollDown = true;
+ ev_pos.setY(rmapyDev(rmapy(ev_pos.y()) - scrollSpeed));
+ doVMove = true;
+ }
+ }
+ else
+ {
+ }
+ break;
+ default:
+ break;
+ }
+
+ //printf("Canvas::scrollTimerDone doHMove:%d doVMove:%d\n", doHMove, doVMove);
+
+ if(!doHMove && !doVMove)
+ {
+ delete scrollTimer;
+ scrollTimer=NULL;
+ doScroll = false;
+ return;
+ }
+ QPoint dist = ev_pos - start;
+ switch(drag)
+ {
+ case DRAG_MOVE:
+ case DRAG_COPY:
+ case DRAG_CLONE:
+ moveItems(ev_pos, 0, false);
+ break;
+ case DRAGX_MOVE:
+ case DRAGX_COPY:
+ case DRAGX_CLONE:
+ moveItems(ev_pos, 1, false);
+ break;
+ case DRAGY_MOVE:
+ case DRAGY_COPY:
+ case DRAGY_CLONE:
+ moveItems(ev_pos, 2, false);
+ break;
+ case DRAG_LASSO:
+ lasso = QRect(start.x(), start.y(), dist.x(), dist.y());
+ redraw();
+ break;
+ case DRAG_NEW:
+ case DRAG_RESIZE:
+ if (dist.x()) {
+ if (dist.x() < 1)
+ curItem->setWidth(1);
+ else
+ curItem->setWidth(dist.x());
+ redraw();
+ }
+ break;
+ default:
+ break;
+ }
+ //printf("Canvas::scrollTimerDone starting scrollTimer: Currently active?%d\n", scrollTimer->isActive());
+
+ // p3.3.43 Make sure to yield to other events (for up to 3 seconds), otherwise other events
+ // take a long time to reach us, causing scrolling to take a painfully long time to stop.
+ // FIXME: Didn't help at all.
+ //qApp->processEvents();
+ // No, try up to 100 ms for each yield.
+ //qApp->processEvents(100);
+ //
+ //scrollTimer->start( 40, TRUE ); // X ms single-shot timer
+ // OK, changing the timeout from 40 to 80 helped.
+ //scrollTimer->start( 80, TRUE ); // X ms single-shot timer
+ scrollTimer->setSingleShot(true);
+ scrollTimer->start(80);
+ }
+ else
+ {
+ //printf("Canvas::scrollTimerDone !(drag != DRAG_OFF && doScroll) deleting scrollTimer\n");
+
+ delete scrollTimer;
+ scrollTimer=NULL;
+ }
+}
+
+
+//---------------------------------------------------------
+// viewMouseMoveEvent
+//---------------------------------------------------------
+
+void Canvas::viewMouseMoveEvent(QMouseEvent* event)
+ {
+
+ ev_pos = event->pos();
+ QPoint dist = ev_pos - start;
+ int ax = ABS(rmapx(dist.x()));
+ int ay = ABS(rmapy(dist.y()));
+ bool moving = (ax >= 2) || (ay > 2);
+
+ // set scrolling variables: doScroll, scrollRight
+ if (drag != DRAG_OFF) {
+
+
+ int ex = rmapx(event->x())+mapx(0);
+ if(ex < 40 && canScrollLeft)
+ hscrollDir = HSCROLL_LEFT;
+ else
+ if(ex > (width() - 40))
+ switch(drag)
+ {
+ case DRAG_NEW:
+ case DRAG_RESIZE:
+ case DRAGX_MOVE:
+ case DRAGX_COPY:
+ case DRAGX_CLONE:
+ case DRAGY_MOVE:
+ case DRAGY_COPY:
+ case DRAGY_CLONE:
+ case DRAG_MOVE:
+ case DRAG_COPY:
+ case DRAG_CLONE:
+ hscrollDir = HSCROLL_RIGHT;
+ break;
+ default:
+ if(canScrollRight)
+ hscrollDir = HSCROLL_RIGHT;
+ else
+ hscrollDir = HSCROLL_NONE;
+ break;
+ }
+ else
+ hscrollDir = HSCROLL_NONE;
+ int ey = rmapy(event->y())+mapy(0);
+ if(ey < 15 && canScrollUp)
+ vscrollDir = VSCROLL_UP;
+ else
+ if(ey > (height() - 15) && canScrollDown)
+ vscrollDir = VSCROLL_DOWN;
+ else
+ vscrollDir = VSCROLL_NONE;
+ if(hscrollDir != HSCROLL_NONE || vscrollDir != VSCROLL_NONE)
+ {
+ doScroll=true;
+ if (!scrollTimer)
+ {
+ scrollTimer= new QTimer(this);
+ connect( scrollTimer, SIGNAL(timeout()), SLOT(scrollTimerDone()) );
+ //scrollTimer->start( 0, TRUE ); // single-shot timer
+ scrollTimer->setSingleShot(true); // single-shot timer
+ scrollTimer->start(0);
+ }
+ }
+ else
+ doScroll=false;
+
+ }
+ else
+ {
+ doScroll=false;
+
+ canScrollLeft = true;
+ canScrollRight = true;
+ canScrollUp = true;
+ canScrollDown = true;
+ }
+
+ switch (drag) {
+ case DRAG_LASSO_START:
+ if (!moving)
+ break;
+ drag = DRAG_LASSO;
+ setCursor();
+ // proceed with DRAG_LASSO:
+
+ case DRAG_LASSO:
+ {
+ lasso = QRect(start.x(), start.y(), dist.x(), dist.y());
+
+ // printf("xorg=%d xmag=%d event->x=%d, mapx(xorg)=%d rmapx0=%d xOffset=%d rmapx(xOffset()=%d\n",
+ // xorg, xmag, event->x(),mapx(xorg), rmapx(0), xOffset(),rmapx(xOffset()));
+
+ }
+ redraw();
+ break;
+
+ case DRAG_MOVE_START:
+ case DRAG_COPY_START:
+ case DRAG_CLONE_START:
+ if (!moving)
+ break;
+ if (keyState & Qt::ControlModifier) {
+ if (ax > ay) {
+ if (drag == DRAG_MOVE_START)
+ drag = DRAGX_MOVE;
+ else if (drag == DRAG_COPY_START)
+ drag = DRAGX_COPY;
+ else
+ drag = DRAGX_CLONE;
+ }
+ else {
+ if (drag == DRAG_MOVE_START)
+ drag = DRAGY_MOVE;
+ else if (drag == DRAG_COPY_START)
+ drag = DRAGY_COPY;
+ else
+ drag = DRAGY_CLONE;
+ }
+ }
+ else {
+ if (drag == DRAG_MOVE_START)
+ drag = DRAG_MOVE;
+ else if (drag == DRAG_COPY_START)
+ drag = DRAG_COPY;
+ else
+ drag = DRAG_CLONE;
+ }
+ setCursor();
+ if (!curItem->isSelected()) {
+ if (drag == DRAG_MOVE)
+ deselectAll();
+ selectItem(curItem, true);
+ updateSelection();
+ redraw();
+ }
+ DragType dt;
+ if (drag == DRAG_MOVE)
+ dt = MOVE_MOVE;
+ else if (drag == DRAG_COPY)
+ dt = MOVE_COPY;
+ else
+ dt = MOVE_CLONE;
+
+ startMoving(ev_pos, dt);
+ break;
+
+ case DRAG_MOVE:
+ case DRAG_COPY:
+ case DRAG_CLONE:
+
+ if(!scrollTimer)
+ moveItems(ev_pos, 0);
+ break;
+
+ case DRAGX_MOVE:
+ case DRAGX_COPY:
+ case DRAGX_CLONE:
+ if(!scrollTimer)
+ moveItems(ev_pos, 1);
+ break;
+
+ case DRAGY_MOVE:
+ case DRAGY_COPY:
+ case DRAGY_CLONE:
+ if(!scrollTimer)
+ moveItems(ev_pos, 2);
+ break;
+
+ case DRAG_NEW:
+ case DRAG_RESIZE:
+ if (dist.x()) {
+ if (dist.x() < 1)
+ curItem->setWidth(1);
+ else
+ curItem->setWidth(dist.x());
+ redraw();
+ }
+ break;
+ case DRAG_DELETE:
+ deleteItem(ev_pos);
+ break;
+
+ case DRAG_OFF:
+ break;
+ }
+
+ mouseMove(ev_pos);
+ }
+
+//---------------------------------------------------------
+// viewMouseReleaseEvent
+//---------------------------------------------------------
+
+void Canvas::viewMouseReleaseEvent(QMouseEvent* event)
+ {
+// printf("release %x %x\n", event->state(), event->button());
+
+ doScroll = false;
+ canScrollLeft = true;
+ canScrollRight = true;
+ canScrollUp = true;
+ canScrollDown = true;
+ ///if (event->state() & (Qt::LeftButton|Qt::RightButton|Qt::MidButton) & ~(event->button())) {
+ if (event->buttons() & (Qt::LeftButton|Qt::RightButton|Qt::MidButton) & ~(event->button())) {
+ ///printf("ignore %x %x\n", keyState, event->button());
+ //printf("viewMouseReleaseEvent ignore buttons:%x mods:%x button:%x\n", (int)event->buttons(), (int)keyState, event->button());
+ return;
+ }
+
+ QPoint pos = event->pos();
+ ///bool shift = event->state() & Qt::ShiftModifier;
+ bool shift = ((QInputEvent*)event)->modifiers() & Qt::ShiftModifier;
+ bool redrawFlag = false;
+
+ switch (drag) {
+ case DRAG_MOVE_START:
+ case DRAG_COPY_START:
+ case DRAG_CLONE_START:
+ if (!shift)
+ deselectAll();
+ selectItem(curItem, !(shift && curItem->isSelected()));
+ updateSelection();
+ redrawFlag = true;
+ itemReleased(curItem, curItem->pos());
+ break;
+ case DRAG_COPY:
+ endMoveItems(pos, MOVE_COPY, 0);
+ break;
+ case DRAGX_COPY:
+ endMoveItems(pos, MOVE_COPY, 1);
+ break;
+ case DRAGY_COPY:
+ endMoveItems(pos, MOVE_COPY, 2);
+ break;
+ case DRAG_MOVE:
+ endMoveItems(pos, MOVE_MOVE, 0);
+ break;
+ case DRAGX_MOVE:
+ endMoveItems(pos, MOVE_MOVE, 1);
+ break;
+ case DRAGY_MOVE:
+ endMoveItems(pos, MOVE_MOVE, 2);
+ break;
+ case DRAG_CLONE:
+ endMoveItems(pos, MOVE_CLONE, 0);
+ break;
+ case DRAGX_CLONE:
+ endMoveItems(pos, MOVE_CLONE, 1);
+ break;
+ case DRAGY_CLONE:
+ endMoveItems(pos, MOVE_CLONE, 2);
+ break;
+ case DRAG_OFF:
+ break;
+ case DRAG_RESIZE:
+ resizeItem(curItem, false);
+ break;
+ case DRAG_NEW:
+ newItem(curItem, false);
+ redrawFlag = true;
+ break;
+ case DRAG_LASSO_START:
+ lasso.setRect(-1, -1, -1, -1);
+ if (!shift)
+ deselectAll();
+ updateSelection();
+ redrawFlag = true;
+ break;
+
+ case DRAG_LASSO:
+ if (!shift)
+ deselectAll();
+ lasso = lasso.normalized();
+ selectLasso(shift);
+ updateSelection();
+ redrawFlag = true;
+ break;
+
+ case DRAG_DELETE:
+ break;
+ }
+ //printf("Canvas::viewMouseReleaseEvent setting drag to DRAG_OFF\n");
+
+ drag = DRAG_OFF;
+ if (redrawFlag)
+ redraw();
+ setCursor();
+ }
+
+//---------------------------------------------------------
+// selectLasso
+//---------------------------------------------------------
+
+void Canvas::selectLasso(bool toggle)
+ {
+ int n = 0;
+ if (virt()) {
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ if (i->second->intersects(lasso)) {
+ selectItem(i->second, !(toggle && i->second->isSelected()));
+ ++n;
+ }
+ }
+ }
+ else {
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ QRect box = i->second->bbox();
+ int x = rmapxDev(box.x());
+ int y = rmapyDev(box.y());
+ int w = rmapxDev(box.width());
+ int h = rmapyDev(box.height());
+ QRect r(x, y, w, h);
+ ///r.moveBy(i->second->pos().x(), i->second->pos().y());
+ r.translate(i->second->pos().x(), i->second->pos().y());
+ if (r.intersects(lasso)) {
+ selectItem(i->second, !(toggle && i->second->isSelected()));
+ ++n;
+ }
+ }
+ }
+
+
+
+ if (n) {
+ updateSelection();
+ redraw();
+ }
+ }
+
+//---------------------------------------------------------
+// endMoveItems
+// dir = 0 move in all directions
+// 1 move only horizontal
+// 2 move only vertical
+//---------------------------------------------------------
+
+void Canvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir)
+ {
+ startUndo(dragtype);
+
+ int dp = y2pitch(pos.y()) - y2pitch(start.y());
+ int dx = pos.x() - start.x();
+
+ if (dir == 1)
+ dp = 0;
+ else if (dir == 2)
+ dx = 0;
+
+
+
+ int modified = 0;
+
+ // Removed by T356.
+ /*
+ for (iCItem i = moving.begin(); i != moving.end(); ++i) {
+ int x = i->second->pos().x();
+ int y = i->second->pos().y();
+ int nx = x + dx;
+ int ny = pitch2y(y2pitch(y) + dp);
+ QPoint newpos = raster(QPoint(nx, ny));
+ selectItem(i->second, true);
+
+ if (moveItem(i->second, newpos, dragtype, &modified))
+ i->second->move(newpos);
+ if (moving.size() == 1) {
+ itemReleased(curItem, newpos);
+ }
+ if (dragtype == MOVE_COPY || dragtype == MOVE_CLONE)
+ selectItem(i->second, false);
+ }
+ */
+
+ moveCanvasItems(moving, dp, dx, dragtype, &modified);
+
+ endUndo(dragtype, modified);
+ moving.clear();
+ updateSelection();
+ redraw();
+ }
+
+//---------------------------------------------------------
+// getCurrentDrag
+// returns 0 if there is no drag operation
+//---------------------------------------------------------
+
+int Canvas::getCurrentDrag()
+ {
+ //printf("getCurrentDrag=%d\n", drag);
+ return drag;
+ }
+
+//---------------------------------------------------------
+// deleteItem
+//---------------------------------------------------------
+
+void Canvas::deleteItem(const QPoint& p)
+ {
+ if (virt()) {
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ if (i->second->contains(p)) {
+ selectItem(i->second, false);
+ if (!deleteItem(i->second)) {
+ if (drag == DRAG_DELETE)
+ drag = DRAG_OFF;
+ }
+ break;
+ }
+ }
+ }
+ else {
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ QRect box = i->second->bbox();
+ int x = rmapxDev(box.x());
+ int y = rmapyDev(box.y());
+ int w = rmapxDev(box.width());
+ int h = rmapyDev(box.height());
+ QRect r(x, y, w, h);
+ ///r.moveBy(i->second->pos().x(), i->second->pos().y());
+ r.translate(i->second->pos().x(), i->second->pos().y());
+ if (r.contains(p)) {
+ if (deleteItem(i->second)) {
+ selectItem(i->second, false);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// setTool
+//---------------------------------------------------------
+
+void Canvas::setTool(int t)
+ {
+ if (_tool == Tool(t))
+ return;
+ _tool = Tool(t);
+ setCursor();
+ }
+
+//---------------------------------------------------------
+// setCursor
+//---------------------------------------------------------
+
+void Canvas::setCursor()
+ {
+ switch (drag) {
+ case DRAGX_MOVE:
+ case DRAGX_COPY:
+ case DRAGX_CLONE:
+ QWidget::setCursor(QCursor(Qt::SizeHorCursor));
+ break;
+
+ case DRAGY_MOVE:
+ case DRAGY_COPY:
+ case DRAGY_CLONE:
+ QWidget::setCursor(QCursor(Qt::SizeVerCursor));
+ break;
+
+ case DRAG_MOVE:
+ case DRAG_COPY:
+ case DRAG_CLONE:
+ QWidget::setCursor(QCursor(Qt::SizeAllCursor));
+ break;
+
+ case DRAG_RESIZE:
+ QWidget::setCursor(QCursor(Qt::SizeHorCursor));
+ break;
+
+ case DRAG_DELETE:
+ case DRAG_COPY_START:
+ case DRAG_CLONE_START:
+ case DRAG_MOVE_START:
+ case DRAG_NEW:
+ case DRAG_LASSO_START:
+ case DRAG_LASSO:
+ case DRAG_OFF:
+ switch(_tool) {
+ case PencilTool:
+ QWidget::setCursor(QCursor(*pencilIcon, 4, 15));
+ break;
+ case RubberTool:
+ QWidget::setCursor(QCursor(*deleteIcon, 4, 15));
+ break;
+ case GlueTool:
+ QWidget::setCursor(QCursor(*glueIcon, 4, 15));
+ break;
+ case CutTool:
+ QWidget::setCursor(QCursor(*cutIcon, 4, 15));
+ break;
+ case MuteTool:
+ QWidget::setCursor(QCursor(*editmuteIcon, 4, 15));
+ break;
+ default:
+ QWidget::setCursor(QCursor(Qt::ArrowCursor));
+ break;
+ }
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// keyPress
+//---------------------------------------------------------
+
+void Canvas::keyPress(QKeyEvent* event)
+ {
+ event->ignore();
+ }
+
+//---------------------------------------------------------
+// isSingleSelection
+//---------------------------------------------------------
+
+bool Canvas::isSingleSelection()
+ {
+ return selectionSize() == 1;
+ }
+
+//---------------------------------------------------------
+// selectionSize
+//---------------------------------------------------------
+
+int Canvas::selectionSize()
+ {
+ int n = 0;
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ if (i->second->isSelected())
+ ++n;
+ }
+ return n;
+ }
+
+//---------------------------------------------------------
+// genCanvasPopup
+//---------------------------------------------------------
+
+QMenu* Canvas::genCanvasPopup()
+ {
+ if (canvasTools == 0)
+ return 0;
+ QMenu* canvasPopup = new QMenu(this);
+ QAction* act0 = 0;
+
+ for (unsigned i = 0; i < 9; ++i) {
+ if ((canvasTools & (1 << i))==0)
+ continue;
+ QAction* act = canvasPopup->addAction(QIcon(**toolList[i].icon), tr(toolList[i].tip));
+ act->setData(1<<i); // ddskrjo
+ if (!act0)
+ act0 = act;
+ }
+ canvasPopup->setActiveAction(act0);
+ return canvasPopup;
+ }
+
+//---------------------------------------------------------
+// canvasPopup
+//---------------------------------------------------------
+
+void Canvas::canvasPopup(int n)
+ {
+ setTool(n);
+ emit toolChanged(n);
+ }
+
+void Canvas::setCurrentPart(Part* part)
+{
+ curItem = NULL;
+ deselectAll();
+ curPart = part;
+ curPartId = curPart->sn();
+ curPartChanged();
+}