Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow users to change mapping options from GUI without having to edit XML or JS #8135

Closed
mixxxbot opened this issue Aug 22, 2022 · 22 comments · Fixed by #11300
Closed

allow users to change mapping options from GUI without having to edit XML or JS #8135

mixxxbot opened this issue Aug 22, 2022 · 22 comments · Fixed by #11300

Comments

@mixxxbot
Copy link
Collaborator

mixxxbot commented Aug 22, 2022

Reported by: Be-ing
Date: 2015-06-30T23:29:21Z
Status: Confirmed
Importance: Wishlist
Launchpad Issue: lp1470278
Tags: controllers, midi


It would be convenient if there was an API for scripts to expose variables to Mixxx's GUI that could be changed from the controller preferences so users would not have to edit mappings themselves. This could be used, for example, to adjust jog wheel sensitivity or which decks the controller manipulates.

See also: #8006

@mixxxbot
Copy link
Collaborator Author

Commented by: daschuer
Date: 2015-07-01T06:52:28Z


Can we rename the bug to something like:
"mapping script ControlObjects with GUI"

We may allow the mapping script to register its own ControlObjects. This is what we have done for Skins:
https://github.com/mixxxdj/mixxx/blob/master/res/skins/Shade/skin.xml#L65

The mapping script may also provide its own GUI to change it's ControlObjects.
This can be done like a "Skin" for the preference.

Before we are able to do this, we may just present them in a view like the CO view in the development menu.

Somehow related: Bug #⁠1166016

@mixxxbot
Copy link
Collaborator Author

Commented by: Be-ing
Date: 2015-07-01T07:31:34Z


If you think allowing scripts to register their own COs which would be exposed to the GUI is the best way to handle this, sure. If this system is flexible enough to allow mappings to specify their own GUI for changing these, this should be easy for script writers and done automatically for simple cases. For example, scripts should not need to specify their own GUI for boolean variables; checkboxes should be made by Mixxx automatically. Similarly, for numeric variables, a number input box with up/down arrows would be made automatically and scripts could specify a range of acceptable values.

Related to Bug 1166016, see the wiki page I started recently for brainstorming about a new mapping format:
http://mixxx.org/wiki/doku.php/new_control_mapping_format

@mixxxbot
Copy link
Collaborator Author

Commented by: daschuer
Date: 2015-07-01T08:38:19Z


We have two issues:

  • Adding descriptions -> a CO currently does not have any self description
  • Internationalization -> Skin specific texts can't be translated.

Maybe we can just statically add a set of COs for the common uses cases into the Mixxx engine.

Do you have use cases for this feature?

@mixxxbot
Copy link
Collaborator Author

Commented by: Be-ing
Date: 2015-07-08T00:57:17Z


Yes, I put a few options at the top of my Electrix Tweaker mapping for users to adjust as they like. See https://github.com/Be-ing/mixxx/blob/tweaker_mapping/res/controllers/Electrix-Tweaker-scripts.js

@acolombier
Copy link
Member

Hi, is this up for pick up? If yes, is there an existing design doc or a draft? Otherwise can I go ahead and suggest some approach for that features?

@daschuer
Copy link
Member

daschuer commented Feb 19, 2023

Yes, I would be happy if you pick it up. We have discussed options to implement it, but I am afraid it is scattered across different places. Maybe one else could point you to the different places.

I think it is reasonable to describe you project here.

We havre two types of controller options. Some maybe static, that can be implemented in a poor man's solution my an alternative mapping and some might be subject to change during a performance. What is your demand?

@acolombier
Copy link
Member

My original thought was to start with implementing global settings. This means that changing them would cause a reload of the mapping. I would imagine this should cover most cases as I would expect rare cases when you would go in settings and change your controller behavior during a performance, but this should still be doable as long as the reload is correctly implemented on the mapping.

My idea was, as a first step, to extend the XML spec to support a new definition block, and define 3 types of options:

  • boolean
  • number (integer/double)
  • enum (selection from a list)

An example of configuration using this new specification could look like this:

    <controller>
        <settings>
            <option 
                variable="myFactor" 
                type="integer" 
                min="1" 
                max="1000" 
                step="10" 
                default="100"
                label="My dummy factor" 
                label_de="Mein Dummy-Faktor" 
                label_fr="Mon facteur factice" />
            <option 
                variable="myOtherFactor" 
                type="real" 
                precision="2"
                min="0" 
                max="1" 
                step="0.05" 
                default="0.15"
                label="My other factor">
                <description>
                    This factor is useful for one thing that you definitely need.
                </description>
                <description lang="de">
                    Dieser Faktor ist nützlich für eine Sache, die Sie unbedingt brauchen.
                </description>
            </option>
            <option 
                variable="myToggle" 
                type="boolean" 
                default="false"
                label="My beta feature">
                <description lang="de">
                    It include many things, you should try it.
                </description>
            </option>
            <option 
                variable="myOptionList" 
                type="enum" 
                label="My list of option">
                <value label="A">a</value>
                <value label="B">b</value>
                <value label="C">c</value>
                <description>
                    This list define how A will interact with the rest of the letters.
                </description>
            </option>
        </settings>
        ...
    </controller>

The i18n is only a suggestion, we could assume it only supports english to make it simple. I don't really like the _ but thought I would still lay out the option

When it comes to UI, it could look like something like the following:
image

Finally, in term of availability withing the mapping definition, it could take the form of an injected object for JS, something like:

mixxxControllerSettings = {
  myFactor: 100,
  myOtherFactor: 0.15,
  myToggle: false,
  myOptionList: "a",
}

For MIDI mapping, it could use something similar to the TAL namespace on Python Chameleon, especially tal:condition and tal:content.

Looking forward to hear your thought on this!

@Swiftb0y
Copy link
Member

Your suggestion is very solid. One thing we previously discussed that would be even more powerful would be to use a QML UI which is loaded from a mapping automatically.
The downsight is that in order to do that without lots of redundant and possibly difficult to manage code is that it requires large rewrites/redesigns of mixxx (QML Gui and new controller system). I think a reasonably simplistic interface description in the XML would work as a decent stop-gap solution.

@daschuer
Copy link
Member

Thank you for this good and straight forward plan.

Just a side note:
There is https://doc.qt.io/qt-5/qabstractformbuilder.html that can read the ui xml used in QT creator.
But I have no idea how to reasonable connect this with the actual config data.

@acolombier
Copy link
Member

Thanks @daschuer, but do you think it needs something this advanced in terms of UI capabilities? IMHO, it would be great to keep the settings capabilities simple, so we make sure UX remains simple enough from a user perspective. Also, this would make sure that Mixxx remains in control on the look-n-feel of these settings, and don't let discrepancy grow between mappings.

@daschuer
Copy link
Member

I fully agree.

@Swiftb0y
Copy link
Member

So do I. If we ever have a QML UI, skins could provide customized UI elements for use by controllers, that way the look-n-feel would stay consistent.

@llaver
Copy link
Contributor

llaver commented Feb 23, 2023

Was hoping someone was thinking about this. @acolombier your proposal is exactly what I had in mind.

As for:

a QML UI which is loaded from a mapping automatically.

In my opinion, adding full UI control adds extra unnecessary complexity to mapping that could lead to hard to find bugs and an inconsistent UI. At most, some kind of grouping and a half or full width option would allow for more consistent grouping/responsiveness of similar settings, and perhaps more efficient use of the negative space in the menu, but in my mind these aren't deal breakers since scrolling covers that.

Edit: sorry I think everyone was on the same page already after re-reading the comments

@acolombier
Copy link
Member

I have started with a draft PR. It would be great if you guys could have a quick look and let me know if it still lines up with what we all had in mind.

@JoergAtGithub
Copy link
Member

I collected some links to screenshots to show how this feature looks in other DJ software:

VirtualDJ:
www.virtualdj.com/manuals/hardware/pioneer/ddj1000/settings.html

RekordBox:
https://forums.pioneerdj.com/hc/user_images/cmLioAjWFKUnNr1ENIgxzQ.jpeg

TraktorPro:
https://www.dj-lab.de/wp-content/uploads/2014/11/S8-Bild-13.jpg
https://support.native-instruments.com/hc/article_attachments/360016228818/Tp3_calibration.PNG

@acolombier
Copy link
Member

acolombier commented Feb 24, 2023

Thanks @JoergAtGithub. Do you think the suggested UI above isn't sufficient? Or is this purely for reference, potentially used when the QML refactor comes in?

@JoergAtGithub
Copy link
Member

It's intended for reference.

I don't think, that complex formatting is needed here. IMHO it would be nice to have the following two simple formating elements:

  • Sections with a title
  • Something to display multiple options in a row e.g.
<row>
   <option>
   </option>
   <option>
   </option>
</row>

@ronso0
Copy link
Member

ronso0 commented Feb 24, 2023

I imagine the on-the-fly LED brightness slider like in Traktor is a nice feature.

@acolombier
Copy link
Member

acolombier commented Feb 25, 2023

@JoergAtGithub I think it sounds good, but we would have to be careful for people not to abuse them: the risk being someone designing their mapping setting on a massive monitor and it breaking up for users on smaller setup.

We could force these row and group to use Flow-like layouts under the hood, but then we come back to the fact that it may not be best to do something so advance UI-wise with the big refactoring coming in.

For the time being, I have implemented some layering information that allows you to do what you've requested. Let me know if it is sufficient.

image

Here is the used mapping
<?xml version='1.0' encoding='utf-8'?>
<MixxxControllerPreset mixxxVersion="2.4.0" schemaVersion="1">
     <info>
        <name>Dummy Device Test Mapping</name>
        <author>acolombier</author>
        <description>HID Mapping virtual test device</description>
        <manual>test_dumy_hid</manual>
        <devices>
            <product protocol="hid" vendor_id="0x1234" product_id="0x5678" />
        </devices>
    </info>
    <settings>
        <row>
            <option 
                variable="myFactor" 
                type="integer" 
                min="1" 
                max="1000" 
                step="10" 
                default="100"
                label="My dummy factor"  />
            <option 
                variable="myOtherFactor" 
                type="real" 
                precision="2"
                min="0" 
                max="1" 
                step="0.05" 
                default="0.15"
                label="My other factor">
                <description>
                    This factor is useful for one thing that you definitely need.
                </description>
            </option>
        </row>
        <group label="Beta feature">
            <option 
                variable="myToggle" 
                type="boolean" 
                default="false"
                label="Enable beta">
                <description>
                    It include many things, you should try it.
                </description>
            </option>
            <option 
                variable="myOptionList" 
                type="enum" 
                label="My list of option">
                <value label="A" default="true">a</value>
                <value label="B">b</value>
                <value label="C">c</value>
                <description>
                    This list define how A will interact with the rest of the letters.
                </description>
            </option>
            <row>
                <option 
                    variable="myOptionList1" 
                    type="enum" 
                    label="My list of option for one">
                    <value label="A" default="true">a</value>
                    <value label="B">b</value>
                    <value label="C">c</value>
                    <description>
                        This list define how one will interact.
                    </description>
                </option>
                <option 
                    variable="myOptionList2" 
                    type="enum" 
                    label="My list of option for two">
                    <value label="A" default="true">a</value>
                    <value label="B">b</value>
                    <value label="C">c</value>
                    <description>
                        This list define how two will interact.
                    </description>
                </option>
            </row>
        </group>
    </settings>
    <controller id="Dummy">
        <scriptfiles>
            <file filename="Test-HID-Dummy.js" functionprefix="Dummy"/>
        </scriptfiles>
    </controller>
</MixxxControllerPreset>

@Swiftb0y @daschuer It would be great to have your thoughts on this extra feature too.

@daschuer
Copy link
Member

IMHO the key is to start simple, while having advanced features in mind to not make them hard or impossible.

@JoergAtGithub
Copy link
Member

For the time being, I have implemented some layering information that allows you to do what you've requested. Let me know if it is sufficient.

This looks very prommissing! But I would suggest to consider the following limitations:

  • Allow only one label/description per row (which should be left of the options and should have a fixed witdh for an aligned look)
  • Make the use of groups mandatory (for a more organized look)

Than we would've all layout options used in this TraktorPro example: https://www.dj-lab.de/wp-content/uploads/2014/11/S8-Bild-13.jpg

@acolombier
Copy link
Member

For anyone interested, discussion continued on Zulip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants