<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.mxwendler.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Admin</id>
	<title>MXWendler Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.mxwendler.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Admin"/>
	<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Special:Contributions/Admin"/>
	<updated>2026-08-21T19:20:01Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.42.3</generator>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Tutorials&amp;diff=6216</id>
		<title>Tutorials</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Tutorials&amp;diff=6216"/>
		<updated>2026-08-09T18:13:18Z</updated>

		<summary type="html">&lt;p&gt;Admin: Remove mis-titled Streamdeck tutorial link (page was a Wii-tutorial copy, being deleted)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==General==&lt;br /&gt;
*[[Tutorial Opening Different Media]]&lt;br /&gt;
*[[Tutorial Setting up Stage Designer Output Windows]]&lt;br /&gt;
*[[Tutorial Triggering Four Media with the Keyboard]]&lt;br /&gt;
*[[Tutorial Coupling Video with Effects and Audio Signals]]&lt;br /&gt;
*[[Tutorial Creating Predefined Layer Position]]&lt;br /&gt;
*[[Tutorial Feedback]]&lt;br /&gt;
*[[Tutorial Creating an I/O Event]]&lt;br /&gt;
*[[Tutorial Creating an Autostart Showfile]]&lt;br /&gt;
*[[Tutorial Creating Compositions (Sets and Patches)]]&lt;br /&gt;
*[[Tutorial Creating Multiple Compositions and Patches]]&lt;br /&gt;
*[[Tutorial Creating and Playing an RTF Text File]]&lt;br /&gt;
*[[Tutorial Licensing New Features]]&lt;br /&gt;
*[[Tutorial Loading and Using JavaScripts in MXWendler]]&lt;br /&gt;
*[[Tutorial Configuring a Virtual Camera]]&lt;br /&gt;
&lt;br /&gt;
==Playlist==&lt;br /&gt;
*[[Tutorial Creating Playlists (Cue Lists)]]&lt;br /&gt;
*[[Tutorial Playlists with Images and Keystone Correction]]&lt;br /&gt;
*[[Tutorial Playlists with Timeline]]&lt;br /&gt;
*[[Tutorial Playlists with Multi-Timeline]]&lt;br /&gt;
*[[Tutorial Playlists with Time and Date Conditions]]&lt;br /&gt;
*[[Tutorial Playlists with Timecode]]&lt;br /&gt;
*[[Tutorial Playlists with Subtitles]]&lt;br /&gt;
*[[Tutorial Playlists with IO - Commands]]&lt;br /&gt;
*[[Tutorial Playlists with PDF and Frame Step]]&lt;br /&gt;
*[[Tutorial Resetting Runtime Counter with IO Commands in Playlist]]&lt;br /&gt;
*[[Tutorial Playlists with Fade Clip]]&lt;br /&gt;
*[[Tutorial Playlists with Auto Step]]&lt;br /&gt;
*[[Tutorial Playlists with Reset Counter]]&lt;br /&gt;
*[[Tutorial Playlists with Shutdown]]&lt;br /&gt;
*[[Tutorial Playlists with Load Show]]&lt;br /&gt;
*[[Tutorial Playlists with OSC Command]]&lt;br /&gt;
*[[Tutorial Playlists with Sys Command]]&lt;br /&gt;
*[[Tutorial Playlists with PJlink Command]]&lt;br /&gt;
*[[Tutorial Playlists in Rehearsal Mode]]&lt;br /&gt;
*[[Tutorial Creating an Automated Show with Daily Event and Playlist Conditions]]&lt;br /&gt;
&lt;br /&gt;
==Keystone==&lt;br /&gt;
*[[Tutorial Simultaneous Playback of two Videos with two Video Projectors]]&lt;br /&gt;
*[[Tutorial Mapping with UV View]]&lt;br /&gt;
*[[Tutorial Masked Output]]&lt;br /&gt;
*[[Tutorial Colored Output with Animations]]&lt;br /&gt;
*[[Tutorial Capture Output Sections with Artnet DMX and Network Grabbers]]&lt;br /&gt;
*[[Tutorial SVG Mapping with the MXWendler Automatic Calibration]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==IO Devices==&lt;br /&gt;
*[[Reference Open Sound Control - OSC]]&lt;br /&gt;
*[[Reference JavaScript]]&lt;br /&gt;
*[[Tutorial Using the Akai APC Mini (Note On/Off)]]&lt;br /&gt;
*[[Tutorial Connecting the grandMA 2Port Node with MXWendler via Art-Net]]&lt;br /&gt;
*[[Tutorial Connecting Jands Vista2 with MXWendler via Art-Net]]&lt;br /&gt;
*[[Tutorial Set up the CITP Footage Library on the Media Server]]&lt;br /&gt;
*[[Tutorial Time-sync and sending IO Commands over OSC Protocol]]&lt;br /&gt;
*[[Tutorial Controlling MXWendler via TouchOSC]]&lt;br /&gt;
*[[Tutorial Optimum Audio Settings with an Integrated Audio Interface]]&lt;br /&gt;
*[[Tutorial Optimum Audio Settings with an External Audio Interface]]&lt;br /&gt;
*[[Tutorial Eventmaster Toolset Controlling MXWendler by e.g. e2 S3 Image Processor]]&lt;br /&gt;
&lt;br /&gt;
==FXServer==&lt;br /&gt;
*[[Tutorial FXServer Output Windows]]&lt;br /&gt;
&lt;br /&gt;
*[[Tutorial How to Setup a Datapath Fx4 for MXWendler with the Wall Designer Software]]&lt;br /&gt;
&lt;br /&gt;
*[[Tutorial How to Optimize Video Footages With Blender]]&lt;br /&gt;
&lt;br /&gt;
==Standalone Encoder==&lt;br /&gt;
*[[Tutorial Standalone Encoder / Video Batch Encoder]]&lt;br /&gt;
&lt;br /&gt;
==EDID Manager==&lt;br /&gt;
*[[Tutorial MXWendler EDID Manager]]&lt;br /&gt;
&lt;br /&gt;
==NDI Tools==&lt;br /&gt;
*[[Tutorial NDI Tools ]]&lt;br /&gt;
*[[Tutorial Sending and Receiving Multiple Video Streams with NDI]]&lt;br /&gt;
&lt;br /&gt;
==Spout==&lt;br /&gt;
*[[Tutorial Sending and Receiving Media Through Spout]]&lt;br /&gt;
*[[Tutorial Connecting Winamp Generative Visuals with MXWendler via Spout]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Tutorials&amp;diff=6215</id>
		<title>Tutorials</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Tutorials&amp;diff=6215"/>
		<updated>2026-08-09T17:25:23Z</updated>

		<summary type="html">&lt;p&gt;Admin: Remove Wiimote tutorial link (feature removed)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==General==&lt;br /&gt;
*[[Tutorial Opening Different Media]]&lt;br /&gt;
*[[Tutorial Setting up Stage Designer Output Windows]]&lt;br /&gt;
*[[Tutorial Triggering Four Media with the Keyboard]]&lt;br /&gt;
*[[Tutorial Coupling Video with Effects and Audio Signals]]&lt;br /&gt;
*[[Tutorial Creating Predefined Layer Position]]&lt;br /&gt;
*[[Tutorial Feedback]]&lt;br /&gt;
*[[Tutorial Creating an I/O Event]]&lt;br /&gt;
*[[Tutorial Creating an Autostart Showfile]]&lt;br /&gt;
*[[Tutorial Creating Compositions (Sets and Patches)]]&lt;br /&gt;
*[[Tutorial Creating Multiple Compositions and Patches]]&lt;br /&gt;
*[[Tutorial Creating and Playing an RTF Text File]]&lt;br /&gt;
*[[Tutorial Licensing New Features]]&lt;br /&gt;
*[[Tutorial Loading and Using JavaScripts in MXWendler]]&lt;br /&gt;
*[[Tutorial Configuring a Virtual Camera]]&lt;br /&gt;
&lt;br /&gt;
==Playlist==&lt;br /&gt;
*[[Tutorial Creating Playlists (Cue Lists)]]&lt;br /&gt;
*[[Tutorial Playlists with Images and Keystone Correction]]&lt;br /&gt;
*[[Tutorial Playlists with Timeline]]&lt;br /&gt;
*[[Tutorial Playlists with Multi-Timeline]]&lt;br /&gt;
*[[Tutorial Playlists with Time and Date Conditions]]&lt;br /&gt;
*[[Tutorial Playlists with Timecode]]&lt;br /&gt;
*[[Tutorial Playlists with Subtitles]]&lt;br /&gt;
*[[Tutorial Playlists with IO - Commands]]&lt;br /&gt;
*[[Tutorial Playlists with PDF and Frame Step]]&lt;br /&gt;
*[[Tutorial Resetting Runtime Counter with IO Commands in Playlist]]&lt;br /&gt;
*[[Tutorial Playlists with Fade Clip]]&lt;br /&gt;
*[[Tutorial Playlists with Auto Step]]&lt;br /&gt;
*[[Tutorial Playlists with Reset Counter]]&lt;br /&gt;
*[[Tutorial Playlists with Shutdown]]&lt;br /&gt;
*[[Tutorial Playlists with Load Show]]&lt;br /&gt;
*[[Tutorial Playlists with OSC Command]]&lt;br /&gt;
*[[Tutorial Playlists with Sys Command]]&lt;br /&gt;
*[[Tutorial Playlists with PJlink Command]]&lt;br /&gt;
*[[Tutorial Playlists in Rehearsal Mode]]&lt;br /&gt;
*[[Tutorial Creating an Automated Show with Daily Event and Playlist Conditions]]&lt;br /&gt;
&lt;br /&gt;
==Keystone==&lt;br /&gt;
*[[Tutorial Simultaneous Playback of two Videos with two Video Projectors]]&lt;br /&gt;
*[[Tutorial Mapping with UV View]]&lt;br /&gt;
*[[Tutorial Masked Output]]&lt;br /&gt;
*[[Tutorial Colored Output with Animations]]&lt;br /&gt;
*[[Tutorial Capture Output Sections with Artnet DMX and Network Grabbers]]&lt;br /&gt;
*[[Tutorial SVG Mapping with the MXWendler Automatic Calibration]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==IO Devices==&lt;br /&gt;
*[[Reference Open Sound Control - OSC]]&lt;br /&gt;
*[[Reference JavaScript]]&lt;br /&gt;
*[[Tutorial Using the Akai APC Mini (Note On/Off)]]&lt;br /&gt;
*[[Tutorial Connecting the grandMA 2Port Node with MXWendler via Art-Net]]&lt;br /&gt;
*[[Tutorial Connecting Jands Vista2 with MXWendler via Art-Net]]&lt;br /&gt;
*[[Tutorial Set up the CITP Footage Library on the Media Server]]&lt;br /&gt;
*[[Tutorial Time-sync and sending IO Commands over OSC Protocol]]&lt;br /&gt;
*[[Tutorial Controlling MXWendler via TouchOSC]]&lt;br /&gt;
*[[Tutorial Optimum Audio Settings with an Integrated Audio Interface]]&lt;br /&gt;
*[[Tutorial Optimum Audio Settings with an External Audio Interface]]&lt;br /&gt;
*[[Tutorial Controlling StageDesigner with Elgato Streamdeck]]&lt;br /&gt;
*[[Tutorial Eventmaster Toolset Controlling MXWendler by e.g. e2 S3 Image Processor]]&lt;br /&gt;
&lt;br /&gt;
==FXServer==&lt;br /&gt;
*[[Tutorial FXServer Output Windows]]&lt;br /&gt;
&lt;br /&gt;
*[[Tutorial How to Setup a Datapath Fx4 for MXWendler with the Wall Designer Software]]&lt;br /&gt;
&lt;br /&gt;
*[[Tutorial How to Optimize Video Footages With Blender]]&lt;br /&gt;
&lt;br /&gt;
==Standalone Encoder==&lt;br /&gt;
*[[Tutorial Standalone Encoder / Video Batch Encoder]]&lt;br /&gt;
&lt;br /&gt;
==EDID Manager==&lt;br /&gt;
*[[Tutorial MXWendler EDID Manager]]&lt;br /&gt;
&lt;br /&gt;
==NDI Tools==&lt;br /&gt;
*[[Tutorial NDI Tools ]]&lt;br /&gt;
*[[Tutorial Sending and Receiving Multiple Video Streams with NDI]]&lt;br /&gt;
&lt;br /&gt;
==Spout==&lt;br /&gt;
*[[Tutorial Sending and Receiving Media Through Spout]]&lt;br /&gt;
*[[Tutorial Connecting Winamp Generative Visuals with MXWendler via Spout]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Triggering&amp;diff=6214</id>
		<title>Triggering</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Triggering&amp;diff=6214"/>
		<updated>2026-08-09T17:25:22Z</updated>

		<summary type="html">&lt;p&gt;Admin: Remove link to TUIO tutorial (feature removed)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;MXWENDLER enables you to trigger a whole series of events and animations with a keystone, or a MIDI / DMX event. &lt;br /&gt;
&lt;br /&gt;
*[[About Events]]&lt;br /&gt;
*[[Creating events]]&lt;br /&gt;
*[[Events / Widgets and Their Addresses / Intrinsic Values]]&lt;br /&gt;
*[[Examples of events]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=About_Events&amp;diff=6213</id>
		<title>About Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=About_Events&amp;diff=6213"/>
		<updated>2026-08-09T17:25:21Z</updated>

		<summary type="html">&lt;p&gt;Admin: Remove TUIO/Wii from trigger tool list (feature removed)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;MXWendler enables you to trigger a whole series of events and animations with a keystroke or a MIDI/DMX event. All events work according to the same principle: a trigger activates an event, which sends a specific value to a receiver at a specific time.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Events are managed in the IO Devices Settings:&lt;br /&gt;
&lt;br /&gt;
1. Open &#039;DMX/MIDI/Keyboard Events&#039; in the settings: &#039;&#039;&#039;(A)&#039;&#039;&#039;&lt;br /&gt;
:&#039;&#039;&#039;Menu: Settings &amp;amp;rarr; IO Devices &amp;amp;rarr; DMX/MIDI/Keyboard Events&#039;&#039;&#039;&lt;br /&gt;
2. Determine the trigger by selecting the respective tool: DMX, MIDI, Keyboard or Timer. &#039;&#039;&#039;(B)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
3. Create an event with the &#039;+&#039; button. &#039;&#039;&#039;(C)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
4. Activate an event. &#039;&#039;&#039;(D)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
5. Specify the various event settings (receiver / event type / time / value). &#039;&#039;&#039;(E)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Events_1.png|728px]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Hardware&amp;diff=6212</id>
		<title>Hardware</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Hardware&amp;diff=6212"/>
		<updated>2026-08-09T17:25:20Z</updated>

		<summary type="html">&lt;p&gt;Admin: Remove TUIO and WiiRemote controller support (feature removed)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=== Building an Optimum System ===&lt;br /&gt;
&lt;br /&gt;
In general, you can be sure that any dedicated graphics card available today can run the MXWendler software. But there are performance differences, so feel free to ask at support[at]mxwendler.net.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Operating System&lt;br /&gt;
*Windows 7, Windows 8, Windows 8.1, Windows 10 - all 32 and 64 Bit&lt;br /&gt;
*Max OS X 10.7, 10.8, 10.9&lt;br /&gt;
Processor&lt;br /&gt;
*We equally work with AMD and Intel Processors. &lt;br /&gt;
*Many PCI devices: The AMD Threadripper series is recommended for the high number of PCI Lanes&lt;br /&gt;
*High Core speed: The Intel i7 and i9 series have a usually higher core speed&lt;br /&gt;
{{#mpdftags: pagebreak}}&lt;br /&gt;
Graphic card&lt;br /&gt;
*Our reference hardware in matter of graphic cards is AMD, especially the Radeon Pro series.&lt;br /&gt;
*NVidia Quadro series.&lt;br /&gt;
*More than 2Gb dedicated Memory is recommended.&lt;br /&gt;
*SLI or dual-GPU setups are not recommended.&lt;br /&gt;
Disk&lt;br /&gt;
*M.2 disks for fast access supported (Samsung 970 Plus)&lt;br /&gt;
*SSD &lt;br /&gt;
*Raid for HD content supported&lt;br /&gt;
*Any disk possible&lt;br /&gt;
External Controller&lt;br /&gt;
*Midi supported ( any standard midi )&lt;br /&gt;
*Midi motor fader supported&lt;br /&gt;
*DMX supported ( Enttec, Soundlight, e:cue )&lt;br /&gt;
*OSC supported&lt;br /&gt;
*Art-Net supported&lt;br /&gt;
{{#mpdftags: pagebreak}}&lt;br /&gt;
Memory&lt;br /&gt;
*Recommended 16GB&lt;br /&gt;
Audio&lt;br /&gt;
*Windows: Multichannel ASIO Audio supported&lt;br /&gt;
*Windows: System Audio&lt;br /&gt;
*Mac: Multichannel Core Audio supported&lt;br /&gt;
&lt;br /&gt;
{{#mpdftags: pagebreak}}&lt;br /&gt;
System resource requirements, based on different performance needs:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Minimum&#039;&#039;&#039;&lt;br /&gt;
*CPU: Intel i7 7700k, Amd 1900x  &lt;br /&gt;
*GPU: AMD: RadeonPro wx3100, NVIDIA: Quadro P620&lt;br /&gt;
*Disk: SSD Samsung 970 Evo or SATA 7200 Rpm&lt;br /&gt;
*RAM: 8GB&lt;br /&gt;
&#039;&#039;&#039;Medium&#039;&#039;&#039;&lt;br /&gt;
*CPU: Intel i7 9700k, Amd 2920x&lt;br /&gt;
*GPU: AMD: RadeonPro wx7100, NVIDIA: Quadro P2200&lt;br /&gt;
*Disk: M.2 Samsung 970 Plus Evo&lt;br /&gt;
*RAM: 16GB&lt;br /&gt;
&#039;&#039;&#039;High&#039;&#039;&#039;&lt;br /&gt;
*CPU: Intel i9 9900k, AMD Ryzen 9 3900x, Amd 2950x&lt;br /&gt;
*GPU: AMD: RadeonPro wx8200, NVIDIA: Quadro P4000&lt;br /&gt;
*Disk: M.2 Samsung 970 Plus Evo or 970 Pro&lt;br /&gt;
*RAM: 32GB+&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Python_plugin_reference&amp;diff=6211</id>
		<title>Python plugin reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Python_plugin_reference&amp;diff=6211"/>
		<updated>2026-08-09T16:00:35Z</updated>

		<summary type="html">&lt;p&gt;Admin: docs: audio streams — mxw.audio capture + audio-producing media plugins (device-rate adaptive)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- MXWendler wiki page: How to create a Python plugin (media and playlist) --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Intended location: https://wiki.mxwendler.net/index.php?title=Python_plugin_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_command_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_imgui_reference --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MXWendler StageDesigner can be extended with &#039;&#039;&#039;Python plugins&#039;&#039;&#039;. A plugin is a plain folder containing a manifest file and a Python module; MXWendler discovers it at startup, shows it in the user interface and calls a defined set of Python functions (&#039;&#039;hooks&#039;&#039;) at the right moments.&lt;br /&gt;
&lt;br /&gt;
Two plugin types exist:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Media plugins&#039;&#039;&#039; produce pixels: they appear as a media source that can be placed in a clip like any video file. Examples: a web browser media, a generative OpenGL cube.&lt;br /&gt;
* &#039;&#039;&#039;Playlist plugins&#039;&#039;&#039; are items in the playlist grid: they run logic when their cue plays. Examples: advance the playlist at a given time of day, write video files, ping a host.&lt;br /&gt;
&lt;br /&gt;
The embedded interpreter is &#039;&#039;&#039;Python 3.12&#039;&#039;&#039;. The general Python command interface (module &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt;) is documented in the [[Python command reference|Python command reference]].&lt;br /&gt;
&lt;br /&gt;
== Plugin anatomy ==&lt;br /&gt;
&lt;br /&gt;
A plugin is one folder with at least two files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
plugins/media/python/plugin_my_effect/&lt;br /&gt;
    mxw_plugin.ini      the manifest: identity, menu entries, addressing&lt;br /&gt;
    mxw_main.py         the Python module with the hook functions&lt;br /&gt;
    (more .py files)    optional: importable as &amp;quot;from plugin_my_effect.xyz import ...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The folder name is the Python package name: additional modules in the folder are imported with absolute imports, e.g. &amp;lt;code&amp;gt;from plugin_my_effect.helpers import foo&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Plugin locations ===&lt;br /&gt;
&lt;br /&gt;
Plugins are searched in several directories. &#039;&#039;&#039;User-controlled locations always override the bundled system location&#039;&#039;&#039;, so a user can replace a built-in plugin by placing a same-named folder in a higher-precedence directory — even without write access to the installation.&lt;br /&gt;
&lt;br /&gt;
Media plugins, descending precedence:&lt;br /&gt;
&lt;br /&gt;
# The open &amp;lt;code&amp;gt;.mxw&amp;lt;/code&amp;gt; project&#039;s &amp;lt;code&amp;gt;plugins/media/python/&amp;lt;/code&amp;gt; tree (opt-in via settings, highest precedence)&lt;br /&gt;
# Directories configured explicitly in the settings (Python tab)&lt;br /&gt;
# The per-user data directory, e.g. &amp;lt;code&amp;gt;%APPDATA%/MXWendler/plugins/media/python/&amp;lt;/code&amp;gt;&lt;br /&gt;
# The installation / resource directory: &amp;lt;code&amp;gt;plugins/media/python/&amp;lt;/code&amp;gt; (also &amp;lt;code&amp;gt;plugins/media/python_dev/&amp;lt;/code&amp;gt;, same precedence, for internal/unpublished plugins)&lt;br /&gt;
&lt;br /&gt;
Playlist plugins, descending precedence:&lt;br /&gt;
&lt;br /&gt;
# The open &amp;lt;code&amp;gt;.mxw&amp;lt;/code&amp;gt; project&#039;s &amp;lt;code&amp;gt;plugins/playlist/python/&amp;lt;/code&amp;gt; tree (opt-in via settings, highest precedence)&lt;br /&gt;
# Directories configured explicitly in the settings (Python tab)&lt;br /&gt;
# The per-user data directory: &amp;lt;code&amp;gt;.../plugins/playlist/python/&amp;lt;/code&amp;gt;&lt;br /&gt;
# The installation / resource directory: &amp;lt;code&amp;gt;plugins/playlist/python/&amp;lt;/code&amp;gt; (also &amp;lt;code&amp;gt;plugins/playlist/python_dev/&amp;lt;/code&amp;gt;, same precedence, for internal/unpublished plugins)&lt;br /&gt;
&lt;br /&gt;
=== The manifest: mxw_plugin.ini ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[mxw_plugin]                            ; must be here&lt;br /&gt;
plugin_version = 1                      ; must be V1&lt;br /&gt;
plugin_script_language = Python         ; must be Python&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Common keys:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Used by !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_menu_parent&amp;lt;/code&amp;gt; || both || Menu the plugin is listed under (e.g. &amp;lt;code&amp;gt;Media&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;IO&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_menu_name&amp;lt;/code&amp;gt; || both || Display name in the menu&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_grid_name&amp;lt;/code&amp;gt; || both || Short name shown in the grid / media list&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_tooltip&amp;lt;/code&amp;gt; || both || Tooltip text&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_menu_level&amp;lt;/code&amp;gt; (media) / &amp;lt;code&amp;gt;plugin_action_level&amp;lt;/code&amp;gt; (playlist) || both || &amp;lt;code&amp;gt;user&amp;lt;/code&amp;gt; (default, visible), &amp;lt;code&amp;gt;development&amp;lt;/code&amp;gt; (visible in debug builds only), &amp;lt;code&amp;gt;disabled&amp;lt;/code&amp;gt; (invisible)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Media-only keys:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_media_scheme&amp;lt;/code&amp;gt; || The URI scheme this plugin handles, e.g. &amp;lt;code&amp;gt;generative&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;web&amp;lt;/code&amp;gt;. Media is addressed as &amp;lt;code&amp;gt;&amp;amp;lt;scheme&amp;amp;gt;://&amp;amp;lt;payload&amp;amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_media_payload&amp;lt;/code&amp;gt; || Optional. If set, the plugin handles exactly &amp;lt;code&amp;gt;scheme://payload&amp;lt;/code&amp;gt;; if omitted, it handles every URI of its scheme. Several plugins can share one scheme and dispatch on the payload.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_media_create_uri&amp;lt;/code&amp;gt; || The URI used when the user creates this media from the menu / Create button.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_playlist_playbackmode_default&amp;lt;/code&amp;gt; || Optional. The clip playback mode a freshly added clip of this media starts in: &amp;lt;code&amp;gt;stop&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;loop&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;oneshot&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;bounce&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jitter&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;random&amp;lt;/code&amp;gt;. Omitted or unknown defaults to &amp;lt;code&amp;gt;loop&amp;lt;/code&amp;gt;. Only seeds the initial mode - a project reload restores the clip&#039;s own saved mode.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_media_has_audio&amp;lt;/code&amp;gt; || Optional. &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; to enable audio output: the host pulls &amp;lt;code&amp;gt;onRenderAudio()&amp;lt;/code&amp;gt; and mixes the PCM into the master.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_media_audio_channels&amp;lt;/code&amp;gt; || Optional (default &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt;). Channel count of the produced audio. There is &#039;&#039;&#039;no&#039;&#039;&#039; sample-rate key &amp;amp;ndash; the rate always follows the output device (see Audio, below).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Playlist-only keys:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_grid_bg_color&amp;lt;/code&amp;gt; || Item background color as &amp;lt;code&amp;gt;r g b a&amp;lt;/code&amp;gt; floats, e.g. &amp;lt;code&amp;gt;0.05 0.05 0.45 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_accepts_trigger&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; (default &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;). When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, dragging a TRIGGER item onto this item&#039;s grid cell connects it (the drag shows a green &amp;quot;connect&amp;quot; outline) instead of moving/swapping cells, and the plugin can read the connection with &amp;lt;code&amp;gt;mxw.pending_trigger_drop(item_id)&amp;lt;/code&amp;gt;. Set it for a timeline; see [[#Connecting to a TRIGGER item]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_cell_scrub&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; (default &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;). When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, ALT + left-drag across this item&#039;s grid cell scrubs instead of moving the item: the host draws a playhead line and stashes the 0..1 fraction of the cell width each frame, readable with &amp;lt;code&amp;gt;mxw.pending_cell_scrub(item_id)&amp;lt;/code&amp;gt;. Set it for a timeline; see [[#Connecting to a TRIGGER item]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The plugin environment ==&lt;br /&gt;
&lt;br /&gt;
=== Per-instance state ===&lt;br /&gt;
&lt;br /&gt;
One Python module serves &#039;&#039;&#039;many simultaneous instances&#039;&#039;&#039; (several clips using the same media plugin, several copies of a playlist item). Before every hook call, the host sets module globals identifying the instance:&lt;br /&gt;
&lt;br /&gt;
* Media plugins: &amp;lt;code&amp;gt;media_id&amp;lt;/code&amp;gt; (integer)&lt;br /&gt;
* Playlist plugins: &amp;lt;code&amp;gt;item_id&amp;lt;/code&amp;gt; (integer) and &amp;lt;code&amp;gt;item_position&amp;lt;/code&amp;gt; (tuple &amp;lt;code&amp;gt;(x, y)&amp;lt;/code&amp;gt;, the grid position)&lt;br /&gt;
&lt;br /&gt;
The standard pattern is a module-level dictionary keyed by the id:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
storage = {}&lt;br /&gt;
&lt;br /&gt;
def onCreate():                    # playlist; media plugins use onOpen(uri)&lt;br /&gt;
    storage[item_id] = my_instance_state()&lt;br /&gt;
&lt;br /&gt;
def onDelete():&lt;br /&gt;
    storage.pop(item_id, None)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Host modules ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt; — the MXWendler command interface (playlist control, layers, clips, ...), see the [[Python command reference|Python command reference]].&lt;br /&gt;
* &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt; — Dear ImGui bindings for drawing settings panels inside MXWendler (used by &amp;lt;code&amp;gt;onRenderPanel()&amp;lt;/code&amp;gt;), documented in the [[Python imgui reference|Python ImGui Reference]].&lt;br /&gt;
&lt;br /&gt;
=== Installing own modules with mxw-pip ===&lt;br /&gt;
&lt;br /&gt;
Plugins may use third-party packages (&amp;lt;code&amp;gt;numpy&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;moderngl&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;opencv-python&amp;lt;/code&amp;gt;, ...). Packages are not installed into the installation folder — the &#039;&#039;&#039;mxw-pip&#039;&#039;&#039; helper (shipped next to the StageDesigner executable) installs them into the current user&#039;s writable folder, &#039;&#039;&#039;no administrator rights required&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%APPDATA%\Python\Python312\site-packages&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is exactly the directory StageDesigner prepends to &amp;lt;code&amp;gt;sys.path&amp;lt;/code&amp;gt; when the option &#039;&#039;&#039;Prepend user site-path&#039;&#039;&#039; is enabled (Settings → Python tab).&lt;br /&gt;
&lt;br /&gt;
mxw-pip runs &amp;lt;code&amp;gt;pip&amp;lt;/code&amp;gt; with the &#039;&#039;&#039;Python 3.12 shipped with StageDesigner&#039;&#039;&#039; (&amp;lt;code&amp;gt;python.exe&amp;lt;/code&amp;gt; in the installation folder / in its &amp;lt;code&amp;gt;python312/&amp;lt;/code&amp;gt; subfolder) — nothing else needs to be installed. Only when the shipped interpreter is missing does it fall back to a system Python (&amp;lt;code&amp;gt;py -3.12&amp;lt;/code&amp;gt;, then &amp;lt;code&amp;gt;python&amp;lt;/code&amp;gt; on &amp;lt;code&amp;gt;PATH&amp;lt;/code&amp;gt;), which must be 3.12 so binary wheels match the runtime ABI.&lt;br /&gt;
&lt;br /&gt;
Step by step:&lt;br /&gt;
&lt;br /&gt;
# Open &#039;&#039;&#039;Settings → Python&#039;&#039;&#039; and enable &#039;&#039;&#039;Prepend user site-path&#039;&#039;&#039;. The two installer buttons below are only active while this option is on, because mxw-pip installs into exactly that folder. Enabling applies immediately; disabling takes full effect after a restart.&lt;br /&gt;
# Click &#039;&#039;&#039;Launch CMD window with mxw-pip module installer..&#039;&#039;&#039; — this opens the installer shell (&amp;lt;code&amp;gt;mxw-pip-shell.bat&amp;lt;/code&amp;gt;). In the shell, type:&lt;br /&gt;
#: &amp;lt;pre&amp;gt;mxw-pip install &amp;lt;modulename&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
#: for example:&lt;br /&gt;
#: &amp;lt;pre&amp;gt;mxw-pip install moderngl&amp;lt;/pre&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Restart MXWendler StageDesigner&#039;&#039;&#039; so the new module is loaded.&lt;br /&gt;
&lt;br /&gt;
Other &amp;lt;code&amp;gt;pip&amp;lt;/code&amp;gt; subcommands are passed through unchanged, e.g. &amp;lt;code&amp;gt;mxw-pip list&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw-pip show moderngl&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw-pip uninstall moderngl&amp;lt;/code&amp;gt;. The button &#039;&#039;&#039;Open per-user module install folder..&#039;&#039;&#039; next to the installer button shows the target directory in the Explorer. Both &amp;lt;code&amp;gt;mxw-pip.bat&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;mxw-pip-shell.bat&amp;lt;/code&amp;gt; can also be run directly from the installation folder in any command prompt.&lt;br /&gt;
&lt;br /&gt;
Because the target folder lives in the user profile, every user keeps their own module set, and reinstalling / updating StageDesigner never touches the installed modules.&lt;br /&gt;
&lt;br /&gt;
=== Error handling ===&lt;br /&gt;
&lt;br /&gt;
Exceptions raised by a hook are reported to the interpreter console (IO dialog) — throttled, so a per-frame error does not flood the log. A &#039;&#039;&#039;per-frame hook that throws is blacklisted&#039;&#039;&#039;: it is not called again until the plugin is reloaded, so one broken callback cannot stall the render loop. Playlist plugins can be hot-reloaded from disk (state is snapshotted via &amp;lt;code&amp;gt;onSave()&amp;lt;/code&amp;gt;, the module source re-executed, then &amp;lt;code&amp;gt;onCreate()&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;onLoad()&amp;lt;/code&amp;gt; restore each instance), which also clears the blacklist.&lt;br /&gt;
&lt;br /&gt;
== Media plugins ==&lt;br /&gt;
&lt;br /&gt;
A media plugin is addressed by a URI: &amp;lt;code&amp;gt;&amp;amp;lt;scheme&amp;amp;gt;://&amp;amp;lt;payload&amp;amp;gt;&amp;lt;/code&amp;gt;, for example &amp;lt;code&amp;gt;generative://cube_spin_opengl&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;web://https://mxwendler.net&amp;lt;/code&amp;gt;. Every created media instance internally carries a unique instance token so two clips never share state; the plugin always sees the clean URI.&lt;br /&gt;
&lt;br /&gt;
=== Hooks ===&lt;br /&gt;
&lt;br /&gt;
All hooks are optional except &amp;lt;code&amp;gt;onOpen&amp;lt;/code&amp;gt; and &#039;&#039;&#039;one of the two render hooks&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Hook !! Direction !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onOpen(uri)&amp;lt;/code&amp;gt; || returns &amp;lt;code&amp;gt;(width, height, length, fps, has_alpha)&amp;lt;/code&amp;gt; || Called when the media is created / loaded. Create the per-instance state here. Do &#039;&#039;&#039;not&#039;&#039;&#039; touch OpenGL yet (see below).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onRenderFrame(frame)&amp;lt;/code&amp;gt; || returns a pixel buffer || Approach 1 and 2: return a &amp;lt;code&amp;gt;H*W*4&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;uint8&amp;lt;/code&amp;gt; buffer (bytes / bytearray / numpy), &#039;&#039;&#039;BGRA&#039;&#039;&#039; byte order, top-down. The host uploads it into the media texture.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onRenderFrameGL(frame, texture, width, height)&amp;lt;/code&amp;gt; || returns &amp;lt;code&amp;gt;bool&amp;lt;/code&amp;gt; || Approach 3: render &#039;&#039;&#039;directly into the media texture&#039;&#039;&#039; — &amp;lt;code&amp;gt;texture&amp;lt;/code&amp;gt; is its raw GL handle. Return &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; when the frame is in the texture; the pixel upload path is then skipped. Tried before &amp;lt;code&amp;gt;onRenderFrame&amp;lt;/code&amp;gt;; a plugin implements one of the two.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onRenderAudio(num_frames)&amp;lt;/code&amp;gt; || returns interleaved float32 || Audio-producing media: return &#039;&#039;num_frames&#039;&#039;&amp;amp;times;channels interleaved &#039;&#039;&#039;float32&#039;&#039;&#039; samples (bytes / bytearray / numpy). The host pulls exactly the frames needed for a gapless cushion. Enabled by &amp;lt;code&amp;gt;plugin_media_has_audio&amp;lt;/code&amp;gt;; generate at the injected &amp;lt;code&amp;gt;audio_samplerate&amp;lt;/code&amp;gt; (see the Audio section).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onClose()&amp;lt;/code&amp;gt; || — || The media is destroyed: release per-instance resources.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onRenderPanel()&amp;lt;/code&amp;gt; || — || Draw ImGui controls (via &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt;) in the clip panel, above the Video Info section.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSizeChange(w, h)&amp;lt;/code&amp;gt; || — || The host changed the render size: recreate size-dependent resources.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSpeedRange()&amp;lt;/code&amp;gt; || returns &amp;lt;code&amp;gt;(min, max)&amp;lt;/code&amp;gt; || Allowed clip playback speed range. Without it the media is locked to speed 1.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSetSpeed(speed)&amp;lt;/code&amp;gt; || — || The clip playback speed changed. Not clamped: 0 and negative values are allowed.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSave()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;onLoad(state)&amp;lt;/code&amp;gt; || string round-trip || Persist per-instance state in the project file.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onDisplayName()&amp;lt;/code&amp;gt; || returns string || Optional live display name (e.g. the web plugin reports the current page URL).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onGetParams()&amp;lt;/code&amp;gt; || returns a list of dicts || Declare addressable parameters, called once per instance and cached: &amp;lt;code&amp;gt;{&amp;quot;name&amp;quot;: str, &amp;quot;type&amp;quot;: &amp;quot;float&amp;quot;|&amp;quot;string&amp;quot;, &amp;quot;min&amp;quot;: float, &amp;quot;max&amp;quot;: float, &amp;quot;default&amp;quot;: float|str}&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;min&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;max&amp;lt;/code&amp;gt; ignored for &amp;lt;code&amp;gt;&amp;quot;string&amp;quot;&amp;lt;/code&amp;gt;; &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; defaults to &amp;lt;code&amp;gt;&amp;quot;float&amp;quot;&amp;lt;/code&amp;gt;).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onParamChanged(index, value)&amp;lt;/code&amp;gt; || — || A parameter was set via OSC, Python or JS at &amp;lt;code&amp;gt;.../clip/media/1/param/&amp;amp;lt;index+1&amp;amp;gt;&amp;lt;/code&amp;gt; (0-based &amp;lt;code&amp;gt;index&amp;lt;/code&amp;gt;). Store or apply it — the host never caches the value itself.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Parameters are addressed exactly like shader effect parameters, e.g. &amp;lt;code&amp;gt;/mxw/track/2/layer/1/clip/media/1/param/1 0.8&amp;lt;/code&amp;gt; or, for a &amp;lt;code&amp;gt;&amp;quot;string&amp;quot;&amp;lt;/code&amp;gt;-typed param, &amp;lt;code&amp;gt;/mxw/track/2/layer/1/clip/media/1/param/2 &amp;quot;https://www.mxwendler.net&amp;quot;&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;media/1&amp;lt;/code&amp;gt; segment reflects the clip&#039;s single active media slot (any other index is out of range). Because the host does not persist a param&#039;s value, a plugin that wants one to survive a project reload must fold it into its own &amp;lt;code&amp;gt;onSave()&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;onLoad()&amp;lt;/code&amp;gt; and hand the restored value back as &amp;lt;code&amp;gt;onGetParams()&amp;lt;/code&amp;gt;&#039;s &amp;lt;code&amp;gt;&amp;quot;default&amp;quot;&amp;lt;/code&amp;gt; — which runs after &amp;lt;code&amp;gt;onLoad()&amp;lt;/code&amp;gt; already restored the instance state.&lt;br /&gt;
&lt;br /&gt;
=== Audio ===&lt;br /&gt;
&lt;br /&gt;
A media plugin can also &#039;&#039;&#039;produce&#039;&#039;&#039; audio: implement &amp;lt;code&amp;gt;onRenderAudio(num_frames)&amp;lt;/code&amp;gt; returning &#039;&#039;num_frames&#039;&#039;&amp;amp;times;channels interleaved &#039;&#039;&#039;float32&#039;&#039;&#039; samples, and set &amp;lt;code&amp;gt;plugin_media_has_audio = 1&amp;lt;/code&amp;gt; in the manifest (channel count via &amp;lt;code&amp;gt;plugin_media_audio_channels&amp;lt;/code&amp;gt;, default 2). The host pulls exactly the frames it needs each render frame into a gapless lookahead cushion, so the sound survives render-loop hitches.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;sample rate always follows the current output device&#039;&#039;&#039; &amp;amp;ndash; there is no sample-rate manifest key. The host injects the live format as the module globals &amp;lt;code&amp;gt;audio_samplerate&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;audio_channels&amp;lt;/code&amp;gt; (like &amp;lt;code&amp;gt;media_id&amp;lt;/code&amp;gt;) before every call; generate at &amp;lt;code&amp;gt;audio_samplerate&amp;lt;/code&amp;gt; and the audio adapts if the device is reopened at another rate. (An optional &amp;lt;code&amp;gt;onAudioFormat()&amp;lt;/code&amp;gt; returning &amp;lt;code&amp;gt;(rate, channels)&amp;lt;/code&amp;gt; may declare the channel count; its rate is ignored.)&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;consume&#039;&#039;&#039; audio (audio-reactive media), read it with the &amp;lt;code&amp;gt;mxw.audio&amp;lt;/code&amp;gt; capture API &amp;amp;ndash; see the [[Python command reference]]: &amp;lt;code&amp;gt;mxw.audio.output_capture()&amp;lt;/code&amp;gt; for the master mix or &amp;lt;code&amp;gt;mxw.audio.input_capture()&amp;lt;/code&amp;gt; for the input device.&lt;br /&gt;
&lt;br /&gt;
=== OpenGL rules for media plugins ===&lt;br /&gt;
&lt;br /&gt;
These rules apply to approaches 2 and 3:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Never create a standalone GL context&#039;&#039;&#039; (no windowed/standalone &amp;lt;code&amp;gt;moderngl.create_context()&amp;lt;/code&amp;gt; at import or in &amp;lt;code&amp;gt;onOpen&amp;lt;/code&amp;gt;). MXWendler makes its own context current every frame; GL objects created in a foreign context will be dereferenced against the wrong context and crash the driver.&lt;br /&gt;
* Instead, &#039;&#039;&#039;lazily attach on the first render call&#039;&#039;&#039;: &amp;lt;code&amp;gt;moderngl.create_context()&amp;lt;/code&amp;gt; inside &amp;lt;code&amp;gt;onRenderFrame / onRenderFrameGL&amp;lt;/code&amp;gt; attaches to MXWendler&#039;s context, which the host guarantees to be current there.&lt;br /&gt;
* The host &#039;&#039;&#039;snapshots and restores all relevant GL state&#039;&#039;&#039; around the render hooks (FBO bindings, program, VAO, buffers, viewport, enables, pixel store). The plugin does not need to unbind anything.&lt;br /&gt;
&lt;br /&gt;
=== Approach 1: rendering into pixels (CPU) ===&lt;br /&gt;
&lt;br /&gt;
The simplest approach: compute the frame on the CPU and return it. No OpenGL knowledge required. The host uploads the buffer into the media texture through a PBO (pixel buffer object) double-buffer, so the upload is asynchronous and cheap — the cost of this approach is the CPU rendering itself.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
W, H = 640, 360&lt;br /&gt;
storage = {}&lt;br /&gt;
&lt;br /&gt;
def onOpen(uri):&lt;br /&gt;
    storage[media_id] = {&amp;quot;phase&amp;quot;: 0.0}&lt;br /&gt;
    return (W, H, 1, 60.0, True)          # width, height, length, fps, has_alpha&lt;br /&gt;
&lt;br /&gt;
def onRenderFrame(frame):&lt;br /&gt;
    inst = storage[media_id]&lt;br /&gt;
    inst[&amp;quot;phase&amp;quot;] += 0.01&lt;br /&gt;
    # a moving horizontal gradient, BGRA byte order, top-down&lt;br /&gt;
    x = (np.linspace(0.0, 1.0, W) + inst[&amp;quot;phase&amp;quot;]) % 1.0&lt;br /&gt;
    row = np.zeros((W, 4), dtype=np.uint8)&lt;br /&gt;
    row[:, 0] = (x * 255).astype(np.uint8)     # B&lt;br /&gt;
    row[:, 2] = ((1 - x) * 255).astype(np.uint8)  # R&lt;br /&gt;
    row[:, 3] = 255                            # A&lt;br /&gt;
    return np.ascontiguousarray(np.tile(row, (H, 1, 1)))&lt;br /&gt;
&lt;br /&gt;
def onClose():&lt;br /&gt;
    storage.pop(media_id, None)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use this for: generated images, PIL/Pillow output, OpenCV results, slow-changing content.&lt;br /&gt;
&lt;br /&gt;
=== Approach 2: rendering into an FBO and streaming ===&lt;br /&gt;
&lt;br /&gt;
Render with OpenGL (e.g. via &#039;&#039;&#039;ModernGL&#039;&#039;&#039;, installed once with &amp;lt;code&amp;gt;mxw-pip install moderngl numpy&amp;lt;/code&amp;gt;) into an offscreen framebuffer, read the pixels back and return them like in approach 1. The scene renders on the GPU, but every frame makes a round trip GPU → CPU (&amp;lt;code&amp;gt;fbo.read()&amp;lt;/code&amp;gt;) → GPU (PBO upload).&lt;br /&gt;
&lt;br /&gt;
Bundled reference: &amp;lt;code&amp;gt;plugins/media/python/plugin_opengl_cube&amp;lt;/code&amp;gt; ([https://github.com/mxwendler/mxw-plugin-opengl-cube github]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import moderngl&lt;br /&gt;
&lt;br /&gt;
storage = {}&lt;br /&gt;
&lt;br /&gt;
class inst_t:&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self.ctx = None&lt;br /&gt;
        self.fbo = None&lt;br /&gt;
&lt;br /&gt;
def onOpen(uri):&lt;br /&gt;
    storage[media_id] = inst_t()&lt;br /&gt;
    return (1024, 1024, 1, 60.0, True)&lt;br /&gt;
&lt;br /&gt;
def onRenderFrame(frame):&lt;br /&gt;
    inst = storage[media_id]&lt;br /&gt;
    if inst.ctx is None:&lt;br /&gt;
        # first frame: attach to MXWendler&#039;s context (never earlier!)&lt;br /&gt;
        inst.ctx = moderngl.create_context()&lt;br /&gt;
        color = inst.ctx.texture((1024, 1024), 4)&lt;br /&gt;
        depth = inst.ctx.depth_renderbuffer((1024, 1024))&lt;br /&gt;
        inst.fbo = inst.ctx.framebuffer([color], depth)&lt;br /&gt;
        # ... build program / vao here ...&lt;br /&gt;
&lt;br /&gt;
    inst.fbo.use()&lt;br /&gt;
    inst.ctx.clear(0.0, 0.0, 0.0, 0.0, depth=1.0)&lt;br /&gt;
    # ... draw the scene ...&lt;br /&gt;
&lt;br /&gt;
    # read back: GL is bottom-up RGBA, the host wants top-down BGRA&lt;br /&gt;
    raw = inst.fbo.read(components=4, alignment=1)&lt;br /&gt;
    img = np.frombuffer(raw, dtype=np.uint8).reshape((1024, 1024, 4))&lt;br /&gt;
    img = np.flipud(img)&lt;br /&gt;
    return np.ascontiguousarray(img[:, :, [2, 1, 0, 3]])&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use this for: GPU-rendered content when you also need the pixels on the CPU (analysis, recording), or as a stepping stone to approach 3.&lt;br /&gt;
&lt;br /&gt;
=== Approach 3: rendering into a bound texture target (direct) ===&lt;br /&gt;
&lt;br /&gt;
The fastest path: the host passes the &#039;&#039;&#039;raw GL handle of the media texture&#039;&#039;&#039; to &amp;lt;code&amp;gt;onRenderFrameGL&amp;lt;/code&amp;gt;. The plugin attaches it to its own framebuffer and renders straight into it. &#039;&#039;&#039;No readback, no upload, no texture streaming&#039;&#039;&#039; — the frame never leaves the GPU.&lt;br /&gt;
&lt;br /&gt;
Bundled reference: &amp;lt;code&amp;gt;plugins/media/python/plugin_opengl_cube_direct&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import moderngl&lt;br /&gt;
&lt;br /&gt;
storage = {}&lt;br /&gt;
&lt;br /&gt;
class inst_t:&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self.ctx = None&lt;br /&gt;
        self.fbo = None&lt;br /&gt;
        self.depth = None&lt;br /&gt;
        self.fbo_key = None       # (texture, w, h) the fbo was built for&lt;br /&gt;
&lt;br /&gt;
def onOpen(uri):&lt;br /&gt;
    storage[media_id] = inst_t()&lt;br /&gt;
    return (1024, 1024, 1, 60.0, True)&lt;br /&gt;
&lt;br /&gt;
def onRenderFrameGL(frame, texture, width, height):&lt;br /&gt;
    inst = storage[media_id]&lt;br /&gt;
    if inst.ctx is None:&lt;br /&gt;
        inst.ctx = moderngl.create_context()   # attach to MXWendler&#039;s context&lt;br /&gt;
        # ... build program / vao here ...&lt;br /&gt;
&lt;br /&gt;
    # (re)wrap the host texture when the handle or size changed: the host&lt;br /&gt;
    # recreates the media texture on a render size change&lt;br /&gt;
    if inst.fbo_key != (texture, width, height):&lt;br /&gt;
        if inst.fbo:&lt;br /&gt;
            inst.fbo.release()&lt;br /&gt;
        if inst.depth:&lt;br /&gt;
            inst.depth.release()&lt;br /&gt;
        color = inst.ctx.external_texture(texture, (width, height), 4, 0, &amp;quot;f1&amp;quot;)&lt;br /&gt;
        inst.depth = inst.ctx.depth_renderbuffer((width, height))&lt;br /&gt;
        inst.fbo = inst.ctx.framebuffer([color], inst.depth)&lt;br /&gt;
        inst.fbo_key = (texture, width, height)&lt;br /&gt;
&lt;br /&gt;
    inst.fbo.use()&lt;br /&gt;
    inst.ctx.clear(0.0, 0.0, 0.0, 0.0, depth=1.0)&lt;br /&gt;
    # ... draw the scene; flip Y in the projection, see below ...&lt;br /&gt;
&lt;br /&gt;
    return True    # the frame is in the texture: host skips the upload path&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rules specific to the direct approach:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Never &amp;lt;code&amp;gt;release()&amp;lt;/code&amp;gt; the external texture wrapper&#039;&#039;&#039; — the GL texture belongs to MXWendler. Only release your own framebuffer and depth renderbuffer.&lt;br /&gt;
* &#039;&#039;&#039;Rebuild the framebuffer when &amp;lt;code&amp;gt;(texture, width, height)&amp;lt;/code&amp;gt; changes.&#039;&#039;&#039; The handle is not stable: a render size change makes the host recreate the media texture.&lt;br /&gt;
* &#039;&#039;&#039;Flip Y.&#039;&#039;&#039; MXWendler media textures are top-down (row 0 = top of the image), a GL render is bottom-up. Negate the Y row of your projection matrix (approaches 1/2 flip on the CPU instead, e.g. with &amp;lt;code&amp;gt;numpy.flipud&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Choosing an approach ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! !! 1: Pixels (CPU) !! 2: FBO + streaming !! 3: Direct texture&lt;br /&gt;
|-&lt;br /&gt;
| Scene renders on || CPU || GPU || GPU&lt;br /&gt;
|-&lt;br /&gt;
| Per-frame copies || CPU → GPU upload || GPU → CPU readback + CPU → GPU upload || none&lt;br /&gt;
|-&lt;br /&gt;
| OpenGL required || no || yes || yes&lt;br /&gt;
|-&lt;br /&gt;
| CPU access to the pixels || yes (you made them) || yes (after readback) || no&lt;br /&gt;
|-&lt;br /&gt;
| Typical use || generated images, PIL, OpenCV || GPU render that also needs CPU pixels || pure GPU generative content, best performance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Playlist plugins ==&lt;br /&gt;
&lt;br /&gt;
A playlist plugin is an item placed in the playlist grid. It participates in the cue lifecycle: it can run logic when its cue is played, every frame while its cue is active, or every frame globally. Playlist control functions (&amp;lt;code&amp;gt;mxw.playlist.play()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.playlist.navigate_index()&amp;lt;/code&amp;gt;, ...) are documented in the [[Python command reference|Python command reference]].&lt;br /&gt;
&lt;br /&gt;
=== Hooks ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Hook !! Required !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onCreate()&amp;lt;/code&amp;gt; || yes || A new instance was placed in the grid (also called after hot-reload): create the per-instance state entry.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onDelete()&amp;lt;/code&amp;gt; || yes || The instance was deleted: release the state entry.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onAction()&amp;lt;/code&amp;gt; || yes || The item&#039;s cue was played (the item &#039;&#039;fires&#039;&#039;).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onPostAction()&amp;lt;/code&amp;gt; || no || Called after the action completed.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSave()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;onLoad(state)&amp;lt;/code&amp;gt; || yes || Serialize / restore per-instance state (string). Called on project save/load and around hot-reload.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onRenderPanel()&amp;lt;/code&amp;gt; || yes || Draw the item&#039;s settings panel with &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getText()&amp;lt;/code&amp;gt; || yes || Detail text appended to the item&#039;s grid label.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onNewFrameAlways()&amp;lt;/code&amp;gt; || no || Called every rendered frame, regardless of cue state.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onNewFrameInPlayoutCue()&amp;lt;/code&amp;gt; || no || Called every rendered frame while the item&#039;s cue is the active playout cue.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onPause(is_paused)&amp;lt;/code&amp;gt; || no || Pause was pressed / released.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onPreparePlayback()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;onCleanup()&amp;lt;/code&amp;gt; || no || Prepare / release playout resources.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onActivateInUI()&amp;lt;/code&amp;gt; || no || The item was selected in the user interface.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onActiveCueChange(direction)&amp;lt;/code&amp;gt; || no || The active cue changed past this item (navigation).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSettingsChanged()&amp;lt;/code&amp;gt; || no || Item settings were changed from outside.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getDuration()&amp;lt;/code&amp;gt; || no || Report the item&#039;s action duration in milliseconds.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getTimeSinceOnActionIssued()&amp;lt;/code&amp;gt; || no || Report elapsed action time in milliseconds (drives the progress display).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getColorBG()&amp;lt;/code&amp;gt; || no || Return a &amp;lt;code&amp;gt;mxw_imgui.Vec4&amp;lt;/code&amp;gt; (rgb 0..255) to set the grid cell background color dynamically.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;renderBlinking()&amp;lt;/code&amp;gt; || no || Return &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; to make the grid cell blink.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getProgress()&amp;lt;/code&amp;gt; || no || Return &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt; to fill the cell&#039;s bottom progress bar (the same bar the built-in advance/fade items draw); &amp;lt;code&amp;gt;&amp;amp;lt;= 0&amp;lt;/code&amp;gt; draws nothing.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Connecting to a TRIGGER item ===&lt;br /&gt;
&lt;br /&gt;
A playlist plugin (e.g. a keyframe timeline) can bind to a TRIGGER item and animate its layer/clip controls. The user drops a trigger either onto the plugin&#039;s settings panel or onto its grid cell; the plugin resolves the connection to the trigger&#039;s grid &amp;lt;code&amp;gt;(col, row)&amp;lt;/code&amp;gt; and enumerates its controls from there. No need to play the trigger first — the controls are read from the connected preload&#039;s fixture layer, and the very same &amp;lt;code&amp;gt;(col,row)&amp;lt;/code&amp;gt; address resolves the &#039;&#039;live&#039;&#039; layer during playout.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Function !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw_imgui.accept_trigger_drop()&amp;lt;/code&amp;gt; || Makes the current panel window a drop target for a trigger; returns the dropped trigger&#039;s 1-based &amp;lt;code&amp;gt;(col, row)&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;(-1, -1)&amp;lt;/code&amp;gt;. Handles the &amp;quot;drop onto the panel&amp;quot; route.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw.pending_trigger_drop(item_id)&amp;lt;/code&amp;gt; || Returns a &amp;lt;code&amp;gt;(col, row)&amp;lt;/code&amp;gt; stashed by the host when a trigger was dropped onto &#039;&#039;this&#039;&#039; plugin item&#039;s grid cell (pass your own &amp;lt;code&amp;gt;item_id&amp;lt;/code&amp;gt;), or &amp;lt;code&amp;gt;(-1, -1)&amp;lt;/code&amp;gt;. Handles the &amp;quot;drop onto the grid cell&amp;quot; route.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw.trigger_controls(col, row)&amp;lt;/code&amp;gt; || Returns the trigger&#039;s animatable (slider) controls as &amp;lt;code&amp;gt;(label, address)&amp;lt;/code&amp;gt; pairs — layer, clip, effect and media params. Re-read it every frame: controls the user swaps on the clip appear/vanish live. Each &amp;lt;code&amp;gt;address&amp;lt;/code&amp;gt; is usable with &amp;lt;code&amp;gt;mxw.widget(address).setValue()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw.pending_cell_scrub(item_id)&amp;lt;/code&amp;gt; || Returns the 0..1 fraction of an ALT + left-drag across &#039;&#039;this&#039;&#039; plugin item&#039;s grid cell (stashed by the host each frame while dragging, consumed on read), or &amp;lt;code&amp;gt;-1.0&amp;lt;/code&amp;gt;. Needs the &amp;lt;code&amp;gt;plugin_cell_scrub&amp;lt;/code&amp;gt; manifest opt-in. Poll it in &amp;lt;code&amp;gt;onNewFrameAlways()&amp;lt;/code&amp;gt; so scrubbing also works while the panel is closed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Poll both drop routes at the top of &amp;lt;code&amp;gt;onRenderPanel()&amp;lt;/code&amp;gt; and store the resulting &amp;lt;code&amp;gt;(col,row)&amp;lt;/code&amp;gt;; then call &amp;lt;code&amp;gt;mxw.trigger_controls()&amp;lt;/code&amp;gt; to (re)build your control list each frame.&lt;br /&gt;
&lt;br /&gt;
A time connection between the connected clip and the plugin follows from these pieces: the clip&#039;s &amp;lt;code&amp;gt;.../clip/Position&amp;lt;/code&amp;gt; control (normalized 0..1) is the clip&#039;s own time axis. Write it when your playhead moves (scrub → seek) and read it every frame to follow the clip when it is scrubbed — or simply playing. See the timeline plugin&#039;s &amp;lt;code&amp;gt;sync_time_link()&amp;lt;/code&amp;gt; for a worked example including the echo filtering (a written Position reads back frame-quantized).&lt;br /&gt;
&lt;br /&gt;
=== Minimal example ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import pickle, codecs&lt;br /&gt;
import mxw&lt;br /&gt;
import mxw_imgui&lt;br /&gt;
&lt;br /&gt;
class state_t:&lt;br /&gt;
    fire_count = 0&lt;br /&gt;
&lt;br /&gt;
storage = {}&lt;br /&gt;
&lt;br /&gt;
def onCreate():&lt;br /&gt;
    storage[item_id] = state_t()&lt;br /&gt;
&lt;br /&gt;
def onDelete():&lt;br /&gt;
    storage.pop(item_id, None)&lt;br /&gt;
&lt;br /&gt;
def onAction():&lt;br /&gt;
    # the item&#039;s cue was played&lt;br /&gt;
    storage[item_id].fire_count += 1&lt;br /&gt;
&lt;br /&gt;
def getText():&lt;br /&gt;
    return &amp;quot; : fired %d times&amp;quot; % storage[item_id].fire_count&lt;br /&gt;
&lt;br /&gt;
def onRenderPanel():&lt;br /&gt;
    inst = storage[item_id]&lt;br /&gt;
    mxw_imgui.text_unformatted(&amp;quot;Fired %d times&amp;quot; % inst.fire_count)&lt;br /&gt;
    if mxw_imgui.button(&amp;quot;Reset&amp;quot;):&lt;br /&gt;
        inst.fire_count = 0&lt;br /&gt;
&lt;br /&gt;
def onSave():&lt;br /&gt;
    return codecs.encode(pickle.dumps(storage[item_id]), &amp;quot;base64&amp;quot;).decode()&lt;br /&gt;
&lt;br /&gt;
def onLoad(serialized):&lt;br /&gt;
    storage[item_id] = pickle.loads(codecs.decode(serialized.encode(), &amp;quot;base64&amp;quot;))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With a manifest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[mxw_plugin]&lt;br /&gt;
plugin_version = 1&lt;br /&gt;
plugin_script_language = Python&lt;br /&gt;
plugin_menu_parent = IO&lt;br /&gt;
plugin_menu_name = Fire Counter&lt;br /&gt;
plugin_grid_name = Counter&lt;br /&gt;
plugin_tooltip = Counts how often its cue was played&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bundled references, all in the [https://github.com/mxwendler/mxw-plugins-playlist mxw-plugins-playlist] repository: &amp;lt;code&amp;gt;plugins/playlist/python/plugin_advance_datetime&amp;lt;/code&amp;gt; (timed playlist navigation, rich settings panel), &amp;lt;code&amp;gt;plugin_video_writer&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;plugin_comment&amp;lt;/code&amp;gt; (a minimal example: a no-op annotation item).&lt;br /&gt;
&lt;br /&gt;
== Example plugins on GitHub ==&lt;br /&gt;
&lt;br /&gt;
The bundled example plugins are maintained as public repositories under [https://github.com/mxwendler github.com/mxwendler], grouped by type — good starting points to fork for an own plugin:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Plugin !! Type !! Approach / purpose !! Repository&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_opengl_cube&amp;lt;/code&amp;gt; || media || Approach 2: ModernGL cube into an offscreen FBO, streamed || [https://github.com/mxwendler/mxw-plugins-media mxw-plugins-media]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_opengl_cube_direct&amp;lt;/code&amp;gt; || media || Approach 3: same cube rendered directly into the media texture || [https://github.com/mxwendler/mxw-plugins-media mxw-plugins-media]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_web_media&amp;lt;/code&amp;gt; || media || A web browser as media source (whole-scheme &amp;lt;code&amp;gt;web://&amp;lt;/code&amp;gt; plugin) || [https://github.com/mxwendler/mxw-plugins-media mxw-plugins-media]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_fragcoord&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;plugin_shadertoy&amp;lt;/code&amp;gt; || media || Shader-as-generative-media (FragCoord.xyz / Shadertoy) || [https://github.com/mxwendler/mxw-plugins-media mxw-plugins-media]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_advance_datetime&amp;lt;/code&amp;gt; || playlist || Timed playlist navigation with a rich settings panel || [https://github.com/mxwendler/mxw-plugins-playlist mxw-plugins-playlist]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_video_writer&amp;lt;/code&amp;gt; || playlist || Write video files from the playlist || [https://github.com/mxwendler/mxw-plugins-playlist mxw-plugins-playlist]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_comment&amp;lt;/code&amp;gt; || playlist || Minimal example: a no-op text annotation item || [https://github.com/mxwendler/mxw-plugins-playlist mxw-plugins-playlist]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Developing a new plugin inside a project ===&lt;br /&gt;
&lt;br /&gt;
The most convenient place to develop a plugin is &#039;&#039;&#039;inside a project folder&#039;&#039;&#039;: the plugin travels with the show, needs no write access to the installation, and overrides a same-named bundled plugin. Conceptually:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Create a project folder&#039;&#039;&#039; — a plain directory that will hold everything belonging to the show, e.g. &amp;lt;code&amp;gt;D:/shows/particles/&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Save the project file there&#039;&#039;&#039; — &#039;&#039;File → Save As..&#039;&#039; into that folder, e.g. &amp;lt;code&amp;gt;D:/shows/particles/particles.mxw&amp;lt;/code&amp;gt;. The folder containing the &amp;lt;code&amp;gt;.mxw&amp;lt;/code&amp;gt; file &#039;&#039;is&#039;&#039; the project folder; loading the project later makes MXWendler pick up its plugins again.&lt;br /&gt;
# &#039;&#039;&#039;Create the plugin directory there&#039;&#039;&#039; — the project mirrors the installation layout: &amp;lt;code&amp;gt;D:/shows/particles/plugins/media/python/&amp;amp;lt;plugin_folder&amp;amp;gt;/&amp;lt;/code&amp;gt; for media plugins (&amp;lt;code&amp;gt;plugins/playlist/python/...&amp;lt;/code&amp;gt; for playlist plugins). Enable &#039;&#039;Settings → Python → Check for plugins inside the project folder&#039;&#039; — project plugins have the highest precedence of all plugin locations.&lt;br /&gt;
&lt;br /&gt;
=== Letting Claude Code write the plugin ===&lt;br /&gt;
&lt;br /&gt;
An AI coding agent like [https://claude.com/claude-code Claude Code] can write a complete plugin from the contract described on this page. Start it &#039;&#039;&#039;in the project folder&#039;&#039;&#039;, so it creates the plugin directly where MXWendler looks for it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd D:/shows/particles&lt;br /&gt;
claude&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Give it the reference material and a precise task — for a generative OpenGL particle system for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Create an MXWendler media plugin under plugins/media/python/plugin_particle_system/&lt;br /&gt;
(folder + mxw_plugin.ini + mxw_main.py).&lt;br /&gt;
&lt;br /&gt;
Reference: the bundled example in &amp;lt;MXWendler install dir&amp;gt;/plugins/media/python/&lt;br /&gt;
plugin_opengl_cube_direct/ - follow its structure and hook usage exactly, and the&lt;br /&gt;
plugin howto at https://wiki.mxwendler.net/index.php?title=Python_plugin_reference.&lt;br /&gt;
&lt;br /&gt;
The plugin is a generative OpenGL particle system, addressed as&lt;br /&gt;
generative://particle_system, rendered with ModernGL directly into the media&lt;br /&gt;
texture via onRenderFrameGL (no readback, no onRenderFrame). Keep per-instance&lt;br /&gt;
state keyed by media_id. Emit particles from the center, integrate velocity and&lt;br /&gt;
gravity per frame scaled by the clip playback speed (onSetSpeed, onSpeedRange&lt;br /&gt;
-5..5). Expose particle count, gravity and start size as sliders in&lt;br /&gt;
onRenderPanel (mxw_imgui) and persist them via onSave/onLoad. Respect the GL&lt;br /&gt;
rules: attach with moderngl.create_context() lazily on the first render call,&lt;br /&gt;
never release the external texture, rebuild the fbo when (texture, w, h)&lt;br /&gt;
changes, flip Y in the projection.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then iterate: create the media in a clip (it appears under its &amp;lt;code&amp;gt;plugin_menu_name&amp;lt;/code&amp;gt;, or address &amp;lt;code&amp;gt;generative://particle_system&amp;lt;/code&amp;gt; directly) and refine with follow-up prompts (&amp;quot;make the particles fade out&amp;quot;, &amp;quot;add a color gradient slider&amp;quot;, ...). Errors show up in the interpreter console. For playlist plugins, &#039;&#039;Settings → Python → Reload Python Plugins&#039;&#039; hot-reloads the edited source; for media plugins, recreate the media (or restart) to re-import the module.&lt;br /&gt;
&lt;br /&gt;
== Persistence ==&lt;br /&gt;
&lt;br /&gt;
Both plugin types persist per-instance state through the &amp;lt;code&amp;gt;onSave() → string&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;onLoad(string)&amp;lt;/code&amp;gt; pair. The string is stored inside the project file; anything goes, a common choice is base64-encoded pickle (see the playlist example above). Media plugins additionally have their render size stored and restored by the host automatically.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Nothing appears in the menu&#039;&#039;&#039; — check the manifest: &amp;lt;code&amp;gt;plugin_version = 1&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;plugin_script_language = Python&amp;lt;/code&amp;gt;, a non-empty &amp;lt;code&amp;gt;plugin_menu_name&amp;lt;/code&amp;gt;, and the level key (&amp;lt;code&amp;gt;development&amp;lt;/code&amp;gt; plugins only show in debug builds).&lt;br /&gt;
* &#039;&#039;&#039;Errors&#039;&#039;&#039; — open the interpreter console (IO dialog): hook exceptions are reported there (throttled). Remember that a throwing per-frame hook is blacklisted until reload.&lt;br /&gt;
* &#039;&#039;&#039;Media shows black&#039;&#039;&#039; — &amp;lt;code&amp;gt;onRenderFrame&amp;lt;/code&amp;gt; returned a buffer of the wrong size (must be &amp;lt;code&amp;gt;width*height*4&amp;lt;/code&amp;gt; bytes), or a GL plugin created its own context instead of attaching to MXWendler&#039;s (see the OpenGL rules).&lt;br /&gt;
* &#039;&#039;&#039;Missing packages&#039;&#039;&#039; — install them with mxw-pip (see [[#Installing own modules with mxw-pip|Installing own modules with mxw-pip]]) and make sure &#039;&#039;&#039;Prepend user site-path&#039;&#039;&#039; is enabled: the embedded interpreter does not see a system-wide Python installation&#039;s packages.&lt;br /&gt;
[[Category:Python]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Python_command_reference&amp;diff=6210</id>
		<title>Python command reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Python_command_reference&amp;diff=6210"/>
		<updated>2026-08-09T16:00:34Z</updated>

		<summary type="html">&lt;p&gt;Admin: docs: audio streams — mxw.audio capture + audio-producing media plugins (device-rate adaptive)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- MXWendler wiki page: Python command reference (module mxw) --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Intended location: https://wiki.mxwendler.net/index.php?title=Python_command_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_imgui_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_plugin_reference --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This page lists the commands of the Python module &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt;, MXWendler&#039;s general Python command interface. It is available from the script console and from Python plugins (see the [[Python plugin reference|Python Plugin Howto]]). For drawing plugin panels see the [[Python imgui reference|Python ImGui Reference]].&lt;br /&gt;
&lt;br /&gt;
The embedded interpreter is &#039;&#039;&#039;Python 3.12&#039;&#039;&#039;. Import is implicit in the script console; in a plugin module use &amp;lt;code&amp;gt;import mxw&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The presented Python commands supported in version 7.2. and up&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Legend ===&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;FLOATS&#039;&#039; are written with one decimal: &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt; &amp;amp;rarr; every float between 0 and 1 inclusive.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;INTEGERS&#039;&#039; are written as plain numbers or ranges: &amp;lt;code&amp;gt;1 .. 5&amp;lt;/code&amp;gt; &amp;amp;rarr; the integers 1,2,3,4,5.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;STRINGS&#039;&#039; are written between double quotes.&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; appears, two alternative call formats produce a similar result; use one at a time.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Addressing:&#039;&#039;&#039; widgets are targeted by their OSC-style address string, e.g. &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip&amp;lt;/code&amp;gt;. The same addresses used over OSC work here.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Access model (7.2):&#039;&#039;&#039; widget values are read/written through &amp;lt;code&amp;gt;mxw.widget(address)&amp;lt;/code&amp;gt;; global functions live in the submodules/factories &amp;lt;code&amp;gt;mxw.playlist&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.io&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.preload(n)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.media(name)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.grabber(name)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Reference ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Software Info&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.millis&amp;lt;/code&amp;gt; || milliseconds passed since the software was opened || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;passed time is &amp;quot; + str(mxw.millis))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.width&amp;lt;/code&amp;gt; || current frame width in px || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;frame width is &amp;quot; + str(mxw.width))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.height&amp;lt;/code&amp;gt; || current frame height in px || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;frame height is &amp;quot; + str(mxw.height))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.outwidth&amp;lt;/code&amp;gt; || current output width in px || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;output width is &amp;quot; + str(mxw.outwidth))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.outheight&amp;lt;/code&amp;gt; || current output height in px || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;output height is &amp;quot; + str(mxw.outheight))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.framecounter&amp;lt;/code&amp;gt; || number of frames rendered since the software was opened || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;frames rendered: &amp;quot; + str(mxw.framecounter))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.print_console(&amp;quot;text&amp;quot;)&amp;lt;/code&amp;gt; || print a line to the script console || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;hello&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.print_statusline(&amp;quot;text&amp;quot;)&amp;lt;/code&amp;gt; || print text on the application status line || &amp;lt;code&amp;gt;mxw.print_statusline(&amp;quot;running&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.makescreenshot(&amp;quot;path&amp;quot;)&amp;lt;/code&amp;gt; || save a full-frame screenshot as PNG (empty path &amp;amp;rarr; Desktop) || &amp;lt;code&amp;gt;mxw.makescreenshot(&amp;quot;c:/Users/me/Desktop/shot.png&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.makesectionscreenshot(&amp;quot;path&amp;quot;, x, y, w, h)&amp;lt;/code&amp;gt; || save a cropped screenshot of the region (x, y, w, h) || &amp;lt;code&amp;gt;mxw.makesectionscreenshot(&amp;quot;c:/Users/me/Desktop/crop.png&amp;quot;, 0, 0, 400, 200)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.describe()&amp;lt;/code&amp;gt; || return a text listing of every operation known to the unified interface registry (auto-docs / discovery) || &amp;lt;code&amp;gt;mxw.print_console(mxw.describe())&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; | I/O ( &amp;lt;code&amp;gt;mxw.io&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.dmx(channel)&amp;lt;/code&amp;gt; || return the DMX value received on the given channel || &amp;lt;code&amp;gt;v = mxw.io.dmx(4)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.midi(device, channel)&amp;lt;/code&amp;gt; || return the MIDI value received from device/channel || &amp;lt;code&amp;gt;v = mxw.io.midi(1, 6)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.keyboard(state, key)&amp;lt;/code&amp;gt; || return whether the given key (ASCII) is in the given state || &amp;lt;code&amp;gt;if mxw.io.keyboard(0, 65): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.send_dmx(channel, value)&amp;lt;/code&amp;gt; || send a DMX value on a channel || &amp;lt;code&amp;gt;mxw.io.send_dmx(4, 255)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.send_midi(device, channel, value)&amp;lt;/code&amp;gt; || send a MIDI value to device/channel || &amp;lt;code&amp;gt;mxw.io.send_midi(1, 6, 100)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.pjlink(&amp;quot;command&amp;quot;, &amp;quot;ip&amp;quot;, &amp;quot;pw&amp;quot;)&amp;lt;/code&amp;gt; || PJLink projector control. Commands: &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;avmute_on&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;avmute_off&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vmute_on&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vmute_off&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;mxw.io.pjlink(&amp;quot;on&amp;quot;, &amp;quot;192.168.1.2&amp;quot;, &amp;quot;panasonic&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.send_osc(&amp;quot;host&amp;quot;, port, &amp;quot;address&amp;quot;, &amp;quot;tags&amp;quot;, *args)&amp;lt;/code&amp;gt; || send an OSC message. &amp;lt;code&amp;gt;tags&amp;lt;/code&amp;gt; is one char per argument: &amp;lt;code&amp;gt;d&amp;lt;/code&amp;gt; float, &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; int, &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt; string, &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt; blob (list of 0..255) || &amp;lt;code&amp;gt;mxw.io.send_osc(&amp;quot;127.0.0.1&amp;quot;, 7000, &amp;quot;/cue&amp;quot;, &amp;quot;ci&amp;quot;, &amp;quot;go&amp;quot;, 5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Playlist ( &amp;lt;code&amp;gt;mxw.playlist&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.preload_media()&amp;lt;/code&amp;gt; || preload the media used by the playlist || &amp;lt;code&amp;gt;mxw.playlist.preload_media()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.play()&amp;lt;/code&amp;gt; || play the playlist || &amp;lt;code&amp;gt;mxw.playlist.play()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.pause()&amp;lt;/code&amp;gt; || pause, or restart if already paused || &amp;lt;code&amp;gt;mxw.playlist.pause()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_pause(True/False)&amp;lt;/code&amp;gt; || halt (True) or resume (False) playback || &amp;lt;code&amp;gt;mxw.playlist.go_pause(True)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.skiptonext()&amp;lt;/code&amp;gt; || skip to the next cue || &amp;lt;code&amp;gt;mxw.playlist.skiptonext()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_next()&amp;lt;/code&amp;gt; || go to the next cue without playing || &amp;lt;code&amp;gt;mxw.playlist.go_next()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_prev()&amp;lt;/code&amp;gt; || go to the previous cue || &amp;lt;code&amp;gt;mxw.playlist.go_prev()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_first()&amp;lt;/code&amp;gt; || go to the first cue || &amp;lt;code&amp;gt;mxw.playlist.go_first()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.navigate_index(index)&amp;lt;/code&amp;gt; || go to the cue with the given index || &amp;lt;code&amp;gt;mxw.playlist.navigate_index(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.navigate_string(&amp;quot;name&amp;quot;)&amp;lt;/code&amp;gt; || go to the cue matching the given name || &amp;lt;code&amp;gt;mxw.playlist.navigate_string(&amp;quot;BG_video2&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.get_active_cue()&amp;lt;/code&amp;gt; || return the active cue index (int) || &amp;lt;code&amp;gt;i = mxw.playlist.get_active_cue()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.get_cue_count()&amp;lt;/code&amp;gt; || return the number of cues (int) || &amp;lt;code&amp;gt;n = mxw.playlist.get_cue_count()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.get_cue_names()&amp;lt;/code&amp;gt; || return the list of cue names (index matches &amp;lt;code&amp;gt;navigate_index&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;for name in mxw.playlist.get_cue_names(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.is_rehearsal()&amp;lt;/code&amp;gt; || return True if the playlist is in rehearsal mode || &amp;lt;code&amp;gt;if mxw.playlist.is_rehearsal(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Preload ( &amp;lt;code&amp;gt;mxw.preload(n)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).isvalid()&amp;lt;/code&amp;gt; || True if preload &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; exists || &amp;lt;code&amp;gt;if mxw.preload(2).isvalid(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).clear()&amp;lt;/code&amp;gt; || clear the selected preload || &amp;lt;code&amp;gt;mxw.preload(2).clear()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_media(&amp;quot;filename&amp;quot;)&amp;lt;/code&amp;gt; || set the preload media by filename || &amp;lt;code&amp;gt;mxw.preload(2).set_media(&amp;quot;try.mp4&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_name(&amp;quot;name&amp;quot;)&amp;lt;/code&amp;gt; || rename the preload || &amp;lt;code&amp;gt;mxw.preload(2).set_name(&amp;quot;new_background&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).add_preload()&amp;lt;/code&amp;gt; || load the preload into the layers || &amp;lt;code&amp;gt;mxw.preload(2).add_preload()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).trigger_preload()&amp;lt;/code&amp;gt; || trigger a layer from the preload || &amp;lt;code&amp;gt;mxw.preload(2).trigger_preload()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_activated()&amp;lt;/code&amp;gt; || True if the preload is open for edit || &amp;lt;code&amp;gt;mxw.preload(2).get_activated()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_activated(True/False)&amp;lt;/code&amp;gt; || open/close the preload for edit || &amp;lt;code&amp;gt;mxw.preload(2).set_activated(False)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_layer_position()&amp;lt;/code&amp;gt; || return the preload&#039;s layer index || &amp;lt;code&amp;gt;mxw.preload(2).get_layer_position()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_track_position()&amp;lt;/code&amp;gt; || return the preload&#039;s track index || &amp;lt;code&amp;gt;mxw.preload(2).get_track_position()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_layer_position(pos)&amp;lt;/code&amp;gt; || set the preload&#039;s layer index || &amp;lt;code&amp;gt;mxw.preload(2).set_layer_position(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_track_position(pos)&amp;lt;/code&amp;gt; || set the preload&#039;s track index || &amp;lt;code&amp;gt;mxw.preload(2).set_track_position(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_preload_names()&amp;lt;/code&amp;gt; || return the list of preload comment/name strings || &amp;lt;code&amp;gt;names = mxw.preload(2).get_preload_names()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_image_sample_cvmat(w, h)&amp;lt;/code&amp;gt; || return a &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt;&amp;amp;times;&amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; RGBA image sample of the preload as a buffer (OpenCV Mat) || &amp;lt;code&amp;gt;img = mxw.preload(2).get_image_sample_cvmat(64, 64)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Widgets ( &amp;lt;code&amp;gt;mxw.widget(address)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).getValue()&amp;lt;/code&amp;gt; || return the widget&#039;s normalized value (float) || &amp;lt;code&amp;gt;o = mxw.widget(&amp;quot;/mxw/track/active/layer/active/opacity&amp;quot;).getValue()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).setValue(v)&amp;lt;/code&amp;gt; || set the widget&#039;s normalized value || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/track/active/layer/active/opacity&amp;quot;).setValue(0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).getStringValue()&amp;lt;/code&amp;gt; || return the widget&#039;s string value (e.g. a cue/clip name) || &amp;lt;code&amp;gt;mxw.print_console(mxw.widget(&amp;quot;/mxw/playlist/container/1/column/0/row/1&amp;quot;).getStringValue())&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).setStringValue(&amp;quot;text&amp;quot;)&amp;lt;/code&amp;gt; || set the widget&#039;s string value (e.g. name a cue) || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/playlist/container/1/column/0/row/1&amp;quot;).setStringValue(&amp;quot;background videoclip&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).setWidgetRealValue(d)&amp;lt;/code&amp;gt; || set the widget&#039;s real (un-normalized) value || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).setWidgetRealValue(120.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).animate(initvalue, incomingvalue, duration, delta, type)&amp;lt;/code&amp;gt; || animate the widget value over &amp;lt;code&amp;gt;duration&amp;lt;/code&amp;gt; ms || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).animate(0.0, 1.0, 1000, 0.0, 0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).info()&amp;lt;/code&amp;gt; || return a list describing the widget. For a &#039;&#039;&#039;clip&#039;&#039;&#039;: &amp;lt;code&amp;gt;[length, width, height, millis_per_frame, cache_state, media_path]&amp;lt;/code&amp;gt;. Returns &amp;lt;code&amp;gt;[]&amp;lt;/code&amp;gt; if the address does not resolve || &amp;lt;code&amp;gt;length, w, h, mspf, cache, path = mxw.widget(&amp;quot;/mxw/track/active/layer/active/clip&amp;quot;).info()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Media ( &amp;lt;code&amp;gt;mxw.media(name)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).isvalid()&amp;lt;/code&amp;gt; || True if the named media exists || &amp;lt;code&amp;gt;if mxw.media(&amp;quot;USB Cam&amp;quot;).isvalid(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).reference(True/False)&amp;lt;/code&amp;gt; || add (True) or remove (False) a reference that keeps the media loaded || &amp;lt;code&amp;gt;mxw.media(&amp;quot;clip.mov&amp;quot;).reference(True)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).unload_media_full_if_not_used_by_clips()&amp;lt;/code&amp;gt; || unload the media if no clip uses it (returns bool) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;clip.mov&amp;quot;).unload_media_full_if_not_used_by_clips()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).get_image_sample_cvmat(w, h)&amp;lt;/code&amp;gt; || return a &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt;&amp;amp;times;&amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; RGBA image sample of the media (OpenCV Mat) || &amp;lt;code&amp;gt;img = mxw.media(&amp;quot;clip.mov&amp;quot;).get_image_sample_cvmat(64, 64)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).get_image_sample_cvmat_async(w, h)&amp;lt;/code&amp;gt; || non-blocking variant of the image sample || &amp;lt;code&amp;gt;img = mxw.media(&amp;quot;clip.mov&amp;quot;).get_image_sample_cvmat_async(64, 64)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).get_capture_device_names()&amp;lt;/code&amp;gt; || return the list of available capture-device names || &amp;lt;code&amp;gt;devs = mxw.media(&amp;quot;&amp;quot;).get_capture_device_names()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_is_supported&amp;quot;)&amp;lt;/code&amp;gt; || return whether the (NDI) camera supports PTZ || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_is_supported&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_zoom&amp;quot;, value)&amp;lt;/code&amp;gt; || zoom, 0 (in) .. 1 (out) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_zoom&amp;quot;, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_zoom_speed&amp;quot;, value)&amp;lt;/code&amp;gt; || zoom speed, -1 (out) .. 1 (in) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_zoom_speed&amp;quot;, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_pan_tilt&amp;quot;, pan, tilt)&amp;lt;/code&amp;gt; || absolute pan/tilt, -1 .. 1 || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_pan_tilt&amp;quot;, -0.5, 0.2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_pan_tilt_speed&amp;quot;, pan_speed, tilt_speed)&amp;lt;/code&amp;gt; || pan/tilt speed, -1 (right/down) .. 1 (left/up) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_pan_tilt_speed&amp;quot;, -0.3, 0.8)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_store_preset&amp;quot;, n)&amp;lt;/code&amp;gt; || store position/focus/zoom into preset 0 .. 99 || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_store_preset&amp;quot;, 75)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_recall_preset&amp;quot;, n, speed)&amp;lt;/code&amp;gt; || recall preset 0 .. 99 at speed 0 .. 1 || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_recall_preset&amp;quot;, 4, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_auto_focus&amp;quot;)&amp;lt;/code&amp;gt; || toggle auto-focus || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_auto_focus&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_focus&amp;quot;, value)&amp;lt;/code&amp;gt; || absolute focus, 0 (infinity) .. 1 (closest) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_focus&amp;quot;, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_focus_speed&amp;quot;, value)&amp;lt;/code&amp;gt; || focus speed, -1 (out) .. 1 (in) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_focus_speed&amp;quot;, -0.2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_auto&amp;quot;)&amp;lt;/code&amp;gt; || auto white balance || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_auto&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_indoor&amp;quot;)&amp;lt;/code&amp;gt; || indoor white balance || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_indoor&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_outdoor&amp;quot;)&amp;lt;/code&amp;gt; || outdoor white balance || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_outdoor&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_oneshot&amp;quot;)&amp;lt;/code&amp;gt; || set white balance once from current brightness || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_oneshot&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_manual&amp;quot;, red, blue)&amp;lt;/code&amp;gt; || manual white balance, 0.0 .. 1.0 each || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_manual&amp;quot;, 0.1, 0.7)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_exposure_auto&amp;quot;)&amp;lt;/code&amp;gt; || auto exposure || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_exposure_auto&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_exposure_manual&amp;quot;, level)&amp;lt;/code&amp;gt; || manual exposure iris, 0.0 (dark) .. 1.0 (light) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_exposure_manual&amp;quot;, 0.4)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_exposure_manual_v2&amp;quot;, iris, gain, shutter)&amp;lt;/code&amp;gt; || manual exposure iris/gain/shutter, 0.0 .. 1.0 each || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_exposure_manual_v2&amp;quot;, 0.4, 0.2, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Grabber ( &amp;lt;code&amp;gt;mxw.grabber(name)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).isvalid()&amp;lt;/code&amp;gt; || True if the named keystone grabber exists || &amp;lt;code&amp;gt;if mxw.grabber(&amp;quot;cam&amp;quot;).isvalid(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).getGrabSizeX()&amp;lt;/code&amp;gt; || grabber width in px || &amp;lt;code&amp;gt;mxw.grabber(&amp;quot;cam&amp;quot;).getGrabSizeX()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).getGrabSizeY()&amp;lt;/code&amp;gt; || grabber height in px || &amp;lt;code&amp;gt;mxw.grabber(&amp;quot;cam&amp;quot;).getGrabSizeY()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).getData()&amp;lt;/code&amp;gt; || return the grabber&#039;s pixels as a byte list (RGBA, width&amp;amp;times;height&amp;amp;times;4) || &amp;lt;code&amp;gt;px = mxw.grabber(&amp;quot;cam&amp;quot;).getData()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Audio capture ( &amp;lt;code&amp;gt;mxw.audio&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.audio.output_capture(capacity_seconds=4.0)&amp;lt;/code&amp;gt; || open a gapless capture of the master OUTPUT mix; returns a capture handle backed by a lock-free ring (&#039;&#039;capacity_seconds&#039;&#039; of buffer) || &amp;lt;code&amp;gt;cap = mxw.audio.output_capture()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.audio.input_capture(capacity_seconds=4.0)&amp;lt;/code&amp;gt; || open a capture of the selected audio INPUT device (same source the analyzer uses) || &amp;lt;code&amp;gt;cap = mxw.audio.input_capture()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;cap.channels&amp;lt;/code&amp;gt; || channel count of the capture || &amp;lt;code&amp;gt;ch = cap.channels&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;cap.sample_rate&amp;lt;/code&amp;gt; || sample rate in Hz (follows the device) || &amp;lt;code&amp;gt;sr = cap.sample_rate&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;cap.available()&amp;lt;/code&amp;gt; || frames currently readable in the ring || &amp;lt;code&amp;gt;n = cap.available()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;cap.read(max_frames)&amp;lt;/code&amp;gt; || read up to &#039;&#039;max_frames&#039;&#039; frames as interleaved &#039;&#039;&#039;float32&#039;&#039;&#039; bytes (length = frames&amp;amp;times;channels&amp;amp;times;4) || &amp;lt;code&amp;gt;import numpy as np; a = np.frombuffer(cap.read(cap.available()), np.float32).reshape(-1, cap.channels)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;cap.is_closed()&amp;lt;/code&amp;gt; || True after a device reopen (rate/channel change) &amp;amp;ndash; drop and re-acquire the handle || &amp;lt;code&amp;gt;if cap.is_closed(): cap = mxw.audio.output_capture()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;cap.close()&amp;lt;/code&amp;gt; || release the capture (idempotent) || &amp;lt;code&amp;gt;cap.close()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;cap.dropped()&amp;lt;/code&amp;gt; || frames dropped because read() fell behind (ring overrun) || &amp;lt;code&amp;gt;cap.dropped()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;cap.starved()&amp;lt;/code&amp;gt; || times the ring was empty on read || &amp;lt;code&amp;gt;cap.starved()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== See also ===&lt;br /&gt;
&lt;br /&gt;
* [[Python imgui reference|Python ImGui Reference]] &amp;amp;ndash; drawing plugin panels with &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt;&lt;br /&gt;
* [[Python plugin reference|Python Plugin Howto]] &amp;amp;ndash; writing media and playlist plugins&lt;br /&gt;
[[Category:Python]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Tutorial_Opening_Different_Media&amp;diff=6209</id>
		<title>Tutorial Opening Different Media</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Tutorial_Opening_Different_Media&amp;diff=6209"/>
		<updated>2026-08-08T19:27:24Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial applies to all different OS and MXWendler versions.&lt;br /&gt;
==Supported Media Sources==&lt;br /&gt;
&lt;br /&gt;
===Video Formats===&lt;br /&gt;
&lt;br /&gt;
All the standard video formats, commonly known as container formats, such as &#039;&#039;&#039;.avi, .mov, .vob or .mpg&#039;&#039;&#039; can be used in the software. Inside these containers are media in the form of so-called codecs for video and audio. MXWendler can read and process all standard codecs, differentiating thereby between ‘internal’ and ‘external’ processing. &amp;lt;div class=&amp;quot;noprint&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
In internal processing, media are transferred – aided by system codecs - into an own format specifically developed for real-time compositing with high-resolution video streams: the CPU in the computer is no longer required to unpack the converted media and can concentrate instead on the graphics. This method enables the 5-times forwards/backwards warping controls, excellent latency at keypoints, frame blending slow motion, and the processing of image sequences. However, to do this, the video material must first be imported. For the direct processing of video material, MXWendler uses an FFMpeg-based decoder that can play performance-optimized videos of up to 4K, and supports multi-channel audio (also via ASIO).&lt;br /&gt;
&lt;br /&gt;
{{#mpdftags: pagebreak}}&lt;br /&gt;
===Live Video===&lt;br /&gt;
&lt;br /&gt;
MXWendler supports nearly all industry-standard grabber- and live input hardware components through Quicktime and DirectShow interfaces. Grabbers for BNC, DVI and SDI video are possible. Latency can be reduced to a minimum, down to under 0,08 seconds, by overclocking the system. Webcams and NDI can be used as live video sources as well. See also: [[Tutorial NDI Tools]].&lt;br /&gt;
&lt;br /&gt;
===Images===&lt;br /&gt;
&lt;br /&gt;
All standard image formats are supported  (&#039;&#039;&#039;.jpg, .png, .psd&#039;&#039;&#039;, etc.).&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
PDF files are supported in MXWendler version 6 and above and can be used as a media source. A PDF file will be played back as an image sequence. Each page of the PDF will be played as one frame. The playback speed can be changed to acquire the desired tempo of the playback. The playback of each frame can be also triggered through the Playlist function, Frame Step. &lt;br /&gt;
See also: [[Tutorial Playlists with PDF and Frame Step]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{#mpdftags: pagebreak}}&lt;br /&gt;
==Opening Different Media==&lt;br /&gt;
&lt;br /&gt;
Different media can be opened/imported in MXWendler by:&lt;br /&gt;
:The file browser in Output Pipeline, in Preload box, or Live Editor.&lt;br /&gt;
:Drag&amp;amp;dropping from explorer to a Preload Clip, a Playlist Cell, in Live Editor, or Layer Manager.&lt;br /&gt;
:Import Multiple Clips through Preload&#039;s function Menu.&lt;br /&gt;
&lt;br /&gt;
===Opening Video &amp;amp; Image Files===&lt;br /&gt;
&lt;br /&gt;
1. Click on the first Preload. The Preload Preview opens (red box). &#039;&#039;&#039;(A)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
2. Left-click on Open to search for the desired file. &#039;&#039;&#039;(B)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
3. Select and open the file. &#039;&#039;&#039;(C)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The file is now in preload and is ready for use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tip: Alternatively, you can also drag&amp;amp;drop the file into the Preload from a file browser, or allocate media to a number of Preloads with Multi Clip Import.&#039;&#039;&lt;br /&gt;
{{#mpdftags: pagebreak}}&lt;br /&gt;
&lt;br /&gt;
[[File:Opening different Media Trigger 1.png|728px]]&lt;br /&gt;
&lt;br /&gt;
===Opening PDF Files===&lt;br /&gt;
&lt;br /&gt;
1. Click on an empty Preload cell to open it.&lt;br /&gt;
&lt;br /&gt;
2. Left-click on Open to search for the desired PDF file.&lt;br /&gt;
&lt;br /&gt;
3. Select and open the file.&lt;br /&gt;
&lt;br /&gt;
The PDF file will be played as an image sequence frame by frame.&lt;br /&gt;
&lt;br /&gt;
4. You can change the playback speed by choosing Speed amounts from 0.0 to 5.0. &#039;&#039;&#039;(A)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
5. You can change the dpi settings (for the resolution of each frame) in settings. &#039;&#039;&#039;(B)&#039;&#039;&#039;&lt;br /&gt;
:&#039;&#039;&#039;Settings &amp;amp;rarr; Media - Clips, Live, Virtual &amp;amp;rarr; PDF &#039;&#039;&#039;&lt;br /&gt;
6. In the Preload Preview, click on Reload Media to make the dpi changes effective. &#039;&#039;&#039;(C)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:pdf.png|728px]]&lt;br /&gt;
&lt;br /&gt;
===Opening a Live Video===&lt;br /&gt;
&lt;br /&gt;
1. Connect the camera to the computer; you may need to restart the software.&lt;br /&gt;
&lt;br /&gt;
2. The Live-Camera must first be activated in MXWendler. &#039;&#039;&#039;(A)&#039;&#039;&#039;&lt;br /&gt;
:&#039;&#039;&#039;Settings &amp;amp;rarr; Media &amp;amp;rarr; Live devices &amp;amp;rarr; Double-click ‘unknown’ &amp;amp;rarr; ‘known’&#039;&#039;&#039;&lt;br /&gt;
:The camera can now be loaded into the Preload.&lt;br /&gt;
3. Open the next Preload. Select the camera in the preview menu under Live Media. &#039;&#039;&#039;(B)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The live video is now in Preload and is ready for use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tip: The camera only needs to be activated a single time. For improved performance, cameras can also be temporarily disabled in the same manner. Please refer to the chapter ‘Media Tips’ for more advanced camera settings.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{#mpdftags: pagebreak}}&lt;br /&gt;
&lt;br /&gt;
[[File:Opening different Media Trigger 2.png|728px]]&lt;br /&gt;
&lt;br /&gt;
===Opening and Creating Image Sequences===&lt;br /&gt;
&lt;br /&gt;
Two things must be considered before the images can be loaded into the Preload:&lt;br /&gt;
&lt;br /&gt;
The images should be stored in a separate folder, and must contain sequential numbering: e.g. Clip_001.png, Clip_002.png...&lt;br /&gt;
 &lt;br /&gt;
1. Open the next Preload. &#039;&#039;&#039;(A)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
2. Click on Open to open the folder containing the images. &#039;&#039;&#039;(B)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
3. Open the first image in the folder. Confirm with Yes to import as a sequence, and set the desired compression quality. &#039;&#039;&#039;(C)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The sequence is now in Preload and is ready for use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tip: Please refer to the chapter ‘Media Tips’ for the proper creation of image sequences.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:Opening different Media Trigger 3.png|728px]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Main_Page&amp;diff=6208</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Main_Page&amp;diff=6208"/>
		<updated>2026-08-08T19:20:05Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= MXWendler Stage Designer and FXServer Knowledge Base =&lt;br /&gt;
MXWendler FXServer and Stage Designer serves the best video playout for Theatres, Facade Projections, Video Mapping, Architectural Lighting, Clubs, and LED Lighting. &#039;&#039;This video software places a strong emphasis on the composition and positioning of the output, because the projection is just as important as the content - no space, stage or scene is like another&#039;&#039;. It is a professional real-time video software, which works quickly, securely and robustly. The clearly laid-out interface makes it easy to use and easy to learn. The only limit is the user’s imagination.&lt;br /&gt;
&lt;br /&gt;
== Getting started ==&lt;br /&gt;
* [[Introduction]]&lt;br /&gt;
* [[User Interface V7|User Interface]]&lt;br /&gt;
* [[Tutorials|Try a Tutorial]]&lt;br /&gt;
* [[Triggering|Triggering Events]]&lt;br /&gt;
* [[Trouble Shooting|Troubleshoot Problems]]&lt;br /&gt;
* [[Usage Tips]]&lt;br /&gt;
* [[Performance|Performance Tips]]&lt;br /&gt;
* [[Translations]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Trouble_Shooting&amp;diff=6207</id>
		<title>Trouble Shooting</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Trouble_Shooting&amp;diff=6207"/>
		<updated>2026-08-08T19:17:15Z</updated>

		<summary type="html">&lt;p&gt;Admin: Restore Aero Peek link; remove outdated &amp;#039;Windows 7 + NDI Tools&amp;#039; link (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Sometimes a driver update or a new hardware or a new operating system screws things up badly. We have collected a lot of knowledge from our test farm and our users over the years to help you across the most common pitfalls.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All OS&#039;&#039;&#039;&lt;br /&gt;
*[[Performance Problems]]&lt;br /&gt;
*[[Smooth Playback/ Frame Drops and Audio Drivers]]&lt;br /&gt;
*[[Keystone: not Opening ./skin/keystone/Video.png: file does not exist]]&lt;br /&gt;
*[[Licenser: Wrong Key Format]]&lt;br /&gt;
*[[Playlist: Crossfading Between Bright Media Becomes Temporarily Dark]]&lt;br /&gt;
*[[Capture Cards (e.g. BM Decklink Studio2)]]&lt;br /&gt;
*[[Memory Allocation Error]]&lt;br /&gt;
*[[Time and Event Sync all PCs]]&lt;br /&gt;
*[[MXW does not start any more]]&lt;br /&gt;
*[[Projector Calculator]]&lt;br /&gt;
*[[Artnet connection issues: Firewall]]&lt;br /&gt;
*[[DMX CITP and Image Sequences]]&lt;br /&gt;
*[[MAudio UC-33 to MXWendler controller programming]]&lt;br /&gt;
*[[OSC Messages - Correct Text and Value Example]]&lt;br /&gt;
*[[User Interface - outside of the main display]]&lt;br /&gt;
*[[PJLink commands for DZ21]]&lt;br /&gt;
*[[SDI Inputs - YUV Format and Wrong Color Output]]&lt;br /&gt;
*[[Vision SDI - Internal Loop/Input]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Windows&#039;&#039;&#039;&lt;br /&gt;
*[[Windows 11 + No Audio Device]]&lt;br /&gt;
*[[Windows 10 + Optimizing Font]]&lt;br /&gt;
*[[Windows 10 + Focusrite 18i20 Audio Issues]]&lt;br /&gt;
*[[Windows 10 + Corrupted Live Video]]&lt;br /&gt;
*[[Windows 10 + VCRUNTTIME140.dll missing]]&lt;br /&gt;
*[[Windows 10 + AJA Kona 5]]&lt;br /&gt;
*[[Windows 10 + Asus Motherboards - Multimonitoring Issues]]&lt;br /&gt;
*[[Windows 10 x64 + Stage Designer/FXServer does not start]]&lt;br /&gt;
*[[Windows 10 + Nvidia and Intel Cards]]&lt;br /&gt;
*[[Windows + Blackmagic Decklink Capture Cards]]&lt;br /&gt;
*[[Windows + Unexpected Output Window Size]]&lt;br /&gt;
*[[Windows + No Output in Output Window]]&lt;br /&gt;
*[[Windows + How to Deactivate Aero Peek to Prevent Unwanted Output Blackouts]]&lt;br /&gt;
*[[Windows 7 + AMD + Stuttering Output]]&lt;br /&gt;
*[[Windows 7 + AMD + Output Window On Wrong Screen]]&lt;br /&gt;
*[[Windows 7 + Artnet]]&lt;br /&gt;
*[[Windows 7 + No Audio]]&lt;br /&gt;
*[[Windows 7 + Configuration (config.xml)]]&lt;br /&gt;
*[[Windows 7 + Richtexteditor Glitches and ClearType]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Linux&#039;&#039;&#039;&lt;br /&gt;
*[[Linux and No Dongle Detection]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mac OSX&#039;&#039;&#039;&lt;br /&gt;
*[[Mac and No Default Clip]]&lt;br /&gt;
*[[Mac and No Translation]]&lt;br /&gt;
*[[Mac and No Shaders Update]]&lt;br /&gt;
*[[Mac Sierra 10.12 Disable App Translocation]]&lt;br /&gt;
*[[Macbook Pro Core 2 Duo with NVidia 9400M]]&lt;br /&gt;
*[[Mac and Graphic Card Performance]]&lt;br /&gt;
*[[Mac Yosemite 10.10 Multimonitor]]&lt;br /&gt;
*[[Mac and Internal Cached Video]]&lt;br /&gt;
*[[Mac and Audio]]&lt;br /&gt;
*[[Mac and Soundflower 64ch Audio]]&lt;br /&gt;
*[[Mac and DMX]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Trouble_Shooting&amp;diff=6206</id>
		<title>Trouble Shooting</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Trouble_Shooting&amp;diff=6206"/>
		<updated>2026-08-08T19:15:28Z</updated>

		<summary type="html">&lt;p&gt;Admin: Remove link to deleted page &amp;#039;Windows + How to Deactivate Aero Peek...&amp;#039; (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Sometimes a driver update or a new hardware or a new operating system screws things up badly. We have collected a lot of knowledge from our test farm and our users over the years to help you across the most common pitfalls.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All OS&#039;&#039;&#039;&lt;br /&gt;
*[[Performance Problems]]&lt;br /&gt;
*[[Smooth Playback/ Frame Drops and Audio Drivers]]&lt;br /&gt;
*[[Keystone: not Opening ./skin/keystone/Video.png: file does not exist]]&lt;br /&gt;
*[[Licenser: Wrong Key Format]]&lt;br /&gt;
*[[Playlist: Crossfading Between Bright Media Becomes Temporarily Dark]]&lt;br /&gt;
*[[Capture Cards (e.g. BM Decklink Studio2)]]&lt;br /&gt;
*[[Memory Allocation Error]]&lt;br /&gt;
*[[Time and Event Sync all PCs]]&lt;br /&gt;
*[[MXW does not start any more]]&lt;br /&gt;
*[[Projector Calculator]]&lt;br /&gt;
*[[Artnet connection issues: Firewall]]&lt;br /&gt;
*[[DMX CITP and Image Sequences]]&lt;br /&gt;
*[[MAudio UC-33 to MXWendler controller programming]]&lt;br /&gt;
*[[OSC Messages - Correct Text and Value Example]]&lt;br /&gt;
*[[User Interface - outside of the main display]]&lt;br /&gt;
*[[PJLink commands for DZ21]]&lt;br /&gt;
*[[SDI Inputs - YUV Format and Wrong Color Output]]&lt;br /&gt;
*[[Vision SDI - Internal Loop/Input]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Windows&#039;&#039;&#039;&lt;br /&gt;
*[[Windows 11 + No Audio Device]]&lt;br /&gt;
*[[Windows 10 + Optimizing Font]]&lt;br /&gt;
*[[Windows 10 + Focusrite 18i20 Audio Issues]]&lt;br /&gt;
*[[Windows 10 + Corrupted Live Video]]&lt;br /&gt;
*[[Windows 10 + VCRUNTTIME140.dll missing]]&lt;br /&gt;
*[[Windows 10 + AJA Kona 5]]&lt;br /&gt;
*[[Windows 10 + Asus Motherboards - Multimonitoring Issues]]&lt;br /&gt;
*[[Windows 10 x64 + Stage Designer/FXServer does not start]]&lt;br /&gt;
*[[Windows 10 + Nvidia and Intel Cards]]&lt;br /&gt;
*[[Windows + Blackmagic Decklink Capture Cards]]&lt;br /&gt;
*[[Windows + Unexpected Output Window Size]]&lt;br /&gt;
*[[Windows + No Output in Output Window]]&lt;br /&gt;
*[[Windows 7 + AMD + Stuttering Output]]&lt;br /&gt;
*[[Windows 7 + AMD + Output Window On Wrong Screen]]&lt;br /&gt;
*[[Windows 7 + Artnet]]&lt;br /&gt;
*[[Windows 7 + No Audio]]&lt;br /&gt;
*[[Windows 7 + Configuration (config.xml)]]&lt;br /&gt;
*[[Windows 7 + Richtexteditor Glitches and ClearType]]&lt;br /&gt;
*[[Windows 7 + NDI Tools]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Linux&#039;&#039;&#039;&lt;br /&gt;
*[[Linux and No Dongle Detection]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mac OSX&#039;&#039;&#039;&lt;br /&gt;
*[[Mac and No Default Clip]]&lt;br /&gt;
*[[Mac and No Translation]]&lt;br /&gt;
*[[Mac and No Shaders Update]]&lt;br /&gt;
*[[Mac Sierra 10.12 Disable App Translocation]]&lt;br /&gt;
*[[Macbook Pro Core 2 Duo with NVidia 9400M]]&lt;br /&gt;
*[[Mac and Graphic Card Performance]]&lt;br /&gt;
*[[Mac Yosemite 10.10 Multimonitor]]&lt;br /&gt;
*[[Mac and Internal Cached Video]]&lt;br /&gt;
*[[Mac and Audio]]&lt;br /&gt;
*[[Mac and Soundflower 64ch Audio]]&lt;br /&gt;
*[[Mac and DMX]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Trouble_Shooting&amp;diff=6205</id>
		<title>Trouble Shooting</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Trouble_Shooting&amp;diff=6205"/>
		<updated>2026-08-08T19:15:10Z</updated>

		<summary type="html">&lt;p&gt;Admin: Remove link to deleted page &amp;#039;Windows XP + No output on second screen&amp;#039; (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Sometimes a driver update or a new hardware or a new operating system screws things up badly. We have collected a lot of knowledge from our test farm and our users over the years to help you across the most common pitfalls.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All OS&#039;&#039;&#039;&lt;br /&gt;
*[[Performance Problems]]&lt;br /&gt;
*[[Smooth Playback/ Frame Drops and Audio Drivers]]&lt;br /&gt;
*[[Keystone: not Opening ./skin/keystone/Video.png: file does not exist]]&lt;br /&gt;
*[[Licenser: Wrong Key Format]]&lt;br /&gt;
*[[Playlist: Crossfading Between Bright Media Becomes Temporarily Dark]]&lt;br /&gt;
*[[Capture Cards (e.g. BM Decklink Studio2)]]&lt;br /&gt;
*[[Memory Allocation Error]]&lt;br /&gt;
*[[Time and Event Sync all PCs]]&lt;br /&gt;
*[[MXW does not start any more]]&lt;br /&gt;
*[[Projector Calculator]]&lt;br /&gt;
*[[Artnet connection issues: Firewall]]&lt;br /&gt;
*[[DMX CITP and Image Sequences]]&lt;br /&gt;
*[[MAudio UC-33 to MXWendler controller programming]]&lt;br /&gt;
*[[OSC Messages - Correct Text and Value Example]]&lt;br /&gt;
*[[User Interface - outside of the main display]]&lt;br /&gt;
*[[PJLink commands for DZ21]]&lt;br /&gt;
*[[SDI Inputs - YUV Format and Wrong Color Output]]&lt;br /&gt;
*[[Vision SDI - Internal Loop/Input]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Windows&#039;&#039;&#039;&lt;br /&gt;
*[[Windows 11 + No Audio Device]]&lt;br /&gt;
*[[Windows 10 + Optimizing Font]]&lt;br /&gt;
*[[Windows 10 + Focusrite 18i20 Audio Issues]]&lt;br /&gt;
*[[Windows 10 + Corrupted Live Video]]&lt;br /&gt;
*[[Windows 10 + VCRUNTTIME140.dll missing]]&lt;br /&gt;
*[[Windows 10 + AJA Kona 5]]&lt;br /&gt;
*[[Windows 10 + Asus Motherboards - Multimonitoring Issues]]&lt;br /&gt;
*[[Windows 10 x64 + Stage Designer/FXServer does not start]]&lt;br /&gt;
*[[Windows 10 + Nvidia and Intel Cards]]&lt;br /&gt;
*[[Windows + Blackmagic Decklink Capture Cards]]&lt;br /&gt;
*[[Windows + How to Deactivate Aero Peek to Prevent Unwanted Output Blackouts]]&lt;br /&gt;
*[[Windows + Unexpected Output Window Size]]&lt;br /&gt;
*[[Windows + No Output in Output Window]]&lt;br /&gt;
*[[Windows 7 + AMD + Stuttering Output]]&lt;br /&gt;
*[[Windows 7 + AMD + Output Window On Wrong Screen]]&lt;br /&gt;
*[[Windows 7 + Artnet]]&lt;br /&gt;
*[[Windows 7 + No Audio]]&lt;br /&gt;
*[[Windows 7 + Configuration (config.xml)]]&lt;br /&gt;
*[[Windows 7 + Richtexteditor Glitches and ClearType]]&lt;br /&gt;
*[[Windows 7 + NDI Tools]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Linux&#039;&#039;&#039;&lt;br /&gt;
*[[Linux and No Dongle Detection]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mac OSX&#039;&#039;&#039;&lt;br /&gt;
*[[Mac and No Default Clip]]&lt;br /&gt;
*[[Mac and No Translation]]&lt;br /&gt;
*[[Mac and No Shaders Update]]&lt;br /&gt;
*[[Mac Sierra 10.12 Disable App Translocation]]&lt;br /&gt;
*[[Macbook Pro Core 2 Duo with NVidia 9400M]]&lt;br /&gt;
*[[Mac and Graphic Card Performance]]&lt;br /&gt;
*[[Mac Yosemite 10.10 Multimonitor]]&lt;br /&gt;
*[[Mac and Internal Cached Video]]&lt;br /&gt;
*[[Mac and Audio]]&lt;br /&gt;
*[[Mac and Soundflower 64ch Audio]]&lt;br /&gt;
*[[Mac and DMX]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Trouble_Shooting&amp;diff=6204</id>
		<title>Trouble Shooting</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Trouble_Shooting&amp;diff=6204"/>
		<updated>2026-08-08T19:14:41Z</updated>

		<summary type="html">&lt;p&gt;Admin: Remove link to deleted page &amp;#039;Re-Converting Video files using AVANTI GUI&amp;#039; (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Sometimes a driver update or a new hardware or a new operating system screws things up badly. We have collected a lot of knowledge from our test farm and our users over the years to help you across the most common pitfalls.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All OS&#039;&#039;&#039;&lt;br /&gt;
*[[Performance Problems]]&lt;br /&gt;
*[[Smooth Playback/ Frame Drops and Audio Drivers]]&lt;br /&gt;
*[[Keystone: not Opening ./skin/keystone/Video.png: file does not exist]]&lt;br /&gt;
*[[Licenser: Wrong Key Format]]&lt;br /&gt;
*[[Playlist: Crossfading Between Bright Media Becomes Temporarily Dark]]&lt;br /&gt;
*[[Capture Cards (e.g. BM Decklink Studio2)]]&lt;br /&gt;
*[[Memory Allocation Error]]&lt;br /&gt;
*[[Time and Event Sync all PCs]]&lt;br /&gt;
*[[MXW does not start any more]]&lt;br /&gt;
*[[Projector Calculator]]&lt;br /&gt;
*[[Artnet connection issues: Firewall]]&lt;br /&gt;
*[[DMX CITP and Image Sequences]]&lt;br /&gt;
*[[MAudio UC-33 to MXWendler controller programming]]&lt;br /&gt;
*[[OSC Messages - Correct Text and Value Example]]&lt;br /&gt;
*[[User Interface - outside of the main display]]&lt;br /&gt;
*[[PJLink commands for DZ21]]&lt;br /&gt;
*[[SDI Inputs - YUV Format and Wrong Color Output]]&lt;br /&gt;
*[[Vision SDI - Internal Loop/Input]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Windows&#039;&#039;&#039;&lt;br /&gt;
*[[Windows 11 + No Audio Device]]&lt;br /&gt;
*[[Windows 10 + Optimizing Font]]&lt;br /&gt;
*[[Windows 10 + Focusrite 18i20 Audio Issues]]&lt;br /&gt;
*[[Windows 10 + Corrupted Live Video]]&lt;br /&gt;
*[[Windows 10 + VCRUNTTIME140.dll missing]]&lt;br /&gt;
*[[Windows 10 + AJA Kona 5]]&lt;br /&gt;
*[[Windows 10 + Asus Motherboards - Multimonitoring Issues]]&lt;br /&gt;
*[[Windows 10 x64 + Stage Designer/FXServer does not start]]&lt;br /&gt;
*[[Windows 10 + Nvidia and Intel Cards]]&lt;br /&gt;
*[[Windows + Blackmagic Decklink Capture Cards]]&lt;br /&gt;
*[[Windows + How to Deactivate Aero Peek to Prevent Unwanted Output Blackouts]]&lt;br /&gt;
*[[Windows + Unexpected Output Window Size]]&lt;br /&gt;
*[[Windows + No Output in Output Window]]&lt;br /&gt;
*[[Windows 7 + AMD + Stuttering Output]]&lt;br /&gt;
*[[Windows 7 + AMD + Output Window On Wrong Screen]]&lt;br /&gt;
*[[Windows 7 + Artnet]]&lt;br /&gt;
*[[Windows 7 + No Audio]]&lt;br /&gt;
*[[Windows 7 + Configuration (config.xml)]]&lt;br /&gt;
*[[Windows 7 + Richtexteditor Glitches and ClearType]]&lt;br /&gt;
*[[Windows 7 + NDI Tools]]&lt;br /&gt;
*[[Windows XP + No output on second screen|Windows XP + NVidia No output on second screen]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Linux&#039;&#039;&#039;&lt;br /&gt;
*[[Linux and No Dongle Detection]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mac OSX&#039;&#039;&#039;&lt;br /&gt;
*[[Mac and No Default Clip]]&lt;br /&gt;
*[[Mac and No Translation]]&lt;br /&gt;
*[[Mac and No Shaders Update]]&lt;br /&gt;
*[[Mac Sierra 10.12 Disable App Translocation]]&lt;br /&gt;
*[[Macbook Pro Core 2 Duo with NVidia 9400M]]&lt;br /&gt;
*[[Mac and Graphic Card Performance]]&lt;br /&gt;
*[[Mac Yosemite 10.10 Multimonitor]]&lt;br /&gt;
*[[Mac and Internal Cached Video]]&lt;br /&gt;
*[[Mac and Audio]]&lt;br /&gt;
*[[Mac and Soundflower 64ch Audio]]&lt;br /&gt;
*[[Mac and DMX]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=OSC_Reference&amp;diff=6203</id>
		<title>OSC Reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=OSC_Reference&amp;diff=6203"/>
		<updated>2026-08-08T19:13:01Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This reference applies to all different OS.&lt;br /&gt;
&amp;lt;div class=&amp;quot;noprint&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
This document describes the MXWendler (MXW) OSC Command Interface through an overview of the command structure and practical examples of integration with external controlling software. &lt;br /&gt;
&lt;br /&gt;
== What is OSC? ==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
OSC or „Open Sound Control“ is a Network-based protocol that commonly utilizes the UDP transport mechanism. Originally developed as a successor of the MIDI control protocol, it used nowadays as a practical communication method between platforms.&lt;br /&gt;
&lt;br /&gt;
OSC Features:&lt;br /&gt;
* Connectionless communication architecture&lt;br /&gt;
* Broadcast-type messages&lt;br /&gt;
* High resolution time tag&lt;br /&gt;
* Allowed data formats including numeric, symbolic, and “blob” arguments&lt;br /&gt;
* Open-ended, dynamic, URL-style naming scheme for the receivers&#039; address&lt;br /&gt;
== Contents ==&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px&amp;quot; | [[Controlling MXW through OSC]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px&amp;quot; | [[MXW OSC command structure]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px&amp;quot; | [[OSC command reference]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px&amp;quot; | [[OSC Troubleshooting|Troubleshooting]] &lt;br /&gt;
|}&lt;br /&gt;
[[Category:OSC]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=OSC_Reference&amp;diff=6202</id>
		<title>OSC Reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=OSC_Reference&amp;diff=6202"/>
		<updated>2026-08-08T19:12:10Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This reference applies to all different OS. The presented OSC commands are for most part supported in version 6.0 but will be fully functional in version 6.0.08 and above. &lt;br /&gt;
&amp;lt;div class=&amp;quot;noprint&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
This document describes the MXWendler (MXW) OSC Command Interface through an overview of the command structure and practical examples of integration with external controlling software. &lt;br /&gt;
&lt;br /&gt;
== What is OSC? ==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
OSC or „Open Sound Control“ is a Network-based protocol that commonly utilizes the UDP transport mechanism. Originally developed as a successor of the MIDI control protocol, it used nowadays as a practical communication method between platforms.&lt;br /&gt;
&lt;br /&gt;
OSC Features:&lt;br /&gt;
* Connectionless communication architecture&lt;br /&gt;
* Broadcast-type messages&lt;br /&gt;
* High resolution time tag&lt;br /&gt;
* Allowed data formats including numeric, symbolic, and “blob” arguments&lt;br /&gt;
* Open-ended, dynamic, URL-style naming scheme for the receivers&#039; address&lt;br /&gt;
      &lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/Open_Sound_Control [1&amp;lt;nowiki&amp;gt;]&amp;lt;/nowiki&amp;gt; Wikipedia Link]&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px&amp;quot; | [[Controlling MXW through OSC]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px&amp;quot; | [[MXW OSC command structure]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px&amp;quot; | [[OSC command reference]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px&amp;quot; | [[OSC Troubleshooting|Troubleshooting]] &lt;br /&gt;
|}&lt;br /&gt;
[[Category:OSC]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=OSC_Reference&amp;diff=6201</id>
		<title>OSC Reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=OSC_Reference&amp;diff=6201"/>
		<updated>2026-08-08T19:08:59Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update link after renaming Troubleshooting -&amp;gt; OSC Troubleshooting (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This reference applies to all different OS. The presented OSC commands are for most part supported in version 6.0 but will be fully functional in version 6.0.08 and above. &lt;br /&gt;
&amp;lt;div class=&amp;quot;noprint&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
This document describes the MXWendler (MXW) OSC Command Interface through an overview of the command structure and practical examples of integration with external controlling software. &lt;br /&gt;
&lt;br /&gt;
== What is OSC? ==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
OSC or „Open Sound Control“ is a Network-based protocol that commonly utilizes the UDP transport mechanism. Originally developed as a successor of the MIDI control protocol, it used nowadays as a practical communication method between platforms.&lt;br /&gt;
&lt;br /&gt;
OSC Features:&lt;br /&gt;
* Connectionless communication architecture&lt;br /&gt;
* Broadcast-type messages&lt;br /&gt;
* High resolution time tag&lt;br /&gt;
* Allowed data formats including numeric, symbolic, and “blob” arguments&lt;br /&gt;
* Open-ended, dynamic, URL-style naming scheme for the receivers&#039; address&lt;br /&gt;
      &lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/Open_Sound_Control [1&amp;lt;nowiki&amp;gt;]&amp;lt;/nowiki&amp;gt; Wikipedia Link]&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px&amp;quot; | [[Controlling MXW through OSC]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;Receiving OSC commands in MXW&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px 10px&amp;quot; | &#039;&#039;Output OSC from MXW: Send vs. Reply&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px 0px&amp;quot; | [[MXW OSC command structure]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;Sending OSC Values&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;Examples&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[OSC command reference]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding:  10px&amp;quot; | [[OSC Troubleshooting|Troubleshooting]] &lt;br /&gt;
|}&lt;br /&gt;
[[Category:OSC]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=OSC_Troubleshooting&amp;diff=6199</id>
		<title>OSC Troubleshooting</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=OSC_Troubleshooting&amp;diff=6199"/>
		<updated>2026-08-08T19:08:57Z</updated>

		<summary type="html">&lt;p&gt;Admin: Admin moved page Troubleshooting to OSC Troubleshooting: Clarify: OSC-specific troubleshooting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Common issues that can arise while using OSC and MXW are generally linked to network malfunctions.&lt;br /&gt;
&lt;br /&gt;
===Network diagnostics===&lt;br /&gt;
     &lt;br /&gt;
Make sure that the system you want to control is correctly connected to the same network as the ‘master’  machine.&lt;br /&gt;
&lt;br /&gt;
==== To proof if the two machines are able to communicate in the network try to ping reciprocally the two systems: ====&lt;br /&gt;
:* For Windows users:&lt;br /&gt;
::1. Open the “Command Prompt” in the ‘master’ system as Administrator&lt;br /&gt;
::2. Type &amp;lt;code&amp;gt; ipconfig &amp;lt;/code&amp;gt; take note of the IPv4 Address&lt;br /&gt;
::3. Repeat for the ‘slave’ system&lt;br /&gt;
::4.In the ‘master’ test if the other machine is reachable by typing &amp;lt;code&amp;gt; ping &amp;lt;/code&amp;gt; followed by the IP of the ‘slave’ (e.g. &amp;lt;code&amp;gt; ping 192.168.178.7 &amp;lt;/code&amp;gt;)&lt;br /&gt;
::5. If the machine is reachable a similar message will appear:&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
              Pinging 192.168.178.7 with 32 bytes of data:&lt;br /&gt;
              Reply from 192.168.178.7: bytes=32 time&amp;lt;1ms TTL=64&lt;br /&gt;
              Reply from 192.168.178.7: bytes=32 time&amp;lt;1ms TTL=64&lt;br /&gt;
              Reply from 192.168.178.7: bytes=32 time&amp;lt;1ms TTL=64&lt;br /&gt;
              Reply from 192.168.178.7: bytes=32 time&amp;lt;1ms TTL=64&lt;br /&gt;
              &lt;br /&gt;
              Ping statistics for 192.168.178.7:&lt;br /&gt;
                  Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),&lt;br /&gt;
              Approximate round trip times in milli-seconds:&lt;br /&gt;
                 Minimum = 0ms, Maximum = 0ms, Average = 0ms&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
::* In case it is not reachable the message will show in the statistics&lt;br /&gt;
              Received = 0 , Lost = 4 (100% Loss) &lt;br /&gt;
::* Repeat the steps sending the ping from the ‘slave’ to the ‘master’ IP to proof the connections&lt;br /&gt;
:* For Mac OS X users:&lt;br /&gt;
::1. Press “Apple” + &amp;quot;SPACE BAR&amp;quot; and search for “Terminal”  in the ‘master’ system&lt;br /&gt;
::2. Type &amp;lt;code&amp;gt; ping &amp;lt;/code&amp;gt; followed by the IP Address of the ‘slave’  &lt;br /&gt;
::3. Proof if the ping get through&lt;br /&gt;
::4. Repeat for the ‘slave’ system pinging the IP of the ‘master’&lt;br /&gt;
              &lt;br /&gt;
==== In case of failure to connect: ==== &lt;br /&gt;
:*Verify that the firewall is not blocking the communication:&lt;br /&gt;
::* For Windows users:&lt;br /&gt;
:::1. Search for “Firewall &amp;amp; Network Protection” in the “Start” menu &lt;br /&gt;
:::2. Deactivate all three (Domain, Private and Public) firewalls by entering the respective window and switching the protection to “Off” in all of them&lt;br /&gt;
::* For Mac OS X users:&lt;br /&gt;
:::1. In the Apple menu, select “System Preferences”&lt;br /&gt;
:::2. In the System Preferences window, select “Security and Privacy”&lt;br /&gt;
:::3. In the tab “Firewall” turn off the Firewall by pressing the “Turn Off” Button (10.6 or higher) or by deselecting the checkbox “Block all incoming connections” (10.5 or lower)&lt;br /&gt;
&amp;lt;/div&amp;gt;        &lt;br /&gt;
::* In your Router settings page (see the manufacturers manual for instructions) disable AP (access point) isolation, also known as &#039;Client Isolation&#039; or &#039;Guest Mode&#039;  when active&lt;br /&gt;
&lt;br /&gt;
==== In case of occasional loss of OSC packages: ====&lt;br /&gt;
::* The maximum size of every OSC package is defined by the MTU (minimum transport unit) of the network in use. Big packages tend to get lost more easily depending on the characteristics of the network so reducing the amount of big blobs (e.g. preview requests) can lower the loss rate. See&lt;br /&gt;
::* In case of loss of small packages, verify if the packages are getting sent and their size with a package sniffer (e.g. &amp;quot;Wireshark&amp;quot;) and try different settings on your receiving console/device.&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;/br&amp;gt;     &lt;br /&gt;
If none of the above solutions solves the issue try by restarting the software and reconnecting all the network chain from start.&lt;br /&gt;
&lt;br /&gt;
For further diagnostics activate the Log of received data in MXW and the dispatch of livesigns (See Points 2.2 and 2.2 d. of the Open Sound Control References) to test the receiving and sending functionality on the wished OSC console, Pd patch or the Protokol App for a mobile option (see point 4.).&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=OSC_Reference&amp;diff=6198</id>
		<title>OSC Reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=OSC_Reference&amp;diff=6198"/>
		<updated>2026-08-08T19:04:34Z</updated>

		<summary type="html">&lt;p&gt;Admin: Remove index numbering from OSC contents (links + sub-items) (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This reference applies to all different OS. The presented OSC commands are for most part supported in version 6.0 but will be fully functional in version 6.0.08 and above. &lt;br /&gt;
&amp;lt;div class=&amp;quot;noprint&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
This document describes the MXWendler (MXW) OSC Command Interface through an overview of the command structure and practical examples of integration with external controlling software. &lt;br /&gt;
&lt;br /&gt;
== What is OSC? ==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
OSC or „Open Sound Control“ is a Network-based protocol that commonly utilizes the UDP transport mechanism. Originally developed as a successor of the MIDI control protocol, it used nowadays as a practical communication method between platforms.&lt;br /&gt;
&lt;br /&gt;
OSC Features:&lt;br /&gt;
* Connectionless communication architecture&lt;br /&gt;
* Broadcast-type messages&lt;br /&gt;
* High resolution time tag&lt;br /&gt;
* Allowed data formats including numeric, symbolic, and “blob” arguments&lt;br /&gt;
* Open-ended, dynamic, URL-style naming scheme for the receivers&#039; address&lt;br /&gt;
      &lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/Open_Sound_Control [1&amp;lt;nowiki&amp;gt;]&amp;lt;/nowiki&amp;gt; Wikipedia Link]&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px&amp;quot; | [[Controlling MXW through OSC]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;Receiving OSC commands in MXW&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px 10px&amp;quot; | &#039;&#039;Output OSC from MXW: Send vs. Reply&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px 0px&amp;quot; | [[MXW OSC command structure]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;Sending OSC Values&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;Examples&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[OSC command reference]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding:  10px&amp;quot; | [[Troubleshooting]] &lt;br /&gt;
|}&lt;br /&gt;
[[Category:OSC]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=OSC_Troubleshooting&amp;diff=6196</id>
		<title>OSC Troubleshooting</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=OSC_Troubleshooting&amp;diff=6196"/>
		<updated>2026-08-08T19:04:14Z</updated>

		<summary type="html">&lt;p&gt;Admin: Admin moved page 5. Troubleshooting to Troubleshooting: Remove leading index prefix from title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Common issues that can arise while using OSC and MXW are generally linked to network malfunctions.&lt;br /&gt;
&lt;br /&gt;
===Network diagnostics===&lt;br /&gt;
     &lt;br /&gt;
Make sure that the system you want to control is correctly connected to the same network as the ‘master’  machine.&lt;br /&gt;
&lt;br /&gt;
==== To proof if the two machines are able to communicate in the network try to ping reciprocally the two systems: ====&lt;br /&gt;
:* For Windows users:&lt;br /&gt;
::1. Open the “Command Prompt” in the ‘master’ system as Administrator&lt;br /&gt;
::2. Type &amp;lt;code&amp;gt; ipconfig &amp;lt;/code&amp;gt; take note of the IPv4 Address&lt;br /&gt;
::3. Repeat for the ‘slave’ system&lt;br /&gt;
::4.In the ‘master’ test if the other machine is reachable by typing &amp;lt;code&amp;gt; ping &amp;lt;/code&amp;gt; followed by the IP of the ‘slave’ (e.g. &amp;lt;code&amp;gt; ping 192.168.178.7 &amp;lt;/code&amp;gt;)&lt;br /&gt;
::5. If the machine is reachable a similar message will appear:&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
              Pinging 192.168.178.7 with 32 bytes of data:&lt;br /&gt;
              Reply from 192.168.178.7: bytes=32 time&amp;lt;1ms TTL=64&lt;br /&gt;
              Reply from 192.168.178.7: bytes=32 time&amp;lt;1ms TTL=64&lt;br /&gt;
              Reply from 192.168.178.7: bytes=32 time&amp;lt;1ms TTL=64&lt;br /&gt;
              Reply from 192.168.178.7: bytes=32 time&amp;lt;1ms TTL=64&lt;br /&gt;
              &lt;br /&gt;
              Ping statistics for 192.168.178.7:&lt;br /&gt;
                  Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),&lt;br /&gt;
              Approximate round trip times in milli-seconds:&lt;br /&gt;
                 Minimum = 0ms, Maximum = 0ms, Average = 0ms&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
::* In case it is not reachable the message will show in the statistics&lt;br /&gt;
              Received = 0 , Lost = 4 (100% Loss) &lt;br /&gt;
::* Repeat the steps sending the ping from the ‘slave’ to the ‘master’ IP to proof the connections&lt;br /&gt;
:* For Mac OS X users:&lt;br /&gt;
::1. Press “Apple” + &amp;quot;SPACE BAR&amp;quot; and search for “Terminal”  in the ‘master’ system&lt;br /&gt;
::2. Type &amp;lt;code&amp;gt; ping &amp;lt;/code&amp;gt; followed by the IP Address of the ‘slave’  &lt;br /&gt;
::3. Proof if the ping get through&lt;br /&gt;
::4. Repeat for the ‘slave’ system pinging the IP of the ‘master’&lt;br /&gt;
              &lt;br /&gt;
==== In case of failure to connect: ==== &lt;br /&gt;
:*Verify that the firewall is not blocking the communication:&lt;br /&gt;
::* For Windows users:&lt;br /&gt;
:::1. Search for “Firewall &amp;amp; Network Protection” in the “Start” menu &lt;br /&gt;
:::2. Deactivate all three (Domain, Private and Public) firewalls by entering the respective window and switching the protection to “Off” in all of them&lt;br /&gt;
::* For Mac OS X users:&lt;br /&gt;
:::1. In the Apple menu, select “System Preferences”&lt;br /&gt;
:::2. In the System Preferences window, select “Security and Privacy”&lt;br /&gt;
:::3. In the tab “Firewall” turn off the Firewall by pressing the “Turn Off” Button (10.6 or higher) or by deselecting the checkbox “Block all incoming connections” (10.5 or lower)&lt;br /&gt;
&amp;lt;/div&amp;gt;        &lt;br /&gt;
::* In your Router settings page (see the manufacturers manual for instructions) disable AP (access point) isolation, also known as &#039;Client Isolation&#039; or &#039;Guest Mode&#039;  when active&lt;br /&gt;
&lt;br /&gt;
==== In case of occasional loss of OSC packages: ====&lt;br /&gt;
::* The maximum size of every OSC package is defined by the MTU (minimum transport unit) of the network in use. Big packages tend to get lost more easily depending on the characteristics of the network so reducing the amount of big blobs (e.g. preview requests) can lower the loss rate. See&lt;br /&gt;
::* In case of loss of small packages, verify if the packages are getting sent and their size with a package sniffer (e.g. &amp;quot;Wireshark&amp;quot;) and try different settings on your receiving console/device.&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;/br&amp;gt;     &lt;br /&gt;
If none of the above solutions solves the issue try by restarting the software and reconnecting all the network chain from start.&lt;br /&gt;
&lt;br /&gt;
For further diagnostics activate the Log of received data in MXW and the dispatch of livesigns (See Points 2.2 and 2.2 d. of the Open Sound Control References) to test the receiving and sending functionality on the wished OSC console, Pd patch or the Protokol App for a mobile option (see point 4.).&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=MXW_OSC_command_structure&amp;diff=6194</id>
		<title>MXW OSC command structure</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=MXW_OSC_command_structure&amp;diff=6194"/>
		<updated>2026-08-08T19:04:13Z</updated>

		<summary type="html">&lt;p&gt;Admin: Admin moved page 2. MXW OSC command structure to MXW OSC command structure: Remove leading index prefix from title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
View source for 2. MXW OSC command structure&lt;br /&gt;
← 2. MXW OSC command structure&lt;br /&gt;
Jump to navigationJump to search&lt;br /&gt;
You do not have permission to edit this page, for the following reason:&lt;br /&gt;
&lt;br /&gt;
The action you have requested is limited to users in the group: Users.&lt;br /&gt;
&lt;br /&gt;
You can view and copy the source of this page.&lt;br /&gt;
&lt;br /&gt;
Commands to the MXW OSC interface always follow the same syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/&amp;lt;address of widget&amp;gt; [MSGID] &amp;lt;float|integer|string&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/track/1 0.5&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
or:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/set play patch1&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
or:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/playlist MSGID0001 info&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Commands always begin with /mxw/ and it is followed by the address of the receiver and an argument that can be a numeric value, a string, or a combination of both.&lt;br /&gt;
The only optional element is the “Message-ID”.&lt;br /&gt;
&lt;br /&gt;
== 2.1 Sending OSC Values ==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
The command receivers listen to a value that is either a float or an integer (if they are widgets), or to strings (e.g. to choose patches or clips). &lt;br /&gt;
==== Faders ====&lt;br /&gt;
Receivers in MXW connected to faders in the user interface are responding to Float values. Floats are always in the range of 0.0 to 1.0 and will be scaled to the actual range of the recalled widget. &amp;lt;br&amp;gt;&lt;br /&gt;
For instance, the speed fader has a range in MXW that goes between -5 and 5 and its active range is dependent on the type of played media. &amp;lt;br&amp;gt; If a float value like 0.6 is sent to the OSC address of the clip speed, the fader moves to the value 1.0  (original speed of the clip).&lt;br /&gt;
&lt;br /&gt;
==== Buttons and Checkboxes ====&lt;br /&gt;
Widgets in MXW that have an &#039;&#039;&#039;ON/OFF&#039;&#039;&#039; state accept integers as values. Buttons have the functions Press and Release assigned respectively to &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; and checkboxes have assigned ON and OFF respectively to &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. &amp;lt;/br&amp;gt; This means that if one wants to send a button press, e.g. a &amp;quot;play&amp;quot; button press, a value &amp;quot;0&amp;quot; has to be sent (to send a command, like with a mouse-click, a button must be pressed &amp;lt;u&amp;gt;and released&amp;lt;/u&amp;gt; after)&lt;br /&gt;
&lt;br /&gt;
==== Drop-down Boxes and Combo Boxes ====&lt;br /&gt;
Drop-down lists and Combo Boxes are indexed with integers ranging between &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; and the maximum number of elements. For example to select the third element of a list the integer &amp;lt;code&amp;gt;3&amp;lt;/code&amp;gt; will be sent to the address of the Combo Box.&lt;br /&gt;
&lt;br /&gt;
=== String Tokens ===&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Specific string tokens can also be sent to the command receivers and they can respectively activate specific functions paired with a numeric value or another string. The usable strings are &amp;lt;code&amp;gt;play&amp;lt;/code&amp;gt;&amp;lt;code&amp;gt;info&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;select&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;preview&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;clear&amp;lt;/code&amp;gt;.&lt;br /&gt;
==== play ====  &lt;br /&gt;
The string play can be sent together with another string containing the name of a saved patch in the address &amp;lt;code&amp;gt;/mxw/set &amp;lt;/code&amp;gt; to start the playback of the recalled patch.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/set play patch1&amp;lt;/code&amp;gt;.&lt;br /&gt;
==== info ====&lt;br /&gt;
The string variable info can be sent to a specific address to acquire information about one field or clip through a reply sent by MXW.&lt;br /&gt;
The reply  bundle coming from MXW will also be sent through OSC and will have this format:&lt;br /&gt;
&lt;br /&gt;
* A reply header composed by:&lt;br /&gt;
&lt;br /&gt;
1. Message &amp;lt;code&amp;gt;mxw/reply&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
2. &amp;lt;code&amp;gt;MSGID&amp;lt;/code&amp;gt; (if specified in the info request)&amp;lt;br&amp;gt;&lt;br /&gt;
3. Address pattern of the request&amp;lt;br&amp;gt;&lt;br /&gt;
4. Time as a long variable&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The actual &#039;&#039;&#039;reply content&#039;&#039;&#039; following this table:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! ADDRESS !! REPLY CONTENT&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist info &amp;lt;/code&amp;gt;|| 1. State of the playback (&amp;lt;code&amp;gt;play&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;paused&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;stopped&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/container/active info &amp;lt;/code&amp;gt;|| 1. Active container index &amp;lt;br&amp;gt; 2. Number of columns &amp;lt;br&amp;gt; 3. Number of rows &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw/playlist/container/active/column/1/row/1 info &amp;lt;/code&amp;gt;|| 1. Label of media in the container in column 1, row 1&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip info &amp;lt;/code&amp;gt;||  1. Length of media &amp;lt;br&amp;gt; 2. Width &amp;lt;br&amp;gt;3. Height&amp;lt;br&amp;gt;4. ms per frame&amp;lt;br&amp;gt; 5. Completition of cache (&amp;lt;code&amp;gt;cachecomplete&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;cachenotcomplete&amp;lt;/code&amp;gt;)&amp;lt;br&amp;gt; 6. Path directory of the active clip&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/preload/1 info &amp;lt;/code&amp;gt;|| 1. Length of media &amp;lt;br&amp;gt; 2. Width &amp;lt;br&amp;gt;3. Height&amp;lt;br&amp;gt;4. ms per frame&amp;lt;br&amp;gt; 5. Completition of cache (&amp;lt;code&amp;gt;cachecomplete&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;cachenotcomplete&amp;lt;/code&amp;gt;)&amp;lt;br&amp;gt; 6. Path directory of the media of the first preload&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw/keystone info &amp;lt;/code&amp;gt;||  1. Active keystone element index &amp;lt;br&amp;gt; 2. Name of active keystone element&amp;lt;br&amp;gt; 3. Amount of total keystone elements &amp;lt;br&amp;gt; 4. Names of  keystone elements separated by commas &amp;lt;br&amp;gt; 5. Active softedge index &amp;lt;br&amp;gt; 6. Name of active softedge &amp;lt;br&amp;gt; 7. Amount of total softedges &amp;lt;br&amp;gt; 8. Names of softedges separated by commas &amp;lt;br&amp;gt; 9. Active grabber element index &amp;lt;br&amp;gt; 10. Name of active grabber element&amp;lt;br&amp;gt; 11. Amount of total grabber elements &amp;lt;br&amp;gt; 12. Names of  grabber elements separated by commas &amp;lt;br&amp;gt; 13. Active blacklevel element index &amp;lt;br&amp;gt; 14. Name of active blacklevel element&amp;lt;br&amp;gt; 15. Amount of total blacklevel elements &amp;lt;br&amp;gt; 16. Names of  blacklevel elements separated by commas&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw/keystone/element/1 info &amp;lt;/code&amp;gt;|| 1. Element name &amp;lt;br&amp;gt; 2. Element type &amp;lt;br&amp;gt; 3. Video track number &amp;lt;br&amp;gt; 4. Video layer number &amp;lt;br&amp;gt; 5. Precision &amp;lt;br&amp;gt; 6. Number of pivots x &amp;lt;br&amp;gt;  7. Number of pivots y &amp;lt;br&amp;gt; 8. Scale &amp;lt;br&amp;gt; 9. Opacity &amp;lt;br&amp;gt; 10. Rotation of element number 1&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/keystone/element/1/pivot/col/1/row/1 info &amp;lt;/code&amp;gt;|| 1. Pivot translation x &amp;lt;br&amp;gt; 2. Translation y  &amp;lt;br&amp;gt; 3. Translation z &amp;lt;br&amp;gt; 4. UV value x  &amp;lt;br&amp;gt; 5. UV values y &amp;lt;br&amp;gt; 6. UV normalized x  &amp;lt;br&amp;gt; 7. UV normalized y &amp;lt;br&amp;gt; 8. RGB COLOUR&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw/layermanager info&amp;lt;/code&amp;gt;|| 1. Active layer index &amp;lt;br&amp;gt; 2. Name of active layer  &amp;lt;br&amp;gt; 3. Amount of total layers &amp;lt;br&amp;gt; 4. Names of layers separated by commas&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw/set info&amp;lt;/code&amp;gt; || 1. Active patch index &amp;lt;br&amp;gt; 2. Name of active patch &amp;lt;br&amp;gt; 3. Amount of total patches &amp;lt;br&amp;gt; 4. Names of patches separated by commas&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw/trackmanager info&amp;lt;/code&amp;gt;||  1. Active track index &amp;lt;br&amp;gt; 2. Name of active track&amp;lt;br&amp;gt; 3. Amount of total tracks &amp;lt;br&amp;gt; 4. Names of tracks separated by commas&lt;br /&gt;
|-&lt;br /&gt;
| Addresses of Drop-down Boxes and Combo Boxes in MXW &amp;lt;br&amp;gt;(e.g.  &amp;lt;code&amp;gt;mxw/render/effect info&amp;lt;/code&amp;gt;)|| 1. Index and Name of currently selected item &amp;lt;br&amp;gt; 2. Amount of total items &amp;lt;br&amp;gt; 3. Names of items separated by commas&lt;br /&gt;
|-&lt;br /&gt;
| Addresses of Faders in MXW &amp;lt;br&amp;gt;(e.g. &amp;lt;code&amp;gt;mxw/render/opacity info&amp;lt;/code&amp;gt; )|| 1. Value of position of fader (&amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| Addresses of Buttons/Checkboxes in MXW &amp;lt;br&amp;gt;(e.g. &amp;lt;code&amp;gt;mxw/track/1/crossfade info&amp;lt;/code&amp;gt;)|| 1. State of the widget (&amp;lt;code&amp;gt;0 = released/OFF , 1 = pressed/ON&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot; | NOTE: The token &amp;lt;code&amp;gt;active&amp;lt;/code&amp;gt; can be substituted with an integer corresponding to the index of the wished element&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As an example, if we send:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/playlist/container/active info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MXWendler will reply:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mxw/reply /mxw/playlist/container/active &amp;amp;emsp;&amp;amp;emsp;&amp;amp;emsp;&amp;amp;emsp;&amp;amp;emsp; 980451 &amp;amp;emsp;&amp;amp;emsp;&amp;amp;emsp;0 &amp;amp;emsp;&amp;amp;emsp;&amp;amp;emsp;&amp;amp;ensp;3 &amp;amp;emsp;&amp;amp;emsp; &amp;amp;emsp; 20&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
 Reply Message    Address of Request           Time    Index  Col.   Row&lt;br /&gt;
&lt;br /&gt;
====select====&lt;br /&gt;
The token select can be added to different addresses to select the single elements on a list of many using a string. This command is can be used in combination with the token &amp;lt;code&amp;gt;info&amp;lt;/code&amp;gt; as the names of the elements can be recalled with &amp;lt;code&amp;gt;info&amp;lt;/code&amp;gt; first and then selected with the &amp;lt;code&amp;gt;select&amp;lt;/code&amp;gt; token. &lt;br /&gt;
The receivers that respond with the token select are:&lt;br /&gt;
* trackmanager&lt;br /&gt;
* layermanager&lt;br /&gt;
* combo-boxes&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/trackmanager select track2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====active====&lt;br /&gt;
The token active is used in the receiver address and can be used in multiple situations to act on the selected element of a list. For example the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/track/active/fader 0.5&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will move the fader of the selected (active) track to his middle position, setting its opacity to 50%.&lt;br /&gt;
&lt;br /&gt;
====preview====&lt;br /&gt;
The string preview can be used to get in return an OSC blob, containing a 128x128px &#039;&#039;&#039;jpg&#039;&#039;&#039; file that is a preview of the currently played media or a thumbnail of the selected clip. Here are the available addresses for a preview:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! NAME !! ADDRESS&lt;br /&gt;
|-&lt;br /&gt;
| Render || &amp;lt;code&amp;gt;/mxw/render preview&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Track || &amp;lt;code&amp;gt;/mxw/track/active preview&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Layer || &amp;lt;code&amp;gt;/mxw/track/active/layer/active preview&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Clip || &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip preview&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Preload || &amp;lt;code&amp;gt;/mxw/preload/&amp;quot;preload index&amp;quot; preview&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;/mxw/preload/7 preview&amp;lt;/code&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| Patch/Set || &amp;lt;code&amp;gt;/mxw/patch/&amp;quot;patch index&amp;quot; preview&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; E.G.&amp;lt;code&amp;gt;/mxw/patch/3 preview&amp;lt;/code&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot; | NOTE: The token &amp;lt;code&amp;gt;active&amp;lt;/code&amp;gt; can be substituted with an integer corresponding to the index of the wished element&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====clear====&lt;br /&gt;
&lt;br /&gt;
The function clear can be sent to the preloads to empty one of the preload spaces.&lt;br /&gt;
&lt;br /&gt;
E.G. &amp;lt;code&amp;gt;mxw/preload/1 clear&amp;lt;/code&amp;gt; will clear the first preload slot.&lt;br /&gt;
&lt;br /&gt;
=== Message-ID ===&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
The “Message-ID”  allows for clear communication and categorization of replies. When a command that generates a reply is sent, it is possible to prepend the command with a  “Message-ID” which will be then in the reply as well. This message must have the format &amp;lt;code&amp;gt; MSGIDXXXX &amp;lt;/code&amp;gt; and it must follow the OSC address like in the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/preload/3 MSGID0123 info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will return a reply similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/reply MSGID0123 /mxw/preload/3 112 320 240 40 cachecomplete c:\footage\clip.avi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2.2 Examples ==&lt;br /&gt;
To address the main fader and fade the opacity of the render from zero to full in ten steps, you would send a command sequence:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/render 0.0&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/render 0.1&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/render 0.2&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/render 0.3&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/render 0.4&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/render 0.5&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/render 0.6&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/render 0.7&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/render 0.8&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/render 0.9&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/render 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finer-grained values can be sent if needed. The commands will be evaluated as soon as they arrive in MXW and the last command before a new frame is drawn will set the widget&#039;s value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/track/active 0.5&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Sets the active track opacity to 0.5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/track/1 0.5&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Sets track 1 opacity to 0.5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/preload/1/trigger 1.0&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Adds a layer with the contents of preload slot 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/track/1/layer/1/opacity 0.5&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Sets the opacity of the first layer of the first track to 0.5 (if there is a layer playing content)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/set 5&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;The active track will load patch 5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/speed 0.6&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Sets the speed of the clip of the active layer of the active track to 1.0 (0.6 translates to 1.0 in a -5 .. +5 range)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/speed 0.5&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Sets the speed of the clip of the active layer of the active track to 0.5 (clip stops)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/trackmanager 1&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Activate the first track&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/trackmanager 3&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Activate the third track&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/trackmanager select track3&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Activate the third track&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/track/2/layer/1/clip/effect/2 select ag_AnimWarp&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Instructs the clip of the first layer of the second track to load the effect with the name &amp;quot;ag_AnimWarp&amp;quot; in the effect slot number 2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/track/2/layer/1/clip/effect/1/param/1 0.8&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Set to the value of 0.8, the parameter 1 of the first effect of the clip of the first layer of the second track &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/preload/2 c:/footage/clip.avi&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Preload slot 2 will load c:/footage/clip.avi (and answer with info). Note the direction of the slashes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/preload/2 clear&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Preload slot 2 will unload&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/preload/2 info&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Preload 2 will answer with clip info like  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/reply /mxw/preload/3 112 320 240 40 cachecomplete &lt;br /&gt;
c:\footage\clip.avi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/preload/2 MSGID0123 info&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Preload 2 will answer with clip info like &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/reply MSGID0123 /mxw/preload/3 112 320 240 40 cachecomplete c:\footage\clip.avi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/master/load_showfile c:/footage/showfile.mxw&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Load the stated showfile&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/master/load_keystonefile c:/footage/keystonefile.mxw_keystone2&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;Load the stated keystonefile&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Controlling_MXW_through_OSC&amp;diff=6192</id>
		<title>Controlling MXW through OSC</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Controlling_MXW_through_OSC&amp;diff=6192"/>
		<updated>2026-08-08T19:04:11Z</updated>

		<summary type="html">&lt;p&gt;Admin: Admin moved page 1. Controlling MXW through OSC to Controlling MXW through OSC: Remove leading index prefix from title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
MXW is designed to be a high-performance real-time video software for media servers. It interactively composites high-resolution footage and interactive media.&lt;br /&gt;
OSC commands can be generated, sent, and received by MXWendler and a wide range of applications: signaling frameworks like Pure Data, Max/MSP,  TouchOSC, and TouchDesigner, audio workstations like Ableton Live, Logic, or Protools,  programming environments like Processing, Perl, Java, Unity, and TidalCycles, other Multimedia, Sensoring, Signal Processing software, Microcontrollers and many more, offering a compatible and fast intercommunication method. &lt;br /&gt;
&lt;br /&gt;
Separating the media server from the controlling infrastructure offers various creative and usability options: &lt;br /&gt;
&lt;br /&gt;
*Control multiple machines from one single point&lt;br /&gt;
*Control a single machine from multiple points&lt;br /&gt;
*Replicate a state into a remote system&lt;br /&gt;
*Custom user interfaces&lt;br /&gt;
*Intercommunication with external software and platforms&lt;br /&gt;
*Control via WAN&lt;br /&gt;
*Control via a microcontroller&lt;br /&gt;
*Connect scene-analysis with scene-composition systems&lt;br /&gt;
*Extract control features e.g mapping or triggering&lt;br /&gt;
      &lt;br /&gt;
&amp;lt;div class=&amp;quot;noprint&amp;quot;&amp;gt;&lt;br /&gt;
== 1.1 Receiving OSC commands in MXW ==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To enable OSC receiving open the software MXWendler: &amp;lt;br&amp;gt;&lt;br /&gt;
1. In  &#039;&#039;&#039;Menu: Settings &amp;amp;rarr; Input and Output &#039;&#039;(CTRL+1)&#039;&#039; &amp;amp;rarr;&#039;&#039;&#039; in the tab  &#039;&#039;&#039;OSC&#039;&#039;&#039;,  activate the box &#039;&#039;&#039;Receive OSC&#039;&#039;&#039; ( &#039;&#039;&#039;(A)&#039;&#039;&#039; In the following picture) &amp;lt;br&amp;gt;&lt;br /&gt;
2. Set the port ( 7000 is recommended as an OSC Standard)  &amp;lt;br&amp;gt;&lt;br /&gt;
3. The box &#039;&#039;&#039;Log received data&#039;&#039;&#039; will log commands in the Error and Log Window visible through &#039;&#039;&#039;Menu: Settings &amp;amp;rarr; Error and Log Window &#039;&#039;(CTRL+SHFT+L)&#039;&#039; &#039;&#039;&#039; &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is particularly useful for testing and troubleshooting as it will make visible what OSC commands are received by MXW. The logging of data has a performance impact on the system so it is important to turn it off when not in use.&lt;br /&gt;
As this option is marked (r) in the menu, to activate the changes, please restart the software.&lt;br /&gt;
&amp;lt;div class=&amp;quot;noprint&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 1.2 Output OSC from MXW: Send vs. Reply ==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
MXW can send OSC commands as well. Multiple distinct options are available in &#039;&#039;&#039;Menu: Settings &amp;amp;rarr; Input and Output &#039;&#039;(CTRL+1)&#039;&#039; &amp;amp;rarr;&#039;&#039;&#039; tab &#039;&#039;&#039;OSC&#039;&#039;&#039; : &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:mxwIO.png|728px]]&lt;br /&gt;
&lt;br /&gt;
{{#mpdftags: pagebreak}}&lt;br /&gt;
&lt;br /&gt;
=== Broadcast and Receive Time over OSC &#039;&#039;&#039;(B)&#039;&#039;&#039; === &lt;br /&gt;
This option will broadcast the MXW time into the selected subnet to synchronize the time among a pool of machines.&lt;br /&gt;
To achieve this a selection mechanism is applied: every machine sends its time until it receives the time from a machine with a lower IP address. In the end, the machine with the lowest IP is selected as the &#039;master&#039; and controls the pool clock.&lt;br /&gt;
IO Events can be forwarded by selecting the relative checkbox. You can for example connect a MIDI device and it will send the MIDI events to the pool.&lt;br /&gt;
&lt;br /&gt;
=== Receive OSC over RS232 &#039;&#039;&#039;(C)&#039;&#039;&#039; ===&lt;br /&gt;
Check this box if the OSC commands are received through a Serial Port instead of a network port. Options for port selection and integer indexing are available.&lt;br /&gt;
&lt;br /&gt;
=== Send OSC &#039;&#039;&#039;(D)&#039;&#039;&#039; ===&lt;br /&gt;
This option will send any action on the running host to another host/network defined in the command options. Moving a track slider will generate the commands that make the track slider in the remote machine move to the same position. The goal is to make another machine (pretended it carries the same media data) produce exactly the same result as the master machine by sending osc commands to replicate the same behaviour.&lt;br /&gt;
Sometimes it is desireable to send only a selction of the generated actions. You can filter the sent commands using the following rules:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
- Adding a + before a *token*, [comment(optional)]&amp;lt;br&amp;gt;&lt;br /&gt;
- Adding a - before a token*, [comment(optional)]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The *token* is a part of the string like &amp;quot;playlist&amp;quot; or &amp;quot;opacity&amp;quot;, a comment can be added after a comma in case we want to specify the reason of the filter. So adding the line &amp;lt;code&amp;gt;+,*playlist*&amp;lt;/code&amp;gt;  will result into that only commands containing the keyword &amp;quot;playlist&amp;quot; will be sent. In the same way using the filter &amp;lt;code&amp;gt;-,*opacity*, opacity_does_not_change&amp;lt;/code&amp;gt; any command referring to &amp;quot;opacity&amp;quot; will not be sent through and everything else will.&lt;br /&gt;
&lt;br /&gt;
=== OSC reply channel &#039;&#039;&#039;(E)&#039;&#039;&#039; ===&lt;br /&gt;
Many OSC commands are capable of asking for specific information e.g. the name of a clip in the preload or the playback status of the playlist. This option must be active in MXW to allow the software to reply to the received OSC commands.  Options for a specific IP address of the host/subnet and Port are given in the settings.  The last checkbox “Send periodical livesigns” allows to receive a constant periodical flow of data from MXW regarding performance and render information, useful as well for diagnostic reasons.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=OSC_Reference&amp;diff=6191</id>
		<title>OSC Reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=OSC_Reference&amp;diff=6191"/>
		<updated>2026-08-08T19:02:08Z</updated>

		<summary type="html">&lt;p&gt;Admin: Remove useless &amp;#039;6. External links&amp;#039; entry from contents (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This reference applies to all different OS. The presented OSC commands are for most part supported in version 6.0 but will be fully functional in version 6.0.08 and above. &lt;br /&gt;
&amp;lt;div class=&amp;quot;noprint&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
This document describes the MXWendler (MXW) OSC Command Interface through an overview of the command structure and practical examples of integration with external controlling software. &lt;br /&gt;
&lt;br /&gt;
== What is OSC? ==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
OSC or „Open Sound Control“ is a Network-based protocol that commonly utilizes the UDP transport mechanism. Originally developed as a successor of the MIDI control protocol, it used nowadays as a practical communication method between platforms.&lt;br /&gt;
&lt;br /&gt;
OSC Features:&lt;br /&gt;
* Connectionless communication architecture&lt;br /&gt;
* Broadcast-type messages&lt;br /&gt;
* High resolution time tag&lt;br /&gt;
* Allowed data formats including numeric, symbolic, and “blob” arguments&lt;br /&gt;
* Open-ended, dynamic, URL-style naming scheme for the receivers&#039; address&lt;br /&gt;
      &lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/Open_Sound_Control [1&amp;lt;nowiki&amp;gt;]&amp;lt;/nowiki&amp;gt; Wikipedia Link]&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px&amp;quot; | [[1. Controlling MXW through OSC]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;1.1 Receiving OSC commands in MXW&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px 10px&amp;quot; | &#039;&#039;1.2 Output OSC from MXW: Send vs. Reply&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px 0px&amp;quot; | [[2. MXW OSC command structure]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;2.1 Sending OSC Values&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;2.2 Examples&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[OSC command reference]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding:  10px&amp;quot; | [[5. Troubleshooting]] &lt;br /&gt;
|}&lt;br /&gt;
[[Category:OSC]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=OSC_Reference&amp;diff=6190</id>
		<title>OSC Reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=OSC_Reference&amp;diff=6190"/>
		<updated>2026-08-08T19:00:26Z</updated>

		<summary type="html">&lt;p&gt;Admin: Remove outdated &amp;#039;Practical examples: Pure Data and TouchOSC&amp;#039; entry from contents (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This reference applies to all different OS. The presented OSC commands are for most part supported in version 6.0 but will be fully functional in version 6.0.08 and above. &lt;br /&gt;
&amp;lt;div class=&amp;quot;noprint&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
This document describes the MXWendler (MXW) OSC Command Interface through an overview of the command structure and practical examples of integration with external controlling software. &lt;br /&gt;
&lt;br /&gt;
== What is OSC? ==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
OSC or „Open Sound Control“ is a Network-based protocol that commonly utilizes the UDP transport mechanism. Originally developed as a successor of the MIDI control protocol, it used nowadays as a practical communication method between platforms.&lt;br /&gt;
&lt;br /&gt;
OSC Features:&lt;br /&gt;
* Connectionless communication architecture&lt;br /&gt;
* Broadcast-type messages&lt;br /&gt;
* High resolution time tag&lt;br /&gt;
* Allowed data formats including numeric, symbolic, and “blob” arguments&lt;br /&gt;
* Open-ended, dynamic, URL-style naming scheme for the receivers&#039; address&lt;br /&gt;
      &lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/Open_Sound_Control [1&amp;lt;nowiki&amp;gt;]&amp;lt;/nowiki&amp;gt; Wikipedia Link]&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px&amp;quot; | [[1. Controlling MXW through OSC]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;1.1 Receiving OSC commands in MXW&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px 10px&amp;quot; | &#039;&#039;1.2 Output OSC from MXW: Send vs. Reply&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px 0px&amp;quot; | [[2. MXW OSC command structure]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;2.1 Sending OSC Values&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;2.2 Examples&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[OSC command reference]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding:  10px&amp;quot; | [[5. Troubleshooting]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[6. External links]]&lt;br /&gt;
|}&lt;br /&gt;
[[Category:OSC]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Python_Reference&amp;diff=6189</id>
		<title>Python Reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Python_Reference&amp;diff=6189"/>
		<updated>2026-08-08T18:58:04Z</updated>

		<summary type="html">&lt;p&gt;Admin: Point TOC to de-numbered &amp;#039;Controlling MXW through Python&amp;#039;; drop index prefixes (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
This document describes the MXWendler (MXW) Python command interface through an overview of the programming structure, with practical examples of automation and internal scripting. The presented Python commands are for most part supported in version 7.2.&lt;br /&gt;
&lt;br /&gt;
== What is Python? ==&lt;br /&gt;
Python is a standardized interpreted, high level programming language. It is used in many applications, mainly in AI and generative tasks. The amount of available libraries is outstanding.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[Controlling MXW through Python]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[Python command reference]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[Python imgui reference]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[Python plugin reference]] &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
[[Category:Python]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Controlling_MXW_through_Python&amp;diff=6187</id>
		<title>Controlling MXW through Python</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Controlling_MXW_through_Python&amp;diff=6187"/>
		<updated>2026-08-08T18:58:03Z</updated>

		<summary type="html">&lt;p&gt;Admin: Admin moved page 1. Controlling MXW through Python to Controlling MXW through Python: Remove leading index prefix from title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- MXWendler wiki page: Controlling MXW through Python (overview / hub) --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Intended location: https://wiki.mxwendler.net/index.php?title=1._Controlling_MXW_through_Python --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_command_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_imgui_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_plugin_reference --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MXWendler StageDesigner embeds &#039;&#039;&#039;Python 3.12&#039;&#039;&#039;. Python is used in two ways:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Command interface / scripting&#039;&#039;&#039; &amp;amp;ndash; the module &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt; controls the running software (playlist, layers, clips, media, I/O, widgets by their address, ...) from the script console or from within a plugin.&lt;br /&gt;
* &#039;&#039;&#039;Plugins&#039;&#039;&#039; &amp;amp;ndash; self-contained folders that add a media source or a playlist item and are called back by the host through a defined set of functions (&#039;&#039;hooks&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The presented Python interface is supported in version 7.2. and up&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Where to go ==&lt;br /&gt;
&lt;br /&gt;
The detailed documentation lives on three dedicated pages; this page only points to them so nothing is documented twice.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Topic !! Page&lt;br /&gt;
|-&lt;br /&gt;
| The &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt; command interface &amp;amp;ndash; software info, &amp;lt;code&amp;gt;playlist&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;io&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;widget(address)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;media(name)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;preload(n)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grabber(name)&amp;lt;/code&amp;gt; || [[Python command reference|Python command reference]]&lt;br /&gt;
|-&lt;br /&gt;
| Drawing plugin settings panels with &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt; (MXWendler&#039;s Dear ImGui binding) || [[Python imgui reference|Python ImGui reference]]&lt;br /&gt;
|-&lt;br /&gt;
| Writing &#039;&#039;&#039;plugins&#039;&#039;&#039; &amp;amp;ndash; media and playlist &amp;amp;ndash; the manifest (&amp;lt;code&amp;gt;mxw_plugin.ini&amp;lt;/code&amp;gt;), the hooks, per-instance state, examples || [[Python plugin reference|Python plugin reference]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Quick start ==&lt;br /&gt;
&lt;br /&gt;
A minimal look at each entry point; follow the links above for the full reference.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Scripting.&#039;&#039;&#039; From the script console (or any hook), the &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt; module reaches the software:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot; line&amp;gt;&lt;br /&gt;
import mxw&lt;br /&gt;
mxw.print_console(&amp;quot;frame &amp;quot; + str(mxw.framecounter))&lt;br /&gt;
mxw.playlist.play()&lt;br /&gt;
mxw.widget(&amp;quot;/mxw/track/active/layer/active/opacity&amp;quot;).setValue(0.5)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Plugins.&#039;&#039;&#039; A plugin is a folder holding a manifest and a Python module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
plugins/playlist/python/plugin_my_item/&lt;br /&gt;
    mxw_plugin.ini      the manifest: identity, menu entries&lt;br /&gt;
    mxw_main.py         the Python module with the hook functions&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The host discovers it at startup, shows it in the user interface and calls its hooks at the right moments. See the [[Python plugin reference|Python plugin reference]] for the manifest fields, the full hook list for media and playlist plugins, plugin locations, installing extra packages with &amp;lt;code&amp;gt;mxw-pip&amp;lt;/code&amp;gt;, and complete examples.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Python command reference|Python command reference]] &amp;amp;ndash; the &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt; module&lt;br /&gt;
* [[Python imgui reference|Python ImGui reference]] &amp;amp;ndash; drawing plugin panels with &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt;&lt;br /&gt;
* [[Python plugin reference|Python plugin reference]] &amp;amp;ndash; writing media and playlist plugins&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=JavaScript_Reference&amp;diff=6186</id>
		<title>JavaScript Reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=JavaScript_Reference&amp;diff=6186"/>
		<updated>2026-08-08T18:51:36Z</updated>

		<summary type="html">&lt;p&gt;Admin: Point TOC to de-numbered page titles; drop index prefixes (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This reference applies to all different OS. The presented OSC commands are for most part supported in version 6.0 but will be fully functional in version 6.0.08 and above.&lt;br /&gt;
&amp;lt;div class=&amp;quot;noprint&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
This document describes the MXWendler (MXW) JavaScript Command Interface through an overview of the programming structure, with practical examples of automation and internal scripting.&lt;br /&gt;
&lt;br /&gt;
== What is JavaScript? ==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
JavaScript is a standardized interpreted, high level programming language. It is one of the core technologies of the World Wide Web and it is mainly used in web browsers to control web pages and test the user input before sending it.&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/JavaScript[1&amp;lt;nowiki&amp;gt;]&amp;lt;/nowiki&amp;gt; Wikipedia Link]&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[Controlling MXW through JavaScript]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[JavaScript command reference]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[Practical examples]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[Troubleshooting scripts]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[External Resources]]&lt;br /&gt;
|}&lt;br /&gt;
[[Category:JavaScript]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=External_Resources&amp;diff=6184</id>
		<title>External Resources</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=External_Resources&amp;diff=6184"/>
		<updated>2026-08-08T18:51:22Z</updated>

		<summary type="html">&lt;p&gt;Admin: Admin moved page 6. External Resources to External Resources: Remove leading index prefix from title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;/br&amp;gt;&lt;br /&gt;
1 https://en.wikipedia.org/wiki/JavaScript&amp;lt;/br&amp;gt;&lt;br /&gt;
2 https://developer.mozilla.org/en-US/docs/Web/JavaScript &amp;lt;/br&amp;gt;&lt;br /&gt;
3 https://curlie.org/Computers/Programming/Languages/JavaScript/ &amp;lt;/br&amp;gt;&lt;br /&gt;
4 https://duktape.org/index.html &amp;lt;/br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Troubleshooting_scripts&amp;diff=6182</id>
		<title>Troubleshooting scripts</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Troubleshooting_scripts&amp;diff=6182"/>
		<updated>2026-08-08T18:51:21Z</updated>

		<summary type="html">&lt;p&gt;Admin: Admin moved page 5. Troubleshooting scripts to Troubleshooting scripts: Remove leading index prefix from title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&#039;&#039;&#039;Problem&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
JavaScript is not functioning as intended. No corresponding action happens when the trigger button for the event is pressed. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hints&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Open the JavaScript console by pressing Ctrl+Shift+J (Mac:Command+Shift+J) and look for error messages.&lt;br /&gt;
# Check for syntax errors in your code and ensure that interface functions are written correctly.&lt;br /&gt;
# Check that predefined hooks and functions like e.g. on_trigger() are written correctly. Syntax highlighting and coloring may help you identify these issues.&lt;br /&gt;
# When resolving widgets, verify the used widgets address (e.g. &amp;quot;/mxw/render/opacity&amp;quot;) and make sure that it is valid. To find the correct address, maybe refer to the list of address suggestions available in the &#039;Receiver&#039; menu.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Practical_examples&amp;diff=6180</id>
		<title>Practical examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Practical_examples&amp;diff=6180"/>
		<updated>2026-08-08T18:51:19Z</updated>

		<summary type="html">&lt;p&gt;Admin: Admin moved page 4. Practical examples to Practical examples: Remove leading index prefix from title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Download the Javascript Reference folder from https://www.mxwendler.net/de/downloads.html&lt;br /&gt;
&lt;br /&gt;
1) 	Double click on the &amp;quot;js-demo.mxw&amp;quot; to load the demo.&amp;lt;div&amp;gt; &lt;br /&gt;
	&lt;br /&gt;
2) 	Open the I/O Settings Window (CTRL+1) or  click on &amp;quot;Settings&amp;quot; → &amp;quot;Inputs and Outputs - Keyboard, Midi, DMX&amp;quot; &amp;lt;div&amp;gt; &lt;br /&gt;
&amp;amp;emsp; and click on SHOW JAVASCRIPT CONSOLE, almost at the bottom of the I/O window.&lt;br /&gt;
&lt;br /&gt;
3)	Follow the instructions on the Javascript Console. &amp;lt;div&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Commands:===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remember to click on the interface header before giving commands,&lt;br /&gt;
the operating System needs to know where the keyboard signals are directed.&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;code&amp;gt;backspace&amp;lt;/code&amp;gt;	starts the patch and selects the LiveEditor Tab.	&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
	&amp;lt;code&amp;gt;spacebar&amp;lt;/code&amp;gt; 	(6 times at least) to set up a tap tempo&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
	&amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; 	Sets the render opacity to 0&lt;br /&gt;
&amp;lt;div&amp;gt;	&lt;br /&gt;
	&amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; 	Sets the render opacity to 0.5&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
	&amp;lt;code&amp;gt;3&amp;lt;/code&amp;gt;  Sets the render opacity to 1&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
	&amp;lt;code&amp;gt;4&amp;lt;/code&amp;gt;  Writes Output informations on the Javascript console.&lt;br /&gt;
			        Takes a screenshot of the output and saves it in &amp;quot;C:\screen&amp;quot;&lt;br /&gt;
			        (if the directory already exists)&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Controlling_MXW_through_JavaScript&amp;diff=6178</id>
		<title>Controlling MXW through JavaScript</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Controlling_MXW_through_JavaScript&amp;diff=6178"/>
		<updated>2026-08-08T18:51:18Z</updated>

		<summary type="html">&lt;p&gt;Admin: Admin moved page 1. Controlling MXW through JavaScript to Controlling MXW through JavaScript: Remove leading index prefix from title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Although there are many ways to control MXWendler with a lot of I/O devices, e.g.  mouse buttons, keyboard, DMX and MIDI devices, and automation commands in MXWendler using events in the playlist, some desired behaviours are too complex to be offered through a GUI element. &lt;br /&gt;
JavaScript allows instead to script any animation and behaviour sequence. Additionally, JavaScript allows you to emit values to I/O devices like DMX, OSC or MIDI and set various internal variables in media and in the software.&lt;br /&gt;
&lt;br /&gt;
The JavaScript engine used by the MXWendler scripting is Duktape, standardized under ECMAScript E5/E5.1. (more info at the Duktape [https://duktape.org/index.html website])&lt;br /&gt;
&lt;br /&gt;
To write JavaScripts open MXWendler &amp;quot;StageDesigner&amp;quot; or &amp;quot;FxServer&amp;quot; and access the editor by clicking &amp;quot;Settings&amp;quot; &amp;amp;rarr; &amp;quot;Inputs and Outputs - Keyboard, Midi, DMX&amp;quot; (or with the hotkey &amp;lt;code&amp;gt;CTRL + 1&amp;lt;/code&amp;gt;) &lt;br /&gt;
&amp;lt;div&amp;gt; &lt;br /&gt;
&lt;br /&gt;
[[File:Open settings.jpeg|728px]]&lt;br /&gt;
{{#mpdftags: pagebreak}}&lt;br /&gt;
&amp;lt;div&amp;gt; &lt;br /&gt;
On the window, in the first tab (&amp;quot;DMX/Midi/Keyboard Events&amp;quot;) the editor is available in the lower right corner.&lt;br /&gt;
&amp;lt;div&amp;gt; &lt;br /&gt;
&lt;br /&gt;
[[File:Editor.jpeg|728px]]&lt;br /&gt;
{{#mpdftags: pagebreak}}&lt;br /&gt;
&amp;lt;div&amp;gt; &lt;br /&gt;
&lt;br /&gt;
To facilitate debugging, a script-wide function &amp;quot;print_console&amp;quot; is available and the Javascript console is available to be opened from either the checkbox under the editor, or from the menu: &amp;quot;Settings&amp;quot; &amp;amp;rarr; &amp;quot;Open Javascript Console&amp;quot; (&amp;lt;code&amp;gt;CTRL + J&amp;lt;/code&amp;gt;)&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Python_imgui_reference&amp;diff=6177</id>
		<title>Python imgui reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Python_imgui_reference&amp;diff=6177"/>
		<updated>2026-08-08T18:00:10Z</updated>

		<summary type="html">&lt;p&gt;Admin: Fix example (mxw.print_console) and repoint broken Python Plugin Howto link (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- MXWendler wiki page: Python mxw_imgui command reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Intended location: https://wiki.mxwendler.net/index.php?title=Python_ImGui_Reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_Reference (the mxw module) --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_plugin_reference --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here are listed the commands available in module &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt;, MXWendler&#039;s Python binding of &#039;&#039;&#039;Dear ImGui&#039;&#039;&#039;. This is how plugins draw their settings panel, in the &amp;lt;code&amp;gt;onRenderPanel()&amp;lt;/code&amp;gt; hook (see the [[Python plugin reference|Python plugin reference]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt; mirrors the Dear ImGui C++ API almost function-for-function: the C++ &amp;lt;code&amp;gt;ImGui::PascalCase&amp;lt;/code&amp;gt; names become Python &amp;lt;code&amp;gt;snake_case&amp;lt;/code&amp;gt;, one argument at a time. If you already know Dear ImGui (or its C++/other-language bindings), the name of a call is usually a mechanical translation away.&lt;br /&gt;
&lt;br /&gt;
=== Legend ===&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Everything from the [[Python_Reference|Python Reference]] Legend applies (floats, integers, strings, &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; for alternative formats). In addition:&lt;br /&gt;
&lt;br /&gt;
Dear ImGui widgets that take a pointer to their value in C++ (so the value can be written back) instead return a &#039;&#039;&#039;tuple&#039;&#039;&#039; &amp;lt;code&amp;gt;(changed, value)&amp;lt;/code&amp;gt; in Python: &amp;lt;code&amp;gt;changed&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; when the user edited the widget this frame, &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt; is the (possibly new) value to keep and pass back in next frame. E.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;changed, value = mxw_imgui.slider_float(&amp;quot;Speed&amp;quot;, value, 0.0, 1.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Widgets with several packed floats/ints (&amp;lt;code&amp;gt;drag_float2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;slider_int4&amp;lt;/code&amp;gt;, ...) take and return a plain Python list/tuple of that length instead of a C array.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Flags&#039;&#039;&#039; (&amp;lt;code&amp;gt;ImGuiTreeNodeFlags&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ImGuiWindowFlags&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ImGuiCol&amp;lt;/code&amp;gt;, ...) are &#039;&#039;&#039;not&#039;&#039;&#039; exposed as named Python constants — pass the plain integer value of the Dear ImGui enum (default &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; means &amp;quot;no flags&amp;quot; for nearly every call). Consult the Dear ImGui headers/docs for the numeric values if you need non-default flags.&lt;br /&gt;
&lt;br /&gt;
Parameters shown as &amp;lt;code&amp;gt;= value&amp;lt;/code&amp;gt; in the tables below are &#039;&#039;&#039;optional&#039;&#039;&#039; with that default; omit them to use the default.&lt;br /&gt;
&lt;br /&gt;
Plugins draw &#039;&#039;&#039;into an existing panel&#039;&#039;&#039; — there is no &amp;lt;code&amp;gt;begin&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; for top-level windows; start directly with widget calls.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data types ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON TYPE !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.Vec2()&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.Vec2(x, y)&amp;lt;/code&amp;gt; || 2D float vector (&amp;lt;code&amp;gt;.x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;.y&amp;lt;/code&amp;gt;), used for sizes and positions || &amp;lt;code&amp;gt;size = mxw_imgui.Vec2(200, 0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.Vec4()&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.Vec4(x, y, z, w)&amp;lt;/code&amp;gt; || 4D float vector (&amp;lt;code&amp;gt;.x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;.y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;.z&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;.w&amp;lt;/code&amp;gt;), used for colors (RGBA) and rectangles || &amp;lt;code&amp;gt;col = mxw_imgui.Vec4(1.0, 0.0, 0.0, 1.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.Vector_char&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Vector_float&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Vector_unsignedchar&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Vector_unsignedshort&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Vector_DrawCmd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Vector_DrawVert&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Vector_FontGlyph&amp;lt;/code&amp;gt; || Read-only iterable wrappers around Dear ImGui&#039;s internal &amp;lt;code&amp;gt;ImVector&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; buffers, returned by some getters (e.g. draw list data). Support &amp;lt;code&amp;gt;len()&amp;lt;/code&amp;gt;, iteration and indexing || &amp;lt;code&amp;gt;for glyph in font.Glyphs: pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Style &amp;amp;amp; Fonts ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_font(font)&amp;lt;/code&amp;gt; || push a font onto the font stack for subsequent widgets || &amp;lt;code&amp;gt;mxw_imgui.push_font(mxw_imgui.get_font())&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_font()&amp;lt;/code&amp;gt; || pop the last pushed font || &amp;lt;code&amp;gt;mxw_imgui.pop_font()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_style_color(idx, col)&amp;lt;/code&amp;gt; || push a style color override (&amp;lt;code&amp;gt;col&amp;lt;/code&amp;gt; as packed &amp;lt;code&amp;gt;u32&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;Vec4&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;mxw_imgui.push_style_color(0, mxw_imgui.Vec4(1,0,0,1))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_style_color(count = 1)&amp;lt;/code&amp;gt; || pop &amp;lt;code&amp;gt;count&amp;lt;/code&amp;gt; previously pushed style colors || &amp;lt;code&amp;gt;mxw_imgui.pop_style_color()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_style_var(idx, val)&amp;lt;/code&amp;gt; || push a style var override (&amp;lt;code&amp;gt;val&amp;lt;/code&amp;gt; as float OR &amp;lt;code&amp;gt;Vec2&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;mxw_imgui.push_style_var(0, 4.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_style_var(count = 1)&amp;lt;/code&amp;gt; || pop &amp;lt;code&amp;gt;count&amp;lt;/code&amp;gt; previously pushed style vars || &amp;lt;code&amp;gt;mxw_imgui.pop_style_var()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_allow_keyboard_focus(allow_keyboard_focus)&amp;lt;/code&amp;gt; || allow/disallow tab-focusing the next widgets || &amp;lt;code&amp;gt;mxw_imgui.push_allow_keyboard_focus(false)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_allow_keyboard_focus()&amp;lt;/code&amp;gt; || pop the keyboard-focus override || &amp;lt;code&amp;gt;mxw_imgui.pop_allow_keyboard_focus()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_button_repeat(repeat)&amp;lt;/code&amp;gt; || make subsequent buttons behave as repeating (held = repeated clicks) || &amp;lt;code&amp;gt;mxw_imgui.push_button_repeat(true)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_button_repeat()&amp;lt;/code&amp;gt; || pop the button-repeat override || &amp;lt;code&amp;gt;mxw_imgui.pop_button_repeat()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_font()&amp;lt;/code&amp;gt; || returns the current font object || &amp;lt;code&amp;gt;f = mxw_imgui.get_font()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_font_size()&amp;lt;/code&amp;gt; || returns the current font size in px || &amp;lt;code&amp;gt;sz = mxw_imgui.get_font_size()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_font_tex_uv_white_pixel()&amp;lt;/code&amp;gt; || returns UV coordinate of a white pixel in the font texture, for custom draw-list use || &amp;lt;code&amp;gt;uv = mxw_imgui.get_font_tex_uv_white_pixel()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_color_u32(idx, alpha_mul = 1.0)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.get_color_u32(col)&amp;lt;/code&amp;gt; || resolve a style color index, a &amp;lt;code&amp;gt;Vec4&amp;lt;/code&amp;gt;, or a packed &amp;lt;code&amp;gt;u32&amp;lt;/code&amp;gt; to a final packed &amp;lt;code&amp;gt;u32&amp;lt;/code&amp;gt; color || &amp;lt;code&amp;gt;c = mxw_imgui.get_color_u32(0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_style_color_vec4(idx)&amp;lt;/code&amp;gt; || returns the raw &amp;lt;code&amp;gt;Vec4&amp;lt;/code&amp;gt; for a style color index || &amp;lt;code&amp;gt;c = mxw_imgui.get_style_color_vec4(0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_style_color_name(idx)&amp;lt;/code&amp;gt; || returns the readable name of a style color index || &amp;lt;code&amp;gt;mxw.print_console(mxw_imgui.get_style_color_name(0))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_color_edit_options(flags)&amp;lt;/code&amp;gt; || set default flags for every subsequent color_edit/color_picker call || &amp;lt;code&amp;gt;mxw_imgui.set_color_edit_options(0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Cursor &amp;amp;amp; Layout ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_item_width(item_width)&amp;lt;/code&amp;gt; || push a fixed width (px, or negative = right-aligned) for subsequent widgets || &amp;lt;code&amp;gt;mxw_imgui.push_item_width(150)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_item_width()&amp;lt;/code&amp;gt; || pop the pushed item width || &amp;lt;code&amp;gt;mxw_imgui.pop_item_width()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_next_item_width(item_width)&amp;lt;/code&amp;gt; || set the width of just the next widget || &amp;lt;code&amp;gt;mxw_imgui.set_next_item_width(300)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.calc_item_width()&amp;lt;/code&amp;gt; || returns the width the next widget would use || &amp;lt;code&amp;gt;w = mxw_imgui.calc_item_width()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_text_wrap_pos(wrap_local_pos_x = 0.0)&amp;lt;/code&amp;gt; || push a word-wrap position (0 = wrap at window edge) for subsequent text || &amp;lt;code&amp;gt;mxw_imgui.push_text_wrap_pos()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_text_wrap_pos()&amp;lt;/code&amp;gt; || pop the pushed wrap position || &amp;lt;code&amp;gt;mxw_imgui.pop_text_wrap_pos()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.separator()&amp;lt;/code&amp;gt; || draw a thin horizontal separator line || &amp;lt;code&amp;gt;mxw_imgui.separator()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.same_line(offset_from_start_x = 0.0, spacing = -1.0)&amp;lt;/code&amp;gt; || keep the next widget on the same line as the previous one || &amp;lt;code&amp;gt;mxw_imgui.same_line()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.new_line()&amp;lt;/code&amp;gt; || force a following widget to start on a new line || &amp;lt;code&amp;gt;mxw_imgui.new_line()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.spacing()&amp;lt;/code&amp;gt; || add vertical spacing || &amp;lt;code&amp;gt;mxw_imgui.spacing()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.dummy(size)&amp;lt;/code&amp;gt; || reserve an empty invisible &amp;lt;code&amp;gt;size&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;Vec2&amp;lt;/code&amp;gt;) area, e.g. as a spacer || &amp;lt;code&amp;gt;mxw_imgui.dummy(mxw_imgui.Vec2(0, 10))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.indent(indent_w = 0.0)&amp;lt;/code&amp;gt; || move the cursor right (indent) || &amp;lt;code&amp;gt;mxw_imgui.indent()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.unindent(indent_w = 0.0)&amp;lt;/code&amp;gt; || move the cursor back left (unindent), matching a prior indent() || &amp;lt;code&amp;gt;mxw_imgui.unindent()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_group()&amp;lt;/code&amp;gt; || start a layout group (following widgets are treated as one unit for layout purposes) || &amp;lt;code&amp;gt;mxw_imgui.begin_group()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.end_group()&amp;lt;/code&amp;gt; || close the current layout group || &amp;lt;code&amp;gt;mxw_imgui.end_group()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_cursor_pos()&amp;lt;/code&amp;gt; || returns the cursor position (&amp;lt;code&amp;gt;Vec2&amp;lt;/code&amp;gt;) relative to the current window || &amp;lt;code&amp;gt;p = mxw_imgui.get_cursor_pos()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_cursor_pos_x()&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.get_cursor_pos_y()&amp;lt;/code&amp;gt; || returns just the X or Y cursor coordinate || &amp;lt;code&amp;gt;x = mxw_imgui.get_cursor_pos_x()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_cursor_pos(local_pos)&amp;lt;/code&amp;gt; || set the cursor position (&amp;lt;code&amp;gt;Vec2&amp;lt;/code&amp;gt;), window-relative || &amp;lt;code&amp;gt;mxw_imgui.set_cursor_pos(mxw_imgui.Vec2(0, 0))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_cursor_pos_x(local_x)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.set_cursor_pos_y(local_y)&amp;lt;/code&amp;gt; || set just the X or Y cursor coordinate || &amp;lt;code&amp;gt;mxw_imgui.set_cursor_pos_x(20)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_cursor_start_pos()&amp;lt;/code&amp;gt; || returns the initial cursor position of the current window/child || &amp;lt;code&amp;gt;p = mxw_imgui.get_cursor_start_pos()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_cursor_screen_pos()&amp;lt;/code&amp;gt; || returns the cursor position in absolute screen coordinates || &amp;lt;code&amp;gt;p = mxw_imgui.get_cursor_screen_pos()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_cursor_screen_pos(pos)&amp;lt;/code&amp;gt; || set the cursor in absolute screen coordinates || &amp;lt;code&amp;gt;mxw_imgui.set_cursor_screen_pos(p)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.align_text_to_frame_padding()&amp;lt;/code&amp;gt; || vertically align following text with standard framed widgets on the same line || &amp;lt;code&amp;gt;mxw_imgui.align_text_to_frame_padding()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_text_line_height()&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.get_text_line_height_with_spacing()&amp;lt;/code&amp;gt; || returns one text line&#039;s height, with or without inter-line spacing || &amp;lt;code&amp;gt;h = mxw_imgui.get_text_line_height()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_frame_height()&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.get_frame_height_with_spacing()&amp;lt;/code&amp;gt; || returns a standard framed widget&#039;s height, with or without spacing || &amp;lt;code&amp;gt;h = mxw_imgui.get_frame_height()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ID stack ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_id(str_id)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.push_id(str_id_begin, str_id_end)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.push_id(ptr_id)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.push_id(int_id)&amp;lt;/code&amp;gt; || push a scope onto the ID stack, so same-labelled widgets in a loop don&#039;t collide || &amp;lt;code&amp;gt;mxw_imgui.push_id(i)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_id()&amp;lt;/code&amp;gt; || pop the last pushed ID scope || &amp;lt;code&amp;gt;mxw_imgui.pop_id()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_id(str_id)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.get_id(str_id_begin, str_id_end)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.get_id(ptr_id)&amp;lt;/code&amp;gt; || compute a widget ID without pushing it || &amp;lt;code&amp;gt;uid = mxw_imgui.get_id(&amp;quot;my_widget&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Text ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.text_unformatted(text, text_end = None)&amp;lt;/code&amp;gt; || draw raw text, faster than &amp;lt;code&amp;gt;text()&amp;lt;/code&amp;gt; for long/dynamic strings (no format parsing) || &amp;lt;code&amp;gt;mxw_imgui.text_unformatted(&amp;quot;Ready.&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.text(fmt)&amp;lt;/code&amp;gt; || draw a line of text || &amp;lt;code&amp;gt;mxw_imgui.text(&amp;quot;Frame: &amp;quot; + str(mxw.framecounter))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.text_colored(col, fmt)&amp;lt;/code&amp;gt; || draw text in the given &amp;lt;code&amp;gt;Vec4&amp;lt;/code&amp;gt; color || &amp;lt;code&amp;gt;mxw_imgui.text_colored(mxw_imgui.Vec4(1,0,0,1), &amp;quot;Error&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.text_disabled(fmt)&amp;lt;/code&amp;gt; || draw text in the disabled/grey style color || &amp;lt;code&amp;gt;mxw_imgui.text_disabled(&amp;quot;(no signal)&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.text_wrapped(fmt)&amp;lt;/code&amp;gt; || draw text that wraps at the window edge, regardless of the wrap-pos stack || &amp;lt;code&amp;gt;mxw_imgui.text_wrapped(status_message)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.label_text(label, fmt)&amp;lt;/code&amp;gt; || draw a &amp;quot;label: value&amp;quot;-style line (label aligned like other widgets) || &amp;lt;code&amp;gt;mxw_imgui.label_text(&amp;quot;Status&amp;quot;, &amp;quot;OK&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.bullet_text(fmt)&amp;lt;/code&amp;gt; || draw a bulleted line of text || &amp;lt;code&amp;gt;mxw_imgui.bullet_text(&amp;quot;first item&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Main widgets ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.button(label, size = Vec2(0,0))&amp;lt;/code&amp;gt; || a clickable button; returns &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; the frame it&#039;s clicked || &amp;lt;code&amp;gt;if mxw_imgui.button(&amp;quot;Reload&amp;quot;): reload()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.small_button(label)&amp;lt;/code&amp;gt; || a button with no extra vertical padding, fits inline with text || &amp;lt;code&amp;gt;if mxw_imgui.small_button(&amp;quot;x&amp;quot;): close()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.invisible_button(str_id, size, flags = 0)&amp;lt;/code&amp;gt; || an invisible clickable/draggable area || &amp;lt;code&amp;gt;mxw_imgui.invisible_button(&amp;quot;drag_area&amp;quot;, mxw_imgui.Vec2(50,50))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.arrow_button(str_id, dir)&amp;lt;/code&amp;gt; || a small square button with an arrow glyph (&amp;lt;code&amp;gt;dir&amp;lt;/code&amp;gt;: 0=left,1=right,2=up,3=down) || &amp;lt;code&amp;gt;mxw_imgui.arrow_button(&amp;quot;up&amp;quot;, 2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.image(user_texture_id, size, uv0 = Vec2(0,0), uv1 = Vec2(1,1), tint_col = Vec4(1,1,1,1), border_col = Vec4(0,0,0,0))&amp;lt;/code&amp;gt; || draw a texture (GL texture id) as an image || &amp;lt;code&amp;gt;mxw_imgui.image(tex_id, mxw_imgui.Vec2(128,128))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.image_button(user_texture_id, size, uv0 = Vec2(0,0), uv1 = Vec2(1,1), frame_padding = -1, bg_col = Vec4(0,0,0,0), tint_col = Vec4(1,1,1,1))&amp;lt;/code&amp;gt; || a clickable image button || &amp;lt;code&amp;gt;if mxw_imgui.image_button(tex_id, mxw_imgui.Vec2(32,32)): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.checkbox(label, v)&amp;lt;/code&amp;gt; || a checkbox; &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt;/return is &amp;lt;code&amp;gt;bool&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;changed, enabled = mxw_imgui.checkbox(&amp;quot;Enabled&amp;quot;, enabled)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.checkbox_flags(label, flags, flags_value)&amp;lt;/code&amp;gt; || a checkbox that toggles one bit(mask) of an int flags value || &amp;lt;code&amp;gt;changed, flags = mxw_imgui.checkbox_flags(&amp;quot;Bit 1&amp;quot;, flags, 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.radio_button(label, active)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.radio_button(label, v, v_button)&amp;lt;/code&amp;gt; || a radio button; single-bool form for manual state, or bind directly to an int selection variable || &amp;lt;code&amp;gt;changed, mode = mxw_imgui.radio_button(&amp;quot;Mode A&amp;quot;, mode, 0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.progress_bar(fraction, size_arg = Vec2(-FLT_MIN, 0), overlay = None)&amp;lt;/code&amp;gt; || a progress bar, &amp;lt;code&amp;gt;fraction&amp;lt;/code&amp;gt; 0.0..1.0 || &amp;lt;code&amp;gt;mxw_imgui.progress_bar(0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.bullet()&amp;lt;/code&amp;gt; || draw just a bullet glyph, e.g. before inline text/widgets || &amp;lt;code&amp;gt;mxw_imgui.bullet()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Combo box ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.combo(label, current_item, items, popup_max_height_in_items = -1)&amp;lt;/code&amp;gt; || a combo box built from a Python list of strings; simplest way to pick one of several options || &amp;lt;code&amp;gt;changed, sel = mxw_imgui.combo(&amp;quot;Mode&amp;quot;, sel, [&amp;quot;A&amp;quot;, &amp;quot;B&amp;quot;, &amp;quot;C&amp;quot;])&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_combo(label, preview_value, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_combo()&amp;lt;/code&amp;gt; || low-level combo box: build the popup content yourself (e.g. with &amp;lt;code&amp;gt;selectable()&amp;lt;/code&amp;gt;) between these two calls || &amp;lt;code&amp;gt;if mxw_imgui.begin_combo(&amp;quot;Mode&amp;quot;, preview): mxw_imgui.end_combo()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Drag sliders ===&lt;br /&gt;
Click-and-drag widgets; typing is also possible (Ctrl+click / double-click).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.drag_float(label, v, v_speed = 1.0, v_min = 0.0, v_max = 0.0, format = None, flags = 0)&amp;lt;/code&amp;gt; || drag a single float; &amp;lt;code&amp;gt;v_min == v_max == 0&amp;lt;/code&amp;gt; means unbounded || &amp;lt;code&amp;gt;changed, value = mxw_imgui.drag_float(&amp;quot;Speed&amp;quot;, value, 0.01, 0.0, 2.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.drag_float2(label, v, ...)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;drag_float3&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;drag_float4&amp;lt;/code&amp;gt; || same, for a list of 2/3/4 floats (e.g. a color or position) || &amp;lt;code&amp;gt;changed, xyz = mxw_imgui.drag_float3(&amp;quot;Position&amp;quot;, xyz)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.drag_float_range2(label, v_current_min, v_current_max, v_speed = 1.0, v_min = 0.0, v_max = 0.0, format = None, format_max = None, flags = 0)&amp;lt;/code&amp;gt; || drag a min/max float range with two handles || &amp;lt;code&amp;gt;changed, lo, hi = mxw_imgui.drag_float_range2(&amp;quot;Range&amp;quot;, lo, hi)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.drag_int(label, v, v_speed = 1.0, v_min = 0, v_max = 0, format = None, flags = 0)&amp;lt;/code&amp;gt; || drag a single int || &amp;lt;code&amp;gt;changed, value = mxw_imgui.drag_int(&amp;quot;Count&amp;quot;, value, 1, 0, 10)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.drag_int2(label, v, ...)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;drag_int3&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;drag_int4&amp;lt;/code&amp;gt; || same, for a list of 2/3/4 ints || &amp;lt;code&amp;gt;changed, rgb = mxw_imgui.drag_int3(&amp;quot;RGB&amp;quot;, rgb, 1, 0, 255)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.drag_int_range2(label, v_current_min, v_current_max, ...)&amp;lt;/code&amp;gt; || drag a min/max int range with two handles || &amp;lt;code&amp;gt;changed, lo, hi = mxw_imgui.drag_int_range2(&amp;quot;Range&amp;quot;, lo, hi)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.drag_scalar(label, data_type, p_data, v_speed, p_min = None, p_max = None, format = None, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;drag_scalar_n(..., components, ...)&amp;lt;/code&amp;gt; || generic drag widget for any &amp;lt;code&amp;gt;ImGuiDataType&amp;lt;/code&amp;gt;, rarely needed from Python || &amp;lt;code&amp;gt;mxw_imgui.drag_scalar(&amp;quot;Value&amp;quot;, 0, ptr, 1.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sliders ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.slider_float(label, v, v_min, v_max, format = None, flags = 0)&amp;lt;/code&amp;gt; || slide a single float between &amp;lt;code&amp;gt;v_min&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;v_max&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;changed, value = mxw_imgui.slider_float(&amp;quot;Mouse X&amp;quot;, value, 0.0, 1.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.slider_float2(label, v, v_min, v_max, ...)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;slider_float3&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;slider_float4&amp;lt;/code&amp;gt; || same, for a list of 2/3/4 floats || &amp;lt;code&amp;gt;changed, rgba = mxw_imgui.slider_float4(&amp;quot;Color&amp;quot;, rgba, 0.0, 1.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.slider_angle(label, v_rad, v_degrees_min = -360.0, v_degrees_max = 360.0, format = None, flags = 0)&amp;lt;/code&amp;gt; || slide an angle, stored in radians but displayed/typed in degrees || &amp;lt;code&amp;gt;changed, rot = mxw_imgui.slider_angle(&amp;quot;Rotation&amp;quot;, rot)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.slider_int(label, v, v_min, v_max, format = None, flags = 0)&amp;lt;/code&amp;gt; || slide a single int || &amp;lt;code&amp;gt;changed, idx = mxw_imgui.slider_int(&amp;quot;Preset&amp;quot;, idx, 0, 99)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.slider_int2(label, v, v_min, v_max, ...)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;slider_int3&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;slider_int4&amp;lt;/code&amp;gt; || same, for a list of 2/3/4 ints || &amp;lt;code&amp;gt;changed, xy = mxw_imgui.slider_int2(&amp;quot;Grid pos&amp;quot;, xy, 0, 10)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.slider_scalar(label, data_type, p_data, p_min, p_max, format = None, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;slider_scalar_n(..., components, ...)&amp;lt;/code&amp;gt; || generic slider for any &amp;lt;code&amp;gt;ImGuiDataType&amp;lt;/code&amp;gt;, rarely needed from Python || &amp;lt;code&amp;gt;mxw_imgui.slider_scalar(&amp;quot;Value&amp;quot;, 0, ptr, p_min, p_max)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.v_slider_float(label, size, v, v_min, v_max, format = None, flags = 0)&amp;lt;/code&amp;gt; || vertical slider variant of &amp;lt;code&amp;gt;slider_float&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;changed, value = mxw_imgui.v_slider_float(&amp;quot;##vol&amp;quot;, mxw_imgui.Vec2(20,100), value, 0.0, 1.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.v_slider_int(label, size, v, v_min, v_max, format = None, flags = 0)&amp;lt;/code&amp;gt; || vertical slider variant of &amp;lt;code&amp;gt;slider_int&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;changed, value = mxw_imgui.v_slider_int(&amp;quot;##lvl&amp;quot;, mxw_imgui.Vec2(20,100), value, 0, 10)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.v_slider_scalar(label, size, data_type, p_data, p_min, p_max, format = None, flags = 0)&amp;lt;/code&amp;gt; || generic vertical slider for any &amp;lt;code&amp;gt;ImGuiDataType&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;mxw_imgui.v_slider_scalar(&amp;quot;##v&amp;quot;, size, 0, ptr, p_min, p_max)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Input widgets ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.input_text(label, data, max_size, flags = 0)&amp;lt;/code&amp;gt; || a single-line text field; &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; is the current string, &amp;lt;code&amp;gt;max_size&amp;lt;/code&amp;gt; the max length in bytes || &amp;lt;code&amp;gt;changed, value = mxw_imgui.input_text(&amp;quot;URL&amp;quot;, url_text, 512)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.input_text_multiline(label, data, max_size, size = Vec2(0,0), flags = 0)&amp;lt;/code&amp;gt; || a multi-line text field || &amp;lt;code&amp;gt;changed, value = mxw_imgui.input_text_multiline(&amp;quot;Notes&amp;quot;, notes, 2048, mxw_imgui.Vec2(300,100))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.input_float(label, v, step = 0.0, step_fast = 0.0, format = None, flags = 0)&amp;lt;/code&amp;gt; || a typed float field with optional +/- step buttons || &amp;lt;code&amp;gt;changed, value = mxw_imgui.input_float(&amp;quot;Gain&amp;quot;, value, 0.1)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.input_float2(label, v, ...)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;input_float3&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;input_float4&amp;lt;/code&amp;gt; || same, for a list of 2/3/4 floats || &amp;lt;code&amp;gt;changed, xyz = mxw_imgui.input_float3(&amp;quot;Pos&amp;quot;, xyz)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.input_int(label, v, step = 1, step_fast = 100, flags = 0)&amp;lt;/code&amp;gt; || a typed int field with +/- step buttons || &amp;lt;code&amp;gt;changed, value = mxw_imgui.input_int(&amp;quot;Count&amp;quot;, value)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.input_int2(label, v, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;input_int3&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;input_int4&amp;lt;/code&amp;gt; || same, for a list of 2/3/4 ints || &amp;lt;code&amp;gt;changed, rgb = mxw_imgui.input_int3(&amp;quot;RGB&amp;quot;, rgb)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.input_double(label, v, step = 0.0, step_fast = 0.0, format = None, flags = 0)&amp;lt;/code&amp;gt; || a typed double field || &amp;lt;code&amp;gt;changed, value = mxw_imgui.input_double(&amp;quot;Precise&amp;quot;, value)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.input_scalar(label, data_type, p_data, p_step = None, p_step_fast = None, format = None, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;input_scalar_n(..., components, ...)&amp;lt;/code&amp;gt; || generic typed field for any &amp;lt;code&amp;gt;ImGuiDataType&amp;lt;/code&amp;gt;, rarely needed from Python || &amp;lt;code&amp;gt;mxw_imgui.input_scalar(&amp;quot;Value&amp;quot;, 0, ptr)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Color editor &amp;amp;amp; picker ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_edit3(label, col, flags = 0)&amp;lt;/code&amp;gt; || a compact RGB color editor (swatch + popup picker); &amp;lt;code&amp;gt;col&amp;lt;/code&amp;gt; is a 3-float list || &amp;lt;code&amp;gt;changed, rgb = mxw_imgui.color_edit3(&amp;quot;Tint&amp;quot;, rgb)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_edit4(label, col, flags = 0)&amp;lt;/code&amp;gt; || same, RGBA (4-float list) || &amp;lt;code&amp;gt;changed, rgba = mxw_imgui.color_edit4(&amp;quot;Tint&amp;quot;, rgba)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_picker3(label, col, flags = 0)&amp;lt;/code&amp;gt; || a full RGB color picker widget, always expanded || &amp;lt;code&amp;gt;changed, rgb = mxw_imgui.color_picker3(&amp;quot;Tint&amp;quot;, rgb)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_picker4(label, col, flags = 0, ref_col = None)&amp;lt;/code&amp;gt; || same, RGBA, optionally showing a reference color for comparison || &amp;lt;code&amp;gt;changed, rgba = mxw_imgui.color_picker4(&amp;quot;Tint&amp;quot;, rgba)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_button(desc_id, col, flags = 0, size = Vec2(0,0))&amp;lt;/code&amp;gt; || a non-editable color swatch button (e.g. as a preview/trigger) || &amp;lt;code&amp;gt;if mxw_imgui.color_button(&amp;quot;preview&amp;quot;, col): open_picker()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.tree_node(label)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.tree_node(str_id, fmt)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.tree_node(ptr_id, fmt)&amp;lt;/code&amp;gt; || an expandable/collapsible tree node; returns &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; while open. Call &amp;lt;code&amp;gt;tree_pop()&amp;lt;/code&amp;gt; if it returned &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;if mxw_imgui.tree_node(&amp;quot;Advanced&amp;quot;): mxw_imgui.tree_pop()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.tree_node_ex(label, flags = 0)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.tree_node_ex(str_id, flags, fmt)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.tree_node_ex(ptr_id, flags, fmt)&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;tree_node()&amp;lt;/code&amp;gt; with explicit flags (e.g. default-open, leaf, selected) || &amp;lt;code&amp;gt;if mxw_imgui.tree_node_ex(&amp;quot;Node&amp;quot;, 0): mxw_imgui.tree_pop()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.tree_push(str_id)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.tree_push(ptr_id = None)&amp;lt;/code&amp;gt; || push an indent level without drawing a node (paired with &amp;lt;code&amp;gt;tree_pop()&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;mxw_imgui.tree_push(&amp;quot;scope&amp;quot;); mxw_imgui.tree_pop()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.tree_pop()&amp;lt;/code&amp;gt; || pop one indent level pushed by &amp;lt;code&amp;gt;tree_node()&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;tree_push()&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;mxw_imgui.tree_pop()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_tree_node_to_label_spacing()&amp;lt;/code&amp;gt; || returns the horizontal spacing between a tree node arrow and its label || &amp;lt;code&amp;gt;s = mxw_imgui.get_tree_node_to_label_spacing()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.collapsing_header(label, flags = 0)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.collapsing_header(label, p_visible, flags = 0)&amp;lt;/code&amp;gt; || a top-level collapsible section header; optionally with a close (&amp;quot;x&amp;quot;) button when &amp;lt;code&amp;gt;p_visible&amp;lt;/code&amp;gt; is passed || &amp;lt;code&amp;gt;if mxw_imgui.collapsing_header(&amp;quot;Settings&amp;quot;): mxw_imgui.text(&amp;quot;...&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_next_item_open(is_open, cond = 0)&amp;lt;/code&amp;gt; || force the next &amp;lt;code&amp;gt;tree_node()&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;collapsing_header()&amp;lt;/code&amp;gt; open/closed state || &amp;lt;code&amp;gt;mxw_imgui.set_next_item_open(true)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Selectables &amp;amp;amp; list boxes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.selectable(label, selected = false, flags = 0, size = Vec2(0,0))&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.selectable(label, p_selected, flags = 0, size = Vec2(0,0))&amp;lt;/code&amp;gt; || a clickable, highlightable row (typically inside a list box) || &amp;lt;code&amp;gt;if mxw_imgui.selectable(&amp;quot;Item 1&amp;quot;, is_sel): pick(1)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_list_box(label, size = Vec2(0,0))&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_list_box()&amp;lt;/code&amp;gt; || low-level list box: build the rows yourself (e.g. with &amp;lt;code&amp;gt;selectable()&amp;lt;/code&amp;gt;) between these two calls || &amp;lt;code&amp;gt;if mxw_imgui.begin_list_box(&amp;quot;Items&amp;quot;): mxw_imgui.end_list_box()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.list_box(label, current_item, items, height_in_items = -1)&amp;lt;/code&amp;gt; || a list box built from a Python list of strings, single-select || &amp;lt;code&amp;gt;changed, sel = mxw_imgui.list_box(&amp;quot;Presets&amp;quot;, sel, [&amp;quot;A&amp;quot;, &amp;quot;B&amp;quot;, &amp;quot;C&amp;quot;])&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.list_box_stretch(label, current_item, items)&amp;lt;/code&amp;gt; || MXWendler custom variant of &amp;lt;code&amp;gt;list_box()&amp;lt;/code&amp;gt; that stretches to fill the remaining panel height || &amp;lt;code&amp;gt;changed, sel = mxw_imgui.list_box_stretch(&amp;quot;Presets&amp;quot;, sel, names)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Data plotting ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.plot_lines(label, values, values_offset = 0, overlay_text = None, scale_min = FLT_MAX, scale_max = FLT_MAX, graph_size = Vec2(0,0))&amp;lt;/code&amp;gt; || draw a line graph from a Python list of floats || &amp;lt;code&amp;gt;mxw_imgui.plot_lines(&amp;quot;Levels&amp;quot;, history)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.plot_histogram(label, values, values_offset = 0, overlay_text = None, scale_min = FLT_MAX, scale_max = FLT_MAX, graph_size = Vec2(0,0))&amp;lt;/code&amp;gt; || draw a bar histogram from a Python list of floats || &amp;lt;code&amp;gt;mxw_imgui.plot_histogram(&amp;quot;Levels&amp;quot;, history)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Value() helpers ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.value(prefix, b)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.value(prefix, v)&amp;lt;/code&amp;gt; (int/uint) OR &amp;lt;code&amp;gt;mxw_imgui.value(prefix, v, float_format = None)&amp;lt;/code&amp;gt; || draw a &amp;quot;prefix: value&amp;quot; line for a bool/int/float, without building the string yourself || &amp;lt;code&amp;gt;mxw_imgui.value(&amp;quot;FPS&amp;quot;, mxw.fps)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Menus ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_menu_bar()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_menu_bar()&amp;lt;/code&amp;gt; || start/end a menu bar inside the current window || &amp;lt;code&amp;gt;if mxw_imgui.begin_menu_bar(): mxw_imgui.end_menu_bar()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_main_menu_bar()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_main_menu_bar()&amp;lt;/code&amp;gt; || start/end the application&#039;s main (top-level) menu bar || &amp;lt;code&amp;gt;if mxw_imgui.begin_main_menu_bar(): mxw_imgui.end_main_menu_bar()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_menu(label, enabled = true)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_menu()&amp;lt;/code&amp;gt; || start/end a (sub)menu; call &amp;lt;code&amp;gt;end_menu()&amp;lt;/code&amp;gt; only if &amp;lt;code&amp;gt;begin_menu()&amp;lt;/code&amp;gt; returned &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;if mxw_imgui.begin_menu(&amp;quot;File&amp;quot;): mxw_imgui.end_menu()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.menu_item(label, shortcut = None, selected = false, enabled = true)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.menu_item(label, shortcut, p_selected, enabled = true)&amp;lt;/code&amp;gt; || a clickable (optionally checkable) menu entry || &amp;lt;code&amp;gt;if mxw_imgui.menu_item(&amp;quot;Save&amp;quot;, &amp;quot;Ctrl+S&amp;quot;): save()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Tooltips ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_tooltip()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_tooltip()&amp;lt;/code&amp;gt; || build a custom tooltip (any widgets) between these two calls || &amp;lt;code&amp;gt;mxw_imgui.begin_tooltip(); mxw_imgui.text(&amp;quot;info&amp;quot;); mxw_imgui.end_tooltip()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_tooltip(fmt)&amp;lt;/code&amp;gt; || a quick one-line tooltip for the last hovered item || &amp;lt;code&amp;gt;if mxw_imgui.is_item_hovered(): mxw_imgui.set_tooltip(&amp;quot;Explain this&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Popups &amp;amp;amp; modals ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.open_popup(str_id, flags = 0)&amp;lt;/code&amp;gt; || flag a popup to open (by ID) on the next matching &amp;lt;code&amp;gt;begin_popup()&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;mxw_imgui.open_popup(&amp;quot;confirm_delete&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_popup(str_id, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_popup()&amp;lt;/code&amp;gt; || build a plain popup&#039;s content; call &amp;lt;code&amp;gt;end_popup()&amp;lt;/code&amp;gt; only if &amp;lt;code&amp;gt;begin_popup()&amp;lt;/code&amp;gt; returned &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;if mxw_imgui.begin_popup(&amp;quot;menu&amp;quot;): mxw_imgui.end_popup()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_popup_modal(name, p_open = None, flags = 0)&amp;lt;/code&amp;gt; || build a modal popup&#039;s content (blocks interaction with the rest of the UI) || &amp;lt;code&amp;gt;opened, _ = mxw_imgui.begin_popup_modal(&amp;quot;Confirm&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.open_popup_on_item_click(str_id = None, popup_flags = 1)&amp;lt;/code&amp;gt; || open a popup when the last item is clicked (e.g. right-click context menu) || &amp;lt;code&amp;gt;mxw_imgui.open_popup_on_item_click(&amp;quot;ctx&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.close_current_popup()&amp;lt;/code&amp;gt; || close the popup currently being drawn (e.g. after a button inside it) || &amp;lt;code&amp;gt;if mxw_imgui.button(&amp;quot;OK&amp;quot;): mxw_imgui.close_current_popup()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_popup_context_item(str_id = None, popup_flags = 1)&amp;lt;/code&amp;gt; || combined open+begin for a right-click context popup on the last item || &amp;lt;code&amp;gt;if mxw_imgui.begin_popup_context_item(): mxw_imgui.end_popup()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_popup_context_window(str_id = None, popup_flags = 1)&amp;lt;/code&amp;gt; || same, anchored to the current window instead of the last item || &amp;lt;code&amp;gt;if mxw_imgui.begin_popup_context_window(): mxw_imgui.end_popup()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_popup_context_void(str_id = None, popup_flags = 1)&amp;lt;/code&amp;gt; || same, opens on right-click on empty space (no window/item under cursor) || &amp;lt;code&amp;gt;if mxw_imgui.begin_popup_context_void(): mxw_imgui.end_popup()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_popup_open(str_id, flags = 0)&amp;lt;/code&amp;gt; || returns whether the given popup is currently open || &amp;lt;code&amp;gt;open = mxw_imgui.is_popup_open(&amp;quot;menu&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Tables ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_table(str_id, column, flags = 0, outer_size = Vec2(0,0), inner_width = 0.0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_table()&amp;lt;/code&amp;gt; || start/end a table; call &amp;lt;code&amp;gt;end_table()&amp;lt;/code&amp;gt; only if &amp;lt;code&amp;gt;begin_table()&amp;lt;/code&amp;gt; returned &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;if mxw_imgui.begin_table(&amp;quot;grid&amp;quot;, 3): mxw_imgui.end_table()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_next_row(row_flags = 0, min_row_height = 0.0)&amp;lt;/code&amp;gt; || start the next table row || &amp;lt;code&amp;gt;mxw_imgui.table_next_row()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_next_column()&amp;lt;/code&amp;gt; || advance to the next cell (wraps to the next row automatically) || &amp;lt;code&amp;gt;mxw_imgui.table_next_column()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_set_column_index(column_n)&amp;lt;/code&amp;gt; || jump directly to a given column in the current row || &amp;lt;code&amp;gt;mxw_imgui.table_set_column_index(1)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_setup_column(label, flags = 0, init_width_or_weight = 0.0, user_id = 0)&amp;lt;/code&amp;gt; || declare a column&#039;s header label / sizing before the first row || &amp;lt;code&amp;gt;mxw_imgui.table_setup_column(&amp;quot;Name&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_setup_scroll_freeze(cols, rows)&amp;lt;/code&amp;gt; || freeze N leading columns/rows while the rest scrolls || &amp;lt;code&amp;gt;mxw_imgui.table_setup_scroll_freeze(0, 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_headers_row()&amp;lt;/code&amp;gt; || draw the header row from the declared &amp;lt;code&amp;gt;table_setup_column()&amp;lt;/code&amp;gt; labels || &amp;lt;code&amp;gt;mxw_imgui.table_headers_row()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_header(label)&amp;lt;/code&amp;gt; || draw a single header cell manually (instead of &amp;lt;code&amp;gt;table_headers_row()&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;mxw_imgui.table_header(&amp;quot;Name&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_get_sort_specs()&amp;lt;/code&amp;gt; || returns the current column sort specification, if the table is sortable || &amp;lt;code&amp;gt;specs = mxw_imgui.table_get_sort_specs()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_get_column_count()&amp;lt;/code&amp;gt; || returns the number of columns of the current table || &amp;lt;code&amp;gt;n = mxw_imgui.table_get_column_count()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_get_column_index()&amp;lt;/code&amp;gt; || returns the current column index || &amp;lt;code&amp;gt;i = mxw_imgui.table_get_column_index()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_get_row_index()&amp;lt;/code&amp;gt; || returns the current row index || &amp;lt;code&amp;gt;i = mxw_imgui.table_get_row_index()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_get_column_name(column_n = -1)&amp;lt;/code&amp;gt; || returns a column&#039;s declared label (-1 = current column) || &amp;lt;code&amp;gt;name = mxw_imgui.table_get_column_name(0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_get_column_flags(column_n = -1)&amp;lt;/code&amp;gt; || returns a column&#039;s current flags (e.g. is it hidden/sorted) || &amp;lt;code&amp;gt;flags = mxw_imgui.table_get_column_flags()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_set_bg_color(target, color, column_n = -1)&amp;lt;/code&amp;gt; || set the background color of a cell/row/column || &amp;lt;code&amp;gt;mxw_imgui.table_set_bg_color(0, mxw_imgui.color_convert_float4_to_u32(mxw_imgui.Vec4(1,0,0,1)))&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Legacy columns ===&lt;br /&gt;
Superseded by [[#Tables|Tables]] above, kept for compatibility.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.columns(count = 1, id = None, border = true)&amp;lt;/code&amp;gt; || switch the rest of the window into a simple N-column layout (&amp;lt;code&amp;gt;count = 1&amp;lt;/code&amp;gt; ends it) || &amp;lt;code&amp;gt;mxw_imgui.columns(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.next_column()&amp;lt;/code&amp;gt; || move to the next column (wraps to the next row) || &amp;lt;code&amp;gt;mxw_imgui.next_column()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_column_index()&amp;lt;/code&amp;gt; || returns the current column index || &amp;lt;code&amp;gt;i = mxw_imgui.get_column_index()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_column_width(column_index = -1)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.set_column_width(column_index, width)&amp;lt;/code&amp;gt; || get/set a column&#039;s width || &amp;lt;code&amp;gt;w = mxw_imgui.get_column_width()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_column_offset(column_index = -1)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.set_column_offset(column_index, offset_x)&amp;lt;/code&amp;gt; || get/set a column&#039;s X offset || &amp;lt;code&amp;gt;x = mxw_imgui.get_column_offset()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_columns_count()&amp;lt;/code&amp;gt; || returns the current column count || &amp;lt;code&amp;gt;n = mxw_imgui.get_columns_count()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Tabs ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_tab_bar(str_id, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_tab_bar()&amp;lt;/code&amp;gt; || start/end a tab bar; call &amp;lt;code&amp;gt;end_tab_bar()&amp;lt;/code&amp;gt; only if &amp;lt;code&amp;gt;begin_tab_bar()&amp;lt;/code&amp;gt; returned &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;if mxw_imgui.begin_tab_bar(&amp;quot;tabs&amp;quot;): mxw_imgui.end_tab_bar()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_tab_item(label, p_open = None, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_tab_item()&amp;lt;/code&amp;gt; || start/end one tab&#039;s content; call &amp;lt;code&amp;gt;end_tab_item()&amp;lt;/code&amp;gt; only if &amp;lt;code&amp;gt;begin_tab_item()&amp;lt;/code&amp;gt; returned &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;opened, _ = mxw_imgui.begin_tab_item(&amp;quot;Settings&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.tab_item_button(label, flags = 0)&amp;lt;/code&amp;gt; || a button drawn as a tab (e.g. a &amp;quot;+&amp;quot; to add a tab) || &amp;lt;code&amp;gt;if mxw_imgui.tab_item_button(&amp;quot;+&amp;quot;): add_tab()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_tab_item_closed(tab_or_docked_window_label)&amp;lt;/code&amp;gt; || programmatically close a tab by label || &amp;lt;code&amp;gt;mxw_imgui.set_tab_item_closed(&amp;quot;Old Tab&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Logging / capture ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.log_to_tty(auto_open_depth = -1)&amp;lt;/code&amp;gt; || start capturing following widgets&#039; text output to the app&#039;s TTY/console || &amp;lt;code&amp;gt;mxw_imgui.log_to_tty()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.log_to_file(auto_open_depth = -1, filename = None)&amp;lt;/code&amp;gt; || start capturing to a file || &amp;lt;code&amp;gt;mxw_imgui.log_to_file(-1, &amp;quot;log.txt&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.log_to_clipboard(auto_open_depth = -1)&amp;lt;/code&amp;gt; || start capturing to the OS clipboard || &amp;lt;code&amp;gt;mxw_imgui.log_to_clipboard()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.log_finish()&amp;lt;/code&amp;gt; || stop the current capture || &amp;lt;code&amp;gt;mxw_imgui.log_finish()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.log_buttons()&amp;lt;/code&amp;gt; || draw the standard &amp;quot;Log/Copy to clipboard&amp;quot; buttons || &amp;lt;code&amp;gt;mxw_imgui.log_buttons()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.log_text(fmt)&amp;lt;/code&amp;gt; || add text directly to the active log capture, without drawing a widget || &amp;lt;code&amp;gt;mxw_imgui.log_text(&amp;quot;captured line&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Drag and drop ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_drag_drop_source(flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_drag_drop_source()&amp;lt;/code&amp;gt; || make the last item a drag source; build the payload/preview between these two calls || &amp;lt;code&amp;gt;if mxw_imgui.begin_drag_drop_source(): mxw_imgui.end_drag_drop_source()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_drag_drop_payload(type, data, sz, cond = 0)&amp;lt;/code&amp;gt; || attach a payload to the drag currently being sourced || &amp;lt;code&amp;gt;mxw_imgui.set_drag_drop_payload(&amp;quot;CLIP&amp;quot;, data, len(data))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_drag_drop_target()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_drag_drop_target()&amp;lt;/code&amp;gt; || make the last item/window a drop target; check &amp;lt;code&amp;gt;accept_drag_drop_payload()&amp;lt;/code&amp;gt; between these two calls || &amp;lt;code&amp;gt;if mxw_imgui.begin_drag_drop_target(): mxw_imgui.end_drag_drop_target()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.accept_drag_drop_payload(type, flags = 0)&amp;lt;/code&amp;gt; || accept a payload of the given type while inside a drop target || &amp;lt;code&amp;gt;p = mxw_imgui.accept_drag_drop_payload(&amp;quot;CLIP&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_drag_drop_payload()&amp;lt;/code&amp;gt; || peek the payload of the drag currently in progress, even outside a target || &amp;lt;code&amp;gt;p = mxw_imgui.get_drag_drop_payload()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Clipping ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_clip_rect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect)&amp;lt;/code&amp;gt; || push a manual clipping rectangle (&amp;lt;code&amp;gt;Vec2&amp;lt;/code&amp;gt; corners) for subsequent drawing || &amp;lt;code&amp;gt;mxw_imgui.push_clip_rect(p_min, p_max, true)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_clip_rect()&amp;lt;/code&amp;gt; || pop the pushed clip rect || &amp;lt;code&amp;gt;mxw_imgui.pop_clip_rect()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Focus &amp;amp;amp; activation ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_item_default_focus()&amp;lt;/code&amp;gt; || make the last item the one focused by default when the panel first appears || &amp;lt;code&amp;gt;mxw_imgui.set_item_default_focus()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_keyboard_focus_here(offset = 0)&amp;lt;/code&amp;gt; || focus the next widget for keyboard input (e.g. auto-focus a text field) || &amp;lt;code&amp;gt;mxw_imgui.set_keyboard_focus_here()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Item / widgets utilities ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_hovered(flags = 0)&amp;lt;/code&amp;gt; || returns whether the last item is hovered by the mouse || &amp;lt;code&amp;gt;if mxw_imgui.is_item_hovered(): mxw_imgui.set_tooltip(&amp;quot;info&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_active()&amp;lt;/code&amp;gt; || returns whether the last item is currently active (e.g. being held/edited) || &amp;lt;code&amp;gt;active = mxw_imgui.is_item_active()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_focused()&amp;lt;/code&amp;gt; || returns whether the last item has keyboard focus || &amp;lt;code&amp;gt;focused = mxw_imgui.is_item_focused()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_clicked(mouse_button = 0)&amp;lt;/code&amp;gt; || returns whether the last item was clicked this frame || &amp;lt;code&amp;gt;if mxw_imgui.is_item_clicked(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_visible()&amp;lt;/code&amp;gt; || returns whether the last item is visible (not clipped) || &amp;lt;code&amp;gt;visible = mxw_imgui.is_item_visible()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_edited()&amp;lt;/code&amp;gt; || returns whether the last item&#039;s value changed this frame || &amp;lt;code&amp;gt;edited = mxw_imgui.is_item_edited()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_activated()&amp;lt;/code&amp;gt; || returns whether the last item just became active this frame || &amp;lt;code&amp;gt;started = mxw_imgui.is_item_activated()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_deactivated()&amp;lt;/code&amp;gt; || returns whether the last item just stopped being active this frame || &amp;lt;code&amp;gt;stopped = mxw_imgui.is_item_deactivated()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_deactivated_after_edit()&amp;lt;/code&amp;gt; || returns whether the last item stopped being active after its value changed (e.g. commit-on-release) || &amp;lt;code&amp;gt;if mxw_imgui.is_item_deactivated_after_edit(): save()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_toggled_open()&amp;lt;/code&amp;gt; || returns whether the last tree node/collapsing header was just opened or closed || &amp;lt;code&amp;gt;toggled = mxw_imgui.is_item_toggled_open()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_any_item_hovered()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.is_any_item_active()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.is_any_item_focused()&amp;lt;/code&amp;gt; || returns whether any item at all is hovered/active/focused || &amp;lt;code&amp;gt;busy = mxw_imgui.is_any_item_active()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_item_rect_min()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.get_item_rect_max()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.get_item_rect_size()&amp;lt;/code&amp;gt; || returns the last item&#039;s bounding rectangle (screen-space corners, or size) || &amp;lt;code&amp;gt;size = mxw_imgui.get_item_rect_size()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_item_allow_overlap()&amp;lt;/code&amp;gt; || allow the next widget to visually overlap the last item without stealing its hover/click || &amp;lt;code&amp;gt;mxw_imgui.set_item_allow_overlap()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Viewport &amp;amp;amp; miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_main_viewport()&amp;lt;/code&amp;gt; || returns the main viewport object (position/size of the whole application) || &amp;lt;code&amp;gt;vp = mxw_imgui.get_main_viewport()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_rect_visible(size)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.is_rect_visible(rect_min, rect_max)&amp;lt;/code&amp;gt; || returns whether a rectangle at the cursor (or explicit corners) is visible/unclipped || &amp;lt;code&amp;gt;visible = mxw_imgui.is_rect_visible(mxw_imgui.Vec2(50,50))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_time()&amp;lt;/code&amp;gt; || returns Dear ImGui&#039;s internal time in seconds (accumulates while the app runs) || &amp;lt;code&amp;gt;t = mxw_imgui.get_time()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_frame_count()&amp;lt;/code&amp;gt; || returns the number of ImGui frames rendered so far || &amp;lt;code&amp;gt;n = mxw_imgui.get_frame_count()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_background_draw_list()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.get_foreground_draw_list()&amp;lt;/code&amp;gt; || returns the draw list rendered behind/in front of all windows, for custom drawing || &amp;lt;code&amp;gt;dl = mxw_imgui.get_foreground_draw_list()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_draw_list_shared_data()&amp;lt;/code&amp;gt; || returns data shared across draw lists (font atlas, clip rect stack, ...), rarely needed from Python || &amp;lt;code&amp;gt;d = mxw_imgui.get_draw_list_shared_data()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_state_storage(storage)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.get_state_storage()&amp;lt;/code&amp;gt; || set/get the key-value storage backing tree/collapsing-header open states || &amp;lt;code&amp;gt;s = mxw_imgui.get_state_storage()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_child_frame(id, size, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_child_frame()&amp;lt;/code&amp;gt; || a framed, scrollable child region (styled like a text/list box) || &amp;lt;code&amp;gt;if mxw_imgui.begin_child_frame(1, mxw_imgui.Vec2(0,100)): mxw_imgui.end_child_frame()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.calc_text_size(text, text_end = None, hide_text_after_double_hash = false, wrap_width = -1.0)&amp;lt;/code&amp;gt; || returns the pixel size a string would occupy with the current font || &amp;lt;code&amp;gt;w = mxw_imgui.calc_text_size(&amp;quot;0&amp;quot;).x&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Color utilities ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_convert_u32_to_float4(in)&amp;lt;/code&amp;gt; || convert a packed &amp;lt;code&amp;gt;u32&amp;lt;/code&amp;gt; color to a &amp;lt;code&amp;gt;Vec4&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;col = mxw_imgui.color_convert_u32_to_float4(0xFFFFFFFF)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_convert_float4_to_u32(in)&amp;lt;/code&amp;gt; || convert a &amp;lt;code&amp;gt;Vec4&amp;lt;/code&amp;gt; color to a packed &amp;lt;code&amp;gt;u32&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;u = mxw_imgui.color_convert_float4_to_u32(mxw_imgui.Vec4(1,1,1,1))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_convert_rg_bto_hsv(r, g, b)&amp;lt;/code&amp;gt; || returns &amp;lt;code&amp;gt;(h, s, v)&amp;lt;/code&amp;gt; for the given RGB floats (0.0..1.0) || &amp;lt;code&amp;gt;h, s, v = mxw_imgui.color_convert_rg_bto_hsv(1.0, 0.0, 0.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_convert_hs_vto_rgb(h, s, v)&amp;lt;/code&amp;gt; || returns &amp;lt;code&amp;gt;(r, g, b)&amp;lt;/code&amp;gt; for the given HSV floats (0.0..1.0) || &amp;lt;code&amp;gt;r, g, b = mxw_imgui.color_convert_hs_vto_rgb(0.0, 1.0, 1.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Keyboard input ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_key_index(imgui_key)&amp;lt;/code&amp;gt; || map a Dear ImGui &amp;lt;code&amp;gt;ImGuiKey_*&amp;lt;/code&amp;gt; value to the user&#039;s backend key index || &amp;lt;code&amp;gt;idx = mxw_imgui.get_key_index(0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_key_down(user_key_index)&amp;lt;/code&amp;gt; || returns whether a key is currently held down || &amp;lt;code&amp;gt;held = mxw_imgui.is_key_down(idx)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_key_pressed(user_key_index, repeat = true)&amp;lt;/code&amp;gt; || returns whether a key was just pressed (optionally auto-repeating while held) || &amp;lt;code&amp;gt;if mxw_imgui.is_key_pressed(idx): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_key_released(user_key_index)&amp;lt;/code&amp;gt; || returns whether a key was just released || &amp;lt;code&amp;gt;if mxw_imgui.is_key_released(idx): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_key_pressed_amount(key_index, repeat_delay, rate)&amp;lt;/code&amp;gt; || returns how many times a key auto-repeated this frame, given a delay/rate || &amp;lt;code&amp;gt;n = mxw_imgui.get_key_pressed_amount(idx, 0.3, 0.1)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Mouse input ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_mouse_down(button)&amp;lt;/code&amp;gt; || returns whether a mouse button is currently held (0=left,1=right,2=middle) || &amp;lt;code&amp;gt;held = mxw_imgui.is_mouse_down(0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_mouse_clicked(button, repeat = false)&amp;lt;/code&amp;gt; || returns whether a mouse button was just clicked || &amp;lt;code&amp;gt;if mxw_imgui.is_mouse_clicked(0): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_mouse_released(button)&amp;lt;/code&amp;gt; || returns whether a mouse button was just released || &amp;lt;code&amp;gt;if mxw_imgui.is_mouse_released(0): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_mouse_double_clicked(button)&amp;lt;/code&amp;gt; || returns whether a mouse button was just double-clicked || &amp;lt;code&amp;gt;if mxw_imgui.is_mouse_double_clicked(0): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_mouse_hovering_rect(r_min, r_max, clip = true)&amp;lt;/code&amp;gt; || returns whether the mouse is over the given screen-space rectangle || &amp;lt;code&amp;gt;over = mxw_imgui.is_mouse_hovering_rect(p_min, p_max)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_mouse_pos_valid(mouse_pos = None)&amp;lt;/code&amp;gt; || returns whether the (current or given) mouse position is valid (app has focus etc.) || &amp;lt;code&amp;gt;valid = mxw_imgui.is_mouse_pos_valid()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_any_mouse_down()&amp;lt;/code&amp;gt; || returns whether any mouse button is currently held || &amp;lt;code&amp;gt;held = mxw_imgui.is_any_mouse_down()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_mouse_pos()&amp;lt;/code&amp;gt; || returns the current mouse position (&amp;lt;code&amp;gt;Vec2&amp;lt;/code&amp;gt;, screen-space) || &amp;lt;code&amp;gt;p = mxw_imgui.get_mouse_pos()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_mouse_pos_on_opening_current_popup()&amp;lt;/code&amp;gt; || returns the mouse position captured when the current popup was opened || &amp;lt;code&amp;gt;p = mxw_imgui.get_mouse_pos_on_opening_current_popup()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_mouse_dragging(button, lock_threshold = -1.0)&amp;lt;/code&amp;gt; || returns whether the mouse is dragging with the given button held || &amp;lt;code&amp;gt;dragging = mxw_imgui.is_mouse_dragging(0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_mouse_drag_delta(button = 0, lock_threshold = -1.0)&amp;lt;/code&amp;gt; || returns the drag distance (&amp;lt;code&amp;gt;Vec2&amp;lt;/code&amp;gt;) since the drag started || &amp;lt;code&amp;gt;d = mxw_imgui.get_mouse_drag_delta()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.reset_mouse_drag_delta(button = 0)&amp;lt;/code&amp;gt; || reset the tracked drag distance for a button || &amp;lt;code&amp;gt;mxw_imgui.reset_mouse_drag_delta()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_mouse_cursor()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.set_mouse_cursor(cursor_type)&amp;lt;/code&amp;gt; || get/set the desired OS mouse cursor shape || &amp;lt;code&amp;gt;mxw_imgui.set_mouse_cursor(1)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Clipboard ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_clipboard_text()&amp;lt;/code&amp;gt; || returns the current OS clipboard text || &amp;lt;code&amp;gt;txt = mxw_imgui.get_clipboard_text()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_clipboard_text(text)&amp;lt;/code&amp;gt; || set the OS clipboard text || &amp;lt;code&amp;gt;mxw_imgui.set_clipboard_text(&amp;quot;copied value&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Disabled blocks &amp;amp;amp; MXWendler extras ===&lt;br /&gt;
The last two functions are MXWendler additions, not part of stock Dear ImGui bindings.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_disabled(disabled = false)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_disabled()&amp;lt;/code&amp;gt; || grey out and block interaction with all widgets in between || &amp;lt;code&amp;gt;mxw_imgui.begin_disabled(not enabled); mxw_imgui.button(&amp;quot;Go&amp;quot;); mxw_imgui.end_disabled()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.render_frame(p_min, p_max, colf, border = true, rounding = 0.0)&amp;lt;/code&amp;gt; || draw a filled/bordered rectangle (screen-space corners as &amp;lt;code&amp;gt;Vec2&amp;lt;/code&amp;gt;, color as &amp;lt;code&amp;gt;Vec4&amp;lt;/code&amp;gt;) directly, e.g. for custom backgrounds || &amp;lt;code&amp;gt;mxw_imgui.render_frame(mxw_imgui.Vec2(0,0), mxw_imgui.Vec2(100,20), mxw_imgui.Vec4(0.2,0.2,0.2,1))&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
[[Category:Python]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Tutorial_Eventmaster_Toolset_Controlling_MXWendler_by_e.g._e2_S3_Image_Processor&amp;diff=6176</id>
		<title>Tutorial Eventmaster Toolset Controlling MXWendler by e.g. e2 S3 Image Processor</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Tutorial_Eventmaster_Toolset_Controlling_MXWendler_by_e.g._e2_S3_Image_Processor&amp;diff=6176"/>
		<updated>2026-08-08T15:41:17Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update link after renaming to &amp;#039;OSC command reference&amp;#039; (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial applies to all different OS and MXWendler versions &amp;gt; 6.0.04&lt;br /&gt;
&lt;br /&gt;
== Introduction==&lt;br /&gt;
This tutorial explains how to set up a Barco Eventmaster to trigger and control media playback on StageDesigner or FXServer.&lt;br /&gt;
&lt;br /&gt;
==Control Setup==&lt;br /&gt;
&lt;br /&gt;
1. Open SD (StageDesigner) and load a clip into preload 1:&lt;br /&gt;
&lt;br /&gt;
[[File:e2_01.png|600px]]&lt;br /&gt;
&lt;br /&gt;
2. Open Settings-&amp;gt;IO-&amp;gt;Barco e2 and activate TCP listening. Also note down the port number.&lt;br /&gt;
&lt;br /&gt;
[[File:e2_02.png|600px]]&lt;br /&gt;
&lt;br /&gt;
3. In the Barco Eventmaster Toolset, create an &#039;External Device&#039;, name it e.g. &#039;StageDesigner&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:e2_03.png|600px]]&lt;br /&gt;
&lt;br /&gt;
4. In the &#039;Adjust: StageDesigner&#039; tab, set IP address and port number.&lt;br /&gt;
&lt;br /&gt;
[[File:e2_04.png|600px]]&lt;br /&gt;
&lt;br /&gt;
5. In the &#039;Adjust: StageDesigner&#039; tab, add a new command. Store the command content, e.g.&lt;br /&gt;
* /mxw/preload/1 play to start a clip&lt;br /&gt;
* /mxw/preload/1 play to stop a clip&lt;br /&gt;
&lt;br /&gt;
More possible commands are in the OSC control section: [[OSC command reference]]&lt;br /&gt;
&lt;br /&gt;
[[File:e2_05.png|600px]]&lt;br /&gt;
&lt;br /&gt;
6. In the &#039;Cue&#039; section, add a cue.&lt;br /&gt;
&lt;br /&gt;
[[File:e2_06.png|600px]]&lt;br /&gt;
&lt;br /&gt;
7. In this &#039;Cue&#039;, add actions.&lt;br /&gt;
&lt;br /&gt;
[[File:e2_07.png|600px]]&lt;br /&gt;
&lt;br /&gt;
8. From &#039;External Devices&#039; drop an available command onto the &#039;Commands&#039; field of the action.&lt;br /&gt;
&lt;br /&gt;
[[File:e2_08c.png|600px]]&lt;br /&gt;
&lt;br /&gt;
9. Play this cue, a clip should be started in the StageDesigner&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=OSC_Reference&amp;diff=6175</id>
		<title>OSC Reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=OSC_Reference&amp;diff=6175"/>
		<updated>2026-08-08T15:40:47Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update link after renaming to &amp;#039;OSC command reference&amp;#039; (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This reference applies to all different OS. The presented OSC commands are for most part supported in version 6.0 but will be fully functional in version 6.0.08 and above. &lt;br /&gt;
&amp;lt;div class=&amp;quot;noprint&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
This document describes the MXWendler (MXW) OSC Command Interface through an overview of the command structure and practical examples of integration with external controlling software. &lt;br /&gt;
&lt;br /&gt;
== What is OSC? ==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
OSC or „Open Sound Control“ is a Network-based protocol that commonly utilizes the UDP transport mechanism. Originally developed as a successor of the MIDI control protocol, it used nowadays as a practical communication method between platforms.&lt;br /&gt;
&lt;br /&gt;
OSC Features:&lt;br /&gt;
* Connectionless communication architecture&lt;br /&gt;
* Broadcast-type messages&lt;br /&gt;
* High resolution time tag&lt;br /&gt;
* Allowed data formats including numeric, symbolic, and “blob” arguments&lt;br /&gt;
* Open-ended, dynamic, URL-style naming scheme for the receivers&#039; address&lt;br /&gt;
      &lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/Open_Sound_Control [1&amp;lt;nowiki&amp;gt;]&amp;lt;/nowiki&amp;gt; Wikipedia Link]&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px&amp;quot; | [[1. Controlling MXW through OSC]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;1.1 Receiving OSC commands in MXW&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px 10px&amp;quot; | &#039;&#039;1.2 Output OSC from MXW: Send vs. Reply&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px 0px&amp;quot; | [[2. MXW OSC command structure]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;2.1 Sending OSC Values&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;2.2 Examples&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[OSC command reference]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px 0px&amp;quot; | [[4. Practical examples: Pure Data and TouchOSC]]&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;4.1 Install Pure Data&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;4.2 MXW Pd Patch&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px 0px&amp;quot; | &#039;&#039;4.3 OSC for portable Devices: TouchOSC and Protokol&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding:  10px&amp;quot; | [[5. Troubleshooting]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[6. External links]]&lt;br /&gt;
|}&lt;br /&gt;
[[Category:OSC]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=OSC_command_reference&amp;diff=6173</id>
		<title>OSC command reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=OSC_command_reference&amp;diff=6173"/>
		<updated>2026-08-08T15:40:46Z</updated>

		<summary type="html">&lt;p&gt;Admin: Admin moved page MXW OSC command reference to OSC command reference: Rename: omit &amp;#039;MXW&amp;#039; prefix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Here are listed all the commands that MXW recognizes.&lt;br /&gt;
&lt;br /&gt;
=== Legend ===&lt;br /&gt;
&amp;lt;div&amp;gt; &lt;br /&gt;
==== Variables ====&lt;br /&gt;
When variables are found in the address of a command ( and not only as the value to be sent), the &amp;lt;code&amp;gt;$+index&amp;lt;/code&amp;gt; notation has been employed :&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/track/$1 [value]  &amp;lt;/code&amp;gt; indicates that a variable  &amp;lt;code&amp;gt;$1&amp;lt;/code&amp;gt; has to be chosen and will specify the correct address where the value will be sent.&amp;lt;br&amp;gt;If the goal is, for example, to reduce of 50% the opacity of the 2nd track, the correct command would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/track/2 0.5 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Values ====&lt;br /&gt;
The standard used to represent the available values for each command (column “RANGE or TOKEN”) is:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;FLOATS&#039;&#039; are represented with one decimal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt; &amp;amp;rarr; all float values between 0 and 1 included&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;INTEGERS&#039;&#039; are represented with numbers or descriptions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;1 .. 5&amp;lt;/code&amp;gt; &amp;amp;rarr; all integers between 1 and 5 included ( 1 , 2 , 3 , 4 , 5 ) &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;1 .. (MAX n layers)&amp;lt;/code&amp;gt; &amp;amp;rarr; all the integers between 1 and the maximum index of layers in MXW (e.g. if 6 layers are being used the values are integers between 1 and 6 included)&lt;br /&gt;
&lt;br /&gt;
When only one number is indicated it means that only one option is given. This is found in addresses of buttons, checkboxes and in the options where &amp;quot;0&amp;quot; or &amp;quot;1&amp;quot; are the only significant values&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;STRINGS&#039;&#039; are represented between quotation marks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;“info”&amp;lt;/code&amp;gt; means that the string info has to be used at the end of the command&lt;br /&gt;
&lt;br /&gt;
E.G.  to ask for information about the patches the command&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/set info &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
would be sent.&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;code&amp;gt;“name”&amp;lt;/code&amp;gt; is contained in the available string variable, then the content is to be substituted with the actual name.&lt;br /&gt;
 &lt;br /&gt;
E.G. :  to select and play a patch called “patch_one” from its name, the address &amp;lt;code&amp;gt;/mxw/set&amp;lt;/code&amp;gt; with tokens &amp;lt;code&amp;gt;&amp;quot;play&amp;quot; &amp;quot;name_of_patch&amp;quot;&amp;lt;/code&amp;gt; has to be used, resulting in this OSC command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/set play patch_one&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; is found it means that two options can deliver a similar result. One of the two formats has to be used at one time.&lt;br /&gt;
&lt;br /&gt;
===Set Reference===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! OSC ADDRESS !! DESCRIPTION !! RANGE  or TOKEN&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt; /mxw/set&amp;lt;/code&amp;gt;||get information on the patches|| &amp;lt;code&amp;gt;“info”&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/set&amp;lt;/code&amp;gt;||play a specific patch|| &amp;lt;code&amp;gt;“play” “name_of_patch”&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/set&amp;lt;/code&amp;gt;||choose a patch|| &amp;lt;code&amp;gt;1 .. (MAX n patches)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/editor&amp;lt;/code&amp;gt;||choose UI tab|| &amp;lt;code&amp;gt;0 .. 5&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/trackmanager&amp;lt;/code&amp;gt;||choose active track || &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt; &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; &amp;lt;code&amp;gt;1 .. 4&amp;lt;/code&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/trackmanager&amp;lt;/code&amp;gt;||clear all tracks || &amp;lt;code&amp;gt;&amp;quot;clear&amp;quot;&amp;lt;/code&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/layermanager&amp;lt;/code&amp;gt; ||choose active layer || &amp;lt;code&amp;gt;1 .. (MAX n layers)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/layermanager&amp;lt;/code&amp;gt;||clear layers in active track|| &amp;lt;code&amp;gt;&amp;quot;clear&amp;quot;&amp;lt;/code&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/beatbutton&amp;lt;/code&amp;gt; || Send pulse to beat-button (BPM)|| &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist info&amp;lt;/code&amp;gt; || return information on the state of the playback of playlist|| &amp;lt;code&amp;gt;&amp;quot;info&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist select&amp;lt;/code&amp;gt; || jump to cue by name || &amp;lt;code&amp;gt;&amp;quot;select&amp;quot; &amp;quot;cuename&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/gotostart&amp;lt;/code&amp;gt; || stop and go to first track on list&amp;lt;ref&amp;gt;The functionality of &#039;&#039;gotostart&#039;&#039; is the same as the &#039;&#039;gotostart&#039;&#039; button in the MXW playlist GUI ( ❙❙◀ ),  so the command has to be sent two times to reset the playlist at the original state.&amp;lt;/ref&amp;gt;|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/gotoprev&amp;lt;/code&amp;gt; || go to previous cue|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/play&amp;lt;/code&amp;gt; || play active item|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/pause&amp;lt;/code&amp;gt; || pause active playing clip|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/gotonext&amp;lt;/code&amp;gt; || go to next cue|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/gotocueandplay&amp;lt;/code&amp;gt; || go to  a specific cue and immediately play|| &amp;lt;code&amp;gt;0..n (MAX n rows)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/gotocue&amp;lt;/code&amp;gt; || go to a specific cue|| &amp;lt;code&amp;gt;0..n (MAX n rows)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/container/active&amp;lt;/code&amp;gt; || info about the total playlist container|| &amp;lt;code&amp;gt;&amp;quot;info&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/container/active/column/$1/row/$2&amp;lt;/code&amp;gt; || info about the selected field in the playlist grid|| $1 &amp;amp;rarr; &amp;lt;code&amp;gt;0 .. (MAX n columns)&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;$2 &amp;amp;rarr; &amp;lt;code&amp;gt;1 .. (MAX n rows)&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&amp;quot;info&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/set/first&amp;lt;/code&amp;gt; || go to first patch on the list|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/set/prev&amp;lt;/code&amp;gt; || select the previous patch || &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/set/play&amp;lt;/code&amp;gt; || play selected patch &amp;lt;ref&amp;gt;The button play in the patch tab works like the play button in the MXW playlist GUI, every click will play the following patch.&amp;lt;/ref&amp;gt;|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/set/next&amp;lt;/code&amp;gt;|| select to next patch|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/set&amp;lt;/code&amp;gt;|| clear all patches || &amp;lt;code&amp;gt;&amp;quot;clear&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render&amp;lt;/code&amp;gt;|| change of render opacity|| &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/opacity&amp;lt;/code&amp;gt;|| change of render opacity|| &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/scale&amp;lt;/code&amp;gt;|| change of render scale|| &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/scalexy&amp;lt;/code&amp;gt;|| change of render scale ratio|| &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/translationx&amp;lt;/code&amp;gt;|| change of render position x|| &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/translationy&amp;lt;/code&amp;gt;|| change of render position y|| &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/rotation&amp;lt;/code&amp;gt;|| change of render rotation|| &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/reset&amp;lt;/code&amp;gt;|| reset render changes|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/effect&amp;lt;/code&amp;gt;|| selects wished render fx|| &amp;lt;code&amp;gt;1 .. (MAX n fx) &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/effect/1/param/$1 &amp;lt;/code&amp;gt;|| modifies value of one parameter($1) of the render fx|| $1&amp;amp;rarr; &amp;lt;code&amp;gt;1 .. (MAX n parameters)&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt; &lt;br /&gt;
VALUE &amp;amp;rarr; &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/$1&amp;lt;/code&amp;gt;|| set opacity value of a specific track ($1)|| $1 &amp;amp;rarr; &amp;lt;code&amp;gt;1 .. 4&amp;lt;/code&amp;gt;&lt;br /&gt;
VALUE &amp;amp;rarr; &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active&amp;lt;/code&amp;gt;|| change opacity of active track moving the fader|| &amp;lt;code&amp;gt;0.0 .. 1.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/fader&amp;lt;/code&amp;gt;|| change opacity of active track moving the fader|| &amp;lt;code&amp;gt;0.0 .. 1.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/crossfader&amp;lt;/code&amp;gt;|| activates the crossfading between tracks|| &amp;lt;code&amp;gt;0.0 (OFF) &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; 1.0 (ON)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/mode&amp;lt;/code&amp;gt;|| changes the mode of fading|| &amp;lt;code&amp;gt;1 .. 8&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/preload/$1/trigger&amp;lt;/code&amp;gt;|| trigger preload $1 content to current track|| $1 &amp;amp;rarr; &amp;lt;code&amp;gt;1 .. (MAX n preloads)&amp;lt;/code&amp;gt; &lt;br /&gt;
VALUE &amp;amp;rarr; &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/preload/$1/flipflop&amp;lt;/code&amp;gt;|| flipflop preload $1 content to current track|| $1 &amp;amp;rarr; &amp;lt;code&amp;gt;1 .. (MAX n preloads)&amp;lt;/code&amp;gt; &lt;br /&gt;
VALUE &amp;amp;rarr; &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/play&amp;lt;/code&amp;gt; || toggles play-pause button of live editor || &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/scale&amp;lt;/code&amp;gt; || change of layer scale || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/scalexy&amp;lt;/code&amp;gt; || change of layer scale ratio || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/translationx&amp;lt;/code&amp;gt; || change of layer position x || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/translationy&amp;lt;/code&amp;gt; || change of layer position y || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/rotation&amp;lt;/code&amp;gt; || change of layer rotation || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/mode&amp;lt;/code&amp;gt; || change of layer blend mode || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/aspectmode&amp;lt;/code&amp;gt; || change of layer aspect mode || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/reset&amp;lt;/code&amp;gt; || reset layer changes || &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/keyin&amp;lt;/code&amp;gt; || set keyin of clip of active layer || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/keyout&amp;lt;/code&amp;gt; || set keyout of clip of active layer || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/speed&amp;lt;/code&amp;gt; || set speed of clip of active layer &amp;lt;ref&amp;gt; The values are sent to the &amp;quot;speed fader&amp;quot;, which values go between 5 and -5, they do not act directly on the &amp;quot;speed value&amp;quot;. This means that depending on the active media the available values in the fader will differ. &amp;lt;/ref&amp;gt; || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/position&amp;lt;/code&amp;gt; || set position of clip of active layer || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/mode&amp;lt;/code&amp;gt; ||  set mode of clip of active layer || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effect&amp;lt;/code&amp;gt; || choose active effect || &amp;lt;code&amp;gt;0 .. (MAX n of fx)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effectbank&amp;lt;/code&amp;gt; || selects active effect || &amp;lt;code&amp;gt;0 .. (MAX n of fx)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effect/active/param/$1&amp;lt;/code&amp;gt; || set param $1 of effect || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effect/1/color/1/red&amp;lt;/code&amp;gt; || set red component of color param. || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effect/1/color/1/green&amp;lt;/code&amp;gt; || set green component param. || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effect/1/color/1/blue&amp;lt;/code&amp;gt; || set blue component param. || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effect/1/color/1/hue&amp;lt;/code&amp;gt; || set huecomponent param.  || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effect/1/color/1/saturation&amp;lt;/code&amp;gt; || set saturation | &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effect/1/color/1/value&amp;lt;/code&amp;gt; || set value component param. || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/keystone/element/$1/pivot/col/$2/row/$3/xposition&amp;lt;/code&amp;gt; || move keystone pivot in x || $1 &amp;amp;rarr;  &amp;lt;code&amp;gt;1 .. (MAX n elements)&amp;lt;/code&amp;gt;&lt;br /&gt;
$2 (COLUMN) &amp;amp;rarr; &amp;lt;code&amp;gt;1 &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; 2&amp;lt;/code&amp;gt;&lt;br /&gt;
$3 (ROW) &amp;amp;rarr; &amp;lt;code&amp;gt;1 &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; 2&amp;lt;/code&amp;gt;&lt;br /&gt;
VALUE &amp;amp;rarr; &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/keystone/element/$1/pivot/col/$2/row/$3/yposition&amp;lt;/code&amp;gt; || move keystone pivot in y|| $1 &amp;amp;rarr;  &amp;lt;code&amp;gt;1 .. (MAX n elements)&amp;lt;/code&amp;gt;&lt;br /&gt;
$2 (COLUMN) &amp;amp;rarr; &amp;lt;code&amp;gt;1 &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; 2&amp;lt;/code&amp;gt;&lt;br /&gt;
$3 (ROW) &amp;amp;rarr; &amp;lt;code&amp;gt;1 &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; 2&amp;lt;/code&amp;gt;&lt;br /&gt;
VALUE &amp;amp;rarr; &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/keystone_io_animator&amp;lt;/code&amp;gt; || keystone io animator fader|| &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
[[Category:OSC]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Category:OSC&amp;diff=6172</id>
		<title>Category:OSC</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Category:OSC&amp;diff=6172"/>
		<updated>2026-08-08T15:36:03Z</updated>

		<summary type="html">&lt;p&gt;Admin: Create category page (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Pages documenting how to control MXWendler through the Open Sound Control (OSC) protocol.&lt;br /&gt;
&lt;br /&gt;
The list below is generated automatically from pages tagged &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Category:OSC]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=OSC_command_reference&amp;diff=6171</id>
		<title>OSC command reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=OSC_command_reference&amp;diff=6171"/>
		<updated>2026-08-08T15:36:00Z</updated>

		<summary type="html">&lt;p&gt;Admin: Add Category:OSC at page end (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Here are listed all the commands that MXW recognizes.&lt;br /&gt;
&lt;br /&gt;
=== Legend ===&lt;br /&gt;
&amp;lt;div&amp;gt; &lt;br /&gt;
==== Variables ====&lt;br /&gt;
When variables are found in the address of a command ( and not only as the value to be sent), the &amp;lt;code&amp;gt;$+index&amp;lt;/code&amp;gt; notation has been employed :&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/track/$1 [value]  &amp;lt;/code&amp;gt; indicates that a variable  &amp;lt;code&amp;gt;$1&amp;lt;/code&amp;gt; has to be chosen and will specify the correct address where the value will be sent.&amp;lt;br&amp;gt;If the goal is, for example, to reduce of 50% the opacity of the 2nd track, the correct command would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/track/2 0.5 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Values ====&lt;br /&gt;
The standard used to represent the available values for each command (column “RANGE or TOKEN”) is:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;FLOATS&#039;&#039; are represented with one decimal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt; &amp;amp;rarr; all float values between 0 and 1 included&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;INTEGERS&#039;&#039; are represented with numbers or descriptions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;1 .. 5&amp;lt;/code&amp;gt; &amp;amp;rarr; all integers between 1 and 5 included ( 1 , 2 , 3 , 4 , 5 ) &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;1 .. (MAX n layers)&amp;lt;/code&amp;gt; &amp;amp;rarr; all the integers between 1 and the maximum index of layers in MXW (e.g. if 6 layers are being used the values are integers between 1 and 6 included)&lt;br /&gt;
&lt;br /&gt;
When only one number is indicated it means that only one option is given. This is found in addresses of buttons, checkboxes and in the options where &amp;quot;0&amp;quot; or &amp;quot;1&amp;quot; are the only significant values&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;STRINGS&#039;&#039; are represented between quotation marks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;“info”&amp;lt;/code&amp;gt; means that the string info has to be used at the end of the command&lt;br /&gt;
&lt;br /&gt;
E.G.  to ask for information about the patches the command&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/set info &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
would be sent.&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;code&amp;gt;“name”&amp;lt;/code&amp;gt; is contained in the available string variable, then the content is to be substituted with the actual name.&lt;br /&gt;
 &lt;br /&gt;
E.G. :  to select and play a patch called “patch_one” from its name, the address &amp;lt;code&amp;gt;/mxw/set&amp;lt;/code&amp;gt; with tokens &amp;lt;code&amp;gt;&amp;quot;play&amp;quot; &amp;quot;name_of_patch&amp;quot;&amp;lt;/code&amp;gt; has to be used, resulting in this OSC command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mxw/set play patch_one&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; is found it means that two options can deliver a similar result. One of the two formats has to be used at one time.&lt;br /&gt;
&lt;br /&gt;
===Set Reference===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! OSC ADDRESS !! DESCRIPTION !! RANGE  or TOKEN&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt; /mxw/set&amp;lt;/code&amp;gt;||get information on the patches|| &amp;lt;code&amp;gt;“info”&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/set&amp;lt;/code&amp;gt;||play a specific patch|| &amp;lt;code&amp;gt;“play” “name_of_patch”&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/set&amp;lt;/code&amp;gt;||choose a patch|| &amp;lt;code&amp;gt;1 .. (MAX n patches)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/editor&amp;lt;/code&amp;gt;||choose UI tab|| &amp;lt;code&amp;gt;0 .. 5&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/trackmanager&amp;lt;/code&amp;gt;||choose active track || &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt; &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; &amp;lt;code&amp;gt;1 .. 4&amp;lt;/code&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/trackmanager&amp;lt;/code&amp;gt;||clear all tracks || &amp;lt;code&amp;gt;&amp;quot;clear&amp;quot;&amp;lt;/code&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/layermanager&amp;lt;/code&amp;gt; ||choose active layer || &amp;lt;code&amp;gt;1 .. (MAX n layers)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/layermanager&amp;lt;/code&amp;gt;||clear layers in active track|| &amp;lt;code&amp;gt;&amp;quot;clear&amp;quot;&amp;lt;/code&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/beatbutton&amp;lt;/code&amp;gt; || Send pulse to beat-button (BPM)|| &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist info&amp;lt;/code&amp;gt; || return information on the state of the playback of playlist|| &amp;lt;code&amp;gt;&amp;quot;info&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist select&amp;lt;/code&amp;gt; || jump to cue by name || &amp;lt;code&amp;gt;&amp;quot;select&amp;quot; &amp;quot;cuename&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/gotostart&amp;lt;/code&amp;gt; || stop and go to first track on list&amp;lt;ref&amp;gt;The functionality of &#039;&#039;gotostart&#039;&#039; is the same as the &#039;&#039;gotostart&#039;&#039; button in the MXW playlist GUI ( ❙❙◀ ),  so the command has to be sent two times to reset the playlist at the original state.&amp;lt;/ref&amp;gt;|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/gotoprev&amp;lt;/code&amp;gt; || go to previous cue|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/play&amp;lt;/code&amp;gt; || play active item|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/pause&amp;lt;/code&amp;gt; || pause active playing clip|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/gotonext&amp;lt;/code&amp;gt; || go to next cue|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/gotocueandplay&amp;lt;/code&amp;gt; || go to  a specific cue and immediately play|| &amp;lt;code&amp;gt;0..n (MAX n rows)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/gotocue&amp;lt;/code&amp;gt; || go to a specific cue|| &amp;lt;code&amp;gt;0..n (MAX n rows)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/container/active&amp;lt;/code&amp;gt; || info about the total playlist container|| &amp;lt;code&amp;gt;&amp;quot;info&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/playlist/container/active/column/$1/row/$2&amp;lt;/code&amp;gt; || info about the selected field in the playlist grid|| $1 &amp;amp;rarr; &amp;lt;code&amp;gt;0 .. (MAX n columns)&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;$2 &amp;amp;rarr; &amp;lt;code&amp;gt;1 .. (MAX n rows)&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&amp;quot;info&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/set/first&amp;lt;/code&amp;gt; || go to first patch on the list|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/set/prev&amp;lt;/code&amp;gt; || select the previous patch || &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/set/play&amp;lt;/code&amp;gt; || play selected patch &amp;lt;ref&amp;gt;The button play in the patch tab works like the play button in the MXW playlist GUI, every click will play the following patch.&amp;lt;/ref&amp;gt;|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/set/next&amp;lt;/code&amp;gt;|| select to next patch|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/set&amp;lt;/code&amp;gt;|| clear all patches || &amp;lt;code&amp;gt;&amp;quot;clear&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render&amp;lt;/code&amp;gt;|| change of render opacity|| &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/opacity&amp;lt;/code&amp;gt;|| change of render opacity|| &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/scale&amp;lt;/code&amp;gt;|| change of render scale|| &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/scalexy&amp;lt;/code&amp;gt;|| change of render scale ratio|| &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/translationx&amp;lt;/code&amp;gt;|| change of render position x|| &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/translationy&amp;lt;/code&amp;gt;|| change of render position y|| &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/rotation&amp;lt;/code&amp;gt;|| change of render rotation|| &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/reset&amp;lt;/code&amp;gt;|| reset render changes|| &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/effect&amp;lt;/code&amp;gt;|| selects wished render fx|| &amp;lt;code&amp;gt;1 .. (MAX n fx) &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/render/effect/1/param/$1 &amp;lt;/code&amp;gt;|| modifies value of one parameter($1) of the render fx|| $1&amp;amp;rarr; &amp;lt;code&amp;gt;1 .. (MAX n parameters)&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt; &lt;br /&gt;
VALUE &amp;amp;rarr; &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/$1&amp;lt;/code&amp;gt;|| set opacity value of a specific track ($1)|| $1 &amp;amp;rarr; &amp;lt;code&amp;gt;1 .. 4&amp;lt;/code&amp;gt;&lt;br /&gt;
VALUE &amp;amp;rarr; &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active&amp;lt;/code&amp;gt;|| change opacity of active track moving the fader|| &amp;lt;code&amp;gt;0.0 .. 1.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/fader&amp;lt;/code&amp;gt;|| change opacity of active track moving the fader|| &amp;lt;code&amp;gt;0.0 .. 1.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/crossfader&amp;lt;/code&amp;gt;|| activates the crossfading between tracks|| &amp;lt;code&amp;gt;0.0 (OFF) &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; 1.0 (ON)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/mode&amp;lt;/code&amp;gt;|| changes the mode of fading|| &amp;lt;code&amp;gt;1 .. 8&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/preload/$1/trigger&amp;lt;/code&amp;gt;|| trigger preload $1 content to current track|| $1 &amp;amp;rarr; &amp;lt;code&amp;gt;1 .. (MAX n preloads)&amp;lt;/code&amp;gt; &lt;br /&gt;
VALUE &amp;amp;rarr; &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/preload/$1/flipflop&amp;lt;/code&amp;gt;|| flipflop preload $1 content to current track|| $1 &amp;amp;rarr; &amp;lt;code&amp;gt;1 .. (MAX n preloads)&amp;lt;/code&amp;gt; &lt;br /&gt;
VALUE &amp;amp;rarr; &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/play&amp;lt;/code&amp;gt; || toggles play-pause button of live editor || &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/scale&amp;lt;/code&amp;gt; || change of layer scale || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/scalexy&amp;lt;/code&amp;gt; || change of layer scale ratio || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/translationx&amp;lt;/code&amp;gt; || change of layer position x || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/translationy&amp;lt;/code&amp;gt; || change of layer position y || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/rotation&amp;lt;/code&amp;gt; || change of layer rotation || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/mode&amp;lt;/code&amp;gt; || change of layer blend mode || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/aspectmode&amp;lt;/code&amp;gt; || change of layer aspect mode || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/reset&amp;lt;/code&amp;gt; || reset layer changes || &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/keyin&amp;lt;/code&amp;gt; || set keyin of clip of active layer || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/keyout&amp;lt;/code&amp;gt; || set keyout of clip of active layer || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/speed&amp;lt;/code&amp;gt; || set speed of clip of active layer &amp;lt;ref&amp;gt; The values are sent to the &amp;quot;speed fader&amp;quot;, which values go between 5 and -5, they do not act directly on the &amp;quot;speed value&amp;quot;. This means that depending on the active media the available values in the fader will differ. &amp;lt;/ref&amp;gt; || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/position&amp;lt;/code&amp;gt; || set position of clip of active layer || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/mode&amp;lt;/code&amp;gt; ||  set mode of clip of active layer || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effect&amp;lt;/code&amp;gt; || choose active effect || &amp;lt;code&amp;gt;0 .. (MAX n of fx)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effectbank&amp;lt;/code&amp;gt; || selects active effect || &amp;lt;code&amp;gt;0 .. (MAX n of fx)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effect/active/param/$1&amp;lt;/code&amp;gt; || set param $1 of effect || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effect/1/color/1/red&amp;lt;/code&amp;gt; || set red component of color param. || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effect/1/color/1/green&amp;lt;/code&amp;gt; || set green component param. || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effect/1/color/1/blue&amp;lt;/code&amp;gt; || set blue component param. || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effect/1/color/1/hue&amp;lt;/code&amp;gt; || set huecomponent param.  || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effect/1/color/1/saturation&amp;lt;/code&amp;gt; || set saturation | &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip/effect/1/color/1/value&amp;lt;/code&amp;gt; || set value component param. || &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/keystone/element/$1/pivot/col/$2/row/$3/xposition&amp;lt;/code&amp;gt; || move keystone pivot in x || $1 &amp;amp;rarr;  &amp;lt;code&amp;gt;1 .. (MAX n elements)&amp;lt;/code&amp;gt;&lt;br /&gt;
$2 (COLUMN) &amp;amp;rarr; &amp;lt;code&amp;gt;1 &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; 2&amp;lt;/code&amp;gt;&lt;br /&gt;
$3 (ROW) &amp;amp;rarr; &amp;lt;code&amp;gt;1 &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; 2&amp;lt;/code&amp;gt;&lt;br /&gt;
VALUE &amp;amp;rarr; &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/keystone/element/$1/pivot/col/$2/row/$3/yposition&amp;lt;/code&amp;gt; || move keystone pivot in y|| $1 &amp;amp;rarr;  &amp;lt;code&amp;gt;1 .. (MAX n elements)&amp;lt;/code&amp;gt;&lt;br /&gt;
$2 (COLUMN) &amp;amp;rarr; &amp;lt;code&amp;gt;1 &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; 2&amp;lt;/code&amp;gt;&lt;br /&gt;
$3 (ROW) &amp;amp;rarr; &amp;lt;code&amp;gt;1 &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; 2&amp;lt;/code&amp;gt;&lt;br /&gt;
VALUE &amp;amp;rarr; &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/mxw/keystone_io_animator&amp;lt;/code&amp;gt; || keystone io animator fader|| &amp;lt;code&amp;gt;0 .. 1&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
[[Category:OSC]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=OSC_Reference&amp;diff=6170</id>
		<title>OSC Reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=OSC_Reference&amp;diff=6170"/>
		<updated>2026-08-08T15:35:58Z</updated>

		<summary type="html">&lt;p&gt;Admin: Add Category:OSC at page end (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This reference applies to all different OS. The presented OSC commands are for most part supported in version 6.0 but will be fully functional in version 6.0.08 and above. &lt;br /&gt;
&amp;lt;div class=&amp;quot;noprint&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
This document describes the MXWendler (MXW) OSC Command Interface through an overview of the command structure and practical examples of integration with external controlling software. &lt;br /&gt;
&lt;br /&gt;
== What is OSC? ==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
OSC or „Open Sound Control“ is a Network-based protocol that commonly utilizes the UDP transport mechanism. Originally developed as a successor of the MIDI control protocol, it used nowadays as a practical communication method between platforms.&lt;br /&gt;
&lt;br /&gt;
OSC Features:&lt;br /&gt;
* Connectionless communication architecture&lt;br /&gt;
* Broadcast-type messages&lt;br /&gt;
* High resolution time tag&lt;br /&gt;
* Allowed data formats including numeric, symbolic, and “blob” arguments&lt;br /&gt;
* Open-ended, dynamic, URL-style naming scheme for the receivers&#039; address&lt;br /&gt;
      &lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/Open_Sound_Control [1&amp;lt;nowiki&amp;gt;]&amp;lt;/nowiki&amp;gt; Wikipedia Link]&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px&amp;quot; | [[1. Controlling MXW through OSC]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;1.1 Receiving OSC commands in MXW&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px 10px&amp;quot; | &#039;&#039;1.2 Output OSC from MXW: Send vs. Reply&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px 0px&amp;quot; | [[2. MXW OSC command structure]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;2.1 Sending OSC Values&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;2.2 Examples&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[MXW OSC command reference]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 10px 0px&amp;quot; | [[4. Practical examples: Pure Data and TouchOSC]]&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;4.1 Install Pure Data&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px&amp;quot; | &#039;&#039;4.2 MXW Pd Patch&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 0px 30px 0px&amp;quot; | &#039;&#039;4.3 OSC for portable Devices: TouchOSC and Protokol&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding:  10px&amp;quot; | [[5. Troubleshooting]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[6. External links]]&lt;br /&gt;
|}&lt;br /&gt;
[[Category:OSC]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Category:Python&amp;diff=6169</id>
		<title>Category:Python</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Category:Python&amp;diff=6169"/>
		<updated>2026-08-08T15:33:47Z</updated>

		<summary type="html">&lt;p&gt;Admin: Create category page (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Pages documenting how to control and extend MXWendler through its embedded Python 3.12 interface (the &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt; module, imgui panels, and plugins).&lt;br /&gt;
&lt;br /&gt;
The list below is generated automatically from pages tagged &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Category:Python]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Category:JavaScript&amp;diff=6168</id>
		<title>Category:JavaScript</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Category:JavaScript&amp;diff=6168"/>
		<updated>2026-08-08T15:33:46Z</updated>

		<summary type="html">&lt;p&gt;Admin: Create category page (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Pages documenting how to control MXWendler through its embedded JavaScript (Duktape) interface.&lt;br /&gt;
&lt;br /&gt;
The list below is generated automatically from pages tagged &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Category:JavaScript]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Python_plugin_reference&amp;diff=6167</id>
		<title>Python plugin reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Python_plugin_reference&amp;diff=6167"/>
		<updated>2026-08-08T15:33:32Z</updated>

		<summary type="html">&lt;p&gt;Admin: Add Category:Python at page end (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- MXWendler wiki page: How to create a Python plugin (media and playlist) --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Intended location: https://wiki.mxwendler.net/index.php?title=Python_plugin_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_command_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_imgui_reference --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MXWendler StageDesigner can be extended with &#039;&#039;&#039;Python plugins&#039;&#039;&#039;. A plugin is a plain folder containing a manifest file and a Python module; MXWendler discovers it at startup, shows it in the user interface and calls a defined set of Python functions (&#039;&#039;hooks&#039;&#039;) at the right moments.&lt;br /&gt;
&lt;br /&gt;
Two plugin types exist:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Media plugins&#039;&#039;&#039; produce pixels: they appear as a media source that can be placed in a clip like any video file. Examples: a web browser media, a generative OpenGL cube.&lt;br /&gt;
* &#039;&#039;&#039;Playlist plugins&#039;&#039;&#039; are items in the playlist grid: they run logic when their cue plays. Examples: advance the playlist at a given time of day, write video files, ping a host.&lt;br /&gt;
&lt;br /&gt;
The embedded interpreter is &#039;&#039;&#039;Python 3.12&#039;&#039;&#039;. The general Python command interface (module &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt;) is documented in the [[Python command reference|Python command reference]].&lt;br /&gt;
&lt;br /&gt;
== Plugin anatomy ==&lt;br /&gt;
&lt;br /&gt;
A plugin is one folder with at least two files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
plugins/media/python/plugin_my_effect/&lt;br /&gt;
    mxw_plugin.ini      the manifest: identity, menu entries, addressing&lt;br /&gt;
    mxw_main.py         the Python module with the hook functions&lt;br /&gt;
    (more .py files)    optional: importable as &amp;quot;from plugin_my_effect.xyz import ...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The folder name is the Python package name: additional modules in the folder are imported with absolute imports, e.g. &amp;lt;code&amp;gt;from plugin_my_effect.helpers import foo&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Plugin locations ===&lt;br /&gt;
&lt;br /&gt;
Plugins are searched in several directories. &#039;&#039;&#039;User-controlled locations always override the bundled system location&#039;&#039;&#039;, so a user can replace a built-in plugin by placing a same-named folder in a higher-precedence directory — even without write access to the installation.&lt;br /&gt;
&lt;br /&gt;
Media plugins, descending precedence:&lt;br /&gt;
&lt;br /&gt;
# The open &amp;lt;code&amp;gt;.mxw&amp;lt;/code&amp;gt; project&#039;s &amp;lt;code&amp;gt;plugins/media/python/&amp;lt;/code&amp;gt; tree (opt-in via settings, highest precedence)&lt;br /&gt;
# Directories configured explicitly in the settings (Python tab)&lt;br /&gt;
# The per-user data directory, e.g. &amp;lt;code&amp;gt;%APPDATA%/MXWendler/plugins/media/python/&amp;lt;/code&amp;gt;&lt;br /&gt;
# The installation / resource directory: &amp;lt;code&amp;gt;plugins/media/python/&amp;lt;/code&amp;gt; (also &amp;lt;code&amp;gt;plugins/media/python_dev/&amp;lt;/code&amp;gt;, same precedence, for internal/unpublished plugins)&lt;br /&gt;
&lt;br /&gt;
Playlist plugins, descending precedence:&lt;br /&gt;
&lt;br /&gt;
# The open &amp;lt;code&amp;gt;.mxw&amp;lt;/code&amp;gt; project&#039;s &amp;lt;code&amp;gt;plugins/playlist/python/&amp;lt;/code&amp;gt; tree (opt-in via settings, highest precedence)&lt;br /&gt;
# Directories configured explicitly in the settings (Python tab)&lt;br /&gt;
# The per-user data directory: &amp;lt;code&amp;gt;.../plugins/playlist/python/&amp;lt;/code&amp;gt;&lt;br /&gt;
# The installation / resource directory: &amp;lt;code&amp;gt;plugins/playlist/python/&amp;lt;/code&amp;gt; (also &amp;lt;code&amp;gt;plugins/playlist/python_dev/&amp;lt;/code&amp;gt;, same precedence, for internal/unpublished plugins)&lt;br /&gt;
&lt;br /&gt;
=== The manifest: mxw_plugin.ini ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[mxw_plugin]                            ; must be here&lt;br /&gt;
plugin_version = 1                      ; must be V1&lt;br /&gt;
plugin_script_language = Python         ; must be Python&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Common keys:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Used by !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_menu_parent&amp;lt;/code&amp;gt; || both || Menu the plugin is listed under (e.g. &amp;lt;code&amp;gt;Media&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;IO&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_menu_name&amp;lt;/code&amp;gt; || both || Display name in the menu&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_grid_name&amp;lt;/code&amp;gt; || both || Short name shown in the grid / media list&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_tooltip&amp;lt;/code&amp;gt; || both || Tooltip text&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_menu_level&amp;lt;/code&amp;gt; (media) / &amp;lt;code&amp;gt;plugin_action_level&amp;lt;/code&amp;gt; (playlist) || both || &amp;lt;code&amp;gt;user&amp;lt;/code&amp;gt; (default, visible), &amp;lt;code&amp;gt;development&amp;lt;/code&amp;gt; (visible in debug builds only), &amp;lt;code&amp;gt;disabled&amp;lt;/code&amp;gt; (invisible)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Media-only keys:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_media_scheme&amp;lt;/code&amp;gt; || The URI scheme this plugin handles, e.g. &amp;lt;code&amp;gt;generative&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;web&amp;lt;/code&amp;gt;. Media is addressed as &amp;lt;code&amp;gt;&amp;amp;lt;scheme&amp;amp;gt;://&amp;amp;lt;payload&amp;amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_media_payload&amp;lt;/code&amp;gt; || Optional. If set, the plugin handles exactly &amp;lt;code&amp;gt;scheme://payload&amp;lt;/code&amp;gt;; if omitted, it handles every URI of its scheme. Several plugins can share one scheme and dispatch on the payload.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_media_create_uri&amp;lt;/code&amp;gt; || The URI used when the user creates this media from the menu / Create button.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_playlist_playbackmode_default&amp;lt;/code&amp;gt; || Optional. The clip playback mode a freshly added clip of this media starts in: &amp;lt;code&amp;gt;stop&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;loop&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;oneshot&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;bounce&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jitter&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;random&amp;lt;/code&amp;gt;. Omitted or unknown defaults to &amp;lt;code&amp;gt;loop&amp;lt;/code&amp;gt;. Only seeds the initial mode - a project reload restores the clip&#039;s own saved mode.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Playlist-only keys:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_grid_bg_color&amp;lt;/code&amp;gt; || Item background color as &amp;lt;code&amp;gt;r g b a&amp;lt;/code&amp;gt; floats, e.g. &amp;lt;code&amp;gt;0.05 0.05 0.45 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_accepts_trigger&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; (default &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;). When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, dragging a TRIGGER item onto this item&#039;s grid cell connects it (the drag shows a green &amp;quot;connect&amp;quot; outline) instead of moving/swapping cells, and the plugin can read the connection with &amp;lt;code&amp;gt;mxw.pending_trigger_drop(item_id)&amp;lt;/code&amp;gt;. Set it for a timeline; see [[#Connecting to a TRIGGER item]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_cell_scrub&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; (default &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;). When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, ALT + left-drag across this item&#039;s grid cell scrubs instead of moving the item: the host draws a playhead line and stashes the 0..1 fraction of the cell width each frame, readable with &amp;lt;code&amp;gt;mxw.pending_cell_scrub(item_id)&amp;lt;/code&amp;gt;. Set it for a timeline; see [[#Connecting to a TRIGGER item]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The plugin environment ==&lt;br /&gt;
&lt;br /&gt;
=== Per-instance state ===&lt;br /&gt;
&lt;br /&gt;
One Python module serves &#039;&#039;&#039;many simultaneous instances&#039;&#039;&#039; (several clips using the same media plugin, several copies of a playlist item). Before every hook call, the host sets module globals identifying the instance:&lt;br /&gt;
&lt;br /&gt;
* Media plugins: &amp;lt;code&amp;gt;media_id&amp;lt;/code&amp;gt; (integer)&lt;br /&gt;
* Playlist plugins: &amp;lt;code&amp;gt;item_id&amp;lt;/code&amp;gt; (integer) and &amp;lt;code&amp;gt;item_position&amp;lt;/code&amp;gt; (tuple &amp;lt;code&amp;gt;(x, y)&amp;lt;/code&amp;gt;, the grid position)&lt;br /&gt;
&lt;br /&gt;
The standard pattern is a module-level dictionary keyed by the id:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
storage = {}&lt;br /&gt;
&lt;br /&gt;
def onCreate():                    # playlist; media plugins use onOpen(uri)&lt;br /&gt;
    storage[item_id] = my_instance_state()&lt;br /&gt;
&lt;br /&gt;
def onDelete():&lt;br /&gt;
    storage.pop(item_id, None)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Host modules ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt; — the MXWendler command interface (playlist control, layers, clips, ...), see the [[Python command reference|Python command reference]].&lt;br /&gt;
* &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt; — Dear ImGui bindings for drawing settings panels inside MXWendler (used by &amp;lt;code&amp;gt;onRenderPanel()&amp;lt;/code&amp;gt;), documented in the [[Python imgui reference|Python ImGui Reference]].&lt;br /&gt;
&lt;br /&gt;
=== Installing own modules with mxw-pip ===&lt;br /&gt;
&lt;br /&gt;
Plugins may use third-party packages (&amp;lt;code&amp;gt;numpy&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;moderngl&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;opencv-python&amp;lt;/code&amp;gt;, ...). Packages are not installed into the installation folder — the &#039;&#039;&#039;mxw-pip&#039;&#039;&#039; helper (shipped next to the StageDesigner executable) installs them into the current user&#039;s writable folder, &#039;&#039;&#039;no administrator rights required&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%APPDATA%\Python\Python312\site-packages&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is exactly the directory StageDesigner prepends to &amp;lt;code&amp;gt;sys.path&amp;lt;/code&amp;gt; when the option &#039;&#039;&#039;Prepend user site-path&#039;&#039;&#039; is enabled (Settings → Python tab).&lt;br /&gt;
&lt;br /&gt;
mxw-pip runs &amp;lt;code&amp;gt;pip&amp;lt;/code&amp;gt; with the &#039;&#039;&#039;Python 3.12 shipped with StageDesigner&#039;&#039;&#039; (&amp;lt;code&amp;gt;python.exe&amp;lt;/code&amp;gt; in the installation folder / in its &amp;lt;code&amp;gt;python312/&amp;lt;/code&amp;gt; subfolder) — nothing else needs to be installed. Only when the shipped interpreter is missing does it fall back to a system Python (&amp;lt;code&amp;gt;py -3.12&amp;lt;/code&amp;gt;, then &amp;lt;code&amp;gt;python&amp;lt;/code&amp;gt; on &amp;lt;code&amp;gt;PATH&amp;lt;/code&amp;gt;), which must be 3.12 so binary wheels match the runtime ABI.&lt;br /&gt;
&lt;br /&gt;
Step by step:&lt;br /&gt;
&lt;br /&gt;
# Open &#039;&#039;&#039;Settings → Python&#039;&#039;&#039; and enable &#039;&#039;&#039;Prepend user site-path&#039;&#039;&#039;. The two installer buttons below are only active while this option is on, because mxw-pip installs into exactly that folder. Enabling applies immediately; disabling takes full effect after a restart.&lt;br /&gt;
# Click &#039;&#039;&#039;Launch CMD window with mxw-pip module installer..&#039;&#039;&#039; — this opens the installer shell (&amp;lt;code&amp;gt;mxw-pip-shell.bat&amp;lt;/code&amp;gt;). In the shell, type:&lt;br /&gt;
#: &amp;lt;pre&amp;gt;mxw-pip install &amp;lt;modulename&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
#: for example:&lt;br /&gt;
#: &amp;lt;pre&amp;gt;mxw-pip install moderngl&amp;lt;/pre&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Restart MXWendler StageDesigner&#039;&#039;&#039; so the new module is loaded.&lt;br /&gt;
&lt;br /&gt;
Other &amp;lt;code&amp;gt;pip&amp;lt;/code&amp;gt; subcommands are passed through unchanged, e.g. &amp;lt;code&amp;gt;mxw-pip list&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw-pip show moderngl&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw-pip uninstall moderngl&amp;lt;/code&amp;gt;. The button &#039;&#039;&#039;Open per-user module install folder..&#039;&#039;&#039; next to the installer button shows the target directory in the Explorer. Both &amp;lt;code&amp;gt;mxw-pip.bat&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;mxw-pip-shell.bat&amp;lt;/code&amp;gt; can also be run directly from the installation folder in any command prompt.&lt;br /&gt;
&lt;br /&gt;
Because the target folder lives in the user profile, every user keeps their own module set, and reinstalling / updating StageDesigner never touches the installed modules.&lt;br /&gt;
&lt;br /&gt;
=== Error handling ===&lt;br /&gt;
&lt;br /&gt;
Exceptions raised by a hook are reported to the interpreter console (IO dialog) — throttled, so a per-frame error does not flood the log. A &#039;&#039;&#039;per-frame hook that throws is blacklisted&#039;&#039;&#039;: it is not called again until the plugin is reloaded, so one broken callback cannot stall the render loop. Playlist plugins can be hot-reloaded from disk (state is snapshotted via &amp;lt;code&amp;gt;onSave()&amp;lt;/code&amp;gt;, the module source re-executed, then &amp;lt;code&amp;gt;onCreate()&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;onLoad()&amp;lt;/code&amp;gt; restore each instance), which also clears the blacklist.&lt;br /&gt;
&lt;br /&gt;
== Media plugins ==&lt;br /&gt;
&lt;br /&gt;
A media plugin is addressed by a URI: &amp;lt;code&amp;gt;&amp;amp;lt;scheme&amp;amp;gt;://&amp;amp;lt;payload&amp;amp;gt;&amp;lt;/code&amp;gt;, for example &amp;lt;code&amp;gt;generative://cube_spin_opengl&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;web://https://mxwendler.net&amp;lt;/code&amp;gt;. Every created media instance internally carries a unique instance token so two clips never share state; the plugin always sees the clean URI.&lt;br /&gt;
&lt;br /&gt;
=== Hooks ===&lt;br /&gt;
&lt;br /&gt;
All hooks are optional except &amp;lt;code&amp;gt;onOpen&amp;lt;/code&amp;gt; and &#039;&#039;&#039;one of the two render hooks&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Hook !! Direction !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onOpen(uri)&amp;lt;/code&amp;gt; || returns &amp;lt;code&amp;gt;(width, height, length, fps, has_alpha)&amp;lt;/code&amp;gt; || Called when the media is created / loaded. Create the per-instance state here. Do &#039;&#039;&#039;not&#039;&#039;&#039; touch OpenGL yet (see below).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onRenderFrame(frame)&amp;lt;/code&amp;gt; || returns a pixel buffer || Approach 1 and 2: return a &amp;lt;code&amp;gt;H*W*4&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;uint8&amp;lt;/code&amp;gt; buffer (bytes / bytearray / numpy), &#039;&#039;&#039;BGRA&#039;&#039;&#039; byte order, top-down. The host uploads it into the media texture.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onRenderFrameGL(frame, texture, width, height)&amp;lt;/code&amp;gt; || returns &amp;lt;code&amp;gt;bool&amp;lt;/code&amp;gt; || Approach 3: render &#039;&#039;&#039;directly into the media texture&#039;&#039;&#039; — &amp;lt;code&amp;gt;texture&amp;lt;/code&amp;gt; is its raw GL handle. Return &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; when the frame is in the texture; the pixel upload path is then skipped. Tried before &amp;lt;code&amp;gt;onRenderFrame&amp;lt;/code&amp;gt;; a plugin implements one of the two.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onClose()&amp;lt;/code&amp;gt; || — || The media is destroyed: release per-instance resources.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onRenderPanel()&amp;lt;/code&amp;gt; || — || Draw ImGui controls (via &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt;) in the clip panel, above the Video Info section.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSizeChange(w, h)&amp;lt;/code&amp;gt; || — || The host changed the render size: recreate size-dependent resources.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSpeedRange()&amp;lt;/code&amp;gt; || returns &amp;lt;code&amp;gt;(min, max)&amp;lt;/code&amp;gt; || Allowed clip playback speed range. Without it the media is locked to speed 1.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSetSpeed(speed)&amp;lt;/code&amp;gt; || — || The clip playback speed changed. Not clamped: 0 and negative values are allowed.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSave()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;onLoad(state)&amp;lt;/code&amp;gt; || string round-trip || Persist per-instance state in the project file.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onDisplayName()&amp;lt;/code&amp;gt; || returns string || Optional live display name (e.g. the web plugin reports the current page URL).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onGetParams()&amp;lt;/code&amp;gt; || returns a list of dicts || Declare addressable parameters, called once per instance and cached: &amp;lt;code&amp;gt;{&amp;quot;name&amp;quot;: str, &amp;quot;type&amp;quot;: &amp;quot;float&amp;quot;|&amp;quot;string&amp;quot;, &amp;quot;min&amp;quot;: float, &amp;quot;max&amp;quot;: float, &amp;quot;default&amp;quot;: float|str}&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;min&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;max&amp;lt;/code&amp;gt; ignored for &amp;lt;code&amp;gt;&amp;quot;string&amp;quot;&amp;lt;/code&amp;gt;; &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; defaults to &amp;lt;code&amp;gt;&amp;quot;float&amp;quot;&amp;lt;/code&amp;gt;).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onParamChanged(index, value)&amp;lt;/code&amp;gt; || — || A parameter was set via OSC, Python or JS at &amp;lt;code&amp;gt;.../clip/media/1/param/&amp;amp;lt;index+1&amp;amp;gt;&amp;lt;/code&amp;gt; (0-based &amp;lt;code&amp;gt;index&amp;lt;/code&amp;gt;). Store or apply it — the host never caches the value itself.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Parameters are addressed exactly like shader effect parameters, e.g. &amp;lt;code&amp;gt;/mxw/track/2/layer/1/clip/media/1/param/1 0.8&amp;lt;/code&amp;gt; or, for a &amp;lt;code&amp;gt;&amp;quot;string&amp;quot;&amp;lt;/code&amp;gt;-typed param, &amp;lt;code&amp;gt;/mxw/track/2/layer/1/clip/media/1/param/2 &amp;quot;https://www.mxwendler.net&amp;quot;&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;media/1&amp;lt;/code&amp;gt; segment reflects the clip&#039;s single active media slot (any other index is out of range). Because the host does not persist a param&#039;s value, a plugin that wants one to survive a project reload must fold it into its own &amp;lt;code&amp;gt;onSave()&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;onLoad()&amp;lt;/code&amp;gt; and hand the restored value back as &amp;lt;code&amp;gt;onGetParams()&amp;lt;/code&amp;gt;&#039;s &amp;lt;code&amp;gt;&amp;quot;default&amp;quot;&amp;lt;/code&amp;gt; — which runs after &amp;lt;code&amp;gt;onLoad()&amp;lt;/code&amp;gt; already restored the instance state.&lt;br /&gt;
&lt;br /&gt;
=== OpenGL rules for media plugins ===&lt;br /&gt;
&lt;br /&gt;
These rules apply to approaches 2 and 3:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Never create a standalone GL context&#039;&#039;&#039; (no windowed/standalone &amp;lt;code&amp;gt;moderngl.create_context()&amp;lt;/code&amp;gt; at import or in &amp;lt;code&amp;gt;onOpen&amp;lt;/code&amp;gt;). MXWendler makes its own context current every frame; GL objects created in a foreign context will be dereferenced against the wrong context and crash the driver.&lt;br /&gt;
* Instead, &#039;&#039;&#039;lazily attach on the first render call&#039;&#039;&#039;: &amp;lt;code&amp;gt;moderngl.create_context()&amp;lt;/code&amp;gt; inside &amp;lt;code&amp;gt;onRenderFrame / onRenderFrameGL&amp;lt;/code&amp;gt; attaches to MXWendler&#039;s context, which the host guarantees to be current there.&lt;br /&gt;
* The host &#039;&#039;&#039;snapshots and restores all relevant GL state&#039;&#039;&#039; around the render hooks (FBO bindings, program, VAO, buffers, viewport, enables, pixel store). The plugin does not need to unbind anything.&lt;br /&gt;
&lt;br /&gt;
=== Approach 1: rendering into pixels (CPU) ===&lt;br /&gt;
&lt;br /&gt;
The simplest approach: compute the frame on the CPU and return it. No OpenGL knowledge required. The host uploads the buffer into the media texture through a PBO (pixel buffer object) double-buffer, so the upload is asynchronous and cheap — the cost of this approach is the CPU rendering itself.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
W, H = 640, 360&lt;br /&gt;
storage = {}&lt;br /&gt;
&lt;br /&gt;
def onOpen(uri):&lt;br /&gt;
    storage[media_id] = {&amp;quot;phase&amp;quot;: 0.0}&lt;br /&gt;
    return (W, H, 1, 60.0, True)          # width, height, length, fps, has_alpha&lt;br /&gt;
&lt;br /&gt;
def onRenderFrame(frame):&lt;br /&gt;
    inst = storage[media_id]&lt;br /&gt;
    inst[&amp;quot;phase&amp;quot;] += 0.01&lt;br /&gt;
    # a moving horizontal gradient, BGRA byte order, top-down&lt;br /&gt;
    x = (np.linspace(0.0, 1.0, W) + inst[&amp;quot;phase&amp;quot;]) % 1.0&lt;br /&gt;
    row = np.zeros((W, 4), dtype=np.uint8)&lt;br /&gt;
    row[:, 0] = (x * 255).astype(np.uint8)     # B&lt;br /&gt;
    row[:, 2] = ((1 - x) * 255).astype(np.uint8)  # R&lt;br /&gt;
    row[:, 3] = 255                            # A&lt;br /&gt;
    return np.ascontiguousarray(np.tile(row, (H, 1, 1)))&lt;br /&gt;
&lt;br /&gt;
def onClose():&lt;br /&gt;
    storage.pop(media_id, None)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use this for: generated images, PIL/Pillow output, OpenCV results, slow-changing content.&lt;br /&gt;
&lt;br /&gt;
=== Approach 2: rendering into an FBO and streaming ===&lt;br /&gt;
&lt;br /&gt;
Render with OpenGL (e.g. via &#039;&#039;&#039;ModernGL&#039;&#039;&#039;, installed once with &amp;lt;code&amp;gt;mxw-pip install moderngl numpy&amp;lt;/code&amp;gt;) into an offscreen framebuffer, read the pixels back and return them like in approach 1. The scene renders on the GPU, but every frame makes a round trip GPU → CPU (&amp;lt;code&amp;gt;fbo.read()&amp;lt;/code&amp;gt;) → GPU (PBO upload).&lt;br /&gt;
&lt;br /&gt;
Bundled reference: &amp;lt;code&amp;gt;plugins/media/python/plugin_opengl_cube&amp;lt;/code&amp;gt; ([https://github.com/mxwendler/mxw-plugin-opengl-cube github]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import moderngl&lt;br /&gt;
&lt;br /&gt;
storage = {}&lt;br /&gt;
&lt;br /&gt;
class inst_t:&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self.ctx = None&lt;br /&gt;
        self.fbo = None&lt;br /&gt;
&lt;br /&gt;
def onOpen(uri):&lt;br /&gt;
    storage[media_id] = inst_t()&lt;br /&gt;
    return (1024, 1024, 1, 60.0, True)&lt;br /&gt;
&lt;br /&gt;
def onRenderFrame(frame):&lt;br /&gt;
    inst = storage[media_id]&lt;br /&gt;
    if inst.ctx is None:&lt;br /&gt;
        # first frame: attach to MXWendler&#039;s context (never earlier!)&lt;br /&gt;
        inst.ctx = moderngl.create_context()&lt;br /&gt;
        color = inst.ctx.texture((1024, 1024), 4)&lt;br /&gt;
        depth = inst.ctx.depth_renderbuffer((1024, 1024))&lt;br /&gt;
        inst.fbo = inst.ctx.framebuffer([color], depth)&lt;br /&gt;
        # ... build program / vao here ...&lt;br /&gt;
&lt;br /&gt;
    inst.fbo.use()&lt;br /&gt;
    inst.ctx.clear(0.0, 0.0, 0.0, 0.0, depth=1.0)&lt;br /&gt;
    # ... draw the scene ...&lt;br /&gt;
&lt;br /&gt;
    # read back: GL is bottom-up RGBA, the host wants top-down BGRA&lt;br /&gt;
    raw = inst.fbo.read(components=4, alignment=1)&lt;br /&gt;
    img = np.frombuffer(raw, dtype=np.uint8).reshape((1024, 1024, 4))&lt;br /&gt;
    img = np.flipud(img)&lt;br /&gt;
    return np.ascontiguousarray(img[:, :, [2, 1, 0, 3]])&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use this for: GPU-rendered content when you also need the pixels on the CPU (analysis, recording), or as a stepping stone to approach 3.&lt;br /&gt;
&lt;br /&gt;
=== Approach 3: rendering into a bound texture target (direct) ===&lt;br /&gt;
&lt;br /&gt;
The fastest path: the host passes the &#039;&#039;&#039;raw GL handle of the media texture&#039;&#039;&#039; to &amp;lt;code&amp;gt;onRenderFrameGL&amp;lt;/code&amp;gt;. The plugin attaches it to its own framebuffer and renders straight into it. &#039;&#039;&#039;No readback, no upload, no texture streaming&#039;&#039;&#039; — the frame never leaves the GPU.&lt;br /&gt;
&lt;br /&gt;
Bundled reference: &amp;lt;code&amp;gt;plugins/media/python/plugin_opengl_cube_direct&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import moderngl&lt;br /&gt;
&lt;br /&gt;
storage = {}&lt;br /&gt;
&lt;br /&gt;
class inst_t:&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self.ctx = None&lt;br /&gt;
        self.fbo = None&lt;br /&gt;
        self.depth = None&lt;br /&gt;
        self.fbo_key = None       # (texture, w, h) the fbo was built for&lt;br /&gt;
&lt;br /&gt;
def onOpen(uri):&lt;br /&gt;
    storage[media_id] = inst_t()&lt;br /&gt;
    return (1024, 1024, 1, 60.0, True)&lt;br /&gt;
&lt;br /&gt;
def onRenderFrameGL(frame, texture, width, height):&lt;br /&gt;
    inst = storage[media_id]&lt;br /&gt;
    if inst.ctx is None:&lt;br /&gt;
        inst.ctx = moderngl.create_context()   # attach to MXWendler&#039;s context&lt;br /&gt;
        # ... build program / vao here ...&lt;br /&gt;
&lt;br /&gt;
    # (re)wrap the host texture when the handle or size changed: the host&lt;br /&gt;
    # recreates the media texture on a render size change&lt;br /&gt;
    if inst.fbo_key != (texture, width, height):&lt;br /&gt;
        if inst.fbo:&lt;br /&gt;
            inst.fbo.release()&lt;br /&gt;
        if inst.depth:&lt;br /&gt;
            inst.depth.release()&lt;br /&gt;
        color = inst.ctx.external_texture(texture, (width, height), 4, 0, &amp;quot;f1&amp;quot;)&lt;br /&gt;
        inst.depth = inst.ctx.depth_renderbuffer((width, height))&lt;br /&gt;
        inst.fbo = inst.ctx.framebuffer([color], inst.depth)&lt;br /&gt;
        inst.fbo_key = (texture, width, height)&lt;br /&gt;
&lt;br /&gt;
    inst.fbo.use()&lt;br /&gt;
    inst.ctx.clear(0.0, 0.0, 0.0, 0.0, depth=1.0)&lt;br /&gt;
    # ... draw the scene; flip Y in the projection, see below ...&lt;br /&gt;
&lt;br /&gt;
    return True    # the frame is in the texture: host skips the upload path&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rules specific to the direct approach:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Never &amp;lt;code&amp;gt;release()&amp;lt;/code&amp;gt; the external texture wrapper&#039;&#039;&#039; — the GL texture belongs to MXWendler. Only release your own framebuffer and depth renderbuffer.&lt;br /&gt;
* &#039;&#039;&#039;Rebuild the framebuffer when &amp;lt;code&amp;gt;(texture, width, height)&amp;lt;/code&amp;gt; changes.&#039;&#039;&#039; The handle is not stable: a render size change makes the host recreate the media texture.&lt;br /&gt;
* &#039;&#039;&#039;Flip Y.&#039;&#039;&#039; MXWendler media textures are top-down (row 0 = top of the image), a GL render is bottom-up. Negate the Y row of your projection matrix (approaches 1/2 flip on the CPU instead, e.g. with &amp;lt;code&amp;gt;numpy.flipud&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Choosing an approach ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! !! 1: Pixels (CPU) !! 2: FBO + streaming !! 3: Direct texture&lt;br /&gt;
|-&lt;br /&gt;
| Scene renders on || CPU || GPU || GPU&lt;br /&gt;
|-&lt;br /&gt;
| Per-frame copies || CPU → GPU upload || GPU → CPU readback + CPU → GPU upload || none&lt;br /&gt;
|-&lt;br /&gt;
| OpenGL required || no || yes || yes&lt;br /&gt;
|-&lt;br /&gt;
| CPU access to the pixels || yes (you made them) || yes (after readback) || no&lt;br /&gt;
|-&lt;br /&gt;
| Typical use || generated images, PIL, OpenCV || GPU render that also needs CPU pixels || pure GPU generative content, best performance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Playlist plugins ==&lt;br /&gt;
&lt;br /&gt;
A playlist plugin is an item placed in the playlist grid. It participates in the cue lifecycle: it can run logic when its cue is played, every frame while its cue is active, or every frame globally. Playlist control functions (&amp;lt;code&amp;gt;mxw.playlist.play()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.playlist.navigate_index()&amp;lt;/code&amp;gt;, ...) are documented in the [[Python command reference|Python command reference]].&lt;br /&gt;
&lt;br /&gt;
=== Hooks ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Hook !! Required !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onCreate()&amp;lt;/code&amp;gt; || yes || A new instance was placed in the grid (also called after hot-reload): create the per-instance state entry.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onDelete()&amp;lt;/code&amp;gt; || yes || The instance was deleted: release the state entry.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onAction()&amp;lt;/code&amp;gt; || yes || The item&#039;s cue was played (the item &#039;&#039;fires&#039;&#039;).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onPostAction()&amp;lt;/code&amp;gt; || no || Called after the action completed.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSave()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;onLoad(state)&amp;lt;/code&amp;gt; || yes || Serialize / restore per-instance state (string). Called on project save/load and around hot-reload.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onRenderPanel()&amp;lt;/code&amp;gt; || yes || Draw the item&#039;s settings panel with &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getText()&amp;lt;/code&amp;gt; || yes || Detail text appended to the item&#039;s grid label.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onNewFrameAlways()&amp;lt;/code&amp;gt; || no || Called every rendered frame, regardless of cue state.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onNewFrameInPlayoutCue()&amp;lt;/code&amp;gt; || no || Called every rendered frame while the item&#039;s cue is the active playout cue.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onPause(is_paused)&amp;lt;/code&amp;gt; || no || Pause was pressed / released.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onPreparePlayback()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;onCleanup()&amp;lt;/code&amp;gt; || no || Prepare / release playout resources.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onActivateInUI()&amp;lt;/code&amp;gt; || no || The item was selected in the user interface.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onActiveCueChange(direction)&amp;lt;/code&amp;gt; || no || The active cue changed past this item (navigation).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSettingsChanged()&amp;lt;/code&amp;gt; || no || Item settings were changed from outside.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getDuration()&amp;lt;/code&amp;gt; || no || Report the item&#039;s action duration in milliseconds.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getTimeSinceOnActionIssued()&amp;lt;/code&amp;gt; || no || Report elapsed action time in milliseconds (drives the progress display).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getColorBG()&amp;lt;/code&amp;gt; || no || Return a &amp;lt;code&amp;gt;mxw_imgui.Vec4&amp;lt;/code&amp;gt; (rgb 0..255) to set the grid cell background color dynamically.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;renderBlinking()&amp;lt;/code&amp;gt; || no || Return &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; to make the grid cell blink.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getProgress()&amp;lt;/code&amp;gt; || no || Return &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt; to fill the cell&#039;s bottom progress bar (the same bar the built-in advance/fade items draw); &amp;lt;code&amp;gt;&amp;amp;lt;= 0&amp;lt;/code&amp;gt; draws nothing.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Connecting to a TRIGGER item ===&lt;br /&gt;
&lt;br /&gt;
A playlist plugin (e.g. a keyframe timeline) can bind to a TRIGGER item and animate its layer/clip controls. The user drops a trigger either onto the plugin&#039;s settings panel or onto its grid cell; the plugin resolves the connection to the trigger&#039;s grid &amp;lt;code&amp;gt;(col, row)&amp;lt;/code&amp;gt; and enumerates its controls from there. No need to play the trigger first — the controls are read from the connected preload&#039;s fixture layer, and the very same &amp;lt;code&amp;gt;(col,row)&amp;lt;/code&amp;gt; address resolves the &#039;&#039;live&#039;&#039; layer during playout.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Function !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw_imgui.accept_trigger_drop()&amp;lt;/code&amp;gt; || Makes the current panel window a drop target for a trigger; returns the dropped trigger&#039;s 1-based &amp;lt;code&amp;gt;(col, row)&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;(-1, -1)&amp;lt;/code&amp;gt;. Handles the &amp;quot;drop onto the panel&amp;quot; route.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw.pending_trigger_drop(item_id)&amp;lt;/code&amp;gt; || Returns a &amp;lt;code&amp;gt;(col, row)&amp;lt;/code&amp;gt; stashed by the host when a trigger was dropped onto &#039;&#039;this&#039;&#039; plugin item&#039;s grid cell (pass your own &amp;lt;code&amp;gt;item_id&amp;lt;/code&amp;gt;), or &amp;lt;code&amp;gt;(-1, -1)&amp;lt;/code&amp;gt;. Handles the &amp;quot;drop onto the grid cell&amp;quot; route.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw.trigger_controls(col, row)&amp;lt;/code&amp;gt; || Returns the trigger&#039;s animatable (slider) controls as &amp;lt;code&amp;gt;(label, address)&amp;lt;/code&amp;gt; pairs — layer, clip, effect and media params. Re-read it every frame: controls the user swaps on the clip appear/vanish live. Each &amp;lt;code&amp;gt;address&amp;lt;/code&amp;gt; is usable with &amp;lt;code&amp;gt;mxw.widget(address).setValue()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw.pending_cell_scrub(item_id)&amp;lt;/code&amp;gt; || Returns the 0..1 fraction of an ALT + left-drag across &#039;&#039;this&#039;&#039; plugin item&#039;s grid cell (stashed by the host each frame while dragging, consumed on read), or &amp;lt;code&amp;gt;-1.0&amp;lt;/code&amp;gt;. Needs the &amp;lt;code&amp;gt;plugin_cell_scrub&amp;lt;/code&amp;gt; manifest opt-in. Poll it in &amp;lt;code&amp;gt;onNewFrameAlways()&amp;lt;/code&amp;gt; so scrubbing also works while the panel is closed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Poll both drop routes at the top of &amp;lt;code&amp;gt;onRenderPanel()&amp;lt;/code&amp;gt; and store the resulting &amp;lt;code&amp;gt;(col,row)&amp;lt;/code&amp;gt;; then call &amp;lt;code&amp;gt;mxw.trigger_controls()&amp;lt;/code&amp;gt; to (re)build your control list each frame.&lt;br /&gt;
&lt;br /&gt;
A time connection between the connected clip and the plugin follows from these pieces: the clip&#039;s &amp;lt;code&amp;gt;.../clip/Position&amp;lt;/code&amp;gt; control (normalized 0..1) is the clip&#039;s own time axis. Write it when your playhead moves (scrub → seek) and read it every frame to follow the clip when it is scrubbed — or simply playing. See the timeline plugin&#039;s &amp;lt;code&amp;gt;sync_time_link()&amp;lt;/code&amp;gt; for a worked example including the echo filtering (a written Position reads back frame-quantized).&lt;br /&gt;
&lt;br /&gt;
=== Minimal example ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import pickle, codecs&lt;br /&gt;
import mxw&lt;br /&gt;
import mxw_imgui&lt;br /&gt;
&lt;br /&gt;
class state_t:&lt;br /&gt;
    fire_count = 0&lt;br /&gt;
&lt;br /&gt;
storage = {}&lt;br /&gt;
&lt;br /&gt;
def onCreate():&lt;br /&gt;
    storage[item_id] = state_t()&lt;br /&gt;
&lt;br /&gt;
def onDelete():&lt;br /&gt;
    storage.pop(item_id, None)&lt;br /&gt;
&lt;br /&gt;
def onAction():&lt;br /&gt;
    # the item&#039;s cue was played&lt;br /&gt;
    storage[item_id].fire_count += 1&lt;br /&gt;
&lt;br /&gt;
def getText():&lt;br /&gt;
    return &amp;quot; : fired %d times&amp;quot; % storage[item_id].fire_count&lt;br /&gt;
&lt;br /&gt;
def onRenderPanel():&lt;br /&gt;
    inst = storage[item_id]&lt;br /&gt;
    mxw_imgui.text_unformatted(&amp;quot;Fired %d times&amp;quot; % inst.fire_count)&lt;br /&gt;
    if mxw_imgui.button(&amp;quot;Reset&amp;quot;):&lt;br /&gt;
        inst.fire_count = 0&lt;br /&gt;
&lt;br /&gt;
def onSave():&lt;br /&gt;
    return codecs.encode(pickle.dumps(storage[item_id]), &amp;quot;base64&amp;quot;).decode()&lt;br /&gt;
&lt;br /&gt;
def onLoad(serialized):&lt;br /&gt;
    storage[item_id] = pickle.loads(codecs.decode(serialized.encode(), &amp;quot;base64&amp;quot;))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With a manifest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[mxw_plugin]&lt;br /&gt;
plugin_version = 1&lt;br /&gt;
plugin_script_language = Python&lt;br /&gt;
plugin_menu_parent = IO&lt;br /&gt;
plugin_menu_name = Fire Counter&lt;br /&gt;
plugin_grid_name = Counter&lt;br /&gt;
plugin_tooltip = Counts how often its cue was played&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bundled references, all in the [https://github.com/mxwendler/mxw-plugins-playlist mxw-plugins-playlist] repository: &amp;lt;code&amp;gt;plugins/playlist/python/plugin_advance_datetime&amp;lt;/code&amp;gt; (timed playlist navigation, rich settings panel), &amp;lt;code&amp;gt;plugin_video_writer&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;plugin_comment&amp;lt;/code&amp;gt; (a minimal example: a no-op annotation item).&lt;br /&gt;
&lt;br /&gt;
== Example plugins on GitHub ==&lt;br /&gt;
&lt;br /&gt;
The bundled example plugins are maintained as public repositories under [https://github.com/mxwendler github.com/mxwendler], grouped by type — good starting points to fork for an own plugin:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Plugin !! Type !! Approach / purpose !! Repository&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_opengl_cube&amp;lt;/code&amp;gt; || media || Approach 2: ModernGL cube into an offscreen FBO, streamed || [https://github.com/mxwendler/mxw-plugins-media mxw-plugins-media]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_opengl_cube_direct&amp;lt;/code&amp;gt; || media || Approach 3: same cube rendered directly into the media texture || [https://github.com/mxwendler/mxw-plugins-media mxw-plugins-media]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_web_media&amp;lt;/code&amp;gt; || media || A web browser as media source (whole-scheme &amp;lt;code&amp;gt;web://&amp;lt;/code&amp;gt; plugin) || [https://github.com/mxwendler/mxw-plugins-media mxw-plugins-media]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_fragcoord&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;plugin_shadertoy&amp;lt;/code&amp;gt; || media || Shader-as-generative-media (FragCoord.xyz / Shadertoy) || [https://github.com/mxwendler/mxw-plugins-media mxw-plugins-media]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_advance_datetime&amp;lt;/code&amp;gt; || playlist || Timed playlist navigation with a rich settings panel || [https://github.com/mxwendler/mxw-plugins-playlist mxw-plugins-playlist]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_video_writer&amp;lt;/code&amp;gt; || playlist || Write video files from the playlist || [https://github.com/mxwendler/mxw-plugins-playlist mxw-plugins-playlist]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_comment&amp;lt;/code&amp;gt; || playlist || Minimal example: a no-op text annotation item || [https://github.com/mxwendler/mxw-plugins-playlist mxw-plugins-playlist]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Developing a new plugin inside a project ===&lt;br /&gt;
&lt;br /&gt;
The most convenient place to develop a plugin is &#039;&#039;&#039;inside a project folder&#039;&#039;&#039;: the plugin travels with the show, needs no write access to the installation, and overrides a same-named bundled plugin. Conceptually:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Create a project folder&#039;&#039;&#039; — a plain directory that will hold everything belonging to the show, e.g. &amp;lt;code&amp;gt;D:/shows/particles/&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Save the project file there&#039;&#039;&#039; — &#039;&#039;File → Save As..&#039;&#039; into that folder, e.g. &amp;lt;code&amp;gt;D:/shows/particles/particles.mxw&amp;lt;/code&amp;gt;. The folder containing the &amp;lt;code&amp;gt;.mxw&amp;lt;/code&amp;gt; file &#039;&#039;is&#039;&#039; the project folder; loading the project later makes MXWendler pick up its plugins again.&lt;br /&gt;
# &#039;&#039;&#039;Create the plugin directory there&#039;&#039;&#039; — the project mirrors the installation layout: &amp;lt;code&amp;gt;D:/shows/particles/plugins/media/python/&amp;amp;lt;plugin_folder&amp;amp;gt;/&amp;lt;/code&amp;gt; for media plugins (&amp;lt;code&amp;gt;plugins/playlist/python/...&amp;lt;/code&amp;gt; for playlist plugins). Enable &#039;&#039;Settings → Python → Check for plugins inside the project folder&#039;&#039; — project plugins have the highest precedence of all plugin locations.&lt;br /&gt;
&lt;br /&gt;
=== Letting Claude Code write the plugin ===&lt;br /&gt;
&lt;br /&gt;
An AI coding agent like [https://claude.com/claude-code Claude Code] can write a complete plugin from the contract described on this page. Start it &#039;&#039;&#039;in the project folder&#039;&#039;&#039;, so it creates the plugin directly where MXWendler looks for it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd D:/shows/particles&lt;br /&gt;
claude&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Give it the reference material and a precise task — for a generative OpenGL particle system for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Create an MXWendler media plugin under plugins/media/python/plugin_particle_system/&lt;br /&gt;
(folder + mxw_plugin.ini + mxw_main.py).&lt;br /&gt;
&lt;br /&gt;
Reference: the bundled example in &amp;lt;MXWendler install dir&amp;gt;/plugins/media/python/&lt;br /&gt;
plugin_opengl_cube_direct/ - follow its structure and hook usage exactly, and the&lt;br /&gt;
plugin howto at https://wiki.mxwendler.net/index.php?title=Python_plugin_reference.&lt;br /&gt;
&lt;br /&gt;
The plugin is a generative OpenGL particle system, addressed as&lt;br /&gt;
generative://particle_system, rendered with ModernGL directly into the media&lt;br /&gt;
texture via onRenderFrameGL (no readback, no onRenderFrame). Keep per-instance&lt;br /&gt;
state keyed by media_id. Emit particles from the center, integrate velocity and&lt;br /&gt;
gravity per frame scaled by the clip playback speed (onSetSpeed, onSpeedRange&lt;br /&gt;
-5..5). Expose particle count, gravity and start size as sliders in&lt;br /&gt;
onRenderPanel (mxw_imgui) and persist them via onSave/onLoad. Respect the GL&lt;br /&gt;
rules: attach with moderngl.create_context() lazily on the first render call,&lt;br /&gt;
never release the external texture, rebuild the fbo when (texture, w, h)&lt;br /&gt;
changes, flip Y in the projection.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then iterate: create the media in a clip (it appears under its &amp;lt;code&amp;gt;plugin_menu_name&amp;lt;/code&amp;gt;, or address &amp;lt;code&amp;gt;generative://particle_system&amp;lt;/code&amp;gt; directly) and refine with follow-up prompts (&amp;quot;make the particles fade out&amp;quot;, &amp;quot;add a color gradient slider&amp;quot;, ...). Errors show up in the interpreter console. For playlist plugins, &#039;&#039;Settings → Python → Reload Python Plugins&#039;&#039; hot-reloads the edited source; for media plugins, recreate the media (or restart) to re-import the module.&lt;br /&gt;
&lt;br /&gt;
== Persistence ==&lt;br /&gt;
&lt;br /&gt;
Both plugin types persist per-instance state through the &amp;lt;code&amp;gt;onSave() → string&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;onLoad(string)&amp;lt;/code&amp;gt; pair. The string is stored inside the project file; anything goes, a common choice is base64-encoded pickle (see the playlist example above). Media plugins additionally have their render size stored and restored by the host automatically.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Nothing appears in the menu&#039;&#039;&#039; — check the manifest: &amp;lt;code&amp;gt;plugin_version = 1&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;plugin_script_language = Python&amp;lt;/code&amp;gt;, a non-empty &amp;lt;code&amp;gt;plugin_menu_name&amp;lt;/code&amp;gt;, and the level key (&amp;lt;code&amp;gt;development&amp;lt;/code&amp;gt; plugins only show in debug builds).&lt;br /&gt;
* &#039;&#039;&#039;Errors&#039;&#039;&#039; — open the interpreter console (IO dialog): hook exceptions are reported there (throttled). Remember that a throwing per-frame hook is blacklisted until reload.&lt;br /&gt;
* &#039;&#039;&#039;Media shows black&#039;&#039;&#039; — &amp;lt;code&amp;gt;onRenderFrame&amp;lt;/code&amp;gt; returned a buffer of the wrong size (must be &amp;lt;code&amp;gt;width*height*4&amp;lt;/code&amp;gt; bytes), or a GL plugin created its own context instead of attaching to MXWendler&#039;s (see the OpenGL rules).&lt;br /&gt;
* &#039;&#039;&#039;Missing packages&#039;&#039;&#039; — install them with mxw-pip (see [[#Installing own modules with mxw-pip|Installing own modules with mxw-pip]]) and make sure &#039;&#039;&#039;Prepend user site-path&#039;&#039;&#039; is enabled: the embedded interpreter does not see a system-wide Python installation&#039;s packages.&lt;br /&gt;
[[Category:Python]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Python_imgui_reference&amp;diff=6166</id>
		<title>Python imgui reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Python_imgui_reference&amp;diff=6166"/>
		<updated>2026-08-08T15:33:30Z</updated>

		<summary type="html">&lt;p&gt;Admin: Add Category:Python at page end (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- MXWendler wiki page: Python mxw_imgui command reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Intended location: https://wiki.mxwendler.net/index.php?title=Python_ImGui_Reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_Reference (the mxw module) --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_Plugin_Howto --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here are listed the commands available in module &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt;, MXWendler&#039;s Python binding of &#039;&#039;&#039;Dear ImGui&#039;&#039;&#039;. This is how plugins draw their settings panel, in the &amp;lt;code&amp;gt;onRenderPanel()&amp;lt;/code&amp;gt; hook (see the [[Python_Plugin_Howto|Python Plugin Howto]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt; mirrors the Dear ImGui C++ API almost function-for-function: the C++ &amp;lt;code&amp;gt;ImGui::PascalCase&amp;lt;/code&amp;gt; names become Python &amp;lt;code&amp;gt;snake_case&amp;lt;/code&amp;gt;, one argument at a time. If you already know Dear ImGui (or its C++/other-language bindings), the name of a call is usually a mechanical translation away.&lt;br /&gt;
&lt;br /&gt;
=== Legend ===&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Everything from the [[Python_Reference|Python Reference]] Legend applies (floats, integers, strings, &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; for alternative formats). In addition:&lt;br /&gt;
&lt;br /&gt;
Dear ImGui widgets that take a pointer to their value in C++ (so the value can be written back) instead return a &#039;&#039;&#039;tuple&#039;&#039;&#039; &amp;lt;code&amp;gt;(changed, value)&amp;lt;/code&amp;gt; in Python: &amp;lt;code&amp;gt;changed&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; when the user edited the widget this frame, &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt; is the (possibly new) value to keep and pass back in next frame. E.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;changed, value = mxw_imgui.slider_float(&amp;quot;Speed&amp;quot;, value, 0.0, 1.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Widgets with several packed floats/ints (&amp;lt;code&amp;gt;drag_float2&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;slider_int4&amp;lt;/code&amp;gt;, ...) take and return a plain Python list/tuple of that length instead of a C array.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Flags&#039;&#039;&#039; (&amp;lt;code&amp;gt;ImGuiTreeNodeFlags&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ImGuiWindowFlags&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ImGuiCol&amp;lt;/code&amp;gt;, ...) are &#039;&#039;&#039;not&#039;&#039;&#039; exposed as named Python constants — pass the plain integer value of the Dear ImGui enum (default &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; means &amp;quot;no flags&amp;quot; for nearly every call). Consult the Dear ImGui headers/docs for the numeric values if you need non-default flags.&lt;br /&gt;
&lt;br /&gt;
Parameters shown as &amp;lt;code&amp;gt;= value&amp;lt;/code&amp;gt; in the tables below are &#039;&#039;&#039;optional&#039;&#039;&#039; with that default; omit them to use the default.&lt;br /&gt;
&lt;br /&gt;
Plugins draw &#039;&#039;&#039;into an existing panel&#039;&#039;&#039; — there is no &amp;lt;code&amp;gt;begin&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; for top-level windows; start directly with widget calls.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data types ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON TYPE !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.Vec2()&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.Vec2(x, y)&amp;lt;/code&amp;gt; || 2D float vector (&amp;lt;code&amp;gt;.x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;.y&amp;lt;/code&amp;gt;), used for sizes and positions || &amp;lt;code&amp;gt;size = mxw_imgui.Vec2(200, 0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.Vec4()&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.Vec4(x, y, z, w)&amp;lt;/code&amp;gt; || 4D float vector (&amp;lt;code&amp;gt;.x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;.y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;.z&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;.w&amp;lt;/code&amp;gt;), used for colors (RGBA) and rectangles || &amp;lt;code&amp;gt;col = mxw_imgui.Vec4(1.0, 0.0, 0.0, 1.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.Vector_char&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Vector_float&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Vector_unsignedchar&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Vector_unsignedshort&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Vector_DrawCmd&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Vector_DrawVert&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Vector_FontGlyph&amp;lt;/code&amp;gt; || Read-only iterable wrappers around Dear ImGui&#039;s internal &amp;lt;code&amp;gt;ImVector&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; buffers, returned by some getters (e.g. draw list data). Support &amp;lt;code&amp;gt;len()&amp;lt;/code&amp;gt;, iteration and indexing || &amp;lt;code&amp;gt;for glyph in font.Glyphs: pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Style &amp;amp;amp; Fonts ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_font(font)&amp;lt;/code&amp;gt; || push a font onto the font stack for subsequent widgets || &amp;lt;code&amp;gt;mxw_imgui.push_font(mxw_imgui.get_font())&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_font()&amp;lt;/code&amp;gt; || pop the last pushed font || &amp;lt;code&amp;gt;mxw_imgui.pop_font()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_style_color(idx, col)&amp;lt;/code&amp;gt; || push a style color override (&amp;lt;code&amp;gt;col&amp;lt;/code&amp;gt; as packed &amp;lt;code&amp;gt;u32&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;Vec4&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;mxw_imgui.push_style_color(0, mxw_imgui.Vec4(1,0,0,1))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_style_color(count = 1)&amp;lt;/code&amp;gt; || pop &amp;lt;code&amp;gt;count&amp;lt;/code&amp;gt; previously pushed style colors || &amp;lt;code&amp;gt;mxw_imgui.pop_style_color()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_style_var(idx, val)&amp;lt;/code&amp;gt; || push a style var override (&amp;lt;code&amp;gt;val&amp;lt;/code&amp;gt; as float OR &amp;lt;code&amp;gt;Vec2&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;mxw_imgui.push_style_var(0, 4.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_style_var(count = 1)&amp;lt;/code&amp;gt; || pop &amp;lt;code&amp;gt;count&amp;lt;/code&amp;gt; previously pushed style vars || &amp;lt;code&amp;gt;mxw_imgui.pop_style_var()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_allow_keyboard_focus(allow_keyboard_focus)&amp;lt;/code&amp;gt; || allow/disallow tab-focusing the next widgets || &amp;lt;code&amp;gt;mxw_imgui.push_allow_keyboard_focus(false)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_allow_keyboard_focus()&amp;lt;/code&amp;gt; || pop the keyboard-focus override || &amp;lt;code&amp;gt;mxw_imgui.pop_allow_keyboard_focus()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_button_repeat(repeat)&amp;lt;/code&amp;gt; || make subsequent buttons behave as repeating (held = repeated clicks) || &amp;lt;code&amp;gt;mxw_imgui.push_button_repeat(true)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_button_repeat()&amp;lt;/code&amp;gt; || pop the button-repeat override || &amp;lt;code&amp;gt;mxw_imgui.pop_button_repeat()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_font()&amp;lt;/code&amp;gt; || returns the current font object || &amp;lt;code&amp;gt;f = mxw_imgui.get_font()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_font_size()&amp;lt;/code&amp;gt; || returns the current font size in px || &amp;lt;code&amp;gt;sz = mxw_imgui.get_font_size()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_font_tex_uv_white_pixel()&amp;lt;/code&amp;gt; || returns UV coordinate of a white pixel in the font texture, for custom draw-list use || &amp;lt;code&amp;gt;uv = mxw_imgui.get_font_tex_uv_white_pixel()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_color_u32(idx, alpha_mul = 1.0)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.get_color_u32(col)&amp;lt;/code&amp;gt; || resolve a style color index, a &amp;lt;code&amp;gt;Vec4&amp;lt;/code&amp;gt;, or a packed &amp;lt;code&amp;gt;u32&amp;lt;/code&amp;gt; to a final packed &amp;lt;code&amp;gt;u32&amp;lt;/code&amp;gt; color || &amp;lt;code&amp;gt;c = mxw_imgui.get_color_u32(0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_style_color_vec4(idx)&amp;lt;/code&amp;gt; || returns the raw &amp;lt;code&amp;gt;Vec4&amp;lt;/code&amp;gt; for a style color index || &amp;lt;code&amp;gt;c = mxw_imgui.get_style_color_vec4(0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_style_color_name(idx)&amp;lt;/code&amp;gt; || returns the readable name of a style color index || &amp;lt;code&amp;gt;mxw_imgui.print_console(mxw_imgui.get_style_color_name(0))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_color_edit_options(flags)&amp;lt;/code&amp;gt; || set default flags for every subsequent color_edit/color_picker call || &amp;lt;code&amp;gt;mxw_imgui.set_color_edit_options(0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Cursor &amp;amp;amp; Layout ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_item_width(item_width)&amp;lt;/code&amp;gt; || push a fixed width (px, or negative = right-aligned) for subsequent widgets || &amp;lt;code&amp;gt;mxw_imgui.push_item_width(150)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_item_width()&amp;lt;/code&amp;gt; || pop the pushed item width || &amp;lt;code&amp;gt;mxw_imgui.pop_item_width()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_next_item_width(item_width)&amp;lt;/code&amp;gt; || set the width of just the next widget || &amp;lt;code&amp;gt;mxw_imgui.set_next_item_width(300)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.calc_item_width()&amp;lt;/code&amp;gt; || returns the width the next widget would use || &amp;lt;code&amp;gt;w = mxw_imgui.calc_item_width()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_text_wrap_pos(wrap_local_pos_x = 0.0)&amp;lt;/code&amp;gt; || push a word-wrap position (0 = wrap at window edge) for subsequent text || &amp;lt;code&amp;gt;mxw_imgui.push_text_wrap_pos()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_text_wrap_pos()&amp;lt;/code&amp;gt; || pop the pushed wrap position || &amp;lt;code&amp;gt;mxw_imgui.pop_text_wrap_pos()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.separator()&amp;lt;/code&amp;gt; || draw a thin horizontal separator line || &amp;lt;code&amp;gt;mxw_imgui.separator()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.same_line(offset_from_start_x = 0.0, spacing = -1.0)&amp;lt;/code&amp;gt; || keep the next widget on the same line as the previous one || &amp;lt;code&amp;gt;mxw_imgui.same_line()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.new_line()&amp;lt;/code&amp;gt; || force a following widget to start on a new line || &amp;lt;code&amp;gt;mxw_imgui.new_line()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.spacing()&amp;lt;/code&amp;gt; || add vertical spacing || &amp;lt;code&amp;gt;mxw_imgui.spacing()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.dummy(size)&amp;lt;/code&amp;gt; || reserve an empty invisible &amp;lt;code&amp;gt;size&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;Vec2&amp;lt;/code&amp;gt;) area, e.g. as a spacer || &amp;lt;code&amp;gt;mxw_imgui.dummy(mxw_imgui.Vec2(0, 10))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.indent(indent_w = 0.0)&amp;lt;/code&amp;gt; || move the cursor right (indent) || &amp;lt;code&amp;gt;mxw_imgui.indent()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.unindent(indent_w = 0.0)&amp;lt;/code&amp;gt; || move the cursor back left (unindent), matching a prior indent() || &amp;lt;code&amp;gt;mxw_imgui.unindent()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_group()&amp;lt;/code&amp;gt; || start a layout group (following widgets are treated as one unit for layout purposes) || &amp;lt;code&amp;gt;mxw_imgui.begin_group()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.end_group()&amp;lt;/code&amp;gt; || close the current layout group || &amp;lt;code&amp;gt;mxw_imgui.end_group()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_cursor_pos()&amp;lt;/code&amp;gt; || returns the cursor position (&amp;lt;code&amp;gt;Vec2&amp;lt;/code&amp;gt;) relative to the current window || &amp;lt;code&amp;gt;p = mxw_imgui.get_cursor_pos()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_cursor_pos_x()&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.get_cursor_pos_y()&amp;lt;/code&amp;gt; || returns just the X or Y cursor coordinate || &amp;lt;code&amp;gt;x = mxw_imgui.get_cursor_pos_x()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_cursor_pos(local_pos)&amp;lt;/code&amp;gt; || set the cursor position (&amp;lt;code&amp;gt;Vec2&amp;lt;/code&amp;gt;), window-relative || &amp;lt;code&amp;gt;mxw_imgui.set_cursor_pos(mxw_imgui.Vec2(0, 0))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_cursor_pos_x(local_x)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.set_cursor_pos_y(local_y)&amp;lt;/code&amp;gt; || set just the X or Y cursor coordinate || &amp;lt;code&amp;gt;mxw_imgui.set_cursor_pos_x(20)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_cursor_start_pos()&amp;lt;/code&amp;gt; || returns the initial cursor position of the current window/child || &amp;lt;code&amp;gt;p = mxw_imgui.get_cursor_start_pos()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_cursor_screen_pos()&amp;lt;/code&amp;gt; || returns the cursor position in absolute screen coordinates || &amp;lt;code&amp;gt;p = mxw_imgui.get_cursor_screen_pos()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_cursor_screen_pos(pos)&amp;lt;/code&amp;gt; || set the cursor in absolute screen coordinates || &amp;lt;code&amp;gt;mxw_imgui.set_cursor_screen_pos(p)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.align_text_to_frame_padding()&amp;lt;/code&amp;gt; || vertically align following text with standard framed widgets on the same line || &amp;lt;code&amp;gt;mxw_imgui.align_text_to_frame_padding()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_text_line_height()&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.get_text_line_height_with_spacing()&amp;lt;/code&amp;gt; || returns one text line&#039;s height, with or without inter-line spacing || &amp;lt;code&amp;gt;h = mxw_imgui.get_text_line_height()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_frame_height()&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.get_frame_height_with_spacing()&amp;lt;/code&amp;gt; || returns a standard framed widget&#039;s height, with or without spacing || &amp;lt;code&amp;gt;h = mxw_imgui.get_frame_height()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ID stack ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_id(str_id)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.push_id(str_id_begin, str_id_end)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.push_id(ptr_id)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.push_id(int_id)&amp;lt;/code&amp;gt; || push a scope onto the ID stack, so same-labelled widgets in a loop don&#039;t collide || &amp;lt;code&amp;gt;mxw_imgui.push_id(i)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_id()&amp;lt;/code&amp;gt; || pop the last pushed ID scope || &amp;lt;code&amp;gt;mxw_imgui.pop_id()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_id(str_id)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.get_id(str_id_begin, str_id_end)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.get_id(ptr_id)&amp;lt;/code&amp;gt; || compute a widget ID without pushing it || &amp;lt;code&amp;gt;uid = mxw_imgui.get_id(&amp;quot;my_widget&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Text ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.text_unformatted(text, text_end = None)&amp;lt;/code&amp;gt; || draw raw text, faster than &amp;lt;code&amp;gt;text()&amp;lt;/code&amp;gt; for long/dynamic strings (no format parsing) || &amp;lt;code&amp;gt;mxw_imgui.text_unformatted(&amp;quot;Ready.&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.text(fmt)&amp;lt;/code&amp;gt; || draw a line of text || &amp;lt;code&amp;gt;mxw_imgui.text(&amp;quot;Frame: &amp;quot; + str(mxw.framecounter))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.text_colored(col, fmt)&amp;lt;/code&amp;gt; || draw text in the given &amp;lt;code&amp;gt;Vec4&amp;lt;/code&amp;gt; color || &amp;lt;code&amp;gt;mxw_imgui.text_colored(mxw_imgui.Vec4(1,0,0,1), &amp;quot;Error&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.text_disabled(fmt)&amp;lt;/code&amp;gt; || draw text in the disabled/grey style color || &amp;lt;code&amp;gt;mxw_imgui.text_disabled(&amp;quot;(no signal)&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.text_wrapped(fmt)&amp;lt;/code&amp;gt; || draw text that wraps at the window edge, regardless of the wrap-pos stack || &amp;lt;code&amp;gt;mxw_imgui.text_wrapped(status_message)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.label_text(label, fmt)&amp;lt;/code&amp;gt; || draw a &amp;quot;label: value&amp;quot;-style line (label aligned like other widgets) || &amp;lt;code&amp;gt;mxw_imgui.label_text(&amp;quot;Status&amp;quot;, &amp;quot;OK&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.bullet_text(fmt)&amp;lt;/code&amp;gt; || draw a bulleted line of text || &amp;lt;code&amp;gt;mxw_imgui.bullet_text(&amp;quot;first item&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Main widgets ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.button(label, size = Vec2(0,0))&amp;lt;/code&amp;gt; || a clickable button; returns &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; the frame it&#039;s clicked || &amp;lt;code&amp;gt;if mxw_imgui.button(&amp;quot;Reload&amp;quot;): reload()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.small_button(label)&amp;lt;/code&amp;gt; || a button with no extra vertical padding, fits inline with text || &amp;lt;code&amp;gt;if mxw_imgui.small_button(&amp;quot;x&amp;quot;): close()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.invisible_button(str_id, size, flags = 0)&amp;lt;/code&amp;gt; || an invisible clickable/draggable area || &amp;lt;code&amp;gt;mxw_imgui.invisible_button(&amp;quot;drag_area&amp;quot;, mxw_imgui.Vec2(50,50))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.arrow_button(str_id, dir)&amp;lt;/code&amp;gt; || a small square button with an arrow glyph (&amp;lt;code&amp;gt;dir&amp;lt;/code&amp;gt;: 0=left,1=right,2=up,3=down) || &amp;lt;code&amp;gt;mxw_imgui.arrow_button(&amp;quot;up&amp;quot;, 2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.image(user_texture_id, size, uv0 = Vec2(0,0), uv1 = Vec2(1,1), tint_col = Vec4(1,1,1,1), border_col = Vec4(0,0,0,0))&amp;lt;/code&amp;gt; || draw a texture (GL texture id) as an image || &amp;lt;code&amp;gt;mxw_imgui.image(tex_id, mxw_imgui.Vec2(128,128))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.image_button(user_texture_id, size, uv0 = Vec2(0,0), uv1 = Vec2(1,1), frame_padding = -1, bg_col = Vec4(0,0,0,0), tint_col = Vec4(1,1,1,1))&amp;lt;/code&amp;gt; || a clickable image button || &amp;lt;code&amp;gt;if mxw_imgui.image_button(tex_id, mxw_imgui.Vec2(32,32)): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.checkbox(label, v)&amp;lt;/code&amp;gt; || a checkbox; &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt;/return is &amp;lt;code&amp;gt;bool&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;changed, enabled = mxw_imgui.checkbox(&amp;quot;Enabled&amp;quot;, enabled)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.checkbox_flags(label, flags, flags_value)&amp;lt;/code&amp;gt; || a checkbox that toggles one bit(mask) of an int flags value || &amp;lt;code&amp;gt;changed, flags = mxw_imgui.checkbox_flags(&amp;quot;Bit 1&amp;quot;, flags, 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.radio_button(label, active)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.radio_button(label, v, v_button)&amp;lt;/code&amp;gt; || a radio button; single-bool form for manual state, or bind directly to an int selection variable || &amp;lt;code&amp;gt;changed, mode = mxw_imgui.radio_button(&amp;quot;Mode A&amp;quot;, mode, 0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.progress_bar(fraction, size_arg = Vec2(-FLT_MIN, 0), overlay = None)&amp;lt;/code&amp;gt; || a progress bar, &amp;lt;code&amp;gt;fraction&amp;lt;/code&amp;gt; 0.0..1.0 || &amp;lt;code&amp;gt;mxw_imgui.progress_bar(0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.bullet()&amp;lt;/code&amp;gt; || draw just a bullet glyph, e.g. before inline text/widgets || &amp;lt;code&amp;gt;mxw_imgui.bullet()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Combo box ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.combo(label, current_item, items, popup_max_height_in_items = -1)&amp;lt;/code&amp;gt; || a combo box built from a Python list of strings; simplest way to pick one of several options || &amp;lt;code&amp;gt;changed, sel = mxw_imgui.combo(&amp;quot;Mode&amp;quot;, sel, [&amp;quot;A&amp;quot;, &amp;quot;B&amp;quot;, &amp;quot;C&amp;quot;])&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_combo(label, preview_value, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_combo()&amp;lt;/code&amp;gt; || low-level combo box: build the popup content yourself (e.g. with &amp;lt;code&amp;gt;selectable()&amp;lt;/code&amp;gt;) between these two calls || &amp;lt;code&amp;gt;if mxw_imgui.begin_combo(&amp;quot;Mode&amp;quot;, preview): mxw_imgui.end_combo()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Drag sliders ===&lt;br /&gt;
Click-and-drag widgets; typing is also possible (Ctrl+click / double-click).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.drag_float(label, v, v_speed = 1.0, v_min = 0.0, v_max = 0.0, format = None, flags = 0)&amp;lt;/code&amp;gt; || drag a single float; &amp;lt;code&amp;gt;v_min == v_max == 0&amp;lt;/code&amp;gt; means unbounded || &amp;lt;code&amp;gt;changed, value = mxw_imgui.drag_float(&amp;quot;Speed&amp;quot;, value, 0.01, 0.0, 2.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.drag_float2(label, v, ...)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;drag_float3&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;drag_float4&amp;lt;/code&amp;gt; || same, for a list of 2/3/4 floats (e.g. a color or position) || &amp;lt;code&amp;gt;changed, xyz = mxw_imgui.drag_float3(&amp;quot;Position&amp;quot;, xyz)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.drag_float_range2(label, v_current_min, v_current_max, v_speed = 1.0, v_min = 0.0, v_max = 0.0, format = None, format_max = None, flags = 0)&amp;lt;/code&amp;gt; || drag a min/max float range with two handles || &amp;lt;code&amp;gt;changed, lo, hi = mxw_imgui.drag_float_range2(&amp;quot;Range&amp;quot;, lo, hi)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.drag_int(label, v, v_speed = 1.0, v_min = 0, v_max = 0, format = None, flags = 0)&amp;lt;/code&amp;gt; || drag a single int || &amp;lt;code&amp;gt;changed, value = mxw_imgui.drag_int(&amp;quot;Count&amp;quot;, value, 1, 0, 10)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.drag_int2(label, v, ...)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;drag_int3&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;drag_int4&amp;lt;/code&amp;gt; || same, for a list of 2/3/4 ints || &amp;lt;code&amp;gt;changed, rgb = mxw_imgui.drag_int3(&amp;quot;RGB&amp;quot;, rgb, 1, 0, 255)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.drag_int_range2(label, v_current_min, v_current_max, ...)&amp;lt;/code&amp;gt; || drag a min/max int range with two handles || &amp;lt;code&amp;gt;changed, lo, hi = mxw_imgui.drag_int_range2(&amp;quot;Range&amp;quot;, lo, hi)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.drag_scalar(label, data_type, p_data, v_speed, p_min = None, p_max = None, format = None, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;drag_scalar_n(..., components, ...)&amp;lt;/code&amp;gt; || generic drag widget for any &amp;lt;code&amp;gt;ImGuiDataType&amp;lt;/code&amp;gt;, rarely needed from Python || &amp;lt;code&amp;gt;mxw_imgui.drag_scalar(&amp;quot;Value&amp;quot;, 0, ptr, 1.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sliders ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.slider_float(label, v, v_min, v_max, format = None, flags = 0)&amp;lt;/code&amp;gt; || slide a single float between &amp;lt;code&amp;gt;v_min&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;v_max&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;changed, value = mxw_imgui.slider_float(&amp;quot;Mouse X&amp;quot;, value, 0.0, 1.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.slider_float2(label, v, v_min, v_max, ...)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;slider_float3&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;slider_float4&amp;lt;/code&amp;gt; || same, for a list of 2/3/4 floats || &amp;lt;code&amp;gt;changed, rgba = mxw_imgui.slider_float4(&amp;quot;Color&amp;quot;, rgba, 0.0, 1.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.slider_angle(label, v_rad, v_degrees_min = -360.0, v_degrees_max = 360.0, format = None, flags = 0)&amp;lt;/code&amp;gt; || slide an angle, stored in radians but displayed/typed in degrees || &amp;lt;code&amp;gt;changed, rot = mxw_imgui.slider_angle(&amp;quot;Rotation&amp;quot;, rot)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.slider_int(label, v, v_min, v_max, format = None, flags = 0)&amp;lt;/code&amp;gt; || slide a single int || &amp;lt;code&amp;gt;changed, idx = mxw_imgui.slider_int(&amp;quot;Preset&amp;quot;, idx, 0, 99)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.slider_int2(label, v, v_min, v_max, ...)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;slider_int3&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;slider_int4&amp;lt;/code&amp;gt; || same, for a list of 2/3/4 ints || &amp;lt;code&amp;gt;changed, xy = mxw_imgui.slider_int2(&amp;quot;Grid pos&amp;quot;, xy, 0, 10)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.slider_scalar(label, data_type, p_data, p_min, p_max, format = None, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;slider_scalar_n(..., components, ...)&amp;lt;/code&amp;gt; || generic slider for any &amp;lt;code&amp;gt;ImGuiDataType&amp;lt;/code&amp;gt;, rarely needed from Python || &amp;lt;code&amp;gt;mxw_imgui.slider_scalar(&amp;quot;Value&amp;quot;, 0, ptr, p_min, p_max)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.v_slider_float(label, size, v, v_min, v_max, format = None, flags = 0)&amp;lt;/code&amp;gt; || vertical slider variant of &amp;lt;code&amp;gt;slider_float&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;changed, value = mxw_imgui.v_slider_float(&amp;quot;##vol&amp;quot;, mxw_imgui.Vec2(20,100), value, 0.0, 1.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.v_slider_int(label, size, v, v_min, v_max, format = None, flags = 0)&amp;lt;/code&amp;gt; || vertical slider variant of &amp;lt;code&amp;gt;slider_int&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;changed, value = mxw_imgui.v_slider_int(&amp;quot;##lvl&amp;quot;, mxw_imgui.Vec2(20,100), value, 0, 10)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.v_slider_scalar(label, size, data_type, p_data, p_min, p_max, format = None, flags = 0)&amp;lt;/code&amp;gt; || generic vertical slider for any &amp;lt;code&amp;gt;ImGuiDataType&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;mxw_imgui.v_slider_scalar(&amp;quot;##v&amp;quot;, size, 0, ptr, p_min, p_max)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Input widgets ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.input_text(label, data, max_size, flags = 0)&amp;lt;/code&amp;gt; || a single-line text field; &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; is the current string, &amp;lt;code&amp;gt;max_size&amp;lt;/code&amp;gt; the max length in bytes || &amp;lt;code&amp;gt;changed, value = mxw_imgui.input_text(&amp;quot;URL&amp;quot;, url_text, 512)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.input_text_multiline(label, data, max_size, size = Vec2(0,0), flags = 0)&amp;lt;/code&amp;gt; || a multi-line text field || &amp;lt;code&amp;gt;changed, value = mxw_imgui.input_text_multiline(&amp;quot;Notes&amp;quot;, notes, 2048, mxw_imgui.Vec2(300,100))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.input_float(label, v, step = 0.0, step_fast = 0.0, format = None, flags = 0)&amp;lt;/code&amp;gt; || a typed float field with optional +/- step buttons || &amp;lt;code&amp;gt;changed, value = mxw_imgui.input_float(&amp;quot;Gain&amp;quot;, value, 0.1)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.input_float2(label, v, ...)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;input_float3&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;input_float4&amp;lt;/code&amp;gt; || same, for a list of 2/3/4 floats || &amp;lt;code&amp;gt;changed, xyz = mxw_imgui.input_float3(&amp;quot;Pos&amp;quot;, xyz)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.input_int(label, v, step = 1, step_fast = 100, flags = 0)&amp;lt;/code&amp;gt; || a typed int field with +/- step buttons || &amp;lt;code&amp;gt;changed, value = mxw_imgui.input_int(&amp;quot;Count&amp;quot;, value)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.input_int2(label, v, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;input_int3&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;input_int4&amp;lt;/code&amp;gt; || same, for a list of 2/3/4 ints || &amp;lt;code&amp;gt;changed, rgb = mxw_imgui.input_int3(&amp;quot;RGB&amp;quot;, rgb)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.input_double(label, v, step = 0.0, step_fast = 0.0, format = None, flags = 0)&amp;lt;/code&amp;gt; || a typed double field || &amp;lt;code&amp;gt;changed, value = mxw_imgui.input_double(&amp;quot;Precise&amp;quot;, value)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.input_scalar(label, data_type, p_data, p_step = None, p_step_fast = None, format = None, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;input_scalar_n(..., components, ...)&amp;lt;/code&amp;gt; || generic typed field for any &amp;lt;code&amp;gt;ImGuiDataType&amp;lt;/code&amp;gt;, rarely needed from Python || &amp;lt;code&amp;gt;mxw_imgui.input_scalar(&amp;quot;Value&amp;quot;, 0, ptr)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Color editor &amp;amp;amp; picker ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_edit3(label, col, flags = 0)&amp;lt;/code&amp;gt; || a compact RGB color editor (swatch + popup picker); &amp;lt;code&amp;gt;col&amp;lt;/code&amp;gt; is a 3-float list || &amp;lt;code&amp;gt;changed, rgb = mxw_imgui.color_edit3(&amp;quot;Tint&amp;quot;, rgb)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_edit4(label, col, flags = 0)&amp;lt;/code&amp;gt; || same, RGBA (4-float list) || &amp;lt;code&amp;gt;changed, rgba = mxw_imgui.color_edit4(&amp;quot;Tint&amp;quot;, rgba)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_picker3(label, col, flags = 0)&amp;lt;/code&amp;gt; || a full RGB color picker widget, always expanded || &amp;lt;code&amp;gt;changed, rgb = mxw_imgui.color_picker3(&amp;quot;Tint&amp;quot;, rgb)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_picker4(label, col, flags = 0, ref_col = None)&amp;lt;/code&amp;gt; || same, RGBA, optionally showing a reference color for comparison || &amp;lt;code&amp;gt;changed, rgba = mxw_imgui.color_picker4(&amp;quot;Tint&amp;quot;, rgba)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_button(desc_id, col, flags = 0, size = Vec2(0,0))&amp;lt;/code&amp;gt; || a non-editable color swatch button (e.g. as a preview/trigger) || &amp;lt;code&amp;gt;if mxw_imgui.color_button(&amp;quot;preview&amp;quot;, col): open_picker()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.tree_node(label)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.tree_node(str_id, fmt)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.tree_node(ptr_id, fmt)&amp;lt;/code&amp;gt; || an expandable/collapsible tree node; returns &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; while open. Call &amp;lt;code&amp;gt;tree_pop()&amp;lt;/code&amp;gt; if it returned &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;if mxw_imgui.tree_node(&amp;quot;Advanced&amp;quot;): mxw_imgui.tree_pop()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.tree_node_ex(label, flags = 0)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.tree_node_ex(str_id, flags, fmt)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.tree_node_ex(ptr_id, flags, fmt)&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;tree_node()&amp;lt;/code&amp;gt; with explicit flags (e.g. default-open, leaf, selected) || &amp;lt;code&amp;gt;if mxw_imgui.tree_node_ex(&amp;quot;Node&amp;quot;, 0): mxw_imgui.tree_pop()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.tree_push(str_id)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.tree_push(ptr_id = None)&amp;lt;/code&amp;gt; || push an indent level without drawing a node (paired with &amp;lt;code&amp;gt;tree_pop()&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;mxw_imgui.tree_push(&amp;quot;scope&amp;quot;); mxw_imgui.tree_pop()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.tree_pop()&amp;lt;/code&amp;gt; || pop one indent level pushed by &amp;lt;code&amp;gt;tree_node()&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;tree_push()&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;mxw_imgui.tree_pop()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_tree_node_to_label_spacing()&amp;lt;/code&amp;gt; || returns the horizontal spacing between a tree node arrow and its label || &amp;lt;code&amp;gt;s = mxw_imgui.get_tree_node_to_label_spacing()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.collapsing_header(label, flags = 0)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.collapsing_header(label, p_visible, flags = 0)&amp;lt;/code&amp;gt; || a top-level collapsible section header; optionally with a close (&amp;quot;x&amp;quot;) button when &amp;lt;code&amp;gt;p_visible&amp;lt;/code&amp;gt; is passed || &amp;lt;code&amp;gt;if mxw_imgui.collapsing_header(&amp;quot;Settings&amp;quot;): mxw_imgui.text(&amp;quot;...&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_next_item_open(is_open, cond = 0)&amp;lt;/code&amp;gt; || force the next &amp;lt;code&amp;gt;tree_node()&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;collapsing_header()&amp;lt;/code&amp;gt; open/closed state || &amp;lt;code&amp;gt;mxw_imgui.set_next_item_open(true)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Selectables &amp;amp;amp; list boxes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.selectable(label, selected = false, flags = 0, size = Vec2(0,0))&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.selectable(label, p_selected, flags = 0, size = Vec2(0,0))&amp;lt;/code&amp;gt; || a clickable, highlightable row (typically inside a list box) || &amp;lt;code&amp;gt;if mxw_imgui.selectable(&amp;quot;Item 1&amp;quot;, is_sel): pick(1)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_list_box(label, size = Vec2(0,0))&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_list_box()&amp;lt;/code&amp;gt; || low-level list box: build the rows yourself (e.g. with &amp;lt;code&amp;gt;selectable()&amp;lt;/code&amp;gt;) between these two calls || &amp;lt;code&amp;gt;if mxw_imgui.begin_list_box(&amp;quot;Items&amp;quot;): mxw_imgui.end_list_box()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.list_box(label, current_item, items, height_in_items = -1)&amp;lt;/code&amp;gt; || a list box built from a Python list of strings, single-select || &amp;lt;code&amp;gt;changed, sel = mxw_imgui.list_box(&amp;quot;Presets&amp;quot;, sel, [&amp;quot;A&amp;quot;, &amp;quot;B&amp;quot;, &amp;quot;C&amp;quot;])&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.list_box_stretch(label, current_item, items)&amp;lt;/code&amp;gt; || MXWendler custom variant of &amp;lt;code&amp;gt;list_box()&amp;lt;/code&amp;gt; that stretches to fill the remaining panel height || &amp;lt;code&amp;gt;changed, sel = mxw_imgui.list_box_stretch(&amp;quot;Presets&amp;quot;, sel, names)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Data plotting ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.plot_lines(label, values, values_offset = 0, overlay_text = None, scale_min = FLT_MAX, scale_max = FLT_MAX, graph_size = Vec2(0,0))&amp;lt;/code&amp;gt; || draw a line graph from a Python list of floats || &amp;lt;code&amp;gt;mxw_imgui.plot_lines(&amp;quot;Levels&amp;quot;, history)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.plot_histogram(label, values, values_offset = 0, overlay_text = None, scale_min = FLT_MAX, scale_max = FLT_MAX, graph_size = Vec2(0,0))&amp;lt;/code&amp;gt; || draw a bar histogram from a Python list of floats || &amp;lt;code&amp;gt;mxw_imgui.plot_histogram(&amp;quot;Levels&amp;quot;, history)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Value() helpers ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.value(prefix, b)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.value(prefix, v)&amp;lt;/code&amp;gt; (int/uint) OR &amp;lt;code&amp;gt;mxw_imgui.value(prefix, v, float_format = None)&amp;lt;/code&amp;gt; || draw a &amp;quot;prefix: value&amp;quot; line for a bool/int/float, without building the string yourself || &amp;lt;code&amp;gt;mxw_imgui.value(&amp;quot;FPS&amp;quot;, mxw.fps)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Menus ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_menu_bar()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_menu_bar()&amp;lt;/code&amp;gt; || start/end a menu bar inside the current window || &amp;lt;code&amp;gt;if mxw_imgui.begin_menu_bar(): mxw_imgui.end_menu_bar()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_main_menu_bar()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_main_menu_bar()&amp;lt;/code&amp;gt; || start/end the application&#039;s main (top-level) menu bar || &amp;lt;code&amp;gt;if mxw_imgui.begin_main_menu_bar(): mxw_imgui.end_main_menu_bar()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_menu(label, enabled = true)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_menu()&amp;lt;/code&amp;gt; || start/end a (sub)menu; call &amp;lt;code&amp;gt;end_menu()&amp;lt;/code&amp;gt; only if &amp;lt;code&amp;gt;begin_menu()&amp;lt;/code&amp;gt; returned &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;if mxw_imgui.begin_menu(&amp;quot;File&amp;quot;): mxw_imgui.end_menu()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.menu_item(label, shortcut = None, selected = false, enabled = true)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.menu_item(label, shortcut, p_selected, enabled = true)&amp;lt;/code&amp;gt; || a clickable (optionally checkable) menu entry || &amp;lt;code&amp;gt;if mxw_imgui.menu_item(&amp;quot;Save&amp;quot;, &amp;quot;Ctrl+S&amp;quot;): save()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Tooltips ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_tooltip()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_tooltip()&amp;lt;/code&amp;gt; || build a custom tooltip (any widgets) between these two calls || &amp;lt;code&amp;gt;mxw_imgui.begin_tooltip(); mxw_imgui.text(&amp;quot;info&amp;quot;); mxw_imgui.end_tooltip()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_tooltip(fmt)&amp;lt;/code&amp;gt; || a quick one-line tooltip for the last hovered item || &amp;lt;code&amp;gt;if mxw_imgui.is_item_hovered(): mxw_imgui.set_tooltip(&amp;quot;Explain this&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Popups &amp;amp;amp; modals ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.open_popup(str_id, flags = 0)&amp;lt;/code&amp;gt; || flag a popup to open (by ID) on the next matching &amp;lt;code&amp;gt;begin_popup()&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;mxw_imgui.open_popup(&amp;quot;confirm_delete&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_popup(str_id, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_popup()&amp;lt;/code&amp;gt; || build a plain popup&#039;s content; call &amp;lt;code&amp;gt;end_popup()&amp;lt;/code&amp;gt; only if &amp;lt;code&amp;gt;begin_popup()&amp;lt;/code&amp;gt; returned &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;if mxw_imgui.begin_popup(&amp;quot;menu&amp;quot;): mxw_imgui.end_popup()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_popup_modal(name, p_open = None, flags = 0)&amp;lt;/code&amp;gt; || build a modal popup&#039;s content (blocks interaction with the rest of the UI) || &amp;lt;code&amp;gt;opened, _ = mxw_imgui.begin_popup_modal(&amp;quot;Confirm&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.open_popup_on_item_click(str_id = None, popup_flags = 1)&amp;lt;/code&amp;gt; || open a popup when the last item is clicked (e.g. right-click context menu) || &amp;lt;code&amp;gt;mxw_imgui.open_popup_on_item_click(&amp;quot;ctx&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.close_current_popup()&amp;lt;/code&amp;gt; || close the popup currently being drawn (e.g. after a button inside it) || &amp;lt;code&amp;gt;if mxw_imgui.button(&amp;quot;OK&amp;quot;): mxw_imgui.close_current_popup()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_popup_context_item(str_id = None, popup_flags = 1)&amp;lt;/code&amp;gt; || combined open+begin for a right-click context popup on the last item || &amp;lt;code&amp;gt;if mxw_imgui.begin_popup_context_item(): mxw_imgui.end_popup()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_popup_context_window(str_id = None, popup_flags = 1)&amp;lt;/code&amp;gt; || same, anchored to the current window instead of the last item || &amp;lt;code&amp;gt;if mxw_imgui.begin_popup_context_window(): mxw_imgui.end_popup()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_popup_context_void(str_id = None, popup_flags = 1)&amp;lt;/code&amp;gt; || same, opens on right-click on empty space (no window/item under cursor) || &amp;lt;code&amp;gt;if mxw_imgui.begin_popup_context_void(): mxw_imgui.end_popup()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_popup_open(str_id, flags = 0)&amp;lt;/code&amp;gt; || returns whether the given popup is currently open || &amp;lt;code&amp;gt;open = mxw_imgui.is_popup_open(&amp;quot;menu&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Tables ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_table(str_id, column, flags = 0, outer_size = Vec2(0,0), inner_width = 0.0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_table()&amp;lt;/code&amp;gt; || start/end a table; call &amp;lt;code&amp;gt;end_table()&amp;lt;/code&amp;gt; only if &amp;lt;code&amp;gt;begin_table()&amp;lt;/code&amp;gt; returned &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;if mxw_imgui.begin_table(&amp;quot;grid&amp;quot;, 3): mxw_imgui.end_table()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_next_row(row_flags = 0, min_row_height = 0.0)&amp;lt;/code&amp;gt; || start the next table row || &amp;lt;code&amp;gt;mxw_imgui.table_next_row()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_next_column()&amp;lt;/code&amp;gt; || advance to the next cell (wraps to the next row automatically) || &amp;lt;code&amp;gt;mxw_imgui.table_next_column()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_set_column_index(column_n)&amp;lt;/code&amp;gt; || jump directly to a given column in the current row || &amp;lt;code&amp;gt;mxw_imgui.table_set_column_index(1)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_setup_column(label, flags = 0, init_width_or_weight = 0.0, user_id = 0)&amp;lt;/code&amp;gt; || declare a column&#039;s header label / sizing before the first row || &amp;lt;code&amp;gt;mxw_imgui.table_setup_column(&amp;quot;Name&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_setup_scroll_freeze(cols, rows)&amp;lt;/code&amp;gt; || freeze N leading columns/rows while the rest scrolls || &amp;lt;code&amp;gt;mxw_imgui.table_setup_scroll_freeze(0, 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_headers_row()&amp;lt;/code&amp;gt; || draw the header row from the declared &amp;lt;code&amp;gt;table_setup_column()&amp;lt;/code&amp;gt; labels || &amp;lt;code&amp;gt;mxw_imgui.table_headers_row()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_header(label)&amp;lt;/code&amp;gt; || draw a single header cell manually (instead of &amp;lt;code&amp;gt;table_headers_row()&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;mxw_imgui.table_header(&amp;quot;Name&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_get_sort_specs()&amp;lt;/code&amp;gt; || returns the current column sort specification, if the table is sortable || &amp;lt;code&amp;gt;specs = mxw_imgui.table_get_sort_specs()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_get_column_count()&amp;lt;/code&amp;gt; || returns the number of columns of the current table || &amp;lt;code&amp;gt;n = mxw_imgui.table_get_column_count()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_get_column_index()&amp;lt;/code&amp;gt; || returns the current column index || &amp;lt;code&amp;gt;i = mxw_imgui.table_get_column_index()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_get_row_index()&amp;lt;/code&amp;gt; || returns the current row index || &amp;lt;code&amp;gt;i = mxw_imgui.table_get_row_index()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_get_column_name(column_n = -1)&amp;lt;/code&amp;gt; || returns a column&#039;s declared label (-1 = current column) || &amp;lt;code&amp;gt;name = mxw_imgui.table_get_column_name(0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_get_column_flags(column_n = -1)&amp;lt;/code&amp;gt; || returns a column&#039;s current flags (e.g. is it hidden/sorted) || &amp;lt;code&amp;gt;flags = mxw_imgui.table_get_column_flags()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.table_set_bg_color(target, color, column_n = -1)&amp;lt;/code&amp;gt; || set the background color of a cell/row/column || &amp;lt;code&amp;gt;mxw_imgui.table_set_bg_color(0, mxw_imgui.color_convert_float4_to_u32(mxw_imgui.Vec4(1,0,0,1)))&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Legacy columns ===&lt;br /&gt;
Superseded by [[#Tables|Tables]] above, kept for compatibility.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.columns(count = 1, id = None, border = true)&amp;lt;/code&amp;gt; || switch the rest of the window into a simple N-column layout (&amp;lt;code&amp;gt;count = 1&amp;lt;/code&amp;gt; ends it) || &amp;lt;code&amp;gt;mxw_imgui.columns(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.next_column()&amp;lt;/code&amp;gt; || move to the next column (wraps to the next row) || &amp;lt;code&amp;gt;mxw_imgui.next_column()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_column_index()&amp;lt;/code&amp;gt; || returns the current column index || &amp;lt;code&amp;gt;i = mxw_imgui.get_column_index()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_column_width(column_index = -1)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.set_column_width(column_index, width)&amp;lt;/code&amp;gt; || get/set a column&#039;s width || &amp;lt;code&amp;gt;w = mxw_imgui.get_column_width()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_column_offset(column_index = -1)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.set_column_offset(column_index, offset_x)&amp;lt;/code&amp;gt; || get/set a column&#039;s X offset || &amp;lt;code&amp;gt;x = mxw_imgui.get_column_offset()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_columns_count()&amp;lt;/code&amp;gt; || returns the current column count || &amp;lt;code&amp;gt;n = mxw_imgui.get_columns_count()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Tabs ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_tab_bar(str_id, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_tab_bar()&amp;lt;/code&amp;gt; || start/end a tab bar; call &amp;lt;code&amp;gt;end_tab_bar()&amp;lt;/code&amp;gt; only if &amp;lt;code&amp;gt;begin_tab_bar()&amp;lt;/code&amp;gt; returned &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;if mxw_imgui.begin_tab_bar(&amp;quot;tabs&amp;quot;): mxw_imgui.end_tab_bar()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_tab_item(label, p_open = None, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_tab_item()&amp;lt;/code&amp;gt; || start/end one tab&#039;s content; call &amp;lt;code&amp;gt;end_tab_item()&amp;lt;/code&amp;gt; only if &amp;lt;code&amp;gt;begin_tab_item()&amp;lt;/code&amp;gt; returned &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;opened, _ = mxw_imgui.begin_tab_item(&amp;quot;Settings&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.tab_item_button(label, flags = 0)&amp;lt;/code&amp;gt; || a button drawn as a tab (e.g. a &amp;quot;+&amp;quot; to add a tab) || &amp;lt;code&amp;gt;if mxw_imgui.tab_item_button(&amp;quot;+&amp;quot;): add_tab()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_tab_item_closed(tab_or_docked_window_label)&amp;lt;/code&amp;gt; || programmatically close a tab by label || &amp;lt;code&amp;gt;mxw_imgui.set_tab_item_closed(&amp;quot;Old Tab&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Logging / capture ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.log_to_tty(auto_open_depth = -1)&amp;lt;/code&amp;gt; || start capturing following widgets&#039; text output to the app&#039;s TTY/console || &amp;lt;code&amp;gt;mxw_imgui.log_to_tty()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.log_to_file(auto_open_depth = -1, filename = None)&amp;lt;/code&amp;gt; || start capturing to a file || &amp;lt;code&amp;gt;mxw_imgui.log_to_file(-1, &amp;quot;log.txt&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.log_to_clipboard(auto_open_depth = -1)&amp;lt;/code&amp;gt; || start capturing to the OS clipboard || &amp;lt;code&amp;gt;mxw_imgui.log_to_clipboard()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.log_finish()&amp;lt;/code&amp;gt; || stop the current capture || &amp;lt;code&amp;gt;mxw_imgui.log_finish()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.log_buttons()&amp;lt;/code&amp;gt; || draw the standard &amp;quot;Log/Copy to clipboard&amp;quot; buttons || &amp;lt;code&amp;gt;mxw_imgui.log_buttons()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.log_text(fmt)&amp;lt;/code&amp;gt; || add text directly to the active log capture, without drawing a widget || &amp;lt;code&amp;gt;mxw_imgui.log_text(&amp;quot;captured line&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Drag and drop ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_drag_drop_source(flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_drag_drop_source()&amp;lt;/code&amp;gt; || make the last item a drag source; build the payload/preview between these two calls || &amp;lt;code&amp;gt;if mxw_imgui.begin_drag_drop_source(): mxw_imgui.end_drag_drop_source()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_drag_drop_payload(type, data, sz, cond = 0)&amp;lt;/code&amp;gt; || attach a payload to the drag currently being sourced || &amp;lt;code&amp;gt;mxw_imgui.set_drag_drop_payload(&amp;quot;CLIP&amp;quot;, data, len(data))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_drag_drop_target()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_drag_drop_target()&amp;lt;/code&amp;gt; || make the last item/window a drop target; check &amp;lt;code&amp;gt;accept_drag_drop_payload()&amp;lt;/code&amp;gt; between these two calls || &amp;lt;code&amp;gt;if mxw_imgui.begin_drag_drop_target(): mxw_imgui.end_drag_drop_target()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.accept_drag_drop_payload(type, flags = 0)&amp;lt;/code&amp;gt; || accept a payload of the given type while inside a drop target || &amp;lt;code&amp;gt;p = mxw_imgui.accept_drag_drop_payload(&amp;quot;CLIP&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_drag_drop_payload()&amp;lt;/code&amp;gt; || peek the payload of the drag currently in progress, even outside a target || &amp;lt;code&amp;gt;p = mxw_imgui.get_drag_drop_payload()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Clipping ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.push_clip_rect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect)&amp;lt;/code&amp;gt; || push a manual clipping rectangle (&amp;lt;code&amp;gt;Vec2&amp;lt;/code&amp;gt; corners) for subsequent drawing || &amp;lt;code&amp;gt;mxw_imgui.push_clip_rect(p_min, p_max, true)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.pop_clip_rect()&amp;lt;/code&amp;gt; || pop the pushed clip rect || &amp;lt;code&amp;gt;mxw_imgui.pop_clip_rect()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Focus &amp;amp;amp; activation ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_item_default_focus()&amp;lt;/code&amp;gt; || make the last item the one focused by default when the panel first appears || &amp;lt;code&amp;gt;mxw_imgui.set_item_default_focus()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_keyboard_focus_here(offset = 0)&amp;lt;/code&amp;gt; || focus the next widget for keyboard input (e.g. auto-focus a text field) || &amp;lt;code&amp;gt;mxw_imgui.set_keyboard_focus_here()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Item / widgets utilities ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_hovered(flags = 0)&amp;lt;/code&amp;gt; || returns whether the last item is hovered by the mouse || &amp;lt;code&amp;gt;if mxw_imgui.is_item_hovered(): mxw_imgui.set_tooltip(&amp;quot;info&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_active()&amp;lt;/code&amp;gt; || returns whether the last item is currently active (e.g. being held/edited) || &amp;lt;code&amp;gt;active = mxw_imgui.is_item_active()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_focused()&amp;lt;/code&amp;gt; || returns whether the last item has keyboard focus || &amp;lt;code&amp;gt;focused = mxw_imgui.is_item_focused()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_clicked(mouse_button = 0)&amp;lt;/code&amp;gt; || returns whether the last item was clicked this frame || &amp;lt;code&amp;gt;if mxw_imgui.is_item_clicked(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_visible()&amp;lt;/code&amp;gt; || returns whether the last item is visible (not clipped) || &amp;lt;code&amp;gt;visible = mxw_imgui.is_item_visible()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_edited()&amp;lt;/code&amp;gt; || returns whether the last item&#039;s value changed this frame || &amp;lt;code&amp;gt;edited = mxw_imgui.is_item_edited()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_activated()&amp;lt;/code&amp;gt; || returns whether the last item just became active this frame || &amp;lt;code&amp;gt;started = mxw_imgui.is_item_activated()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_deactivated()&amp;lt;/code&amp;gt; || returns whether the last item just stopped being active this frame || &amp;lt;code&amp;gt;stopped = mxw_imgui.is_item_deactivated()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_deactivated_after_edit()&amp;lt;/code&amp;gt; || returns whether the last item stopped being active after its value changed (e.g. commit-on-release) || &amp;lt;code&amp;gt;if mxw_imgui.is_item_deactivated_after_edit(): save()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_item_toggled_open()&amp;lt;/code&amp;gt; || returns whether the last tree node/collapsing header was just opened or closed || &amp;lt;code&amp;gt;toggled = mxw_imgui.is_item_toggled_open()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_any_item_hovered()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.is_any_item_active()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.is_any_item_focused()&amp;lt;/code&amp;gt; || returns whether any item at all is hovered/active/focused || &amp;lt;code&amp;gt;busy = mxw_imgui.is_any_item_active()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_item_rect_min()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.get_item_rect_max()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.get_item_rect_size()&amp;lt;/code&amp;gt; || returns the last item&#039;s bounding rectangle (screen-space corners, or size) || &amp;lt;code&amp;gt;size = mxw_imgui.get_item_rect_size()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_item_allow_overlap()&amp;lt;/code&amp;gt; || allow the next widget to visually overlap the last item without stealing its hover/click || &amp;lt;code&amp;gt;mxw_imgui.set_item_allow_overlap()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Viewport &amp;amp;amp; miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_main_viewport()&amp;lt;/code&amp;gt; || returns the main viewport object (position/size of the whole application) || &amp;lt;code&amp;gt;vp = mxw_imgui.get_main_viewport()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_rect_visible(size)&amp;lt;/code&amp;gt; OR &amp;lt;code&amp;gt;mxw_imgui.is_rect_visible(rect_min, rect_max)&amp;lt;/code&amp;gt; || returns whether a rectangle at the cursor (or explicit corners) is visible/unclipped || &amp;lt;code&amp;gt;visible = mxw_imgui.is_rect_visible(mxw_imgui.Vec2(50,50))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_time()&amp;lt;/code&amp;gt; || returns Dear ImGui&#039;s internal time in seconds (accumulates while the app runs) || &amp;lt;code&amp;gt;t = mxw_imgui.get_time()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_frame_count()&amp;lt;/code&amp;gt; || returns the number of ImGui frames rendered so far || &amp;lt;code&amp;gt;n = mxw_imgui.get_frame_count()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_background_draw_list()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.get_foreground_draw_list()&amp;lt;/code&amp;gt; || returns the draw list rendered behind/in front of all windows, for custom drawing || &amp;lt;code&amp;gt;dl = mxw_imgui.get_foreground_draw_list()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_draw_list_shared_data()&amp;lt;/code&amp;gt; || returns data shared across draw lists (font atlas, clip rect stack, ...), rarely needed from Python || &amp;lt;code&amp;gt;d = mxw_imgui.get_draw_list_shared_data()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_state_storage(storage)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.get_state_storage()&amp;lt;/code&amp;gt; || set/get the key-value storage backing tree/collapsing-header open states || &amp;lt;code&amp;gt;s = mxw_imgui.get_state_storage()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_child_frame(id, size, flags = 0)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_child_frame()&amp;lt;/code&amp;gt; || a framed, scrollable child region (styled like a text/list box) || &amp;lt;code&amp;gt;if mxw_imgui.begin_child_frame(1, mxw_imgui.Vec2(0,100)): mxw_imgui.end_child_frame()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.calc_text_size(text, text_end = None, hide_text_after_double_hash = false, wrap_width = -1.0)&amp;lt;/code&amp;gt; || returns the pixel size a string would occupy with the current font || &amp;lt;code&amp;gt;w = mxw_imgui.calc_text_size(&amp;quot;0&amp;quot;).x&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Color utilities ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_convert_u32_to_float4(in)&amp;lt;/code&amp;gt; || convert a packed &amp;lt;code&amp;gt;u32&amp;lt;/code&amp;gt; color to a &amp;lt;code&amp;gt;Vec4&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;col = mxw_imgui.color_convert_u32_to_float4(0xFFFFFFFF)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_convert_float4_to_u32(in)&amp;lt;/code&amp;gt; || convert a &amp;lt;code&amp;gt;Vec4&amp;lt;/code&amp;gt; color to a packed &amp;lt;code&amp;gt;u32&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;u = mxw_imgui.color_convert_float4_to_u32(mxw_imgui.Vec4(1,1,1,1))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_convert_rg_bto_hsv(r, g, b)&amp;lt;/code&amp;gt; || returns &amp;lt;code&amp;gt;(h, s, v)&amp;lt;/code&amp;gt; for the given RGB floats (0.0..1.0) || &amp;lt;code&amp;gt;h, s, v = mxw_imgui.color_convert_rg_bto_hsv(1.0, 0.0, 0.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.color_convert_hs_vto_rgb(h, s, v)&amp;lt;/code&amp;gt; || returns &amp;lt;code&amp;gt;(r, g, b)&amp;lt;/code&amp;gt; for the given HSV floats (0.0..1.0) || &amp;lt;code&amp;gt;r, g, b = mxw_imgui.color_convert_hs_vto_rgb(0.0, 1.0, 1.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Keyboard input ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_key_index(imgui_key)&amp;lt;/code&amp;gt; || map a Dear ImGui &amp;lt;code&amp;gt;ImGuiKey_*&amp;lt;/code&amp;gt; value to the user&#039;s backend key index || &amp;lt;code&amp;gt;idx = mxw_imgui.get_key_index(0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_key_down(user_key_index)&amp;lt;/code&amp;gt; || returns whether a key is currently held down || &amp;lt;code&amp;gt;held = mxw_imgui.is_key_down(idx)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_key_pressed(user_key_index, repeat = true)&amp;lt;/code&amp;gt; || returns whether a key was just pressed (optionally auto-repeating while held) || &amp;lt;code&amp;gt;if mxw_imgui.is_key_pressed(idx): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_key_released(user_key_index)&amp;lt;/code&amp;gt; || returns whether a key was just released || &amp;lt;code&amp;gt;if mxw_imgui.is_key_released(idx): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_key_pressed_amount(key_index, repeat_delay, rate)&amp;lt;/code&amp;gt; || returns how many times a key auto-repeated this frame, given a delay/rate || &amp;lt;code&amp;gt;n = mxw_imgui.get_key_pressed_amount(idx, 0.3, 0.1)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Mouse input ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_mouse_down(button)&amp;lt;/code&amp;gt; || returns whether a mouse button is currently held (0=left,1=right,2=middle) || &amp;lt;code&amp;gt;held = mxw_imgui.is_mouse_down(0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_mouse_clicked(button, repeat = false)&amp;lt;/code&amp;gt; || returns whether a mouse button was just clicked || &amp;lt;code&amp;gt;if mxw_imgui.is_mouse_clicked(0): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_mouse_released(button)&amp;lt;/code&amp;gt; || returns whether a mouse button was just released || &amp;lt;code&amp;gt;if mxw_imgui.is_mouse_released(0): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_mouse_double_clicked(button)&amp;lt;/code&amp;gt; || returns whether a mouse button was just double-clicked || &amp;lt;code&amp;gt;if mxw_imgui.is_mouse_double_clicked(0): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_mouse_hovering_rect(r_min, r_max, clip = true)&amp;lt;/code&amp;gt; || returns whether the mouse is over the given screen-space rectangle || &amp;lt;code&amp;gt;over = mxw_imgui.is_mouse_hovering_rect(p_min, p_max)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_mouse_pos_valid(mouse_pos = None)&amp;lt;/code&amp;gt; || returns whether the (current or given) mouse position is valid (app has focus etc.) || &amp;lt;code&amp;gt;valid = mxw_imgui.is_mouse_pos_valid()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_any_mouse_down()&amp;lt;/code&amp;gt; || returns whether any mouse button is currently held || &amp;lt;code&amp;gt;held = mxw_imgui.is_any_mouse_down()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_mouse_pos()&amp;lt;/code&amp;gt; || returns the current mouse position (&amp;lt;code&amp;gt;Vec2&amp;lt;/code&amp;gt;, screen-space) || &amp;lt;code&amp;gt;p = mxw_imgui.get_mouse_pos()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_mouse_pos_on_opening_current_popup()&amp;lt;/code&amp;gt; || returns the mouse position captured when the current popup was opened || &amp;lt;code&amp;gt;p = mxw_imgui.get_mouse_pos_on_opening_current_popup()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.is_mouse_dragging(button, lock_threshold = -1.0)&amp;lt;/code&amp;gt; || returns whether the mouse is dragging with the given button held || &amp;lt;code&amp;gt;dragging = mxw_imgui.is_mouse_dragging(0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_mouse_drag_delta(button = 0, lock_threshold = -1.0)&amp;lt;/code&amp;gt; || returns the drag distance (&amp;lt;code&amp;gt;Vec2&amp;lt;/code&amp;gt;) since the drag started || &amp;lt;code&amp;gt;d = mxw_imgui.get_mouse_drag_delta()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.reset_mouse_drag_delta(button = 0)&amp;lt;/code&amp;gt; || reset the tracked drag distance for a button || &amp;lt;code&amp;gt;mxw_imgui.reset_mouse_drag_delta()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_mouse_cursor()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.set_mouse_cursor(cursor_type)&amp;lt;/code&amp;gt; || get/set the desired OS mouse cursor shape || &amp;lt;code&amp;gt;mxw_imgui.set_mouse_cursor(1)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Clipboard ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.get_clipboard_text()&amp;lt;/code&amp;gt; || returns the current OS clipboard text || &amp;lt;code&amp;gt;txt = mxw_imgui.get_clipboard_text()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.set_clipboard_text(text)&amp;lt;/code&amp;gt; || set the OS clipboard text || &amp;lt;code&amp;gt;mxw_imgui.set_clipboard_text(&amp;quot;copied value&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Disabled blocks &amp;amp;amp; MXWendler extras ===&lt;br /&gt;
The last two functions are MXWendler additions, not part of stock Dear ImGui bindings.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.begin_disabled(disabled = false)&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;mxw_imgui.end_disabled()&amp;lt;/code&amp;gt; || grey out and block interaction with all widgets in between || &amp;lt;code&amp;gt;mxw_imgui.begin_disabled(not enabled); mxw_imgui.button(&amp;quot;Go&amp;quot;); mxw_imgui.end_disabled()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw_imgui.render_frame(p_min, p_max, colf, border = true, rounding = 0.0)&amp;lt;/code&amp;gt; || draw a filled/bordered rectangle (screen-space corners as &amp;lt;code&amp;gt;Vec2&amp;lt;/code&amp;gt;, color as &amp;lt;code&amp;gt;Vec4&amp;lt;/code&amp;gt;) directly, e.g. for custom backgrounds || &amp;lt;code&amp;gt;mxw_imgui.render_frame(mxw_imgui.Vec2(0,0), mxw_imgui.Vec2(100,20), mxw_imgui.Vec4(0.2,0.2,0.2,1))&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
[[Category:Python]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Python_command_reference&amp;diff=6165</id>
		<title>Python command reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Python_command_reference&amp;diff=6165"/>
		<updated>2026-08-08T15:33:29Z</updated>

		<summary type="html">&lt;p&gt;Admin: Add Category:Python at page end (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- MXWendler wiki page: Python command reference (module mxw) --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Intended location: https://wiki.mxwendler.net/index.php?title=Python_command_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_imgui_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_plugin_reference --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This page lists the commands of the Python module &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt;, MXWendler&#039;s general Python command interface. It is available from the script console and from Python plugins (see the [[Python plugin reference|Python Plugin Howto]]). For drawing plugin panels see the [[Python imgui reference|Python ImGui Reference]].&lt;br /&gt;
&lt;br /&gt;
The embedded interpreter is &#039;&#039;&#039;Python 3.12&#039;&#039;&#039;. Import is implicit in the script console; in a plugin module use &amp;lt;code&amp;gt;import mxw&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The presented Python commands supported in version 7.2. and up&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Legend ===&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;FLOATS&#039;&#039; are written with one decimal: &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt; &amp;amp;rarr; every float between 0 and 1 inclusive.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;INTEGERS&#039;&#039; are written as plain numbers or ranges: &amp;lt;code&amp;gt;1 .. 5&amp;lt;/code&amp;gt; &amp;amp;rarr; the integers 1,2,3,4,5.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;STRINGS&#039;&#039; are written between double quotes.&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; appears, two alternative call formats produce a similar result; use one at a time.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Addressing:&#039;&#039;&#039; widgets are targeted by their OSC-style address string, e.g. &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip&amp;lt;/code&amp;gt;. The same addresses used over OSC work here.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Access model (7.2):&#039;&#039;&#039; widget values are read/written through &amp;lt;code&amp;gt;mxw.widget(address)&amp;lt;/code&amp;gt;; global functions live in the submodules/factories &amp;lt;code&amp;gt;mxw.playlist&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.io&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.preload(n)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.media(name)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.grabber(name)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Reference ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Software Info&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.millis&amp;lt;/code&amp;gt; || milliseconds passed since the software was opened || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;passed time is &amp;quot; + str(mxw.millis))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.width&amp;lt;/code&amp;gt; || current frame width in px || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;frame width is &amp;quot; + str(mxw.width))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.height&amp;lt;/code&amp;gt; || current frame height in px || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;frame height is &amp;quot; + str(mxw.height))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.outwidth&amp;lt;/code&amp;gt; || current output width in px || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;output width is &amp;quot; + str(mxw.outwidth))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.outheight&amp;lt;/code&amp;gt; || current output height in px || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;output height is &amp;quot; + str(mxw.outheight))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.framecounter&amp;lt;/code&amp;gt; || number of frames rendered since the software was opened || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;frames rendered: &amp;quot; + str(mxw.framecounter))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.print_console(&amp;quot;text&amp;quot;)&amp;lt;/code&amp;gt; || print a line to the script console || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;hello&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.print_statusline(&amp;quot;text&amp;quot;)&amp;lt;/code&amp;gt; || print text on the application status line || &amp;lt;code&amp;gt;mxw.print_statusline(&amp;quot;running&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.makescreenshot(&amp;quot;path&amp;quot;)&amp;lt;/code&amp;gt; || save a full-frame screenshot as PNG (empty path &amp;amp;rarr; Desktop) || &amp;lt;code&amp;gt;mxw.makescreenshot(&amp;quot;c:/Users/me/Desktop/shot.png&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.makesectionscreenshot(&amp;quot;path&amp;quot;, x, y, w, h)&amp;lt;/code&amp;gt; || save a cropped screenshot of the region (x, y, w, h) || &amp;lt;code&amp;gt;mxw.makesectionscreenshot(&amp;quot;c:/Users/me/Desktop/crop.png&amp;quot;, 0, 0, 400, 200)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.describe()&amp;lt;/code&amp;gt; || return a text listing of every operation known to the unified interface registry (auto-docs / discovery) || &amp;lt;code&amp;gt;mxw.print_console(mxw.describe())&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; | I/O ( &amp;lt;code&amp;gt;mxw.io&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.dmx(channel)&amp;lt;/code&amp;gt; || return the DMX value received on the given channel || &amp;lt;code&amp;gt;v = mxw.io.dmx(4)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.midi(device, channel)&amp;lt;/code&amp;gt; || return the MIDI value received from device/channel || &amp;lt;code&amp;gt;v = mxw.io.midi(1, 6)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.keyboard(state, key)&amp;lt;/code&amp;gt; || return whether the given key (ASCII) is in the given state || &amp;lt;code&amp;gt;if mxw.io.keyboard(0, 65): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.send_dmx(channel, value)&amp;lt;/code&amp;gt; || send a DMX value on a channel || &amp;lt;code&amp;gt;mxw.io.send_dmx(4, 255)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.send_midi(device, channel, value)&amp;lt;/code&amp;gt; || send a MIDI value to device/channel || &amp;lt;code&amp;gt;mxw.io.send_midi(1, 6, 100)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.pjlink(&amp;quot;command&amp;quot;, &amp;quot;ip&amp;quot;, &amp;quot;pw&amp;quot;)&amp;lt;/code&amp;gt; || PJLink projector control. Commands: &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;avmute_on&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;avmute_off&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vmute_on&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vmute_off&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;mxw.io.pjlink(&amp;quot;on&amp;quot;, &amp;quot;192.168.1.2&amp;quot;, &amp;quot;panasonic&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.send_osc(&amp;quot;host&amp;quot;, port, &amp;quot;address&amp;quot;, &amp;quot;tags&amp;quot;, *args)&amp;lt;/code&amp;gt; || send an OSC message. &amp;lt;code&amp;gt;tags&amp;lt;/code&amp;gt; is one char per argument: &amp;lt;code&amp;gt;d&amp;lt;/code&amp;gt; float, &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; int, &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt; string, &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt; blob (list of 0..255) || &amp;lt;code&amp;gt;mxw.io.send_osc(&amp;quot;127.0.0.1&amp;quot;, 7000, &amp;quot;/cue&amp;quot;, &amp;quot;ci&amp;quot;, &amp;quot;go&amp;quot;, 5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Playlist ( &amp;lt;code&amp;gt;mxw.playlist&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.preload_media()&amp;lt;/code&amp;gt; || preload the media used by the playlist || &amp;lt;code&amp;gt;mxw.playlist.preload_media()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.play()&amp;lt;/code&amp;gt; || play the playlist || &amp;lt;code&amp;gt;mxw.playlist.play()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.pause()&amp;lt;/code&amp;gt; || pause, or restart if already paused || &amp;lt;code&amp;gt;mxw.playlist.pause()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_pause(True/False)&amp;lt;/code&amp;gt; || halt (True) or resume (False) playback || &amp;lt;code&amp;gt;mxw.playlist.go_pause(True)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.skiptonext()&amp;lt;/code&amp;gt; || skip to the next cue || &amp;lt;code&amp;gt;mxw.playlist.skiptonext()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_next()&amp;lt;/code&amp;gt; || go to the next cue without playing || &amp;lt;code&amp;gt;mxw.playlist.go_next()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_prev()&amp;lt;/code&amp;gt; || go to the previous cue || &amp;lt;code&amp;gt;mxw.playlist.go_prev()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_first()&amp;lt;/code&amp;gt; || go to the first cue || &amp;lt;code&amp;gt;mxw.playlist.go_first()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.navigate_index(index)&amp;lt;/code&amp;gt; || go to the cue with the given index || &amp;lt;code&amp;gt;mxw.playlist.navigate_index(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.navigate_string(&amp;quot;name&amp;quot;)&amp;lt;/code&amp;gt; || go to the cue matching the given name || &amp;lt;code&amp;gt;mxw.playlist.navigate_string(&amp;quot;BG_video2&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.get_active_cue()&amp;lt;/code&amp;gt; || return the active cue index (int) || &amp;lt;code&amp;gt;i = mxw.playlist.get_active_cue()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.get_cue_count()&amp;lt;/code&amp;gt; || return the number of cues (int) || &amp;lt;code&amp;gt;n = mxw.playlist.get_cue_count()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.get_cue_names()&amp;lt;/code&amp;gt; || return the list of cue names (index matches &amp;lt;code&amp;gt;navigate_index&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;for name in mxw.playlist.get_cue_names(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.is_rehearsal()&amp;lt;/code&amp;gt; || return True if the playlist is in rehearsal mode || &amp;lt;code&amp;gt;if mxw.playlist.is_rehearsal(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Preload ( &amp;lt;code&amp;gt;mxw.preload(n)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).isvalid()&amp;lt;/code&amp;gt; || True if preload &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; exists || &amp;lt;code&amp;gt;if mxw.preload(2).isvalid(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).clear()&amp;lt;/code&amp;gt; || clear the selected preload || &amp;lt;code&amp;gt;mxw.preload(2).clear()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_media(&amp;quot;filename&amp;quot;)&amp;lt;/code&amp;gt; || set the preload media by filename || &amp;lt;code&amp;gt;mxw.preload(2).set_media(&amp;quot;try.mp4&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_name(&amp;quot;name&amp;quot;)&amp;lt;/code&amp;gt; || rename the preload || &amp;lt;code&amp;gt;mxw.preload(2).set_name(&amp;quot;new_background&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).add_preload()&amp;lt;/code&amp;gt; || load the preload into the layers || &amp;lt;code&amp;gt;mxw.preload(2).add_preload()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).trigger_preload()&amp;lt;/code&amp;gt; || trigger a layer from the preload || &amp;lt;code&amp;gt;mxw.preload(2).trigger_preload()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_activated()&amp;lt;/code&amp;gt; || True if the preload is open for edit || &amp;lt;code&amp;gt;mxw.preload(2).get_activated()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_activated(True/False)&amp;lt;/code&amp;gt; || open/close the preload for edit || &amp;lt;code&amp;gt;mxw.preload(2).set_activated(False)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_layer_position()&amp;lt;/code&amp;gt; || return the preload&#039;s layer index || &amp;lt;code&amp;gt;mxw.preload(2).get_layer_position()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_track_position()&amp;lt;/code&amp;gt; || return the preload&#039;s track index || &amp;lt;code&amp;gt;mxw.preload(2).get_track_position()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_layer_position(pos)&amp;lt;/code&amp;gt; || set the preload&#039;s layer index || &amp;lt;code&amp;gt;mxw.preload(2).set_layer_position(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_track_position(pos)&amp;lt;/code&amp;gt; || set the preload&#039;s track index || &amp;lt;code&amp;gt;mxw.preload(2).set_track_position(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_preload_names()&amp;lt;/code&amp;gt; || return the list of preload comment/name strings || &amp;lt;code&amp;gt;names = mxw.preload(2).get_preload_names()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_image_sample_cvmat(w, h)&amp;lt;/code&amp;gt; || return a &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt;&amp;amp;times;&amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; RGBA image sample of the preload as a buffer (OpenCV Mat) || &amp;lt;code&amp;gt;img = mxw.preload(2).get_image_sample_cvmat(64, 64)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Widgets ( &amp;lt;code&amp;gt;mxw.widget(address)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).getValue()&amp;lt;/code&amp;gt; || return the widget&#039;s normalized value (float) || &amp;lt;code&amp;gt;o = mxw.widget(&amp;quot;/mxw/track/active/layer/active/opacity&amp;quot;).getValue()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).setValue(v)&amp;lt;/code&amp;gt; || set the widget&#039;s normalized value || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/track/active/layer/active/opacity&amp;quot;).setValue(0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).getStringValue()&amp;lt;/code&amp;gt; || return the widget&#039;s string value (e.g. a cue/clip name) || &amp;lt;code&amp;gt;mxw.print_console(mxw.widget(&amp;quot;/mxw/playlist/container/1/column/0/row/1&amp;quot;).getStringValue())&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).setStringValue(&amp;quot;text&amp;quot;)&amp;lt;/code&amp;gt; || set the widget&#039;s string value (e.g. name a cue) || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/playlist/container/1/column/0/row/1&amp;quot;).setStringValue(&amp;quot;background videoclip&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).setWidgetRealValue(d)&amp;lt;/code&amp;gt; || set the widget&#039;s real (un-normalized) value || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).setWidgetRealValue(120.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).animate(initvalue, incomingvalue, duration, delta, type)&amp;lt;/code&amp;gt; || animate the widget value over &amp;lt;code&amp;gt;duration&amp;lt;/code&amp;gt; ms || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).animate(0.0, 1.0, 1000, 0.0, 0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).info()&amp;lt;/code&amp;gt; || return a list describing the widget. For a &#039;&#039;&#039;clip&#039;&#039;&#039;: &amp;lt;code&amp;gt;[length, width, height, millis_per_frame, cache_state, media_path]&amp;lt;/code&amp;gt;. Returns &amp;lt;code&amp;gt;[]&amp;lt;/code&amp;gt; if the address does not resolve || &amp;lt;code&amp;gt;length, w, h, mspf, cache, path = mxw.widget(&amp;quot;/mxw/track/active/layer/active/clip&amp;quot;).info()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Media ( &amp;lt;code&amp;gt;mxw.media(name)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).isvalid()&amp;lt;/code&amp;gt; || True if the named media exists || &amp;lt;code&amp;gt;if mxw.media(&amp;quot;USB Cam&amp;quot;).isvalid(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).reference(True/False)&amp;lt;/code&amp;gt; || add (True) or remove (False) a reference that keeps the media loaded || &amp;lt;code&amp;gt;mxw.media(&amp;quot;clip.mov&amp;quot;).reference(True)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).unload_media_full_if_not_used_by_clips()&amp;lt;/code&amp;gt; || unload the media if no clip uses it (returns bool) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;clip.mov&amp;quot;).unload_media_full_if_not_used_by_clips()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).get_image_sample_cvmat(w, h)&amp;lt;/code&amp;gt; || return a &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt;&amp;amp;times;&amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; RGBA image sample of the media (OpenCV Mat) || &amp;lt;code&amp;gt;img = mxw.media(&amp;quot;clip.mov&amp;quot;).get_image_sample_cvmat(64, 64)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).get_image_sample_cvmat_async(w, h)&amp;lt;/code&amp;gt; || non-blocking variant of the image sample || &amp;lt;code&amp;gt;img = mxw.media(&amp;quot;clip.mov&amp;quot;).get_image_sample_cvmat_async(64, 64)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).get_capture_device_names()&amp;lt;/code&amp;gt; || return the list of available capture-device names || &amp;lt;code&amp;gt;devs = mxw.media(&amp;quot;&amp;quot;).get_capture_device_names()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_is_supported&amp;quot;)&amp;lt;/code&amp;gt; || return whether the (NDI) camera supports PTZ || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_is_supported&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_zoom&amp;quot;, value)&amp;lt;/code&amp;gt; || zoom, 0 (in) .. 1 (out) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_zoom&amp;quot;, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_zoom_speed&amp;quot;, value)&amp;lt;/code&amp;gt; || zoom speed, -1 (out) .. 1 (in) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_zoom_speed&amp;quot;, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_pan_tilt&amp;quot;, pan, tilt)&amp;lt;/code&amp;gt; || absolute pan/tilt, -1 .. 1 || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_pan_tilt&amp;quot;, -0.5, 0.2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_pan_tilt_speed&amp;quot;, pan_speed, tilt_speed)&amp;lt;/code&amp;gt; || pan/tilt speed, -1 (right/down) .. 1 (left/up) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_pan_tilt_speed&amp;quot;, -0.3, 0.8)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_store_preset&amp;quot;, n)&amp;lt;/code&amp;gt; || store position/focus/zoom into preset 0 .. 99 || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_store_preset&amp;quot;, 75)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_recall_preset&amp;quot;, n, speed)&amp;lt;/code&amp;gt; || recall preset 0 .. 99 at speed 0 .. 1 || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_recall_preset&amp;quot;, 4, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_auto_focus&amp;quot;)&amp;lt;/code&amp;gt; || toggle auto-focus || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_auto_focus&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_focus&amp;quot;, value)&amp;lt;/code&amp;gt; || absolute focus, 0 (infinity) .. 1 (closest) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_focus&amp;quot;, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_focus_speed&amp;quot;, value)&amp;lt;/code&amp;gt; || focus speed, -1 (out) .. 1 (in) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_focus_speed&amp;quot;, -0.2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_auto&amp;quot;)&amp;lt;/code&amp;gt; || auto white balance || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_auto&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_indoor&amp;quot;)&amp;lt;/code&amp;gt; || indoor white balance || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_indoor&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_outdoor&amp;quot;)&amp;lt;/code&amp;gt; || outdoor white balance || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_outdoor&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_oneshot&amp;quot;)&amp;lt;/code&amp;gt; || set white balance once from current brightness || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_oneshot&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_manual&amp;quot;, red, blue)&amp;lt;/code&amp;gt; || manual white balance, 0.0 .. 1.0 each || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_manual&amp;quot;, 0.1, 0.7)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_exposure_auto&amp;quot;)&amp;lt;/code&amp;gt; || auto exposure || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_exposure_auto&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_exposure_manual&amp;quot;, level)&amp;lt;/code&amp;gt; || manual exposure iris, 0.0 (dark) .. 1.0 (light) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_exposure_manual&amp;quot;, 0.4)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_exposure_manual_v2&amp;quot;, iris, gain, shutter)&amp;lt;/code&amp;gt; || manual exposure iris/gain/shutter, 0.0 .. 1.0 each || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_exposure_manual_v2&amp;quot;, 0.4, 0.2, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Grabber ( &amp;lt;code&amp;gt;mxw.grabber(name)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).isvalid()&amp;lt;/code&amp;gt; || True if the named keystone grabber exists || &amp;lt;code&amp;gt;if mxw.grabber(&amp;quot;cam&amp;quot;).isvalid(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).getGrabSizeX()&amp;lt;/code&amp;gt; || grabber width in px || &amp;lt;code&amp;gt;mxw.grabber(&amp;quot;cam&amp;quot;).getGrabSizeX()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).getGrabSizeY()&amp;lt;/code&amp;gt; || grabber height in px || &amp;lt;code&amp;gt;mxw.grabber(&amp;quot;cam&amp;quot;).getGrabSizeY()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).getData()&amp;lt;/code&amp;gt; || return the grabber&#039;s pixels as a byte list (RGBA, width&amp;amp;times;height&amp;amp;times;4) || &amp;lt;code&amp;gt;px = mxw.grabber(&amp;quot;cam&amp;quot;).getData()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== See also ===&lt;br /&gt;
&lt;br /&gt;
* [[Python imgui reference|Python ImGui Reference]] &amp;amp;ndash; drawing plugin panels with &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt;&lt;br /&gt;
* [[Python plugin reference|Python Plugin Howto]] &amp;amp;ndash; writing media and playlist plugins&lt;br /&gt;
[[Category:Python]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Python_Reference&amp;diff=6164</id>
		<title>Python Reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Python_Reference&amp;diff=6164"/>
		<updated>2026-08-08T15:33:27Z</updated>

		<summary type="html">&lt;p&gt;Admin: Add Category:Python at page end (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
This document describes the MXWendler (MXW) Python command interface through an overview of the programming structure, with practical examples of automation and internal scripting. The presented Python commands are for most part supported in version 7.2.&lt;br /&gt;
&lt;br /&gt;
== What is Python? ==&lt;br /&gt;
Python is a standardized interpreted, high level programming language. It is used in many applications, mainly in AI and generative tasks. The amount of available libraries is outstanding.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[1. Controlling MXW through Python]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[Python command reference | 2. Python command reference]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[Python imgui reference | 2. Python imgui reference]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[Python plugin reference | Python plugin reference]] &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
[[Category:Python]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=JavaScript_command_reference&amp;diff=6163</id>
		<title>JavaScript command reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=JavaScript_command_reference&amp;diff=6163"/>
		<updated>2026-08-08T15:33:26Z</updated>

		<summary type="html">&lt;p&gt;Admin: Add Category:JavaScript at page end (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- MXWendler wiki page: JavaScript command reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Intended location: https://wiki.mxwendler.net/index.php?title=JavaScript_command_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=JavaScript_Reference --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This page lists the commands of the MXWendler JavaScript command interface. Scripts run on an embedded ECMAScript engine (Duktape) and reach the software through the global &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt; object plus a few free functions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The presented JavaScript commands supported in version 7.2. and up&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Legend ===&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;FLOATS&#039;&#039; are written with one decimal: &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt; &amp;amp;rarr; every float between 0 and 1 inclusive.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;INTEGERS&#039;&#039; are written as plain numbers or ranges: &amp;lt;code&amp;gt;1 .. 5&amp;lt;/code&amp;gt; &amp;amp;rarr; the integers 1,2,3,4,5.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;STRINGS&#039;&#039; are written between double quotes.&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; appears, two alternative call formats produce a similar result; use one at a time.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Addressing:&#039;&#039;&#039; widgets are targeted by their OSC-style address string, e.g. &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Access model:&#039;&#039;&#039; &amp;lt;code&amp;gt;mxw.playlist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;mxw.io&amp;lt;/code&amp;gt; are ready-made objects &amp;amp;ndash; call their methods directly, e.g. &amp;lt;code&amp;gt;mxw.playlist.play()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.io.dmx(4)&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;mxw.widget(address)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.media(name)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.preload(n)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;mxw.grabber(name)&amp;lt;/code&amp;gt; are factories that take an address/name/index and return the object to call, e.g. &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).getValue()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Reference ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! JS COMMAND !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Software Info&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.millis&amp;lt;/code&amp;gt; || milliseconds passed since the software was opened || &amp;lt;code&amp;gt;print_console(&amp;quot;passed time is &amp;quot; + mxw.millis)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.width&amp;lt;/code&amp;gt; || current frame width in px || &amp;lt;code&amp;gt;print_console(&amp;quot;frame width is &amp;quot; + mxw.width)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.height&amp;lt;/code&amp;gt; || current frame height in px || &amp;lt;code&amp;gt;print_console(&amp;quot;frame height is &amp;quot; + mxw.height)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.outwidth&amp;lt;/code&amp;gt; || current output width in px || &amp;lt;code&amp;gt;print_console(&amp;quot;output width is &amp;quot; + mxw.outwidth)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.outheight&amp;lt;/code&amp;gt; || current output height in px || &amp;lt;code&amp;gt;print_console(&amp;quot;output height is &amp;quot; + mxw.outheight)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.framecounter&amp;lt;/code&amp;gt; || number of frames rendered since the software was opened || &amp;lt;code&amp;gt;print_console(&amp;quot;frames rendered: &amp;quot; + mxw.framecounter)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;print_console(&amp;quot;text&amp;quot;)&amp;lt;/code&amp;gt; || print a line to the script console (global function) || &amp;lt;code&amp;gt;print_console(&amp;quot;hello&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;print_statusline(&amp;quot;text&amp;quot;)&amp;lt;/code&amp;gt; || print text on the application status line (global function) || &amp;lt;code&amp;gt;print_statusline(&amp;quot;running&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.makescreenshot(&amp;quot;path&amp;quot;)&amp;lt;/code&amp;gt; || save a full-frame screenshot as PNG || &amp;lt;code&amp;gt;mxw.makescreenshot(&amp;quot;c:/Users/me/Desktop/shot.png&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.makesectionscreenshot(&amp;quot;path&amp;quot;, x, y, w, h)&amp;lt;/code&amp;gt; || save a cropped screenshot of the region (x, y, w, h) || &amp;lt;code&amp;gt;mxw.makesectionscreenshot(&amp;quot;c:/Users/me/Desktop/crop.png&amp;quot;, 0, 0, 400, 200)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.describe()&amp;lt;/code&amp;gt; || return a text listing of every operation known to the unified interface registry || &amp;lt;code&amp;gt;print_console(mxw.describe())&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; | I/O ( &amp;lt;code&amp;gt;mxw.io&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.dmx(channel)&amp;lt;/code&amp;gt; || return the DMX value received on the given channel || &amp;lt;code&amp;gt;print_console(&amp;quot;DMX ch4 = &amp;quot; + mxw.io.dmx(4))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.midi(device, channel)&amp;lt;/code&amp;gt; || return the MIDI value received from device/channel || &amp;lt;code&amp;gt;print_console(&amp;quot;MIDI = &amp;quot; + mxw.io.midi(1, 6))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.keyboard(state, key)&amp;lt;/code&amp;gt; || return whether the given key (ASCII) is in the given state || &amp;lt;code&amp;gt;mxw.io.keyboard(0, 65)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.send_dmx(channel, value)&amp;lt;/code&amp;gt; || send a DMX value on a channel || &amp;lt;code&amp;gt;mxw.io.send_dmx(4, 255)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.send_midi(device, channel, value)&amp;lt;/code&amp;gt; || send a MIDI value to device/channel || &amp;lt;code&amp;gt;mxw.io.send_midi(1, 6, 100)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.pjlink(&amp;quot;command&amp;quot;, &amp;quot;ip&amp;quot;, &amp;quot;pw&amp;quot;)&amp;lt;/code&amp;gt; || PJLink projector control. Commands: &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;avmute_on&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;avmute_off&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vmute_on&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vmute_off&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;mxw.io.pjlink(&amp;quot;on&amp;quot;, &amp;quot;192.168.1.2&amp;quot;, &amp;quot;panasonic&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.send_osc(&amp;quot;host&amp;quot;, port, &amp;quot;address&amp;quot;, &amp;quot;tags&amp;quot;, ...args)&amp;lt;/code&amp;gt; || send an OSC message. &amp;lt;code&amp;gt;tags&amp;lt;/code&amp;gt; is one char per argument: &amp;lt;code&amp;gt;d&amp;lt;/code&amp;gt; float, &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; int, &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt; string, &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt; blob (array of 0..255) || &amp;lt;code&amp;gt;mxw.io.send_osc(&amp;quot;127.0.0.1&amp;quot;, 7000, &amp;quot;/cue&amp;quot;, &amp;quot;ci&amp;quot;, &amp;quot;go&amp;quot;, 5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Playlist ( &amp;lt;code&amp;gt;mxw.playlist&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.preload_media()&amp;lt;/code&amp;gt; || preload the media used by the playlist || &amp;lt;code&amp;gt;mxw.playlist.preload_media()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.play()&amp;lt;/code&amp;gt; || play the playlist || &amp;lt;code&amp;gt;mxw.playlist.play()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.pause()&amp;lt;/code&amp;gt; || pause, or restart if already paused || &amp;lt;code&amp;gt;mxw.playlist.pause()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_pause(true/false)&amp;lt;/code&amp;gt; || halt (true) or resume (false) playback || &amp;lt;code&amp;gt;mxw.playlist.go_pause(true)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.skiptonext()&amp;lt;/code&amp;gt; || skip to the next cue || &amp;lt;code&amp;gt;mxw.playlist.skiptonext()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_next()&amp;lt;/code&amp;gt; || go to the next cue without playing || &amp;lt;code&amp;gt;mxw.playlist.go_next()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_prev()&amp;lt;/code&amp;gt; || go to the previous cue || &amp;lt;code&amp;gt;mxw.playlist.go_prev()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_first()&amp;lt;/code&amp;gt; || go to the first cue || &amp;lt;code&amp;gt;mxw.playlist.go_first()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.navigate_index(index)&amp;lt;/code&amp;gt; || go to the cue with the given index || &amp;lt;code&amp;gt;mxw.playlist.navigate_index(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.navigate_string(&amp;quot;name&amp;quot;)&amp;lt;/code&amp;gt; || go to the cue matching the given name || &amp;lt;code&amp;gt;mxw.playlist.navigate_string(&amp;quot;BG_video2&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.get_active_cue()&amp;lt;/code&amp;gt; || return the active cue index || &amp;lt;code&amp;gt;var i = mxw.playlist.get_active_cue()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Preload ( &amp;lt;code&amp;gt;mxw.preload(n)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).clear()&amp;lt;/code&amp;gt; || clear the selected preload || &amp;lt;code&amp;gt;mxw.preload(2).clear()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_media(&amp;quot;filename&amp;quot;)&amp;lt;/code&amp;gt; || set the preload media by filename || &amp;lt;code&amp;gt;mxw.preload(2).set_media(&amp;quot;try.mp4&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_name(&amp;quot;name&amp;quot;)&amp;lt;/code&amp;gt; || rename the preload || &amp;lt;code&amp;gt;mxw.preload(2).set_name(&amp;quot;new_background&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_name()&amp;lt;/code&amp;gt; || return the preload name || &amp;lt;code&amp;gt;var s = mxw.preload(2).get_name()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).add_preload()&amp;lt;/code&amp;gt; || load the preload into the layers || &amp;lt;code&amp;gt;mxw.preload(2).add_preload()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).trigger_preload()&amp;lt;/code&amp;gt; || trigger a layer from the preload || &amp;lt;code&amp;gt;mxw.preload(2).trigger_preload()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_activated()&amp;lt;/code&amp;gt; || true if the preload is open for edit || &amp;lt;code&amp;gt;mxw.preload(2).get_activated()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_activated(true/false)&amp;lt;/code&amp;gt; || open/close the preload for edit || &amp;lt;code&amp;gt;mxw.preload(2).set_activated(false)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_layer_position()&amp;lt;/code&amp;gt; || return the preload&#039;s layer index || &amp;lt;code&amp;gt;mxw.preload(2).get_layer_position()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_track_position()&amp;lt;/code&amp;gt; || return the preload&#039;s track index || &amp;lt;code&amp;gt;mxw.preload(2).get_track_position()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_layer_position(pos)&amp;lt;/code&amp;gt; || set the preload&#039;s layer index || &amp;lt;code&amp;gt;mxw.preload(2).set_layer_position(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_track_position(pos)&amp;lt;/code&amp;gt; || set the preload&#039;s track index || &amp;lt;code&amp;gt;mxw.preload(2).set_track_position(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Widgets ( &amp;lt;code&amp;gt;mxw.widget(address)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).isvalid()&amp;lt;/code&amp;gt; || true if the address resolves to a widget || &amp;lt;code&amp;gt;if (mxw.widget(&amp;quot;/mxw/path&amp;quot;).isvalid()) {}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).getValue()&amp;lt;/code&amp;gt; || return the widget&#039;s normalized value || &amp;lt;code&amp;gt;var o = mxw.widget(&amp;quot;/mxw/track/active/layer/active/opacity&amp;quot;).getValue()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).setValue(v)&amp;lt;/code&amp;gt; || set the widget&#039;s normalized value || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/track/active/layer/active/opacity&amp;quot;).setValue(0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).getStringValue()&amp;lt;/code&amp;gt; || return the widget&#039;s string value (e.g. a cue/clip name) || &amp;lt;code&amp;gt;print_console(mxw.widget(&amp;quot;/mxw/playlist/container/1/column/0/row/1&amp;quot;).getStringValue())&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).setStringValue(&amp;quot;text&amp;quot;)&amp;lt;/code&amp;gt; || set the widget&#039;s string value (e.g. name a cue) || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/playlist/container/1/column/0/row/1&amp;quot;).setStringValue(&amp;quot;background videoclip&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).animate(initvalue, incomingvalue, duration, delta, type)&amp;lt;/code&amp;gt; || animate the widget value over &amp;lt;code&amp;gt;duration&amp;lt;/code&amp;gt; ms || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).animate(0.0, 1.0, 1000, 0.0, 0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).info()&amp;lt;/code&amp;gt; || return an array describing the widget. For a &#039;&#039;&#039;clip&#039;&#039;&#039;: &amp;lt;code&amp;gt;[length, width, height, millis_per_frame, cache_state, media_path]&amp;lt;/code&amp;gt;. Empty array if the address does not resolve || &amp;lt;code&amp;gt;var info = mxw.widget(&amp;quot;/mxw/track/active/layer/active/clip&amp;quot;).info(); print_console(info[5]);&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Media ( &amp;lt;code&amp;gt;mxw.media(name)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).isvalid()&amp;lt;/code&amp;gt; || true if the named media exists || &amp;lt;code&amp;gt;if (mxw.media(&amp;quot;USB Cam&amp;quot;).isvalid()) {}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_is_supported&amp;quot;)&amp;lt;/code&amp;gt; || return whether the (NDI) camera supports PTZ || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_is_supported&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_zoom&amp;quot;, value)&amp;lt;/code&amp;gt; || zoom, 0 (in) .. 1 (out) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_zoom&amp;quot;, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_zoom_speed&amp;quot;, value)&amp;lt;/code&amp;gt; || zoom speed, -1 (out) .. 1 (in) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_zoom_speed&amp;quot;, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_pan_tilt&amp;quot;, pan, tilt)&amp;lt;/code&amp;gt; || absolute pan/tilt, -1 .. 1 || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_pan_tilt&amp;quot;, -0.5, 0.2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_pan_tilt_speed&amp;quot;, pan_speed, tilt_speed)&amp;lt;/code&amp;gt; || pan/tilt speed, -1 (right/down) .. 1 (left/up) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_pan_tilt_speed&amp;quot;, -0.3, 0.8)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_store_preset&amp;quot;, n)&amp;lt;/code&amp;gt; || store position/focus/zoom into preset 0 .. 99 || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_store_preset&amp;quot;, 75)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_recall_preset&amp;quot;, n, speed)&amp;lt;/code&amp;gt; || recall preset 0 .. 99 at speed 0 .. 1 || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_recall_preset&amp;quot;, 4, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_auto_focus&amp;quot;)&amp;lt;/code&amp;gt; || toggle auto-focus || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_auto_focus&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_focus&amp;quot;, value)&amp;lt;/code&amp;gt; || absolute focus, 0 (infinity) .. 1 (closest) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_focus&amp;quot;, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_focus_speed&amp;quot;, value)&amp;lt;/code&amp;gt; || focus speed, -1 (out) .. 1 (in) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_focus_speed&amp;quot;, -0.2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_auto&amp;quot;)&amp;lt;/code&amp;gt; || auto white balance || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_auto&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_indoor&amp;quot;)&amp;lt;/code&amp;gt; || indoor white balance || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_indoor&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_outdoor&amp;quot;)&amp;lt;/code&amp;gt; || outdoor white balance || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_outdoor&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_oneshot&amp;quot;)&amp;lt;/code&amp;gt; || set white balance once from current brightness || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_oneshot&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_manual&amp;quot;, red, blue)&amp;lt;/code&amp;gt; || manual white balance, 0.0 .. 1.0 each || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_manual&amp;quot;, 0.1, 0.7)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_exposure_auto&amp;quot;)&amp;lt;/code&amp;gt; || auto exposure || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_exposure_auto&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_exposure_manual&amp;quot;, level)&amp;lt;/code&amp;gt; || manual exposure iris, 0.0 (dark) .. 1.0 (light) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_exposure_manual&amp;quot;, 0.4)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_exposure_manual_v2&amp;quot;, iris, gain, shutter)&amp;lt;/code&amp;gt; || manual exposure iris/gain/shutter, 0.0 .. 1.0 each || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_exposure_manual_v2&amp;quot;, 0.4, 0.2, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Grabber ( &amp;lt;code&amp;gt;mxw.grabber(name)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).isvalid()&amp;lt;/code&amp;gt; || true if the named keystone grabber exists || &amp;lt;code&amp;gt;if (mxw.grabber(&amp;quot;cam&amp;quot;).isvalid()) {}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).getGrabSizeX()&amp;lt;/code&amp;gt; || grabber width in px || &amp;lt;code&amp;gt;mxw.grabber(&amp;quot;cam&amp;quot;).getGrabSizeX()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).getGrabSizeY()&amp;lt;/code&amp;gt; || grabber height in px || &amp;lt;code&amp;gt;mxw.grabber(&amp;quot;cam&amp;quot;).getGrabSizeY()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).getData()&amp;lt;/code&amp;gt; || return the grabber&#039;s pixels (RGBA, width&amp;amp;times;height&amp;amp;times;4) || &amp;lt;code&amp;gt;var px = mxw.grabber(&amp;quot;cam&amp;quot;).getData()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== See also ===&lt;br /&gt;
&lt;br /&gt;
* [[JavaScript_Reference|JavaScript Reference]] &amp;amp;ndash; overview and getting started&lt;br /&gt;
[[Category:JavaScript]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=JavaScript_Reference&amp;diff=6162</id>
		<title>JavaScript Reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=JavaScript_Reference&amp;diff=6162"/>
		<updated>2026-08-08T15:33:24Z</updated>

		<summary type="html">&lt;p&gt;Admin: Add Category:JavaScript at page end (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This reference applies to all different OS. The presented OSC commands are for most part supported in version 6.0 but will be fully functional in version 6.0.08 and above.&lt;br /&gt;
&amp;lt;div class=&amp;quot;noprint&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
This document describes the MXWendler (MXW) JavaScript Command Interface through an overview of the programming structure, with practical examples of automation and internal scripting.&lt;br /&gt;
&lt;br /&gt;
== What is JavaScript? ==&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
JavaScript is a standardized interpreted, high level programming language. It is one of the core technologies of the World Wide Web and it is mainly used in web browsers to control web pages and test the user input before sending it.&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/JavaScript[1&amp;lt;nowiki&amp;gt;]&amp;lt;/nowiki&amp;gt; Wikipedia Link]&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[1. Controlling MXW through JavaScript]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[JavaScript command reference | 2. JavaScript command reference]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[4. Practical examples | 3. Practical examples]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[5. Troubleshooting scripts | 4. Troubleshooting scripts]] &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 10px&amp;quot; | [[6. External Resources | 5. External Resources]]&lt;br /&gt;
|}&lt;br /&gt;
[[Category:JavaScript]]&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=JavaScript_command_reference&amp;diff=6161</id>
		<title>JavaScript command reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=JavaScript_command_reference&amp;diff=6161"/>
		<updated>2026-08-08T15:28:33Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update links after removing &amp;#039;3.&amp;#039; prefix from reference titles (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- MXWendler wiki page: JavaScript command reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Intended location: https://wiki.mxwendler.net/index.php?title=JavaScript_command_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=JavaScript_Reference --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This page lists the commands of the MXWendler JavaScript command interface. Scripts run on an embedded ECMAScript engine (Duktape) and reach the software through the global &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt; object plus a few free functions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The presented JavaScript commands supported in version 7.2. and up&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Legend ===&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;FLOATS&#039;&#039; are written with one decimal: &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt; &amp;amp;rarr; every float between 0 and 1 inclusive.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;INTEGERS&#039;&#039; are written as plain numbers or ranges: &amp;lt;code&amp;gt;1 .. 5&amp;lt;/code&amp;gt; &amp;amp;rarr; the integers 1,2,3,4,5.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;STRINGS&#039;&#039; are written between double quotes.&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; appears, two alternative call formats produce a similar result; use one at a time.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Addressing:&#039;&#039;&#039; widgets are targeted by their OSC-style address string, e.g. &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Access model:&#039;&#039;&#039; &amp;lt;code&amp;gt;mxw.playlist&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;mxw.io&amp;lt;/code&amp;gt; are ready-made objects &amp;amp;ndash; call their methods directly, e.g. &amp;lt;code&amp;gt;mxw.playlist.play()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.io.dmx(4)&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;mxw.widget(address)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.media(name)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.preload(n)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;mxw.grabber(name)&amp;lt;/code&amp;gt; are factories that take an address/name/index and return the object to call, e.g. &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).getValue()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Reference ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! JS COMMAND !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Software Info&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.millis&amp;lt;/code&amp;gt; || milliseconds passed since the software was opened || &amp;lt;code&amp;gt;print_console(&amp;quot;passed time is &amp;quot; + mxw.millis)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.width&amp;lt;/code&amp;gt; || current frame width in px || &amp;lt;code&amp;gt;print_console(&amp;quot;frame width is &amp;quot; + mxw.width)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.height&amp;lt;/code&amp;gt; || current frame height in px || &amp;lt;code&amp;gt;print_console(&amp;quot;frame height is &amp;quot; + mxw.height)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.outwidth&amp;lt;/code&amp;gt; || current output width in px || &amp;lt;code&amp;gt;print_console(&amp;quot;output width is &amp;quot; + mxw.outwidth)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.outheight&amp;lt;/code&amp;gt; || current output height in px || &amp;lt;code&amp;gt;print_console(&amp;quot;output height is &amp;quot; + mxw.outheight)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.framecounter&amp;lt;/code&amp;gt; || number of frames rendered since the software was opened || &amp;lt;code&amp;gt;print_console(&amp;quot;frames rendered: &amp;quot; + mxw.framecounter)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;print_console(&amp;quot;text&amp;quot;)&amp;lt;/code&amp;gt; || print a line to the script console (global function) || &amp;lt;code&amp;gt;print_console(&amp;quot;hello&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;print_statusline(&amp;quot;text&amp;quot;)&amp;lt;/code&amp;gt; || print text on the application status line (global function) || &amp;lt;code&amp;gt;print_statusline(&amp;quot;running&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.makescreenshot(&amp;quot;path&amp;quot;)&amp;lt;/code&amp;gt; || save a full-frame screenshot as PNG || &amp;lt;code&amp;gt;mxw.makescreenshot(&amp;quot;c:/Users/me/Desktop/shot.png&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.makesectionscreenshot(&amp;quot;path&amp;quot;, x, y, w, h)&amp;lt;/code&amp;gt; || save a cropped screenshot of the region (x, y, w, h) || &amp;lt;code&amp;gt;mxw.makesectionscreenshot(&amp;quot;c:/Users/me/Desktop/crop.png&amp;quot;, 0, 0, 400, 200)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.describe()&amp;lt;/code&amp;gt; || return a text listing of every operation known to the unified interface registry || &amp;lt;code&amp;gt;print_console(mxw.describe())&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; | I/O ( &amp;lt;code&amp;gt;mxw.io&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.dmx(channel)&amp;lt;/code&amp;gt; || return the DMX value received on the given channel || &amp;lt;code&amp;gt;print_console(&amp;quot;DMX ch4 = &amp;quot; + mxw.io.dmx(4))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.midi(device, channel)&amp;lt;/code&amp;gt; || return the MIDI value received from device/channel || &amp;lt;code&amp;gt;print_console(&amp;quot;MIDI = &amp;quot; + mxw.io.midi(1, 6))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.keyboard(state, key)&amp;lt;/code&amp;gt; || return whether the given key (ASCII) is in the given state || &amp;lt;code&amp;gt;mxw.io.keyboard(0, 65)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.send_dmx(channel, value)&amp;lt;/code&amp;gt; || send a DMX value on a channel || &amp;lt;code&amp;gt;mxw.io.send_dmx(4, 255)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.send_midi(device, channel, value)&amp;lt;/code&amp;gt; || send a MIDI value to device/channel || &amp;lt;code&amp;gt;mxw.io.send_midi(1, 6, 100)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.pjlink(&amp;quot;command&amp;quot;, &amp;quot;ip&amp;quot;, &amp;quot;pw&amp;quot;)&amp;lt;/code&amp;gt; || PJLink projector control. Commands: &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;avmute_on&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;avmute_off&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vmute_on&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vmute_off&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;mxw.io.pjlink(&amp;quot;on&amp;quot;, &amp;quot;192.168.1.2&amp;quot;, &amp;quot;panasonic&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.send_osc(&amp;quot;host&amp;quot;, port, &amp;quot;address&amp;quot;, &amp;quot;tags&amp;quot;, ...args)&amp;lt;/code&amp;gt; || send an OSC message. &amp;lt;code&amp;gt;tags&amp;lt;/code&amp;gt; is one char per argument: &amp;lt;code&amp;gt;d&amp;lt;/code&amp;gt; float, &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; int, &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt; string, &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt; blob (array of 0..255) || &amp;lt;code&amp;gt;mxw.io.send_osc(&amp;quot;127.0.0.1&amp;quot;, 7000, &amp;quot;/cue&amp;quot;, &amp;quot;ci&amp;quot;, &amp;quot;go&amp;quot;, 5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Playlist ( &amp;lt;code&amp;gt;mxw.playlist&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.preload_media()&amp;lt;/code&amp;gt; || preload the media used by the playlist || &amp;lt;code&amp;gt;mxw.playlist.preload_media()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.play()&amp;lt;/code&amp;gt; || play the playlist || &amp;lt;code&amp;gt;mxw.playlist.play()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.pause()&amp;lt;/code&amp;gt; || pause, or restart if already paused || &amp;lt;code&amp;gt;mxw.playlist.pause()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_pause(true/false)&amp;lt;/code&amp;gt; || halt (true) or resume (false) playback || &amp;lt;code&amp;gt;mxw.playlist.go_pause(true)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.skiptonext()&amp;lt;/code&amp;gt; || skip to the next cue || &amp;lt;code&amp;gt;mxw.playlist.skiptonext()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_next()&amp;lt;/code&amp;gt; || go to the next cue without playing || &amp;lt;code&amp;gt;mxw.playlist.go_next()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_prev()&amp;lt;/code&amp;gt; || go to the previous cue || &amp;lt;code&amp;gt;mxw.playlist.go_prev()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_first()&amp;lt;/code&amp;gt; || go to the first cue || &amp;lt;code&amp;gt;mxw.playlist.go_first()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.navigate_index(index)&amp;lt;/code&amp;gt; || go to the cue with the given index || &amp;lt;code&amp;gt;mxw.playlist.navigate_index(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.navigate_string(&amp;quot;name&amp;quot;)&amp;lt;/code&amp;gt; || go to the cue matching the given name || &amp;lt;code&amp;gt;mxw.playlist.navigate_string(&amp;quot;BG_video2&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.get_active_cue()&amp;lt;/code&amp;gt; || return the active cue index || &amp;lt;code&amp;gt;var i = mxw.playlist.get_active_cue()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Preload ( &amp;lt;code&amp;gt;mxw.preload(n)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).clear()&amp;lt;/code&amp;gt; || clear the selected preload || &amp;lt;code&amp;gt;mxw.preload(2).clear()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_media(&amp;quot;filename&amp;quot;)&amp;lt;/code&amp;gt; || set the preload media by filename || &amp;lt;code&amp;gt;mxw.preload(2).set_media(&amp;quot;try.mp4&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_name(&amp;quot;name&amp;quot;)&amp;lt;/code&amp;gt; || rename the preload || &amp;lt;code&amp;gt;mxw.preload(2).set_name(&amp;quot;new_background&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_name()&amp;lt;/code&amp;gt; || return the preload name || &amp;lt;code&amp;gt;var s = mxw.preload(2).get_name()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).add_preload()&amp;lt;/code&amp;gt; || load the preload into the layers || &amp;lt;code&amp;gt;mxw.preload(2).add_preload()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).trigger_preload()&amp;lt;/code&amp;gt; || trigger a layer from the preload || &amp;lt;code&amp;gt;mxw.preload(2).trigger_preload()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_activated()&amp;lt;/code&amp;gt; || true if the preload is open for edit || &amp;lt;code&amp;gt;mxw.preload(2).get_activated()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_activated(true/false)&amp;lt;/code&amp;gt; || open/close the preload for edit || &amp;lt;code&amp;gt;mxw.preload(2).set_activated(false)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_layer_position()&amp;lt;/code&amp;gt; || return the preload&#039;s layer index || &amp;lt;code&amp;gt;mxw.preload(2).get_layer_position()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_track_position()&amp;lt;/code&amp;gt; || return the preload&#039;s track index || &amp;lt;code&amp;gt;mxw.preload(2).get_track_position()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_layer_position(pos)&amp;lt;/code&amp;gt; || set the preload&#039;s layer index || &amp;lt;code&amp;gt;mxw.preload(2).set_layer_position(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_track_position(pos)&amp;lt;/code&amp;gt; || set the preload&#039;s track index || &amp;lt;code&amp;gt;mxw.preload(2).set_track_position(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Widgets ( &amp;lt;code&amp;gt;mxw.widget(address)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).isvalid()&amp;lt;/code&amp;gt; || true if the address resolves to a widget || &amp;lt;code&amp;gt;if (mxw.widget(&amp;quot;/mxw/path&amp;quot;).isvalid()) {}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).getValue()&amp;lt;/code&amp;gt; || return the widget&#039;s normalized value || &amp;lt;code&amp;gt;var o = mxw.widget(&amp;quot;/mxw/track/active/layer/active/opacity&amp;quot;).getValue()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).setValue(v)&amp;lt;/code&amp;gt; || set the widget&#039;s normalized value || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/track/active/layer/active/opacity&amp;quot;).setValue(0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).getStringValue()&amp;lt;/code&amp;gt; || return the widget&#039;s string value (e.g. a cue/clip name) || &amp;lt;code&amp;gt;print_console(mxw.widget(&amp;quot;/mxw/playlist/container/1/column/0/row/1&amp;quot;).getStringValue())&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).setStringValue(&amp;quot;text&amp;quot;)&amp;lt;/code&amp;gt; || set the widget&#039;s string value (e.g. name a cue) || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/playlist/container/1/column/0/row/1&amp;quot;).setStringValue(&amp;quot;background videoclip&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).animate(initvalue, incomingvalue, duration, delta, type)&amp;lt;/code&amp;gt; || animate the widget value over &amp;lt;code&amp;gt;duration&amp;lt;/code&amp;gt; ms || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).animate(0.0, 1.0, 1000, 0.0, 0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).info()&amp;lt;/code&amp;gt; || return an array describing the widget. For a &#039;&#039;&#039;clip&#039;&#039;&#039;: &amp;lt;code&amp;gt;[length, width, height, millis_per_frame, cache_state, media_path]&amp;lt;/code&amp;gt;. Empty array if the address does not resolve || &amp;lt;code&amp;gt;var info = mxw.widget(&amp;quot;/mxw/track/active/layer/active/clip&amp;quot;).info(); print_console(info[5]);&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Media ( &amp;lt;code&amp;gt;mxw.media(name)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).isvalid()&amp;lt;/code&amp;gt; || true if the named media exists || &amp;lt;code&amp;gt;if (mxw.media(&amp;quot;USB Cam&amp;quot;).isvalid()) {}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_is_supported&amp;quot;)&amp;lt;/code&amp;gt; || return whether the (NDI) camera supports PTZ || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_is_supported&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_zoom&amp;quot;, value)&amp;lt;/code&amp;gt; || zoom, 0 (in) .. 1 (out) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_zoom&amp;quot;, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_zoom_speed&amp;quot;, value)&amp;lt;/code&amp;gt; || zoom speed, -1 (out) .. 1 (in) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_zoom_speed&amp;quot;, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_pan_tilt&amp;quot;, pan, tilt)&amp;lt;/code&amp;gt; || absolute pan/tilt, -1 .. 1 || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_pan_tilt&amp;quot;, -0.5, 0.2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_pan_tilt_speed&amp;quot;, pan_speed, tilt_speed)&amp;lt;/code&amp;gt; || pan/tilt speed, -1 (right/down) .. 1 (left/up) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_pan_tilt_speed&amp;quot;, -0.3, 0.8)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_store_preset&amp;quot;, n)&amp;lt;/code&amp;gt; || store position/focus/zoom into preset 0 .. 99 || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_store_preset&amp;quot;, 75)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_recall_preset&amp;quot;, n, speed)&amp;lt;/code&amp;gt; || recall preset 0 .. 99 at speed 0 .. 1 || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_recall_preset&amp;quot;, 4, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_auto_focus&amp;quot;)&amp;lt;/code&amp;gt; || toggle auto-focus || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_auto_focus&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_focus&amp;quot;, value)&amp;lt;/code&amp;gt; || absolute focus, 0 (infinity) .. 1 (closest) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_focus&amp;quot;, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_focus_speed&amp;quot;, value)&amp;lt;/code&amp;gt; || focus speed, -1 (out) .. 1 (in) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_focus_speed&amp;quot;, -0.2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_auto&amp;quot;)&amp;lt;/code&amp;gt; || auto white balance || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_auto&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_indoor&amp;quot;)&amp;lt;/code&amp;gt; || indoor white balance || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_indoor&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_outdoor&amp;quot;)&amp;lt;/code&amp;gt; || outdoor white balance || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_outdoor&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_oneshot&amp;quot;)&amp;lt;/code&amp;gt; || set white balance once from current brightness || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_oneshot&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_manual&amp;quot;, red, blue)&amp;lt;/code&amp;gt; || manual white balance, 0.0 .. 1.0 each || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_manual&amp;quot;, 0.1, 0.7)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_exposure_auto&amp;quot;)&amp;lt;/code&amp;gt; || auto exposure || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_exposure_auto&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_exposure_manual&amp;quot;, level)&amp;lt;/code&amp;gt; || manual exposure iris, 0.0 (dark) .. 1.0 (light) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_exposure_manual&amp;quot;, 0.4)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_exposure_manual_v2&amp;quot;, iris, gain, shutter)&amp;lt;/code&amp;gt; || manual exposure iris/gain/shutter, 0.0 .. 1.0 each || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_exposure_manual_v2&amp;quot;, 0.4, 0.2, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Grabber ( &amp;lt;code&amp;gt;mxw.grabber(name)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).isvalid()&amp;lt;/code&amp;gt; || true if the named keystone grabber exists || &amp;lt;code&amp;gt;if (mxw.grabber(&amp;quot;cam&amp;quot;).isvalid()) {}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).getGrabSizeX()&amp;lt;/code&amp;gt; || grabber width in px || &amp;lt;code&amp;gt;mxw.grabber(&amp;quot;cam&amp;quot;).getGrabSizeX()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).getGrabSizeY()&amp;lt;/code&amp;gt; || grabber height in px || &amp;lt;code&amp;gt;mxw.grabber(&amp;quot;cam&amp;quot;).getGrabSizeY()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).getData()&amp;lt;/code&amp;gt; || return the grabber&#039;s pixels (RGBA, width&amp;amp;times;height&amp;amp;times;4) || &amp;lt;code&amp;gt;var px = mxw.grabber(&amp;quot;cam&amp;quot;).getData()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== See also ===&lt;br /&gt;
&lt;br /&gt;
* [[JavaScript_Reference|JavaScript Reference]] &amp;amp;ndash; overview and getting started&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Python_plugin_reference&amp;diff=6160</id>
		<title>Python plugin reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Python_plugin_reference&amp;diff=6160"/>
		<updated>2026-08-08T15:28:30Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update links after removing &amp;#039;3.&amp;#039; prefix from reference titles (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- MXWendler wiki page: How to create a Python plugin (media and playlist) --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Intended location: https://wiki.mxwendler.net/index.php?title=Python_plugin_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_command_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_imgui_reference --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MXWendler StageDesigner can be extended with &#039;&#039;&#039;Python plugins&#039;&#039;&#039;. A plugin is a plain folder containing a manifest file and a Python module; MXWendler discovers it at startup, shows it in the user interface and calls a defined set of Python functions (&#039;&#039;hooks&#039;&#039;) at the right moments.&lt;br /&gt;
&lt;br /&gt;
Two plugin types exist:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Media plugins&#039;&#039;&#039; produce pixels: they appear as a media source that can be placed in a clip like any video file. Examples: a web browser media, a generative OpenGL cube.&lt;br /&gt;
* &#039;&#039;&#039;Playlist plugins&#039;&#039;&#039; are items in the playlist grid: they run logic when their cue plays. Examples: advance the playlist at a given time of day, write video files, ping a host.&lt;br /&gt;
&lt;br /&gt;
The embedded interpreter is &#039;&#039;&#039;Python 3.12&#039;&#039;&#039;. The general Python command interface (module &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt;) is documented in the [[Python command reference|Python command reference]].&lt;br /&gt;
&lt;br /&gt;
== Plugin anatomy ==&lt;br /&gt;
&lt;br /&gt;
A plugin is one folder with at least two files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
plugins/media/python/plugin_my_effect/&lt;br /&gt;
    mxw_plugin.ini      the manifest: identity, menu entries, addressing&lt;br /&gt;
    mxw_main.py         the Python module with the hook functions&lt;br /&gt;
    (more .py files)    optional: importable as &amp;quot;from plugin_my_effect.xyz import ...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The folder name is the Python package name: additional modules in the folder are imported with absolute imports, e.g. &amp;lt;code&amp;gt;from plugin_my_effect.helpers import foo&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Plugin locations ===&lt;br /&gt;
&lt;br /&gt;
Plugins are searched in several directories. &#039;&#039;&#039;User-controlled locations always override the bundled system location&#039;&#039;&#039;, so a user can replace a built-in plugin by placing a same-named folder in a higher-precedence directory — even without write access to the installation.&lt;br /&gt;
&lt;br /&gt;
Media plugins, descending precedence:&lt;br /&gt;
&lt;br /&gt;
# The open &amp;lt;code&amp;gt;.mxw&amp;lt;/code&amp;gt; project&#039;s &amp;lt;code&amp;gt;plugins/media/python/&amp;lt;/code&amp;gt; tree (opt-in via settings, highest precedence)&lt;br /&gt;
# Directories configured explicitly in the settings (Python tab)&lt;br /&gt;
# The per-user data directory, e.g. &amp;lt;code&amp;gt;%APPDATA%/MXWendler/plugins/media/python/&amp;lt;/code&amp;gt;&lt;br /&gt;
# The installation / resource directory: &amp;lt;code&amp;gt;plugins/media/python/&amp;lt;/code&amp;gt; (also &amp;lt;code&amp;gt;plugins/media/python_dev/&amp;lt;/code&amp;gt;, same precedence, for internal/unpublished plugins)&lt;br /&gt;
&lt;br /&gt;
Playlist plugins, descending precedence:&lt;br /&gt;
&lt;br /&gt;
# The open &amp;lt;code&amp;gt;.mxw&amp;lt;/code&amp;gt; project&#039;s &amp;lt;code&amp;gt;plugins/playlist/python/&amp;lt;/code&amp;gt; tree (opt-in via settings, highest precedence)&lt;br /&gt;
# Directories configured explicitly in the settings (Python tab)&lt;br /&gt;
# The per-user data directory: &amp;lt;code&amp;gt;.../plugins/playlist/python/&amp;lt;/code&amp;gt;&lt;br /&gt;
# The installation / resource directory: &amp;lt;code&amp;gt;plugins/playlist/python/&amp;lt;/code&amp;gt; (also &amp;lt;code&amp;gt;plugins/playlist/python_dev/&amp;lt;/code&amp;gt;, same precedence, for internal/unpublished plugins)&lt;br /&gt;
&lt;br /&gt;
=== The manifest: mxw_plugin.ini ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[mxw_plugin]                            ; must be here&lt;br /&gt;
plugin_version = 1                      ; must be V1&lt;br /&gt;
plugin_script_language = Python         ; must be Python&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Common keys:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Used by !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_menu_parent&amp;lt;/code&amp;gt; || both || Menu the plugin is listed under (e.g. &amp;lt;code&amp;gt;Media&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;IO&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_menu_name&amp;lt;/code&amp;gt; || both || Display name in the menu&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_grid_name&amp;lt;/code&amp;gt; || both || Short name shown in the grid / media list&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_tooltip&amp;lt;/code&amp;gt; || both || Tooltip text&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_menu_level&amp;lt;/code&amp;gt; (media) / &amp;lt;code&amp;gt;plugin_action_level&amp;lt;/code&amp;gt; (playlist) || both || &amp;lt;code&amp;gt;user&amp;lt;/code&amp;gt; (default, visible), &amp;lt;code&amp;gt;development&amp;lt;/code&amp;gt; (visible in debug builds only), &amp;lt;code&amp;gt;disabled&amp;lt;/code&amp;gt; (invisible)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Media-only keys:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_media_scheme&amp;lt;/code&amp;gt; || The URI scheme this plugin handles, e.g. &amp;lt;code&amp;gt;generative&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;web&amp;lt;/code&amp;gt;. Media is addressed as &amp;lt;code&amp;gt;&amp;amp;lt;scheme&amp;amp;gt;://&amp;amp;lt;payload&amp;amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_media_payload&amp;lt;/code&amp;gt; || Optional. If set, the plugin handles exactly &amp;lt;code&amp;gt;scheme://payload&amp;lt;/code&amp;gt;; if omitted, it handles every URI of its scheme. Several plugins can share one scheme and dispatch on the payload.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_media_create_uri&amp;lt;/code&amp;gt; || The URI used when the user creates this media from the menu / Create button.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_playlist_playbackmode_default&amp;lt;/code&amp;gt; || Optional. The clip playback mode a freshly added clip of this media starts in: &amp;lt;code&amp;gt;stop&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;loop&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;oneshot&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;bounce&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jitter&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;random&amp;lt;/code&amp;gt;. Omitted or unknown defaults to &amp;lt;code&amp;gt;loop&amp;lt;/code&amp;gt;. Only seeds the initial mode - a project reload restores the clip&#039;s own saved mode.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Playlist-only keys:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_grid_bg_color&amp;lt;/code&amp;gt; || Item background color as &amp;lt;code&amp;gt;r g b a&amp;lt;/code&amp;gt; floats, e.g. &amp;lt;code&amp;gt;0.05 0.05 0.45 1.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_accepts_trigger&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; (default &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;). When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, dragging a TRIGGER item onto this item&#039;s grid cell connects it (the drag shows a green &amp;quot;connect&amp;quot; outline) instead of moving/swapping cells, and the plugin can read the connection with &amp;lt;code&amp;gt;mxw.pending_trigger_drop(item_id)&amp;lt;/code&amp;gt;. Set it for a timeline; see [[#Connecting to a TRIGGER item]].&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_cell_scrub&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; (default &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;). When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, ALT + left-drag across this item&#039;s grid cell scrubs instead of moving the item: the host draws a playhead line and stashes the 0..1 fraction of the cell width each frame, readable with &amp;lt;code&amp;gt;mxw.pending_cell_scrub(item_id)&amp;lt;/code&amp;gt;. Set it for a timeline; see [[#Connecting to a TRIGGER item]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The plugin environment ==&lt;br /&gt;
&lt;br /&gt;
=== Per-instance state ===&lt;br /&gt;
&lt;br /&gt;
One Python module serves &#039;&#039;&#039;many simultaneous instances&#039;&#039;&#039; (several clips using the same media plugin, several copies of a playlist item). Before every hook call, the host sets module globals identifying the instance:&lt;br /&gt;
&lt;br /&gt;
* Media plugins: &amp;lt;code&amp;gt;media_id&amp;lt;/code&amp;gt; (integer)&lt;br /&gt;
* Playlist plugins: &amp;lt;code&amp;gt;item_id&amp;lt;/code&amp;gt; (integer) and &amp;lt;code&amp;gt;item_position&amp;lt;/code&amp;gt; (tuple &amp;lt;code&amp;gt;(x, y)&amp;lt;/code&amp;gt;, the grid position)&lt;br /&gt;
&lt;br /&gt;
The standard pattern is a module-level dictionary keyed by the id:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
storage = {}&lt;br /&gt;
&lt;br /&gt;
def onCreate():                    # playlist; media plugins use onOpen(uri)&lt;br /&gt;
    storage[item_id] = my_instance_state()&lt;br /&gt;
&lt;br /&gt;
def onDelete():&lt;br /&gt;
    storage.pop(item_id, None)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Host modules ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt; — the MXWendler command interface (playlist control, layers, clips, ...), see the [[Python command reference|Python command reference]].&lt;br /&gt;
* &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt; — Dear ImGui bindings for drawing settings panels inside MXWendler (used by &amp;lt;code&amp;gt;onRenderPanel()&amp;lt;/code&amp;gt;), documented in the [[Python imgui reference|Python ImGui Reference]].&lt;br /&gt;
&lt;br /&gt;
=== Installing own modules with mxw-pip ===&lt;br /&gt;
&lt;br /&gt;
Plugins may use third-party packages (&amp;lt;code&amp;gt;numpy&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;moderngl&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;opencv-python&amp;lt;/code&amp;gt;, ...). Packages are not installed into the installation folder — the &#039;&#039;&#039;mxw-pip&#039;&#039;&#039; helper (shipped next to the StageDesigner executable) installs them into the current user&#039;s writable folder, &#039;&#039;&#039;no administrator rights required&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%APPDATA%\Python\Python312\site-packages&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is exactly the directory StageDesigner prepends to &amp;lt;code&amp;gt;sys.path&amp;lt;/code&amp;gt; when the option &#039;&#039;&#039;Prepend user site-path&#039;&#039;&#039; is enabled (Settings → Python tab).&lt;br /&gt;
&lt;br /&gt;
mxw-pip runs &amp;lt;code&amp;gt;pip&amp;lt;/code&amp;gt; with the &#039;&#039;&#039;Python 3.12 shipped with StageDesigner&#039;&#039;&#039; (&amp;lt;code&amp;gt;python.exe&amp;lt;/code&amp;gt; in the installation folder / in its &amp;lt;code&amp;gt;python312/&amp;lt;/code&amp;gt; subfolder) — nothing else needs to be installed. Only when the shipped interpreter is missing does it fall back to a system Python (&amp;lt;code&amp;gt;py -3.12&amp;lt;/code&amp;gt;, then &amp;lt;code&amp;gt;python&amp;lt;/code&amp;gt; on &amp;lt;code&amp;gt;PATH&amp;lt;/code&amp;gt;), which must be 3.12 so binary wheels match the runtime ABI.&lt;br /&gt;
&lt;br /&gt;
Step by step:&lt;br /&gt;
&lt;br /&gt;
# Open &#039;&#039;&#039;Settings → Python&#039;&#039;&#039; and enable &#039;&#039;&#039;Prepend user site-path&#039;&#039;&#039;. The two installer buttons below are only active while this option is on, because mxw-pip installs into exactly that folder. Enabling applies immediately; disabling takes full effect after a restart.&lt;br /&gt;
# Click &#039;&#039;&#039;Launch CMD window with mxw-pip module installer..&#039;&#039;&#039; — this opens the installer shell (&amp;lt;code&amp;gt;mxw-pip-shell.bat&amp;lt;/code&amp;gt;). In the shell, type:&lt;br /&gt;
#: &amp;lt;pre&amp;gt;mxw-pip install &amp;lt;modulename&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
#: for example:&lt;br /&gt;
#: &amp;lt;pre&amp;gt;mxw-pip install moderngl&amp;lt;/pre&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Restart MXWendler StageDesigner&#039;&#039;&#039; so the new module is loaded.&lt;br /&gt;
&lt;br /&gt;
Other &amp;lt;code&amp;gt;pip&amp;lt;/code&amp;gt; subcommands are passed through unchanged, e.g. &amp;lt;code&amp;gt;mxw-pip list&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw-pip show moderngl&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw-pip uninstall moderngl&amp;lt;/code&amp;gt;. The button &#039;&#039;&#039;Open per-user module install folder..&#039;&#039;&#039; next to the installer button shows the target directory in the Explorer. Both &amp;lt;code&amp;gt;mxw-pip.bat&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;mxw-pip-shell.bat&amp;lt;/code&amp;gt; can also be run directly from the installation folder in any command prompt.&lt;br /&gt;
&lt;br /&gt;
Because the target folder lives in the user profile, every user keeps their own module set, and reinstalling / updating StageDesigner never touches the installed modules.&lt;br /&gt;
&lt;br /&gt;
=== Error handling ===&lt;br /&gt;
&lt;br /&gt;
Exceptions raised by a hook are reported to the interpreter console (IO dialog) — throttled, so a per-frame error does not flood the log. A &#039;&#039;&#039;per-frame hook that throws is blacklisted&#039;&#039;&#039;: it is not called again until the plugin is reloaded, so one broken callback cannot stall the render loop. Playlist plugins can be hot-reloaded from disk (state is snapshotted via &amp;lt;code&amp;gt;onSave()&amp;lt;/code&amp;gt;, the module source re-executed, then &amp;lt;code&amp;gt;onCreate()&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;onLoad()&amp;lt;/code&amp;gt; restore each instance), which also clears the blacklist.&lt;br /&gt;
&lt;br /&gt;
== Media plugins ==&lt;br /&gt;
&lt;br /&gt;
A media plugin is addressed by a URI: &amp;lt;code&amp;gt;&amp;amp;lt;scheme&amp;amp;gt;://&amp;amp;lt;payload&amp;amp;gt;&amp;lt;/code&amp;gt;, for example &amp;lt;code&amp;gt;generative://cube_spin_opengl&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;web://https://mxwendler.net&amp;lt;/code&amp;gt;. Every created media instance internally carries a unique instance token so two clips never share state; the plugin always sees the clean URI.&lt;br /&gt;
&lt;br /&gt;
=== Hooks ===&lt;br /&gt;
&lt;br /&gt;
All hooks are optional except &amp;lt;code&amp;gt;onOpen&amp;lt;/code&amp;gt; and &#039;&#039;&#039;one of the two render hooks&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Hook !! Direction !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onOpen(uri)&amp;lt;/code&amp;gt; || returns &amp;lt;code&amp;gt;(width, height, length, fps, has_alpha)&amp;lt;/code&amp;gt; || Called when the media is created / loaded. Create the per-instance state here. Do &#039;&#039;&#039;not&#039;&#039;&#039; touch OpenGL yet (see below).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onRenderFrame(frame)&amp;lt;/code&amp;gt; || returns a pixel buffer || Approach 1 and 2: return a &amp;lt;code&amp;gt;H*W*4&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;uint8&amp;lt;/code&amp;gt; buffer (bytes / bytearray / numpy), &#039;&#039;&#039;BGRA&#039;&#039;&#039; byte order, top-down. The host uploads it into the media texture.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onRenderFrameGL(frame, texture, width, height)&amp;lt;/code&amp;gt; || returns &amp;lt;code&amp;gt;bool&amp;lt;/code&amp;gt; || Approach 3: render &#039;&#039;&#039;directly into the media texture&#039;&#039;&#039; — &amp;lt;code&amp;gt;texture&amp;lt;/code&amp;gt; is its raw GL handle. Return &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; when the frame is in the texture; the pixel upload path is then skipped. Tried before &amp;lt;code&amp;gt;onRenderFrame&amp;lt;/code&amp;gt;; a plugin implements one of the two.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onClose()&amp;lt;/code&amp;gt; || — || The media is destroyed: release per-instance resources.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onRenderPanel()&amp;lt;/code&amp;gt; || — || Draw ImGui controls (via &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt;) in the clip panel, above the Video Info section.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSizeChange(w, h)&amp;lt;/code&amp;gt; || — || The host changed the render size: recreate size-dependent resources.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSpeedRange()&amp;lt;/code&amp;gt; || returns &amp;lt;code&amp;gt;(min, max)&amp;lt;/code&amp;gt; || Allowed clip playback speed range. Without it the media is locked to speed 1.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSetSpeed(speed)&amp;lt;/code&amp;gt; || — || The clip playback speed changed. Not clamped: 0 and negative values are allowed.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSave()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;onLoad(state)&amp;lt;/code&amp;gt; || string round-trip || Persist per-instance state in the project file.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onDisplayName()&amp;lt;/code&amp;gt; || returns string || Optional live display name (e.g. the web plugin reports the current page URL).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onGetParams()&amp;lt;/code&amp;gt; || returns a list of dicts || Declare addressable parameters, called once per instance and cached: &amp;lt;code&amp;gt;{&amp;quot;name&amp;quot;: str, &amp;quot;type&amp;quot;: &amp;quot;float&amp;quot;|&amp;quot;string&amp;quot;, &amp;quot;min&amp;quot;: float, &amp;quot;max&amp;quot;: float, &amp;quot;default&amp;quot;: float|str}&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;min&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;max&amp;lt;/code&amp;gt; ignored for &amp;lt;code&amp;gt;&amp;quot;string&amp;quot;&amp;lt;/code&amp;gt;; &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; defaults to &amp;lt;code&amp;gt;&amp;quot;float&amp;quot;&amp;lt;/code&amp;gt;).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onParamChanged(index, value)&amp;lt;/code&amp;gt; || — || A parameter was set via OSC, Python or JS at &amp;lt;code&amp;gt;.../clip/media/1/param/&amp;amp;lt;index+1&amp;amp;gt;&amp;lt;/code&amp;gt; (0-based &amp;lt;code&amp;gt;index&amp;lt;/code&amp;gt;). Store or apply it — the host never caches the value itself.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Parameters are addressed exactly like shader effect parameters, e.g. &amp;lt;code&amp;gt;/mxw/track/2/layer/1/clip/media/1/param/1 0.8&amp;lt;/code&amp;gt; or, for a &amp;lt;code&amp;gt;&amp;quot;string&amp;quot;&amp;lt;/code&amp;gt;-typed param, &amp;lt;code&amp;gt;/mxw/track/2/layer/1/clip/media/1/param/2 &amp;quot;https://www.mxwendler.net&amp;quot;&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;media/1&amp;lt;/code&amp;gt; segment reflects the clip&#039;s single active media slot (any other index is out of range). Because the host does not persist a param&#039;s value, a plugin that wants one to survive a project reload must fold it into its own &amp;lt;code&amp;gt;onSave()&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;onLoad()&amp;lt;/code&amp;gt; and hand the restored value back as &amp;lt;code&amp;gt;onGetParams()&amp;lt;/code&amp;gt;&#039;s &amp;lt;code&amp;gt;&amp;quot;default&amp;quot;&amp;lt;/code&amp;gt; — which runs after &amp;lt;code&amp;gt;onLoad()&amp;lt;/code&amp;gt; already restored the instance state.&lt;br /&gt;
&lt;br /&gt;
=== OpenGL rules for media plugins ===&lt;br /&gt;
&lt;br /&gt;
These rules apply to approaches 2 and 3:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Never create a standalone GL context&#039;&#039;&#039; (no windowed/standalone &amp;lt;code&amp;gt;moderngl.create_context()&amp;lt;/code&amp;gt; at import or in &amp;lt;code&amp;gt;onOpen&amp;lt;/code&amp;gt;). MXWendler makes its own context current every frame; GL objects created in a foreign context will be dereferenced against the wrong context and crash the driver.&lt;br /&gt;
* Instead, &#039;&#039;&#039;lazily attach on the first render call&#039;&#039;&#039;: &amp;lt;code&amp;gt;moderngl.create_context()&amp;lt;/code&amp;gt; inside &amp;lt;code&amp;gt;onRenderFrame / onRenderFrameGL&amp;lt;/code&amp;gt; attaches to MXWendler&#039;s context, which the host guarantees to be current there.&lt;br /&gt;
* The host &#039;&#039;&#039;snapshots and restores all relevant GL state&#039;&#039;&#039; around the render hooks (FBO bindings, program, VAO, buffers, viewport, enables, pixel store). The plugin does not need to unbind anything.&lt;br /&gt;
&lt;br /&gt;
=== Approach 1: rendering into pixels (CPU) ===&lt;br /&gt;
&lt;br /&gt;
The simplest approach: compute the frame on the CPU and return it. No OpenGL knowledge required. The host uploads the buffer into the media texture through a PBO (pixel buffer object) double-buffer, so the upload is asynchronous and cheap — the cost of this approach is the CPU rendering itself.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
W, H = 640, 360&lt;br /&gt;
storage = {}&lt;br /&gt;
&lt;br /&gt;
def onOpen(uri):&lt;br /&gt;
    storage[media_id] = {&amp;quot;phase&amp;quot;: 0.0}&lt;br /&gt;
    return (W, H, 1, 60.0, True)          # width, height, length, fps, has_alpha&lt;br /&gt;
&lt;br /&gt;
def onRenderFrame(frame):&lt;br /&gt;
    inst = storage[media_id]&lt;br /&gt;
    inst[&amp;quot;phase&amp;quot;] += 0.01&lt;br /&gt;
    # a moving horizontal gradient, BGRA byte order, top-down&lt;br /&gt;
    x = (np.linspace(0.0, 1.0, W) + inst[&amp;quot;phase&amp;quot;]) % 1.0&lt;br /&gt;
    row = np.zeros((W, 4), dtype=np.uint8)&lt;br /&gt;
    row[:, 0] = (x * 255).astype(np.uint8)     # B&lt;br /&gt;
    row[:, 2] = ((1 - x) * 255).astype(np.uint8)  # R&lt;br /&gt;
    row[:, 3] = 255                            # A&lt;br /&gt;
    return np.ascontiguousarray(np.tile(row, (H, 1, 1)))&lt;br /&gt;
&lt;br /&gt;
def onClose():&lt;br /&gt;
    storage.pop(media_id, None)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use this for: generated images, PIL/Pillow output, OpenCV results, slow-changing content.&lt;br /&gt;
&lt;br /&gt;
=== Approach 2: rendering into an FBO and streaming ===&lt;br /&gt;
&lt;br /&gt;
Render with OpenGL (e.g. via &#039;&#039;&#039;ModernGL&#039;&#039;&#039;, installed once with &amp;lt;code&amp;gt;mxw-pip install moderngl numpy&amp;lt;/code&amp;gt;) into an offscreen framebuffer, read the pixels back and return them like in approach 1. The scene renders on the GPU, but every frame makes a round trip GPU → CPU (&amp;lt;code&amp;gt;fbo.read()&amp;lt;/code&amp;gt;) → GPU (PBO upload).&lt;br /&gt;
&lt;br /&gt;
Bundled reference: &amp;lt;code&amp;gt;plugins/media/python/plugin_opengl_cube&amp;lt;/code&amp;gt; ([https://github.com/mxwendler/mxw-plugin-opengl-cube github]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import moderngl&lt;br /&gt;
&lt;br /&gt;
storage = {}&lt;br /&gt;
&lt;br /&gt;
class inst_t:&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self.ctx = None&lt;br /&gt;
        self.fbo = None&lt;br /&gt;
&lt;br /&gt;
def onOpen(uri):&lt;br /&gt;
    storage[media_id] = inst_t()&lt;br /&gt;
    return (1024, 1024, 1, 60.0, True)&lt;br /&gt;
&lt;br /&gt;
def onRenderFrame(frame):&lt;br /&gt;
    inst = storage[media_id]&lt;br /&gt;
    if inst.ctx is None:&lt;br /&gt;
        # first frame: attach to MXWendler&#039;s context (never earlier!)&lt;br /&gt;
        inst.ctx = moderngl.create_context()&lt;br /&gt;
        color = inst.ctx.texture((1024, 1024), 4)&lt;br /&gt;
        depth = inst.ctx.depth_renderbuffer((1024, 1024))&lt;br /&gt;
        inst.fbo = inst.ctx.framebuffer([color], depth)&lt;br /&gt;
        # ... build program / vao here ...&lt;br /&gt;
&lt;br /&gt;
    inst.fbo.use()&lt;br /&gt;
    inst.ctx.clear(0.0, 0.0, 0.0, 0.0, depth=1.0)&lt;br /&gt;
    # ... draw the scene ...&lt;br /&gt;
&lt;br /&gt;
    # read back: GL is bottom-up RGBA, the host wants top-down BGRA&lt;br /&gt;
    raw = inst.fbo.read(components=4, alignment=1)&lt;br /&gt;
    img = np.frombuffer(raw, dtype=np.uint8).reshape((1024, 1024, 4))&lt;br /&gt;
    img = np.flipud(img)&lt;br /&gt;
    return np.ascontiguousarray(img[:, :, [2, 1, 0, 3]])&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use this for: GPU-rendered content when you also need the pixels on the CPU (analysis, recording), or as a stepping stone to approach 3.&lt;br /&gt;
&lt;br /&gt;
=== Approach 3: rendering into a bound texture target (direct) ===&lt;br /&gt;
&lt;br /&gt;
The fastest path: the host passes the &#039;&#039;&#039;raw GL handle of the media texture&#039;&#039;&#039; to &amp;lt;code&amp;gt;onRenderFrameGL&amp;lt;/code&amp;gt;. The plugin attaches it to its own framebuffer and renders straight into it. &#039;&#039;&#039;No readback, no upload, no texture streaming&#039;&#039;&#039; — the frame never leaves the GPU.&lt;br /&gt;
&lt;br /&gt;
Bundled reference: &amp;lt;code&amp;gt;plugins/media/python/plugin_opengl_cube_direct&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import moderngl&lt;br /&gt;
&lt;br /&gt;
storage = {}&lt;br /&gt;
&lt;br /&gt;
class inst_t:&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self.ctx = None&lt;br /&gt;
        self.fbo = None&lt;br /&gt;
        self.depth = None&lt;br /&gt;
        self.fbo_key = None       # (texture, w, h) the fbo was built for&lt;br /&gt;
&lt;br /&gt;
def onOpen(uri):&lt;br /&gt;
    storage[media_id] = inst_t()&lt;br /&gt;
    return (1024, 1024, 1, 60.0, True)&lt;br /&gt;
&lt;br /&gt;
def onRenderFrameGL(frame, texture, width, height):&lt;br /&gt;
    inst = storage[media_id]&lt;br /&gt;
    if inst.ctx is None:&lt;br /&gt;
        inst.ctx = moderngl.create_context()   # attach to MXWendler&#039;s context&lt;br /&gt;
        # ... build program / vao here ...&lt;br /&gt;
&lt;br /&gt;
    # (re)wrap the host texture when the handle or size changed: the host&lt;br /&gt;
    # recreates the media texture on a render size change&lt;br /&gt;
    if inst.fbo_key != (texture, width, height):&lt;br /&gt;
        if inst.fbo:&lt;br /&gt;
            inst.fbo.release()&lt;br /&gt;
        if inst.depth:&lt;br /&gt;
            inst.depth.release()&lt;br /&gt;
        color = inst.ctx.external_texture(texture, (width, height), 4, 0, &amp;quot;f1&amp;quot;)&lt;br /&gt;
        inst.depth = inst.ctx.depth_renderbuffer((width, height))&lt;br /&gt;
        inst.fbo = inst.ctx.framebuffer([color], inst.depth)&lt;br /&gt;
        inst.fbo_key = (texture, width, height)&lt;br /&gt;
&lt;br /&gt;
    inst.fbo.use()&lt;br /&gt;
    inst.ctx.clear(0.0, 0.0, 0.0, 0.0, depth=1.0)&lt;br /&gt;
    # ... draw the scene; flip Y in the projection, see below ...&lt;br /&gt;
&lt;br /&gt;
    return True    # the frame is in the texture: host skips the upload path&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rules specific to the direct approach:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Never &amp;lt;code&amp;gt;release()&amp;lt;/code&amp;gt; the external texture wrapper&#039;&#039;&#039; — the GL texture belongs to MXWendler. Only release your own framebuffer and depth renderbuffer.&lt;br /&gt;
* &#039;&#039;&#039;Rebuild the framebuffer when &amp;lt;code&amp;gt;(texture, width, height)&amp;lt;/code&amp;gt; changes.&#039;&#039;&#039; The handle is not stable: a render size change makes the host recreate the media texture.&lt;br /&gt;
* &#039;&#039;&#039;Flip Y.&#039;&#039;&#039; MXWendler media textures are top-down (row 0 = top of the image), a GL render is bottom-up. Negate the Y row of your projection matrix (approaches 1/2 flip on the CPU instead, e.g. with &amp;lt;code&amp;gt;numpy.flipud&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Choosing an approach ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! !! 1: Pixels (CPU) !! 2: FBO + streaming !! 3: Direct texture&lt;br /&gt;
|-&lt;br /&gt;
| Scene renders on || CPU || GPU || GPU&lt;br /&gt;
|-&lt;br /&gt;
| Per-frame copies || CPU → GPU upload || GPU → CPU readback + CPU → GPU upload || none&lt;br /&gt;
|-&lt;br /&gt;
| OpenGL required || no || yes || yes&lt;br /&gt;
|-&lt;br /&gt;
| CPU access to the pixels || yes (you made them) || yes (after readback) || no&lt;br /&gt;
|-&lt;br /&gt;
| Typical use || generated images, PIL, OpenCV || GPU render that also needs CPU pixels || pure GPU generative content, best performance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Playlist plugins ==&lt;br /&gt;
&lt;br /&gt;
A playlist plugin is an item placed in the playlist grid. It participates in the cue lifecycle: it can run logic when its cue is played, every frame while its cue is active, or every frame globally. Playlist control functions (&amp;lt;code&amp;gt;mxw.playlist.play()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.playlist.navigate_index()&amp;lt;/code&amp;gt;, ...) are documented in the [[Python command reference|Python command reference]].&lt;br /&gt;
&lt;br /&gt;
=== Hooks ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Hook !! Required !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onCreate()&amp;lt;/code&amp;gt; || yes || A new instance was placed in the grid (also called after hot-reload): create the per-instance state entry.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onDelete()&amp;lt;/code&amp;gt; || yes || The instance was deleted: release the state entry.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onAction()&amp;lt;/code&amp;gt; || yes || The item&#039;s cue was played (the item &#039;&#039;fires&#039;&#039;).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onPostAction()&amp;lt;/code&amp;gt; || no || Called after the action completed.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSave()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;onLoad(state)&amp;lt;/code&amp;gt; || yes || Serialize / restore per-instance state (string). Called on project save/load and around hot-reload.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onRenderPanel()&amp;lt;/code&amp;gt; || yes || Draw the item&#039;s settings panel with &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getText()&amp;lt;/code&amp;gt; || yes || Detail text appended to the item&#039;s grid label.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onNewFrameAlways()&amp;lt;/code&amp;gt; || no || Called every rendered frame, regardless of cue state.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onNewFrameInPlayoutCue()&amp;lt;/code&amp;gt; || no || Called every rendered frame while the item&#039;s cue is the active playout cue.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onPause(is_paused)&amp;lt;/code&amp;gt; || no || Pause was pressed / released.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onPreparePlayback()&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;onCleanup()&amp;lt;/code&amp;gt; || no || Prepare / release playout resources.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onActivateInUI()&amp;lt;/code&amp;gt; || no || The item was selected in the user interface.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onActiveCueChange(direction)&amp;lt;/code&amp;gt; || no || The active cue changed past this item (navigation).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;onSettingsChanged()&amp;lt;/code&amp;gt; || no || Item settings were changed from outside.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getDuration()&amp;lt;/code&amp;gt; || no || Report the item&#039;s action duration in milliseconds.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getTimeSinceOnActionIssued()&amp;lt;/code&amp;gt; || no || Report elapsed action time in milliseconds (drives the progress display).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getColorBG()&amp;lt;/code&amp;gt; || no || Return a &amp;lt;code&amp;gt;mxw_imgui.Vec4&amp;lt;/code&amp;gt; (rgb 0..255) to set the grid cell background color dynamically.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;renderBlinking()&amp;lt;/code&amp;gt; || no || Return &amp;lt;code&amp;gt;True&amp;lt;/code&amp;gt; to make the grid cell blink.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getProgress()&amp;lt;/code&amp;gt; || no || Return &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt; to fill the cell&#039;s bottom progress bar (the same bar the built-in advance/fade items draw); &amp;lt;code&amp;gt;&amp;amp;lt;= 0&amp;lt;/code&amp;gt; draws nothing.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Connecting to a TRIGGER item ===&lt;br /&gt;
&lt;br /&gt;
A playlist plugin (e.g. a keyframe timeline) can bind to a TRIGGER item and animate its layer/clip controls. The user drops a trigger either onto the plugin&#039;s settings panel or onto its grid cell; the plugin resolves the connection to the trigger&#039;s grid &amp;lt;code&amp;gt;(col, row)&amp;lt;/code&amp;gt; and enumerates its controls from there. No need to play the trigger first — the controls are read from the connected preload&#039;s fixture layer, and the very same &amp;lt;code&amp;gt;(col,row)&amp;lt;/code&amp;gt; address resolves the &#039;&#039;live&#039;&#039; layer during playout.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Function !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw_imgui.accept_trigger_drop()&amp;lt;/code&amp;gt; || Makes the current panel window a drop target for a trigger; returns the dropped trigger&#039;s 1-based &amp;lt;code&amp;gt;(col, row)&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;(-1, -1)&amp;lt;/code&amp;gt;. Handles the &amp;quot;drop onto the panel&amp;quot; route.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw.pending_trigger_drop(item_id)&amp;lt;/code&amp;gt; || Returns a &amp;lt;code&amp;gt;(col, row)&amp;lt;/code&amp;gt; stashed by the host when a trigger was dropped onto &#039;&#039;this&#039;&#039; plugin item&#039;s grid cell (pass your own &amp;lt;code&amp;gt;item_id&amp;lt;/code&amp;gt;), or &amp;lt;code&amp;gt;(-1, -1)&amp;lt;/code&amp;gt;. Handles the &amp;quot;drop onto the grid cell&amp;quot; route.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw.trigger_controls(col, row)&amp;lt;/code&amp;gt; || Returns the trigger&#039;s animatable (slider) controls as &amp;lt;code&amp;gt;(label, address)&amp;lt;/code&amp;gt; pairs — layer, clip, effect and media params. Re-read it every frame: controls the user swaps on the clip appear/vanish live. Each &amp;lt;code&amp;gt;address&amp;lt;/code&amp;gt; is usable with &amp;lt;code&amp;gt;mxw.widget(address).setValue()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mxw.pending_cell_scrub(item_id)&amp;lt;/code&amp;gt; || Returns the 0..1 fraction of an ALT + left-drag across &#039;&#039;this&#039;&#039; plugin item&#039;s grid cell (stashed by the host each frame while dragging, consumed on read), or &amp;lt;code&amp;gt;-1.0&amp;lt;/code&amp;gt;. Needs the &amp;lt;code&amp;gt;plugin_cell_scrub&amp;lt;/code&amp;gt; manifest opt-in. Poll it in &amp;lt;code&amp;gt;onNewFrameAlways()&amp;lt;/code&amp;gt; so scrubbing also works while the panel is closed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Poll both drop routes at the top of &amp;lt;code&amp;gt;onRenderPanel()&amp;lt;/code&amp;gt; and store the resulting &amp;lt;code&amp;gt;(col,row)&amp;lt;/code&amp;gt;; then call &amp;lt;code&amp;gt;mxw.trigger_controls()&amp;lt;/code&amp;gt; to (re)build your control list each frame.&lt;br /&gt;
&lt;br /&gt;
A time connection between the connected clip and the plugin follows from these pieces: the clip&#039;s &amp;lt;code&amp;gt;.../clip/Position&amp;lt;/code&amp;gt; control (normalized 0..1) is the clip&#039;s own time axis. Write it when your playhead moves (scrub → seek) and read it every frame to follow the clip when it is scrubbed — or simply playing. See the timeline plugin&#039;s &amp;lt;code&amp;gt;sync_time_link()&amp;lt;/code&amp;gt; for a worked example including the echo filtering (a written Position reads back frame-quantized).&lt;br /&gt;
&lt;br /&gt;
=== Minimal example ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import pickle, codecs&lt;br /&gt;
import mxw&lt;br /&gt;
import mxw_imgui&lt;br /&gt;
&lt;br /&gt;
class state_t:&lt;br /&gt;
    fire_count = 0&lt;br /&gt;
&lt;br /&gt;
storage = {}&lt;br /&gt;
&lt;br /&gt;
def onCreate():&lt;br /&gt;
    storage[item_id] = state_t()&lt;br /&gt;
&lt;br /&gt;
def onDelete():&lt;br /&gt;
    storage.pop(item_id, None)&lt;br /&gt;
&lt;br /&gt;
def onAction():&lt;br /&gt;
    # the item&#039;s cue was played&lt;br /&gt;
    storage[item_id].fire_count += 1&lt;br /&gt;
&lt;br /&gt;
def getText():&lt;br /&gt;
    return &amp;quot; : fired %d times&amp;quot; % storage[item_id].fire_count&lt;br /&gt;
&lt;br /&gt;
def onRenderPanel():&lt;br /&gt;
    inst = storage[item_id]&lt;br /&gt;
    mxw_imgui.text_unformatted(&amp;quot;Fired %d times&amp;quot; % inst.fire_count)&lt;br /&gt;
    if mxw_imgui.button(&amp;quot;Reset&amp;quot;):&lt;br /&gt;
        inst.fire_count = 0&lt;br /&gt;
&lt;br /&gt;
def onSave():&lt;br /&gt;
    return codecs.encode(pickle.dumps(storage[item_id]), &amp;quot;base64&amp;quot;).decode()&lt;br /&gt;
&lt;br /&gt;
def onLoad(serialized):&lt;br /&gt;
    storage[item_id] = pickle.loads(codecs.decode(serialized.encode(), &amp;quot;base64&amp;quot;))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With a manifest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[mxw_plugin]&lt;br /&gt;
plugin_version = 1&lt;br /&gt;
plugin_script_language = Python&lt;br /&gt;
plugin_menu_parent = IO&lt;br /&gt;
plugin_menu_name = Fire Counter&lt;br /&gt;
plugin_grid_name = Counter&lt;br /&gt;
plugin_tooltip = Counts how often its cue was played&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bundled references, all in the [https://github.com/mxwendler/mxw-plugins-playlist mxw-plugins-playlist] repository: &amp;lt;code&amp;gt;plugins/playlist/python/plugin_advance_datetime&amp;lt;/code&amp;gt; (timed playlist navigation, rich settings panel), &amp;lt;code&amp;gt;plugin_video_writer&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;plugin_comment&amp;lt;/code&amp;gt; (a minimal example: a no-op annotation item).&lt;br /&gt;
&lt;br /&gt;
== Example plugins on GitHub ==&lt;br /&gt;
&lt;br /&gt;
The bundled example plugins are maintained as public repositories under [https://github.com/mxwendler github.com/mxwendler], grouped by type — good starting points to fork for an own plugin:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Plugin !! Type !! Approach / purpose !! Repository&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_opengl_cube&amp;lt;/code&amp;gt; || media || Approach 2: ModernGL cube into an offscreen FBO, streamed || [https://github.com/mxwendler/mxw-plugins-media mxw-plugins-media]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_opengl_cube_direct&amp;lt;/code&amp;gt; || media || Approach 3: same cube rendered directly into the media texture || [https://github.com/mxwendler/mxw-plugins-media mxw-plugins-media]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_web_media&amp;lt;/code&amp;gt; || media || A web browser as media source (whole-scheme &amp;lt;code&amp;gt;web://&amp;lt;/code&amp;gt; plugin) || [https://github.com/mxwendler/mxw-plugins-media mxw-plugins-media]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_fragcoord&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;plugin_shadertoy&amp;lt;/code&amp;gt; || media || Shader-as-generative-media (FragCoord.xyz / Shadertoy) || [https://github.com/mxwendler/mxw-plugins-media mxw-plugins-media]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_advance_datetime&amp;lt;/code&amp;gt; || playlist || Timed playlist navigation with a rich settings panel || [https://github.com/mxwendler/mxw-plugins-playlist mxw-plugins-playlist]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_video_writer&amp;lt;/code&amp;gt; || playlist || Write video files from the playlist || [https://github.com/mxwendler/mxw-plugins-playlist mxw-plugins-playlist]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;plugin_comment&amp;lt;/code&amp;gt; || playlist || Minimal example: a no-op text annotation item || [https://github.com/mxwendler/mxw-plugins-playlist mxw-plugins-playlist]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Developing a new plugin inside a project ===&lt;br /&gt;
&lt;br /&gt;
The most convenient place to develop a plugin is &#039;&#039;&#039;inside a project folder&#039;&#039;&#039;: the plugin travels with the show, needs no write access to the installation, and overrides a same-named bundled plugin. Conceptually:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Create a project folder&#039;&#039;&#039; — a plain directory that will hold everything belonging to the show, e.g. &amp;lt;code&amp;gt;D:/shows/particles/&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;Save the project file there&#039;&#039;&#039; — &#039;&#039;File → Save As..&#039;&#039; into that folder, e.g. &amp;lt;code&amp;gt;D:/shows/particles/particles.mxw&amp;lt;/code&amp;gt;. The folder containing the &amp;lt;code&amp;gt;.mxw&amp;lt;/code&amp;gt; file &#039;&#039;is&#039;&#039; the project folder; loading the project later makes MXWendler pick up its plugins again.&lt;br /&gt;
# &#039;&#039;&#039;Create the plugin directory there&#039;&#039;&#039; — the project mirrors the installation layout: &amp;lt;code&amp;gt;D:/shows/particles/plugins/media/python/&amp;amp;lt;plugin_folder&amp;amp;gt;/&amp;lt;/code&amp;gt; for media plugins (&amp;lt;code&amp;gt;plugins/playlist/python/...&amp;lt;/code&amp;gt; for playlist plugins). Enable &#039;&#039;Settings → Python → Check for plugins inside the project folder&#039;&#039; — project plugins have the highest precedence of all plugin locations.&lt;br /&gt;
&lt;br /&gt;
=== Letting Claude Code write the plugin ===&lt;br /&gt;
&lt;br /&gt;
An AI coding agent like [https://claude.com/claude-code Claude Code] can write a complete plugin from the contract described on this page. Start it &#039;&#039;&#039;in the project folder&#039;&#039;&#039;, so it creates the plugin directly where MXWendler looks for it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd D:/shows/particles&lt;br /&gt;
claude&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Give it the reference material and a precise task — for a generative OpenGL particle system for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Create an MXWendler media plugin under plugins/media/python/plugin_particle_system/&lt;br /&gt;
(folder + mxw_plugin.ini + mxw_main.py).&lt;br /&gt;
&lt;br /&gt;
Reference: the bundled example in &amp;lt;MXWendler install dir&amp;gt;/plugins/media/python/&lt;br /&gt;
plugin_opengl_cube_direct/ - follow its structure and hook usage exactly, and the&lt;br /&gt;
plugin howto at https://wiki.mxwendler.net/index.php?title=Python_plugin_reference.&lt;br /&gt;
&lt;br /&gt;
The plugin is a generative OpenGL particle system, addressed as&lt;br /&gt;
generative://particle_system, rendered with ModernGL directly into the media&lt;br /&gt;
texture via onRenderFrameGL (no readback, no onRenderFrame). Keep per-instance&lt;br /&gt;
state keyed by media_id. Emit particles from the center, integrate velocity and&lt;br /&gt;
gravity per frame scaled by the clip playback speed (onSetSpeed, onSpeedRange&lt;br /&gt;
-5..5). Expose particle count, gravity and start size as sliders in&lt;br /&gt;
onRenderPanel (mxw_imgui) and persist them via onSave/onLoad. Respect the GL&lt;br /&gt;
rules: attach with moderngl.create_context() lazily on the first render call,&lt;br /&gt;
never release the external texture, rebuild the fbo when (texture, w, h)&lt;br /&gt;
changes, flip Y in the projection.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then iterate: create the media in a clip (it appears under its &amp;lt;code&amp;gt;plugin_menu_name&amp;lt;/code&amp;gt;, or address &amp;lt;code&amp;gt;generative://particle_system&amp;lt;/code&amp;gt; directly) and refine with follow-up prompts (&amp;quot;make the particles fade out&amp;quot;, &amp;quot;add a color gradient slider&amp;quot;, ...). Errors show up in the interpreter console. For playlist plugins, &#039;&#039;Settings → Python → Reload Python Plugins&#039;&#039; hot-reloads the edited source; for media plugins, recreate the media (or restart) to re-import the module.&lt;br /&gt;
&lt;br /&gt;
== Persistence ==&lt;br /&gt;
&lt;br /&gt;
Both plugin types persist per-instance state through the &amp;lt;code&amp;gt;onSave() → string&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;onLoad(string)&amp;lt;/code&amp;gt; pair. The string is stored inside the project file; anything goes, a common choice is base64-encoded pickle (see the playlist example above). Media plugins additionally have their render size stored and restored by the host automatically.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Nothing appears in the menu&#039;&#039;&#039; — check the manifest: &amp;lt;code&amp;gt;plugin_version = 1&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;plugin_script_language = Python&amp;lt;/code&amp;gt;, a non-empty &amp;lt;code&amp;gt;plugin_menu_name&amp;lt;/code&amp;gt;, and the level key (&amp;lt;code&amp;gt;development&amp;lt;/code&amp;gt; plugins only show in debug builds).&lt;br /&gt;
* &#039;&#039;&#039;Errors&#039;&#039;&#039; — open the interpreter console (IO dialog): hook exceptions are reported there (throttled). Remember that a throwing per-frame hook is blacklisted until reload.&lt;br /&gt;
* &#039;&#039;&#039;Media shows black&#039;&#039;&#039; — &amp;lt;code&amp;gt;onRenderFrame&amp;lt;/code&amp;gt; returned a buffer of the wrong size (must be &amp;lt;code&amp;gt;width*height*4&amp;lt;/code&amp;gt; bytes), or a GL plugin created its own context instead of attaching to MXWendler&#039;s (see the OpenGL rules).&lt;br /&gt;
* &#039;&#039;&#039;Missing packages&#039;&#039;&#039; — install them with mxw-pip (see [[#Installing own modules with mxw-pip|Installing own modules with mxw-pip]]) and make sure &#039;&#039;&#039;Prepend user site-path&#039;&#039;&#039; is enabled: the embedded interpreter does not see a system-wide Python installation&#039;s packages.&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Python_command_reference&amp;diff=6159</id>
		<title>Python command reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Python_command_reference&amp;diff=6159"/>
		<updated>2026-08-08T15:28:28Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update links after removing &amp;#039;3.&amp;#039; prefix from reference titles (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- MXWendler wiki page: Python command reference (module mxw) --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Intended location: https://wiki.mxwendler.net/index.php?title=Python_command_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_imgui_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_plugin_reference --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This page lists the commands of the Python module &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt;, MXWendler&#039;s general Python command interface. It is available from the script console and from Python plugins (see the [[Python plugin reference|Python Plugin Howto]]). For drawing plugin panels see the [[Python imgui reference|Python ImGui Reference]].&lt;br /&gt;
&lt;br /&gt;
The embedded interpreter is &#039;&#039;&#039;Python 3.12&#039;&#039;&#039;. Import is implicit in the script console; in a plugin module use &amp;lt;code&amp;gt;import mxw&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The presented Python commands supported in version 7.2. and up&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Legend ===&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;FLOATS&#039;&#039; are written with one decimal: &amp;lt;code&amp;gt;0.0 .. 1.0&amp;lt;/code&amp;gt; &amp;amp;rarr; every float between 0 and 1 inclusive.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;INTEGERS&#039;&#039; are written as plain numbers or ranges: &amp;lt;code&amp;gt;1 .. 5&amp;lt;/code&amp;gt; &amp;amp;rarr; the integers 1,2,3,4,5.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;STRINGS&#039;&#039; are written between double quotes.&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;u&amp;gt;OR&amp;lt;/u&amp;gt; appears, two alternative call formats produce a similar result; use one at a time.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Addressing:&#039;&#039;&#039; widgets are targeted by their OSC-style address string, e.g. &amp;lt;code&amp;gt;/mxw/track/active/layer/active/clip&amp;lt;/code&amp;gt;. The same addresses used over OSC work here.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Access model (7.2):&#039;&#039;&#039; widget values are read/written through &amp;lt;code&amp;gt;mxw.widget(address)&amp;lt;/code&amp;gt;; global functions live in the submodules/factories &amp;lt;code&amp;gt;mxw.playlist&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.io&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.preload(n)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.media(name)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mxw.grabber(name)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Reference ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PYTHON COMMAND/SYMBOL !! DESCRIPTION !! EXAMPLE&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Software Info&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.millis&amp;lt;/code&amp;gt; || milliseconds passed since the software was opened || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;passed time is &amp;quot; + str(mxw.millis))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.width&amp;lt;/code&amp;gt; || current frame width in px || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;frame width is &amp;quot; + str(mxw.width))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.height&amp;lt;/code&amp;gt; || current frame height in px || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;frame height is &amp;quot; + str(mxw.height))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.outwidth&amp;lt;/code&amp;gt; || current output width in px || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;output width is &amp;quot; + str(mxw.outwidth))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.outheight&amp;lt;/code&amp;gt; || current output height in px || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;output height is &amp;quot; + str(mxw.outheight))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.framecounter&amp;lt;/code&amp;gt; || number of frames rendered since the software was opened || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;frames rendered: &amp;quot; + str(mxw.framecounter))&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.print_console(&amp;quot;text&amp;quot;)&amp;lt;/code&amp;gt; || print a line to the script console || &amp;lt;code&amp;gt;mxw.print_console(&amp;quot;hello&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.print_statusline(&amp;quot;text&amp;quot;)&amp;lt;/code&amp;gt; || print text on the application status line || &amp;lt;code&amp;gt;mxw.print_statusline(&amp;quot;running&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.makescreenshot(&amp;quot;path&amp;quot;)&amp;lt;/code&amp;gt; || save a full-frame screenshot as PNG (empty path &amp;amp;rarr; Desktop) || &amp;lt;code&amp;gt;mxw.makescreenshot(&amp;quot;c:/Users/me/Desktop/shot.png&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.makesectionscreenshot(&amp;quot;path&amp;quot;, x, y, w, h)&amp;lt;/code&amp;gt; || save a cropped screenshot of the region (x, y, w, h) || &amp;lt;code&amp;gt;mxw.makesectionscreenshot(&amp;quot;c:/Users/me/Desktop/crop.png&amp;quot;, 0, 0, 400, 200)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.describe()&amp;lt;/code&amp;gt; || return a text listing of every operation known to the unified interface registry (auto-docs / discovery) || &amp;lt;code&amp;gt;mxw.print_console(mxw.describe())&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; | I/O ( &amp;lt;code&amp;gt;mxw.io&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.dmx(channel)&amp;lt;/code&amp;gt; || return the DMX value received on the given channel || &amp;lt;code&amp;gt;v = mxw.io.dmx(4)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.midi(device, channel)&amp;lt;/code&amp;gt; || return the MIDI value received from device/channel || &amp;lt;code&amp;gt;v = mxw.io.midi(1, 6)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.keyboard(state, key)&amp;lt;/code&amp;gt; || return whether the given key (ASCII) is in the given state || &amp;lt;code&amp;gt;if mxw.io.keyboard(0, 65): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.send_dmx(channel, value)&amp;lt;/code&amp;gt; || send a DMX value on a channel || &amp;lt;code&amp;gt;mxw.io.send_dmx(4, 255)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.send_midi(device, channel, value)&amp;lt;/code&amp;gt; || send a MIDI value to device/channel || &amp;lt;code&amp;gt;mxw.io.send_midi(1, 6, 100)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.pjlink(&amp;quot;command&amp;quot;, &amp;quot;ip&amp;quot;, &amp;quot;pw&amp;quot;)&amp;lt;/code&amp;gt; || PJLink projector control. Commands: &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;off&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;avmute_on&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;avmute_off&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vmute_on&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vmute_off&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;mxw.io.pjlink(&amp;quot;on&amp;quot;, &amp;quot;192.168.1.2&amp;quot;, &amp;quot;panasonic&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.io.send_osc(&amp;quot;host&amp;quot;, port, &amp;quot;address&amp;quot;, &amp;quot;tags&amp;quot;, *args)&amp;lt;/code&amp;gt; || send an OSC message. &amp;lt;code&amp;gt;tags&amp;lt;/code&amp;gt; is one char per argument: &amp;lt;code&amp;gt;d&amp;lt;/code&amp;gt; float, &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; int, &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt; string, &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt; blob (list of 0..255) || &amp;lt;code&amp;gt;mxw.io.send_osc(&amp;quot;127.0.0.1&amp;quot;, 7000, &amp;quot;/cue&amp;quot;, &amp;quot;ci&amp;quot;, &amp;quot;go&amp;quot;, 5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Playlist ( &amp;lt;code&amp;gt;mxw.playlist&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.preload_media()&amp;lt;/code&amp;gt; || preload the media used by the playlist || &amp;lt;code&amp;gt;mxw.playlist.preload_media()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.play()&amp;lt;/code&amp;gt; || play the playlist || &amp;lt;code&amp;gt;mxw.playlist.play()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.pause()&amp;lt;/code&amp;gt; || pause, or restart if already paused || &amp;lt;code&amp;gt;mxw.playlist.pause()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_pause(True/False)&amp;lt;/code&amp;gt; || halt (True) or resume (False) playback || &amp;lt;code&amp;gt;mxw.playlist.go_pause(True)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.skiptonext()&amp;lt;/code&amp;gt; || skip to the next cue || &amp;lt;code&amp;gt;mxw.playlist.skiptonext()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_next()&amp;lt;/code&amp;gt; || go to the next cue without playing || &amp;lt;code&amp;gt;mxw.playlist.go_next()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_prev()&amp;lt;/code&amp;gt; || go to the previous cue || &amp;lt;code&amp;gt;mxw.playlist.go_prev()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.go_first()&amp;lt;/code&amp;gt; || go to the first cue || &amp;lt;code&amp;gt;mxw.playlist.go_first()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.navigate_index(index)&amp;lt;/code&amp;gt; || go to the cue with the given index || &amp;lt;code&amp;gt;mxw.playlist.navigate_index(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.navigate_string(&amp;quot;name&amp;quot;)&amp;lt;/code&amp;gt; || go to the cue matching the given name || &amp;lt;code&amp;gt;mxw.playlist.navigate_string(&amp;quot;BG_video2&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.get_active_cue()&amp;lt;/code&amp;gt; || return the active cue index (int) || &amp;lt;code&amp;gt;i = mxw.playlist.get_active_cue()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.get_cue_count()&amp;lt;/code&amp;gt; || return the number of cues (int) || &amp;lt;code&amp;gt;n = mxw.playlist.get_cue_count()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.get_cue_names()&amp;lt;/code&amp;gt; || return the list of cue names (index matches &amp;lt;code&amp;gt;navigate_index&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;for name in mxw.playlist.get_cue_names(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.playlist.is_rehearsal()&amp;lt;/code&amp;gt; || return True if the playlist is in rehearsal mode || &amp;lt;code&amp;gt;if mxw.playlist.is_rehearsal(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Preload ( &amp;lt;code&amp;gt;mxw.preload(n)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).isvalid()&amp;lt;/code&amp;gt; || True if preload &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; exists || &amp;lt;code&amp;gt;if mxw.preload(2).isvalid(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).clear()&amp;lt;/code&amp;gt; || clear the selected preload || &amp;lt;code&amp;gt;mxw.preload(2).clear()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_media(&amp;quot;filename&amp;quot;)&amp;lt;/code&amp;gt; || set the preload media by filename || &amp;lt;code&amp;gt;mxw.preload(2).set_media(&amp;quot;try.mp4&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_name(&amp;quot;name&amp;quot;)&amp;lt;/code&amp;gt; || rename the preload || &amp;lt;code&amp;gt;mxw.preload(2).set_name(&amp;quot;new_background&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).add_preload()&amp;lt;/code&amp;gt; || load the preload into the layers || &amp;lt;code&amp;gt;mxw.preload(2).add_preload()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).trigger_preload()&amp;lt;/code&amp;gt; || trigger a layer from the preload || &amp;lt;code&amp;gt;mxw.preload(2).trigger_preload()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_activated()&amp;lt;/code&amp;gt; || True if the preload is open for edit || &amp;lt;code&amp;gt;mxw.preload(2).get_activated()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_activated(True/False)&amp;lt;/code&amp;gt; || open/close the preload for edit || &amp;lt;code&amp;gt;mxw.preload(2).set_activated(False)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_layer_position()&amp;lt;/code&amp;gt; || return the preload&#039;s layer index || &amp;lt;code&amp;gt;mxw.preload(2).get_layer_position()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_track_position()&amp;lt;/code&amp;gt; || return the preload&#039;s track index || &amp;lt;code&amp;gt;mxw.preload(2).get_track_position()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_layer_position(pos)&amp;lt;/code&amp;gt; || set the preload&#039;s layer index || &amp;lt;code&amp;gt;mxw.preload(2).set_layer_position(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).set_track_position(pos)&amp;lt;/code&amp;gt; || set the preload&#039;s track index || &amp;lt;code&amp;gt;mxw.preload(2).set_track_position(2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_preload_names()&amp;lt;/code&amp;gt; || return the list of preload comment/name strings || &amp;lt;code&amp;gt;names = mxw.preload(2).get_preload_names()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.preload(n).get_image_sample_cvmat(w, h)&amp;lt;/code&amp;gt; || return a &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt;&amp;amp;times;&amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; RGBA image sample of the preload as a buffer (OpenCV Mat) || &amp;lt;code&amp;gt;img = mxw.preload(2).get_image_sample_cvmat(64, 64)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Widgets ( &amp;lt;code&amp;gt;mxw.widget(address)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).getValue()&amp;lt;/code&amp;gt; || return the widget&#039;s normalized value (float) || &amp;lt;code&amp;gt;o = mxw.widget(&amp;quot;/mxw/track/active/layer/active/opacity&amp;quot;).getValue()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).setValue(v)&amp;lt;/code&amp;gt; || set the widget&#039;s normalized value || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/track/active/layer/active/opacity&amp;quot;).setValue(0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).getStringValue()&amp;lt;/code&amp;gt; || return the widget&#039;s string value (e.g. a cue/clip name) || &amp;lt;code&amp;gt;mxw.print_console(mxw.widget(&amp;quot;/mxw/playlist/container/1/column/0/row/1&amp;quot;).getStringValue())&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).setStringValue(&amp;quot;text&amp;quot;)&amp;lt;/code&amp;gt; || set the widget&#039;s string value (e.g. name a cue) || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/playlist/container/1/column/0/row/1&amp;quot;).setStringValue(&amp;quot;background videoclip&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).setWidgetRealValue(d)&amp;lt;/code&amp;gt; || set the widget&#039;s real (un-normalized) value || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).setWidgetRealValue(120.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).animate(initvalue, incomingvalue, duration, delta, type)&amp;lt;/code&amp;gt; || animate the widget value over &amp;lt;code&amp;gt;duration&amp;lt;/code&amp;gt; ms || &amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).animate(0.0, 1.0, 1000, 0.0, 0)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.widget(&amp;quot;/mxw/path&amp;quot;).info()&amp;lt;/code&amp;gt; || return a list describing the widget. For a &#039;&#039;&#039;clip&#039;&#039;&#039;: &amp;lt;code&amp;gt;[length, width, height, millis_per_frame, cache_state, media_path]&amp;lt;/code&amp;gt;. Returns &amp;lt;code&amp;gt;[]&amp;lt;/code&amp;gt; if the address does not resolve || &amp;lt;code&amp;gt;length, w, h, mspf, cache, path = mxw.widget(&amp;quot;/mxw/track/active/layer/active/clip&amp;quot;).info()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Media ( &amp;lt;code&amp;gt;mxw.media(name)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).isvalid()&amp;lt;/code&amp;gt; || True if the named media exists || &amp;lt;code&amp;gt;if mxw.media(&amp;quot;USB Cam&amp;quot;).isvalid(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).reference(True/False)&amp;lt;/code&amp;gt; || add (True) or remove (False) a reference that keeps the media loaded || &amp;lt;code&amp;gt;mxw.media(&amp;quot;clip.mov&amp;quot;).reference(True)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).unload_media_full_if_not_used_by_clips()&amp;lt;/code&amp;gt; || unload the media if no clip uses it (returns bool) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;clip.mov&amp;quot;).unload_media_full_if_not_used_by_clips()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).get_image_sample_cvmat(w, h)&amp;lt;/code&amp;gt; || return a &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt;&amp;amp;times;&amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; RGBA image sample of the media (OpenCV Mat) || &amp;lt;code&amp;gt;img = mxw.media(&amp;quot;clip.mov&amp;quot;).get_image_sample_cvmat(64, 64)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).get_image_sample_cvmat_async(w, h)&amp;lt;/code&amp;gt; || non-blocking variant of the image sample || &amp;lt;code&amp;gt;img = mxw.media(&amp;quot;clip.mov&amp;quot;).get_image_sample_cvmat_async(64, 64)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).get_capture_device_names()&amp;lt;/code&amp;gt; || return the list of available capture-device names || &amp;lt;code&amp;gt;devs = mxw.media(&amp;quot;&amp;quot;).get_capture_device_names()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_is_supported&amp;quot;)&amp;lt;/code&amp;gt; || return whether the (NDI) camera supports PTZ || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_is_supported&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_zoom&amp;quot;, value)&amp;lt;/code&amp;gt; || zoom, 0 (in) .. 1 (out) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_zoom&amp;quot;, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_zoom_speed&amp;quot;, value)&amp;lt;/code&amp;gt; || zoom speed, -1 (out) .. 1 (in) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_zoom_speed&amp;quot;, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_pan_tilt&amp;quot;, pan, tilt)&amp;lt;/code&amp;gt; || absolute pan/tilt, -1 .. 1 || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_pan_tilt&amp;quot;, -0.5, 0.2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_pan_tilt_speed&amp;quot;, pan_speed, tilt_speed)&amp;lt;/code&amp;gt; || pan/tilt speed, -1 (right/down) .. 1 (left/up) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_pan_tilt_speed&amp;quot;, -0.3, 0.8)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_store_preset&amp;quot;, n)&amp;lt;/code&amp;gt; || store position/focus/zoom into preset 0 .. 99 || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_store_preset&amp;quot;, 75)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_recall_preset&amp;quot;, n, speed)&amp;lt;/code&amp;gt; || recall preset 0 .. 99 at speed 0 .. 1 || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_recall_preset&amp;quot;, 4, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_auto_focus&amp;quot;)&amp;lt;/code&amp;gt; || toggle auto-focus || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_auto_focus&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_focus&amp;quot;, value)&amp;lt;/code&amp;gt; || absolute focus, 0 (infinity) .. 1 (closest) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_focus&amp;quot;, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_focus_speed&amp;quot;, value)&amp;lt;/code&amp;gt; || focus speed, -1 (out) .. 1 (in) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_focus_speed&amp;quot;, -0.2)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_auto&amp;quot;)&amp;lt;/code&amp;gt; || auto white balance || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_auto&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_indoor&amp;quot;)&amp;lt;/code&amp;gt; || indoor white balance || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_indoor&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_outdoor&amp;quot;)&amp;lt;/code&amp;gt; || outdoor white balance || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_outdoor&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_oneshot&amp;quot;)&amp;lt;/code&amp;gt; || set white balance once from current brightness || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_oneshot&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_white_balance_manual&amp;quot;, red, blue)&amp;lt;/code&amp;gt; || manual white balance, 0.0 .. 1.0 each || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_white_balance_manual&amp;quot;, 0.1, 0.7)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_exposure_auto&amp;quot;)&amp;lt;/code&amp;gt; || auto exposure || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_exposure_auto&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_exposure_manual&amp;quot;, level)&amp;lt;/code&amp;gt; || manual exposure iris, 0.0 (dark) .. 1.0 (light) || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_exposure_manual&amp;quot;, 0.4)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.media(&amp;quot;name&amp;quot;).ptz(&amp;quot;ptz_exposure_manual_v2&amp;quot;, iris, gain, shutter)&amp;lt;/code&amp;gt; || manual exposure iris/gain/shutter, 0.0 .. 1.0 each || &amp;lt;code&amp;gt;mxw.media(&amp;quot;USB Cam&amp;quot;).ptz(&amp;quot;ptz_exposure_manual_v2&amp;quot;, 0.4, 0.2, 0.5)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot; |Grabber ( &amp;lt;code&amp;gt;mxw.grabber(name)&amp;lt;/code&amp;gt; )&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).isvalid()&amp;lt;/code&amp;gt; || True if the named keystone grabber exists || &amp;lt;code&amp;gt;if mxw.grabber(&amp;quot;cam&amp;quot;).isvalid(): pass&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).getGrabSizeX()&amp;lt;/code&amp;gt; || grabber width in px || &amp;lt;code&amp;gt;mxw.grabber(&amp;quot;cam&amp;quot;).getGrabSizeX()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).getGrabSizeY()&amp;lt;/code&amp;gt; || grabber height in px || &amp;lt;code&amp;gt;mxw.grabber(&amp;quot;cam&amp;quot;).getGrabSizeY()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mxw.grabber(&amp;quot;name&amp;quot;).getData()&amp;lt;/code&amp;gt; || return the grabber&#039;s pixels as a byte list (RGBA, width&amp;amp;times;height&amp;amp;times;4) || &amp;lt;code&amp;gt;px = mxw.grabber(&amp;quot;cam&amp;quot;).getData()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== See also ===&lt;br /&gt;
&lt;br /&gt;
* [[Python imgui reference|Python ImGui Reference]] &amp;amp;ndash; drawing plugin panels with &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt;&lt;br /&gt;
* [[Python plugin reference|Python Plugin Howto]] &amp;amp;ndash; writing media and playlist plugins&lt;br /&gt;
[[Category:Reference]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Tutorial_Eventmaster_Toolset_Controlling_MXWendler_by_e.g._e2_S3_Image_Processor&amp;diff=6158</id>
		<title>Tutorial Eventmaster Toolset Controlling MXWendler by e.g. e2 S3 Image Processor</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Tutorial_Eventmaster_Toolset_Controlling_MXWendler_by_e.g._e2_S3_Image_Processor&amp;diff=6158"/>
		<updated>2026-08-08T15:28:26Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update links after removing &amp;#039;3.&amp;#039; prefix from reference titles (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial applies to all different OS and MXWendler versions &amp;gt; 6.0.04&lt;br /&gt;
&lt;br /&gt;
== Introduction==&lt;br /&gt;
This tutorial explains how to set up a Barco Eventmaster to trigger and control media playback on StageDesigner or FXServer.&lt;br /&gt;
&lt;br /&gt;
==Control Setup==&lt;br /&gt;
&lt;br /&gt;
1. Open SD (StageDesigner) and load a clip into preload 1:&lt;br /&gt;
&lt;br /&gt;
[[File:e2_01.png|600px]]&lt;br /&gt;
&lt;br /&gt;
2. Open Settings-&amp;gt;IO-&amp;gt;Barco e2 and activate TCP listening. Also note down the port number.&lt;br /&gt;
&lt;br /&gt;
[[File:e2_02.png|600px]]&lt;br /&gt;
&lt;br /&gt;
3. In the Barco Eventmaster Toolset, create an &#039;External Device&#039;, name it e.g. &#039;StageDesigner&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:e2_03.png|600px]]&lt;br /&gt;
&lt;br /&gt;
4. In the &#039;Adjust: StageDesigner&#039; tab, set IP address and port number.&lt;br /&gt;
&lt;br /&gt;
[[File:e2_04.png|600px]]&lt;br /&gt;
&lt;br /&gt;
5. In the &#039;Adjust: StageDesigner&#039; tab, add a new command. Store the command content, e.g.&lt;br /&gt;
* /mxw/preload/1 play to start a clip&lt;br /&gt;
* /mxw/preload/1 play to stop a clip&lt;br /&gt;
&lt;br /&gt;
More possible commands are in the OSC control section: [[MXW_OSC_command_reference]]&lt;br /&gt;
&lt;br /&gt;
[[File:e2_05.png|600px]]&lt;br /&gt;
&lt;br /&gt;
6. In the &#039;Cue&#039; section, add a cue.&lt;br /&gt;
&lt;br /&gt;
[[File:e2_06.png|600px]]&lt;br /&gt;
&lt;br /&gt;
7. In this &#039;Cue&#039;, add actions.&lt;br /&gt;
&lt;br /&gt;
[[File:e2_07.png|600px]]&lt;br /&gt;
&lt;br /&gt;
8. From &#039;External Devices&#039; drop an available command onto the &#039;Commands&#039; field of the action.&lt;br /&gt;
&lt;br /&gt;
[[File:e2_08c.png|600px]]&lt;br /&gt;
&lt;br /&gt;
9. Play this cue, a clip should be started in the StageDesigner&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.mxwendler.net/index.php?title=Controlling_MXW_through_Python&amp;diff=6157</id>
		<title>Controlling MXW through Python</title>
		<link rel="alternate" type="text/html" href="https://wiki.mxwendler.net/index.php?title=Controlling_MXW_through_Python&amp;diff=6157"/>
		<updated>2026-08-08T15:28:25Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update links after removing &amp;#039;3.&amp;#039; prefix from reference titles (bot)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- MXWendler wiki page: Controlling MXW through Python (overview / hub) --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Intended location: https://wiki.mxwendler.net/index.php?title=1._Controlling_MXW_through_Python --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_command_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_imgui_reference --&amp;gt;&lt;br /&gt;
&amp;lt;!-- See also: https://wiki.mxwendler.net/index.php?title=Python_plugin_reference --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MXWendler StageDesigner embeds &#039;&#039;&#039;Python 3.12&#039;&#039;&#039;. Python is used in two ways:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Command interface / scripting&#039;&#039;&#039; &amp;amp;ndash; the module &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt; controls the running software (playlist, layers, clips, media, I/O, widgets by their address, ...) from the script console or from within a plugin.&lt;br /&gt;
* &#039;&#039;&#039;Plugins&#039;&#039;&#039; &amp;amp;ndash; self-contained folders that add a media source or a playlist item and are called back by the host through a defined set of functions (&#039;&#039;hooks&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The presented Python interface is supported in version 7.2. and up&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Where to go ==&lt;br /&gt;
&lt;br /&gt;
The detailed documentation lives on three dedicated pages; this page only points to them so nothing is documented twice.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Topic !! Page&lt;br /&gt;
|-&lt;br /&gt;
| The &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt; command interface &amp;amp;ndash; software info, &amp;lt;code&amp;gt;playlist&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;io&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;widget(address)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;media(name)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;preload(n)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;grabber(name)&amp;lt;/code&amp;gt; || [[Python command reference|Python command reference]]&lt;br /&gt;
|-&lt;br /&gt;
| Drawing plugin settings panels with &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt; (MXWendler&#039;s Dear ImGui binding) || [[Python imgui reference|Python ImGui reference]]&lt;br /&gt;
|-&lt;br /&gt;
| Writing &#039;&#039;&#039;plugins&#039;&#039;&#039; &amp;amp;ndash; media and playlist &amp;amp;ndash; the manifest (&amp;lt;code&amp;gt;mxw_plugin.ini&amp;lt;/code&amp;gt;), the hooks, per-instance state, examples || [[Python plugin reference|Python plugin reference]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Quick start ==&lt;br /&gt;
&lt;br /&gt;
A minimal look at each entry point; follow the links above for the full reference.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Scripting.&#039;&#039;&#039; From the script console (or any hook), the &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt; module reaches the software:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Python&amp;quot; line&amp;gt;&lt;br /&gt;
import mxw&lt;br /&gt;
mxw.print_console(&amp;quot;frame &amp;quot; + str(mxw.framecounter))&lt;br /&gt;
mxw.playlist.play()&lt;br /&gt;
mxw.widget(&amp;quot;/mxw/track/active/layer/active/opacity&amp;quot;).setValue(0.5)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Plugins.&#039;&#039;&#039; A plugin is a folder holding a manifest and a Python module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
plugins/playlist/python/plugin_my_item/&lt;br /&gt;
    mxw_plugin.ini      the manifest: identity, menu entries&lt;br /&gt;
    mxw_main.py         the Python module with the hook functions&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The host discovers it at startup, shows it in the user interface and calls its hooks at the right moments. See the [[Python plugin reference|Python plugin reference]] for the manifest fields, the full hook list for media and playlist plugins, plugin locations, installing extra packages with &amp;lt;code&amp;gt;mxw-pip&amp;lt;/code&amp;gt;, and complete examples.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Python command reference|Python command reference]] &amp;amp;ndash; the &amp;lt;code&amp;gt;mxw&amp;lt;/code&amp;gt; module&lt;br /&gt;
* [[Python imgui reference|Python ImGui reference]] &amp;amp;ndash; drawing plugin panels with &amp;lt;code&amp;gt;mxw_imgui&amp;lt;/code&amp;gt;&lt;br /&gt;
* [[Python plugin reference|Python plugin reference]] &amp;amp;ndash; writing media and playlist plugins&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>