julian+alberto classlib merges for 3.4 (10125, 10130, 10133)
[supercollider.git] / common / build / SCClassLibrary / Common / GUI / Base / EZRangerSC.sc
blobb1677548a842d9ef63a8c489b2e792f1ef125a6c
2 EZRanger : EZGui {
4         var <rangeSlider, <hiBox,<loBox, <unitView, <>controlSpec,
5                  <>action,<lo, <hi, popUp=false, numSize,numberWidth,unitWidth;
6         var <>round = 0.001;
8         *new { arg parent, bounds, label, controlSpec, action, initVal,
9                         initAction=false, labelWidth=60, numberWidth=45,
10                         unitWidth=0, labelHeight=20,  layout=\horz, gap,margin;
12                 ^super.new.init(parent, bounds, label, controlSpec, action,
13                         initVal, initAction, labelWidth, numberWidth,
14                                 unitWidth, labelHeight, layout, gap, margin)
15         }
17         init { arg parentView, bounds, label, argControlSpec, argAction, initVal,
18                         initAction, labelWidth, argNumberWidth,argUnitWidth,
19                         labelHeight, argLayout, argGap,argMargin;
21                 var labelBounds, hiBounds,loBounds, unitBounds,rangerBounds;
22                 var numberStep;
24                 // Set Margin and Gap
25                 this.prMakeMarginGap(parentView, argMargin, argGap);
27                 unitWidth = argUnitWidth;
28                 numberWidth = argNumberWidth;
29                 layout=argLayout;
31                 bounds.isNil.if{bounds = 350@20};
33                 // if no parent, then pop up window
34                 # view,bounds = this.prMakeView( parentView,bounds);
36                 labelSize=labelWidth@labelHeight;
37                 numSize = numberWidth@labelHeight;
39                 // calcualate bounds
40                 # labelBounds,hiBounds,loBounds,rangerBounds, unitBounds
41                                 = this.prSubViewBounds(innerBounds, label.notNil, unitWidth>0);
43                 label.notNil.if{ //only add a label if desired
44                         labelView = GUI.staticText.new(view, labelBounds);
45                         labelView.string = label;
46                 };
48                 (unitWidth>0).if{ //only add a unitLabel if desired
49                         unitView = GUI.staticText.new(view, unitBounds);
50                 };
53                 loBox = GUI.numberBox.new(view, loBounds);
54                 rangeSlider = GUI.rangeSlider.new(view, rangerBounds);
55                 hiBox = GUI.numberBox.new(view, hiBounds);
57                 controlSpec = argControlSpec.asSpec;
58                 (unitWidth>0).if{unitView.string = " "++controlSpec.units.asString};
59                 action = argAction;
61                 loBox.action_({ |box| this.lo_(box.value).doAction; });
62                 rangeSlider.action_({ |sl|
63                                 this.lo_(controlSpec.map(sl.lo));
64                                 this.hi_(controlSpec.map(sl.hi));
65                                 this.doAction;
66                         });
67                 hiBox.action_({ |box| this.hi_(box.value).doAction; });
69                 if (initVal.notNil) { this.value_(initVal) };
70                 if (initAction) { this.doAction };
73 //              if (controlSpec.step != 0) {
74 //                      rangeSlider.step = (controlSpec.step / (controlSpec.maxval - controlSpec.minval));
75 //              };
77                 numberStep = controlSpec.step;
78                 if (numberStep == 0) {
79                         numberStep = controlSpec.guessNumberStep;
80                 }{
81                         // controlSpec wants a step, so zooming in with alt is disabled.
82                         hiBox.alt_scale = 1.0;
83                         loBox.alt_scale = 1.0;
84                         rangeSlider.alt_scale = 1.0;
85                 };
87                 hiBox.step=numberStep;
88                 loBox.step=numberStep;
89                 hiBox.scroll_step=numberStep;
90                 loBox.scroll_step=numberStep;
92                 rangeSlider.receiveDragHandler = { arg slider;
93                         slider.valueAction = controlSpec.unmap(GUI.view.currentDrag);
94                 };
96                 rangeSlider.beginDragAction = { arg slider;
97                         controlSpec.map(slider.value)
98                 };
100                 this.prSetViewParams;
102         }
104         doAction { action.value(this); }
105         
106         set { arg label, spec, argAction, initVal, initAction = false;
107                 labelView.notNil.if { labelView.string = label.asString };
108                 spec.notNil.if { controlSpec = spec.asSpec };
109                 argAction.notNil.if { action = argAction };
111                 initVal = initVal ? this.value ? controlSpec.default.dup(2);
113                 if (initAction) {
114                         this.valueAction_(initVal);
115                 }{
116                         this.value_(initVal);
117                 };
118         }
120         value { ^[lo, hi] }
121         value_ { |vals| this.lo_(vals[0]).hi_(vals[1]) }
122         valueAction_ { |vals| this.value_(vals).doAction }
124         lo_ { |val|
125                 lo = controlSpec.constrain(val);
126                 loBox.value_(lo.round(round));
127                 rangeSlider.lo_(controlSpec.unmap(lo));
128         }
130         hi_ { |val|
131                 hi = controlSpec.constrain(val);
132                 hiBox.value_(hi.round(round));
133                 rangeSlider.hi_(controlSpec.unmap(hi));
134         }
135         setColors{arg stringBackground, stringColor, sliderColor,  numBackground,numStringColor,
136                          numNormalColor, numTypingColor, knobColor,background ;
138                         stringBackground.notNil.if{
139                                 labelView.notNil.if{labelView.background_(stringBackground)};
140                                 unitView.notNil.if{unitView.background_(stringBackground)};};
141                         stringColor.notNil.if{
142                                 labelView.notNil.if{labelView.stringColor_(stringColor)};
143                                 unitView.notNil.if{unitView.stringColor_(stringColor)};};
144                         sliderColor.notNil.if{
145                                 rangeSlider.background_(sliderColor);};
146                         numBackground.notNil.if{
147                                 hiBox.background_(numBackground);
148                                 loBox.background_(numBackground);};
149                         numNormalColor.notNil.if{
150                                 hiBox.normalColor_(numNormalColor);
151                                 loBox.normalColor_(numNormalColor);};
152                         numTypingColor.notNil.if{
153                                 hiBox.typingColor_(numTypingColor);
154                                 loBox.typingColor_(numTypingColor);};
155                         numStringColor.notNil.if{
156                                 hiBox.stringColor_(numStringColor);
157                                 loBox.stringColor_(numStringColor);};
158                         knobColor.notNil.if{
159                                 rangeSlider.knobColor_(knobColor);};
160                         background.notNil.if{
161                                 view.background=background;};
162                         hiBox.refresh;
163         }
165         font_{ arg font;
167                         labelView.notNil.if{labelView.font=font};
168                         unitView.notNil.if{unitView.font=font};
169                         hiBox.font=font;
170                         loBox.font=font;
171         }
174         prSetViewParams{
176                 switch (layout,
177                 \line2, {
178                         labelView.notNil.if{
179                                 labelView.resize_(2);
180                                 unitView.notNil.if{unitView.resize_(3)};
181                                 hiBox.resize_(3);
182                                 loBox.resize_(3);
183                                 }{
184                                 unitView.notNil.if{
185                                         unitView.resize_(2).align_(\left)};
186                                 hiBox.resize_(1);
187                                 loBox.resize_(1);
188                                 };
189                         rangeSlider.resize_(5);
190                         popUp.if{view.resize_(2)};
191                 },
192                 \vert, {
193                         labelView.notNil.if{labelView.resize_(2)};
194                         unitView.notNil.if{unitView.resize_(8)};
195                         loBox.resize_(8);
196                         hiBox.resize_(2);
197                         rangeSlider.resize_(5);
198                         popUp.if{view.resize_(4)};
199                 },
200                 \horz, {
201                         labelView.notNil.if{labelView.resize_(4).align_(\right)};
202                         unitView.notNil.if{unitView.resize_(6)};
203                         loBox.resize_(4);
204                         hiBox.resize_(6);
205                         rangeSlider.resize_(5);
206                         popUp.if{view.resize_(2)};
207                 });
208         }
209         prSubViewBounds{arg rect, hasLabel, hasUnit;
210                 var hiBounds,loBounds,labelBounds,rangerBounds;
211                 var unitBounds, gap1, gap2, gap3,gap4, tmp, labelH, unitH;
212                 gap1 = gap.copy; // use copy to make sure these are unique
213                 gap2 = gap.copy; // since you later set the .x or .y
214                 gap3 = gap.copy;
215                 gap4 = gap.copy;
216                 labelH=labelSize.y;//  needed for \vert
217                 unitH=labelSize.y; //  needed for \vert
219                 switch (layout,
220                         \line2, {
221                                 hasLabel.not.if{ gap2 = 0@0; labelSize.x = 0 ;};
222                                 hasUnit.not.if{ gap4 = 0@0; unitWidth = 0};
223                                 hasLabel.if{ // with label
224                                         unitBounds = (unitWidth@labelSize.y)
225                                                 .asRect.left_(rect.width-unitWidth);// view to right
226                                         hiBounds = (numSize.x@labelSize.y)
227                                                 .asRect.left_(rect.width-unitBounds.width-numberWidth-gap4.x); // view to right
228                                         loBounds = (numSize.x@labelSize.y)
229                                                 .asRect.left_(rect.width-unitBounds.width-numberWidth
230                                                         -gap3.x-hiBounds.width-gap4.x); // view to right
231                                         labelBounds = (labelSize.x@labelSize.y)
232                                                 .asRect.width_(loBounds.left-gap2.x); //adjust width
233                                 }{ // no label
234                                 labelBounds = (0@labelSize.y).asRect; //just a dummy
235                                 loBounds = (numberWidth@labelSize.y).asRect; //view to left
236                                 hiBounds = (numberWidth@labelSize.y).asRect.moveTo(loBounds.width+gap3.x,0); //view to left
237                                 (unitWidth>0).if{
238                                         unitBounds = Rect.newSides (hiBounds.right+gap4.x,
239                                         0,rect.width, labelSize.y); //adjust width
240                                                 }{
241                                         unitBounds = Rect (0, 0,0,0); //no unitView
242                                                 };
244                                 };
245                                 rangerBounds = Rect(
246                                                 0,
247                                                 labelSize.y+gap1.y,
248                                                 rect.width,
249                                                 rect.height-numSize.y-gap1.y;
250                                                 );
251                                 },
253                          \vert, {
254                                 hasLabel.not.if{labelH=0; gap1.y=0};
255                                 labelBounds = (rect.width@labelH).asRect; // to top
256                                 hasUnit.not.if{unitH=0; gap4 = 0@0;};
257                                 unitBounds = (rect.width@unitH)
258                                         .asRect.top_(rect.height-unitH); // to bottom
259                                 hiBounds = (rect.width@labelSize.y)
260                                         .asRect.top_(labelBounds.height+gap1.y); // to bottom
261                                 loBounds = (rect.width@labelSize.y)
262                                         .asRect.top_(rect.height-unitBounds.height-numSize.y-gap4.y); // to bottom
263                                 rangerBounds = Rect.newSides(
264                                         0,
265                                         hiBounds.bottom+gap2.y,
266                                         rect.width,
267                                         loBounds.top-gap3.y
268                                         );
269                                 },
271                          \horz, {
272                                 hasLabel.not.if{ gap1 = 0@0; labelSize.x = 0 ;};
273                                 hasUnit.not.if{ gap4 = 0@0; unitWidth = 0};
274                                 labelSize.y=rect.height;
275                                 labelBounds = (labelSize.x@labelSize.y).asRect;
276                                 unitBounds = (unitWidth@labelSize.y).asRect.left_(rect.width-unitWidth);
277                                 loBounds = (numSize.x@labelSize.y).asRect
278                                         .left_(labelBounds.width+gap1.x);
279                                 hiBounds = (numSize.x@labelSize.y).asRect
280                                         .left_(rect.width-unitBounds.width-numSize.x-gap4.x);
281                                 rangerBounds  =  Rect.newSides(
282                                         loBounds.right+gap2.x , 0,
283                                         rect.width-hiBounds.width-unitBounds.width
284                                                 -gap3.x-gap4.x,
285                                         labelSize.y);
287                         });
290                 ^[labelBounds, hiBounds, loBounds, rangerBounds, unitBounds]
291                         .collect{arg v; v.moveBy(margin.x,margin.y)}
292         }