deprecate SCViewHolder-layRight
[supercollider.git] / SCClassLibrary / Common / GUI / GUI.sc
blobd685f36a48fa9ef93b9d23a673f8fd0368dc85f4
1 /**
2  *      Factory abstraction for all GUI related core classes.
3  *      Each GUI kit is described by a scheme that maps class names
4  *      to actual classes.
5  *
6  *      See the help file for details. The default
7  *      scheme is cocoa.
8  *
9  *      Changelog:
10  *              - jrh added makeGUI
11  *              - sciss added add, set, get, use, useID
12  *
13  *      @version        0.16, 10-Apr-07
14  */
15 GUI {
16         classvar <scheme, <schemes, <skin, <skins;
18         *new { arg key; ^scheme.perform( key )}
20         *makeGUI { arg key, args, properties;
21                 var meth, class;
22                 class = scheme.at(key);
23                 if(properties.notNil) {
24                         meth = class.class.findMethod(\new);
25                         if(meth.notNil) {
26                                 meth.argNames.drop(args.size).do { |key| args = args ++ properties[key] }
27                         }
28                 };
29                 meth.argNames.postln;
30                 args.postln;
31                 ^class.new(*args)
32         }
34         *initClass {
35                 skins = (
36                         default: (
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,
43                                 gap:                    0 @ 0,
44                                 margin:                 2@2,
45                                 buttonHeight:   16
46                         )
47                 );
49                 skin            = skins.default;
50                 schemes = IdentityDictionary.new;
51         }
53         /**
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.
57          *
58          *      @return the current (cocoa) scheme
59          */
60         *cocoa {
61                 ^this.fromID( \cocoa );
62         }
64         /**
65          *      Makes Swing (Java GUI) the current scheme
66          *      and returns it. Subsequent GUI object calls
67          *      to GUI are delegated to swing.
68          *
69          *      @return the current (swing) scheme
70          */
71         *swing {
72                 ^this.fromID( \swing );
73         }
75         /**
76         *  Makes qt (Qt GUI) the current scheme
77         *  and returns it. Subsequent GUI object calls
78         *  to GUI are delegated to qt.
79         *
80         *  @return the current (qt) scheme
81         */
82         *qt {
83                 ^this.fromID( \qt );
84         }
86         /**
87          *      Changes the current scheme and returns it.
88          *
89          *      @param  id              (Symbol) the identifier of the scheme to
90          *                                      use, such as returned by calling
91          *                                      aScheme.id
92          *      @return the new current scheme
93          */
94         *fromID { arg id;
95                 var newScheme = schemes[ id.asSymbol ];
96                 if( newScheme.notNil, {
97                         scheme = newScheme;
98                 }, {
99                         ("GUI.fromID : The GUI scheme '" ++ id ++ "' is not installed\n" ++
100                          "The current scheme is still '" ++ if( scheme.notNil, { scheme.id }) ++ "'!").warn;
101                 });
102                 ^scheme;
103         }
105         /**
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.
111          *
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.
115          *
116          *      @return the current scheme
117          */
118         *current {
119                 ^scheme;
120         }
122         /**
123          *      Returns the scheme for a given identifier.
124          *      Does not switch the current scheme.
125          *
126          *      @param  id              (Symbol) the identifier of the scheme to
127          *                                      retrieve, such as returned by calling
128          *                                      aScheme.id
129          *      @return the scheme for the given id or nil
130          */
131         *get { arg id;
132                 ^schemes[ id.asSymbol ];
133         }
135         /**
136          *      Changes the current scheme.
137          *
138          *      @param  aScheme the scheme to use as current scheme
139          */
140         *set { arg aScheme;
141                 scheme = aScheme;
142         }
144         /**
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.
150          *
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
154          */
155         *use { arg aScheme, func;
156                 var recent      = scheme;
157                 scheme          = aScheme;
158                 ^func.protect({ scheme = recent });
159         }
161         /**
162          *      Same as 'use' but using a scheme's id as first argument
163          *
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
167          */
168         *useID { arg id, func;
169                 ^this.use( schemes[ id.asSymbol ], func );
170         }
172         /**
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.
177          *
178          *      @param  aScheme the scheme to add
179          */
180         *add { arg aScheme;
181                 schemes.put( aScheme.id, aScheme );
182                 if( scheme.isNil, {                             // first registration = first default kit
183                         scheme = aScheme;
184                 }, {
185                         scheme = schemes[ scheme.id ];  // in case we are updating an existing scheme
186                 });
187         }
189         /**
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
193          *      current scheme.
194          */
195         *doesNotUnderstand { arg selector ... args;
196                 if ( scheme.notNil ){
197                         ^scheme.performList( selector, args );
198                 }{
199                         ("No GUI scheme active: " + selector + args ).warn;
200                 }
201         }
203         /**
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(...) };
210          */
211         *setSkin { arg skinName;
212                 skin = skins[skinName];
213                 scheme.font.new(*GUI.skin.fontSpecs).setDefault;
214         }