Dynamic graphic user interfaces

julien breval's icon

julien breval

4月 22 2011 | 12:38 午前

Hello,

What is the best solution for getting a tab graphic control in Max? I mean, something like the tabs in Google Chrome.

For example, take a patch that can be divided in 3 parts: "sequencer", "instrument", "effects". Each has a dedicated graphic user interface, and only one is displayed at a given time. For displaying the "sequencer" interface, you click on a tab or a button labelled "show sequencer" (same for "instrument" and "effects").

What is the clean way for doing this in Max?

Cheers,
Julien

Peter Nyboer's icon

Peter Nyboer

4月 22 2011 | 12:51 午前

Max Patch
Copy patch and select New From Clipboard in Max.

try this.

Luke Hall's icon

Luke Hall

4月 22 2011 | 3:56 午前

Or just look in the "more" subpatch of the [bpatcher] help file.

julien breval's icon

julien breval

4月 22 2011 | 12:23 午後

Thanks for your suggestions.

They work correctly, but I was talking about big interface panels (say 1024x768), and I can have many of them (up to about 10 maybe) so the bpatcher-based solutions are quite difficult to use in this case. Moreover some of my interfaces already contain a bpatcher and I have not tested bpatcher nesting in Max.

Alternatively, the bpatcher could embed different patches dynamically, but it would be problematic for implementing the patch-level preset system (classic pattrstorage + autopattr stuff), and I prefer to have all the patch in a single file so that everything is loaded when the patch is opened.

---

Currently I am using the following workaround:

1. The main patch is a horizontal narrow window, situated at the top of the screen.

2 Each interface is a big window that is displayed below the main patch window.

3. The main patch window contains buttons for loading the interface windows (loading one of them also closes the others).

4. All window open in presentation mode with "Fixed Initial Window Location" set to the proper value. The OS window decorations (bar, close button, menu, etc) are disabled (message "window notitle" to [thispatcher], and I use the patch with Max Runtime so that the Max low toolbar is not displayed either.
As the window decorations are taken in account when positioning the windows with "Fixed Initial Window Location", it's a pain to implement but finally I made a patch template that works.
It's certainly beautiful and useable, but for sure it will not display exactly the same way when using another computer because the window decorations will not have the same size :(

Best,
Julien

Chris Muir's icon

Chris Muir

4月 22 2011 | 5:10 午後

You can nest bpatchers. In my Gyre program, I have a bunch of note twisters at the top of the window that get swapped around by using a custom tab control. Basically, each twister is its own bpatcher. All the twisters then get included into a scroller bpatcher. The scroller bpatcher gets inserted at the top level. The scroller bpatcher takes messages from the top level about which pane should be shown, and scrolls to that position. Each of the twister bpatchers knows when it is selected, and enables output.

Tj Shredder's icon

Tj Shredder

4月 23 2011 | 5:13 午前

There are some examples in the collection of devices which come in MaxForLive.
I would place each UI into its own bpatcher, and place them on top of each other. Then show/hide them according to the tabs.
I found the bpatcher offset method always bad, as it forces you to a positioning logic which is most likely non intuitive and against the programming logic. Hiding has a simple clarity thanks to the presentation mode...
You could also try fullscreen mode, which should work the same in different OSes and screen sizes. You could even adapt the UI to the screen size.
But I would not like it as a user, I definitely prefer applications which do not take over my computer...;-)

julien breval's icon

julien breval

4月 25 2011 | 12:02 午前

Thanks for your answers.

Chris:
I have a quick question about preset saving in Gyre.
Can you save the state of a graphic control directly in the Master preset system, even if this control is loaded into a bpatcher?
Or does it require to use a sub-preset system for each patch that you load into a bpatcher?

Stefan:
Same question actually.

---

In my current patch template, any control (of any subpatch/window) can either be saved:

* directly in the master preset
* in a "local" preset (and local preset numbers are saved in the master preset)

I would like to keep this functionality but cannot find a solution when using bpatchers (either tiled or nested, it's not the problem in this case).

I do use bpatchers for loading abstractions that have a GUI, but in this case they always have a "local" preset system.
If I want the same GUI to be saved in the master preset system, I paste all the controls directly at the main patch level instead of loading the abstraction into a bpatcher.
I am using both these methods depending on the context (generally speaking, I would use local presets only for subsystems or modules that are likely to have the same presets in most tracks, say velocity curve module for example).

Best
Julien

Chris Muir's icon

Chris Muir

4月 25 2011 | 2:29 午前

If the bpatcher has a scripting name, and has pattr or autopattr stuff in it, it will be visible to the pattr system at the upper level.

I have a mix of local and global preset saving. In reality, things get saved at the top level no matter what, even if there's local storage, too. The local level has a library of local presets, but the current local state also gets stored at the top level when a preset is stored there. This does mean that the local storage always changes when the top level preset changes, but that's more or less what I want. In my ideal world, just the address of the local storage would be stashed at the top level, but this is really only a storage efficiency concern.

julien breval's icon

julien breval

5月 01 2011 | 5:00 午後

Thanks everybody, I have finally found a solution using bpatchers and full screen mode.

The only problem I have is that I cannot show or hide a bpatcher.
All bpatchers have the same size and are placed at the same position in presentation mode. Depending on the selected view (using tabs) I would like to show the right bpatcher and hide the others.

Officially, sending "presentation 1" or "presentation 0" to the bpatcher's leftmost inlet should work, but in practice this does not work, or I missed something. Same for the "hidden" message.

Both messages work correctly with other objects though.

I was working on OSX, will try it on Windows just now, maybe it works better.

So, how do you show or hide a bpatcher?

Julien

julien breval's icon

julien breval

5月 01 2011 | 5:36 午後

fixed it!
"script hide bpatcherScriptingName" or "script show bpatcherScriptingName" work with bpatcher

I just wonder why you can still send "presentation $1" to a bpatcher

Chris Muir's icon

Chris Muir

5月 01 2011 | 5:51 午後

Attached is an example of how I'm doing it with nested bpatchers.

2167.BPScroller.zip
zip
julien breval's icon

julien breval

5月 01 2011 | 10:11 午後

Thanks for your example Chris. It is similar to the one shown in the bpatcher help patch, though yours is much cleaner.

Actually, the patches I am programming use large bpatchers (1070 x 780 in presentation). A single screen is too small for displaying many things, moreover I don't like tiny graphic controls, especially on my 13' laptop. This is why I use several views in parallel, that I launch with tab buttons. Most patches will have 5 to 10 views, perhaps more in some cases. You can really think of it as Google Chrome or Firefox, albeit with a static tab count for each patch. Also, I chose to stack the tabs vertically, at the left border of the window.

This is why the bpatcher offset technique is difficult to use for me (a 10700 pixel wide patcher would be quite impractical to edit). So finally I made a "main" patch that contains as many bpatchers as there are views. Each bpatcher loads a specific "view" patch. In presentation mode, the bpatchers are tiled but only one is shown at a time, using "script hide X" or "script show X" messages.

Of course the views can contain other bpatchers as nesting works indeed.

Thanks to your explanations I could finally make a preset system with:
> a main preset system that saves everything
> local presets, but they don't interact with the main preset system

This is not a Max-based audio software, but a template for making a specific patch for each song.
Actually it is part of a slightly more complex architecture, with a host patch that can launch "track" (or "song") patches. I also made some "generic" abstractions (hence the local presets) that can be instantiated in track patches.

It displays identically on Windows and OSX. When I have a new desktop, the screen resolution will be different but I guess I can stretch the Max widgets automatically, using the built-in zoom.

There is only one problem I could not resolve:
All this system works in fullscreen mode. Suppose you have 2 patches opened in full screen mode. Patch 1 has a button for bringing Patch 2 to focus, and Patch 2 has a button for bringing Patch 1 to focus. It works, but on OSX you can see a horizontal stripe of desktop at the top of the screen, and this stripe has the same size as the OSX menu bar. When switching between both patches using the keyboard shortcut (Command-` on my computer), it works properly.
Not tested on Windows yet

Best,
Julien