annotate view/ViewManager.cpp @ 1534:bfd8b22fd67c

Fix #1904 Scrolling colour 3d plot does not always work when in View normalisation mode. We shouldn't imagine we've just invalidated the cache if the truth is that we've only just created the renderer
author Chris Cannam
date Wed, 09 Oct 2019 13:45:17 +0100
parents 9bf8aa2916e9
children 4e466690bf20
rev   line source
Chris@127 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@127 2
Chris@127 3 /*
Chris@127 4 Sonic Visualiser
Chris@127 5 An audio file viewer and annotation editor.
Chris@127 6 Centre for Digital Music, Queen Mary, University of London.
Chris@182 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@127 8
Chris@127 9 This program is free software; you can redistribute it and/or
Chris@127 10 modify it under the terms of the GNU General Public License as
Chris@127 11 published by the Free Software Foundation; either version 2 of the
Chris@127 12 License, or (at your option) any later version. See the file
Chris@127 13 COPYING included with this distribution for more information.
Chris@127 14 */
Chris@127 15
Chris@127 16 #include "ViewManager.h"
Chris@128 17 #include "base/AudioPlaySource.h"
Chris@1210 18 #include "base/AudioRecordTarget.h"
Chris@502 19 #include "base/RealTime.h"
Chris@128 20 #include "data/model/Model.h"
Chris@376 21 #include "widgets/CommandHistory.h"
Chris@211 22 #include "View.h"
Chris@503 23 #include "Overview.h"
Chris@127 24
Chris@133 25 #include <QSettings>
Chris@292 26 #include <QApplication>
Chris@133 27
Chris@127 28 #include <iostream>
Chris@127 29
Chris@643 30 //#define DEBUG_VIEW_MANAGER 1
Chris@127 31
Chris@127 32 ViewManager::ViewManager() :
Chris@1408 33 m_playSource(nullptr),
Chris@1408 34 m_recordTarget(nullptr),
Chris@127 35 m_globalCentreFrame(0),
Chris@1327 36 m_globalZoom(ZoomLevel::FramesPerPixel, 1024),
Chris@127 37 m_playbackFrame(0),
Chris@127 38 m_mainModelSampleRate(0),
Chris@127 39 m_lastLeft(0),
Chris@127 40 m_lastRight(0),
Chris@127 41 m_inProgressExclusive(true),
Chris@127 42 m_toolMode(NavigateMode),
Chris@127 43 m_playLoopMode(false),
Chris@127 44 m_playSelectionMode(false),
Chris@301 45 m_playSoloMode(false),
Chris@314 46 m_alignMode(false),
Chris@741 47 m_overlayMode(StandardOverlays),
Chris@292 48 m_zoomWheelsEnabled(true),
Chris@1468 49 m_opportunisticEditingEnabled(true),
Chris@607 50 m_showCentreLine(true),
Chris@326 51 m_illuminateLocalFeatures(true),
Chris@326 52 m_showWorkTitle(false),
matthiasm@822 53 m_showDuration(true),
Chris@292 54 m_lightPalette(QApplication::palette()),
Chris@292 55 m_darkPalette(QApplication::palette())
Chris@127 56 {
Chris@133 57 QSettings settings;
Chris@133 58 settings.beginGroup("MainWindow");
Chris@133 59 m_overlayMode = OverlayMode
Chris@133 60 (settings.value("overlay-mode", int(m_overlayMode)).toInt());
Chris@607 61
Chris@607 62 if (m_overlayMode != NoOverlays &&
Chris@741 63 m_overlayMode != StandardOverlays &&
Chris@607 64 m_overlayMode != AllOverlays) {
Chris@741 65 m_overlayMode = StandardOverlays;
Chris@607 66 }
Chris@607 67
Chris@133 68 m_zoomWheelsEnabled =
Chris@133 69 settings.value("zoom-wheels-enabled", m_zoomWheelsEnabled).toBool();
Chris@607 70 m_showCentreLine =
Chris@607 71 settings.value("show-centre-line", m_showCentreLine).toBool();
Chris@133 72 settings.endGroup();
Chris@292 73
Chris@292 74 if (getGlobalDarkBackground()) {
Chris@343 75 /*
Chris@682 76 cerr << "dark palette:" << endl;
Chris@682 77 cerr << "window = " << QApplication::palette().color(QPalette::Window).name() << endl;
Chris@682 78 cerr << "windowtext = " << QApplication::palette().color(QPalette::WindowText).name() << endl;
Chris@682 79 cerr << "base = " << QApplication::palette().color(QPalette::Base).name() << endl;
Chris@682 80 cerr << "alternatebase = " << QApplication::palette().color(QPalette::AlternateBase).name() << endl;
Chris@682 81 cerr << "text = " << QApplication::palette().color(QPalette::Text).name() << endl;
Chris@682 82 cerr << "button = " << QApplication::palette().color(QPalette::Button).name() << endl;
Chris@682 83 cerr << "buttontext = " << QApplication::palette().color(QPalette::ButtonText).name() << endl;
Chris@682 84 cerr << "brighttext = " << QApplication::palette().color(QPalette::BrightText).name() << endl;
Chris@682 85 cerr << "light = " << QApplication::palette().color(QPalette::Light).name() << endl;
Chris@682 86 cerr << "dark = " << QApplication::palette().color(QPalette::Dark).name() << endl;
Chris@682 87 cerr << "mid = " << QApplication::palette().color(QPalette::Mid).name() << endl;
Chris@343 88 */
Chris@293 89 m_lightPalette = QPalette(QColor("#000000"), // WindowText
Chris@293 90 QColor("#dddfe4"), // Button
Chris@293 91 QColor("#ffffff"), // Light
Chris@293 92 QColor("#555555"), // Dark
Chris@293 93 QColor("#c7c7c7"), // Mid
Chris@293 94 QColor("#000000"), // Text
Chris@293 95 QColor("#ffffff"), // BrightText
Chris@293 96 QColor("#ffffff"), // Base
Chris@293 97 QColor("#efefef")); // Window
Chris@293 98
Chris@293 99
Chris@292 100 } else {
Chris@343 101 /*
Chris@682 102 cerr << "light palette:" << endl;
Chris@682 103 cerr << "window = " << QApplication::palette().color(QPalette::Window).name() << endl;
Chris@682 104 cerr << "windowtext = " << QApplication::palette().color(QPalette::WindowText).name() << endl;
Chris@682 105 cerr << "base = " << QApplication::palette().color(QPalette::Base).name() << endl;
Chris@682 106 cerr << "alternatebase = " << QApplication::palette().color(QPalette::AlternateBase).name() << endl;
Chris@682 107 cerr << "text = " << QApplication::palette().color(QPalette::Text).name() << endl;
Chris@682 108 cerr << "button = " << QApplication::palette().color(QPalette::Button).name() << endl;
Chris@682 109 cerr << "buttontext = " << QApplication::palette().color(QPalette::ButtonText).name() << endl;
Chris@682 110 cerr << "brighttext = " << QApplication::palette().color(QPalette::BrightText).name() << endl;
Chris@682 111 cerr << "light = " << QApplication::palette().color(QPalette::Light).name() << endl;
Chris@682 112 cerr << "dark = " << QApplication::palette().color(QPalette::Dark).name() << endl;
Chris@682 113 cerr << "mid = " << QApplication::palette().color(QPalette::Mid).name() << endl;
Chris@343 114 */
Chris@293 115 m_darkPalette = QPalette(QColor("#ffffff"), // WindowText
Chris@293 116 QColor("#3e3e3e"), // Button
Chris@293 117 QColor("#808080"), // Light
Chris@293 118 QColor("#1e1e1e"), // Dark
Chris@293 119 QColor("#404040"), // Mid
Chris@293 120 QColor("#ffffff"), // Text
Chris@293 121 QColor("#ffffff"), // BrightText
Chris@293 122 QColor("#000000"), // Base
Chris@293 123 QColor("#202020")); // Window
Chris@292 124 }
Chris@127 125 }
Chris@127 126
Chris@127 127 ViewManager::~ViewManager()
Chris@127 128 {
Chris@127 129 }
Chris@127 130
Chris@902 131 sv_frame_t
Chris@127 132 ViewManager::getGlobalCentreFrame() const
Chris@127 133 {
Chris@127 134 #ifdef DEBUG_VIEW_MANAGER
Chris@682 135 cerr << "ViewManager::getGlobalCentreFrame: returning " << m_globalCentreFrame << endl;
Chris@127 136 #endif
Chris@127 137 return m_globalCentreFrame;
Chris@127 138 }
Chris@127 139
Chris@180 140 void
Chris@902 141 ViewManager::setGlobalCentreFrame(sv_frame_t f)
Chris@180 142 {
Chris@180 143 #ifdef DEBUG_VIEW_MANAGER
Chris@682 144 cerr << "ViewManager::setGlobalCentreFrame to " << f << endl;
Chris@180 145 #endif
Chris@180 146 m_globalCentreFrame = f;
Chris@211 147 emit globalCentreFrameChanged(f);
Chris@180 148 }
Chris@180 149
Chris@1327 150 ZoomLevel
Chris@127 151 ViewManager::getGlobalZoom() const
Chris@127 152 {
Chris@127 153 #ifdef DEBUG_VIEW_MANAGER
Chris@682 154 cerr << "ViewManager::getGlobalZoom: returning " << m_globalZoom << endl;
Chris@127 155 #endif
Chris@127 156 return m_globalZoom;
Chris@127 157 }
Chris@127 158
Chris@902 159 sv_frame_t
Chris@127 160 ViewManager::getPlaybackFrame() const
Chris@127 161 {
Chris@1210 162 if (isRecording()) {
Chris@1210 163 m_playbackFrame = m_recordTarget->getRecordDuration();
Chris@1210 164 #ifdef DEBUG_VIEW_MANAGER
Chris@1210 165 cout << "ViewManager::getPlaybackFrame(recording) -> " << m_playbackFrame << endl;
Chris@1210 166 #endif
Chris@1210 167 } else if (isPlaying()) {
Chris@1266 168 m_playbackFrame = m_playSource->getCurrentPlayingFrame();
Chris@1185 169 #ifdef DEBUG_VIEW_MANAGER
Chris@1185 170 cout << "ViewManager::getPlaybackFrame(playing) -> " << m_playbackFrame << endl;
Chris@1185 171 #endif
Chris@1185 172 } else {
Chris@1185 173 #ifdef DEBUG_VIEW_MANAGER
Chris@1185 174 cout << "ViewManager::getPlaybackFrame(not playing) -> " << m_playbackFrame << endl;
Chris@1185 175 #endif
Chris@127 176 }
Chris@127 177 return m_playbackFrame;
Chris@127 178 }
Chris@127 179
Chris@127 180 void
Chris@902 181 ViewManager::setPlaybackFrame(sv_frame_t f)
Chris@127 182 {
Chris@1185 183 #ifdef DEBUG_VIEW_MANAGER
Chris@1185 184 cerr << "ViewManager::setPlaybackFrame(" << f << ")" << endl;
Chris@1185 185 #endif
Chris@968 186 if (f < 0) f = 0;
Chris@127 187 if (m_playbackFrame != f) {
Chris@1266 188 m_playbackFrame = f;
Chris@1266 189 emit playbackFrameChanged(f);
Chris@1266 190 if (isPlaying()) {
Chris@1266 191 m_playSource->play(f);
Chris@1266 192 }
Chris@127 193 }
Chris@127 194 }
Chris@127 195
Chris@1479 196 ModelId
Chris@301 197 ViewManager::getPlaybackModel() const
Chris@301 198 {
Chris@301 199 return m_playbackModel;
Chris@301 200 }
Chris@301 201
Chris@301 202 void
Chris@1479 203 ViewManager::setPlaybackModel(ModelId model)
Chris@301 204 {
Chris@301 205 m_playbackModel = model;
Chris@301 206 }
Chris@301 207
Chris@902 208 sv_frame_t
Chris@902 209 ViewManager::alignPlaybackFrameToReference(sv_frame_t frame) const
Chris@333 210 {
Chris@830 211 #ifdef DEBUG_VIEW_MANAGER
Chris@830 212 cerr << "ViewManager::alignPlaybackFrameToReference(" << frame << "): playback model is " << m_playbackModel << endl;
Chris@830 213 #endif
Chris@1479 214 if (m_playbackModel.isNone() || !m_alignMode) {
Chris@830 215 return frame;
Chris@830 216 } else {
Chris@1479 217 auto playbackModel = ModelById::get(m_playbackModel);
Chris@1479 218 if (!playbackModel) {
Chris@1479 219 return frame;
Chris@1479 220 }
Chris@1479 221 sv_frame_t f = playbackModel->alignToReference(frame);
Chris@830 222 #ifdef DEBUG_VIEW_MANAGER
Chris@830 223 cerr << "aligned frame = " << f << endl;
Chris@830 224 #endif
Chris@830 225 return f;
Chris@830 226 }
Chris@333 227 }
Chris@333 228
Chris@902 229 sv_frame_t
Chris@902 230 ViewManager::alignReferenceToPlaybackFrame(sv_frame_t frame) const
Chris@333 231 {
Chris@830 232 #ifdef DEBUG_VIEW_MANAGER
Chris@830 233 cerr << "ViewManager::alignReferenceToPlaybackFrame(" << frame << "): playback model is " << m_playbackModel << endl;
Chris@830 234 #endif
Chris@1479 235 if (m_playbackModel.isNone() || !m_alignMode) {
Chris@830 236 return frame;
Chris@830 237 } else {
Chris@1479 238 auto playbackModel = ModelById::get(m_playbackModel);
Chris@1479 239 if (!playbackModel) {
Chris@1479 240 return frame;
Chris@1479 241 }
Chris@1479 242 sv_frame_t f = playbackModel->alignFromReference(frame);
Chris@830 243 #ifdef DEBUG_VIEW_MANAGER
Chris@830 244 cerr << "aligned frame = " << f << endl;
Chris@830 245 #endif
Chris@830 246 return f;
Chris@830 247 }
Chris@333 248 }
Chris@333 249
Chris@127 250 bool
Chris@127 251 ViewManager::haveInProgressSelection() const
Chris@127 252 {
Chris@127 253 return !m_inProgressSelection.isEmpty();
Chris@127 254 }
Chris@127 255
Chris@127 256 const Selection &
Chris@127 257 ViewManager::getInProgressSelection(bool &exclusive) const
Chris@127 258 {
Chris@127 259 exclusive = m_inProgressExclusive;
Chris@127 260 return m_inProgressSelection;
Chris@127 261 }
Chris@127 262
Chris@127 263 void
Chris@127 264 ViewManager::setInProgressSelection(const Selection &selection, bool exclusive)
Chris@127 265 {
Chris@127 266 m_inProgressExclusive = exclusive;
Chris@127 267 m_inProgressSelection = selection;
Chris@127 268 if (exclusive) clearSelections();
Chris@127 269 emit inProgressSelectionChanged();
Chris@127 270 }
Chris@127 271
Chris@127 272 void
Chris@127 273 ViewManager::clearInProgressSelection()
Chris@127 274 {
Chris@127 275 m_inProgressSelection = Selection();
Chris@127 276 emit inProgressSelectionChanged();
Chris@127 277 }
Chris@127 278
Chris@127 279 const MultiSelection &
Chris@127 280 ViewManager::getSelection() const
Chris@127 281 {
Chris@127 282 return m_selections;
Chris@127 283 }
Chris@127 284
Chris@127 285 const MultiSelection::SelectionList &
Chris@127 286 ViewManager::getSelections() const
Chris@127 287 {
Chris@127 288 return m_selections.getSelections();
Chris@127 289 }
Chris@127 290
Chris@127 291 void
Chris@127 292 ViewManager::setSelection(const Selection &selection)
Chris@127 293 {
Chris@127 294 MultiSelection ms(m_selections);
Chris@127 295 ms.setSelection(selection);
Chris@127 296 setSelections(ms);
Chris@127 297 }
Chris@127 298
Chris@127 299 void
Chris@127 300 ViewManager::addSelection(const Selection &selection)
Chris@127 301 {
Chris@127 302 MultiSelection ms(m_selections);
Chris@127 303 ms.addSelection(selection);
Chris@127 304 setSelections(ms);
Chris@127 305 }
Chris@127 306
Chris@127 307 void
Chris@762 308 ViewManager::addSelectionQuietly(const Selection &selection)
Chris@762 309 {
Chris@762 310 MultiSelection ms(m_selections);
Chris@762 311 ms.addSelection(selection);
Chris@762 312 setSelections(ms, true);
Chris@762 313 }
Chris@762 314
Chris@762 315 void
Chris@127 316 ViewManager::removeSelection(const Selection &selection)
Chris@127 317 {
Chris@127 318 MultiSelection ms(m_selections);
Chris@127 319 ms.removeSelection(selection);
Chris@127 320 setSelections(ms);
Chris@127 321 }
Chris@127 322
Chris@127 323 void
Chris@127 324 ViewManager::clearSelections()
Chris@127 325 {
Chris@127 326 MultiSelection ms(m_selections);
Chris@127 327 ms.clearSelections();
Chris@127 328 setSelections(ms);
Chris@127 329 }
Chris@127 330
Chris@127 331 void
Chris@762 332 ViewManager::setSelections(const MultiSelection &ms, bool quietly)
Chris@127 333 {
Chris@127 334 if (m_selections.getSelections() == ms.getSelections()) return;
Chris@127 335 SetSelectionCommand *command = new SetSelectionCommand(this, ms);
Chris@127 336 CommandHistory::getInstance()->addCommand(command);
Chris@762 337 if (!quietly) {
Chris@762 338 emit selectionChangedByUser();
Chris@762 339 }
Chris@127 340 }
Chris@127 341
Chris@902 342 sv_frame_t
Chris@902 343 ViewManager::constrainFrameToSelection(sv_frame_t frame) const
Chris@271 344 {
Chris@271 345 MultiSelection::SelectionList sl = getSelections();
Chris@271 346 if (sl.empty()) return frame;
Chris@271 347
Chris@368 348 for (MultiSelection::SelectionList::const_iterator i = sl.begin();
Chris@368 349 i != sl.end(); ++i) {
Chris@368 350
Chris@368 351 if (frame < i->getEndFrame()) {
Chris@368 352 if (frame < i->getStartFrame()) {
Chris@368 353 return i->getStartFrame();
Chris@368 354 } else {
Chris@368 355 return frame;
Chris@368 356 }
Chris@368 357 }
Chris@271 358 }
Chris@271 359
Chris@368 360 return sl.begin()->getStartFrame();
Chris@271 361 }
Chris@271 362
Chris@127 363 void
Chris@127 364 ViewManager::signalSelectionChange()
Chris@127 365 {
Chris@127 366 emit selectionChanged();
Chris@127 367 }
Chris@127 368
Chris@127 369 ViewManager::SetSelectionCommand::SetSelectionCommand(ViewManager *vm,
Chris@1266 370 const MultiSelection &ms) :
Chris@127 371 m_vm(vm),
Chris@127 372 m_oldSelection(vm->m_selections),
Chris@127 373 m_newSelection(ms)
Chris@127 374 {
Chris@127 375 }
Chris@127 376
Chris@127 377 ViewManager::SetSelectionCommand::~SetSelectionCommand() { }
Chris@127 378
Chris@127 379 void
Chris@127 380 ViewManager::SetSelectionCommand::execute()
Chris@127 381 {
Chris@127 382 m_vm->m_selections = m_newSelection;
Chris@127 383 m_vm->signalSelectionChange();
Chris@127 384 }
Chris@127 385
Chris@127 386 void
Chris@127 387 ViewManager::SetSelectionCommand::unexecute()
Chris@127 388 {
Chris@127 389 m_vm->m_selections = m_oldSelection;
Chris@127 390 m_vm->signalSelectionChange();
Chris@127 391 }
Chris@127 392
Chris@127 393 QString
Chris@127 394 ViewManager::SetSelectionCommand::getName() const
Chris@127 395 {
Chris@127 396 if (m_newSelection.getSelections().empty()) return tr("Clear Selection");
Chris@502 397 if (m_newSelection.getSelections().size() > 1) return tr("Select Multiple Regions");
Chris@502 398 else return tr("Select Region");
Chris@127 399 }
Chris@127 400
Chris@127 401 Selection
Chris@902 402 ViewManager::getContainingSelection(sv_frame_t frame, bool defaultToFollowing) const
Chris@127 403 {
Chris@127 404 return m_selections.getContainingSelection(frame, defaultToFollowing);
Chris@127 405 }
Chris@127 406
Chris@127 407 void
Chris@127 408 ViewManager::setToolMode(ToolMode mode)
Chris@127 409 {
Chris@127 410 m_toolMode = mode;
Chris@127 411
Chris@127 412 emit toolModeChanged();
Chris@502 413
Chris@502 414 switch (mode) {
Chris@502 415 case NavigateMode: emit activity(tr("Enter Navigate mode")); break;
Chris@502 416 case SelectMode: emit activity(tr("Enter Select mode")); break;
Chris@502 417 case EditMode: emit activity(tr("Enter Edit mode")); break;
Chris@502 418 case DrawMode: emit activity(tr("Enter Draw mode")); break;
Chris@502 419 case EraseMode: emit activity(tr("Enter Erase mode")); break;
Chris@502 420 case MeasureMode: emit activity(tr("Enter Measure mode")); break;
gyorgyf@645 421 case NoteEditMode: emit activity(tr("Enter NoteEdit mode")); break; // GF: NoteEditMode activity (I'm not yet certain why we need to emit this.)
Chris@502 422 };
Chris@127 423 }
Chris@127 424
Chris@711 425 ViewManager::ToolMode
Chris@711 426 ViewManager::getToolModeFor(const View *v) const
Chris@711 427 {
Chris@711 428 if (m_toolModeOverrides.find(v) == m_toolModeOverrides.end()) {
Chris@711 429 return getToolMode();
Chris@711 430 } else {
Chris@711 431 return m_toolModeOverrides.find(v)->second;
Chris@711 432 }
Chris@711 433 }
Chris@711 434
Chris@711 435 void
Chris@711 436 ViewManager::setToolModeFor(const View *v, ToolMode mode)
Chris@711 437 {
Chris@711 438 m_toolModeOverrides[v] = mode;
Chris@711 439 }
Chris@711 440
Chris@711 441 void
Chris@711 442 ViewManager::clearToolModeOverrides()
Chris@711 443 {
Chris@711 444 m_toolModeOverrides.clear();
Chris@711 445 }
Chris@711 446
Chris@127 447 void
Chris@127 448 ViewManager::setPlayLoopMode(bool mode)
Chris@127 449 {
Chris@177 450 if (m_playLoopMode != mode) {
Chris@127 451
Chris@177 452 m_playLoopMode = mode;
Chris@177 453
Chris@177 454 emit playLoopModeChanged();
Chris@177 455 emit playLoopModeChanged(mode);
Chris@502 456
Chris@502 457 if (mode) emit activity(tr("Switch on Loop mode"));
Chris@502 458 else emit activity(tr("Switch off Loop mode"));
Chris@177 459 }
Chris@127 460 }
Chris@127 461
Chris@127 462 void
Chris@127 463 ViewManager::setPlaySelectionMode(bool mode)
Chris@127 464 {
Chris@177 465 if (m_playSelectionMode != mode) {
Chris@127 466
Chris@177 467 m_playSelectionMode = mode;
Chris@177 468
Chris@177 469 emit playSelectionModeChanged();
Chris@177 470 emit playSelectionModeChanged(mode);
Chris@502 471
Chris@502 472 if (mode) emit activity(tr("Switch on Play Selection mode"));
Chris@502 473 else emit activity(tr("Switch off Play Selection mode"));
Chris@177 474 }
Chris@127 475 }
Chris@127 476
Chris@301 477 void
Chris@301 478 ViewManager::setPlaySoloMode(bool mode)
Chris@301 479 {
Chris@301 480 if (m_playSoloMode != mode) {
Chris@301 481
Chris@301 482 m_playSoloMode = mode;
Chris@301 483
Chris@301 484 emit playSoloModeChanged();
Chris@301 485 emit playSoloModeChanged(mode);
Chris@502 486
Chris@502 487 if (mode) emit activity(tr("Switch on Play Solo mode"));
Chris@502 488 else emit activity(tr("Switch off Play Solo mode"));
Chris@301 489 }
Chris@301 490 }
Chris@301 491
Chris@314 492 void
Chris@314 493 ViewManager::setAlignMode(bool mode)
Chris@314 494 {
Chris@314 495 if (m_alignMode != mode) {
Chris@314 496
Chris@314 497 m_alignMode = mode;
Chris@314 498
Chris@314 499 emit alignModeChanged();
Chris@314 500 emit alignModeChanged(mode);
Chris@502 501
Chris@502 502 if (mode) emit activity(tr("Switch on Alignment mode"));
Chris@502 503 else emit activity(tr("Switch off Alignment mode"));
Chris@314 504 }
Chris@314 505 }
Chris@314 506
Chris@902 507 sv_samplerate_t
Chris@224 508 ViewManager::getPlaybackSampleRate() const
Chris@224 509 {
Chris@224 510 if (m_playSource) {
Chris@224 511 return m_playSource->getSourceSampleRate();
Chris@224 512 }
Chris@224 513 return 0;
Chris@224 514 }
Chris@224 515
Chris@902 516 sv_samplerate_t
Chris@1181 517 ViewManager::getDeviceSampleRate() const
Chris@127 518 {
Chris@127 519 if (m_playSource) {
Chris@1266 520 return m_playSource->getDeviceSampleRate();
Chris@127 521 }
Chris@127 522 return 0;
Chris@127 523 }
Chris@127 524
Chris@127 525 void
Chris@127 526 ViewManager::setAudioPlaySource(AudioPlaySource *source)
Chris@127 527 {
Chris@127 528 if (!m_playSource) {
Chris@1266 529 QTimer::singleShot(100, this, SLOT(checkPlayStatus()));
Chris@127 530 }
Chris@127 531 m_playSource = source;
Chris@127 532 }
Chris@127 533
Chris@127 534 void
Chris@1210 535 ViewManager::setAudioRecordTarget(AudioRecordTarget *target)
Chris@1210 536 {
Chris@1210 537 if (!m_recordTarget) {
Chris@1266 538 QTimer::singleShot(100, this, SLOT(checkPlayStatus()));
Chris@1210 539 }
Chris@1210 540 m_recordTarget = target;
Chris@1210 541 }
Chris@1210 542
Chris@1210 543 void
Chris@248 544 ViewManager::playStatusChanged(bool /* playing */)
Chris@127 545 {
Chris@689 546 #ifdef DEBUG_VIEW_MANAGER
Chris@689 547 cerr << "ViewManager::playStatusChanged" << endl;
Chris@689 548 #endif
Chris@127 549 checkPlayStatus();
Chris@127 550 }
Chris@127 551
Chris@127 552 void
Chris@1210 553 ViewManager::recordStatusChanged(bool /* recording */)
Chris@1210 554 {
Chris@1210 555 #ifdef DEBUG_VIEW_MANAGER
Chris@1210 556 cerr << "ViewManager::recordStatusChanged" << endl;
Chris@1210 557 #endif
Chris@1210 558 checkPlayStatus();
Chris@1210 559 }
Chris@1210 560
Chris@1210 561 void
Chris@127 562 ViewManager::checkPlayStatus()
Chris@127 563 {
Chris@1210 564 if (isRecording()) {
Chris@1210 565
Chris@1266 566 float left = 0, right = 0;
Chris@1266 567 if (m_recordTarget->getInputLevels(left, right)) {
Chris@1266 568 if (left != m_lastLeft || right != m_lastRight) {
Chris@1266 569 emit monitoringLevelsChanged(left, right);
Chris@1266 570 m_lastLeft = left;
Chris@1266 571 m_lastRight = right;
Chris@1266 572 }
Chris@1266 573 }
Chris@1210 574
Chris@1266 575 m_playbackFrame = m_recordTarget->getRecordDuration();
Chris@1210 576
Chris@1210 577 #ifdef DEBUG_VIEW_MANAGER
Chris@1266 578 cerr << "ViewManager::checkPlayStatus: Recording, frame " << m_playbackFrame << ", levels " << m_lastLeft << "," << m_lastRight << endl;
Chris@1210 579 #endif
Chris@1210 580
Chris@1266 581 emit playbackFrameChanged(m_playbackFrame);
Chris@1210 582
Chris@1266 583 QTimer::singleShot(500, this, SLOT(checkPlayStatus()));
Chris@1210 584
Chris@1210 585 } else if (isPlaying()) {
Chris@127 586
Chris@1266 587 float left = 0, right = 0;
Chris@1266 588 if (m_playSource->getOutputLevels(left, right)) {
Chris@1266 589 if (left != m_lastLeft || right != m_lastRight) {
Chris@1266 590 emit monitoringLevelsChanged(left, right);
Chris@1266 591 m_lastLeft = left;
Chris@1266 592 m_lastRight = right;
Chris@1266 593 }
Chris@1266 594 }
Chris@127 595
Chris@1266 596 m_playbackFrame = m_playSource->getCurrentPlayingFrame();
Chris@127 597
Chris@127 598 #ifdef DEBUG_VIEW_MANAGER
Chris@1266 599 cerr << "ViewManager::checkPlayStatus: Playing, frame " << m_playbackFrame << ", levels " << m_lastLeft << "," << m_lastRight << endl;
Chris@127 600 #endif
Chris@127 601
Chris@1266 602 emit playbackFrameChanged(m_playbackFrame);
Chris@127 603
Chris@1266 604 QTimer::singleShot(20, this, SLOT(checkPlayStatus()));
Chris@127 605
Chris@127 606 } else {
Chris@127 607
Chris@1266 608 if (m_lastLeft != 0.0 || m_lastRight != 0.0) {
Chris@1266 609 emit monitoringLevelsChanged(0.0, 0.0);
Chris@1266 610 m_lastLeft = 0.0;
Chris@1266 611 m_lastRight = 0.0;
Chris@1266 612 }
Chris@127 613
Chris@127 614 #ifdef DEBUG_VIEW_MANAGER
Chris@1266 615 cerr << "ViewManager::checkPlayStatus: Not playing or recording" << endl;
Chris@127 616 #endif
Chris@127 617 }
Chris@127 618 }
Chris@127 619
Chris@127 620 bool
Chris@127 621 ViewManager::isPlaying() const
Chris@127 622 {
Chris@127 623 return m_playSource && m_playSource->isPlaying();
Chris@127 624 }
Chris@127 625
Chris@1210 626 bool
Chris@1210 627 ViewManager::isRecording() const
Chris@1210 628 {
Chris@1210 629 return m_recordTarget && m_recordTarget->isRecording();
Chris@1210 630 }
Chris@1210 631
Chris@127 632 void
Chris@902 633 ViewManager::viewCentreFrameChanged(sv_frame_t f, bool locked,
Chris@211 634 PlaybackFollowMode mode)
Chris@127 635 {
Chris@211 636 View *v = dynamic_cast<View *>(sender());
Chris@211 637
Chris@398 638 #ifdef DEBUG_VIEW_MANAGER
Chris@682 639 cerr << "ViewManager::viewCentreFrameChanged(" << f << ", " << locked << ", " << mode << "), view is " << v << endl;
Chris@398 640 #endif
Chris@394 641
Chris@127 642 if (locked) {
Chris@211 643 m_globalCentreFrame = f;
Chris@211 644 emit globalCentreFrameChanged(f);
Chris@211 645 } else {
Chris@211 646 if (v) emit viewCentreFrameChanged(v, f);
Chris@127 647 }
Chris@127 648
Chris@815 649 if (!dynamic_cast<Overview *>(v) || (mode != PlaybackIgnore)) {
Chris@527 650 if (m_mainModelSampleRate != 0) {
Chris@527 651 emit activity(tr("Scroll to %1")
Chris@527 652 .arg(RealTime::frame2RealTime
Chris@527 653 (f, m_mainModelSampleRate).toText().c_str()));
Chris@527 654 }
Chris@503 655 }
Chris@502 656
Chris@815 657 if (mode == PlaybackScrollPageWithCentre ||
Chris@815 658 mode == PlaybackScrollContinuous) {
Chris@815 659 seek(f);
Chris@211 660 }
Chris@211 661 }
Chris@211 662
Chris@211 663 void
Chris@902 664 ViewManager::seek(sv_frame_t f)
Chris@211 665 {
Chris@127 666 #ifdef DEBUG_VIEW_MANAGER
Chris@682 667 cerr << "ViewManager::seek(" << f << ")" << endl;
Chris@127 668 #endif
Chris@127 669
Chris@1210 670 if (isRecording()) {
Chris@1210 671 // ignore
Chris@1210 672 #ifdef DEBUG_VIEW_MANAGER
Chris@1210 673 cerr << "ViewManager::seek: Ignoring during recording" << endl;
Chris@1210 674 #endif
Chris@1210 675 return;
Chris@1210 676 }
Chris@1210 677
Chris@1210 678 if (isPlaying()) {
Chris@1266 679 sv_frame_t playFrame = m_playSource->getCurrentPlayingFrame();
Chris@1266 680 sv_frame_t diff = std::max(f, playFrame) - std::min(f, playFrame);
Chris@1266 681 if (diff > 20000) {
Chris@1266 682 m_playbackFrame = f;
Chris@1266 683 m_playSource->play(f);
Chris@127 684 #ifdef DEBUG_VIEW_MANAGER
Chris@1266 685 cerr << "ViewManager::seek: reseeking from " << playFrame << " to " << f << endl;
Chris@127 686 #endif
Chris@211 687 emit playbackFrameChanged(f);
Chris@1266 688 }
Chris@127 689 } else {
Chris@211 690 if (m_playbackFrame != f) {
Chris@211 691 m_playbackFrame = f;
Chris@211 692 emit playbackFrameChanged(f);
Chris@211 693 }
Chris@127 694 }
Chris@127 695 }
Chris@127 696
Chris@127 697 void
Chris@1327 698 ViewManager::viewZoomLevelChanged(ZoomLevel z, bool locked)
Chris@127 699 {
Chris@222 700 View *v = dynamic_cast<View *>(sender());
Chris@222 701
Chris@222 702 if (!v) {
Chris@587 703 SVDEBUG << "ViewManager::viewZoomLevelChanged: WARNING: sender is not a view" << endl;
Chris@222 704 return;
Chris@222 705 }
Chris@222 706
Chris@222 707 //!!! emit zoomLevelChanged();
Chris@133 708
Chris@127 709 if (locked) {
Chris@1266 710 m_globalZoom = z;
Chris@127 711 }
Chris@127 712
Chris@127 713 #ifdef DEBUG_VIEW_MANAGER
Chris@682 714 cerr << "ViewManager::viewZoomLevelChanged(" << v << ", " << z << ", " << locked << ")" << endl;
Chris@127 715 #endif
Chris@222 716
Chris@222 717 emit viewZoomLevelChanged(v, z, locked);
Chris@503 718
Chris@503 719 if (!dynamic_cast<Overview *>(v)) {
Chris@1327 720 if (z.zone == ZoomLevel::FramesPerPixel) {
Chris@1327 721 emit activity(tr("Zoom to %n sample(s) per pixel", "", z.level));
Chris@1327 722 } else {
Chris@1327 723 emit activity(tr("Zoom to %n pixels per sample", "", z.level));
Chris@1327 724 }
Chris@503 725 }
Chris@127 726 }
Chris@127 727
Chris@127 728 void
Chris@127 729 ViewManager::setOverlayMode(OverlayMode mode)
Chris@127 730 {
Chris@127 731 if (m_overlayMode != mode) {
Chris@127 732 m_overlayMode = mode;
Chris@127 733 emit overlayModeChanged();
Chris@502 734 emit activity(tr("Change overlay level"));
Chris@127 735 }
Chris@133 736
Chris@133 737 QSettings settings;
Chris@133 738 settings.beginGroup("MainWindow");
Chris@133 739 settings.setValue("overlay-mode", int(m_overlayMode));
Chris@133 740 settings.endGroup();
Chris@127 741 }
Chris@127 742
Chris@133 743 void
Chris@133 744 ViewManager::setZoomWheelsEnabled(bool enabled)
Chris@133 745 {
Chris@133 746 if (m_zoomWheelsEnabled != enabled) {
Chris@133 747 m_zoomWheelsEnabled = enabled;
Chris@133 748 emit zoomWheelsEnabledChanged();
Chris@502 749 if (enabled) emit activity("Show zoom wheels");
Chris@502 750 else emit activity("Hide zoom wheels");
Chris@133 751 }
Chris@127 752
Chris@133 753 QSettings settings;
Chris@133 754 settings.beginGroup("MainWindow");
Chris@133 755 settings.setValue("zoom-wheels-enabled", m_zoomWheelsEnabled);
Chris@133 756 settings.endGroup();
Chris@133 757 }
Chris@133 758
Chris@292 759 void
Chris@1468 760 ViewManager::setOpportunisticEditingEnabled(bool enabled)
Chris@1468 761 {
Chris@1468 762 if (m_opportunisticEditingEnabled != enabled) {
Chris@1468 763 m_opportunisticEditingEnabled = enabled;
Chris@1468 764 emit opportunisticEditingEnabledChanged();
Chris@1468 765 }
Chris@1468 766 }
Chris@1468 767
Chris@1468 768 void
Chris@607 769 ViewManager::setShowCentreLine(bool show)
Chris@607 770 {
Chris@607 771 if (m_showCentreLine != show) {
Chris@607 772 m_showCentreLine = show;
Chris@607 773 emit showCentreLineChanged();
Chris@607 774 if (show) emit activity("Show centre line");
Chris@607 775 else emit activity("Hide centre line");
Chris@607 776 }
Chris@607 777
Chris@607 778 QSettings settings;
Chris@607 779 settings.beginGroup("MainWindow");
Chris@607 780 settings.setValue("show-centre-line", int(m_showCentreLine));
Chris@607 781 settings.endGroup();
Chris@607 782 }
Chris@607 783
Chris@607 784 void
Chris@292 785 ViewManager::setGlobalDarkBackground(bool dark)
Chris@292 786 {
Chris@292 787 // also save the current palette, in case the user has changed it
Chris@292 788 // since construction
Chris@292 789 if (getGlobalDarkBackground()) {
Chris@292 790 m_darkPalette = QApplication::palette();
Chris@292 791 } else {
Chris@292 792 m_lightPalette = QApplication::palette();
Chris@292 793 }
Chris@292 794
Chris@737 795 #ifndef Q_OS_MAC
Chris@292 796 if (dark) {
Chris@292 797 QApplication::setPalette(m_darkPalette);
Chris@292 798 } else {
Chris@292 799 QApplication::setPalette(m_lightPalette);
Chris@292 800 }
Chris@737 801 #endif
Chris@292 802 }
Chris@292 803
Chris@292 804 bool
Chris@292 805 ViewManager::getGlobalDarkBackground() const
Chris@292 806 {
Chris@292 807 bool dark = false;
Chris@292 808 QColor windowBg = QApplication::palette().color(QPalette::Window);
Chris@292 809 if (windowBg.red() + windowBg.green() + windowBg.blue() < 384) {
Chris@292 810 dark = true;
Chris@292 811 }
Chris@292 812 return dark;
Chris@292 813 }
Chris@292 814
Chris@894 815 int
Chris@894 816 ViewManager::scalePixelSize(int pixels)
Chris@894 817 {
Chris@908 818 static double ratio = 0.0;
Chris@908 819 if (ratio == 0.0) {
Chris@908 820 double baseEm;
Chris@894 821 #ifdef Q_OS_MAC
Chris@908 822 baseEm = 17.0;
Chris@894 823 #else
Chris@908 824 baseEm = 15.0;
Chris@894 825 #endif
Chris@908 826 double em = QFontMetrics(QFont()).height();
Chris@894 827 ratio = em / baseEm;
Chris@1224 828
Chris@1224 829 SVDEBUG << "ViewManager::scalePixelSize: ratio is " << ratio
Chris@1224 830 << " (em = " << em << ")" << endl;
Chris@894 831 }
Chris@894 832
Chris@894 833 int scaled = int(pixels * ratio + 0.5);
Chris@1273 834 // SVDEBUG << "scaledSize: " << pixels << " -> " << scaled << " at ratio " << ratio << endl;
Chris@894 835 if (pixels != 0 && scaled == 0) scaled = 1;
Chris@894 836 return scaled;
Chris@894 837 }
Chris@946 838