annotate view/ViewManager.cpp @ 1605:ae2d5f8ff005

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