Skip to content

Commit 25cc597

Browse files
authored
Merge pull request #6325 from janezd/rangeslider
Implement IntervalSlider; use it for color gradient selection
2 parents 3588d2d + eba6dda commit 25cc597

File tree

3 files changed

+295
-87
lines changed

3 files changed

+295
-87
lines changed

Orange/widgets/utils/colorgradientselection.py

Lines changed: 32 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22

33
from AnyQt.QtCore import Qt, QSize, QAbstractItemModel, Property
44
from AnyQt.QtWidgets import (
5-
QWidget, QSlider, QFormLayout, QComboBox, QStyle, QHBoxLayout, QLabel,
6-
QSizePolicy
5+
QWidget, QSlider, QFormLayout, QComboBox, QStyle, QSizePolicy
76
)
87
from AnyQt.QtCore import Signal
98

10-
from orangewidget.gui import Slider
11-
129
from Orange.widgets.utils import itemmodels, colorpalettes
1310
from Orange.widgets.utils.spinbox import DoubleSpinBox, DBL_MIN, DBL_MAX
11+
from Orange.widgets.utils.intervalslider import IntervalSlider
1412

1513

1614
class ColorGradientSelection(QWidget):
@@ -48,59 +46,37 @@ def __init__(self, *args, thresholds=(0.0, 1.0), center=None, **kwargs):
4846
self.gradient_cb.setModel(model)
4947
self.gradient_cb.activated[int].connect(self.activated)
5048
self.gradient_cb.currentIndexChanged.connect(self.currentIndexChanged)
49+
self.gradient_cb.currentIndexChanged.connect(
50+
self.__update_center_visibility)
51+
form.setWidget(0, QFormLayout.SpanningRole, self.gradient_cb)
52+
53+
def on_center_spin_value_changed(value):
54+
if self.__center != value:
55+
self.__center = value
56+
self.centerChanged.emit(self.__center)
5157

5258
if center is not None:
53-
def on_center_spin_value_changed(value):
54-
if self.__center != value:
55-
self.__center = value
56-
self.centerChanged.emit(self.__center)
57-
58-
self.center_box = QWidget()
59-
center_layout = QHBoxLayout()
60-
self.center_box.setLayout(center_layout)
6159
self.center_edit = DoubleSpinBox(
6260
value=self.__center,
6361
minimum=DBL_MIN, maximum=DBL_MAX, minimumStep=0.01,
64-
minimumContentsLenght=8,
62+
minimumContentsLenght=8, alignment=Qt.AlignRight,
6563
stepType=DoubleSpinBox.AdaptiveDecimalStepType,
6664
keyboardTracking=False,
67-
sizePolicy=QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
65+
sizePolicy=QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed),
6866
)
6967
self.center_edit.valueChanged.connect(on_center_spin_value_changed)
70-
center_layout.setContentsMargins(0, 0, 0, 0)
71-
center_layout.addStretch(1)
72-
center_layout.addWidget(QLabel("Centered at"))
73-
center_layout.addWidget(self.center_edit)
74-
self.gradient_cb.currentIndexChanged.connect(
75-
self.__update_center_visibility)
7668
else:
77-
self.center_box = None
69+
self.center_edit = None
7870

79-
slider_low = Slider(
80-
objectName="threshold-low-slider", minimum=0, maximum=100,
81-
value=int(low * 100), orientation=Qt.Horizontal,
82-
tickPosition=QSlider.TicksBelow, pageStep=10,
71+
slider = self.slider = IntervalSlider(
72+
int(low * 100), int(high * 100), minimum=0, maximum=100,
73+
tickPosition=QSlider.NoTicks,
8374
toolTip=self.tr("Low gradient threshold"),
8475
whatsThis=self.tr("Applying a low threshold will squeeze the "
8576
"gradient from the lower end")
8677
)
87-
slider_high = Slider(
88-
objectName="threshold-low-slider", minimum=0, maximum=100,
89-
value=int(high * 100), orientation=Qt.Horizontal,
90-
tickPosition=QSlider.TicksAbove, pageStep=10,
91-
toolTip=self.tr("High gradient threshold"),
92-
whatsThis=self.tr("Applying a high threshold will squeeze the "
93-
"gradient from the higher end")
94-
)
95-
form.setWidget(0, QFormLayout.SpanningRole, self.gradient_cb)
96-
if self.center_box:
97-
form.setWidget(1, QFormLayout.SpanningRole, self.center_box)
98-
form.addRow(self.tr("Low:"), slider_low)
99-
form.addRow(self.tr("High:"), slider_high)
100-
self.slider_low = slider_low
101-
self.slider_high = slider_high
102-
self.slider_low.valueChanged.connect(self.__on_slider_low_moved)
103-
self.slider_high.valueChanged.connect(self.__on_slider_high_moved)
78+
form.addRow(self.tr("Range:"), slider)
79+
self.slider.intervalChanged.connect(self.__on_slider_moved)
10480
self.setLayout(form)
10581

10682
def setModel(self, model: QAbstractItemModel) -> None:
@@ -148,24 +124,10 @@ def setThresholdHigh(self, high: float) -> None:
148124
thresholdHigh_ = Property(
149125
float, thresholdLow, setThresholdLow, notify=thresholdsChanged)
150126

151-
def __on_slider_low_moved(self, value: int) -> None:
152-
high = self.slider_high
127+
def __on_slider_moved(self, low: int, high: int) -> None:
153128
old = self.__threshold_low, self.__threshold_high
154-
self.__threshold_low = value / 100.
155-
if value >= high.value():
156-
self.__threshold_high = value / 100.
157-
high.setSliderPosition(value)
158-
new = self.__threshold_low, self.__threshold_high
159-
if new != old:
160-
self.thresholdsChanged.emit(*new)
161-
162-
def __on_slider_high_moved(self, value: int) -> None:
163-
low = self.slider_low
164-
old = self.__threshold_low, self.__threshold_high
165-
self.__threshold_high = value / 100.
166-
if low.value() >= value:
167-
self.__threshold_low = value / 100
168-
low.setSliderPosition(value)
129+
self.__threshold_low = low / 100.
130+
self.__threshold_high = high / 100.
169131
new = self.__threshold_low, self.__threshold_high
170132
if new != old:
171133
self.thresholdsChanged.emit(*new)
@@ -178,18 +140,22 @@ def setThresholds(self, low: float, high: float) -> None:
178140
if self.__threshold_low != low or self.__threshold_high != high:
179141
self.__threshold_high = high
180142
self.__threshold_low = low
181-
self.slider_low.setSliderPosition(int(low * 100))
182-
self.slider_high.setSliderPosition(int(high * 100))
143+
self.slider.setInterval(int(low * 100), int(high * 100))
183144
self.thresholdsChanged.emit(high, low)
184145

185146
def __update_center_visibility(self):
186-
if self.center_box is None:
147+
palette = self.currentData()
148+
if self.center_edit is None or \
149+
(visible := self.center_edit.parent() is not None) \
150+
== bool(isinstance(palette, colorpalettes.Palette)
151+
and palette.flags & palette.Flags.Diverging):
187152
return
153+
if visible:
154+
self.layout().takeRow(1).labelItem.widget().setParent(None)
155+
self.center_edit.setParent(None)
156+
else:
157+
self.layout().insertRow(1, "Center at:", self.center_edit)
188158

189-
palette = self.currentData()
190-
self.center_box.setVisible(
191-
isinstance(palette, colorpalettes.Palette)
192-
and palette.flags & palette.Flags.Diverging != 0)
193159

194160
def center(self) -> float:
195161
return self.__center

0 commit comments

Comments
 (0)