annotate widgets/Pane.cpp @ 27:38fe0ea9e46e

* Some fixes to waveform layer greyscaling * Tidying in panner class
author Chris Cannam
date Fri, 03 Feb 2006 17:30:47 +0000
parents dcdb21b62dbb
children 202d1dca67d2
rev   line source
Chris@0 1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@0 4 A waveform viewer and audio annotation editor.
Chris@5 5 Chris Cannam, Queen Mary University of London, 2005-2006
Chris@0 6
Chris@0 7 This is experimental software. Not for distribution.
Chris@0 8 */
Chris@0 9
Chris@0 10 #include "widgets/Pane.h"
Chris@0 11 #include "base/Layer.h"
Chris@0 12 #include "base/Model.h"
Chris@0 13 #include "base/ZoomConstraint.h"
Chris@0 14 #include "base/RealTime.h"
Chris@0 15 #include "base/Profiler.h"
Chris@13 16 #include "base/ViewManager.h"
Chris@0 17
Chris@0 18 #include <QPaintEvent>
Chris@0 19 #include <QPainter>
Chris@0 20 #include <iostream>
Chris@0 21 #include <cmath>
Chris@0 22
Chris@0 23 using std::cerr;
Chris@0 24 using std::endl;
Chris@0 25
Chris@0 26 Pane::Pane(QWidget *w) :
Chris@0 27 View(w, true),
Chris@0 28 m_identifyFeatures(false),
Chris@0 29 m_clickedInRange(false),
Chris@0 30 m_shiftPressed(false),
Chris@13 31 m_ctrlPressed(false),
Chris@17 32 m_navigating(false),
Chris@17 33 m_resizing(false),
Chris@0 34 m_centreLineVisible(true)
Chris@0 35 {
Chris@0 36 setObjectName("Pane");
Chris@0 37 setMouseTracking(true);
Chris@0 38 }
Chris@0 39
Chris@0 40 bool
Chris@0 41 Pane::shouldIlluminateLocalFeatures(const Layer *layer, QPoint &pos)
Chris@0 42 {
Chris@27 43 /*!!!
Chris@0 44 for (LayerList::iterator vi = m_layers.end(); vi != m_layers.begin(); ) {
Chris@0 45 --vi;
Chris@0 46 if (layer != *vi) return false;
Chris@0 47 pos = m_identifyPoint;
Chris@0 48 return m_identifyFeatures;
Chris@0 49 }
Chris@27 50 */
Chris@27 51 if (layer == getSelectedLayer()) {
Chris@27 52 pos = m_identifyPoint;
Chris@27 53 return m_identifyFeatures;
Chris@27 54 }
Chris@0 55
Chris@0 56 return false;
Chris@0 57 }
Chris@0 58
Chris@0 59 void
Chris@0 60 Pane::setCentreLineVisible(bool visible)
Chris@0 61 {
Chris@0 62 m_centreLineVisible = visible;
Chris@0 63 update();
Chris@0 64 }
Chris@0 65
Chris@0 66 void
Chris@0 67 Pane::paintEvent(QPaintEvent *e)
Chris@0 68 {
Chris@0 69 QPainter paint;
Chris@0 70
Chris@0 71 QRect r(rect());
Chris@0 72
Chris@0 73 if (e) {
Chris@0 74 r = e->rect();
Chris@0 75 }
Chris@0 76 /*
Chris@0 77 paint.begin(this);
Chris@0 78 paint.setClipRect(r);
Chris@0 79
Chris@0 80 if (hasLightBackground()) {
Chris@0 81 paint.setPen(Qt::white);
Chris@0 82 paint.setBrush(Qt::white);
Chris@0 83 } else {
Chris@0 84 paint.setPen(Qt::black);
Chris@0 85 paint.setBrush(Qt::black);
Chris@0 86 }
Chris@0 87 paint.drawRect(r);
Chris@0 88
Chris@0 89 paint.end();
Chris@0 90 */
Chris@0 91 View::paintEvent(e);
Chris@0 92
Chris@0 93 paint.begin(this);
Chris@0 94
Chris@0 95 if (e) {
Chris@0 96 paint.setClipRect(r);
Chris@0 97 }
Chris@0 98
Chris@0 99 for (LayerList::iterator vi = m_layers.end(); vi != m_layers.begin(); ) {
Chris@0 100 --vi;
Chris@0 101
Chris@0 102 int sw = (*vi)->getVerticalScaleWidth(paint);
Chris@0 103
Chris@0 104 if (sw > 0 && r.left() < sw) {
Chris@0 105
Chris@0 106 // Profiler profiler("Pane::paintEvent - painting vertical scale", true);
Chris@0 107
Chris@0 108 // std::cerr << "Pane::paintEvent: calling paint.save() in vertical scale block" << std::endl;
Chris@0 109 paint.save();
Chris@0 110
Chris@0 111 paint.setPen(Qt::black);
Chris@0 112 paint.setBrush(Qt::white);
Chris@0 113 paint.drawRect(0, 0, sw, height());
Chris@0 114
Chris@0 115 paint.setBrush(Qt::NoBrush);
Chris@0 116 (*vi)->paintVerticalScale(paint, QRect(0, 0, sw, height()));
Chris@0 117
Chris@0 118 paint.restore();
Chris@0 119 }
Chris@0 120
Chris@0 121 if (m_identifyFeatures) {
Chris@25 122
Chris@25 123 QPoint pos = m_identifyPoint;
Chris@25 124 QString desc = (*vi)->getFeatureDescription(pos);
Chris@25 125
Chris@25 126 if (desc != "") {
Chris@25 127
Chris@25 128 paint.save();
Chris@25 129
Chris@25 130 int tabStop =
Chris@25 131 paint.fontMetrics().width(tr("Some lengthy prefix:"));
Chris@25 132
Chris@25 133 QRect boundingRect =
Chris@25 134 paint.fontMetrics().boundingRect
Chris@25 135 (rect(),
Chris@25 136 Qt::AlignRight | Qt::AlignTop | Qt::TextExpandTabs,
Chris@25 137 desc, tabStop);
Chris@25 138
Chris@25 139 if (hasLightBackground()) {
Chris@25 140 paint.setPen(Qt::NoPen);
Chris@25 141 paint.setBrush(QColor(250, 250, 250, 200));
Chris@25 142 } else {
Chris@25 143 paint.setPen(Qt::NoPen);
Chris@25 144 paint.setBrush(QColor(50, 50, 50, 200));
Chris@25 145 }
Chris@25 146
Chris@25 147 int extra = paint.fontMetrics().descent();
Chris@25 148 paint.drawRect(width() - boundingRect.width() - 10 - extra,
Chris@25 149 10 - extra,
Chris@25 150 boundingRect.width() + 2 * extra,
Chris@25 151 boundingRect.height() + extra);
Chris@25 152
Chris@25 153 if (hasLightBackground()) {
Chris@25 154 paint.setPen(QColor(150, 20, 0));
Chris@25 155 } else {
Chris@25 156 paint.setPen(QColor(255, 150, 100));
Chris@25 157 }
Chris@25 158
Chris@25 159 QTextOption option;
Chris@25 160 option.setWrapMode(QTextOption::NoWrap);
Chris@25 161 option.setAlignment(Qt::AlignRight | Qt::AlignTop);
Chris@25 162 option.setTabStop(tabStop);
Chris@25 163 paint.drawText(QRectF(width() - boundingRect.width() - 10, 10,
Chris@25 164 boundingRect.width(),
Chris@25 165 boundingRect.height()),
Chris@25 166 desc,
Chris@25 167 option);
Chris@25 168
Chris@25 169 paint.restore();
Chris@25 170 }
Chris@0 171 }
Chris@0 172
Chris@0 173 break;
Chris@0 174 }
Chris@0 175
Chris@0 176 if (m_centreLineVisible) {
Chris@0 177
Chris@0 178 if (hasLightBackground()) {
Chris@0 179 paint.setPen(QColor(50, 50, 50));
Chris@0 180 } else {
Chris@0 181 paint.setPen(QColor(200, 200, 200));
Chris@0 182 }
Chris@0 183 paint.setBrush(Qt::NoBrush);
Chris@0 184 paint.drawLine(width() / 2, 0, width() / 2, height() - 1);
Chris@0 185
Chris@0 186 // QFont font(paint.font());
Chris@0 187 // font.setBold(true);
Chris@0 188 // paint.setFont(font);
Chris@0 189
Chris@0 190 int sampleRate = getModelsSampleRate();
Chris@0 191 int y = height() - paint.fontMetrics().height()
Chris@0 192 + paint.fontMetrics().ascent() - 6;
Chris@0 193
Chris@0 194 LayerList::iterator vi = m_layers.end();
Chris@0 195
Chris@0 196 if (vi != m_layers.begin()) {
Chris@0 197
Chris@0 198 switch ((*--vi)->getPreferredFrameCountPosition()) {
Chris@0 199
Chris@0 200 case Layer::PositionTop:
Chris@0 201 y = paint.fontMetrics().ascent() + 6;
Chris@0 202 break;
Chris@0 203
Chris@0 204 case Layer::PositionMiddle:
Chris@0 205 y = (height() - paint.fontMetrics().height()) / 2
Chris@0 206 + paint.fontMetrics().ascent();
Chris@0 207 break;
Chris@0 208
Chris@0 209 case Layer::PositionBottom:
Chris@0 210 // y already set correctly
Chris@0 211 break;
Chris@0 212 }
Chris@0 213 }
Chris@0 214
Chris@0 215 if (sampleRate) {
Chris@0 216
Chris@0 217 QString text(QString::fromStdString
Chris@0 218 (RealTime::frame2RealTime
Chris@0 219 (m_centreFrame, sampleRate).toText(true)));
Chris@0 220
Chris@0 221 int tw = paint.fontMetrics().width(text);
Chris@0 222 int x = width()/2 - 4 - tw;
Chris@0 223
Chris@0 224 if (hasLightBackground()) {
Chris@0 225 paint.setPen(palette().background().color());
Chris@0 226 for (int dx = -1; dx <= 1; ++dx) {
Chris@0 227 for (int dy = -1; dy <= 1; ++dy) {
Chris@0 228 if ((dx && dy) || !(dx || dy)) continue;
Chris@0 229 paint.drawText(x + dx, y + dy, text);
Chris@0 230 }
Chris@0 231 }
Chris@0 232 paint.setPen(QColor(50, 50, 50));
Chris@0 233 } else {
Chris@0 234 paint.setPen(QColor(200, 200, 200));
Chris@0 235 }
Chris@0 236
Chris@0 237 paint.drawText(x, y, text);
Chris@0 238 }
Chris@0 239
Chris@0 240 QString text = QString("%1").arg(m_centreFrame);
Chris@0 241
Chris@0 242 int tw = paint.fontMetrics().width(text);
Chris@0 243 int x = width()/2 + 4;
Chris@0 244
Chris@0 245 if (hasLightBackground()) {
Chris@0 246 paint.setPen(palette().background().color());
Chris@0 247 for (int dx = -1; dx <= 1; ++dx) {
Chris@0 248 for (int dy = -1; dy <= 1; ++dy) {
Chris@0 249 if ((dx && dy) || !(dx || dy)) continue;
Chris@0 250 paint.drawText(x + dx, y + dy, text);
Chris@0 251 }
Chris@0 252 }
Chris@0 253 paint.setPen(QColor(50, 50, 50));
Chris@0 254 } else {
Chris@0 255 paint.setPen(QColor(200, 200, 200));
Chris@0 256 }
Chris@0 257 paint.drawText(x, y, text);
Chris@0 258 }
Chris@0 259
Chris@0 260 if (m_clickedInRange && m_shiftPressed) {
Chris@19 261 if (m_manager && (m_manager->getToolMode() == ViewManager::NavigateMode)) {
Chris@19 262 //!!! be nice if this looked a bit more in keeping with the
Chris@19 263 //selection block
Chris@19 264 paint.setPen(Qt::blue);
Chris@19 265 paint.drawRect(m_clickPos.x(), m_clickPos.y(),
Chris@19 266 m_mousePos.x() - m_clickPos.x(),
Chris@19 267 m_mousePos.y() - m_clickPos.y());
Chris@19 268 }
Chris@0 269 }
Chris@0 270
Chris@0 271 paint.end();
Chris@0 272 }
Chris@0 273
Chris@17 274 Selection
Chris@17 275 Pane::getSelectionAt(int x, bool &closeToLeftEdge, bool &closeToRightEdge)
Chris@17 276 {
Chris@17 277 closeToLeftEdge = closeToRightEdge = false;
Chris@17 278
Chris@17 279 if (!m_manager) return Selection();
Chris@17 280
Chris@20 281 long testFrame = getFrameForX(x - 5);
Chris@17 282 if (testFrame < 0) {
Chris@20 283 testFrame = getFrameForX(x);
Chris@17 284 if (testFrame < 0) return Selection();
Chris@17 285 }
Chris@17 286
Chris@17 287 Selection selection = m_manager->getContainingSelection(testFrame, true);
Chris@17 288 if (selection.isEmpty()) return selection;
Chris@17 289
Chris@20 290 int lx = getXForFrame(selection.getStartFrame());
Chris@20 291 int rx = getXForFrame(selection.getEndFrame());
Chris@17 292
Chris@17 293 int fuzz = 2;
Chris@17 294 if (x < lx - fuzz || x > rx + fuzz) return Selection();
Chris@17 295
Chris@17 296 int width = rx - lx;
Chris@17 297 fuzz = 3;
Chris@17 298 if (width < 12) fuzz = width / 4;
Chris@17 299 if (fuzz < 1) fuzz = 1;
Chris@17 300
Chris@17 301 if (x < lx + fuzz) closeToLeftEdge = true;
Chris@17 302 if (x > rx - fuzz) closeToRightEdge = true;
Chris@17 303
Chris@17 304 return selection;
Chris@17 305 }
Chris@17 306
Chris@0 307 void
Chris@0 308 Pane::mousePressEvent(QMouseEvent *e)
Chris@0 309 {
Chris@0 310 m_clickPos = e->pos();
Chris@0 311 m_clickedInRange = true;
Chris@0 312 m_shiftPressed = (e->modifiers() & Qt::ShiftModifier);
Chris@13 313 m_ctrlPressed = (e->modifiers() & Qt::ControlModifier);
Chris@13 314
Chris@13 315 ViewManager::ToolMode mode = ViewManager::NavigateMode;
Chris@13 316 if (m_manager) mode = m_manager->getToolMode();
Chris@13 317
Chris@17 318 m_navigating = false;
Chris@13 319
Chris@17 320 if (mode == ViewManager::NavigateMode || (e->buttons() & Qt::MidButton)) {
Chris@17 321
Chris@17 322 if (mode != ViewManager::NavigateMode) {
Chris@17 323 setCursor(Qt::PointingHandCursor);
Chris@17 324 }
Chris@17 325
Chris@17 326 m_navigating = true;
Chris@13 327 m_dragCentreFrame = m_centreFrame;
Chris@13 328
Chris@13 329 } else if (mode == ViewManager::SelectMode) {
Chris@13 330
Chris@17 331 bool closeToLeft = false, closeToRight = false;
Chris@17 332 Selection selection = getSelectionAt(e->x(), closeToLeft, closeToRight);
Chris@17 333
Chris@17 334 if ((closeToLeft || closeToRight) && !(closeToLeft && closeToRight)) {
Chris@17 335
Chris@17 336 m_manager->removeSelection(selection);
Chris@17 337
Chris@17 338 if (closeToLeft) {
Chris@17 339 m_selectionStartFrame = selection.getEndFrame();
Chris@17 340 } else {
Chris@17 341 m_selectionStartFrame = selection.getStartFrame();
Chris@17 342 }
Chris@17 343
Chris@17 344 m_manager->setInProgressSelection(selection, false);
Chris@17 345 m_resizing = true;
Chris@13 346
Chris@17 347 } else {
Chris@17 348
Chris@20 349 int mouseFrame = getFrameForX(e->x());
Chris@17 350 size_t resolution = 1;
Chris@17 351 int snapFrame = mouseFrame;
Chris@17 352
Chris@17 353 Layer *layer = getSelectedLayer();
Chris@17 354 if (layer) {
Chris@17 355 snapFrame = layer->getNearestFeatureFrame(mouseFrame, resolution,
Chris@17 356 false);
Chris@17 357 }
Chris@17 358
Chris@17 359 if (snapFrame < 0) snapFrame = 0;
Chris@17 360 m_selectionStartFrame = snapFrame;
Chris@17 361 if (m_manager) {
Chris@17 362 m_manager->setInProgressSelection(Selection(snapFrame,
Chris@17 363 snapFrame + resolution),
Chris@17 364 !m_ctrlPressed);
Chris@17 365 }
Chris@17 366
Chris@17 367 m_resizing = false;
Chris@17 368 }
Chris@17 369
Chris@17 370 update();
Chris@17 371
Chris@17 372 } else if (mode == ViewManager::DrawMode) {
Chris@17 373
Chris@13 374 Layer *layer = getSelectedLayer();
Chris@23 375 if (layer && layer->isLayerEditable()) {
Chris@17 376 layer->drawStart(e);
Chris@13 377 }
Chris@18 378
Chris@18 379 } else if (mode == ViewManager::EditMode) {
Chris@18 380
Chris@18 381 Layer *layer = getSelectedLayer();
Chris@23 382 if (layer && layer->isLayerEditable()) {
Chris@18 383 layer->editStart(e);
Chris@18 384 }
Chris@13 385 }
Chris@0 386
Chris@0 387 emit paneInteractedWith();
Chris@0 388 }
Chris@0 389
Chris@0 390 void
Chris@0 391 Pane::mouseReleaseEvent(QMouseEvent *e)
Chris@0 392 {
Chris@13 393 ViewManager::ToolMode mode = ViewManager::NavigateMode;
Chris@13 394 if (m_manager) mode = m_manager->getToolMode();
Chris@13 395
Chris@0 396 if (m_clickedInRange) {
Chris@0 397 mouseMoveEvent(e);
Chris@0 398 }
Chris@0 399
Chris@17 400 if (m_navigating || mode == ViewManager::NavigateMode) {
Chris@17 401
Chris@17 402 m_navigating = false;
Chris@17 403
Chris@17 404 if (mode != ViewManager::NavigateMode) {
Chris@17 405 // restore cursor
Chris@17 406 toolModeChanged();
Chris@17 407 }
Chris@0 408
Chris@13 409 if (m_shiftPressed) {
Chris@0 410
Chris@13 411 int x0 = std::min(m_clickPos.x(), m_mousePos.x());
Chris@13 412 int x1 = std::max(m_clickPos.x(), m_mousePos.x());
Chris@13 413 int w = x1 - x0;
Chris@13 414
Chris@20 415 long newStartFrame = getFrameForX(x0);
Chris@13 416
Chris@20 417 long visibleFrames = getEndFrame() - getStartFrame();
Chris@20 418 if (newStartFrame <= -visibleFrames) {
Chris@20 419 newStartFrame = -visibleFrames + 1;
Chris@13 420 }
Chris@13 421
Chris@13 422 if (newStartFrame >= long(getModelsEndFrame())) {
Chris@13 423 newStartFrame = getModelsEndFrame() - 1;
Chris@13 424 }
Chris@13 425
Chris@13 426 float ratio = float(w) / float(width());
Chris@13 427 // std::cerr << "ratio: " << ratio << std::endl;
Chris@13 428 size_t newZoomLevel = (size_t)nearbyint(m_zoomLevel * ratio);
Chris@13 429 if (newZoomLevel < 1) newZoomLevel = 1;
Chris@13 430
Chris@13 431 // std::cerr << "start: " << m_startFrame << ", level " << m_zoomLevel << std::endl;
Chris@13 432 setZoomLevel(getZoomConstraintBlockSize(newZoomLevel));
Chris@13 433 setStartFrame(newStartFrame);
Chris@13 434
Chris@13 435 //cerr << "mouseReleaseEvent: start frame now " << m_startFrame << endl;
Chris@13 436 // update();
Chris@0 437 }
Chris@0 438
Chris@13 439 } else if (mode == ViewManager::SelectMode) {
Chris@13 440
Chris@13 441 if (m_manager && m_manager->haveInProgressSelection()) {
Chris@13 442
Chris@13 443 bool exclusive;
Chris@13 444 Selection selection = m_manager->getInProgressSelection(exclusive);
Chris@13 445
Chris@13 446 if (selection.getEndFrame() < selection.getStartFrame() + 2) {
Chris@13 447 selection = Selection();
Chris@13 448 }
Chris@13 449
Chris@13 450 m_manager->clearInProgressSelection();
Chris@13 451
Chris@13 452 if (exclusive) {
Chris@13 453 m_manager->setSelection(selection);
Chris@13 454 } else {
Chris@13 455 m_manager->addSelection(selection);
Chris@13 456 }
Chris@0 457 }
Chris@13 458
Chris@13 459 update();
Chris@17 460
Chris@17 461 } else if (mode == ViewManager::DrawMode) {
Chris@17 462
Chris@17 463 Layer *layer = getSelectedLayer();
Chris@23 464 if (layer && layer->isLayerEditable()) {
Chris@17 465 layer->drawEnd(e);
Chris@17 466 update();
Chris@17 467 }
Chris@18 468
Chris@18 469 } else if (mode == ViewManager::EditMode) {
Chris@18 470
Chris@18 471 Layer *layer = getSelectedLayer();
Chris@23 472 if (layer && layer->isLayerEditable()) {
Chris@18 473 layer->editEnd(e);
Chris@18 474 update();
Chris@18 475 }
Chris@17 476 }
Chris@0 477
Chris@0 478 m_clickedInRange = false;
Chris@0 479
Chris@0 480 emit paneInteractedWith();
Chris@0 481 }
Chris@0 482
Chris@0 483 void
Chris@0 484 Pane::mouseMoveEvent(QMouseEvent *e)
Chris@0 485 {
Chris@13 486 ViewManager::ToolMode mode = ViewManager::NavigateMode;
Chris@13 487 if (m_manager) mode = m_manager->getToolMode();
Chris@13 488
Chris@0 489 if (!m_clickedInRange) {
Chris@0 490
Chris@17 491 if (mode == ViewManager::SelectMode) {
Chris@17 492 bool closeToLeft = false, closeToRight = false;
Chris@17 493 getSelectionAt(e->x(), closeToLeft, closeToRight);
Chris@17 494 if ((closeToLeft || closeToRight) && !(closeToLeft && closeToRight)) {
Chris@17 495 setCursor(Qt::SizeHorCursor);
Chris@17 496 } else {
Chris@17 497 setCursor(Qt::ArrowCursor);
Chris@17 498 }
Chris@17 499 }
Chris@0 500
Chris@17 501 if (mode != ViewManager::DrawMode) {
Chris@0 502
Chris@17 503 bool previouslyIdentifying = m_identifyFeatures;
Chris@17 504 QPoint prevPoint = m_identifyPoint;
Chris@0 505
Chris@17 506 m_identifyFeatures = true;
Chris@17 507 m_identifyPoint = e->pos();
Chris@17 508
Chris@17 509 if (m_identifyFeatures != previouslyIdentifying ||
Chris@17 510 m_identifyPoint != prevPoint) {
Chris@17 511 update();
Chris@17 512 }
Chris@0 513 }
Chris@0 514
Chris@13 515 return;
Chris@13 516 }
Chris@0 517
Chris@17 518 if (m_navigating || mode == ViewManager::NavigateMode) {
Chris@0 519
Chris@13 520 if (m_shiftPressed) {
Chris@0 521
Chris@13 522 m_mousePos = e->pos();
Chris@13 523 update();
Chris@0 524
Chris@0 525 } else {
Chris@13 526
Chris@20 527 long frameOff = getFrameForX(e->x()) - getFrameForX(m_clickPos.x());
Chris@20 528
Chris@13 529 size_t newCentreFrame = m_dragCentreFrame;
Chris@13 530
Chris@13 531 if (frameOff < 0) {
Chris@13 532 newCentreFrame -= frameOff;
Chris@13 533 } else if (newCentreFrame >= size_t(frameOff)) {
Chris@13 534 newCentreFrame -= frameOff;
Chris@13 535 } else {
Chris@13 536 newCentreFrame = 0;
Chris@13 537 }
Chris@13 538
Chris@13 539 if (newCentreFrame >= getModelsEndFrame()) {
Chris@13 540 newCentreFrame = getModelsEndFrame();
Chris@13 541 if (newCentreFrame > 0) --newCentreFrame;
Chris@13 542 }
Chris@20 543
Chris@20 544 if (getXForFrame(m_centreFrame) != getXForFrame(newCentreFrame)) {
Chris@13 545 setCentreFrame(newCentreFrame);
Chris@13 546 }
Chris@0 547 }
Chris@0 548
Chris@13 549 } else if (mode == ViewManager::SelectMode) {
Chris@13 550
Chris@20 551 int mouseFrame = getFrameForX(e->x());
Chris@13 552 size_t resolution = 1;
Chris@13 553 int snapFrameLeft = mouseFrame;
Chris@13 554 int snapFrameRight = mouseFrame;
Chris@13 555
Chris@13 556 Layer *layer = getSelectedLayer();
Chris@13 557 if (layer) {
Chris@13 558 snapFrameLeft = layer->getNearestFeatureFrame(mouseFrame, resolution,
Chris@13 559 false);
Chris@13 560 snapFrameRight = layer->getNearestFeatureFrame(mouseFrame, resolution,
Chris@13 561 true);
Chris@13 562 }
Chris@13 563
Chris@13 564 if (snapFrameLeft < 0) snapFrameLeft = 0;
Chris@13 565 if (snapFrameRight < 0) snapFrameRight = 0;
Chris@13 566
Chris@13 567 size_t min, max;
Chris@13 568
Chris@13 569 if (m_selectionStartFrame > snapFrameLeft) {
Chris@13 570 min = snapFrameLeft;
Chris@13 571 max = m_selectionStartFrame;
Chris@13 572 } else if (snapFrameRight > m_selectionStartFrame) {
Chris@13 573 min = m_selectionStartFrame;
Chris@13 574 max = snapFrameRight;
Chris@13 575 } else {
Chris@13 576 min = snapFrameLeft;
Chris@13 577 max = snapFrameRight;
Chris@0 578 }
Chris@0 579
Chris@13 580 if (m_manager) {
Chris@13 581 m_manager->setInProgressSelection(Selection(min, max),
Chris@17 582 !m_resizing && !m_ctrlPressed);
Chris@0 583 }
Chris@15 584
Chris@15 585 bool doScroll = false;
Chris@15 586 if (!m_manager) doScroll = true;
Chris@15 587 if (!m_manager->isPlaying()) doScroll = true;
Chris@15 588 if (m_followPlay != PlaybackScrollContinuous) doScroll = true;
Chris@15 589
Chris@15 590 if (doScroll) {
Chris@13 591 int offset = mouseFrame - getStartFrame();
Chris@13 592 int available = getEndFrame() - getStartFrame();
Chris@15 593 if (offset >= available * 0.95) {
Chris@15 594 int move = int(offset - available * 0.95) + 1;
Chris@14 595 setCentreFrame(m_centreFrame + move);
Chris@15 596 } else if (offset <= available * 0.10) {
Chris@15 597 int move = int(available * 0.10 - offset) + 1;
Chris@14 598 if (m_centreFrame > move) {
Chris@14 599 setCentreFrame(m_centreFrame - move);
Chris@14 600 } else {
Chris@14 601 setCentreFrame(0);
Chris@14 602 }
Chris@13 603 }
Chris@13 604 }
Chris@13 605
Chris@13 606 update();
Chris@17 607
Chris@17 608 } else if (mode == ViewManager::DrawMode) {
Chris@17 609
Chris@17 610 Layer *layer = getSelectedLayer();
Chris@23 611 if (layer && layer->isLayerEditable()) {
Chris@17 612 layer->drawDrag(e);
Chris@17 613 }
Chris@18 614
Chris@18 615 } else if (mode == ViewManager::EditMode) {
Chris@18 616
Chris@18 617 Layer *layer = getSelectedLayer();
Chris@23 618 if (layer && layer->isLayerEditable()) {
Chris@18 619 layer->editDrag(e);
Chris@18 620 }
Chris@0 621 }
Chris@0 622 }
Chris@0 623
Chris@0 624 void
Chris@0 625 Pane::mouseDoubleClickEvent(QMouseEvent *e)
Chris@0 626 {
Chris@0 627 std::cerr << "mouseDoubleClickEvent" << std::endl;
Chris@0 628 }
Chris@0 629
Chris@0 630 void
Chris@0 631 Pane::leaveEvent(QEvent *)
Chris@0 632 {
Chris@0 633 bool previouslyIdentifying = m_identifyFeatures;
Chris@0 634 m_identifyFeatures = false;
Chris@0 635 if (previouslyIdentifying) update();
Chris@0 636 }
Chris@0 637
Chris@0 638 void
Chris@0 639 Pane::wheelEvent(QWheelEvent *e)
Chris@0 640 {
Chris@0 641 //std::cerr << "wheelEvent, delta " << e->delta() << std::endl;
Chris@0 642
Chris@0 643 int count = e->delta();
Chris@0 644
Chris@0 645 if (count > 0) {
Chris@0 646 if (count >= 120) count /= 120;
Chris@0 647 else count = 1;
Chris@0 648 }
Chris@0 649
Chris@0 650 if (count < 0) {
Chris@0 651 if (count <= -120) count /= 120;
Chris@0 652 else count = -1;
Chris@0 653 }
Chris@17 654
Chris@17 655 if (e->modifiers() & Qt::ControlModifier) {
Chris@17 656
Chris@20 657 // Scroll left or right, rapidly
Chris@20 658
Chris@17 659 if (getStartFrame() < 0 &&
Chris@17 660 getEndFrame() >= getModelsEndFrame()) return;
Chris@17 661
Chris@17 662 long delta = ((width() / 2) * count * m_zoomLevel);
Chris@17 663
Chris@17 664 if (int(m_centreFrame) < delta) {
Chris@17 665 setCentreFrame(0);
Chris@17 666 } else if (int(m_centreFrame) - delta >= int(getModelsEndFrame())) {
Chris@17 667 setCentreFrame(getModelsEndFrame());
Chris@17 668 } else {
Chris@17 669 setCentreFrame(m_centreFrame - delta);
Chris@17 670 }
Chris@17 671
Chris@17 672 } else {
Chris@17 673
Chris@20 674 // Zoom in or out
Chris@20 675
Chris@17 676 int newZoomLevel = m_zoomLevel;
Chris@0 677
Chris@17 678 while (count > 0) {
Chris@17 679 if (newZoomLevel <= 2) {
Chris@17 680 newZoomLevel = 1;
Chris@17 681 break;
Chris@17 682 }
Chris@17 683 newZoomLevel = getZoomConstraintBlockSize(newZoomLevel - 1,
Chris@17 684 ZoomConstraint::RoundDown);
Chris@17 685 --count;
Chris@0 686 }
Chris@17 687
Chris@17 688 while (count < 0) {
Chris@17 689 newZoomLevel = getZoomConstraintBlockSize(newZoomLevel + 1,
Chris@17 690 ZoomConstraint::RoundUp);
Chris@17 691 ++count;
Chris@17 692 }
Chris@17 693
Chris@17 694 if (newZoomLevel != m_zoomLevel) {
Chris@17 695 setZoomLevel(newZoomLevel);
Chris@17 696 }
Chris@0 697 }
Chris@0 698
Chris@0 699 emit paneInteractedWith();
Chris@0 700 }
Chris@8 701
Chris@13 702 void
Chris@13 703 Pane::toolModeChanged()
Chris@13 704 {
Chris@13 705 ViewManager::ToolMode mode = m_manager->getToolMode();
Chris@13 706 std::cerr << "Pane::toolModeChanged(" << mode << ")" << std::endl;
Chris@13 707
Chris@13 708 switch (mode) {
Chris@13 709
Chris@13 710 case ViewManager::NavigateMode:
Chris@13 711 setCursor(Qt::PointingHandCursor);
Chris@13 712 break;
Chris@13 713
Chris@13 714 case ViewManager::SelectMode:
Chris@13 715 setCursor(Qt::ArrowCursor);
Chris@13 716 break;
Chris@13 717
Chris@13 718 case ViewManager::EditMode:
Chris@19 719 setCursor(Qt::UpArrowCursor);
Chris@13 720 break;
Chris@13 721
Chris@13 722 case ViewManager::DrawMode:
Chris@13 723 setCursor(Qt::CrossCursor);
Chris@13 724 break;
Chris@13 725
Chris@13 726 case ViewManager::TextMode:
Chris@13 727 setCursor(Qt::IBeamCursor);
Chris@13 728 break;
Chris@13 729 }
Chris@13 730 }
Chris@13 731
Chris@8 732 QString
Chris@8 733 Pane::toXmlString(QString indent, QString extraAttributes) const
Chris@8 734 {
Chris@8 735 return View::toXmlString
Chris@8 736 (indent,
Chris@8 737 QString("type=\"pane\" centreLineVisible=\"%1\" %2")
Chris@8 738 .arg(m_centreLineVisible).arg(extraAttributes));
Chris@8 739 }
Chris@8 740
Chris@0 741
Chris@0 742 #ifdef INCLUDE_MOCFILES
Chris@0 743 #include "Pane.moc.cpp"
Chris@0 744 #endif
Chris@0 745