SwingOSC – Java-based GUI classes

last mod: 01-Aug-08 sciss

known issues / todo
File->CloseDoesn't work for some reason with internal frames
OS X Screen MenuModifications to the menu root are not reflected in the menu "prototype" visible when no window is open

 

JSCMenuRoot, JSCMenuGroup, JSCMenuItem, JSCMenuCheckItem, JSCMenuSeparator

Menu bar management. The root handle of a menu bar is represented by JSCMenuRoot. Currently, only one global, application wide menu root is supported, but future versions might provide a menu root per window.

To create a menu, an instance of JSCMenuGroup is created with the menu root as its parent argument. The group is then populated with items by instantiating the JSCMenuItem class with the group as the parent argument. To create submenus, groups can be nested. To enhance visual clarity, separators can be inserted through the JSCMenuSeparator class.

Note that on Mac OS X the menu bar appears as the screen title bar. However it is only visible if at least one SwingOSC window is opened.

JSCMenuRoot

	JSCMenuRoot.new( <server> )
	

Note that only one instance per server can be created, if you try to instantiate the root again, the same object will be returned.

    r = JSCMenuRoot.new;

JSCMenuGroup

	JSCMenuGroup.new( <parent>, <name>, <index> )
	

 

Example:

(
    r = JSCMenuRoot.new;
    a = JSCMenuGroup( r, "Utilities" );   // add to the end of the root
    b = JSCMenuGroup( r, "Demos" );       // add to the end of the root
    c = JSCMenuGroup( a, "Server" );      // a submenu of "Utilities"
    
    // depending on the OS, the window bar not visible
    // unless there is at least one window
    if( JSCWindow.allWindows.size == 0, { JSCWindow( "Test" ).front });
)

JSCMenuItem

	JSCMenuGroup.new( <parent>, <name>, <index> )
	

The arguments have the same meaning as with JSCMenuGroup. An item cannot have submenus. Instead is represents an action to be performed upon selection. Similar to a JSCView, you can register a Function to be invoked when the item is selected, using the setter method action_( <func> ).

Example:

(
    // we want this item to appear before the "Server"
    // submenu, hence we use an index of 0
    d = JSCMenuItem( a, "Browse UGens", 0 );
    d.action = { arg item; UGen.browse };
    e = JSCMenuItem( a, "Inspect Server", 1 );
    e.action = { arg item; Server.default.inspect };
    // now inside the "Server" submenu
    f = JSCMenuItem( c, "Query All Nodes" ).action_({ Server.default.queryAllNodes });
    // and one for the "Demo" menu
    h = JSCMenuItem( b, "Analog Bubbles" ).action_({
        {
	       CombN.ar( SinOsc.ar( LFSaw.kr( 0.4, 0, 24, LFSaw.kr([ 8, 7.23 ], 0, 3, 80 )).midicps, 0, 0.04 ),
                      0.2, 0.2, 4 );
        }.play;
    });
)

name_

Some of the properties of the nodes can be modified. For example, a groups or item's name, using the name_( <newName> ) setter method:

    a.name = "Tools";

enabled_

Also groups and items can be disabled so they appear greyed out and cannot be selected. The corresponding setter method is enabled_( <bool> ). In the following example, an observer is set up that enables and disables the scsynth based menu nodes depending on whether scsynth is running or not:

(
    UpdateListener.newFor( Server.default, { arg upd, s;
        c.enabled = s.serverRunning;
        h.enabled = s.serverRunning;
    }, \serverRunning ).update( Server.default, \serverRunning );
)

shortcut_

For quicker access, keyboard shortcuts can be assigned, using the shortcut_( <description> ) setter method. The argument is a human readable string following the format <modifiers>* <key>, where:


The key code name consists either of a normal signal alphanumerical character, e.g. "Q", "W", "E", "R", "T", etc., or a any of the VK_... as defined in java.awt.KeyEvent, e.g. "BACK_SLASH", "DOWN", "ESCAPE", etc.

Important: To facilitate cross-platform operation, the meaning of "meta" and "meta2" depends on the platform: On OS X, "meta" corresponds to the Command-Key, on Windows and Linux this maps to the Control-Key, so it always corresponds to the commonly used menu shortcut modifier. On the other hand, "meta2" maps to the Control-Key on OS X, and on Windows and Linux is realized as a combination of Control and Alt. Hence you can use "meta2" as a secondary menu modifier that will not conflict with the primary modifier. If possible, avoid the use of "control" and "alt", since they may interfere with the other modifiers.

Example:

    d.shortcut = "meta U";
    e.shortcut = "alt shift I";
    h.shortcut = "meta2 B";

Removing Nodes

Nodes can be removed from the menu bar by calling the remove method:

    h.remove;

JSCMenuCheckItem

The JSCMenuCheckItem extends the functionality of JSCMenuItem by having a checkmark icon that gets toggled on and off. The state of the checkmark can be queried using the selected method, or programmatically set using selected_( <bool> ).

In the following example, the checkmark reflects whether the Moto-Rev synth is actually playing:

(
    var synth;
    h = JSCMenuCheckItem( b, "Moto Rev" )
        .shortcut_( "meta2 M" )
        .enabled_( Server.default.serverRunning )
        .action_({ arg item;
            synth.release; synth = nil;
            if( item.selected, {
                synth = {
                    RLPF.ar( LFPulse.ar( SinOsc.kr( 0.2, 0, 10, 21 ), 0.1 ), 100, 0.1 ).clip2( 0.4 );
                }.play.register;
                UpdateListener.newFor( synth, { arg upd, n;
                    if( synth == n, { synth = nil; item.selected = false });
                }, \n_end );
            });
        });
)

JSCMenuSeparator

Finally, separator lines can be inserted for increased visual clarity. The constructor is JSCMenuSeparator<parent><index> ). Here we insert a separator before the "Server" submenu:

    JSCMenuSeparator( a, 2 );