annotate layer/Layer.h @ 378:22b72f0f6a4e

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