Custom editors and plugin windows
Video effects, audio effects and generators can replace the standard parameter form with a fully custom editor while keeping the same declarative parameter data for project persistence, presets, preview and export.
Timeline processors continue to use the native parameter UI.
Use a custom editor for genuinely visual interactions such as an image-driven interface, node editor, meter, spatial control or bespoke canvas. Prefer native controls for normal numeric, boolean and choice settings.
Note: Yrendr owns window movement, resizing, focus and close/minimize/maximize hitboxes. Custom editors should draw presentation around that host-owned behavior.
Register a custom editor
Pass custom_editor= and, optionally, window_options= while registering the effect or generator:
from editor.plugin_api import (
PluginParameterDefinition,
PluginWindowOptions,
)
def register(api):
api.register_video_effect(
effect_id="visual_editor",
name="Visual Editor",
processor=process,
parameters=(
PluginParameterDefinition(
key="strength",
label="Strength",
control="slider",
default=1.0,
minimum=0.0,
maximum=2.0,
step=0.01,
),
),
custom_editor=edit_parameters,
window_options=PluginWindowOptions(
initial_size=(960, 720),
minimum_size=(640, 480),
maximum_size=(1440, 1080),
resizable=True,
resize_mode="aspect",
aspect_ratio=4 / 3,
resize_grip_size=24,
draggable=True,
minimizable=False,
maximizable=False,
show_title_bar=True,
show_close_button=True,
title_bar_height=46,
border_radius=14,
border_width=1,
border_color=(86, 93, 102),
topbar_renderer=draw_custom_topbar,
),
)Keep the normal PluginParameterDefinition entries even when the visual editor does not render those controls directly. The parameter dictionary remains the stable data contract used by projects, presets, preview and export.
Custom editor callback
Yrendr calls a custom editor with keyword arguments:
def edit_parameters(
*,
definition,
parameters,
on_live_change=None,
background_tick=None,
waveform_provider=None,
window_key=None,
window_options=None,
):
...| Argument | Meaning |
|---|---|
definition |
The registered PluginEffectDefinition. |
parameters |
A deep-copied parameter dictionary for the current instance. |
on_live_change |
Optional callback for previewing parameter changes while the editor is open. |
background_tick |
Optional callback that lets the main editor continue its background/playback work. |
waveform_provider |
Optional audio waveform provider when available. |
window_key |
Stable host identity used for singleton/focus behavior. |
window_options |
The normalized PluginWindowOptions for the definition. |
Return the final parameter dictionary to apply the edit. Return None to cancel. If live changes were previewed, restore the original values before returning None when cancel should discard that preview.
PluginWindowOptions
PluginWindowOptions keeps window behavior in the host while allowing plugins to control sizing and presentation.
| Field | Default | Meaning |
|---|---|---|
initial_size |
None |
Preferred initial (width, height). |
minimum_size |
None |
Smallest allowed window size. |
maximum_size |
None |
Largest allowed window size. |
resizable |
True |
Enables host-owned resizing. |
draggable |
True |
Enables host-owned dragging. |
minimizable |
False |
Enables minimize and the host Windows-list restore path. |
maximizable |
False |
Enables maximize. |
resize_mode |
"free" |
Chooses the allowed resize behavior. |
aspect_ratio |
None |
Ratio used by resize_mode="aspect". |
resize_grip_size |
18 |
Bottom-right resize hit-area size. |
show_title_bar |
True |
Enables title-bar interaction/presentation. |
show_close_button |
True |
Enables the host close button/hitbox. |
title_bar_height |
54 |
Height reserved for title-bar interaction. |
border_radius |
6 |
Window corner radius when not maximized. |
border_width |
1 |
Host-drawn border width. 0 disables that border. |
border_color |
None |
Optional RGB border override. |
topbar_renderer |
None |
Optional callback that draws custom title-bar visuals/actions. |
A plain dictionary using supported option keys is also accepted and normalized to PluginWindowOptions.
Resize modes
resize_mode accepts free, aspect, horizontal, vertical or fixed. Use minimum_size and maximum_size to keep artwork and interaction regions usable at every supported size.
Full-panel content renderer
Custom editors can draw across the complete modal by passing content_renderer= to ModalSession.draw_panel():
def render_content(surface, panel_rect, state):
draw_plugin_ui(surface, panel_rect, state)
panel = modal.draw_panel(
initial_size,
definition.name,
content_renderer=render_content,
)The content renderer receives the display surface, the current panel rectangle and a state mapping. Yrendr draws the configured border/title-bar layer after the full-panel content.
Custom topbar renderer
A topbar_renderer receives the surface, panel rectangle, title, host control rectangles and a state mapping. Yrendr still owns close, minimize, maximize, dragging and resizing.
The renderer may also return custom action rectangles:
def draw_custom_topbar(surface, panel, title, controls, state):
apply_rect = draw_apply_button(surface, panel)
reset_rect = draw_reset_button(surface, panel)
return {
"apply": apply_rect,
"reset": reset_rect,
}Yrendr excludes returned action rectangles from title-bar dragging. A modal loop can query them with:
action = modal.titlebar_action_at(event.pos)
if action == "apply":
return valuesThis lets a plugin add branded title-bar actions without reimplementing window movement or overlapping drag hitboxes.
Singleton windows and window_key
Use the window_key supplied by Yrendr when constructing ModalSession. A stable key identifies the logical editor instance, allowing the host to focus/restore the existing window instead of opening duplicates.
Do not generate a new key on every redraw.
Design rules
- Keep persisted state in declared parameters, not only in custom UI objects.
- Treat the custom editor as presentation around the same effect definition used during export.
- Use
on_live_changefor useful feedback but avoid expensive processing on every pointer event when commit-on-release is sufficient. - Respect
background_tickinstead of running a second editor loop. - Let Yrendr own dragging, resizing, minimizing, maximizing and close hitboxes.
- Return custom topbar action rectangles when those buttons overlap title-bar drag space.
- Make layouts responsive to the current panel rectangle.
- Return
Nonefor cancel and a JSON-compatible parameter dictionary for apply.