feat: adding ColouredEnum component

This commit is contained in:
Mose Müller
2023-10-11 13:35:05 +02:00
parent 93c2f5ab70
commit 34e46e05ee
6 changed files with 163 additions and 3 deletions

View File

@@ -27,10 +27,12 @@ print(my_service.voltage.value) # Output: 5
```
"""
from pydase.components.coloured_enum import ColouredEnum
from pydase.components.image import Image
from pydase.components.number_slider import NumberSlider
__all__ = [
"NumberSlider",
"Image",
"ColouredEnum",
]

View File

@@ -0,0 +1,61 @@
from enum import StrEnum
class ColouredEnum(StrEnum):
"""
Represents a UI element that can display colour-coded text based on its value.
This class extends the standard StrEnum but requires its values to be valid CSS
colour codes. Supported colour formats include:
- Hexadecimal colours
- Hexadecimal colours with transparency
- RGB colours
- RGBA colours
- HSL colours
- HSLA colours
- Predefined/Cross-browser colour names
Refer to the this website for more details on colour formats:
(https://www.w3schools.com/cssref/css_colours_legal.php)
The behavior of this component in the UI depends on how it's defined in the data
service:
- As property with a setter or as attribute: Renders as a dropdown menu,
allowing users to select and change its value from the frontend.
- As property without a setter: Displays as a coloured box with the key of the
`ColouredEnum` as text inside, serving as a visual indicator without user
interaction.
Example:
--------
```python
import pydase.components as pyc
import pydase
class MyStatus(pyc.ColouredEnum):
PENDING = "#FFA500" # Orange
RUNNING = "#0000FF80" # Transparent Blue
PAUSED = "rgb(169, 169, 169)" # Dark Gray
RETRYING = "rgba(255, 255, 0, 0.3)" # Transparent Yellow
COMPLETED = "hsl(120, 100%, 50%)" # Green
FAILED = "hsla(0, 100%, 50%, 0.7)" # Transparent Red
CANCELLED = "SlateGray" # Slate Gray
class StatusExample(pydase.DataService):
_status = MyStatus.RUNNING
@property
def status(self) -> MyStatus:
return self._status
@status.setter
def status(self, value: MyStatus) -> None:
# Custom logic here...
self._status = value
# Example usage:
my_service = StatusExample()
my_service.status = MyStatus.FAILED
```
"""
pass

View File

@@ -311,8 +311,12 @@ class DataService(rpyc.Service, AbstractDataService):
"value": running_task_info,
}
elif isinstance(value, Enum):
if type(value).__base__.__name__ == "ColouredEnum":
val_type = "ColouredEnum"
else:
val_type = "Enum"
result[key] = {
"type": "Enum",
"type": val_type,
"value": value.name,
"enum": {
name: member.value

View File

@@ -1,5 +1,7 @@
from loguru import logger
from pydase.utils.helpers import get_component_class_names
def warn_if_instance_class_does_not_inherit_from_DataService(__value: object) -> None:
base_class_name = __value.__class__.__base__.__name__
@@ -13,7 +15,8 @@ def warn_if_instance_class_does_not_inherit_from_DataService(__value: object) ->
"asyncio.unix_events",
"_abc",
]
and base_class_name not in ["DataService", "list", "Enum"]
and base_class_name
not in ["DataService", "list", "Enum"] + get_component_class_names()
and type(__value).__name__ not in ["CallbackManager", "TaskManager", "Quantity"]
):
logger.warning(