Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
62e0091
add: chaser filter type to type enum
Doralitze May 6, 2026
127d0d7
add: chaser filter node
Doralitze May 6, 2026
626a042
add: initial chaser filter model
Doralitze May 6, 2026
cd9a51d
add: layers table for further usage in GUI
Doralitze May 6, 2026
f639164
add: chaser_layer_help resource link
Doralitze May 7, 2026
5c02a19
add: layout prototype
Doralitze May 7, 2026
7f36eb4
add: missing chaser model serialization
Doralitze May 7, 2026
84c96cc
add: event selection button
Doralitze May 9, 2026
d9de2e0
add: parameter container widgets
Doralitze May 9, 2026
8317927
mrg: branch 'main' into 389-add-chaser-editor
Doralitze May 11, 2026
98a3626
fix: ruff issues in chaser model
Doralitze May 11, 2026
5652db9
chg: gif loading to be opportunistic
Doralitze May 13, 2026
6f8d6a3
add: functionality to parameter mgmt
Doralitze May 13, 2026
02699b0
chg: display preview query only if parameters configured
Doralitze May 13, 2026
e92377c
add: layer list to ChaserConfigWidget
Doralitze May 13, 2026
c2997a4
fix: ruff issues
Doralitze May 14, 2026
babc001
del: redundant variable
Doralitze May 14, 2026
0d43d8e
add: Percent Number Parameter Widget
Doralitze May 14, 2026
c45fd5d
chg: refactored classes to be in separate file
Doralitze May 15, 2026
61e81c5
chg: both number parameter widgets to share common base class
Doralitze May 15, 2026
ed28050
add: towards color parameter widget
Doralitze May 15, 2026
fc38fcf
add: preset selection logic
Doralitze May 15, 2026
33a74f3
mrg: branch 'main' into 389-add-chaser-editor
Doralitze May 15, 2026
582d552
add: color parameter widget change logic
Doralitze May 15, 2026
dbc413b
add: dialog stub
Doralitze May 15, 2026
6d27587
add: delete actions for layers and config
Doralitze May 15, 2026
7885b4a
fix: various issues
Doralitze May 15, 2026
95c5743
fix: layout
Doralitze May 15, 2026
8c9f611
fix: parameter settings widgets
Doralitze May 16, 2026
018d4eb
fix: gifs not rendering
Doralitze May 16, 2026
6b6e257
add: test button
Doralitze May 16, 2026
f948198
add: preset names
Doralitze May 16, 2026
8a13c85
add: extract command
Doralitze May 16, 2026
9132370
add: chaser update insert command dialog
Doralitze May 16, 2026
3c7ed2c
fix: variant data editing
Doralitze May 16, 2026
54b05f0
add: chaser preset UI widget
Doralitze May 17, 2026
147beb5
add: preset list ui widget final
Doralitze May 18, 2026
bb8f77e
fix: broken apply
Doralitze May 18, 2026
1f5fee2
fix: lambda layout
Doralitze May 19, 2026
139b306
fix: layer removal
Doralitze May 19, 2026
3275862
fix: missing mask mod parameters
Doralitze May 19, 2026
62fe501
add: live config uiwidget prototype
Doralitze May 19, 2026
362757b
chg: layer param list separator to line
Doralitze May 19, 2026
e997c13
add: layer up / down buttons
Doralitze May 19, 2026
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
1 change: 1 addition & 0 deletions Project-Editor.spec
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ added_files = [
( 'src/resources/data', 'resources/data' ),
( 'src/resources/fonts', 'resources/fonts' ),
( 'src/resources/icons', 'resources/icons' ),
( 'src/resources/chaser_layer_help', 'resources/chaser_layer_help' ),
( 'src/configs','configs')
]

Expand Down
2 changes: 2 additions & 0 deletions src/controller/cli/cli_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from controller.cli.bankset_command import BankSetCommand
from controller.cli.connect_command import ConnectCommand
from controller.cli.event_command import EventCommand
from controller.cli.extract_command import ExtractCommand
from controller.cli.fish_con_command import FishConnCommand
from controller.cli.help_command import HelpCommand
from controller.cli.list_command import ListCommand
Expand Down Expand Up @@ -106,6 +107,7 @@ def __init__(self, show: BoardConfiguration, network_manager: NetworkManager, ex
ConnectCommand(self),
FishConnCommand(self),
UIPageCommand(self),
ExtractCommand(self),
]
self._selected_bank: BankSet | None = None
self._selected_scene: Scene | None = None
Expand Down
67 changes: 67 additions & 0 deletions src/controller/cli/extract_command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""Contains extract command."""

from __future__ import annotations

from typing import TYPE_CHECKING, override

from controller.cli.command import Command

if TYPE_CHECKING:
from argparse import ArgumentParser, Namespace

from controller.cli.cli_context import CLIContext


class ExtractCommand(Command):
"""Command to extract element from list."""

def __init__(self, context: CLIContext) -> None:
"""Initialize the command."""
super().__init__(context, "extract")
self._help_text = "Extract element from list"

@override
def configure_parser(self, parser: ArgumentParser) -> None:
parser.add_argument("destination", type=str, help="Destination variable.")
parser.add_argument("element", type=int, help="Index of element to extract.")
subparsers = parser.add_subparsers(dest="target", help="Extraction target.")
for target in ["filter-param", "filter-config"]:
filter_param_parser = subparsers.add_parser(
target,
help=f"Extract {target} from filter.",
exit_on_error=False
)
filter_param_parser.add_argument("--scene", type=int, default=-1,
help="Scene of the filter. Default: Current selected scene.")
filter_param_parser.add_argument("fid", type=str, help="Filter ID.")
filter_param_parser.add_argument("parameter", type=str, help="The parameter to extract.")
filter_param_parser.add_argument("delimiter", type=str, help="The delimiter to use.")

@override
def execute(self, args: Namespace) -> bool:
match args.target:
case "filter-param" | "filter-config":
scene = args.scene
if scene == -1:
scene = self.context.selected_scene
if scene is None:
self.context.print("Error: No scene specified.")
return False
if isinstance(scene, int):
scene = self.context.show.get_scene_by_id(scene)
if scene is None:
self.context.print("Error: No scene with specified ID exists.")
return False
filter_inst = scene.get_filter_by_id(args.fid)
if filter_inst is None:
self.context.print(f"Error: No filter with ID '{args.fid}' not found.")
return False
selected_dict = filter_inst.initial_parameters if args.target == "filter-param"\
else filter_inst.filter_configurations
splitted_param = selected_dict.get(args.parameter, "").split(args.delimiter)
element = splitted_param[args.element] if abs(args.element) < len(splitted_param) else ""
if len(args.destination) < 0:
self.context.print("Error: Invalid destination variable.")
return False
self.context.update_variables({args.destination: element})
return True
9 changes: 8 additions & 1 deletion src/controller/cli/help_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ def execute(self, args: Namespace) -> bool:
self.context.print("\tscene -- Select the scene to perform actions on")
self.context.print("\tcolumn -- Select the control desk column to perform actions on")
self.context.print("\tbank_set -- Select the control desk bank set to perform actions on")
case "extract":
self.context.print("Use this command to extract data from concatenated lists and store it in the "
"specified destination variable.")
self.context.print("Usage: extract <destination> <element> <target> <...>")
self.context.print("The following targets exist:")
self.context.print("\tfilter-param [--scene <scene>] <filter-id> <parameter> <delimiter>")
self.context.print("\tfilter-config [--scene <scene>] <filter-id> <parameter> <delimiter>")
case "list":
self.context.print("This command displays the content of system collections.")
self.context.print("The following containers can be queried:")
Expand Down Expand Up @@ -99,6 +106,6 @@ def execute(self, args: Namespace) -> bool:
self.context.print(f"ERROR: The requested help topic '{args.topic}' is unknown.")
self.context.print("The following topics are known:")
self.context.print("\tevent\tselect\tlist\tpatch\tbank_set\tshowctl\tdelay\tmacro")
self.context.print("\tprint\tasset\tset\tif\tconnect\tfish\tuipage")
self.context.print("\tprint\tasset\tset\tif\tconnect\tfish\tuipage\textract")
return False
return True
29 changes: 29 additions & 0 deletions src/model/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

from logging import getLogger
from typing import NamedTuple

import proto.Events_pb2
from controller.network import NetworkManager
Expand Down Expand Up @@ -63,6 +64,34 @@ def handle_incoming_sender_update(msg: proto.Events_pb2.event_sender) -> None:
_broadcaster_instance.event_sender_update.connect(handle_incoming_sender_update)


class EventFilter(NamedTuple):
"""Event Filter Description."""

event_sender: int
event_sender_function: int
args: list[int]

@staticmethod
def from_filter_str(filter_str: str) -> EventFilter:
"""Create a EventFilter instance from a filter string."""
parts = filter_str.split(":")
if len(parts) < 2:
raise ValueError(f"Invalid filter string: '{filter_str}'")
ef = EventFilter()
ef.event_sender = int(parts[0])
ef.event_sender_function = int(parts[1])
parts.pop(0)
parts.pop(0)
for arg in parts:
ef.args.append(int(arg))

def format_for_filters(self) -> str:
"""Serialize the event filter into a string representation."""
mlist = [str(self.event_sender), str(self.event_sender_function)]
mlist.extend(str(i) for i in self.args)
return ":".join(mlist)


class EventSender:
"""Base class for fish event sender representations.

Expand Down
1 change: 1 addition & 0 deletions src/model/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ class FilterTypeEnumeration(IntFlag):
FILTER_RESPONDING_CONSTANT_16BIT = 72
FILTER_RESPONDING_CONSTANT_FLOAT = 73
FILTER_RESPONDING_CONSTANT_COLOR = 74
FILTER_COLOR_CHASER = 75


class Filter:
Expand Down
Loading
Loading