22
33from AnyQt .QtCore import Qt , QSize , QAbstractItemModel , Property
44from AnyQt .QtWidgets import (
5- QWidget , QSlider , QFormLayout , QComboBox , QStyle
6- )
5+ QWidget , QSlider , QFormLayout , QComboBox , QStyle ,
6+ QHBoxLayout , QLineEdit , QLabel )
77from AnyQt .QtCore import Signal
8+ from AnyQt .QtGui import QFontMetrics , QDoubleValidator
89
9- from Orange .widgets .utils import itemmodels
10+ from Orange .widgets .utils import itemmodels , colorpalettes
1011
1112
1213class ColorGradientSelection (QWidget ):
1314 activated = Signal (int )
1415
1516 currentIndexChanged = Signal (int )
1617 thresholdsChanged = Signal (float , float )
18+ centerChanged = Signal (float )
1719
18- def __init__ (self , * args , thresholds = (0.0 , 1.0 ), ** kwargs ):
20+ def __init__ (self , * args , thresholds = (0.0 , 1.0 ), center = 0 , ** kwargs ):
1921 super ().__init__ (* args , ** kwargs )
2022
2123 low = round (clip (thresholds [0 ], 0. , 1. ), 2 )
2224 high = round (clip (thresholds [1 ], 0. , 1. ), 2 )
2325 high = max (low , high )
2426 self .__threshold_low , self .__threshold_high = low , high
27+ self .__center = center
2528 form = QFormLayout (
2629 formAlignment = Qt .AlignLeft ,
2730 labelAlignment = Qt .AlignLeft ,
@@ -42,6 +45,21 @@ def __init__(self, *args, thresholds=(0.0, 1.0), **kwargs):
4245 self .gradient_cb .setModel (model )
4346 self .gradient_cb .activated [int ].connect (self .activated )
4447 self .gradient_cb .currentIndexChanged .connect (self .currentIndexChanged )
48+ self .gradient_cb .currentIndexChanged .connect (self .__on_palette_changed )
49+
50+ self .center_box = QWidget ()
51+ center_layout = QHBoxLayout ()
52+ self .center_box .setLayout (center_layout )
53+ width = QFontMetrics (self .font ()).boundingRect ("9999999" ).width ()
54+ self .center_edit = QLineEdit (
55+ text = f"{ self .__center } " ,
56+ maximumWidth = width , placeholderText = "0" , alignment = Qt .AlignRight )
57+ self .center_edit .setValidator (QDoubleValidator ())
58+ self .center_edit .editingFinished .connect (self .__on_center_changed )
59+ center_layout .setContentsMargins (0 , 0 , 0 , 0 )
60+ center_layout .addStretch (1 )
61+ center_layout .addWidget (QLabel ("Centered at" ))
62+ center_layout .addWidget (self .center_edit )
4563
4664 slider_low = QSlider (
4765 objectName = "threshold-low-slider" , minimum = 0 , maximum = 100 ,
@@ -60,6 +78,7 @@ def __init__(self, *args, thresholds=(0.0, 1.0), **kwargs):
6078 "gradient from the higher end" )
6179 )
6280 form .setWidget (0 , QFormLayout .SpanningRole , self .gradient_cb )
81+ form .setWidget (1 , QFormLayout .FieldRole , self .center_box )
6382 form .addRow (self .tr ("Low:" ), slider_low )
6483 form .addRow (self .tr ("High:" ), slider_high )
6584 self .slider_low = slider_low
@@ -109,6 +128,14 @@ def thresholdHigh(self) -> float:
109128 def setThresholdHigh (self , high : float ) -> None :
110129 self .setThresholds (min (self .__threshold_low , high ), high )
111130
131+ def center (self ) -> float :
132+ return self .__center
133+
134+ def setCenter (self , center : float ) -> None :
135+ self .__center = center
136+ self .center_edit .setText (f"{ center } " )
137+ self .centerChanged .emit (center )
138+
112139 thresholdHigh_ = Property (
113140 float , thresholdLow , setThresholdLow , notify = thresholdsChanged )
114141
@@ -146,6 +173,15 @@ def setThresholds(self, low: float, high: float) -> None:
146173 self .slider_high .setSliderPosition (high * 100 )
147174 self .thresholdsChanged .emit (high , low )
148175
176+ def __on_palette_changed (self ):
177+ palette = self .currentData ()
178+ self .center_box .setVisible (
179+ isinstance (palette , colorpalettes .Palette )
180+ and palette .flags & palette .Flags .Diverging )
181+
182+ def __on_center_changed (self ):
183+ self .__center = float (self .center_edit .text () or "0" )
184+ self .centerChanged .emit (self .__center )
149185
150186def clip (a , amin , amax ):
151187 return min (max (a , amin ), amax )
0 commit comments