Mercurial > hg > svgui
comparison widgets/Pane.cpp @ 17:0183ebb725ca
* Add ability to create empty layers for editing
* Add first basic editing capability (adding points to a time instant layer)
* Add various keyboard and mouse shortcuts for navigation &c
* Add ability to resize a selection by dragging its edges
* Add maximum zoom level
author | Chris Cannam |
---|---|
date | Thu, 26 Jan 2006 16:15:40 +0000 |
parents | 4d5d9aba406b |
children | 7c767d41bcee |
comparison
equal
deleted
inserted
replaced
16:02a718909b2d | 17:0183ebb725ca |
---|---|
27 View(w, true), | 27 View(w, true), |
28 m_identifyFeatures(false), | 28 m_identifyFeatures(false), |
29 m_clickedInRange(false), | 29 m_clickedInRange(false), |
30 m_shiftPressed(false), | 30 m_shiftPressed(false), |
31 m_ctrlPressed(false), | 31 m_ctrlPressed(false), |
32 m_navigating(false), | |
33 m_resizing(false), | |
32 m_centreLineVisible(true) | 34 m_centreLineVisible(true) |
33 { | 35 { |
34 setObjectName("Pane"); | 36 setObjectName("Pane"); |
35 setMouseTracking(true); | 37 setMouseTracking(true); |
36 } | 38 } |
234 } | 236 } |
235 | 237 |
236 paint.end(); | 238 paint.end(); |
237 } | 239 } |
238 | 240 |
241 Selection | |
242 Pane::getSelectionAt(int x, bool &closeToLeftEdge, bool &closeToRightEdge) | |
243 { | |
244 closeToLeftEdge = closeToRightEdge = false; | |
245 | |
246 if (!m_manager) return Selection(); | |
247 | |
248 long testFrame = (x - 5) * m_zoomLevel + getStartFrame(); | |
249 if (testFrame < 0) { | |
250 testFrame = x * m_zoomLevel + getStartFrame(); | |
251 if (testFrame < 0) return Selection(); | |
252 } | |
253 | |
254 Selection selection = m_manager->getContainingSelection(testFrame, true); | |
255 if (selection.isEmpty()) return selection; | |
256 | |
257 int lx = (int(selection.getStartFrame()) - getStartFrame()) / m_zoomLevel; | |
258 int rx = (int(selection.getEndFrame()) - getStartFrame()) / m_zoomLevel; | |
259 | |
260 int fuzz = 2; | |
261 if (x < lx - fuzz || x > rx + fuzz) return Selection(); | |
262 | |
263 int width = rx - lx; | |
264 fuzz = 3; | |
265 if (width < 12) fuzz = width / 4; | |
266 if (fuzz < 1) fuzz = 1; | |
267 | |
268 if (x < lx + fuzz) closeToLeftEdge = true; | |
269 if (x > rx - fuzz) closeToRightEdge = true; | |
270 | |
271 return selection; | |
272 } | |
273 | |
239 void | 274 void |
240 Pane::mousePressEvent(QMouseEvent *e) | 275 Pane::mousePressEvent(QMouseEvent *e) |
241 { | 276 { |
242 m_clickPos = e->pos(); | 277 m_clickPos = e->pos(); |
243 m_clickedInRange = true; | 278 m_clickedInRange = true; |
245 m_ctrlPressed = (e->modifiers() & Qt::ControlModifier); | 280 m_ctrlPressed = (e->modifiers() & Qt::ControlModifier); |
246 | 281 |
247 ViewManager::ToolMode mode = ViewManager::NavigateMode; | 282 ViewManager::ToolMode mode = ViewManager::NavigateMode; |
248 if (m_manager) mode = m_manager->getToolMode(); | 283 if (m_manager) mode = m_manager->getToolMode(); |
249 | 284 |
250 if (mode == ViewManager::NavigateMode) { | 285 m_navigating = false; |
251 | 286 |
287 if (mode == ViewManager::NavigateMode || (e->buttons() & Qt::MidButton)) { | |
288 | |
289 if (mode != ViewManager::NavigateMode) { | |
290 setCursor(Qt::PointingHandCursor); | |
291 } | |
292 | |
293 m_navigating = true; | |
252 m_dragCentreFrame = m_centreFrame; | 294 m_dragCentreFrame = m_centreFrame; |
253 | 295 |
254 } else if (mode == ViewManager::SelectMode) { | 296 } else if (mode == ViewManager::SelectMode) { |
255 | 297 |
256 int mouseFrame = e->x() * m_zoomLevel + getStartFrame(); | 298 bool closeToLeft = false, closeToRight = false; |
257 size_t resolution = 1; | 299 Selection selection = getSelectionAt(e->x(), closeToLeft, closeToRight); |
258 int snapFrame = mouseFrame; | 300 |
259 | 301 if ((closeToLeft || closeToRight) && !(closeToLeft && closeToRight)) { |
302 | |
303 m_manager->removeSelection(selection); | |
304 | |
305 if (closeToLeft) { | |
306 m_selectionStartFrame = selection.getEndFrame(); | |
307 } else { | |
308 m_selectionStartFrame = selection.getStartFrame(); | |
309 } | |
310 | |
311 m_manager->setInProgressSelection(selection, false); | |
312 m_resizing = true; | |
313 | |
314 } else { | |
315 | |
316 int mouseFrame = e->x() * m_zoomLevel + getStartFrame(); | |
317 size_t resolution = 1; | |
318 int snapFrame = mouseFrame; | |
319 | |
320 Layer *layer = getSelectedLayer(); | |
321 if (layer) { | |
322 snapFrame = layer->getNearestFeatureFrame(mouseFrame, resolution, | |
323 false); | |
324 } | |
325 | |
326 if (snapFrame < 0) snapFrame = 0; | |
327 m_selectionStartFrame = snapFrame; | |
328 if (m_manager) { | |
329 m_manager->setInProgressSelection(Selection(snapFrame, | |
330 snapFrame + resolution), | |
331 !m_ctrlPressed); | |
332 } | |
333 | |
334 m_resizing = false; | |
335 } | |
336 | |
337 update(); | |
338 | |
339 } else if (mode == ViewManager::DrawMode) { | |
340 | |
260 Layer *layer = getSelectedLayer(); | 341 Layer *layer = getSelectedLayer(); |
261 if (layer) { | 342 if (layer) { |
262 snapFrame = layer->getNearestFeatureFrame(mouseFrame, resolution, | 343 layer->drawStart(e); |
263 false); | 344 } |
264 } | |
265 | |
266 if (snapFrame < 0) snapFrame = 0; | |
267 m_selectionStartFrame = snapFrame; | |
268 if (m_manager) { | |
269 m_manager->setInProgressSelection(Selection(snapFrame, | |
270 snapFrame + resolution), | |
271 !m_ctrlPressed); | |
272 } | |
273 update(); | |
274 } | 345 } |
275 | 346 |
276 emit paneInteractedWith(); | 347 emit paneInteractedWith(); |
277 } | 348 } |
278 | 349 |
284 | 355 |
285 if (m_clickedInRange) { | 356 if (m_clickedInRange) { |
286 mouseMoveEvent(e); | 357 mouseMoveEvent(e); |
287 } | 358 } |
288 | 359 |
289 if (mode == ViewManager::NavigateMode) { | 360 if (m_navigating || mode == ViewManager::NavigateMode) { |
361 | |
362 m_navigating = false; | |
363 | |
364 if (mode != ViewManager::NavigateMode) { | |
365 // restore cursor | |
366 toolModeChanged(); | |
367 } | |
290 | 368 |
291 if (m_shiftPressed) { | 369 if (m_shiftPressed) { |
292 | 370 |
293 int x0 = std::min(m_clickPos.x(), m_mousePos.x()); | 371 int x0 = std::min(m_clickPos.x(), m_mousePos.x()); |
294 int x1 = std::max(m_clickPos.x(), m_mousePos.x()); | 372 int x1 = std::max(m_clickPos.x(), m_mousePos.x()); |
336 m_manager->addSelection(selection); | 414 m_manager->addSelection(selection); |
337 } | 415 } |
338 } | 416 } |
339 | 417 |
340 update(); | 418 update(); |
341 } | 419 |
420 } else if (mode == ViewManager::DrawMode) { | |
421 | |
422 Layer *layer = getSelectedLayer(); | |
423 if (layer) { | |
424 layer->drawEnd(e); | |
425 update(); | |
426 } | |
427 } | |
342 | 428 |
343 m_clickedInRange = false; | 429 m_clickedInRange = false; |
344 | 430 |
345 emit paneInteractedWith(); | 431 emit paneInteractedWith(); |
346 } | 432 } |
351 ViewManager::ToolMode mode = ViewManager::NavigateMode; | 437 ViewManager::ToolMode mode = ViewManager::NavigateMode; |
352 if (m_manager) mode = m_manager->getToolMode(); | 438 if (m_manager) mode = m_manager->getToolMode(); |
353 | 439 |
354 if (!m_clickedInRange) { | 440 if (!m_clickedInRange) { |
355 | 441 |
356 // std::cerr << "Pane: calling identifyLocalFeatures" << std::endl; | 442 if (mode == ViewManager::SelectMode) { |
357 | 443 bool closeToLeft = false, closeToRight = false; |
358 //!!! identifyLocalFeatures(true, e->x(), e->y()); | 444 getSelectionAt(e->x(), closeToLeft, closeToRight); |
359 | 445 if ((closeToLeft || closeToRight) && !(closeToLeft && closeToRight)) { |
360 bool previouslyIdentifying = m_identifyFeatures; | 446 setCursor(Qt::SizeHorCursor); |
361 QPoint prevPoint = m_identifyPoint; | 447 } else { |
362 | 448 setCursor(Qt::ArrowCursor); |
363 m_identifyFeatures = true; | 449 } |
364 m_identifyPoint = e->pos(); | 450 } |
365 | 451 |
366 if (m_identifyFeatures != previouslyIdentifying || | 452 if (mode != ViewManager::DrawMode) { |
367 m_identifyPoint != prevPoint) { | 453 |
368 update(); | 454 bool previouslyIdentifying = m_identifyFeatures; |
455 QPoint prevPoint = m_identifyPoint; | |
456 | |
457 m_identifyFeatures = true; | |
458 m_identifyPoint = e->pos(); | |
459 | |
460 if (m_identifyFeatures != previouslyIdentifying || | |
461 m_identifyPoint != prevPoint) { | |
462 update(); | |
463 } | |
369 } | 464 } |
370 | 465 |
371 return; | 466 return; |
372 | 467 } |
373 } | 468 |
374 | 469 if (m_navigating || mode == ViewManager::NavigateMode) { |
375 if (mode == ViewManager::NavigateMode) { | |
376 | 470 |
377 if (m_shiftPressed) { | 471 if (m_shiftPressed) { |
378 | 472 |
379 m_mousePos = e->pos(); | 473 m_mousePos = e->pos(); |
380 update(); | 474 update(); |
436 max = snapFrameRight; | 530 max = snapFrameRight; |
437 } | 531 } |
438 | 532 |
439 if (m_manager) { | 533 if (m_manager) { |
440 m_manager->setInProgressSelection(Selection(min, max), | 534 m_manager->setInProgressSelection(Selection(min, max), |
441 !m_ctrlPressed); | 535 !m_resizing && !m_ctrlPressed); |
442 } | 536 } |
443 | 537 |
444 bool doScroll = false; | 538 bool doScroll = false; |
445 if (!m_manager) doScroll = true; | 539 if (!m_manager) doScroll = true; |
446 if (!m_manager->isPlaying()) doScroll = true; | 540 if (!m_manager->isPlaying()) doScroll = true; |
461 } | 555 } |
462 } | 556 } |
463 } | 557 } |
464 | 558 |
465 update(); | 559 update(); |
560 | |
561 } else if (mode == ViewManager::DrawMode) { | |
562 | |
563 Layer *layer = getSelectedLayer(); | |
564 if (layer) { | |
565 layer->drawDrag(e); | |
566 } | |
466 } | 567 } |
467 } | 568 } |
468 | 569 |
469 void | 570 void |
470 Pane::mouseDoubleClickEvent(QMouseEvent *e) | 571 Pane::mouseDoubleClickEvent(QMouseEvent *e) |
482 | 583 |
483 void | 584 void |
484 Pane::wheelEvent(QWheelEvent *e) | 585 Pane::wheelEvent(QWheelEvent *e) |
485 { | 586 { |
486 //std::cerr << "wheelEvent, delta " << e->delta() << std::endl; | 587 //std::cerr << "wheelEvent, delta " << e->delta() << std::endl; |
487 | |
488 int newZoomLevel = m_zoomLevel; | |
489 | 588 |
490 int count = e->delta(); | 589 int count = e->delta(); |
491 | 590 |
492 if (count > 0) { | 591 if (count > 0) { |
493 if (count >= 120) count /= 120; | 592 if (count >= 120) count /= 120; |
496 | 595 |
497 if (count < 0) { | 596 if (count < 0) { |
498 if (count <= -120) count /= 120; | 597 if (count <= -120) count /= 120; |
499 else count = -1; | 598 else count = -1; |
500 } | 599 } |
600 | |
601 if (e->modifiers() & Qt::ControlModifier) { | |
602 | |
603 if (getStartFrame() < 0 && | |
604 getEndFrame() >= getModelsEndFrame()) return; | |
605 | |
606 long delta = ((width() / 2) * count * m_zoomLevel); | |
607 | |
608 if (int(m_centreFrame) < delta) { | |
609 setCentreFrame(0); | |
610 } else if (int(m_centreFrame) - delta >= int(getModelsEndFrame())) { | |
611 setCentreFrame(getModelsEndFrame()); | |
612 } else { | |
613 setCentreFrame(m_centreFrame - delta); | |
614 } | |
615 | |
616 } else { | |
617 | |
618 int newZoomLevel = m_zoomLevel; | |
501 | 619 |
502 while (count > 0) { | 620 while (count > 0) { |
503 if (newZoomLevel <= 2) { | 621 if (newZoomLevel <= 2) { |
504 newZoomLevel = 1; | 622 newZoomLevel = 1; |
505 break; | 623 break; |
506 } | 624 } |
507 newZoomLevel = getZoomConstraintBlockSize(newZoomLevel - 1, | 625 newZoomLevel = getZoomConstraintBlockSize(newZoomLevel - 1, |
508 ZoomConstraint::RoundDown); | 626 ZoomConstraint::RoundDown); |
509 --count; | 627 --count; |
510 } | 628 } |
511 | 629 |
512 while (count < 0) { | 630 while (count < 0) { |
513 newZoomLevel = getZoomConstraintBlockSize(newZoomLevel + 1, | 631 newZoomLevel = getZoomConstraintBlockSize(newZoomLevel + 1, |
514 ZoomConstraint::RoundUp); | 632 ZoomConstraint::RoundUp); |
515 ++count; | 633 ++count; |
516 } | 634 } |
517 | 635 |
518 if (newZoomLevel != m_zoomLevel) { | 636 if (newZoomLevel != m_zoomLevel) { |
519 setZoomLevel(newZoomLevel); | 637 setZoomLevel(newZoomLevel); |
638 } | |
520 } | 639 } |
521 | 640 |
522 emit paneInteractedWith(); | 641 emit paneInteractedWith(); |
523 } | 642 } |
524 | 643 |