annotate layer/Layer.h @ 333:e74b56f07c73

* Some work on correct alignment when moving panes during playback * Overhaul alignment for playback frame values (view manager now always refers to reference-timeline values, only the play source deals in playback model timeline values) * When making a selection, ensure the selection regions shown in other panes (and used for playback constraints if appropriate) are aligned correctly. This may be the coolest feature ever implemented in any program ever.
author Chris Cannam
date Thu, 22 Nov 2007 14:17:19 +0000
parents 984c1975f1ff
children 2f83b6e3b8ca 64e84e5efb76
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 #ifndef _LAYER_H_
Chris@127 17 #define _LAYER_H_
Chris@127 18
Chris@128 19 #include "base/PropertyContainer.h"
Chris@128 20 #include "base/XmlExportable.h"
Chris@128 21 #include "base/Selection.h"
Chris@127 22
Chris@127 23 #include <QObject>
Chris@127 24 #include <QRect>
Chris@127 25 #include <QXmlAttributes>
Chris@131 26 #include <QMutex>
Chris@299 27 #include <QPixmap>
Chris@127 28
Chris@127 29 #include <map>
Chris@268 30 #include <set>
Chris@127 31
Chris@127 32 class ZoomConstraint;
Chris@127 33 class Model;
Chris@127 34 class QPainter;
Chris@127 35 class View;
Chris@127 36 class QMouseEvent;
Chris@127 37 class Clipboard;
Chris@187 38 class RangeMapper;
Chris@127 39
Chris@127 40 /**
Chris@127 41 * The base class for visual representations of the data found in a
Chris@127 42 * Model. Layers are expected to be able to draw themselves onto a
Chris@127 43 * View, and may also be editable.
Chris@127 44 */
Chris@127 45
Chris@127 46 class Layer : public PropertyContainer,
Chris@127 47 public XmlExportable
Chris@127 48 {
Chris@127 49 Q_OBJECT
Chris@127 50
Chris@127 51 public:
Chris@127 52 Layer();
Chris@127 53 virtual ~Layer();
Chris@127 54
Chris@127 55 virtual const Model *getModel() const = 0;
Chris@127 56 virtual Model *getModel() {
Chris@127 57 return const_cast<Model *>(const_cast<const Layer *>(this)->getModel());
Chris@127 58 }
Chris@127 59
Chris@137 60 /**
Chris@137 61 * Return a zoom constraint object defining the supported zoom
Chris@137 62 * levels for this layer. If this returns zero, the layer will
Chris@137 63 * support any integer zoom level.
Chris@137 64 */
Chris@127 65 virtual const ZoomConstraint *getZoomConstraint() const { return 0; }
Chris@137 66
Chris@137 67 /**
Chris@137 68 * Return true if this layer can handle zoom levels other than
Chris@137 69 * those supported by its zoom constraint (presumably less
Chris@137 70 * efficiently or accurately than the officially supported zoom
Chris@137 71 * levels). If true, the layer will unenthusistically accept any
Chris@137 72 * integer zoom level from 1 to the maximum returned by its zoom
Chris@137 73 * constraint.
Chris@137 74 */
Chris@137 75 virtual bool supportsOtherZoomLevels() const { return true; }
Chris@137 76
Chris@127 77 virtual void paint(View *, QPainter &, QRect) const = 0;
Chris@127 78
Chris@127 79 enum VerticalPosition {
Chris@127 80 PositionTop, PositionMiddle, PositionBottom
Chris@127 81 };
Chris@127 82 virtual VerticalPosition getPreferredTimeRulerPosition() const {
Chris@127 83 return PositionMiddle;
Chris@127 84 }
Chris@127 85 virtual VerticalPosition getPreferredFrameCountPosition() const {
Chris@127 86 return PositionBottom;
Chris@127 87 }
Chris@224 88 virtual bool hasLightBackground() const {
Chris@224 89 return true;
Chris@224 90 }
Chris@127 91
Chris@127 92 virtual QString getPropertyContainerIconName() const;
Chris@127 93
Chris@127 94 virtual QString getPropertyContainerName() const {
Chris@127 95 return objectName();
Chris@127 96 }
Chris@127 97
Chris@127 98 virtual QString getLayerPresentationName() const;
Chris@299 99 virtual QPixmap getLayerPresentationPixmap(QSize) const { return QPixmap(); }
Chris@127 100
Chris@127 101 virtual int getVerticalScaleWidth(View *, QPainter &) const { return 0; }
Chris@127 102 virtual void paintVerticalScale(View *, QPainter &, QRect) const { }
Chris@127 103
Chris@127 104 virtual bool getCrosshairExtents(View *, QPainter &, QPoint /* cursorPos */,
Chris@127 105 std::vector<QRect> &) const {
Chris@127 106 return false;
Chris@127 107 }
Chris@127 108 virtual void paintCrosshairs(View *, QPainter &, QPoint) const { }
Chris@127 109
Chris@272 110 virtual void paintMeasurementRects(View *, QPainter &,
Chris@272 111 bool showFocus, QPoint focusPoint) const;
Chris@272 112
Chris@272 113 virtual bool nearestMeasurementRectChanged(View *, QPoint prev,
Chris@272 114 QPoint now) const;
Chris@267 115
Chris@127 116 virtual QString getFeatureDescription(View *, QPoint &) const {
Chris@127 117 return "";
Chris@127 118 }
Chris@127 119
Chris@127 120 enum SnapType {
Chris@127 121 SnapLeft,
Chris@127 122 SnapRight,
Chris@127 123 SnapNearest,
Chris@127 124 SnapNeighbouring
Chris@127 125 };
Chris@127 126
Chris@127 127 /**
Chris@127 128 * Adjust the given frame to snap to the nearest feature, if
Chris@127 129 * possible.
Chris@127 130 *
Chris@127 131 * If snap is SnapLeft or SnapRight, adjust the frame to match
Chris@127 132 * that of the nearest feature in the given direction regardless
Chris@127 133 * of how far away it is. If snap is SnapNearest, adjust the
Chris@127 134 * frame to that of the nearest feature in either direction. If
Chris@127 135 * snap is SnapNeighbouring, adjust the frame to that of the
Chris@127 136 * nearest feature if it is close, and leave it alone (returning
Chris@127 137 * false) otherwise. SnapNeighbouring should always choose the
Chris@127 138 * same feature that would be used in an editing operation through
Chris@127 139 * calls to editStart etc.
Chris@127 140 *
Chris@127 141 * Return true if a suitable feature was found and frame adjusted
Chris@180 142 * accordingly. Return false if no suitable feature was available
Chris@180 143 * (and leave frame unmodified). Also return the resolution of
Chris@180 144 * the model in this layer in sample frames.
Chris@127 145 */
Chris@127 146 virtual bool snapToFeatureFrame(View * /* v */,
Chris@127 147 int & /* frame */,
Chris@127 148 size_t &resolution,
Chris@127 149 SnapType /* snap */) const {
Chris@127 150 resolution = 1;
Chris@127 151 return false;
Chris@127 152 }
Chris@127 153
Chris@127 154 // Draw and edit modes:
Chris@127 155 //
Chris@127 156 // Layer needs to get actual mouse events, I guess. Draw mode is
Chris@127 157 // probably the easier.
Chris@127 158
Chris@127 159 virtual void drawStart(View *, QMouseEvent *) { }
Chris@127 160 virtual void drawDrag(View *, QMouseEvent *) { }
Chris@127 161 virtual void drawEnd(View *, QMouseEvent *) { }
Chris@127 162
Chris@127 163 virtual void editStart(View *, QMouseEvent *) { }
Chris@127 164 virtual void editDrag(View *, QMouseEvent *) { }
Chris@127 165 virtual void editEnd(View *, QMouseEvent *) { }
Chris@127 166
Chris@267 167 // Measurement rectangle (or equivalent). Unlike draw and edit,
Chris@267 168 // the base Layer class can provide working implementations of
Chris@267 169 // these for most situations.
Chris@267 170 //
Chris@267 171 virtual void measureStart(View *, QMouseEvent *);
Chris@267 172 virtual void measureDrag(View *, QMouseEvent *);
Chris@267 173 virtual void measureEnd(View *, QMouseEvent *);
Chris@280 174 virtual void measureDoubleClick(View *, QMouseEvent *);
Chris@267 175
Chris@283 176 virtual bool haveCurrentMeasureRect() const {
Chris@283 177 return m_haveCurrentMeasureRect;
Chris@283 178 }
Chris@283 179 virtual void deleteCurrentMeasureRect(); // using a command
Chris@283 180
Chris@255 181 /**
Chris@255 182 * Open an editor on the item under the mouse (e.g. on
Chris@255 183 * double-click). If there is no item or editing is not
Chris@255 184 * supported, return false.
Chris@255 185 */
Chris@255 186 virtual bool editOpen(View *, QMouseEvent *) { return false; }
Chris@127 187
Chris@127 188 virtual void moveSelection(Selection, size_t /* newStartFrame */) { }
Chris@127 189 virtual void resizeSelection(Selection, Selection /* newSize */) { }
Chris@127 190 virtual void deleteSelection(Selection) { }
Chris@127 191
Chris@127 192 virtual void copy(Selection, Clipboard & /* to */) { }
Chris@127 193
Chris@127 194 /**
Chris@127 195 * Paste from the given clipboard onto the layer at the given
Chris@127 196 * frame offset. If interactive is true, the layer may ask the
Chris@127 197 * user about paste options through a dialog if desired, and may
Chris@127 198 * return false if the user cancelled the paste operation. This
Chris@127 199 * function should return true if a paste actually occurred.
Chris@127 200 */
Chris@127 201 virtual bool paste(const Clipboard & /* from */,
Chris@127 202 int /* frameOffset */,
Chris@127 203 bool /* interactive */) { return false; }
Chris@127 204
Chris@127 205 // Text mode:
Chris@127 206 //
Chris@127 207 // Label nearest feature. We need to get the feature coordinates
Chris@127 208 // and current label from the layer, and then the pane can pop up
Chris@127 209 // a little text entry dialog at the right location. Or we edit
Chris@127 210 // in place? Probably the dialog is easier.
Chris@127 211
Chris@127 212 /**
Chris@127 213 * This should return true if the layer can safely be scrolled
Chris@127 214 * automatically by a given view (simply copying the existing data
Chris@127 215 * and then refreshing the exposed area) without altering its
Chris@127 216 * meaning. For the view widget as a whole this is usually not
Chris@127 217 * possible because of invariant (non-scrolling) material
Chris@127 218 * displayed over the top, but the widget may be able to optimise
Chris@127 219 * scrolling better if it is known that individual views can be
Chris@127 220 * scrolled safely in this way.
Chris@127 221 */
Chris@127 222 virtual bool isLayerScrollable(const View *) const { return true; }
Chris@127 223
Chris@127 224 /**
Chris@127 225 * This should return true if the layer completely obscures any
Chris@127 226 * underlying layers. It's used to determine whether the view can
Chris@127 227 * safely draw any selection rectangles under the layer instead of
Chris@127 228 * over it, in the case where the layer is not scrollable and
Chris@127 229 * therefore needs to be redrawn each time (so that the selection
Chris@127 230 * rectangle can be cached).
Chris@127 231 */
Chris@127 232 virtual bool isLayerOpaque() const { return false; }
Chris@127 233
Chris@287 234 enum ColourSignificance {
Chris@287 235 ColourAbsent,
Chris@287 236 ColourIrrelevant,
Chris@287 237 ColourDistinguishes,
Chris@287 238 ColourAndBackgroundSignificant,
Chris@287 239 ColourHasMeaningfulValue
Chris@287 240 };
Chris@287 241
Chris@127 242 /**
Chris@287 243 * This should return the degree of meaning associated with colour
Chris@287 244 * in this layer.
Chris@287 245 *
Chris@287 246 * If ColourAbsent, the layer does not use colour. If
Chris@287 247 * ColourIrrelevant, the layer is coloured and the colour may be
Chris@287 248 * set by the user, but it doesn't really matter what the colour
Chris@287 249 * is (for example, in a time ruler layer). If
Chris@287 250 * ColourDistinguishes, then the colour is used to distinguish
Chris@287 251 * this layer from other similar layers (e.g. for data layers).
Chris@287 252 * If ColourAndBackgroundSignificant, then the layer should be
Chris@287 253 * given greater weight than ColourDistinguishes layers when
Chris@287 254 * choosing a background colour (e.g. for waveforms). If
Chris@287 255 * ColourHasMeaningfulValue, colours are actually meaningful --
Chris@287 256 * the view will then show selections using unfilled rectangles
Chris@287 257 * instead of translucent filled rectangles, so as not to disturb
Chris@287 258 * the colours underneath.
Chris@183 259 */
Chris@287 260 virtual ColourSignificance getLayerColourSignificance() const = 0;
Chris@183 261
Chris@183 262 /**
Chris@127 263 * This should return true if the layer can be edited by the user.
Chris@127 264 * If this is the case, the appropriate edit tools may be made
Chris@127 265 * available by the application and the layer's drawStart/Drag/End
Chris@127 266 * and editStart/Drag/End methods should be implemented.
Chris@127 267 */
Chris@127 268 virtual bool isLayerEditable() const { return false; }
Chris@127 269
Chris@127 270 /**
Chris@127 271 * Return the proportion of background work complete in drawing
Chris@127 272 * this view, as a percentage -- in most cases this will be the
Chris@127 273 * value returned by pointer from a call to the underlying model's
Chris@226 274 * isReady(int *) call. The view may choose to show a progress
Chris@127 275 * meter if it finds that this returns < 100 at any given moment.
Chris@127 276 */
Chris@127 277 virtual int getCompletion(View *) const { return 100; }
Chris@127 278
Chris@127 279 virtual void setObjectName(const QString &name);
Chris@127 280
Chris@127 281 /**
Chris@127 282 * Convert the layer's data (though not those of the model it
Chris@316 283 * refers to) into XML for file output. This class implements the
Chris@316 284 * basic name/type/model-id output; subclasses will typically call
Chris@316 285 * this superclass implementation with extra attributes describing
Chris@316 286 * their particular properties.
Chris@127 287 */
Chris@316 288 virtual void toXml(QTextStream &stream, QString indent = "",
Chris@316 289 QString extraAttributes = "") const;
Chris@127 290
Chris@127 291 /**
Chris@127 292 * Set the particular properties of a layer (those specific to the
Chris@127 293 * subclass) from a set of XML attributes. This is the effective
Chris@316 294 * inverse of the toXml method.
Chris@127 295 */
Chris@127 296 virtual void setProperties(const QXmlAttributes &) = 0;
Chris@127 297
Chris@127 298 /**
Chris@316 299 * Produce XML containing the layer's ID and type. This is used
Chris@316 300 * to refer to the layer in the display section of the SV session
Chris@316 301 * file, for a layer that has already been described in the data
Chris@316 302 * section.
Chris@269 303 */
Chris@316 304 virtual void toBriefXml(QTextStream &stream,
Chris@316 305 QString indent = "",
Chris@316 306 QString extraAttributes = "") const;
Chris@269 307
Chris@269 308 /**
Chris@269 309 * Add a measurement rectangle from the given XML attributes
Chris@269 310 * (presumably taken from a measurement element).
Chris@269 311 * Does not use a command.
Chris@269 312 */
Chris@269 313 virtual void addMeasurementRect(const QXmlAttributes &);
Chris@269 314
Chris@269 315 /**
Chris@127 316 * Indicate that a layer is not currently visible in the given
Chris@127 317 * view and is not expected to become visible in the near future
Chris@127 318 * (for example because the user has explicitly removed or hidden
Chris@127 319 * it). The layer may respond by (for example) freeing any cache
Chris@127 320 * memory it is using, until next time its paint method is called,
Chris@127 321 * when it should set itself un-dormant again.
Chris@131 322 *
Chris@131 323 * A layer class that overrides this function must also call this
Chris@131 324 * class's implementation.
Chris@127 325 */
Chris@131 326 virtual void setLayerDormant(const View *v, bool dormant);
Chris@127 327
Chris@127 328 /**
Chris@127 329 * Return whether the layer is dormant (i.e. hidden) in the given
Chris@127 330 * view.
Chris@127 331 */
Chris@131 332 virtual bool isLayerDormant(const View *v) const;
Chris@127 333
Chris@127 334 virtual PlayParameters *getPlayParameters();
Chris@127 335
Chris@127 336 virtual bool needsTextLabelHeight() const { return false; }
Chris@127 337
Chris@217 338 virtual bool hasTimeXAxis() const { return true; }
Chris@217 339
Chris@127 340 /**
Chris@127 341 * Return the minimum and maximum values for the y axis of the
Chris@127 342 * model in this layer, as well as whether the layer is configured
Chris@127 343 * to use a logarithmic y axis display. Also return the unit for
Chris@127 344 * these values if known.
Chris@127 345 *
Chris@127 346 * This function returns the "normal" extents for the layer, not
Chris@127 347 * necessarily the extents actually in use in the display.
Chris@127 348 */
Chris@127 349 virtual bool getValueExtents(float &min, float &max,
Chris@127 350 bool &logarithmic, QString &unit) const = 0;
Chris@127 351
Chris@127 352 /**
Chris@127 353 * Return the minimum and maximum values within the displayed
Chris@127 354 * range for the y axis, if only a subset of the whole range of
Chris@127 355 * the model (returned by getValueExtents) is being displayed.
Chris@127 356 * Return false if the layer is not imposing a particular display
Chris@127 357 * extent (using the normal layer extents or deferring to whatever
Chris@127 358 * is in use for the same units elsewhere in the view).
Chris@127 359 */
Chris@127 360 virtual bool getDisplayExtents(float & /* min */,
Chris@127 361 float & /* max */) const {
Chris@127 362 return false;
Chris@127 363 }
Chris@127 364
Chris@127 365 /**
Chris@127 366 * Set the displayed minimum and maximum values for the y axis to
Chris@127 367 * the given range, if supported. Return false if not supported
Chris@127 368 * on this layer (and set nothing). In most cases, layers that
Chris@127 369 * return false for getDisplayExtents should also return false for
Chris@127 370 * this function.
Chris@127 371 */
Chris@127 372 virtual bool setDisplayExtents(float /* min */,
Chris@127 373 float /* max */) {
Chris@127 374 return false;
Chris@127 375 }
Chris@127 376
Chris@133 377 /**
Chris@260 378 * Return the value and unit at the given x coordinate in the
Chris@260 379 * given view. This is for descriptive purposes using the
Chris@260 380 * measurement tool. The default implementation works correctly
Chris@260 381 * if the layer hasTimeXAxis().
Chris@260 382 */
Chris@267 383 virtual bool getXScaleValue(const View *v, int x,
Chris@260 384 float &value, QString &unit) const;
Chris@260 385
Chris@260 386 /**
Chris@260 387 * Return the value and unit at the given y coordinate in the
Chris@260 388 * given view.
Chris@260 389 */
Chris@267 390 virtual bool getYScaleValue(const View *, int /* y */,
Chris@260 391 float &/* value */, QString &/* unit */) const {
Chris@260 392 return false;
Chris@260 393 }
Chris@260 394
Chris@260 395 /**
Chris@274 396 * Return the difference between the values at the given y
Chris@274 397 * coordinates in the given view, and the unit of the difference.
Chris@274 398 * The default implementation just calls getYScaleValue twice and
Chris@274 399 * returns the difference, with the same unit.
Chris@274 400 */
Chris@274 401 virtual bool getYScaleDifference(const View *v, int y0, int y1,
Chris@274 402 float &diff, QString &unit) const;
Chris@274 403
Chris@274 404 /**
Chris@133 405 * Get the number of vertical zoom steps available for this layer.
Chris@133 406 * If vertical zooming is not available, return 0. The meaning of
Chris@133 407 * "zooming" is entirely up to the layer -- changing the zoom
Chris@133 408 * level may cause the layer to reset its display extents or
Chris@180 409 * change another property such as display gain. However, layers
Chris@180 410 * are advised for consistency to treat smaller zoom steps as
Chris@180 411 * "more distant" or "zoomed out" and larger ones as "closer" or
Chris@180 412 * "zoomed in".
Chris@180 413 *
Chris@133 414 * Layers that provide this facility should also emit the
Chris@133 415 * verticalZoomChanged signal if their vertical zoom changes
Chris@133 416 * due to factors other than setVerticalZoomStep being called.
Chris@133 417 */
Chris@248 418 virtual int getVerticalZoomSteps(int & /* defaultStep */) const { return 0; }
Chris@133 419
Chris@133 420 /**
Chris@133 421 * Get the current vertical zoom step. A layer may support finer
Chris@133 422 * control over ranges etc than is available through the integer
Chris@133 423 * zoom step mechanism; if this one does, it should just return
Chris@133 424 * the nearest of the available zoom steps to the current settings.
Chris@133 425 */
Chris@133 426 virtual int getCurrentVerticalZoomStep() const { return 0; }
Chris@133 427
Chris@133 428 /**
Chris@133 429 * Set the vertical zoom step. The meaning of "zooming" is
Chris@133 430 * entirely up to the layer -- changing the zoom level may cause
Chris@133 431 * the layer to reset its display extents or change another
Chris@133 432 * property such as display gain.
Chris@133 433 */
Chris@133 434 virtual void setVerticalZoomStep(int) { }
Chris@133 435
Chris@187 436 /**
Chris@187 437 * Create and return a range mapper for vertical zoom step values.
Chris@187 438 * See the RangeMapper documentation for more details. The
Chris@187 439 * returned value is allocated on the heap and will be deleted by
Chris@187 440 * the caller.
Chris@187 441 */
Chris@187 442 virtual RangeMapper *getNewVerticalZoomRangeMapper() const { return 0; }
Chris@187 443
Chris@127 444 public slots:
Chris@127 445 void showLayer(View *, bool show);
Chris@127 446
Chris@127 447 signals:
Chris@127 448 void modelChanged();
Chris@127 449 void modelCompletionChanged();
Chris@320 450 void modelAlignmentCompletionChanged();
Chris@127 451 void modelChanged(size_t startFrame, size_t endFrame);
Chris@127 452 void modelReplaced();
Chris@127 453
Chris@127 454 void layerParametersChanged();
Chris@197 455 void layerParameterRangesChanged();
Chris@268 456 void layerMeasurementRectsChanged();
Chris@127 457 void layerNameChanged();
Chris@127 458
Chris@133 459 void verticalZoomChanged();
Chris@133 460
Chris@267 461 protected:
Chris@320 462 void connectSignals(const Model *);
Chris@320 463
Chris@267 464 struct MeasureRect {
Chris@268 465
Chris@267 466 mutable QRect pixrect;
Chris@268 467 bool haveFrames;
Chris@268 468 long startFrame; // only valid if haveFrames
Chris@267 469 long endFrame; // ditto
Chris@273 470 double startY;
Chris@273 471 double endY;
Chris@268 472
Chris@268 473 bool operator<(const MeasureRect &mr) const;
Chris@316 474 void toXml(QTextStream &stream, QString indent) const;
Chris@267 475 };
Chris@267 476
Chris@268 477 class AddMeasurementRectCommand : public Command
Chris@268 478 {
Chris@268 479 public:
Chris@268 480 AddMeasurementRectCommand(Layer *layer, MeasureRect rect) :
Chris@268 481 m_layer(layer), m_rect(rect) { }
Chris@268 482
Chris@268 483 virtual QString getName() const;
Chris@268 484 virtual void execute();
Chris@268 485 virtual void unexecute();
Chris@268 486
Chris@268 487 private:
Chris@268 488 Layer *m_layer;
Chris@268 489 MeasureRect m_rect;
Chris@268 490 };
Chris@268 491
Chris@283 492 class DeleteMeasurementRectCommand : public Command
Chris@283 493 {
Chris@283 494 public:
Chris@283 495 DeleteMeasurementRectCommand(Layer *layer, MeasureRect rect) :
Chris@283 496 m_layer(layer), m_rect(rect) { }
Chris@283 497
Chris@283 498 virtual QString getName() const;
Chris@283 499 virtual void execute();
Chris@283 500 virtual void unexecute();
Chris@283 501
Chris@283 502 private:
Chris@283 503 Layer *m_layer;
Chris@283 504 MeasureRect m_rect;
Chris@283 505 };
Chris@283 506
Chris@269 507 void addMeasureRectToSet(const MeasureRect &r) {
Chris@268 508 m_measureRects.insert(r);
Chris@268 509 emit layerMeasurementRectsChanged();
Chris@268 510 }
Chris@268 511
Chris@269 512 void deleteMeasureRectFromSet(const MeasureRect &r) {
Chris@268 513 m_measureRects.erase(r);
Chris@268 514 emit layerMeasurementRectsChanged();
Chris@268 515 }
Chris@268 516
Chris@268 517 typedef std::set<MeasureRect> MeasureRectSet;
Chris@268 518 MeasureRectSet m_measureRects;
Chris@267 519 MeasureRect m_draggingRect;
Chris@267 520 bool m_haveDraggingRect;
Chris@283 521 mutable bool m_haveCurrentMeasureRect;
Chris@283 522 mutable QPoint m_currentMeasureRectPoint;
Chris@272 523
Chris@272 524 // Note that pixrects are only correct for a single view.
Chris@272 525 // So we should update them at the start of the paint procedure
Chris@272 526 // (painting is single threaded) and only use them after that.
Chris@273 527 void updateMeasurePixrects(View *v) const;
Chris@273 528
Chris@273 529 virtual void updateMeasureRectYCoords(View *v, const MeasureRect &r) const;
Chris@273 530 virtual void setMeasureRectYCoord(View *v, MeasureRect &r, bool start, int y) const;
Chris@283 531 virtual void setMeasureRectFromPixrect(View *v, MeasureRect &r, QRect pixrect) const;
Chris@272 532
Chris@272 533 // This assumes updateMeasurementPixrects has been called
Chris@272 534 MeasureRectSet::const_iterator findFocusedMeasureRect(QPoint) const;
Chris@267 535
Chris@269 536 void paintMeasurementRect(View *v, QPainter &paint,
Chris@270 537 const MeasureRect &r, bool focus) const;
Chris@268 538
Chris@131 539 private:
Chris@131 540 mutable QMutex m_dormancyMutex;
Chris@127 541 mutable std::map<const void *, bool> m_dormancy;
Chris@127 542 };
Chris@127 543
Chris@127 544 #endif
Chris@127 545