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 * Makes qt (Qt GUI) the current scheme
77 * and returns it. Subsequent GUI object calls
78 * to GUI are delegated to qt.
80 * @return the current (qt) scheme
87 * Changes the current scheme and returns it.
89 * @param id (Symbol) the identifier of the scheme to
90 * use, such as returned by calling
92 * @return the new current scheme
95 var newScheme = schemes[ id.asSymbol ];
96 if( newScheme.notNil, {
99 ("GUI.fromID : The GUI scheme '" ++ id ++ "' is not installed\n" ++
100 "The current scheme is still '" ++ if( scheme.notNil, { scheme.id }) ++ "'!").warn;
106 * Returns the current scheme. This
107 * is useful for objects that, upon instantiation,
108 * wish to store the then-current scheme, so as
109 * to be able to consistently use the same scheme
110 * in future method calls.
112 * Note: the caller shouldn't make any assumptions about
113 * the nature (the class) of the returned object, so that
114 * the actual implementation (an Event) may change in the future.
116 * @return the current scheme
123 * Returns the scheme for a given identifier.
124 * Does not switch the current scheme.
126 * @param id (Symbol) the identifier of the scheme to
127 * retrieve, such as returned by calling
129 * @return the scheme for the given id or nil
132 ^schemes[ id.asSymbol ];
136 * Changes the current scheme.
138 * @param aScheme the scheme to use as current scheme
145 * Executes a function body, temporarily
146 * setting the current GUI scheme. This is usefull inside
147 * view's action functions in order to make this function
148 * use the GUI scheme that was originally used for the
149 * view of the action, even if the scheme has been switched meanwhile.
151 * @param scheme the scheme to use during the function execution
152 * @param func (Function) a body to execute
153 * @return the result of the function
155 *use { arg aScheme, func;
158 ^func.protect({ scheme = recent });
162 * Same as 'use' but using a scheme's id as first argument
164 * @param id the id of the scheme to use during the function execution
165 * @param func (Function) a body to execute
166 * @return the result of the function
168 *useID { arg id, func;
169 ^this.use( schemes[ id.asSymbol ], func );
173 * Registers a new scheme. This is typically called
174 * by external libraries in their startup procedure.
175 * If a scheme with the same identifier (scheme.id)
176 * exists, it is overwritten.
178 * @param aScheme the scheme to add
181 schemes.put( aScheme.id, aScheme );
182 if( scheme.isNil, { // first registration = first default kit
185 scheme = schemes[ scheme.id ]; // in case we are updating an existing scheme
190 * All method calls are mapped to the current
191 * scheme, so that for example GUI.button can be used
192 * and is delegated to the button association of the
195 *doesNotUnderstand { arg selector ... args;
196 if ( scheme.notNil ){
197 ^scheme.performList( selector, args );
199 ("No GUI scheme active: " + selector + args ).warn;
204 * Add skins : GUI.skins.put(skinName,( fontSpecs: etc. ) )
205 * then set that as default here.
206 * Note that if you wanted to do this in an *initClass that the scheme and GUI must be initialized
207 * and the scheme must be created in CocoaGUI.initClass (class varies on platform) so you cannot
208 * explicitly init that class by name since it varies across platforms. so you can't really setSkin
209 * in an initClass. Your initClass method could do StartUp.add { GUI.setSkin(...) };
211 *setSkin { arg skinName;
212 skin = skins[skinName];
213 scheme.font.new(*GUI.skin.fontSpecs).setDefault;