comparison widgets/Pane.cpp @ 13:01849cd277e6

* Hook up tool selection buttons to switch the cursor mode * Implement simple and multi-selection, snapping to the resolution of the current layer. You can't actually do anything with a selection yet
author Chris Cannam
date Mon, 23 Jan 2006 17:02:57 +0000
parents 06bba0b79b1c
children aa37f84ab70a
comparison
equal deleted inserted replaced
12:484e7320f59f 13:01849cd277e6
11 #include "base/Layer.h" 11 #include "base/Layer.h"
12 #include "base/Model.h" 12 #include "base/Model.h"
13 #include "base/ZoomConstraint.h" 13 #include "base/ZoomConstraint.h"
14 #include "base/RealTime.h" 14 #include "base/RealTime.h"
15 #include "base/Profiler.h" 15 #include "base/Profiler.h"
16 #include "base/ViewManager.h"
16 17
17 #include <QPaintEvent> 18 #include <QPaintEvent>
18 #include <QPainter> 19 #include <QPainter>
19 #include <iostream> 20 #include <iostream>
20 #include <cmath> 21 #include <cmath>
25 Pane::Pane(QWidget *w) : 26 Pane::Pane(QWidget *w) :
26 View(w, true), 27 View(w, true),
27 m_identifyFeatures(false), 28 m_identifyFeatures(false),
28 m_clickedInRange(false), 29 m_clickedInRange(false),
29 m_shiftPressed(false), 30 m_shiftPressed(false),
31 m_ctrlPressed(false),
30 m_centreLineVisible(true) 32 m_centreLineVisible(true)
31 { 33 {
32 setObjectName("Pane"); 34 setObjectName("Pane");
33 setMouseTracking(true); 35 setMouseTracking(true);
34 } 36 }
221 } 223 }
222 paint.drawText(x, y, text); 224 paint.drawText(x, y, text);
223 } 225 }
224 226
225 if (m_clickedInRange && m_shiftPressed) { 227 if (m_clickedInRange && m_shiftPressed) {
228 //!!! be nice if this looked a bit more in keeping with the
229 //selection block
226 paint.setPen(Qt::blue); 230 paint.setPen(Qt::blue);
227 paint.drawRect(m_clickPos.x(), m_clickPos.y(), 231 paint.drawRect(m_clickPos.x(), m_clickPos.y(),
228 m_mousePos.x() - m_clickPos.x(), 232 m_mousePos.x() - m_clickPos.x(),
229 m_mousePos.y() - m_clickPos.y()); 233 m_mousePos.y() - m_clickPos.y());
230 } 234 }
236 Pane::mousePressEvent(QMouseEvent *e) 240 Pane::mousePressEvent(QMouseEvent *e)
237 { 241 {
238 m_clickPos = e->pos(); 242 m_clickPos = e->pos();
239 m_clickedInRange = true; 243 m_clickedInRange = true;
240 m_shiftPressed = (e->modifiers() & Qt::ShiftModifier); 244 m_shiftPressed = (e->modifiers() & Qt::ShiftModifier);
241 m_dragCentreFrame = m_centreFrame; 245 m_ctrlPressed = (e->modifiers() & Qt::ControlModifier);
246
247 ViewManager::ToolMode mode = ViewManager::NavigateMode;
248 if (m_manager) mode = m_manager->getToolMode();
249
250 if (mode == ViewManager::NavigateMode) {
251
252 m_dragCentreFrame = m_centreFrame;
253
254 } else if (mode == ViewManager::SelectMode) {
255
256 int mouseFrame = e->x() * m_zoomLevel + getStartFrame();
257 size_t resolution = 1;
258 int snapFrame = mouseFrame;
259
260 Layer *layer = getSelectedLayer();
261 if (layer) {
262 snapFrame = layer->getNearestFeatureFrame(mouseFrame, resolution,
263 false);
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 }
242 275
243 emit paneInteractedWith(); 276 emit paneInteractedWith();
244 } 277 }
245 278
246 void 279 void
247 Pane::mouseReleaseEvent(QMouseEvent *e) 280 Pane::mouseReleaseEvent(QMouseEvent *e)
248 { 281 {
282 ViewManager::ToolMode mode = ViewManager::NavigateMode;
283 if (m_manager) mode = m_manager->getToolMode();
284
249 if (m_clickedInRange) { 285 if (m_clickedInRange) {
250 mouseMoveEvent(e); 286 mouseMoveEvent(e);
251 } 287 }
252 if (m_shiftPressed) { 288
253 289 if (mode == ViewManager::NavigateMode) {
254 int x0 = std::min(m_clickPos.x(), m_mousePos.x()); 290
255 int x1 = std::max(m_clickPos.x(), m_mousePos.x()); 291 if (m_shiftPressed) {
256 int w = x1 - x0; 292
257 293 int x0 = std::min(m_clickPos.x(), m_mousePos.x());
258 long newStartFrame = getStartFrame() + m_zoomLevel * x0; 294 int x1 = std::max(m_clickPos.x(), m_mousePos.x());
259 295 int w = x1 - x0;
260 if (newStartFrame <= -long(width() * m_zoomLevel)) { 296
261 newStartFrame = -long(width() * m_zoomLevel) + 1; 297 long newStartFrame = getStartFrame() + m_zoomLevel * x0;
262 } 298
263 299 if (newStartFrame <= -long(width() * m_zoomLevel)) {
264 if (newStartFrame >= long(getModelsEndFrame())) { 300 newStartFrame = -long(width() * m_zoomLevel) + 1;
265 newStartFrame = getModelsEndFrame() - 1; 301 }
266 } 302
267 303 if (newStartFrame >= long(getModelsEndFrame())) {
268 float ratio = float(w) / float(width()); 304 newStartFrame = getModelsEndFrame() - 1;
305 }
306
307 float ratio = float(w) / float(width());
269 // std::cerr << "ratio: " << ratio << std::endl; 308 // std::cerr << "ratio: " << ratio << std::endl;
270 size_t newZoomLevel = (size_t)nearbyint(m_zoomLevel * ratio); 309 size_t newZoomLevel = (size_t)nearbyint(m_zoomLevel * ratio);
271 if (newZoomLevel < 1) newZoomLevel = 1; 310 if (newZoomLevel < 1) newZoomLevel = 1;
272 311
273 // std::cerr << "start: " << m_startFrame << ", level " << m_zoomLevel << std::endl; 312 // std::cerr << "start: " << m_startFrame << ", level " << m_zoomLevel << std::endl;
274 setZoomLevel(getZoomConstraintBlockSize(newZoomLevel)); 313 setZoomLevel(getZoomConstraintBlockSize(newZoomLevel));
275 setStartFrame(newStartFrame); 314 setStartFrame(newStartFrame);
276 315
277 //cerr << "mouseReleaseEvent: start frame now " << m_startFrame << endl; 316 //cerr << "mouseReleaseEvent: start frame now " << m_startFrame << endl;
278 // update(); 317 // update();
279 } 318 }
319
320 } else if (mode == ViewManager::SelectMode) {
321
322 if (m_manager && m_manager->haveInProgressSelection()) {
323
324 bool exclusive;
325 Selection selection = m_manager->getInProgressSelection(exclusive);
326
327 if (selection.getEndFrame() < selection.getStartFrame() + 2) {
328 selection = Selection();
329 }
330
331 m_manager->clearInProgressSelection();
332
333 if (exclusive) {
334 m_manager->setSelection(selection);
335 } else {
336 m_manager->addSelection(selection);
337 }
338 }
339
340 update();
341 }
342
280 m_clickedInRange = false; 343 m_clickedInRange = false;
281 344
282 emit paneInteractedWith(); 345 emit paneInteractedWith();
283 } 346 }
284 347
285 void 348 void
286 Pane::mouseMoveEvent(QMouseEvent *e) 349 Pane::mouseMoveEvent(QMouseEvent *e)
287 { 350 {
351 ViewManager::ToolMode mode = ViewManager::NavigateMode;
352 if (m_manager) mode = m_manager->getToolMode();
353
288 if (!m_clickedInRange) { 354 if (!m_clickedInRange) {
289 355
290 // std::cerr << "Pane: calling identifyLocalFeatures" << std::endl; 356 // std::cerr << "Pane: calling identifyLocalFeatures" << std::endl;
291 357
292 //!!! identifyLocalFeatures(true, e->x(), e->y()); 358 //!!! identifyLocalFeatures(true, e->x(), e->y());
300 if (m_identifyFeatures != previouslyIdentifying || 366 if (m_identifyFeatures != previouslyIdentifying ||
301 m_identifyPoint != prevPoint) { 367 m_identifyPoint != prevPoint) {
302 update(); 368 update();
303 } 369 }
304 370
305 } else if (m_shiftPressed) { 371 return;
306 372
307 m_mousePos = e->pos(); 373 }
374
375 if (mode == ViewManager::NavigateMode) {
376
377 if (m_shiftPressed) {
378
379 m_mousePos = e->pos();
380 update();
381
382 } else {
383
384 long xoff = int(e->x()) - int(m_clickPos.x());
385 long frameOff = xoff * m_zoomLevel;
386
387 size_t newCentreFrame = m_dragCentreFrame;
388
389 if (frameOff < 0) {
390 newCentreFrame -= frameOff;
391 } else if (newCentreFrame >= size_t(frameOff)) {
392 newCentreFrame -= frameOff;
393 } else {
394 newCentreFrame = 0;
395 }
396
397 if (newCentreFrame >= getModelsEndFrame()) {
398 newCentreFrame = getModelsEndFrame();
399 if (newCentreFrame > 0) --newCentreFrame;
400 }
401
402 if (std::max(m_centreFrame, newCentreFrame) -
403 std::min(m_centreFrame, newCentreFrame) > size_t(m_zoomLevel)) {
404 setCentreFrame(newCentreFrame);
405 }
406 }
407
408 } else if (mode == ViewManager::SelectMode) {
409
410 int mouseFrame = e->x() * m_zoomLevel + getStartFrame();
411 size_t resolution = 1;
412 int snapFrameLeft = mouseFrame;
413 int snapFrameRight = mouseFrame;
414
415 Layer *layer = getSelectedLayer();
416 if (layer) {
417 snapFrameLeft = layer->getNearestFeatureFrame(mouseFrame, resolution,
418 false);
419 snapFrameRight = layer->getNearestFeatureFrame(mouseFrame, resolution,
420 true);
421 }
422
423 if (snapFrameLeft < 0) snapFrameLeft = 0;
424 if (snapFrameRight < 0) snapFrameRight = 0;
425
426 size_t min, max;
427
428 if (m_selectionStartFrame > snapFrameLeft) {
429 min = snapFrameLeft;
430 max = m_selectionStartFrame;
431 } else if (snapFrameRight > m_selectionStartFrame) {
432 min = m_selectionStartFrame;
433 max = snapFrameRight;
434 } else {
435 min = snapFrameLeft;
436 max = snapFrameRight;
437 }
438
439 if (m_manager) {
440 m_manager->setInProgressSelection(Selection(min, max),
441 !m_ctrlPressed);
442 }
443
444 if (!m_manager || !m_manager->isPlaying()) {
445 int offset = mouseFrame - getStartFrame();
446 int available = getEndFrame() - getStartFrame();
447 if (offset >= available * 0.9) {
448 setCentreFrame(m_centreFrame + int(offset - available * 0.9) + 1);
449 } else if (offset <= available * 0.15) {
450 setCentreFrame(m_centreFrame - int(available * 0.15 - offset) - 1);
451 }
452 }
453
308 update(); 454 update();
309
310 } else {
311
312 long xoff = int(e->x()) - int(m_clickPos.x());
313 long frameOff = xoff * m_zoomLevel;
314
315 size_t newCentreFrame = m_dragCentreFrame;
316
317 if (frameOff < 0) {
318 newCentreFrame -= frameOff;
319 } else if (newCentreFrame >= size_t(frameOff)) {
320 newCentreFrame -= frameOff;
321 } else {
322 newCentreFrame = 0;
323 }
324
325 if (newCentreFrame >= getModelsEndFrame()) {
326 newCentreFrame = getModelsEndFrame();
327 if (newCentreFrame > 0) --newCentreFrame;
328 }
329
330 if (std::max(m_centreFrame, newCentreFrame) -
331 std::min(m_centreFrame, newCentreFrame) > size_t(m_zoomLevel)) {
332 setCentreFrame(newCentreFrame);
333 }
334 } 455 }
335 } 456 }
336 457
337 void 458 void
338 Pane::mouseDoubleClickEvent(QMouseEvent *e) 459 Pane::mouseDoubleClickEvent(QMouseEvent *e)
388 } 509 }
389 510
390 emit paneInteractedWith(); 511 emit paneInteractedWith();
391 } 512 }
392 513
514 void
515 Pane::toolModeChanged()
516 {
517 ViewManager::ToolMode mode = m_manager->getToolMode();
518 std::cerr << "Pane::toolModeChanged(" << mode << ")" << std::endl;
519
520 switch (mode) {
521
522 case ViewManager::NavigateMode:
523 setCursor(Qt::PointingHandCursor);
524 break;
525
526 case ViewManager::SelectMode:
527 setCursor(Qt::ArrowCursor);
528 break;
529
530 case ViewManager::EditMode:
531 setCursor(Qt::SizeAllCursor);
532 break;
533
534 case ViewManager::DrawMode:
535 setCursor(Qt::CrossCursor);
536 break;
537
538 case ViewManager::TextMode:
539 setCursor(Qt::IBeamCursor);
540 break;
541 }
542 }
543
393 QString 544 QString
394 Pane::toXmlString(QString indent, QString extraAttributes) const 545 Pane::toXmlString(QString indent, QString extraAttributes) const
395 { 546 {
396 return View::toXmlString 547 return View::toXmlString
397 (indent, 548 (indent,