deprecate SCViewHolder-layRight
[supercollider.git] / SCClassLibrary / Common / GUI / Base / EZgui.sc
blob86e34b06128ca9fd3d9fb37a7563ac16401b8902
1 EZGui{ // an abstract class
2         var <>labelView, <widget, <view, gap, popUp=false, innerBounds,
3         <>action,   <layout, <value, labelSize, <alwaysOnTop=false, margin;
4         var scaler=1;  //for swing compatibility
5         // general stuff for all EZ classes. override as needed
6         visible { ^view.getProperty(\visible) }
7         visible_ { |bool|  view.setProperty(\visible,bool)  }
9         enabled {  ^view.enabled }
10         enabled_ { |bool| view.enabled_(bool) }
12         remove { view.remove}
14         alwaysOnTop_{arg bool;
15                 alwaysOnTop=bool;
16                 popUp.if{this.window.alwaysOnTop=alwaysOnTop};
18         }
19         font_{ arg font;
20                 labelView.notNil.if{labelView.font=font};
21                 widget.font=font;
22         }
24         window{^ popUp.if{view.parent.findWindow};}
26         onClose{^ popUp.if{this.window.onClose}{view.onClose};}
28         onClose_{|func| popUp.if{this.window.onClose_(func)}{view.onClose_(func)};}
31         //// value stuff. override as needed
34         value_{|val| value=val; widget.value_(val)}
36         valueAction_{|val| this.value_(val); this.doAction}
38         doAction {this.action.value(this)}
40         bounds{^view.bounds}
41         ///////// private methods. You can still override these in subclasses
43         prSubViewBounds{arg rect, hasLabel;
44                 var widgetBounds,labelBounds,tmp;
45                 hasLabel.not.if{gap=0@0; labelSize=0@0};
47                 if (layout==\vert)
48                         { widgetBounds= Rect(  // fit to full width
49                                         0,
50                                         labelSize.y+gap.y,
51                                         rect.width,
52                                         rect.height-labelSize.y-gap.y
53                                         );
54                         labelBounds=Rect(0,0,widgetBounds.width,labelSize.y);//fit to full width
55                 }{
56                         widgetBounds= Rect(   // fit to full remaining
57                                         labelSize.x+gap.x,
58                                         0,
59                                         rect.width-labelSize.x-gap.x,
60                                         rect.height
61                                         );
62                         labelBounds=Rect(0,0, labelSize.x ,widgetBounds.height )}; // to left
64                 ^[labelBounds, widgetBounds].collect{arg v; v.moveBy(margin.x,margin.y)}
65         }
68         prMakeView{arg parentView,bounds; // return a container, or a popUpWindow with a container
69                 var w, winBounds, view, extraHeight=24;
70                 (GUI.id==\swing).if{extraHeight=36};
71                 parentView.isNil.if{
72                         popUp=true;
73                                 // if bounds is a point the place the window on screen
74                                 if (bounds.class==Point)
75                                         { bounds = bounds.x@max(bounds.y,bounds.y+extraHeight);// window minimum height;
76                                          winBounds=Rect(200, Window.screenBounds.height-bounds.y-100,
77                                                                 bounds.x,bounds.y)
78                                         }{// window minimum height;
79                                         winBounds = bounds.height_(max(bounds.height,bounds.height+extraHeight))
80                                         };
81                                 w = GUI.window.new("",winBounds).alwaysOnTop_(alwaysOnTop);
82                                 parentView=w.asView;
83                                 w.front;
84                                 bounds=bounds.asRect;
85                                 // inset the bounds to make a nice margin
86                                 bounds=Rect(4,4,bounds.width-8,bounds.height-extraHeight);
87                                 view=GUI.compositeView.new(parentView,bounds).resize_(2);
88                                 w.bounds=w.bounds; // swing needs this for some reason, or bounds are too high
90                 }{// normal parent view
91                         bounds=bounds.asRect;
92                         view=GUI.compositeView.new(parentView,bounds);
93                 };
95                 innerBounds=view.bounds.insetBy(margin.x,margin.y);
96         ^[view,bounds];
97         }
99         prMakeMarginGap{arg parentView, argMargin, argGap;
100                 //try to use the parent decorator gap
101                 var     decorator = parentView.asView.tryPerform(\decorator);
102                 argGap.isNil.if{
103                         gap = gap ? decorator.tryPerform(\gap).copy; // use copy to protect the parent gap
104                         gap = gap ? (2@2)}
105                         {gap=argGap};
107                 argMargin.isNil.if{margin=0@0}{margin=argMargin};
108         }
113 EZLists : EZGui{  // an abstract class
115         var <items, <>globalAction;
117         *new { arg parentView, bounds, label,items, globalAction, initVal=0,
118                         initAction=false, labelWidth,labelHeight=20, layout, gap, margin;
120                 ^super.new.init(parentView, bounds, label, items, globalAction, initVal,
121                         initAction, labelWidth,labelHeight,layout, gap, margin);
122                         }
124         init { arg parentView, bounds, label, argItems, argGlobalAction, initVal,
125                         initAction, labelWidth, labelHeight, layout,  argGap, argMargin;
127                 // try to use the parent decorator gap
128                 this.prMakeMarginGap(parentView, argMargin, argGap);
130                 // init the views (handled by subclasses)
131                 this.initViews(  parentView, bounds, label, labelWidth,labelHeight,layout );
133                 this.items=argItems ? [];
135                 globalAction=argGlobalAction;
137                 widget.action={arg obj;
138                         items.at(obj.value).value.value(this);
139                         globalAction.value(this);
140                         };
142                 this.value_(initVal);
144                 items.notNil.if{
145                         if(initAction){
146                                         items.at(initVal).value.value(this); // You must do this like this
147                                         globalAction.value(this);       // since listView's array is not accessible yet
148                                 };
149                         this.value_(initVal);
150                 };
152         }
154         initViews{}  // override this for your subclass views
156         value{ ^widget.value}
157         value_{|val| widget.value=val}
159         valueAction_{|val| widget.value_(val); this.doAction}
161         doAction {widget.doAction;}
163         items_{ arg assocArray;
164                 assocArray = assocArray.collect({ |it| if (it.isKindOf(Association), { it }, { it -> nil }) });
165                 items=assocArray;
166                 widget.items=assocArray.collect({|item| item.key});
167         }
169         item {^items.at(this.value).key}
170         itemFunc {^items.at(this.value).value}
172         addItem{arg name, action;
173                 this.insertItem(nil, name, action);
174         }
176         insertItem{ arg index, name, action;
177                 var temp;
178                 index = index ? items.size;
179                 this.items=items.insert(index, name.asSymbol -> action);
180          }
182         removeItemAt{ arg index;
183                 var temp;
184                 items.removeAt(index);
185                 this.items_(items)
187         }
189         replaceItemAt{ arg index, name, action;
190                 var temp;
191                 name = name ? items.at(index).key;
192                 action = action ? items.at(index).value;
193                 this.removeItemAt(index);
194                 this.insertItem(index, name, action);
196         }