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.
Files changed (40) hide show
  1. rocket_welder_sdk/__init__.py +95 -0
  2. rocket_welder_sdk/bytes_size.py +234 -0
  3. rocket_welder_sdk/connection_string.py +291 -0
  4. rocket_welder_sdk/controllers.py +831 -0
  5. rocket_welder_sdk/external_controls/__init__.py +30 -0
  6. rocket_welder_sdk/external_controls/contracts.py +100 -0
  7. rocket_welder_sdk/external_controls/contracts_old.py +105 -0
  8. rocket_welder_sdk/frame_metadata.py +138 -0
  9. rocket_welder_sdk/gst_metadata.py +411 -0
  10. rocket_welder_sdk/high_level/__init__.py +54 -0
  11. rocket_welder_sdk/high_level/client.py +235 -0
  12. rocket_welder_sdk/high_level/connection_strings.py +331 -0
  13. rocket_welder_sdk/high_level/data_context.py +169 -0
  14. rocket_welder_sdk/high_level/frame_sink_factory.py +118 -0
  15. rocket_welder_sdk/high_level/schema.py +195 -0
  16. rocket_welder_sdk/high_level/transport_protocol.py +238 -0
  17. rocket_welder_sdk/keypoints_protocol.py +642 -0
  18. rocket_welder_sdk/opencv_controller.py +278 -0
  19. rocket_welder_sdk/periodic_timer.py +303 -0
  20. rocket_welder_sdk/py.typed +2 -0
  21. rocket_welder_sdk/rocket_welder_client.py +497 -0
  22. rocket_welder_sdk/segmentation_result.py +420 -0
  23. rocket_welder_sdk/session_id.py +238 -0
  24. rocket_welder_sdk/transport/__init__.py +31 -0
  25. rocket_welder_sdk/transport/frame_sink.py +122 -0
  26. rocket_welder_sdk/transport/frame_source.py +74 -0
  27. rocket_welder_sdk/transport/nng_transport.py +197 -0
  28. rocket_welder_sdk/transport/stream_transport.py +193 -0
  29. rocket_welder_sdk/transport/tcp_transport.py +154 -0
  30. rocket_welder_sdk/transport/unix_socket_transport.py +339 -0
  31. rocket_welder_sdk/ui/__init__.py +48 -0
  32. rocket_welder_sdk/ui/controls.py +362 -0
  33. rocket_welder_sdk/ui/icons.py +21628 -0
  34. rocket_welder_sdk/ui/ui_events_projection.py +226 -0
  35. rocket_welder_sdk/ui/ui_service.py +358 -0
  36. rocket_welder_sdk/ui/value_types.py +72 -0
  37. rocket_welder_sdk-1.1.36.dev14.dist-info/METADATA +845 -0
  38. rocket_welder_sdk-1.1.36.dev14.dist-info/RECORD +40 -0
  39. rocket_welder_sdk-1.1.36.dev14.dist-info/WHEEL +5 -0
  40. 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