Skip to content

Commit 54c596b

Browse files
committed
_NumberValueMenu updates. #374
1 parent 4823b43 commit 54c596b

File tree

5 files changed

+168
-24
lines changed

5 files changed

+168
-24
lines changed

NodeGraphQt/custom_widgets/properties_bin/custom_widget_color_picker.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ def __init__(self, parent=None):
1515
self._color = (0, 0, 0)
1616
self._button = QtWidgets.QPushButton()
1717
self._vector = PropVector3()
18+
self._vector.set_steps([1, 10, 100])
19+
self._vector.set_data_type(int)
1820
self._vector.set_value([0, 0, 0])
21+
self._vector.set_min(0)
22+
self._vector.set_max(255)
1923
self._update_color()
2024

2125
self._button.clicked.connect(self._on_select_color)
@@ -53,6 +57,15 @@ def _update_color(self):
5357
'rgb: {}\nhex: {}'.format(self._color[:3], hex_color)
5458
)
5559

60+
def set_data_type(self, data_type):
61+
"""
62+
Sets the input line edit fields to either display in float or int.
63+
64+
Args:
65+
data_type(int or float): int or float data type object.
66+
"""
67+
self._vector.set_data_type(data_type)
68+
5669
def get_value(self):
5770
return self._color[:3]
5871

@@ -74,7 +87,11 @@ def __init__(self, parent=None):
7487
self._color = (0, 0, 0, 255)
7588
self._button = QtWidgets.QPushButton()
7689
self._vector = PropVector4()
90+
self._vector.set_steps([1, 10, 100])
91+
self._vector.set_data_type(int)
7792
self._vector.set_value([0, 0, 0, 255])
93+
self._vector.set_min(0)
94+
self._vector.set_max(255)
7895
self._update_color()
7996

8097
self._button.clicked.connect(self._on_select_color)

NodeGraphQt/custom_widgets/properties_bin/custom_widget_value_edit.py

Lines changed: 111 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
#!/usr/bin/python
2+
import re
3+
24
from Qt import QtWidgets, QtCore, QtGui
35

6+
_NUMB_REGEX = re.compile(r'^((?:\-)*\d+)*([\.,])*(\d+(?:[eE](?:[\-\+])*\d+)*)*')
7+
48

59
class _NumberValueMenu(QtWidgets.QMenu):
610

@@ -83,16 +87,17 @@ def __init__(self, parent=None, data_type=float):
8387
self._previous_x = None
8488
self._previous_value = None
8589
self._step = 1
86-
self._speed = 0.1
90+
self._speed = 0.05
8791
self._data_type = float
92+
self._min = None
93+
self._max = None
8894

8995
self._menu = _NumberValueMenu()
9096
self._menu.mouseMove.connect(self.mouseMoveEvent)
9197
self._menu.mouseRelease.connect(self.mouseReleaseEvent)
9298
self._menu.stepChange.connect(self._reset_previous_x)
93-
self._menu.set_steps([0.001, 0.01, 0.1, 1, 10, 100, 1000])
9499

95-
self.editingFinished.connect(self._on_text_changed)
100+
self.editingFinished.connect(self._on_editing_finished)
96101

97102
self.set_data_type(data_type)
98103

@@ -113,7 +118,7 @@ def mouseMoveEvent(self, event):
113118
value = self._previous_value
114119
value = value + int(delta * self._speed) * self._step
115120
self.set_value(value)
116-
self._on_text_changed()
121+
self._on_mmb_mouse_move()
117122
super(_NumberValueEdit, self).mouseMoveEvent(event)
118123

119124
def mousePressEvent(self, event):
@@ -140,15 +145,37 @@ def keyPressEvent(self, event):
140145
def _reset_previous_x(self):
141146
self._previous_x = None
142147

143-
def _on_text_changed(self):
148+
def _on_mmb_mouse_move(self):
149+
self.value_changed.emit(self.get_value())
150+
151+
def _on_editing_finished(self):
152+
if self._data_type is float:
153+
match = _NUMB_REGEX.match(self.text())
154+
if match:
155+
val1, point, val2 = match.groups()
156+
if point:
157+
val1 = val1 or '0'
158+
val2 = val2 or '0'
159+
self.setText(val1 + point + val2)
144160
self.value_changed.emit(self.get_value())
145161

146162
def _convert_text(self, text):
147-
# int("1.0") will return error
148-
# so we use int(float("1.0"))
149-
try:
150-
value = float(text)
151-
except:
163+
"""
164+
Convert text to int or float.
165+
166+
Args:
167+
text (str): input text.
168+
169+
Returns:
170+
int or float: converted value.
171+
"""
172+
match = _NUMB_REGEX.match(text)
173+
if match:
174+
val1, _, val2 = match.groups()
175+
val1 = val1 or '0'
176+
val2 = val2 or '0'
177+
value = float(val1 + '.' + val2)
178+
else:
152179
value = 0.0
153180
if self._data_type is int:
154181
value = int(value)
@@ -157,26 +184,90 @@ def _convert_text(self, text):
157184
# public
158185

159186
def set_data_type(self, data_type):
187+
"""
188+
Sets the line edit to either display value in float or int.
189+
190+
Args:
191+
data_type(int or float): int or float data type object.
192+
"""
160193
self._data_type = data_type
161-
self._menu.set_data_type(data_type)
162194
if data_type is int:
163-
self.setValidator(QtGui.QIntValidator())
195+
regexp = QtCore.QRegExp(r'\d+')
196+
validator = QtGui.QRegExpValidator(regexp, self)
197+
steps = [1, 10, 100, 1000]
164198
elif data_type is float:
165-
self.setValidator(QtGui.QDoubleValidator())
199+
regexp = QtCore.QRegExp(r'\d+[\.,]\d+(?:[eE](?:[\-\+]|)\d+)*')
200+
validator = QtGui.QRegExpValidator(regexp, self)
201+
steps = [0.001, 0.01, 0.1, 1]
202+
self.setValidator(validator)
203+
if not self._menu.steps:
204+
self._menu.set_steps(steps)
205+
self._menu.set_data_type(data_type)
166206

167207
def set_steps(self, steps=None):
168-
steps = steps or [0.001, 0.01, 0.1, 1, 10, 100, 1000]
208+
"""
209+
Sets the step items in the MMB context menu.
210+
211+
Args:
212+
steps (list[int] or list[float]): list of ints or floats.
213+
"""
214+
step_types = {
215+
int: [1, 10, 100, 1000],
216+
float: [0.001, 0.01, 0.1, 1]
217+
}
218+
steps = steps or step_types.get(self._data_type)
169219
self._menu.set_steps(steps)
170220

221+
def set_min(self, value=None):
222+
"""
223+
Set the minimum range for the input field.
224+
225+
Args:
226+
value (int or float): minimum range value.
227+
"""
228+
if self._data_type is int:
229+
self._min = int(value)
230+
elif self._data_type is float:
231+
self._min = float(value)
232+
else:
233+
self._min = value
234+
235+
def set_max(self, value=None):
236+
"""
237+
Set the maximum range for the input field.
238+
239+
Args:
240+
value (int or float): maximum range value.
241+
"""
242+
if self._data_type is int:
243+
self._max = int(value)
244+
elif self._data_type is float:
245+
self._max = float(value)
246+
else:
247+
self._max = value
248+
171249
def get_value(self):
172-
if self.text().startswith('.'):
173-
text = '0' + self.text()
174-
self.setText(text)
175-
return self._convert_text(self.text())
250+
value = self._convert_text(self.text())
251+
return value
176252

177253
def set_value(self, value):
178-
if value != self.get_value():
179-
self.setText(str(self._convert_text(value)))
254+
text = str(value)
255+
converted = self._convert_text(text)
256+
current = self.get_value()
257+
if converted == current:
258+
return
259+
point = None
260+
if isinstance(converted, float):
261+
point = _NUMB_REGEX.match(str(value)).groups(2)
262+
if self._min is not None and converted < self._min:
263+
text = str(self._min)
264+
if point and point not in text:
265+
text = str(self._min).replace('.', point)
266+
if self._max is not None and converted > self._max:
267+
text = str(self._max)
268+
if point and point not in text:
269+
text = text.replace('.', point)
270+
self.setText(text)
180271

181272

182273
class IntValueEdit(_NumberValueEdit):

NodeGraphQt/custom_widgets/properties_bin/custom_widget_vectors.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,45 @@ def _update_items(self):
5151
self._items[index].set_value(value)
5252

5353
def set_data_type(self, data_type):
54+
"""
55+
Sets the input line edit fields to either display in float or int.
56+
57+
Args:
58+
data_type(int or float): int or float data type object.
59+
"""
5460
for item in self._items:
5561
item.set_data_type(data_type)
5662

63+
def set_steps(self, steps):
64+
"""
65+
Sets the step items in the MMB context menu.
66+
67+
Args:
68+
steps (list[int] or list[float]): list of ints or floats.
69+
"""
70+
for item in self._items:
71+
item.set_steps(steps)
72+
73+
def set_min(self, value):
74+
"""
75+
Set the minimum range for the input fields.
76+
77+
Args:
78+
value (int or float): minimum range value.
79+
"""
80+
for item in self._items:
81+
item.set_min(value)
82+
83+
def set_max(self, value):
84+
"""
85+
Set the maximum range for the input fields.
86+
87+
Args:
88+
value (int or float): maximum range value.
89+
"""
90+
for item in self._items:
91+
item.set_max(value)
92+
5793
def get_value(self):
5894
return self._value
5995

NodeGraphQt/nodes/base_node.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -697,9 +697,9 @@ def connected_output_nodes(self):
697697

698698
def add_accept_port_type(self, port, port_type_data):
699699
"""
700-
Add a accept constrain to a specified node port.
700+
Add an accept constrain to a specified node port.
701701
702-
Once a constrain has been added only ports of that type specified will
702+
Once a constraint has been added only ports of that type specified will
703703
be allowed a pipe connection.
704704
705705
port type data example
@@ -759,7 +759,7 @@ def add_reject_port_type(self, port, port_type_data):
759759
"""
760760
Add a reject constrain to a specified node port.
761761
762-
Once a constrain has been added only ports of that type specified will
762+
Once a constraint has been added only ports of that type specified will
763763
NOT be allowed a pipe connection.
764764
765765
port type data example

NodeGraphQt/pkg_info.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/python
22
# -*- coding: utf-8 -*-
3-
__version__ = '0.6.21'
3+
__version__ = '0.6.22'
44
__status__ = 'Work in Progress'
55
__license__ = 'MIT'
66

0 commit comments

Comments
 (0)