Skip to content

Commands API#375

Merged
FelipeDefensor merged 81 commits intodevfrom
refactor-timeline-requests
Mar 20, 2026
Merged

Commands API#375
FelipeDefensor merged 81 commits intodevfrom
refactor-timeline-requests

Conversation

@FelipeDefensor
Copy link
Collaborator

Introduces the commands API, a much simpler way to handle user interactions. Commands make all the following obsolete:

  • All timeline and timeline component RequestHandlers
  • TimelineComponentSelector
  • Several TimelineSelectors
  • TiliaActions
  • user_action fixture
  • TimelineUi.on_timeline_request, TimelineUI.on_timeline_component_request (substituted by TimelineUIs.on_timeline_command)
  • TimelineUIs.pre_process_timeline_request()
  • tilia\ui\timelines\collection\requests\args.py
  • Several Post and Get members
  • Some TimelineSelector members

The core functionality is given by command.py, along with fuller documentation.

Usage of commands:

    # Register a new command
    commands.register(
        'example.command',
        callback_function,
        text='Menu Text',  # Optional: for display in Qt interface
        shortcut='Ctrl+E',  # Optional: keyboard shortcut
        icon='example_icon'   # Optional: icon name in IMG_DIR (without extension)
    )

    # Execute a command
    commands.execute('example.command', arg1, arg2, kwarg1=value1)

Examples of commands:

  • File commands: 'file.open', 'file.save', 'file.export.img'
  • Timeline commands: 'timeline.delete', 'timeline.component.copy'
  • View commands: 'view.zoom.in', 'view.zoom.out'

Note that we can pass arguments to commands directly, so we don't need (horrible) things like TimelineSelector.FROM_MANAGE_TIMELINES_TO_PERMUTE.

Commands also set the stage for plugins, as they provide a simpler interface to modify application state programatically.

This PR also contains small changes that were covenient preliminaries for or complements to the implementation:
- Bug fixes (3be8cee, 24576bd, 6964fdd)
- Additional testing (467cb5e, f07fd4d)
- Convenient refactors (b8d15ef, 914a0bd, 974e715, 769e30b, f13fa08)
- Documentation (45dd1da)

This is a hacky, temporary solution. This state can be achieved by:
- Creating a score timeline and then deleting the beat timeline used to create it
- Restoring the app state (e.g. after an exception during a timeline command), if the svg viewer happens to be loaded before the beat timeline is restored
"" is a valid value for the color property, it means "use the default color", just as None.
…eline kinds

We should leverage classes as first-class citizens to use them instead of relying on an additional TimelineKind abstraction (TimelineKind). This is a first step towards that.
This commits introduces the commands API, a much simpler way to handle user interactions. Commands make all the following obsolete:

- All timeline and timeline component `RequestHandlers`
- `TimelineComponentSelector`
-  Several `TimelineSelectors`
- `TiliaActions`
- `user_action` fixture
- `TimelineUi.on_timeline_request`, `TimelineUI.on_timeline_component_request` (substituted by `TimelineUIs.on_timeline_command`)
- `TimelineUIs.pre_process_timeline_request()`
- `tilia\ui\timelines\collection\requests\args.py`
- Several `Post` and `Get` members
- Some `TimelineSelector` members

The core functionality is given by `command.py`, along with fuller documentation.

Usage of commands:
```
    # Register a new command
    commands.register(
        'example.command',
        callback_function,
        text='Menu Text',  # Optional: for display in Qt interface
        shortcut='Ctrl+E',  # Optional: keyboard shortcut
        icon='example_icon'   # Optional: icon name in IMG_DIR (without extension)
    )

    # Execute a command
    commands.execute('example.command', arg1, arg2, kwarg1=value1)
```

Examples of commands:
- File commands:        'file.open', 'file.save', 'file.export.img'
- Timeline commands:    'timeline.delete', 'timeline.component.copy'
- View commands:        'view.zoom.in', 'view.zoom.out'

Note that we can pass arguments to commands directly, so we don't need (horrible) things like `TimelineSelector.FROM_MANAGE_TIMELINES_TO_PERMUTE`.

Commands also set the stage for plugins, as they provide a simpler interface to modify application state programatically.
Also add tests for clear commands
Also improve message wording.
@FelipeDefensor
Copy link
Collaborator Author

This shaves of 600 lines, while still adding functionality and fixing a bunch of bugs. Feels good :)
grafik

@FelipeDefensor
Copy link
Collaborator Author

FelipeDefensor commented Nov 26, 2025

@azfoo, let me know if you want to review this (partly or fully).

@FelipeDefensor FelipeDefensor force-pushed the refactor-timeline-requests branch 2 times, most recently from 7749286 to 4749d00 Compare January 16, 2026 11:07
@FelipeDefensor FelipeDefensor requested a review from azfoo March 18, 2026 14:25
@FelipeDefensor
Copy link
Collaborator Author

I wasn't able to reproduce it anymore with that last file. This has happened again with another file, though. I am worried, but I don't know how we should proceed if we are not able to reproduce.

See #407.

@FelipeDefensor
Copy link
Collaborator Author

I am merging this before final approval to try and release v0.6.0 today. I don't think it will be possible though.

@FelipeDefensor FelipeDefensor merged commit 4c79fc9 into dev Mar 20, 2026
9 checks passed
@FelipeDefensor FelipeDefensor deleted the refactor-timeline-requests branch March 20, 2026 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Existing IDs are not being considered when choosing a new ID for a unit

2 participants