Mercurial > hg > svgui
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, |