scide: implement selectionLength for openDocument
[supercollider.git] / HelpSource / Classes / ObjectGui.schelp
blob8a80fc16b0fd677458bc07be7825e065b37e9443
1 CLASS:: ObjectGui
2 summary:: Controller class for MVC architecture, superclass for all XYZGui classes
3 related:: Reference/gui
4 categories:: GUI
6 DESCRIPTION::
7 In the MVC architecture this is the Controller, which creates Views for manipulating the properties of your Model, and receives messages from the View and enacts the changes on the Model.
9 Each class specifies its Gui class via the guiClass method.
11 The default guiClass for an Object is ObjectGui.  So if a class does not implement guiClass at all, then at least there is a default ObjectGui that will display the name.
13 Many subclasses overide the guiClass method to specify a different class, one that subclasses ObjectGui.
15 It is the simplest display, it is just the object asString.
17 The .gui method is called on your model:
19 code::
20 // standard usage
21 theModel.gui( parent, bounds )
23 // this results in these steps:
24 guiClass = theModel.guiClass;
25 gui = guiClass.new( theModel );
26 gui.gui( parent, bounds );
29 In addition to those steps the model/gui dependencies are managed, defaults (nil parent or nil bounds) are managed and when the window or parent view is closed then dependencies are safely managed.
32 CLASSMETHODS::
34 METHOD:: new
35 Create a gui controller object but does not yet create the views / window.  Call .gui to create the views.
37 argument:: model
38 The model is the object that the GUI is a graphical interface for.
40 returns:: the ObjectGui or subclass object
43 INSTANCEMETHODS::
45 METHOD:: guiBody
46 When implementing subclasses this is the primary and often the only method that needs to be implemented.  The ObjectGui parent class takes care of setting up all windows and dependencies and then the guiBody method adds views to the layout.  It is normal to declare instance variables in the ObjectGui subclass that are used to store the widgets so they can be updated later.
48 argument:: layout
49 Usually a FlowView : a parent view with a FlowLayout to add views to.
51 argument:: bounds
52 nil or a Rect.
54 argument:: ... args
55 More args may be passed here.
57 returns:: this
59 METHOD:: update
60 When the model is changed and the .changed method is called then .update is called on all dependants including this gui object.  Update the views you have placed in the guiBody.
62 argument:: changed
63 The model.  Within your gui class the model is already in the instance variable 'model'.
65 argument:: changer
66 Depends on the conventions of how .changed was called.  If an object called someModel.changed(this) then it is supplying itself as the changer and will be passed through here.  Sometimes a flag is used: someModel.changed('points') and the gui may know of and particpate in that convention.  Sometimes no changer is passed in.
69 METHOD:: gui
70 The standard method to create a view / window.  Usually you call yourModel.gui(parent,bounds) and this creates the gui (of the related ObjectGui subclass) and then theObjectGui.gui(parent,bounds) is called, forwarding the arguments.  So this method is what receives the forwarded (parent,bounds) from the initial call to theModel.gui(parent,bounds). Usually you do not call this manually and would avoid reimplementing it.
72 argument:: parent
73 parent view : nil, a Window, a FlowView or any other usable container view.
75 argument:: bounds
76 nil or a Rect.  The default of nil will offer the entire bounds to the guiBody method and then shrink the view size afterwards to the exact size of the contents that were actually added.
78 argument::  ... args
79 More args may be passed into theModel.gui(parent,bounds,anArg,moreArg) and will be forwarded to guiBody.
81 returns:: this
83 METHOD:: guify
84 This converts a supplied parent and bounds into a usable parent container view on a window.  It creates a window if needed.
86 argument:: parent
87 parent view or nil
89 argument:: bounds
90 desired bounds or nil
92 argument:: title
93 window title IF a new window is being created.  if there is a parent view then title is ignored.
95 returns:: converted parent
98 METHOD:: model
99 set a new model. This allows to use a single gui and dynamically swap in a different model of the same class.  The old model releases the gui as a dependant and the new model adds the gui as a dependent.  Then the views are updated.
101 argument:: newModel
102 The new object
104 returns:: (returnvalue)
106 METHOD:: dragSource
107 The default implementation of writeName places a nameplate on the gui that is draggable.  This method is an accessor for that dragSource object.
109 returns:: a GUi.dragSource
111 METHOD:: viewDidClose
112 This is called when the parent view closes. It releases dependants.
114 returns:: this
116 METHOD:: background
117 Each ObjectGui subclass may implement a default background color.
119 returns:: a color
121 METHOD:: writeName
122 ObjectGui by default makes a nameplate with the name of the model.  Implement this in subclasses if a different name style or no nameplate is desired.  Note: this may change in the near future.  So many classes overide this to shut off the name.
124 argument:: layout
125 The layout to place the nameplate on.  Probably the same as is being passed to guiBody
127 METHOD:: prWriteName
128 The default write name implementation.  You could call this from a subclass if you are primarily implementing writeName to customize what name is shown or to add other items to that area.
130 argument:: layout
131 the layout
133 argument:: name
134 the string to display
137 EXAMPLES::
139 code::
141 YourSimpleGuiClass : ObjectGui {
143         guiBody { arg layout;
144         
145                 // we refer to the model and
146                 // access its variable howFast.
147                 // if its a simple number, it will display
148                 // using the default ObjectGui class, which
149                 // will simply show its value as a string.
150                 model.howFast.gui(layout);
151         }
155 // more complex
156 YourGuiClass : ObjectGui {
157         
158         var numberEditor;
159         
160         //for example
161         guiBody { arg layout;
162                 var r;
163                 // the object you are making a gui for is referred to as the model
164                 
165                 // display some param on screen.
166                 // here we assume that someParam is something that
167                 //  has a suitable gui class
168                 // implemented, or that the default ObjectGui is sufficient.
169                 model.someParam.gui(layout);
170                 
171                 // using non 'gui' objects
172                 r = layout.layRight(300,300); // allocate yourself some space
173                 Button(layout.win,r)
174                         .action_({ arg butt;
175                                 model.goApeShit;
176                         });
177                 
178                 // note: NumberEditor is a cruciallib class
179                 // which is itself a model (its an editor of a value)
180                 // and has its own gui class that creates and manages the NumberBox view
181                 numberEditor = NumberEditor(model.howFast,[0,100])
182                         .action_({ arg val; 
183                                 model.howFast = val; 
184                                 model.changed(this); 
185                                 // tell the model that this gui changed it
186                         });
187                 numberEditor.gui(layout);
188         }
189         
190         // your gui object will have update called any time the .changed message
191         // is sent to your model
192         update { arg changed,changer;
193         
194                 if(changer !== this,{ 
195                         /* if it is this gui object that changed the value
196                                 using the numberEditor, then we already have a correct
197                                 display and don't need to waste cpu to update it.
198                                 if anyone else changed anything about the model,
199                                 we will update ourselves here.
200                         */
201                         numberEditor.value = model.howFast;
202                         /*
203                                 note that 
204                                         numberEditor.value = model.howFast;
205                                 is passive, and does not fire the numberEditor's action.        
207                                 numberEditor.activeValue = model.howFast
208                                 would fire the action as well, resulting in a loop that would
209                                 probably crash your machine.
210                         */
211                 }
212         }