Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 36 additions & 10 deletions streamdeck/models/events/common.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

from abc import ABC
from typing import Annotated, Generic, Literal, NamedTuple, Union
from typing import Annotated, Generic, Literal, NamedTuple, TypeAlias, Union

from pydantic import Field
from typing_extensions import TypedDict, TypeVar
Expand Down Expand Up @@ -33,30 +32,37 @@ class DeviceSpecificEventMixin:

## Payload models and metadata used by multiple event models.





EncoderControllerType = Literal["Encoder"]
"""The 'Encoder' controller type refers to a dial or touchscreen on a 'Stream Deck +' device."""


KeypadControllerType = Literal["Keypad"]
"""The 'Keypad' controller type refers to a standard action on a Stream Deck device, e.g. buttons or a pedal."""


ControllerType = Literal[EncoderControllerType, KeypadControllerType]
"""Defines the controller type the action is applicable to."""


CT = TypeVar("CT", bound=ControllerType, default=ControllerType)


class BasePayload(ConfiguredBaseModel, Generic[CT], ABC):
"""Base class for all complex payload models."""
class SettingsPayloadMixin:
"""Mixin for payload models that carry plugin-defined settings."""

settings: PluginDefinedData
"""Settings associated with a plugin or action instance."""


class BasePayload(ConfiguredBaseModel, SettingsPayloadMixin, Generic[CT]):
"""Base class for action payload models with controller and settings data."""

controller: CT
"""Defines the controller type the action is applicable to.

'Keypad' refers to a standard action on a Stream Deck device, e.g. buttons or a pedal.
'Encoder' refers to a dial / touchscreen on a 'Stream Deck +' device.
"""
settings: PluginDefinedData
"""Settings associated with the action instance."""


class CoordinatesDict(TypedDict):
Expand Down Expand Up @@ -107,6 +113,26 @@ class StatefulActionPayloadMixin:
"""


ContextualPayload: TypeAlias = (
SettingsPayloadMixin | StatefulActionPayloadMixin | CoordinatesPayloadMixin
)
"""Payload mixins that provide values copied into action-instance contexts."""


ContextualPayloadT = TypeVar(
"ContextualPayloadT",
bound=ContextualPayload,
default=ContextualPayload,
)


class ContextualPayloadEventMixin(ContextualEventMixin, Generic[ContextualPayloadT]):
"""Mixin for contextual event models with payloads that update action-instance context."""

payload: ContextualPayloadT
"""Payload data associated with the contextual event."""


class SingleActionPayloadMixin:
"""Mixin class for event models that have a single action payload."""

Expand Down
8 changes: 4 additions & 4 deletions streamdeck/models/events/dials.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from streamdeck.models.events.base import EventBase
from streamdeck.models.events.common import (
BasePayload,
ContextualEventMixin,
ContextualPayloadEventMixin,
CoordinatesPayloadMixin,
DeviceSpecificEventMixin,
EncoderControllerType,
Expand All @@ -31,21 +31,21 @@ class DialRotatePayload(EncoderPayload):
## Event models for DialDown, DialRotate, and DialUp events


class DialDown(EventBase[Literal["dialDown"]], ContextualEventMixin, DeviceSpecificEventMixin):
class DialDown(EventBase[Literal["dialDown"]], ContextualPayloadEventMixin[EncoderPayload], DeviceSpecificEventMixin): # fmt: skip
"""Occurs when the user presses a dial (Stream Deck +)."""

payload: EncoderPayload
"""Contextualized information for this event."""


class DialRotate(EventBase[Literal["dialRotate"]], ContextualEventMixin, DeviceSpecificEventMixin):
class DialRotate(EventBase[Literal["dialRotate"]], ContextualPayloadEventMixin[DialRotatePayload], DeviceSpecificEventMixin): # fmt: skip
"""Occurs when the user rotates a dial (Stream Deck +)."""

payload: DialRotatePayload
"""Contextualized information for this event."""


class DialUp(EventBase[Literal["dialUp"]], ContextualEventMixin, DeviceSpecificEventMixin):
class DialUp(EventBase[Literal["dialUp"]], ContextualPayloadEventMixin[EncoderPayload], DeviceSpecificEventMixin): # fmt: skip
"""Occurs when the user releases a pressed dial (Stream Deck +)."""

payload: EncoderPayload
Expand Down
6 changes: 3 additions & 3 deletions streamdeck/models/events/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from streamdeck.models.events.common import (
BasePayload,
CardinalityDiscriminated,
ContextualEventMixin,
ContextualPayloadEventMixin,
CoordinatesPayloadMixin,
DeviceSpecificEventMixin,
KeypadControllerType,
Expand Down Expand Up @@ -50,14 +50,14 @@ class MultiActionKeyGesturePayload(
## Event models for KeyDown and KeyUp events


class KeyDown(EventBase[Literal["keyDown"]], ContextualEventMixin, DeviceSpecificEventMixin):
class KeyDown(EventBase[Literal["keyDown"]], ContextualPayloadEventMixin[CardinalityDiscriminated[SingleActionKeyGesturePayload, MultiActionKeyGesturePayload]], DeviceSpecificEventMixin): # fmt: skip
"""Occurs when the user presses a action down."""

payload: CardinalityDiscriminated[SingleActionKeyGesturePayload, MultiActionKeyGesturePayload]
"""Contextualized information for this event."""


class KeyUp(EventBase[Literal["keyUp"]], ContextualEventMixin, DeviceSpecificEventMixin):
class KeyUp(EventBase[Literal["keyUp"]], ContextualPayloadEventMixin[CardinalityDiscriminated[SingleActionKeyGesturePayload, MultiActionKeyGesturePayload]], DeviceSpecificEventMixin): # fmt: skip
"""Occurs when the user releases a pressed action."""

payload: CardinalityDiscriminated[SingleActionKeyGesturePayload, MultiActionKeyGesturePayload]
Expand Down
13 changes: 4 additions & 9 deletions streamdeck/models/events/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
from streamdeck.models.events.common import (
BasePayload,
CardinalityDiscriminated,
ContextualEventMixin,
ContextualPayloadEventMixin,
CoordinatesPayloadMixin,
DeviceSpecificEventMixin,
KeypadControllerType,
MultiActionPayloadMixin,
SettingsPayloadMixin,
SingleActionPayloadMixin,
StatefulActionPayloadMixin,
)
from streamdeck.types import PluginDefinedData # noqa: TC001


## Models for didReceiveSettings event and its specific payloads.
Expand All @@ -40,9 +40,7 @@ class MultiActionSettingsPayload(
"""


class DidReceiveSettings(
EventBase[Literal["didReceiveSettings"]], ContextualEventMixin, DeviceSpecificEventMixin
):
class DidReceiveSettings(EventBase[Literal["didReceiveSettings"]], ContextualPayloadEventMixin[CardinalityDiscriminated[SingleActionSettingsPayload, MultiActionSettingsPayload]], DeviceSpecificEventMixin): # fmt: skip
"""Occurs when the settings associated with an action instance are requested, or when the the settings were updated by the property inspector."""

payload: CardinalityDiscriminated[SingleActionSettingsPayload, MultiActionSettingsPayload]
Expand All @@ -52,12 +50,9 @@ class DidReceiveSettings(
## Models for didReceiveGlobalSettings event and its specific payload.


class GlobalSettingsPayload(ConfiguredBaseModel):
class GlobalSettingsPayload(ConfiguredBaseModel, SettingsPayloadMixin):
"""Additional information about the didReceiveGlobalSettings event that occurred."""

settings: PluginDefinedData
"""The global settings received from the Stream Deck."""


class DidReceiveGlobalSettings(EventBase[Literal["didReceiveGlobalSettings"]]):
"""Occurs when the plugin receives the global settings from the Stream Deck."""
Expand Down
4 changes: 2 additions & 2 deletions streamdeck/models/events/title_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from streamdeck.models.events.base import ConfiguredBaseModel, EventBase
from streamdeck.models.events.common import (
BasePayload,
ContextualEventMixin,
ContextualPayloadEventMixin,
CoordinatesPayloadMixin,
DeviceSpecificEventMixin,
StatefulActionPayloadMixin,
Expand Down Expand Up @@ -50,7 +50,7 @@ class TitleParametersDidChangePayload(
"""Defines aesthetic properties that determine how the title should be rendered."""


class TitleParametersDidChange(EventBase[Literal["titleParametersDidChange"]], ContextualEventMixin, DeviceSpecificEventMixin): # fmt: skip
class TitleParametersDidChange(EventBase[Literal["titleParametersDidChange"]], ContextualPayloadEventMixin[TitleParametersDidChangePayload], DeviceSpecificEventMixin): # fmt: skip
"""Occurs when the user updates an action's title settings in the Stream Deck application."""

payload: TitleParametersDidChangePayload
4 changes: 2 additions & 2 deletions streamdeck/models/events/touch_tap.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from streamdeck.models.events.base import EventBase
from streamdeck.models.events.common import (
BasePayload,
ContextualEventMixin,
ContextualPayloadEventMixin,
CoordinatesPayloadMixin,
DeviceSpecificEventMixin,
EncoderControllerType,
Expand All @@ -23,7 +23,7 @@ class TouchTapPayload(BasePayload[EncoderControllerType], CoordinatesPayloadMixi
"""Coordinates of where the touchscreen tap occurred, relative to the canvas of the action."""


class TouchTap(EventBase[Literal["touchTap"]], ContextualEventMixin, DeviceSpecificEventMixin):
class TouchTap(EventBase[Literal["touchTap"]], ContextualPayloadEventMixin[TouchTapPayload], DeviceSpecificEventMixin): # fmt: skip
"""Occurs when the user taps the touchscreen (Stream Deck +)."""

payload: TouchTapPayload
Expand Down
6 changes: 3 additions & 3 deletions streamdeck/models/events/visibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from streamdeck.models.events.common import (
BasePayload,
CardinalityDiscriminated,
ContextualEventMixin,
ContextualPayloadEventMixin,
CoordinatesPayloadMixin,
DeviceSpecificEventMixin,
KeypadControllerType,
Expand Down Expand Up @@ -36,7 +36,7 @@ class MultiActionVisibilityPayload(
## Event models for WillAppear and WillDisappear events


class WillAppear(EventBase[Literal["willAppear"]], ContextualEventMixin, DeviceSpecificEventMixin):
class WillAppear(EventBase[Literal["willAppear"]], ContextualPayloadEventMixin[CardinalityDiscriminated[SingleActionVisibilityPayload, MultiActionVisibilityPayload]], DeviceSpecificEventMixin): # fmt: skip
"""Occurs when an action appears on the Stream Deck due to the user navigating to another page, profile, folder, etc.

This also occurs during startup if the action is on the "front page".
Expand All @@ -46,7 +46,7 @@ class WillAppear(EventBase[Literal["willAppear"]], ContextualEventMixin, DeviceS
payload: CardinalityDiscriminated[SingleActionVisibilityPayload, MultiActionVisibilityPayload]


class WillDisappear(EventBase[Literal["willDisappear"]], ContextualEventMixin, DeviceSpecificEventMixin): # fmt: skip
class WillDisappear(EventBase[Literal["willDisappear"]], ContextualPayloadEventMixin[CardinalityDiscriminated[SingleActionVisibilityPayload, MultiActionVisibilityPayload]], DeviceSpecificEventMixin): # fmt: skip
"""Occurs when an action disappears from the Stream Deck due to the user navigating to another page, profile, folder, etc.

An action refers to all types of actions, e.g. keys, dials, touchscreens, pedals, etc.
Expand Down
Loading