diff options
Diffstat (limited to 'attic/muse2-oom/muse2/muse/widgets/canvas.cpp')
-rw-r--r-- | attic/muse2-oom/muse2/muse/widgets/canvas.cpp | 1463 |
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(); +} |