rocket-welder-sdk 1.1.36.dev14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rocket_welder_sdk/__init__.py +95 -0
- rocket_welder_sdk/bytes_size.py +234 -0
- rocket_welder_sdk/connection_string.py +291 -0
- rocket_welder_sdk/controllers.py +831 -0
- rocket_welder_sdk/external_controls/__init__.py +30 -0
- rocket_welder_sdk/external_controls/contracts.py +100 -0
- rocket_welder_sdk/external_controls/contracts_old.py +105 -0
- rocket_welder_sdk/frame_metadata.py +138 -0
- rocket_welder_sdk/gst_metadata.py +411 -0
- rocket_welder_sdk/high_level/__init__.py +54 -0
- rocket_welder_sdk/high_level/client.py +235 -0
- rocket_welder_sdk/high_level/connection_strings.py +331 -0
- rocket_welder_sdk/high_level/data_context.py +169 -0
- rocket_welder_sdk/high_level/frame_sink_factory.py +118 -0
- rocket_welder_sdk/high_level/schema.py +195 -0
- rocket_welder_sdk/high_level/transport_protocol.py +238 -0
- rocket_welder_sdk/keypoints_protocol.py +642 -0
- rocket_welder_sdk/opencv_controller.py +278 -0
- rocket_welder_sdk/periodic_timer.py +303 -0
- rocket_welder_sdk/py.typed +2 -0
- rocket_welder_sdk/rocket_welder_client.py +497 -0
- rocket_welder_sdk/segmentation_result.py +420 -0
- rocket_welder_sdk/session_id.py +238 -0
- rocket_welder_sdk/transport/__init__.py +31 -0
- rocket_welder_sdk/transport/frame_sink.py +122 -0
- rocket_welder_sdk/transport/frame_source.py +74 -0
- rocket_welder_sdk/transport/nng_transport.py +197 -0
- rocket_welder_sdk/transport/stream_transport.py +193 -0
- rocket_welder_sdk/transport/tcp_transport.py +154 -0
- rocket_welder_sdk/transport/unix_socket_transport.py +339 -0
- rocket_welder_sdk/ui/__init__.py +48 -0
- rocket_welder_sdk/ui/controls.py +362 -0
- rocket_welder_sdk/ui/icons.py +21628 -0
- rocket_welder_sdk/ui/ui_events_projection.py +226 -0
- rocket_welder_sdk/ui/ui_service.py +358 -0
- rocket_welder_sdk/ui/value_types.py +72 -0
- rocket_welder_sdk-1.1.36.dev14.dist-info/METADATA +845 -0
- rocket_welder_sdk-1.1.36.dev14.dist-info/RECORD +40 -0
- rocket_welder_sdk-1.1.36.dev14.dist-info/WHEEL +5 -0
- rocket_welder_sdk-1.1.36.dev14.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
"""UI Control base classes and implementations."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from typing import TYPE_CHECKING, Any, Callable, ClassVar
|
|
7
|
+
|
|
8
|
+
from rocket_welder_sdk.external_controls.contracts import (
|
|
9
|
+
ArrowDirection,
|
|
10
|
+
ButtonDown,
|
|
11
|
+
ButtonUp,
|
|
12
|
+
KeyDown,
|
|
13
|
+
KeyUp,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from .value_types import Color, ControlType, Size, Typography
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from .ui_service import UiService
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ControlBase(ABC):
|
|
23
|
+
"""Base class for all UI controls."""
|
|
24
|
+
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
control_id: str,
|
|
28
|
+
control_type: ControlType,
|
|
29
|
+
ui_service: UiService,
|
|
30
|
+
properties: dict[str, str] | None = None,
|
|
31
|
+
) -> None:
|
|
32
|
+
"""
|
|
33
|
+
Initialize base control.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
control_id: Unique identifier for the control
|
|
37
|
+
control_type: Type of the control
|
|
38
|
+
ui_service: Reference to parent UiService
|
|
39
|
+
properties: Initial properties
|
|
40
|
+
"""
|
|
41
|
+
self.id: str = control_id
|
|
42
|
+
self.control_type: ControlType = control_type
|
|
43
|
+
self._ui_service: UiService = ui_service
|
|
44
|
+
self._properties: dict[str, str] = properties or {}
|
|
45
|
+
self._changed: dict[str, str] = {}
|
|
46
|
+
self._is_disposed: bool = False
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def is_dirty(self) -> bool:
|
|
50
|
+
"""Check if control has uncommitted changes."""
|
|
51
|
+
return bool(self._changed)
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def changed(self) -> dict[str, str]:
|
|
55
|
+
"""Get pending changes."""
|
|
56
|
+
return self._changed.copy()
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def properties(self) -> dict[str, str]:
|
|
60
|
+
"""Get current properties including changes."""
|
|
61
|
+
props = self._properties.copy()
|
|
62
|
+
props.update(self._changed)
|
|
63
|
+
return props
|
|
64
|
+
|
|
65
|
+
def set_property(self, name: str, value: Any) -> None:
|
|
66
|
+
"""
|
|
67
|
+
Set a property value.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
name: Property name
|
|
71
|
+
value: Property value (will be converted to string)
|
|
72
|
+
"""
|
|
73
|
+
str_value = str(value) if value is not None else ""
|
|
74
|
+
if self._properties.get(name) != str_value:
|
|
75
|
+
self._changed[name] = str_value
|
|
76
|
+
|
|
77
|
+
def commit_changes(self) -> None:
|
|
78
|
+
"""Commit pending changes to properties."""
|
|
79
|
+
self._properties.update(self._changed)
|
|
80
|
+
self._changed.clear()
|
|
81
|
+
|
|
82
|
+
@abstractmethod
|
|
83
|
+
def handle_event(self, event: Any) -> None:
|
|
84
|
+
"""
|
|
85
|
+
Handle an event for this control.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
event: Event to handle
|
|
89
|
+
"""
|
|
90
|
+
pass
|
|
91
|
+
|
|
92
|
+
def dispose(self) -> None:
|
|
93
|
+
"""Dispose of the control."""
|
|
94
|
+
if not self._is_disposed:
|
|
95
|
+
self._is_disposed = True
|
|
96
|
+
self._ui_service.schedule_delete(self.id)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class IconButtonControl(ControlBase):
|
|
100
|
+
"""Icon button control with click events."""
|
|
101
|
+
|
|
102
|
+
def __init__(
|
|
103
|
+
self,
|
|
104
|
+
control_id: str,
|
|
105
|
+
ui_service: UiService,
|
|
106
|
+
icon: str,
|
|
107
|
+
properties: dict[str, str] | None = None,
|
|
108
|
+
) -> None:
|
|
109
|
+
"""
|
|
110
|
+
Initialize icon button control.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
control_id: Unique identifier
|
|
114
|
+
ui_service: Parent UiService
|
|
115
|
+
icon: SVG path for the icon
|
|
116
|
+
properties: Additional properties
|
|
117
|
+
"""
|
|
118
|
+
props = properties or {}
|
|
119
|
+
props["Icon"] = icon
|
|
120
|
+
super().__init__(control_id, ControlType.ICON_BUTTON, ui_service, props)
|
|
121
|
+
|
|
122
|
+
# Event handlers
|
|
123
|
+
self.on_button_down: Callable[[IconButtonControl], None] | None = None
|
|
124
|
+
self.on_button_up: Callable[[IconButtonControl], None] | None = None
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def icon(self) -> str:
|
|
128
|
+
"""Get icon SVG path."""
|
|
129
|
+
return self.properties.get("Icon", "")
|
|
130
|
+
|
|
131
|
+
@icon.setter
|
|
132
|
+
def icon(self, value: str) -> None:
|
|
133
|
+
"""Set icon SVG path."""
|
|
134
|
+
self.set_property("Icon", value)
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def text(self) -> str | None:
|
|
138
|
+
"""Get button text."""
|
|
139
|
+
return self.properties.get("Text")
|
|
140
|
+
|
|
141
|
+
@text.setter
|
|
142
|
+
def text(self, value: str | None) -> None:
|
|
143
|
+
"""Set button text."""
|
|
144
|
+
if value is not None:
|
|
145
|
+
self.set_property("Text", value)
|
|
146
|
+
|
|
147
|
+
@property
|
|
148
|
+
def color(self) -> Color:
|
|
149
|
+
"""Get button color."""
|
|
150
|
+
color_str = self.properties.get("Color", Color.PRIMARY.value)
|
|
151
|
+
try:
|
|
152
|
+
return Color(color_str)
|
|
153
|
+
except ValueError:
|
|
154
|
+
return Color.PRIMARY
|
|
155
|
+
|
|
156
|
+
@color.setter
|
|
157
|
+
def color(self, value: Color | str) -> None:
|
|
158
|
+
"""Set button color."""
|
|
159
|
+
if isinstance(value, Color):
|
|
160
|
+
self.set_property("Color", value.value)
|
|
161
|
+
else:
|
|
162
|
+
# Try to find matching enum
|
|
163
|
+
for color in Color:
|
|
164
|
+
if color.value == value:
|
|
165
|
+
self.set_property("Color", value)
|
|
166
|
+
return
|
|
167
|
+
raise ValueError(f"Invalid color value: {value}")
|
|
168
|
+
|
|
169
|
+
@property
|
|
170
|
+
def size(self) -> Size:
|
|
171
|
+
"""Get button size."""
|
|
172
|
+
size_str = self.properties.get("Size", Size.MEDIUM.value)
|
|
173
|
+
try:
|
|
174
|
+
return Size(size_str)
|
|
175
|
+
except ValueError:
|
|
176
|
+
return Size.MEDIUM
|
|
177
|
+
|
|
178
|
+
@size.setter
|
|
179
|
+
def size(self, value: Size | str) -> None:
|
|
180
|
+
"""Set button size."""
|
|
181
|
+
if isinstance(value, Size):
|
|
182
|
+
self.set_property("Size", value.value)
|
|
183
|
+
else:
|
|
184
|
+
# Try to find matching enum
|
|
185
|
+
for size in Size:
|
|
186
|
+
if size.value == value:
|
|
187
|
+
self.set_property("Size", value)
|
|
188
|
+
return
|
|
189
|
+
raise ValueError(f"Invalid size value: {value}")
|
|
190
|
+
|
|
191
|
+
def handle_event(self, event: Any) -> None:
|
|
192
|
+
"""Handle button events."""
|
|
193
|
+
if isinstance(event, ButtonDown) and self.on_button_down:
|
|
194
|
+
self.on_button_down(self)
|
|
195
|
+
elif isinstance(event, ButtonUp) and self.on_button_up:
|
|
196
|
+
self.on_button_up(self)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
class ArrowGridControl(ControlBase):
|
|
200
|
+
"""Arrow grid control for directional input."""
|
|
201
|
+
|
|
202
|
+
# Mapping from key codes to arrow directions
|
|
203
|
+
KEY_TO_DIRECTION: ClassVar[dict[str, ArrowDirection]] = {
|
|
204
|
+
"ArrowUp": ArrowDirection.UP,
|
|
205
|
+
"ArrowDown": ArrowDirection.DOWN,
|
|
206
|
+
"ArrowLeft": ArrowDirection.LEFT,
|
|
207
|
+
"ArrowRight": ArrowDirection.RIGHT,
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
def __init__(
|
|
211
|
+
self, control_id: str, ui_service: UiService, properties: dict[str, str] | None = None
|
|
212
|
+
) -> None:
|
|
213
|
+
"""
|
|
214
|
+
Initialize arrow grid control.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
control_id: Unique identifier
|
|
218
|
+
ui_service: Parent UiService
|
|
219
|
+
properties: Additional properties
|
|
220
|
+
"""
|
|
221
|
+
super().__init__(control_id, ControlType.ARROW_GRID, ui_service, properties)
|
|
222
|
+
|
|
223
|
+
# Event handlers
|
|
224
|
+
self.on_arrow_down: Callable[[ArrowGridControl, ArrowDirection], None] | None = None
|
|
225
|
+
self.on_arrow_up: Callable[[ArrowGridControl, ArrowDirection], None] | None = None
|
|
226
|
+
|
|
227
|
+
@property
|
|
228
|
+
def size(self) -> Size:
|
|
229
|
+
"""Get grid size."""
|
|
230
|
+
size_str = self.properties.get("Size", Size.MEDIUM.value)
|
|
231
|
+
try:
|
|
232
|
+
return Size(size_str)
|
|
233
|
+
except ValueError:
|
|
234
|
+
return Size.MEDIUM
|
|
235
|
+
|
|
236
|
+
@size.setter
|
|
237
|
+
def size(self, value: Size | str) -> None:
|
|
238
|
+
"""Set grid size."""
|
|
239
|
+
if isinstance(value, Size):
|
|
240
|
+
self.set_property("Size", value.value)
|
|
241
|
+
else:
|
|
242
|
+
# Try to find matching enum
|
|
243
|
+
for size in Size:
|
|
244
|
+
if size.value == value:
|
|
245
|
+
self.set_property("Size", value)
|
|
246
|
+
return
|
|
247
|
+
raise ValueError(f"Invalid size value: {value}")
|
|
248
|
+
|
|
249
|
+
@property
|
|
250
|
+
def color(self) -> Color:
|
|
251
|
+
"""Get grid color."""
|
|
252
|
+
color_str = self.properties.get("Color", Color.PRIMARY.value)
|
|
253
|
+
try:
|
|
254
|
+
return Color(color_str)
|
|
255
|
+
except ValueError:
|
|
256
|
+
return Color.PRIMARY
|
|
257
|
+
|
|
258
|
+
@color.setter
|
|
259
|
+
def color(self, value: Color | str) -> None:
|
|
260
|
+
"""Set grid color."""
|
|
261
|
+
if isinstance(value, Color):
|
|
262
|
+
self.set_property("Color", value.value)
|
|
263
|
+
else:
|
|
264
|
+
# Try to find matching enum
|
|
265
|
+
for color in Color:
|
|
266
|
+
if color.value == value:
|
|
267
|
+
self.set_property("Color", value)
|
|
268
|
+
return
|
|
269
|
+
raise ValueError(f"Invalid color value: {value}")
|
|
270
|
+
|
|
271
|
+
def handle_event(self, event: Any) -> None:
|
|
272
|
+
"""Handle keyboard events and translate to arrow events."""
|
|
273
|
+
if isinstance(event, KeyDown):
|
|
274
|
+
direction = self.KEY_TO_DIRECTION.get(event.code)
|
|
275
|
+
if direction and self.on_arrow_down:
|
|
276
|
+
self.on_arrow_down(self, direction)
|
|
277
|
+
elif isinstance(event, KeyUp):
|
|
278
|
+
direction = self.KEY_TO_DIRECTION.get(event.code)
|
|
279
|
+
if direction and self.on_arrow_up:
|
|
280
|
+
self.on_arrow_up(self, direction)
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
class LabelControl(ControlBase):
|
|
284
|
+
"""Label control for displaying text."""
|
|
285
|
+
|
|
286
|
+
def __init__(
|
|
287
|
+
self,
|
|
288
|
+
control_id: str,
|
|
289
|
+
ui_service: UiService,
|
|
290
|
+
text: str,
|
|
291
|
+
properties: dict[str, str] | None = None,
|
|
292
|
+
) -> None:
|
|
293
|
+
"""
|
|
294
|
+
Initialize label control.
|
|
295
|
+
|
|
296
|
+
Args:
|
|
297
|
+
control_id: Unique identifier
|
|
298
|
+
ui_service: Parent UiService
|
|
299
|
+
text: Label text
|
|
300
|
+
properties: Additional properties
|
|
301
|
+
"""
|
|
302
|
+
props = properties or {}
|
|
303
|
+
props["Text"] = text
|
|
304
|
+
super().__init__(control_id, ControlType.LABEL, ui_service, props)
|
|
305
|
+
|
|
306
|
+
@property
|
|
307
|
+
def text(self) -> str:
|
|
308
|
+
"""Get label text."""
|
|
309
|
+
return self.properties.get("Text", "")
|
|
310
|
+
|
|
311
|
+
@text.setter
|
|
312
|
+
def text(self, value: str) -> None:
|
|
313
|
+
"""Set label text."""
|
|
314
|
+
self.set_property("Text", value)
|
|
315
|
+
|
|
316
|
+
@property
|
|
317
|
+
def typography(self) -> Typography:
|
|
318
|
+
"""Get label typography."""
|
|
319
|
+
typo_str = self.properties.get("Typography", Typography.BODY1.value)
|
|
320
|
+
try:
|
|
321
|
+
return Typography(typo_str)
|
|
322
|
+
except ValueError:
|
|
323
|
+
return Typography.BODY1
|
|
324
|
+
|
|
325
|
+
@typography.setter
|
|
326
|
+
def typography(self, value: Typography | str) -> None:
|
|
327
|
+
"""Set label typography."""
|
|
328
|
+
if isinstance(value, Typography):
|
|
329
|
+
self.set_property("Typography", value.value)
|
|
330
|
+
else:
|
|
331
|
+
# Try to find matching enum
|
|
332
|
+
for typo in Typography:
|
|
333
|
+
if typo.value == value:
|
|
334
|
+
self.set_property("Typography", value)
|
|
335
|
+
return
|
|
336
|
+
raise ValueError(f"Invalid typography value: {value}")
|
|
337
|
+
|
|
338
|
+
@property
|
|
339
|
+
def color(self) -> Color:
|
|
340
|
+
"""Get label color."""
|
|
341
|
+
color_str = self.properties.get("Color", Color.TEXT_PRIMARY.value)
|
|
342
|
+
try:
|
|
343
|
+
return Color(color_str)
|
|
344
|
+
except ValueError:
|
|
345
|
+
return Color.TEXT_PRIMARY
|
|
346
|
+
|
|
347
|
+
@color.setter
|
|
348
|
+
def color(self, value: Color | str) -> None:
|
|
349
|
+
"""Set label color."""
|
|
350
|
+
if isinstance(value, Color):
|
|
351
|
+
self.set_property("Color", value.value)
|
|
352
|
+
else:
|
|
353
|
+
# Try to find matching enum
|
|
354
|
+
for color in Color:
|
|
355
|
+
if color.value == value:
|
|
356
|
+
self.set_property("Color", value)
|
|
357
|
+
return
|
|
358
|
+
raise ValueError(f"Invalid color value: {value}")
|
|
359
|
+
|
|
360
|
+
def handle_event(self, event: Any) -> None:
|
|
361
|
+
"""Labels typically don't handle events."""
|
|
362
|
+
pass
|