annotate layer/Layer.h @ 312:6de6f78b13a1

* Make it possible to drop audio files, layer files, session files and images onto SV panes. Need to do a bit more work on where we expect the dropped file to go, particularly in the case of audio files -- at the moment they're always opened in new panes, but it may be better to by default replace whatever is in the target pane.
author Chris Cannam
date Wed, 10 Oct 2007 15:18:02 +0000
parents 5c59c433b358
children c0b9eec70639
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@127 283 * refers to) into an XML string for file output. This class
Chris@127 284 * implements the basic name/type/model-id output; subclasses will
Chris@127 285 * typically call this superclass implementation with extra
Chris@127 286 * attributes describing their particular properties.
Chris@127 287 */
Chris@127 288 virtual QString toXmlString(QString indent = "",
Chris@127 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@127 294 * inverse of the toXmlString method.
Chris@127 295 */
Chris@127 296 virtual void setProperties(const QXmlAttributes &) = 0;
Chris@127 297
Chris@127 298 /**
Chris@269 299 * Produce an XML string containing the layer's ID and type. This
Chris@269 300 * is used to refer to the layer in the display section of the SV
Chris@269 301 * session file, for a layer that has already been described in
Chris@269 302 * the data section.
Chris@269 303 */
Chris@269 304 virtual QString toBriefXmlString(QString indent = "",
Chris@269 305 QString extraAttributes = "") const;
Chris@269 306
Chris@269 307 /**
Chris@269 308 * Add a measurement rectangle from the given XML attributes
Chris@269 309 * (presumably taken from a measurement element).
Chris@269 310 * Does not use a command.
Chris@269 311 */
Chris@269 312 virtual void addMeasurementRect(const QXmlAttributes &);
Chris@269 313
Chris@269 314 /**
Chris@127 315 * Indicate that a layer is not currently visible in the given
Chris@127 316 * view and is not expected to become visible in the near future
Chris@127 317 * (for example because the user has explicitly removed or hidden
Chris@127 318 * it). The layer may respond by (for example) freeing any cache
Chris@127 319 * memory it is using, until next time its paint method is called,
Chris@127 320 * when it should set itself un-dormant again.
Chris@131 321 *
Chris@131 322 * A layer class that overrides this function must also call this
Chris@131 323 * class's implementation.
Chris@127 324 */
Chris@131 325 virtual void setLayerDormant(const View *v, bool dormant);
Chris@127 326
Chris@127 327 /**
Chris@127 328 * Return whether the layer is dormant (i.e. hidden) in the given
Chris@127 329 * view.
Chris@127 330 */
Chris@131 331 virtual bool isLayerDormant(const View *v) const;
Chris@127 332
Chris@127 333 virtual PlayParameters *getPlayParameters();
Chris@127 334
Chris@127 335 virtual bool needsTextLabelHeight() const { return false; }
Chris@127 336
Chris@217 337 virtual bool hasTimeXAxis() const { return true; }
Chris@217 338
Chris@127 339 /**
Chris@127 340 * Return the minimum and maximum values for the y axis of the
Chris@127 341 * model in this layer, as well as whether the layer is configured
Chris@127 342 * to use a logarithmic y axis display. Also return the unit for
Chris@127 343 * these values if known.
Chris@127 344 *
Chris@127 345 * This function returns the "normal" extents for the layer, not
Chris@127 346 * necessarily the extents actually in use in the display.
Chris@127 347 */
Chris@127 348 virtual bool getValueExtents(float &min, float &max,
Chris@127 349 bool &logarithmic, QString &unit) const = 0;
Chris@127 350
Chris@127 351 /**
Chris@127 352 * Return the minimum and maximum values within the displayed
Chris@127 353 * range for the y axis, if only a subset of the whole range of
Chris@127 354 * the model (returned by getValueExtents) is being displayed.
Chris@127 355 * Return false if the layer is not imposing a particular display
Chris@127 356 * extent (using the normal layer extents or deferring to whatever
Chris@127 357 * is in use for the same units elsewhere in the view).
Chris@127 358 */
Chris@127 359 virtual bool getDisplayExtents(float & /* min */,
Chris@127 360 float & /* max */) const {
Chris@127 361 return false;
Chris@127 362 }
Chris@127 363
Chris@127 364 /**
Chris@127 365 * Set the displayed minimum and maximum values for the y axis to
Chris@127 366 * the given range, if supported. Return false if not supported
Chris@127 367 * on this layer (and set nothing). In most cases, layers that
Chris@127 368 * return false for getDisplayExtents should also return false for
Chris@127 369 * this function.
Chris@127 370 */
Chris@127 371 virtual bool setDisplayExtents(float /* min */,
Chris@127 372 float /* max */) {
Chris@127 373 return false;
Chris@127 374 }
Chris@127 375
Chris@133 376 /**
Chris@260 377 * Return the value and unit at the given x coordinate in the
Chris@260 378 * given view. This is for descriptive purposes using the
Chris@260 379 * measurement tool. The default implementation works correctly
Chris@260 380 * if the layer hasTimeXAxis().
Chris@260 381 */
Chris@267 382 virtual bool getXScaleValue(const View *v, int x,
Chris@260 383 float &value, QString &unit) const;
Chris@260 384
Chris@260 385 /**
Chris@260 386 * Return the value and unit at the given y coordinate in the
Chris@260 387 * given view.
Chris@260 388 */
Chris@267 389 virtual bool getYScaleValue(const View *, int /* y */,
Chris@260 390 float &/* value */, QString &/* unit */) const {
Chris@260 391 return false;
Chris@260 392 }
Chris@260 393
Chris@260 394 /**
Chris@274 395 * Return the difference between the values at the given y
Chris@274 396 * coordinates in the given view, and the unit of the difference.
Chris@274 397 * The default implementation just calls getYScaleValue twice and
Chris@274 398 * returns the difference, with the same unit.
Chris@274 399 */
Chris@274 400 virtual bool getYScaleDifference(const View *v, int y0, int y1,
Chris@274 401 float &diff, QString &unit) const;
Chris@274 402
Chris@274 403 /**
Chris@133 404 * Get the number of vertical zoom steps available for this layer.
Chris@133 405 * If vertical zooming is not available, return 0. The meaning of
Chris@133 406 * "zooming" is entirely up to the layer -- changing the zoom
Chris@133 407 * level may cause the layer to reset its display extents or
Chris@180 408 * change another property such as display gain. However, layers
Chris@180 409 * are advised for consistency to treat smaller zoom steps as
Chris@180 410 * "more distant" or "zoomed out" and larger ones as "closer" or
Chris@180 411 * "zoomed in".
Chris@180 412 *
Chris@133 413 * Layers that provide this facility should also emit the
Chris@133 414 * verticalZoomChanged signal if their vertical zoom changes
Chris@133 415 * due to factors other than setVerticalZoomStep being called.
Chris@133 416 */
Chris@248 417 virtual int getVerticalZoomSteps(int & /* defaultStep */) const { return 0; }
Chris@133 418
Chris@133 419 /**
Chris@133 420 * Get the current vertical zoom step. A layer may support finer
Chris@133 421 * control over ranges etc than is available through the integer
Chris@133 422 * zoom step mechanism; if this one does, it should just return
Chris@133 423 * the nearest of the available zoom steps to the current settings.
Chris@133 424 */
Chris@133 425 virtual int getCurrentVerticalZoomStep() const { return 0; }
Chris@133 426
Chris@133 427 /**
Chris@133 428 * Set the vertical zoom step. The meaning of "zooming" is
Chris@133 429 * entirely up to the layer -- changing the zoom level may cause
Chris@133 430 * the layer to reset its display extents or change another
Chris@133 431 * property such as display gain.
Chris@133 432 */
Chris@133 433 virtual void setVerticalZoomStep(int) { }
Chris@133 434
Chris@187 435 /**
Chris@187 436 * Create and return a range mapper for vertical zoom step values.
Chris@187 437 * See the RangeMapper documentation for more details. The
Chris@187 438 * returned value is allocated on the heap and will be deleted by
Chris@187 439 * the caller.
Chris@187 440 */
Chris@187 441 virtual RangeMapper *getNewVerticalZoomRangeMapper() const { return 0; }
Chris@187 442
Chris@127 443 public slots:
Chris@127 444 void showLayer(View *, bool show);
Chris@127 445
Chris@127 446 signals:
Chris@127 447 void modelChanged();
Chris@127 448 void modelCompletionChanged();
Chris@127 449 void modelChanged(size_t startFrame, size_t endFrame);
Chris@127 450 void modelReplaced();
Chris@127 451
Chris@127 452 void layerParametersChanged();
Chris@197 453 void layerParameterRangesChanged();
Chris@268 454 void layerMeasurementRectsChanged();
Chris@127 455 void layerNameChanged();
Chris@127 456
Chris@133 457 void verticalZoomChanged();
Chris@133 458
Chris@267 459 protected:
Chris@267 460 struct MeasureRect {
Chris@268 461
Chris@267 462 mutable QRect pixrect;
Chris@268 463 bool haveFrames;
Chris@268 464 long startFrame; // only valid if haveFrames
Chris@267 465 long endFrame; // ditto
Chris@273 466 double startY;
Chris@273 467 double endY;
Chris@268 468
Chris@268 469 bool operator<(const MeasureRect &mr) const;
Chris@269 470 QString toXmlString(QString indent) const;
Chris@267 471 };
Chris@267 472
Chris@268 473 class AddMeasurementRectCommand : public Command
Chris@268 474 {
Chris@268 475 public:
Chris@268 476 AddMeasurementRectCommand(Layer *layer, MeasureRect rect) :
Chris@268 477 m_layer(layer), m_rect(rect) { }
Chris@268 478
Chris@268 479 virtual QString getName() const;
Chris@268 480 virtual void execute();
Chris@268 481 virtual void unexecute();
Chris@268 482
Chris@268 483 private:
Chris@268 484 Layer *m_layer;
Chris@268 485 MeasureRect m_rect;
Chris@268 486 };
Chris@268 487
Chris@283 488 class DeleteMeasurementRectCommand : public Command
Chris@283 489 {
Chris@283 490 public:
Chris@283 491 DeleteMeasurementRectCommand(Layer *layer, MeasureRect rect) :
Chris@283 492 m_layer(layer), m_rect(rect) { }
Chris@283 493
Chris@283 494 virtual QString getName() const;
Chris@283 495 virtual void execute();
Chris@283 496 virtual void unexecute();
Chris@283 497
Chris@283 498 private:
Chris@283 499 Layer *m_layer;
Chris@283 500 MeasureRect m_rect;
Chris@283 501 };
Chris@283 502
Chris@269 503 void addMeasureRectToSet(const MeasureRect &r) {
Chris@268 504 m_measureRects.insert(r);
Chris@268 505 emit layerMeasurementRectsChanged();
Chris@268 506 }
Chris@268 507
Chris@269 508 void deleteMeasureRectFromSet(const MeasureRect &r) {
Chris@268 509 m_measureRects.erase(r);
Chris@268 510 emit layerMeasurementRectsChanged();
Chris@268 511 }
Chris@268 512
Chris@268 513 typedef std::set<MeasureRect> MeasureRectSet;
Chris@268 514 MeasureRectSet m_measureRects;
Chris@267 515 MeasureRect m_draggingRect;
Chris@267 516 bool m_haveDraggingRect;
Chris@283 517 mutable bool m_haveCurrentMeasureRect;
Chris@283 518 mutable QPoint m_currentMeasureRectPoint;
Chris@272 519
Chris@272 520 // Note that pixrects are only correct for a single view.
Chris@272 521 // So we should update them at the start of the paint procedure
Chris@272 522 // (painting is single threaded) and only use them after that.
Chris@273 523 void updateMeasurePixrects(View *v) const;
Chris@273 524
Chris@273 525 virtual void updateMeasureRectYCoords(View *v, const MeasureRect &r) const;
Chris@273 526 virtual void setMeasureRectYCoord(View *v, MeasureRect &r, bool start, int y) const;
Chris@283 527 virtual void setMeasureRectFromPixrect(View *v, MeasureRect &r, QRect pixrect) const;
Chris@272 528
Chris@272 529 // This assumes updateMeasurementPixrects has been called
Chris@272 530 MeasureRectSet::const_iterator findFocusedMeasureRect(QPoint) const;
Chris@267 531
Chris@269 532 void paintMeasurementRect(View *v, QPainter &paint,
Chris@270 533 const MeasureRect &r, bool focus) const;
Chris@268 534
Chris@131 535 private:
Chris@131 536 mutable QMutex m_dormancyMutex;
Chris@127 537 mutable std::map<const void *, bool> m_dormancy;
Chris@127 538 };
Chris@127 539
Chris@127 540 #endif
Chris@127 541