2 * Factory abstraction for all GUI related core classes.
3 * Each GUI kit is described by a scheme that maps class names
6 * See the help file for details. The default
11 * - sciss added add, set, get, use, useID
13 * @version 0.16, 10-Apr-07
16 classvar <scheme, <schemes, <skin, <skins;
18 *new { arg key; ^scheme.perform( key )}
20 *makeGUI { arg key, args, properties;
22 class = scheme.at(key);
23 if(properties.notNil) {
24 meth = class.class.findMethod(\new);
26 meth.argNames.drop(args.size).do { |key| args = args ++ properties[key] }
37 fontSpecs: ["Helvetica", 10],
38 fontColor: Color.black,
39 background: Color(0.8, 0.85, 0.7, 0.5),
40 foreground: Color.grey(0.95),
41 onColor: Color(0.5, 1, 0.5),
42 offColor: Color.clear,
50 schemes = IdentityDictionary.new;
54 * Makes Cocoa (Mac OS X GUI) the current scheme
55 * and returns it. Subsequent GUI object calls
56 * to GUI are delegated to cocoa.
58 * @return the current (cocoa) scheme
61 ^this.fromID( \cocoa );
65 * Makes Swing (Java GUI) the current scheme
66 * and returns it. Subsequent GUI object calls
67 * to GUI are delegated to swing.
69 * @return the current (swing) scheme
72 ^this.fromID( \swing );
76 * Changes the current scheme and returns it.
78 * @param id (Symbol) the identifier of the scheme to
79 * use, such as returned by calling
81 * @return the new current scheme
84 var newScheme = schemes[ id.asSymbol ];
85 if( newScheme.notNil, {
88 ("GUI.fromID : The GUI scheme '" ++ id ++ "' is not installed\n" ++
89 "The current scheme is still '" ++ if( scheme.notNil, { scheme.id }) ++ "'!").warn;
95 * Returns the current scheme. This
96 * is useful for objects that, upon instantiation,
97 * wish to store the then-current scheme, so as
98 * to be able to consistently use the same scheme
99 * in future method calls.
101 * Note: the caller shouldn't make any assumptions about
102 * the nature (the class) of the returned object, so that
103 * the actual implementation (an Event) may change in the future.
105 * @return the current scheme
112 * Returns the scheme for a given identifier.
113 * Does not switch the current scheme.
115 * @param id (Symbol) the identifier of the scheme to
116 * retrieve, such as returned by calling
118 * @return the scheme for the given id or nil
121 ^schemes[ id.asSymbol ];
125 * Changes the current scheme.
127 * @param aScheme the scheme to use as current scheme
134 * Executes a function body, temporarily
135 * setting the current GUI scheme. This is usefull inside
136 * view's action functions in order to make this function
137 * use the GUI scheme that was originally used for the
138 * view of the action, even if the scheme has been switched meanwhile.
140 * @param scheme the scheme to use during the function execution
141 * @param func (Function) a body to execute
142 * @return the result of the function
144 *use { arg aScheme, func;
147 ^func.protect({ scheme = recent });
151 * Same as 'use' but using a scheme's id as first argument
153 * @param id the id of the scheme to use during the function execution
154 * @param func (Function) a body to execute
155 * @return the result of the function
157 *useID { arg id, func;
158 ^this.use( schemes[ id.asSymbol ], func );
162 * Registers a new scheme. This is typically called
163 * by external libraries in their startup procedure.
164 * If a scheme with the same identifier (scheme.id)
165 * exists, it is overwritten.
167 * @param aScheme the scheme to add
170 schemes.put( aScheme.id, aScheme );
171 if( scheme.isNil, { // first registration = first default kit
174 scheme = schemes[ scheme.id ]; // in case we are updating an existing scheme
179 * All method calls are mapped to the current
180 * scheme, so that for example GUI.button can be used
181 * and is delegated to the button association of the
184 *doesNotUnderstand { arg selector ... args;
185 ^scheme.performList( selector, args );
189 * Add skins : GUI.skins.put(skinName,( fontSpecs: etc. ) )
190 * then set that as default here.
191 * Note that if you wanted to do this in an *initClass that the scheme and GUI must be initialized
192 * and the scheme must be created in CocoaGUI.initClass (class varies on platform) so you cannot
193 * explicitly init that class by name since it varies across platforms. so you can't really setSkin
194 * in an initClass. Your initClass method could do StartUp.add { GUI.setSkin(...) };
196 *setSkin { arg skinName;
197 skin = skins[skinName];
198 scheme.font.new(*GUI.skin.fontSpecs).setDefault;