-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqgscolorwidgets.h
798 lines (622 loc) · 22 KB
/
qgscolorwidgets.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
/***************************************************************************
qgscolorwidgets.h - color selection widgets
---------------------
begin : September 2014
copyright : (C) 2014 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSCOLORWIDGETS_H
#define QGSCOLORWIDGETS_H
#include <QWidgetAction>
#include <QWidget>
#include "qgis_gui.h"
#include "qgis.h"
class QColor;
class QSpinBox;
class QLineEdit;
class QToolButton;
/**
* \ingroup gui
* \class QgsColorWidget
* A base class for interactive color widgets. Widgets can either allow setting a single component of
* a color (e.g., the red or green components), or an entire color. The QgsColorWidget also keeps track of
* any explicitly set hue for the color, so that this information is not lost when the widget is
* set to a color with an ambiguous hue (e.g., black or white shades).
* \since QGIS 2.5
*/
class GUI_EXPORT QgsColorWidget : public QWidget
{
Q_OBJECT
public:
/**
* Specifies the color component which the widget alters
*/
enum ColorComponent
{
Multiple = 0, //!< Widget alters multiple color components
Red, //!< Red component of color
Green, //!< Green component of color
Blue, //!< Blue component of color
Hue, //!< Hue component of color (based on HSV model)
Saturation, //!< Saturation component of color (based on HSV model)
Value, //!< Value component of color (based on HSV model)
Alpha //!< Alpha component (opacity) of color
};
/**
* Construct a new color widget.
* \param parent parent QWidget for the widget
* \param component color component the widget alters
*/
QgsColorWidget( QWidget *parent SIP_TRANSFERTHIS = nullptr, const ColorComponent component = Multiple );
/**
* Returns the current color for the widget
* \returns current widget color
* \see setColor
*/
QColor color() const;
/**
* Returns the color component which the widget controls
* \returns color component for widget
* \see setComponent
*/
ColorComponent component() const { return mComponent; }
/**
* Returns the current value of the widget's color component
* \returns value of color component, or -1 if widget has multiple components or an invalid color
* set
* \see setComponentValue
* \see component
*/
int componentValue() const;
/**
* Create an icon for dragging colors
* \param color for icon
*/
static QPixmap createDragIcon( const QColor &color );
public slots:
/**
* Sets the color for the widget
* \param color widget color
* \param emitSignals set to true to emit the colorChanged signal after setting color
* \see color
*/
virtual void setColor( const QColor &color, const bool emitSignals = false );
/**
* Sets the color component which the widget controls
* \param component color component for widget
* \see component
*/
virtual void setComponent( const ColorComponent component );
/**
* Alters the widget's color by setting the value for the widget's color component
* \param value value for widget's color component. This value is automatically
* clipped to the range of valid values for the color component.
* \see componentValue
* \see setComponent
* \note this method has no effect if the widget is set to the QgsColorWidget::Multiple
* component
*/
virtual void setComponentValue( const int value );
signals:
/**
* Emitted when the widget's color changes
* \param color new widget color
*/
void colorChanged( const QColor &color );
/**
* Emitted when mouse hovers over widget.
* \since QGIS 2.14
*/
void hovered();
protected:
QColor mCurrentColor;
ColorComponent mComponent;
/**
* QColor wipes the hue information when it is ambiguous (e.g., for saturation = 0). So
* the hue is stored in mExplicit hue to keep it around, as it is useful when modifying colors
*/
int mExplicitHue = 0;
/**
* Returns the range of valid values for the color widget's component
* \returns maximum value allowed for color component, or -1 if widget has multiple components
*/
int componentRange() const;
/**
* Returns the range of valid values a color component
* \returns maximum value allowed for color component
*/
int componentRange( const ColorComponent component ) const;
/**
* Returns the value of a component of the widget's current color. This method correctly
* handles hue values when the color has an ambiguous hue (e.g., black or white shades)
* \param component color component to return
* \returns value of color component, or -1 if widget has an invalid color set
* \see hue
*/
int componentValue( const ColorComponent component ) const;
/**
* Returns the hue for the widget. This may differ from the hue for the QColor returned by color(),
* as QColor returns a hue of -1 if the color's hue is ambiguous (e.g., if the saturation is zero).
* \returns explicitly set hue for widget
*/
int hue() const;
/**
* Alters a color by modifiying the value of a specific color component
* \param color color to alter
* \param component color component to alter
* \param newValue new value of color component. Values are automatically clipped to a
* valid range for the color component.
*/
void alterColor( QColor &color, const QgsColorWidget::ColorComponent component, const int newValue ) const;
/**
* Generates a checkboard pattern pixmap for use as a background to transparent colors
* \returns checkerboard pixmap
*/
static const QPixmap &transparentBackground();
//Reimplemented to accept dragged colors
void dragEnterEvent( QDragEnterEvent *e ) override;
//Reimplemented to accept dropped colors
void dropEvent( QDropEvent *e ) override;
void mouseMoveEvent( QMouseEvent *e ) override;
void mousePressEvent( QMouseEvent *e ) override;
void mouseReleaseEvent( QMouseEvent *e ) override;
};
/**
* \ingroup gui
* \class QgsColorWidgetAction
* An action containing a color widget, which can be embedded into a menu.
* \see QgsColorWidget
* \since QGIS 2.14
*/
class GUI_EXPORT QgsColorWidgetAction: public QWidgetAction
{
Q_OBJECT
public:
/**
* Construct a new color widget action.
* \param colorWidget QgsColorWidget to show in action
* \param menu parent menu
* \param parent parent widget
*/
QgsColorWidgetAction( QgsColorWidget *colorWidget, QMenu *menu = nullptr, QWidget *parent SIP_TRANSFERTHIS = nullptr );
/**
* Returns the color widget contained in the widget action.
*/
QgsColorWidget *colorWidget() { return mColorWidget; }
/**
* Sets whether the parent menu should be dismissed and closed when a color is selected
* from the action's color widget.
* \param dismiss set to true (default) to immediately close the menu when a color is selected
* from the widget. If set to false, the colorChanged signal will be emitted but the menu will
* stay open.
* \see dismissOnColorSelection()
*/
void setDismissOnColorSelection( bool dismiss ) { mDismissOnColorSelection = dismiss; }
/**
* Returns whether the parent menu will be dismissed after a color is selected from the
* action's color widget.
* \see setDismissOnColorSelection
*/
bool dismissOnColorSelection() const { return mDismissOnColorSelection; }
signals:
/**
* Emitted when a color has been selected from the widget
* \param color selected color
*/
void colorChanged( const QColor &color );
private:
QMenu *mMenu = nullptr;
QgsColorWidget *mColorWidget = nullptr;
//used to suppress recursion with hover events
bool mSuppressRecurse;
bool mDismissOnColorSelection;
private slots:
/**
* Handles setting the active action for the menu when cursor hovers over color widget
*/
void onHover();
/**
* Emits color changed signal and closes parent menu
*/
void setColor( const QColor &color );
};
/**
* \ingroup gui
* \class QgsColorWheel
* A color wheel widget. This widget consists of an outer ring which allows for hue selection, and an
* inner rotating triangle which allows for saturation and value selection.
* \since QGIS 2.5
*/
class GUI_EXPORT QgsColorWheel : public QgsColorWidget
{
Q_OBJECT
public:
/**
* Constructs a new color wheel widget.
* \param parent parent QWidget for the widget
*/
QgsColorWheel( QWidget *parent SIP_TRANSFERTHIS = nullptr );
~QgsColorWheel() override;
QSize sizeHint() const override;
void paintEvent( QPaintEvent *event ) override;
public slots:
void setColor( const QColor &color, const bool emitSignals = false ) override;
protected:
void resizeEvent( QResizeEvent *event ) override;
void mouseMoveEvent( QMouseEvent *event ) override;
void mousePressEvent( QMouseEvent *event ) override;
void mouseReleaseEvent( QMouseEvent *event ) override;
private:
enum ControlPart
{
None,
Wheel,
Triangle
};
/*Margin between outer ring and edge of widget*/
int mMargin = 4;
/*Thickness of hue ring in pixels*/
int mWheelThickness = 18;
/*Part of the wheel where the mouse was originally depressed*/
ControlPart mClickedPart = QgsColorWheel::None;
/*Cached image of hue wheel*/
QImage *mWheelImage = nullptr;
/*Cached image of inner triangle*/
QImage *mTriangleImage = nullptr;
/*Resuable, temporary image for drawing widget*/
QImage *mWidgetImage = nullptr;
/*Whether the color wheel image requires redrawing*/
bool mWheelDirty = true;
/*Whether the inner triangle image requires redrawing*/
bool mTriangleDirty = true;
/*Conical gradient brush used for drawing hue wheel*/
QBrush mWheelBrush;
/**
* Creates cache images for specified widget size
* \param size widget size for images
*/
void createImages( const QSizeF size );
//! Creates the hue wheel image
void createWheel();
//! Creates the inner triangle image
void createTriangle();
/**
* Sets the widget color based on a point in the widget
* \param pos position for color
*/
void setColorFromPos( const QPointF pos );
};
/**
* \ingroup gui
* \class QgsColorBox
* A color box widget. This widget consists of a two dimensional rectangle filled with color
* variations, where a different color component varies along both the horizontal and vertical
* axis.
* \since QGIS 2.5
*/
class GUI_EXPORT QgsColorBox : public QgsColorWidget
{
Q_OBJECT
public:
/**
* Construct a new color box widget.
* \param parent parent QWidget for the widget
* \param component constant color component for the widget. The color components
* which vary along the horizontal and vertical axis are automatically assigned
* based on this constant color component.
*/
QgsColorBox( QWidget *parent SIP_TRANSFERTHIS = nullptr, const ColorComponent component = Value );
~QgsColorBox() override;
QSize sizeHint() const override;
void paintEvent( QPaintEvent *event ) override;
void setComponent( const ColorComponent component ) override;
public slots:
void setColor( const QColor &color, const bool emitSignals = false ) override;
protected:
void resizeEvent( QResizeEvent *event ) override;
void mouseMoveEvent( QMouseEvent *event ) override;
void mousePressEvent( QMouseEvent *event ) override;
private:
/*Margin between outer ring and edge of widget*/
int mMargin = 2;
/*Cached image for color box*/
QImage *mBoxImage = nullptr;
/*Whether the cached image requires redrawing*/
bool mDirty = true;
/**
* Creates the color box background cached image
*/
void createBox();
/**
* Returns the range of permissible values along the x axis
* \returns maximum color component value for x axis
*/
int valueRangeX() const;
/**
* Returns the range of permissible values along the y axis
* \returns maximum color component value for y axis
*/
int valueRangeY() const;
/**
* Returns the color component which varies along the y axis
*/
QgsColorWidget::ColorComponent yComponent() const;
/**
* Returns the value of the color component which varies along the y axis
*/
int yComponentValue() const;
/**
* Returns the color component which varies along the x axis
*/
QgsColorWidget::ColorComponent xComponent() const;
/**
* Returns the value of the color component which varies along the x axis
*/
int xComponentValue() const;
/**
* Updates the widget's color based on a point within the widget
* \param point point within the widget
*/
void setColorFromPoint( QPoint point );
};
/**
* \ingroup gui
* \class QgsColorRampWidget
* A color ramp widget. This widget consists of an interactive box filled with a color which varies along
* its length by a single color component (e.g., varying saturation from 0 to 100%).
* \since QGIS 2.5
*/
class GUI_EXPORT QgsColorRampWidget : public QgsColorWidget
{
Q_OBJECT
public:
/**
* Specifies the orientation of a color ramp
*/
enum Orientation
{
Horizontal = 0, //!< Horizontal ramp
Vertical //!< Vertical ramp
};
/**
* Construct a new color ramp widget.
* \param parent parent QWidget for the widget
* \param component color component which varies along the ramp
* \param orientation orientation for widget
*/
QgsColorRampWidget( QWidget *parent SIP_TRANSFERTHIS = nullptr,
const ColorComponent component = QgsColorWidget::Red,
const Orientation orientation = QgsColorRampWidget::Horizontal );
QSize sizeHint() const override;
void paintEvent( QPaintEvent *event ) override;
/**
* Sets the orientation for the color ramp
* \param orientation new orientation for the ramp
* \see orientation
*/
void setOrientation( const Orientation orientation );
/**
* Fetches the orientation for the color ramp
* \returns orientation for the ramp
* \see setOrientation
*/
Orientation orientation() const { return mOrientation; }
/**
* Sets the margin between the edge of the widget and the ramp
* \param margin margin around the ramp
* \see interiorMargin
*/
void setInteriorMargin( const int margin );
/**
* Fetches the margin between the edge of the widget and the ramp
* \returns margin around the ramp
* \see setInteriorMargin
*/
int interiorMargin() const { return mMargin; }
/**
* Sets whether the ramp should be drawn within a frame
* \param showFrame set to true to draw a frame around the ramp
* \see showFrame
*/
void setShowFrame( const bool showFrame );
/**
* Fetches whether the ramp is drawn within a frame
* \returns true if a frame is drawn around the ramp
* \see setShowFrame
*/
bool showFrame() const { return mShowFrame; }
/**
* Sets the size for drawing the triangular markers on the ramp
* \param markerSize marker size in pixels
*/
void setMarkerSize( const int markerSize );
signals:
/**
* Emitted when the widget's color component value changes
* \param value new value of color component
*/
void valueChanged( const int value );
protected:
void mouseMoveEvent( QMouseEvent *event ) override;
void wheelEvent( QWheelEvent *event ) override;
void mousePressEvent( QMouseEvent *event ) override;
void keyPressEvent( QKeyEvent *event ) override;
private:
/*Orientation for ramp*/
Orientation mOrientation;
/*Margin around ramp*/
int mMargin = 4;
/*Whether to draw a frame around the ramp*/
bool mShowFrame = false;
/*Polygon for upper triangle marker*/
QPolygonF mTopTriangle;
/*Polygon for lower triangle marker*/
QPolygonF mBottomTriangle;
/**
* Updates the widget's color based on a point within the widget
* \param point point within the widget
*/
void setColorFromPoint( QPointF point );
};
/**
* \ingroup gui
* \class QgsColorSliderWidget
* A composite horizontal color ramp widget and associated spinbox for manual value entry.
* \since QGIS 2.5
*/
class GUI_EXPORT QgsColorSliderWidget : public QgsColorWidget
{
Q_OBJECT
public:
/**
* Construct a new color slider widget.
* \param parent parent QWidget for the widget
* \param component color component which is controlled by the slider
*/
QgsColorSliderWidget( QWidget *parent SIP_TRANSFERTHIS = nullptr, const ColorComponent component = QgsColorWidget::Red );
void setComponent( const ColorComponent component ) override;
void setComponentValue( const int value ) override;
void setColor( const QColor &color, const bool emitSignals = false ) override;
private:
/*Color ramp widget*/
QgsColorRampWidget *mRampWidget = nullptr;
/*Spin box widget*/
QSpinBox *mSpinBox = nullptr;
/**
* Converts the real value of a color component to a friendly display value. For instance,
* alpha values from 0-255 have little meaning to users, so we translate them to 0-100%
* \param realValue actual value of the color component
* \returns display value of color component
* \see convertDisplayToReal
*/
int convertRealToDisplay( const int realValue ) const;
/**
* Converts the display value of a color component to a real value.
* \param displayValue friendly display value of the color component
* \returns real value of color component
* \see convertRealToDisplay
*/
int convertDisplayToReal( const int displayValue ) const;
private slots:
/**
* Called when the color for the ramp changes
*/
void rampColorChanged( const QColor &color );
/**
* Called when the value of the spin box changes
*/
void spinChanged( int value );
/**
* Called when the value for the ramp changes
*/
void rampChanged( int value );
};
/**
* \ingroup gui
* \class QgsColorTextWidget
* A line edit widget which displays colors as text and accepts string representations
* of colors.
* \since QGIS 2.5
*/
class GUI_EXPORT QgsColorTextWidget : public QgsColorWidget
{
Q_OBJECT
public:
/**
* Construct a new color line edit widget.
* \param parent parent QWidget for the widget
*/
QgsColorTextWidget( QWidget *parent SIP_TRANSFERTHIS = nullptr );
void setColor( const QColor &color, const bool emitSignals = false ) override;
protected:
void resizeEvent( QResizeEvent *event ) override;
private:
/**
* Specifies the display format for a color
*/
enum ColorTextFormat
{
HexRgb = 0, //!< \#RRGGBB in hexadecimal
HexRgbA, //!< \#RRGGBBAA in hexadecimal, with alpha
Rgb, //!< Rgb( r, g, b ) format
Rgba //!< Rgba( r, g, b, a ) format, with alpha
};
QLineEdit *mLineEdit = nullptr;
/*Drop-down menu button*/
QToolButton *mMenuButton = nullptr;
/*Display format for colors*/
ColorTextFormat mFormat = QgsColorTextWidget::HexRgb;
/**
* Updates the text based on the current color
*/
void updateText();
private slots:
/**
* Called when the user enters text into the widget
*/
void textChanged();
/**
* Called when the drop-down arrow is clicked to show the format selection menu
*/
void showMenu();
};
/**
* \ingroup gui
* \class QgsColorPreviewWidget
* A preview box which displays one or two colors as swatches.
* \since QGIS 2.5
*/
class GUI_EXPORT QgsColorPreviewWidget : public QgsColorWidget
{
Q_OBJECT
public:
/**
* Construct a new color preview widget.
* \param parent parent QWidget for the widget
*/
QgsColorPreviewWidget( QWidget *parent SIP_TRANSFERTHIS = nullptr );
void paintEvent( QPaintEvent *event ) override;
QSize sizeHint() const override;
/**
* Returns the secondary color for the widget
* \returns secondary widget color, or an invalid color if the widget
* has no secondary color
* \see color
* \see setColor2
*/
QColor color2() const { return mColor2; }
public slots:
/**
* Sets the second color for the widget
* \param color secondary widget color. Set to an invalid color to prevent
* drawing of a secondary color
* \see setColor
* \see color2
*/
virtual void setColor2( const QColor &color );
protected:
//reimplemented to allow dragging colors
void mousePressEvent( QMouseEvent *e ) override;
//reimplemented to click colors
void mouseReleaseEvent( QMouseEvent *e ) override;
//reimplemented to allow dragging colors
void mouseMoveEvent( QMouseEvent *e ) override;
private:
/*Secondary color for widget*/
QColor mColor2;
QPoint mDragStartPosition;
/*Draws a color preview within the specified rect.
* \param color color to draw
* \param rect rect to draw color in
* \param painter destination painter
*/
void drawColor( const QColor &color, QRect rect, QPainter &painter );
};
#endif // #ifndef QGSCOLORWIDGETS_H