XML Defined Controllers

Parts of the app can be customized regarding the MIDI they generate and their visual appearance. This includes all pad controllers on the Keyboard and XY-Pads screens, XY-Overlays, the central controller block 'underneath' the keyboard and the Workshop screen.

User customizations 'live' in the current XML document and are stored within it. Controller definitions for seperate parts can also be imported, exported and shared individually.

All customizable parts are edited in the same way. All pad controllers and fully user-defineable controllers (Workshop, XY Overlays and the central block underneath the keyboard) share the same code and are equivalent in what they can (and can not) do.

Edit Mode

To start editing select "Edit" from the menu. This will bring up a dialog with multiple tabs covering things like MIDI, colors, text, layout etc. and is discussed in more detail below.

Some additional functionality is given in the dialog's header: The title that indicates the edited control provides a link to the app's XML Editor. When you touch it, the xml will be shown scrolled to the highlighted representation of the currently edited component. Edits can generally be done via the dialog UI or directly in the xml.

If a hardware keyboard is connected, 'Ctrl-E' will enter and exit edit mode. 'Ctrl-Shift-E' breaks directly into the XML editor.

The Trigram symbol ( ☳ ) in the middle of the dialog's header can be used to move the dialog around as it will of course obstruct a good part of the screen especially on phones.

Edits will only take effect and be written to the xml document when confirmed with the OK button. Multiple components can be edited before confirming, though. When working on the xml itself, use the "(Save And) Close" menu entries to exit the XML editor.

Use the "Done" button, double-tap the screen's background or touch the screen's menu again to exit edit mode. (Note that exiting edit mode will NOT confirm edits!)

Selecting Components

In Edit mode touching a pad or control selects it and displays its properties in the dialog. The currently edited component will be marked by an orange border.

To change the selection either touch another control or use the arrow buttons in the dialog's header, resp. the left / right arrow keys on an attached hardware keyboard to step through controls.

Selecting groups

If you touch the currently selected control again, selection will change to the group the control lives in.

The next touch selects the group's enclosing group.


This will go up all the way until the top level of the controller is selected before it will start with the originally selected control again. To interrupt the proceeding touch some other control.

Groups in the end are just simple layout containers, but can mostly be handled like other controls: They have their own color and layout related properties and once selected can be removed or be exchanged against other controls via the "Control" tab.

Editor Tabs

The editor dialog will have slightly different content depending on whether you edit pad controllers or xml layouts. Pad controllers can not change the controls themselves, so there will be no tab to select the type of control. Pads do however have a concept of global overrides (primarily for colors) where settings may apply to all pads that do not have individual settings. This is not available for XML layouts. The dialog will have 5 tabs when editing XML layout and only 4 when editing a pad controller. The contents of some tabs may differ in details.


(Not shown when editing Pads)

Defines the type of individual controls and some of their basic properties. The contents of the tab's right half will change depending on what is selected in the list on the left.

Selecting a different control type in the list will exchange the currently selected one when you press OK.

To create a new control instead of modifying the currently selected one, check either the "Insert" or "Append" boxes on the lower right hand side. This will show another popup that gives you the option to add multiple controls in one step. "Insert" means that new controls will be inserted right before the currently selected one. "Append" will add new controls at the end of the group the currently selected one lives in.

New groups will be prefilled with default numbers of controls whose type you can select when creating groups. You can change their contents after they have been created.

To delete a control, select the last - "None (Remove)" - entry in the list and click OK. If a hardware keyboard is connected you can also use 'Del' or 'Ctrl-Backspace'. On Android 5 and larger dragging a component and dropping it 'offscreen' will also remove it.

Control specific properties:

Properties are stored in xml attributes. Most controls will use a 'mode' attribute for the basic properties exposed on the Control tab. The attribute holds a numeric value that is interpreted bitwise, i.e.: the number really holds up to 32 on/off switches. The meaning of single bits may vary by control and is given in more detail below. As of version 2.4.0 the app will write 'mode' (and other bitmask values) in hexadecimal format, which can make it more easily readable (if one understands hex notation, which in the end is easy and worth getting a hold of). Values can still be given in decimal format, though.

A litle tool to help figuring out bitset values outside of the app can be found below.

  • Buttonmode: determines how and when MIDI will be sent upon touches:

    • Momentary: High value sent when pressed, low value sent on release
    • Single: Only the high value is sent, low value and button release are ignored.
    • Toggle: First press sends high value, next sends low value. Release is ignored.

    Some MIDI data types are always sent as "Single": There is no "off" state for Program and Bank changes, Sysex and most of the non-MIDI commands.

    The 3 variants available for 'Toggle' buttons are about managing the state of a toggle switch in relation to local touch events and incoming MIDI feedback. Which one you want will depend much on the behaviour of the remote side (and in many cases you probably will not want a toggle button at all):

    • Shared: Both sides can flip the toggle's state. In this mode the button will only react to incoming 'high' values (same as it is only affected by button presses, not releases). If a button is remotely toggled it will 'report' its changed state. This mode is primarily intended for standard momentary button / LED combinations on external hard- or software.
    • Local: the toggle state is maintained in the app. The remote side can only flip it with 'opposing' data: If a toggle is on, an off event will turn it off while a high value would be ignored and vice versa.
    • Remote: the toggle state is expected to be handled and reported by the remote side. Local button presses reverse the last received state, but do not flip it internally.

  • Excl.Group: lets you combine several pads or buttons into virtual groups out of which only one will then be selectable at a time. On pad controllers this primarily affects the pad's visual representation. A pad's button-mode setting (Momentary,..,Single) remains in effect. Buttons in exclusive groups on custom layouts will internally be set to be toggles (and hide the 'Buttonmode' control). Members of an exclusive group that were the selected will by default send their "off" state when another member of the group is selected. This can be disabled by unchecking the box next to the group dropdowns. When unselected, the group's output will directly transition between the buttons' high values and only send an off state when the selected button is explicitly untoggled.

    - A button's exclusive group is stored as a simple numeric index in a grp attribute on the button's xml node.
    - Group behaviors are stored as a bitmask in an xgf attribute on the top-level controller node.

Fader & Small Fader:
  • Invert - Inverts the MIDI output (sends 0 when fader is up, max value when down
  • Centered - Initially shows with knob at 50%. Resets to 50% on double-click.
  • Allow Jumps - Move knob without directly touching it. This disables double-click resets when also 'centered'.
Pitchwheel & Crossfader:
  • Same options as faders. Centered by default.
  • Step: Moves in eight steps and only sends MIDI when high nibble changes.
  • Black: Render with a dark knob (Colors can also be individually set).
  • Velocity - Sets how the velocity value for outgoing MIDI is determined.
  • Velocity Code - Sets a colorcode to visualize incoming velocity information (Ableton Live grid controller stuff).
  • Aftertouch - Sets how the second MIDI stream is generated (actual data type does not necessarily need to be aftertouch).
  • Blinkable - Makes the pad listen for its assigned MIDI message on 2 more MIDI channels to trigger blink & pulse styles.
  • Touchable - Sets whether the control reacts to touch (and sends MIDI vs. only receiving and visualizing it).
  • Blinkable - Makes the label listen for its assigned MIDI message on 2 more MIDI channels to trigger blink & pulse styles.
  • Invert - Inverts the MIDI output (inverting the 'direction' in endless mode)
  • Centered - Initially shows at 50%. Resets to 50% on double-click. No effect in endless mode.
  • Operation - Touch interaction options. 'Relative (Circular)' has no effect in endless mode.
Jogwheel and Scrubwheel:
  • Invert - Inverts the MIDI output (inverting the 'direction' in endless mode).

    Rotary controls switch between endless and linear mode depending on their MIDI settings: With a 'Control Change' (CC, 0xBn) status byte, values of 0 - 3 for the second databyte select between endless modes (see MIDI Mode). Higher values make the control 'linear' (and define the range for potentiometers).


Tabbed groups create a tab for every direct child placed inside them and then show one of those tabs or pages at a time. Direct children to a tabbed group will usually be groups again, which then hold individual controls, but it is also possible to add controls directly. The 'Synth-Controls' and 'Alt-Keys' presets demonstrate use of tabbed groups.
Newly created tabbed groups will be prefilled with two groups each holding a placeholder label.
  • Tab Position - Sets how and where tab controls are rendered.

Scrollgroups allow for horizontally or vertically scrolling parts inside a layout. They will normally hold child controls directly and have the same prefill options as plain groups. The 'MIDI Volume', 'NRPN' and 'Drawbars' and 'Sound / FX' presets show use of scrollgroups.
  • Vertical - Sets scroll direction.

Controls taking multiple pointers:

The following more complex controls make additional properties available through an in-control menu. They still use the 'mode' attribute, but will store things like scales and notelayouts, color schemes and sensors in additional attributes.
The runtime menus will also contain mute controls for separate CC streams if any exist. You will need them for mapping. Mutes are not stored in xml.

  • Centered - Move pointer and values back to center position on release.
  • Allow Jumps - If off first touch event must be close to current position or will be ignored.
  • BG Sensor - Keep an evtl. active sensor running when control is hidden.
  • Z-Source - Sets what feeds a pointer's third datastream (if not linked to a sensor).

    XY-Pads support two pointers that can (also partially) be activated by setting or disabling MIDI messages for its 8 streams.
    The first pointer can be driven by device sensors (Accelerometer, Magnetic Field and Orientation. Whether all of those will be available depends on the device).
    Streams can individually be inverted, which will be stored in an 'inv' attribute.
    Sensors, Inversion and (runtime) mute controls are accessible via the in-control menu.

  • Hide Labels - Show or hide octave root note names.
  • Hide High C - Hide the next octave's root key.
  • Disable Glides - Ignore key changes resulting from move events.
  • Show MIDI input - Visualize incoming note events.
  • Show Menu - dto. Off by default here.
  • Velocity - Sets how the velocity value for outgoing MIDI is determined.
  • Aftertouch - Sets message type and touch interpretation for key aftertouch.

    Scales, their basenote and octave-counts are accessible via the in-control menu and stored in a "kbm" attribute.
  • Orientation - Sets whether notes are arranged horizontally, vertically or depending on component size.
  • Hide Labels - Show or hide note names.
  • Show MIDI input - Visualize incoming note events.
  • Velocity - Sets how the velocity value for outgoing MIDI is determined.
  • Aftertouch - Sets message type and touch interpretation for key aftertouch.

    Scale, basenote and note-count accessible via in-control menu.
  • Hide Labels - Show or hide note names.
  • Show MIDI input - Visualize incoming note events.
  • Velocity - Sets how the velocity value for outgoing MIDI is determined.
  • Aftertouch - Sets message type and touch interpretation (Y-axis) for key aftertouch.

    Notelayout, evtl. color scheme, scale, basenote and octave-count accessible via in-control menu.
  • Show MIDI input - Visualize incoming note events.
  • Aftertouch - Sets aftertouch message type (always uses size / pressure for touch interpretation).

    Scale, basenote and note-count accessible via in-control menu.
  • No extra properties. Mutes are always accessible on screen.

Small utility for bitset attribute values:

Whenever the textfields on the right say "--default--", the attribute does not need to be given in xml at all (and TouchDAW would remove it). 0 or 0x0 can be a valid non-default value.


Defines the data sent by the selected control. Buttons, faders etc. will also react to the MIDI messages they are set to send.

When editing Pad controllers this tab will also contain controls for buttonmodes and exclusive groups (see button properties on the 'Control' tab above).

Most controls will only offer a single 'stream' of data. When you edit a control that creates more than one, there will be a scrollable column at the left side where you can select the individual streams.

The display format of MIDI data fields can be changed between decimal, hex and note name by touching the "Data..." labels above them.

Entries in the "Type" popup from "Bank + Prg. Change" onwards will change the contents of the dialog:

Bank / Prg. Change allows to attach combined bank and program change commands with both MSB and LSB fields for the bank part to a single touch action. Both the LSB part of the bank change command as well as the Program Change can be ommitted by setting the resp. popup to their last ("Ignore") entry.

Sysex will in most cases consist of more than three bytes and needs to be entered via a multiline textfield as hex values. Alternatively you can import sysex from the internal library or from .syx files selectable through a standard file picker (Android 4.3 and larger). You can also use this field to attach System realtime commands or combinations of multiple MIDI messages to a pad.
XML layouts can modify sysex like the mixer's MIDI mode (See xml sample. Only the fader related parts are supported here).

NRPN & RPN makes linear controls send (Non) Registered Parameter Number controllers. The two data pop-ups set the parameter number. Controllers will be sent in 14bit resolution.

Chord creates basic chord types each with a number of voicing variants to be send with a single touch event (more exotic stuff like sus, 9, 11 etc. is pending, but you can use the 'Sysex' entry to create additional chords as running status combined note assemblies)

MIDI Channel: Forces all controls configured to send standard MIDI to a given MIDI channel (not currently overwritable with individual settings). XY-Pads only: If the "All" option is checked, this will also affect standard MIDI controls in an eventual XY overlay or a second xml customized pad.

Data Offset: Adds the given value to the individually configured ones for all (standard MIDI) pads. This can be used for some sort of "controller-side bank switching". Unlike the "MIDI channel" modifier this option only affects the screen half it is invoked in. Note that the data field is context dependent: While it will usually be "Data 1" (ie. Note, CC or program number), pads set to bank select CCs will have "Data 2" modified. Also be aware that MIDI still uses 7bit values. The actual output may be clamped if it would exceed the maximum range.

DAW Control lets you attach standard DAW Control functions to a control. The displayed popup will contain command names depending on the app's "Sequencer" preference. For sliders in an XML layout this will only be channel and master volume, for rotaries it will be channel v-pots, etc. Buttons can be set to send commands with modifiers. All DAW commands will be sent out via the app's first MIDI port.

Preset Change swaps the currently loaded preset against another previously exported one. This enables creation of multipage controllers. Note that only user exports will be available for this action. If you want to switch to one of the 'factory' presets, load and export it first.

App Navigation can be used to make pads or buttons switch to other screens in the app. XY-Pads only: This also provides a way to toggle the xy overlay on and off in mixed setups.

The Undo arrow button resets any of these extensions to standard MIDI (where all available message types are then available in the "Type" dropdown).

MIDI Learn

You can let the currently edited control learn (standard) MIDI from the app's second MIDI port:

When on the MIDI tab, touch the tab header again. The little white dot will turn red, the next MIDI received is set to be this control's MIDI data and MIDI learn is disabled again.

If you touch and hold the tab header, learn mode will both be activated and set to automatically advance to the next control after something was learned in. The learned value will briefly be displayed before the next control is selected. After a successful learn operation MIDI input is also blocked for ~1sec to prevent note-offs or CC overturns from immediately being assigned to that next control. Touch the header again when done.

Incoming velocity, CC and pitch values are 'ignored'. The learned MIDI message will represent channel, type and note / CC numbers of the incoming message, but have its value field(s) set to the 7 bit maximum.


Text input and some basic formatting options for controls that can show text.

Many controls have no way to show and / or format text and will have the tab or its components disabled or partially hidden.

Linebreaks are supported, the textfield will expand when you hit enter.

Unicode symbols can be used by entering codepoints in "\u....", "U+...." or HTML entity ("&#x....;") notation, but availability and rendering of unicode glyphs depends much on system version and manufacturer preferences.

For Transport buttons the text input may take a number between 0 and 11 as an index into standard transport icons.


This controls color and layout aspects. The right half of the tab differs between pads and XML layouts.

Pad controllers:

Colorfields set a pad's background, text and pressed (or MIDI triggered) colors. When you check the "Apply to all" box (not shown), selected colors will be written to the parent xml node and will apply to all pads that do not have individual colors set. Global color values, exclusive groups and velocity codes are displayed and editable on the 'Global' tab. To reset global colors touch and hold the colorfield there.

The "Hit" color will be used to show MIDI input unless there is also a velocity code set.

Velocity codes are used to map incoming MIDI velocity values to colors. This is commonly used with grid controllers to reflect clip state and to mirror clipcolors on external controllers. A few velocity codes are predefined in the app and you can define additional ones in the xml.

To reset a color value to defaults, touch and hold the respective field.

XML Layouts:

Colorfields set background and foreground colors depending on the type of the selected control. Not all controls will care for all three (or any) of the colorfields. Touch and hold a field to reset it to default values.

When editing a group or a label there will also be controls for selecting background images and editing their display properties.

The right half of the tab contains layout parameters. Most of these need not be set, but can be used to overwrite what the layout engine does without being given any hints. Some are only available for groups, some only for the top-level controller. Numeric values that reference 'Pixels' will be interpreted as 'device independent pixels'.

  • Screen (top-level only): Can be used to enforce landscape or portrait orientation. Default is 'Sensor', layouts will rotate with the device. This writes a "rotation" attribute with an integer value (0 - landscape, 1 - portrait).

  • Orientation (groups and top-level only): Sets a group's layout direction. The default layout direction on the top-level is horizontal. Groups by default always flip the layout direction of their direct parent. A group in a horizontal layout will stack its children vertically, a group in a vertical layout aligns its children horizontally. A group inside a group will flip the direction again.

    This behavior can be overwritten with an "orientation" attribute. 0 - enforces a horizontal layout, 1 makes it vertical and 2 makes the top-level layout direction depend on screen orientation (This is used by some of the Workshop presets that adapt to screen orientation).

  • Width: Enforces some sort of horizontal size. This can be an absolute pixel value, but more often should be either left blank or be set to -1 (meaning: match parent) or -2 (for: wrap content) as rule based layouts will usually work better with varying screen-sizes than layouts based on absolute coordinates and values.

  • Height: Same as 'Width', just for the vertical axis

  • Weight: takes a floating point value that is larger than 0 and smaller than 1 and sets how much of the space available in the direct parent a control should cover. The sum of all children's weight should be 1. Use of "weight" will often make it obsolete to give values for width and height.

  • Alignment (groups only): Can be used to make controls align horizontally and / or vertically without padding a group up with spaces or the like. Slightly changes the way in which controls are 'measured' (how their size is determined) and may require more explicit sizing attributes on the group's children in some cases.

  • Margin: Can be used to add space around a control. This takes a comma seperated list of up to 4 values (L[,T[,R,B]]) that will be interpreted CSS style. Fixed aspect controls may ignore some of the values.

  • Padding (groups only): Adds some inner space to a group, shrinking its children. (L[,T[,R,B]]) again.

  • Visibility: Can be used to make controls conditionally show depending on device characteristics (tablet vs. phone, portrait vs. landscape etc.) Touch and hold the textfield to show the available options. Value is a bitmask.
    Note that hidden controls will by default be skipped in the editor. To change a hidden control's settings either bring the device into the state where the control will be shown or disable the skipping in the dialog's menu and use the left / right arrow buttons in the header to navigate to the hidden object.

General notes on layouts:

Do not expect to find anything like absolute position and size values! Layouts using fixed absolute values would immediately break the moment they are run on another device, because screensize, resolution, aspects etc. would very likely not match. Layouts rather work with a 'filling available space' concept and designing a layout will mostly be about arranging containers (ie.: groups) in a way that gives the actual controls the desired space.

That said: Building an Android app normally requires to create multiple layouts for the same thing to account for all the different screens the app may run on. The system's internal mechanics then select the appropriate layout definition at runtime. Android's system-level layout engine however can only be used with definitions that have been precompiled into the apk. This is obviously not possible with user-defined layouts. TouchDAW's XML layouts therefore are built by the app's own layout engine, which replicates some concepts of the system, but in the end is very different and a lot less powerful. Amongst other shortcomings it lacks the ability to pick a screen-matching definition at runtime. When building a layout you should be aware that things may look a bit different when screensize, resolution, aspect ratio etc. change.

As a rule of thumb, 'mixed groups' (groups containing different types of controls especially if those have drastically different aspect ratios like for example encoders and faders) should be avoided. You will otherwise likely need to adjust multiple individual layout attributes.

Background Images

Groups and labels can show .png or .jpeg image-backgrounds or use xml defined 'shapes' to create borders, gradients and fills.

Images are a bit of a logistical nightmare, because external files need to be moved around with the xml. Also Android will not allow an app to load any old image from everywhere on your device without a lot of permission hazzle. TouchDAW will therefore only load images from its private storage space and copy everything that you import to that space before using it. When exporting controllers images and xml can be bundled in zip archives.

Touching the image-search icon will open a file-picker in the app's presets/img directory. This directory will be empty initially, but you can import files from the file-picker. See the files page for details.

When an image has been selected it will replace the image-search icon and you can set some scaling options. To remove a background image, touch and hold its miniature view in the dialog.

Keep your images at reasonable sizes! Bitmaps can take up a lot of memory and RAM-allocation failures may crash the app. It makes no sense to use a multi-megapixel shot from your camera roll as a background for some small subpanel (or even the whole controller)!


Shapes are an Android concept to describe drawing commands via xml. TouchDAW currently only supports basic 'ShapeDrawables', but these can nevertheless offer a very economic alternative to bitmap images. To select a shape instead of a bitmap touch the 'Image' label. It will change to 'Shape' and touching the image-search icon will then take you to the 'presets/shapes' directory. Some example shapes are included. You can edit them from the file picker to adjust colors, line thickness, corner radii etc. See the comments in the xml and check the Android documentation on ShapeDrawables for more details. Shapes have no scaling option, because they are (mostly) resolution independent by definition.


(XML Layouts only)

This tab contains a screen-specific list of presets. Some of them are ready-made controllers, some are mere templates that will need individual adjustments. All of them are customizable.

After loading a preset by selecting it in the list and clicking OK (or by double-tapping the entry in the list) the controller definition will be merged into the current xml document and can be modified.

The Import / Export controls on the right hand side can be used to save and load controller definitions outside of the context of the global setup file. These isolate definitions for the current screen and write / reload them without affecting the contents of other screens or any DAW control modifications you may have made. See the Files page for information on where the app stores its data.

The file-dialog also lets you 'share' presets (export to a Drive instance, send out via email etc.) or import from non app-private folders, Google Drive etc..

With the introduction of the 'Preset Change' action the app starts to transition away from holding all definitions in one central XML document. If you import a preset and then edit it, your changes will also be written back to the file originally imported. Use the copy options on the filepicker to create explicit backups if needed!

Presets for the individual screens are documented on the respective manual pages: Keyboard & XY-Pads, Workshop.

(Pad controllers only)

Presets for pad controllers are given in a simple dropdown list on the 'Global' tab. Import and export options are equivalent to those described above for XML layouts, allthough the contents of the created documents will be different. Trying to import an XML layout on a Pad controller (and vice versa) will not work.

The menu icon in the header ( ☰︎ ) gives access to some basic copy / paste functions that will copy / paste attributes in context of the current tab.

If there are 'emulation' nodes inside the controller definition or globally in the document the menupage will also show a list of queries and responses with a checkbox to individually (de)activate them.

Drag and drop

Simple rearrangements of a layout can be done via drag and drop. When you touch and hold a control in edit mode the app will hide the editor dialog and switch into drag and drop mode.

This is indicated by a green border around the selected control and a drag shadow being displayed that will follow your finger's position.

When you move that drag shadow over other controls, a green line will indicate the point where the dragged control would be inserted if you took the finger off the screen.

When the shadow is moved close to a control's border that is off the axis of its enclosing group the insertpoint will change to 'before the group'. This is again indicated by a solid green line showing the insertpoint while the group the control would be moved out of will be bordered by a dotted line.

You can also drag and drop entire groups of controls after first selecting them as described above before performing the 'touch and hold' on the originally selected control.

After a dragged control is dropped, the dialog will come up again. Drag and drop changes are not immediately saved. You will still need to 'OK' the dialog. If you click 'Cancel' instead, all uncorfirmed drag and drop changes will be reverted.

Please note that drag and drop operation will come to its limits when you try to find insertpoints between multiple nested groups. On small screens and when dealing with small controls it may also be difficult to see both the drag shadow as well as the indicators for insertpoints as they will quickly be covered by your finger. All in all it is a bit questionable if this sort of operation really is suited to touchscreens at all (and I seriously doubt it).

MIDI Monitor

For debugging purposes you can call up a monitor overlay by long-clicking the edit menu button or by attaching an 'App Navigation / MIDI Monitor' action to a button.

MIDI input received on the selected port will be displayed on the left. Data going out to that port is shown on the right.

The overlay is semi-transparent and 'touch-through', components behind it will still be usable. If you need to scroll the monitor, it can be made touch-reactive via the two little arrows at the top.

Note that the monitor is a temporary tool and should not be mistaken as a UI component for controllers. It can have a bit of a performance impact with heavy input loads and its state will not be preserved across rotation and screen changes.

XML Editor

While controllers can be fully edited via the UI, it may at points be faster and more convenient to work directly on the xml. The app's internal XML editor is little more than a standard Android text editing component with the usual touch-based selection, copy / paste, deletion options. If a hardware keyboard is connected those will also be available via standard keyboard shortcuts (Ctrl-c, Ctrl-v etc.). Additionally there will be some extra key commands:
  • Ctrl +/-: Change font size.
  • Ctrl-s: Save file.
  • Ctrl-Shift-s: Save file as. After this you will be working on the newly created file.
  • Ctrl-Alt-s: Save and close. Saves the xml and reloads the controller.
  • Esc - Close editor without saving
Working 'on-device' using a Usb or Bluetooth keyboard (and optionally a mouse) will be more convenient than editing externally on a PC, because Android's file transfer and access options won't allow for direct editing of on-device files from a PC, so this would involve constant downloads and re-uploads. Key-commands will only be available with hardware keyboards, not with the virtual onscreen touch-keyboard (because... Android).

XML Attributes

List of attributes used on pad and control nodes:
  • "id": Integer pad ID (controls in XML layouts do not currently use IDs)

  • "type" (XML layouts only): String control type
  • "mode": Integer flags for button modes, slider inversion etc.

  • "midi": Comma separated list of hexadecimal byte values
  • "midi_1" ... "midi_n": MIDI messages for additional 'streams' if any

  • "color": Comma separated list of 1 - 3 32bit hex color values
  • "vc": Integer index into defined velocity codes

  • "rotation" - Integer screen orientation lock
  • "orientation" - Integer layout direction for groups
  • "width" - Integer X-dimension
  • "height" - Integer Y-dimension
  • "weight" - Float layout space allocation
  • "margin" - Comma separated list of 1, 2 or 4 Integers, outer spacing
  • "padding" - Comma separated list of 1, 2 or 4 Integers, inner spacing for groups

  • "title": Label string
  • "tf": Integer text flags

  • "grp": (pads and buttons only): Integer group index
  • "fc": Integer global MIDI channel enforcement


Things that are currently NOT possible:
  • No (complex) interaction between controls beyond exclusive groups and channel / data offsets
  • The basic visual appearance of controls can not be changed beyond alternating colors
  • No individual layouts for landscape and portrait mode, phones or tablets or otherwise 'different' screens
  • There is no central repository to up- and download additional controller definitions to / from
  • Not all controls are direct equivalents to those used in other parts of the app. There will at points be minor functional differences.
  • Plus probably countless other things...