annotate view/View.h @ 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 4eafe5a1b655
children 4f8c72adbf43
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@127 7 This file copyright 2006 Chris Cannam.
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@1225 16 #ifndef SV_VIEW_H
Chris@1225 17 #define SV_VIEW_H
Chris@127 18
Chris@127 19 #include <QFrame>
Chris@127 20 #include <QProgressBar>
Chris@127 21
Chris@1077 22 #include "layer/LayerGeometryProvider.h"
Chris@916 23
Chris@127 24 #include "base/ZoomConstraint.h"
Chris@127 25 #include "base/PropertyContainer.h"
Chris@128 26 #include "ViewManager.h"
Chris@127 27 #include "base/XmlExportable.h"
Chris@902 28 #include "base/BaseTypes.h"
Chris@127 29
Chris@1475 30 #include "data/model/Model.h"
Chris@1475 31
Chris@127 32 // #define DEBUG_VIEW_WIDGET_PAINT 1
Chris@127 33
Chris@127 34 class Layer;
Chris@127 35 class ViewPropertyContainer;
Chris@127 36
Chris@797 37 class QPushButton;
Chris@797 38
Chris@127 39 #include <map>
Chris@315 40 #include <set>
Chris@127 41
Chris@127 42 /**
Chris@127 43 * View is the base class of widgets that display one or more
Chris@127 44 * overlaid views of data against a horizontal time scale.
Chris@127 45 *
Chris@127 46 * A View may have any number of attached Layers, each of which
Chris@127 47 * is expected to have one data Model (although multiple views may
Chris@127 48 * share the same model).
Chris@127 49 *
Chris@127 50 * A View may be panned in time and zoomed, although the
Chris@127 51 * mechanisms for doing so (as well as any other operations and
Chris@127 52 * properties available) depend on the subclass.
Chris@127 53 */
Chris@127 54
Chris@127 55 class View : public QFrame,
Chris@1266 56 public XmlExportable,
Chris@916 57 public LayerGeometryProvider
Chris@127 58 {
Chris@127 59 Q_OBJECT
Chris@127 60
Chris@127 61 public:
Chris@127 62 /**
Chris@127 63 * Deleting a View does not delete any of its layers. They should
Chris@127 64 * be managed elsewhere (e.g. by the Document).
Chris@127 65 */
Chris@127 66 virtual ~View();
Chris@1044 67
Chris@1044 68 /**
Chris@1044 69 * Retrieve the id of this object. Views have their own unique
Chris@1044 70 * ids, but ViewProxy objects share the id of their View.
Chris@1044 71 */
Chris@1406 72 int getId() const override { return m_id; }
Chris@1030 73
Chris@127 74 /**
Chris@127 75 * Retrieve the first visible sample frame on the widget.
Chris@127 76 * This is a calculated value based on the centre-frame, widget
Chris@127 77 * width and zoom level. The result may be negative.
Chris@127 78 */
Chris@1406 79 sv_frame_t getStartFrame() const override;
Chris@127 80
Chris@127 81 /**
Chris@127 82 * Set the widget pan based on the given first visible frame. The
Chris@127 83 * frame value may be negative.
Chris@127 84 */
Chris@902 85 void setStartFrame(sv_frame_t);
Chris@127 86
Chris@127 87 /**
Chris@127 88 * Return the centre frame of the visible widget. This is an
Chris@127 89 * exact value that does not depend on the zoom block size. Other
Chris@127 90 * frame values (start, end) are calculated from this based on the
Chris@127 91 * zoom and other factors.
Chris@127 92 */
Chris@1406 93 sv_frame_t getCentreFrame() const override { return m_centreFrame; }
Chris@127 94
Chris@127 95 /**
Chris@127 96 * Set the centre frame of the visible widget.
Chris@127 97 */
Chris@902 98 void setCentreFrame(sv_frame_t f) { setCentreFrame(f, true); }
Chris@127 99
Chris@127 100 /**
Chris@127 101 * Retrieve the last visible sample frame on the widget.
Chris@127 102 * This is a calculated value based on the centre-frame, widget
Chris@127 103 * width and zoom level.
Chris@127 104 */
Chris@1406 105 sv_frame_t getEndFrame() const override;
Chris@127 106
Chris@127 107 /**
Chris@127 108 * Return the pixel x-coordinate corresponding to a given sample
Chris@1375 109 * frame. The frame is permitted to be negative, and the result
Chris@1375 110 * may be outside the currently visible area. But this should not
Chris@1375 111 * be called with frame values very far away from the currently
Chris@1375 112 * visible area, as that could lead to overflow. In that situation
Chris@1375 113 * an error will be logged and 0 returned.
Chris@127 114 */
Chris@1406 115 int getXForFrame(sv_frame_t frame) const override;
Chris@127 116
Chris@127 117 /**
Chris@127 118 * Return the closest frame to the given pixel x-coordinate.
Chris@127 119 */
Chris@1406 120 sv_frame_t getFrameForX(int x) const override;
Chris@127 121
Chris@127 122 /**
Chris@1030 123 * Return the closest pixel x-coordinate corresponding to a given
Chris@1030 124 * view x-coordinate. Default is no scaling, ViewProxy handles
Chris@1030 125 * scaling case.
Chris@1030 126 */
Chris@1406 127 int getXForViewX(int viewx) const override { return viewx; }
Chris@1030 128
Chris@1030 129 /**
Chris@1030 130 * Return the closest view x-coordinate corresponding to a given
Chris@1030 131 * pixel x-coordinate. Default is no scaling, ViewProxy handles
Chris@1030 132 * scaling case.
Chris@1030 133 */
Chris@1406 134 int getViewXForX(int x) const override { return x; }
Chris@1030 135
Chris@1030 136 /**
Chris@127 137 * Return the pixel y-coordinate corresponding to a given
Chris@127 138 * frequency, if the frequency range is as specified. This does
Chris@127 139 * not imply any policy about layer frequency ranges, but it might
Chris@127 140 * be useful for layers to match theirs up if desired.
Chris@127 141 *
Chris@127 142 * Not thread-safe in logarithmic mode. Call only from GUI thread.
Chris@127 143 */
Chris@904 144 double getYForFrequency(double frequency, double minFreq, double maxFreq,
Chris@1406 145 bool logarithmic) const override;
Chris@127 146
Chris@127 147 /**
Chris@127 148 * Return the closest frequency to the given pixel y-coordinate,
Chris@127 149 * if the frequency range is as specified.
Chris@127 150 *
Chris@127 151 * Not thread-safe in logarithmic mode. Call only from GUI thread.
Chris@127 152 */
Chris@1085 153 double getFrequencyForY(double y, double minFreq, double maxFreq,
Chris@1406 154 bool logarithmic) const override;
Chris@127 155
Chris@127 156 /**
Chris@1183 157 * Return the zoom level, i.e. the number of frames per pixel or
Chris@1183 158 * pixels per frame
Chris@127 159 */
Chris@1406 160 ZoomLevel getZoomLevel() const override;
Chris@127 161
Chris@127 162 /**
Chris@1183 163 * Set the zoom level, i.e. the number of frames per pixel or
Chris@1183 164 * pixels per frame. The centre frame will be unchanged; the
Chris@1183 165 * start and end frames will change.
Chris@127 166 */
Chris@1183 167 virtual void setZoomLevel(ZoomLevel z);
Chris@127 168
Chris@127 169 /**
Chris@127 170 * Zoom in or out.
Chris@127 171 */
Chris@127 172 virtual void zoom(bool in);
Chris@127 173
Chris@127 174 /**
Chris@127 175 * Scroll left or right by a smallish or largish amount.
Chris@127 176 */
Chris@510 177 virtual void scroll(bool right, bool lots, bool doEmit = true);
Chris@127 178
Chris@834 179 /**
Chris@834 180 * Add a layer to the view. (Normally this should be handled
Chris@834 181 * through some command abstraction instead of using this function
Chris@834 182 * directly.)
Chris@834 183 */
Chris@127 184 virtual void addLayer(Layer *v);
Chris@834 185
Chris@834 186 /**
Chris@834 187 * Remove a layer from the view. Does not delete the
Chris@834 188 * layer. (Normally this should be handled through some command
Chris@834 189 * abstraction instead of using this function directly.)
Chris@834 190 */
Chris@834 191 virtual void removeLayer(Layer *v);
Chris@834 192
Chris@834 193 /**
Chris@834 194 * Return the number of layers, regardless of whether visible or
Chris@834 195 * dormant, i.e. invisible, in this view.
Chris@834 196 */
Chris@902 197 virtual int getLayerCount() const { return int(m_layerStack.size()); }
Chris@127 198
Chris@127 199 /**
Chris@834 200 * Return the nth layer, counted in stacking order. That is,
Chris@834 201 * layer 0 is the bottom layer and layer "getLayerCount()-1" is
Chris@834 202 * the top one. The returned layer may be visible or it may be
Chris@834 203 * dormant, i.e. invisible.
Chris@127 204 */
Chris@277 205 virtual Layer *getLayer(int n) {
Chris@902 206 if (in_range_for(m_layerStack, n)) return m_layerStack[n];
Chris@835 207 else return 0;
Chris@277 208 }
Chris@127 209
Chris@127 210 /**
Chris@835 211 * Return the nth layer, counted in the order they were
Chris@835 212 * added. Unlike the stacking order used in getLayer(), which
Chris@835 213 * changes each time a layer is selected, this ordering remains
Chris@835 214 * fixed. The returned layer may be visible or it may be dormant,
Chris@835 215 * i.e. invisible.
Chris@268 216 */
Chris@835 217 virtual Layer *getFixedOrderLayer(int n) {
Chris@835 218 if (n < int(m_fixedOrderLayers.size())) return m_fixedOrderLayers[n];
Chris@835 219 else return 0;
Chris@268 220 }
Chris@268 221
Chris@268 222 /**
Chris@834 223 * Return the layer currently active for tool interaction. This is
Chris@834 224 * the topmost non-dormant (i.e. visible) layer in the view. If
Chris@834 225 * there are no visible layers in the view, return 0.
Chris@834 226 */
Chris@834 227 virtual Layer *getInteractionLayer();
Chris@834 228
Chris@841 229 virtual const Layer *getInteractionLayer() const;
Chris@841 230
Chris@834 231 /**
Chris@835 232 * Return the layer most recently selected by the user. This is
Chris@835 233 * the layer that any non-tool-driven commands should operate on,
Chris@835 234 * in the case where this view is the "current" one.
Chris@835 235 *
Chris@835 236 * If the user has selected the view itself more recently than any
Chris@835 237 * of the layers on it, this function will return 0, and any
Chris@835 238 * non-tool-driven layer commands should be deactivated while this
Chris@835 239 * view is current. It will also return 0 if there are no layers
Chris@835 240 * in the view.
Chris@834 241 *
Chris@834 242 * Note that, unlike getInteractionLayer(), this could return an
Chris@834 243 * invisible (dormant) layer.
Chris@127 244 */
Chris@127 245 virtual Layer *getSelectedLayer();
Chris@834 246
Chris@127 247 virtual const Layer *getSelectedLayer() const;
Chris@127 248
Chris@835 249 /**
Chris@835 250 * Return the "top" layer in the view, whether visible or dormant.
Chris@835 251 * This is the same as getLayer(getLayerCount()-1) if there is at
Chris@835 252 * least one layer, and 0 otherwise.
Chris@835 253 *
Chris@835 254 * For most purposes involving interaction or commands, you
Chris@835 255 * probably want either getInteractionLayer() or
Chris@835 256 * getSelectedLayer() instead.
Chris@835 257 */
Chris@835 258 virtual Layer *getTopLayer() {
Chris@835 259 return m_layerStack.empty() ? 0 : m_layerStack[m_layerStack.size()-1];
Chris@835 260 }
Chris@835 261
Chris@127 262 virtual void setViewManager(ViewManager *m);
Chris@908 263 virtual void setViewManager(ViewManager *m, sv_frame_t initialFrame);
Chris@1406 264 ViewManager *getViewManager() const override { return m_manager; }
Chris@127 265
Chris@127 266 virtual void setFollowGlobalPan(bool f);
Chris@127 267 virtual bool getFollowGlobalPan() const { return m_followPan; }
Chris@127 268
Chris@127 269 virtual void setFollowGlobalZoom(bool f);
Chris@127 270 virtual bool getFollowGlobalZoom() const { return m_followZoom; }
Chris@127 271
Chris@1406 272 bool hasLightBackground() const override;
Chris@1406 273 QColor getForeground() const override;
Chris@1406 274 QColor getBackground() const override;
Chris@127 275
Chris@1406 276 void drawMeasurementRect(QPainter &p, const Layer *,
Chris@1406 277 QRect rect, bool focus) const override;
Chris@127 278
Chris@1406 279 bool shouldShowFeatureLabels() const override {
Chris@741 280 return m_manager && m_manager->shouldShowFeatureLabels();
Chris@741 281 }
Chris@1406 282 bool shouldIlluminateLocalFeatures(const Layer *, QPoint &) const override {
Chris@1266 283 return false;
Chris@127 284 }
Chris@127 285 virtual bool shouldIlluminateLocalSelection(QPoint &, bool &, bool &) const {
Chris@1266 286 return false;
Chris@127 287 }
Chris@127 288
Chris@127 289 virtual void setPlaybackFollow(PlaybackFollowMode m);
Chris@127 290 virtual PlaybackFollowMode getPlaybackFollow() const { return m_followPlay; }
Chris@127 291
Chris@127 292 typedef PropertyContainer::PropertyName PropertyName;
Chris@127 293
Chris@127 294 // We implement the PropertyContainer API, although we don't
Chris@127 295 // actually subclass PropertyContainer. We have our own
Chris@127 296 // PropertyContainer that we can return on request that just
Chris@127 297 // delegates back to us.
Chris@127 298 virtual PropertyContainer::PropertyList getProperties() const;
Chris@127 299 virtual QString getPropertyLabel(const PropertyName &) const;
Chris@127 300 virtual PropertyContainer::PropertyType getPropertyType(const PropertyName &) const;
Chris@127 301 virtual int getPropertyRangeAndValue(const PropertyName &,
Chris@1266 302 int *min, int *max, int *deflt) const;
Chris@127 303 virtual QString getPropertyValueLabel(const PropertyName &,
Chris@1266 304 int value) const;
Chris@127 305 virtual void setProperty(const PropertyName &, int value);
Chris@127 306 virtual QString getPropertyContainerName() const {
Chris@1266 307 return objectName();
Chris@127 308 }
Chris@127 309 virtual QString getPropertyContainerIconName() const = 0;
Chris@127 310
Chris@806 311 virtual int getPropertyContainerCount() const;
Chris@127 312
Chris@837 313 // The 0th property container is the view's own; the rest are the
Chris@837 314 // layers in fixed-order series
Chris@806 315 virtual const PropertyContainer *getPropertyContainer(int i) const;
Chris@806 316 virtual PropertyContainer *getPropertyContainer(int i);
Chris@127 317
Chris@1202 318 /**
Chris@1202 319 * Render the view contents to a new QImage (which may be wider
Chris@1202 320 * than the visible View).
Chris@1202 321 */
Chris@1202 322 virtual QImage *renderToNewImage();
Chris@226 323
Chris@1202 324 /**
Chris@1202 325 * Render the view contents between the given frame extents to a
Chris@1202 326 * new QImage (which may be wider than the visible View).
Chris@1202 327 */
Chris@1202 328 virtual QImage *renderPartToNewImage(sv_frame_t f0, sv_frame_t f1);
Chris@1202 329
Chris@1202 330 /**
Chris@1202 331 * Calculate and return the size of image that will be generated
Chris@1202 332 * by renderToNewImage().
Chris@1202 333 */
Chris@1202 334 virtual QSize getRenderedImageSize();
Chris@1202 335
Chris@1202 336 /**
Chris@1202 337 * Calculate and return the size of image that will be generated
Chris@1202 338 * by renderPartToNewImage(f0, f1).
Chris@1202 339 */
Chris@1202 340 virtual QSize getRenderedPartImageSize(sv_frame_t f0, sv_frame_t f1);
Chris@1202 341
Chris@1202 342 /**
Chris@1202 343 * Render the view contents to a new SVG file.
Chris@1202 344 */
Chris@1202 345 virtual bool renderToSvgFile(QString filename);
Chris@1202 346
Chris@1202 347 /**
Chris@1202 348 * Render the view contents between the given frame extents to a
Chris@1202 349 * new SVG file.
Chris@1202 350 */
Chris@1202 351 virtual bool renderPartToSvgFile(QString filename,
Chris@1202 352 sv_frame_t f0, sv_frame_t f1);
Chris@1202 353
Chris@1406 354 int getTextLabelHeight(const Layer *layer, QPainter &) const override;
Chris@127 355
Chris@1406 356 bool getValueExtents(QString unit, double &min, double &max,
Chris@1520 357 bool &log) const override;
Chris@127 358
Chris@1406 359 void toXml(QTextStream &stream, QString indent = "",
Chris@1406 360 QString extraAttributes = "") const override;
Chris@127 361
Chris@222 362 // First frame actually in model, to right of scale, if present
Chris@902 363 virtual sv_frame_t getFirstVisibleFrame() const;
Chris@902 364 virtual sv_frame_t getLastVisibleFrame() const;
Chris@222 365
Chris@1406 366 sv_frame_t getModelsStartFrame() const override;
Chris@1406 367 sv_frame_t getModelsEndFrame() const override;
Chris@127 368
Chris@915 369 /**
Chris@915 370 * To be called from a layer, to obtain the extent of the surface
Chris@915 371 * that the layer is currently painting to. This may be the extent
Chris@915 372 * of the view (if 1x display scaling is in effect) or of a larger
Chris@915 373 * cached pixmap (if greater display scaling is in effect).
Chris@915 374 */
Chris@1406 375 QRect getPaintRect() const override;
Chris@915 376
Chris@1406 377 QSize getPaintSize() const override { return getPaintRect().size(); }
Chris@1406 378 int getPaintWidth() const override { return getPaintRect().width(); }
Chris@1406 379 int getPaintHeight() const override { return getPaintRect().height(); }
Chris@915 380
Chris@1406 381 double scaleSize(double size) const override;
Chris@1406 382 int scalePixelSize(int size) const override;
Chris@1406 383 double scalePenWidth(double width) const override;
Chris@1406 384 QPen scalePen(QPen pen) const override;
Chris@1401 385
Chris@1475 386 typedef std::set<ModelId> ModelSet;
Chris@315 387 ModelSet getModels();
Chris@315 388
Chris@1490 389 //!!!??? poor name, probably poor api, consider this
Chris@1490 390 void setUseAligningProxy(bool uap) {
Chris@1490 391 m_useAligningProxy = uap;
Chris@1490 392 }
Chris@1490 393
Chris@301 394 //!!!
Chris@1475 395 ModelId getAligningModel() const;
Chris@1490 396 void getAligningAndReferenceModels(ModelId &aligning, ModelId &reference) const;
Chris@902 397 sv_frame_t alignFromReference(sv_frame_t) const;
Chris@902 398 sv_frame_t alignToReference(sv_frame_t) const;
Chris@902 399 sv_frame_t getAlignedPlaybackFrame() const;
Chris@301 400
Chris@1406 401 void updatePaintRect(QRect r) override { update(r); }
Chris@1030 402
Chris@1406 403 View *getView() override { return this; }
Chris@1406 404 const View *getView() const override { return this; }
Chris@918 405
Chris@127 406 signals:
Chris@127 407 void propertyContainerAdded(PropertyContainer *pc);
Chris@127 408 void propertyContainerRemoved(PropertyContainer *pc);
Chris@127 409 void propertyContainerPropertyChanged(PropertyContainer *pc);
Chris@197 410 void propertyContainerPropertyRangeChanged(PropertyContainer *pc);
Chris@127 411 void propertyContainerNameChanged(PropertyContainer *pc);
Chris@298 412 void propertyContainerSelected(PropertyContainer *pc);
Chris@127 413 void propertyChanged(PropertyContainer::PropertyName);
Chris@127 414
Chris@336 415 void layerModelChanged();
Chris@336 416
Chris@1483 417 void cancelButtonPressed(Layer *);
Chris@1483 418
Chris@902 419 void centreFrameChanged(sv_frame_t frame,
Chris@211 420 bool globalScroll,
Chris@211 421 PlaybackFollowMode followMode);
Chris@211 422
Chris@1183 423 void zoomLevelChanged(ZoomLevel level, bool locked);
Chris@127 424
Chris@189 425 void contextHelpChanged(const QString &);
Chris@189 426
Chris@127 427 public slots:
Chris@1481 428 virtual void modelChanged(ModelId);
Chris@1481 429 virtual void modelChangedWithin(ModelId, sv_frame_t startFrame, sv_frame_t endFrame);
Chris@1481 430 virtual void modelCompletionChanged(ModelId);
Chris@1481 431 virtual void modelAlignmentCompletionChanged(ModelId);
Chris@127 432 virtual void modelReplaced();
Chris@127 433 virtual void layerParametersChanged();
Chris@197 434 virtual void layerParameterRangesChanged();
Chris@268 435 virtual void layerMeasurementRectsChanged();
Chris@127 436 virtual void layerNameChanged();
Chris@127 437
Chris@902 438 virtual void globalCentreFrameChanged(sv_frame_t);
Chris@902 439 virtual void viewCentreFrameChanged(View *, sv_frame_t);
Chris@902 440 virtual void viewManagerPlaybackFrameChanged(sv_frame_t);
Chris@1183 441 virtual void viewZoomLevelChanged(View *, ZoomLevel, bool);
Chris@127 442
Chris@1441 443 /**
Chris@1441 444 * A property container has been selected, for example in the
Chris@1441 445 * associated property stack. The property container may be a
Chris@1441 446 * layer, in which case the effect should be to raise that layer
Chris@1441 447 * to the front of the view and select it; or it may be the view's
Chris@1441 448 * own property container, in which case the effect is to switch
Chris@1441 449 * to a mode in which no layer is selected.
Chris@1441 450 *
Chris@1441 451 * (This is the main slot for raising a layer.)
Chris@1441 452 */
Chris@127 453 virtual void propertyContainerSelected(View *, PropertyContainer *pc);
Chris@127 454
Chris@127 455 virtual void selectionChanged();
Chris@127 456 virtual void toolModeChanged();
Chris@133 457 virtual void overlayModeChanged();
Chris@133 458 virtual void zoomWheelsEnabledChanged();
Chris@127 459
Chris@797 460 virtual void cancelClicked();
Chris@797 461
Chris@555 462 virtual void progressCheckStalledTimerElapsed();
Chris@555 463
Chris@127 464 protected:
Chris@127 465 View(QWidget *, bool showProgress);
Chris@1030 466
Chris@1030 467 int m_id;
Chris@1030 468
Chris@1406 469 void paintEvent(QPaintEvent *e) override;
Chris@127 470 virtual void drawSelections(QPainter &);
Chris@127 471 virtual bool shouldLabelSelections() const { return true; }
Chris@1357 472 virtual void drawPlayPointer(QPainter &);
Chris@908 473 virtual bool render(QPainter &paint, int x0, sv_frame_t f0, sv_frame_t f1);
Chris@339 474 virtual void setPaintFont(QPainter &paint);
Chris@952 475
Chris@952 476 QSize scaledSize(const QSize &s, int factor) {
Chris@952 477 return QSize(s.width() * factor, s.height() * factor);
Chris@952 478 }
Chris@952 479 QRect scaledRect(const QRect &r, int factor) {
Chris@952 480 return QRect(r.x() * factor, r.y() * factor,
Chris@952 481 r.width() * factor, r.height() * factor);
Chris@952 482 }
Chris@339 483
Chris@127 484 typedef std::vector<Layer *> LayerList;
Chris@127 485
Chris@908 486 sv_samplerate_t getModelsSampleRate() const;
Chris@127 487 bool areLayersScrollable() const;
Chris@127 488 LayerList getScrollableBackLayers(bool testChanged, bool &changed) const;
Chris@127 489 LayerList getNonScrollableFrontLayers(bool testChanged, bool &changed) const;
Chris@1354 490
Chris@1183 491 ZoomLevel getZoomConstraintLevel(ZoomLevel level,
Chris@1183 492 ZoomConstraint::RoundingDirection dir =
Chris@1183 493 ZoomConstraint::RoundNearest) const;
Chris@127 494
Chris@1354 495 // These three are slow, intended for indexing GUI thumbwheel stuff
Chris@1354 496 int countZoomLevels() const;
Chris@1354 497 int getZoomLevelIndex(ZoomLevel level) const;
Chris@1354 498 ZoomLevel getZoomLevelByIndex(int ix) const;
Chris@1354 499
Chris@183 500 // True if the top layer(s) use colours for meaningful things. If
Chris@183 501 // this is the case, selections will be shown using unfilled boxes
Chris@183 502 // rather than with a translucent fill.
Chris@183 503 bool areLayerColoursSignificant() const;
Chris@183 504
Chris@217 505 // True if the top layer has a time axis on the x coordinate (this
Chris@217 506 // is generally the case except for spectrum/slice layers). It
Chris@217 507 // will not be possible to make or display selections if this is
Chris@217 508 // false.
Chris@217 509 bool hasTopLayerTimeXAxis() const;
Chris@217 510
Chris@902 511 bool setCentreFrame(sv_frame_t f, bool doEmit);
Chris@127 512
Chris@902 513 void movePlayPointer(sv_frame_t f);
Chris@511 514
Chris@1481 515 void checkProgress(ModelId);
Chris@1496 516 void checkAlignmentProgress(ModelId);
Chris@1496 517
Chris@384 518 int getProgressBarWidth() const; // if visible
Chris@127 519
Chris@956 520 int effectiveDevicePixelRatio() const;
Chris@956 521
Chris@902 522 sv_frame_t m_centreFrame;
Chris@1183 523 ZoomLevel m_zoomLevel;
Chris@127 524 bool m_followPan;
Chris@127 525 bool m_followZoom;
Chris@127 526 PlaybackFollowMode m_followPlay;
Chris@789 527 bool m_followPlayIsDetached;
Chris@902 528 sv_frame_t m_playPointerFrame;
Chris@127 529 bool m_lightBackground;
Chris@127 530 bool m_showProgress;
Chris@127 531
Chris@1215 532 QPixmap *m_cache; // I own this
Chris@1215 533 QPixmap *m_buffer; // I own this
Chris@1357 534 bool m_cacheValid;
Chris@902 535 sv_frame_t m_cacheCentreFrame;
Chris@1183 536 ZoomLevel m_cacheZoomLevel;
Chris@127 537 bool m_selectionCached;
Chris@127 538
Chris@127 539 bool m_deleting;
Chris@127 540
Chris@835 541 LayerList m_layerStack; // I don't own these, but see dtor note above
Chris@835 542 LayerList m_fixedOrderLayers;
Chris@127 543 bool m_haveSelectedLayer;
Chris@127 544
Chris@1490 545 bool m_useAligningProxy;
Chris@1490 546
Chris@583 547 QString m_lastError;
Chris@583 548
Chris@127 549 // caches for use in getScrollableBackLayers, getNonScrollableFrontLayers
Chris@127 550 mutable LayerList m_lastScrollableBackLayers;
Chris@127 551 mutable LayerList m_lastNonScrollableBackLayers;
Chris@127 552
Chris@555 553 struct ProgressBarRec {
Chris@797 554 QPushButton *cancel;
Chris@555 555 QProgressBar *bar;
Chris@1496 556 int lastStallCheckValue;
Chris@1496 557 QTimer *stallCheckTimer;
Chris@555 558 };
Chris@555 559 typedef std::map<Layer *, ProgressBarRec> ProgressMap;
Chris@1496 560 ProgressMap m_progressBars; // I own the ProgressBarRecs and their contents
Chris@1496 561
Chris@1496 562 struct AlignmentProgressBarRec {
Chris@1496 563 ModelId alignedModel;
Chris@1496 564 QProgressBar *bar;
Chris@1496 565 };
Chris@1496 566 AlignmentProgressBarRec m_alignmentProgressBar;
Chris@127 567
Chris@127 568 ViewManager *m_manager; // I don't own this
Chris@127 569 ViewPropertyContainer *m_propertyContainer; // I own this
Chris@127 570 };
Chris@127 571
Chris@127 572
Chris@127 573 // Use this for delegation, because we can't subclass from
Chris@127 574 // PropertyContainer (which is a QObject) ourselves because of
Chris@127 575 // ambiguity with QFrame parent
Chris@127 576
Chris@127 577 class ViewPropertyContainer : public PropertyContainer
Chris@127 578 {
Chris@127 579 Q_OBJECT
Chris@127 580
Chris@127 581 public:
Chris@127 582 ViewPropertyContainer(View *v);
Chris@728 583 virtual ~ViewPropertyContainer();
Chris@728 584
Chris@1406 585 PropertyList getProperties() const override { return m_v->getProperties(); }
Chris@1406 586 QString getPropertyLabel(const PropertyName &n) const override {
Chris@127 587 return m_v->getPropertyLabel(n);
Chris@127 588 }
Chris@1406 589 PropertyType getPropertyType(const PropertyName &n) const override {
Chris@1266 590 return m_v->getPropertyType(n);
Chris@127 591 }
Chris@216 592 int getPropertyRangeAndValue(const PropertyName &n, int *min, int *max,
Chris@1406 593 int *deflt) const override {
Chris@1266 594 return m_v->getPropertyRangeAndValue(n, min, max, deflt);
Chris@127 595 }
Chris@1406 596 QString getPropertyValueLabel(const PropertyName &n, int value) const override {
Chris@1266 597 return m_v->getPropertyValueLabel(n, value);
Chris@127 598 }
Chris@1406 599 QString getPropertyContainerName() const override {
Chris@1266 600 return m_v->getPropertyContainerName();
Chris@127 601 }
Chris@1406 602 QString getPropertyContainerIconName() const override {
Chris@1266 603 return m_v->getPropertyContainerIconName();
Chris@127 604 }
Chris@127 605
Chris@127 606 public slots:
Chris@1406 607 void setProperty(const PropertyName &n, int value) override {
Chris@1266 608 m_v->setProperty(n, value);
Chris@127 609 }
Chris@127 610
Chris@127 611 protected:
Chris@127 612 View *m_v;
Chris@127 613 };
Chris@127 614
Chris@127 615 #endif
Chris@127 616