annotate view/View.h @ 1619:36634b427d61

Fix wrongly-written test which made the mapping alignments line up wrongly in some cases where adjacent panes were related (but, because of this test, the alignment view thought they were not)
author Chris Cannam
date Tue, 18 Aug 2020 14:49:36 +0100
parents ae2d5f8ff005
children
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@1537 353
Chris@1537 354 /**
Chris@1537 355 * Return the visible vertical extents for the given unit, if any.
Chris@1537 356 * Overridden from LayerGeometryProvider (see docs there).
Chris@1537 357 */
Chris@1537 358 bool getVisibleExtentsForUnit(QString unit, double &min, double &max,
Chris@1537 359 bool &log) const override;
Chris@1537 360
Chris@1537 361 /**
Chris@1537 362 * Return some visible vertical extents and unit. That is, if at
Chris@1537 363 * least one non-dormant layer has a non-empty unit and returns
Chris@1537 364 * some values from its getDisplayExtents() method, return the
Chris@1537 365 * extents and unit from the topmost of those. Otherwise return
Chris@1537 366 * false.
Chris@1537 367 */
Chris@1537 368 bool getVisibleExtentsForAnyUnit(double &min, double &max,
Chris@1537 369 bool &logarithmic, QString &unit) const;
Chris@1202 370
Chris@1537 371 int getTextLabelYCoord(const Layer *layer, QPainter &) const override;
Chris@127 372
Chris@1406 373 void toXml(QTextStream &stream, QString indent = "",
Chris@1406 374 QString extraAttributes = "") const override;
Chris@127 375
Chris@222 376 // First frame actually in model, to right of scale, if present
Chris@902 377 virtual sv_frame_t getFirstVisibleFrame() const;
Chris@902 378 virtual sv_frame_t getLastVisibleFrame() const;
Chris@222 379
Chris@1406 380 sv_frame_t getModelsStartFrame() const override;
Chris@1406 381 sv_frame_t getModelsEndFrame() const override;
Chris@127 382
Chris@915 383 /**
Chris@915 384 * To be called from a layer, to obtain the extent of the surface
Chris@915 385 * that the layer is currently painting to. This may be the extent
Chris@915 386 * of the view (if 1x display scaling is in effect) or of a larger
Chris@915 387 * cached pixmap (if greater display scaling is in effect).
Chris@915 388 */
Chris@1406 389 QRect getPaintRect() const override;
Chris@915 390
Chris@1406 391 QSize getPaintSize() const override { return getPaintRect().size(); }
Chris@1406 392 int getPaintWidth() const override { return getPaintRect().width(); }
Chris@1406 393 int getPaintHeight() const override { return getPaintRect().height(); }
Chris@915 394
Chris@1406 395 double scaleSize(double size) const override;
Chris@1406 396 int scalePixelSize(int size) const override;
Chris@1406 397 double scalePenWidth(double width) const override;
Chris@1406 398 QPen scalePen(QPen pen) const override;
Chris@1401 399
Chris@1475 400 typedef std::set<ModelId> ModelSet;
Chris@315 401 ModelSet getModels();
Chris@315 402
Chris@1490 403 //!!!??? poor name, probably poor api, consider this
Chris@1490 404 void setUseAligningProxy(bool uap) {
Chris@1490 405 m_useAligningProxy = uap;
Chris@1490 406 }
Chris@1490 407
Chris@301 408 //!!!
Chris@1475 409 ModelId getAligningModel() const;
Chris@1490 410 void getAligningAndReferenceModels(ModelId &aligning, ModelId &reference) const;
Chris@902 411 sv_frame_t alignFromReference(sv_frame_t) const;
Chris@902 412 sv_frame_t alignToReference(sv_frame_t) const;
Chris@902 413 sv_frame_t getAlignedPlaybackFrame() const;
Chris@301 414
Chris@1406 415 void updatePaintRect(QRect r) override { update(r); }
Chris@1030 416
Chris@1406 417 View *getView() override { return this; }
Chris@1406 418 const View *getView() const override { return this; }
Chris@918 419
Chris@127 420 signals:
Chris@127 421 void propertyContainerAdded(PropertyContainer *pc);
Chris@127 422 void propertyContainerRemoved(PropertyContainer *pc);
Chris@127 423 void propertyContainerPropertyChanged(PropertyContainer *pc);
Chris@197 424 void propertyContainerPropertyRangeChanged(PropertyContainer *pc);
Chris@127 425 void propertyContainerNameChanged(PropertyContainer *pc);
Chris@298 426 void propertyContainerSelected(PropertyContainer *pc);
Chris@127 427 void propertyChanged(PropertyContainer::PropertyName);
Chris@127 428
Chris@336 429 void layerModelChanged();
Chris@336 430
Chris@1483 431 void cancelButtonPressed(Layer *);
Chris@1483 432
Chris@902 433 void centreFrameChanged(sv_frame_t frame,
Chris@211 434 bool globalScroll,
Chris@211 435 PlaybackFollowMode followMode);
Chris@211 436
Chris@1183 437 void zoomLevelChanged(ZoomLevel level, bool locked);
Chris@127 438
Chris@189 439 void contextHelpChanged(const QString &);
Chris@189 440
Chris@127 441 public slots:
Chris@1481 442 virtual void modelChanged(ModelId);
Chris@1481 443 virtual void modelChangedWithin(ModelId, sv_frame_t startFrame, sv_frame_t endFrame);
Chris@1481 444 virtual void modelCompletionChanged(ModelId);
Chris@1481 445 virtual void modelAlignmentCompletionChanged(ModelId);
Chris@127 446 virtual void modelReplaced();
Chris@127 447 virtual void layerParametersChanged();
Chris@197 448 virtual void layerParameterRangesChanged();
Chris@268 449 virtual void layerMeasurementRectsChanged();
Chris@127 450 virtual void layerNameChanged();
Chris@127 451
Chris@902 452 virtual void globalCentreFrameChanged(sv_frame_t);
Chris@902 453 virtual void viewCentreFrameChanged(View *, sv_frame_t);
Chris@902 454 virtual void viewManagerPlaybackFrameChanged(sv_frame_t);
Chris@1183 455 virtual void viewZoomLevelChanged(View *, ZoomLevel, bool);
Chris@127 456
Chris@1441 457 /**
Chris@1441 458 * A property container has been selected, for example in the
Chris@1441 459 * associated property stack. The property container may be a
Chris@1441 460 * layer, in which case the effect should be to raise that layer
Chris@1441 461 * to the front of the view and select it; or it may be the view's
Chris@1441 462 * own property container, in which case the effect is to switch
Chris@1441 463 * to a mode in which no layer is selected.
Chris@1441 464 *
Chris@1441 465 * (This is the main slot for raising a layer.)
Chris@1441 466 */
Chris@127 467 virtual void propertyContainerSelected(View *, PropertyContainer *pc);
Chris@127 468
Chris@127 469 virtual void selectionChanged();
Chris@127 470 virtual void toolModeChanged();
Chris@133 471 virtual void overlayModeChanged();
Chris@133 472 virtual void zoomWheelsEnabledChanged();
Chris@127 473
Chris@797 474 virtual void cancelClicked();
Chris@797 475
Chris@555 476 virtual void progressCheckStalledTimerElapsed();
Chris@555 477
Chris@127 478 protected:
Chris@127 479 View(QWidget *, bool showProgress);
Chris@1030 480
Chris@1030 481 int m_id;
Chris@1030 482
Chris@1406 483 void paintEvent(QPaintEvent *e) override;
Chris@127 484 virtual void drawSelections(QPainter &);
Chris@127 485 virtual bool shouldLabelSelections() const { return true; }
Chris@1357 486 virtual void drawPlayPointer(QPainter &);
Chris@908 487 virtual bool render(QPainter &paint, int x0, sv_frame_t f0, sv_frame_t f1);
Chris@339 488 virtual void setPaintFont(QPainter &paint);
Chris@952 489
Chris@952 490 QSize scaledSize(const QSize &s, int factor) {
Chris@952 491 return QSize(s.width() * factor, s.height() * factor);
Chris@952 492 }
Chris@952 493 QRect scaledRect(const QRect &r, int factor) {
Chris@952 494 return QRect(r.x() * factor, r.y() * factor,
Chris@952 495 r.width() * factor, r.height() * factor);
Chris@952 496 }
Chris@339 497
Chris@127 498 typedef std::vector<Layer *> LayerList;
Chris@127 499
Chris@908 500 sv_samplerate_t getModelsSampleRate() const;
Chris@127 501 bool areLayersScrollable() const;
Chris@127 502 LayerList getScrollableBackLayers(bool testChanged, bool &changed) const;
Chris@127 503 LayerList getNonScrollableFrontLayers(bool testChanged, bool &changed) const;
Chris@1354 504
Chris@1539 505 Layer *getScaleProvidingLayerForUnit(QString unit) const;
Chris@1539 506
Chris@1183 507 ZoomLevel getZoomConstraintLevel(ZoomLevel level,
Chris@1183 508 ZoomConstraint::RoundingDirection dir =
Chris@1183 509 ZoomConstraint::RoundNearest) const;
Chris@127 510
Chris@1354 511 // These three are slow, intended for indexing GUI thumbwheel stuff
Chris@1354 512 int countZoomLevels() const;
Chris@1354 513 int getZoomLevelIndex(ZoomLevel level) const;
Chris@1354 514 ZoomLevel getZoomLevelByIndex(int ix) const;
Chris@1354 515
Chris@183 516 // True if the top layer(s) use colours for meaningful things. If
Chris@183 517 // this is the case, selections will be shown using unfilled boxes
Chris@183 518 // rather than with a translucent fill.
Chris@183 519 bool areLayerColoursSignificant() const;
Chris@183 520
Chris@217 521 // True if the top layer has a time axis on the x coordinate (this
Chris@217 522 // is generally the case except for spectrum/slice layers). It
Chris@217 523 // will not be possible to make or display selections if this is
Chris@217 524 // false.
Chris@217 525 bool hasTopLayerTimeXAxis() const;
Chris@217 526
Chris@902 527 bool setCentreFrame(sv_frame_t f, bool doEmit);
Chris@127 528
Chris@902 529 void movePlayPointer(sv_frame_t f);
Chris@511 530
Chris@1481 531 void checkProgress(ModelId);
Chris@1496 532 void checkAlignmentProgress(ModelId);
Chris@1605 533
Chris@1605 534 bool waitForLayersToBeReady(); // returns false if user cancelled waiting
Chris@1496 535
Chris@384 536 int getProgressBarWidth() const; // if visible
Chris@127 537
Chris@956 538 int effectiveDevicePixelRatio() const;
Chris@956 539
Chris@902 540 sv_frame_t m_centreFrame;
Chris@1183 541 ZoomLevel m_zoomLevel;
Chris@127 542 bool m_followPan;
Chris@127 543 bool m_followZoom;
Chris@127 544 PlaybackFollowMode m_followPlay;
Chris@789 545 bool m_followPlayIsDetached;
Chris@902 546 sv_frame_t m_playPointerFrame;
Chris@127 547 bool m_lightBackground;
Chris@127 548 bool m_showProgress;
Chris@127 549
Chris@1215 550 QPixmap *m_cache; // I own this
Chris@1215 551 QPixmap *m_buffer; // I own this
Chris@1357 552 bool m_cacheValid;
Chris@902 553 sv_frame_t m_cacheCentreFrame;
Chris@1183 554 ZoomLevel m_cacheZoomLevel;
Chris@127 555 bool m_selectionCached;
Chris@127 556
Chris@127 557 bool m_deleting;
Chris@127 558
Chris@835 559 LayerList m_layerStack; // I don't own these, but see dtor note above
Chris@835 560 LayerList m_fixedOrderLayers;
Chris@127 561 bool m_haveSelectedLayer;
Chris@127 562
Chris@1490 563 bool m_useAligningProxy;
Chris@1490 564
Chris@583 565 QString m_lastError;
Chris@583 566
Chris@127 567 // caches for use in getScrollableBackLayers, getNonScrollableFrontLayers
Chris@127 568 mutable LayerList m_lastScrollableBackLayers;
Chris@127 569 mutable LayerList m_lastNonScrollableBackLayers;
Chris@127 570
Chris@555 571 struct ProgressBarRec {
Chris@797 572 QPushButton *cancel;
Chris@555 573 QProgressBar *bar;
Chris@1496 574 int lastStallCheckValue;
Chris@1496 575 QTimer *stallCheckTimer;
Chris@555 576 };
Chris@555 577 typedef std::map<Layer *, ProgressBarRec> ProgressMap;
Chris@1496 578 ProgressMap m_progressBars; // I own the ProgressBarRecs and their contents
Chris@1496 579
Chris@1496 580 struct AlignmentProgressBarRec {
Chris@1496 581 ModelId alignedModel;
Chris@1496 582 QProgressBar *bar;
Chris@1496 583 };
Chris@1496 584 AlignmentProgressBarRec m_alignmentProgressBar;
Chris@127 585
Chris@127 586 ViewManager *m_manager; // I don't own this
Chris@127 587 ViewPropertyContainer *m_propertyContainer; // I own this
Chris@127 588 };
Chris@127 589
Chris@127 590
Chris@127 591 // Use this for delegation, because we can't subclass from
Chris@127 592 // PropertyContainer (which is a QObject) ourselves because of
Chris@127 593 // ambiguity with QFrame parent
Chris@127 594
Chris@127 595 class ViewPropertyContainer : public PropertyContainer
Chris@127 596 {
Chris@127 597 Q_OBJECT
Chris@127 598
Chris@127 599 public:
Chris@127 600 ViewPropertyContainer(View *v);
Chris@728 601 virtual ~ViewPropertyContainer();
Chris@728 602
Chris@1406 603 PropertyList getProperties() const override { return m_v->getProperties(); }
Chris@1406 604 QString getPropertyLabel(const PropertyName &n) const override {
Chris@127 605 return m_v->getPropertyLabel(n);
Chris@127 606 }
Chris@1406 607 PropertyType getPropertyType(const PropertyName &n) const override {
Chris@1266 608 return m_v->getPropertyType(n);
Chris@127 609 }
Chris@216 610 int getPropertyRangeAndValue(const PropertyName &n, int *min, int *max,
Chris@1406 611 int *deflt) const override {
Chris@1266 612 return m_v->getPropertyRangeAndValue(n, min, max, deflt);
Chris@127 613 }
Chris@1406 614 QString getPropertyValueLabel(const PropertyName &n, int value) const override {
Chris@1266 615 return m_v->getPropertyValueLabel(n, value);
Chris@127 616 }
Chris@1406 617 QString getPropertyContainerName() const override {
Chris@1266 618 return m_v->getPropertyContainerName();
Chris@127 619 }
Chris@1406 620 QString getPropertyContainerIconName() const override {
Chris@1266 621 return m_v->getPropertyContainerIconName();
Chris@127 622 }
Chris@127 623
Chris@127 624 public slots:
Chris@1406 625 void setProperty(const PropertyName &n, int value) override {
Chris@1266 626 m_v->setProperty(n, value);
Chris@127 627 }
Chris@127 628
Chris@127 629 protected:
Chris@127 630 View *m_v;
Chris@127 631 };
Chris@127 632
Chris@127 633 #endif
Chris@127 634