deprecate SCViewHolder-layRight
[supercollider.git] / SCClassLibrary / Common / GUI / guicrucial / PageLayout.sc
blobdc5c52d8c1d957a6a0a5aaded0f80c4ec14cae87
3 PageLayout  {
5         // a Window with a FlowView on it
6         // it also manages onClose handlers for use by ObjectGui's MVC model,
8         var <window,<view;
9         var <>isClosed=false,boundsWereExplicit=false,<>onClose;
11         var autoRemoves;
13         *new { arg title,bounds,margin,background,scroll=true,front=true;
14                 ^super.new.init(title,bounds,margin,background,scroll,front)
15         }
17         init { arg title,bounds,argMargin,background,argScroll=true,front=true;
18                 var w,v;
19                 if(bounds.notNil,{
20                         boundsWereExplicit = true;
21                         bounds = bounds.asRect
22                 },{
23                         bounds = GUI.window.screenBounds.insetAll(10,20,0,25)
24                 });
25                 window = GUI.window.new("< " ++ title.asString ++ " >",bounds, border: true, scroll: argScroll );
26                 window.onClose_({ this.close });
27                 if(background.isKindOf(Boolean),{  // bwcompat : metal=true/false
28                         background = background.if(nil,{Color(0.88, 0.94, 0.87, 1)})
29                 });
31                 if(background.notNil,{
32                         window.view.background_(background);
33                 });
34                 isClosed = false;
35                 view =  FlowView.new( window, window.view.bounds.insetAll(4,4,0,0)  );
36                 view.decorator.margin_(argMargin ?? {GUI.skin.margin});
37                 autoRemoves = [];
38                 if(front,{ window.front });
39         }
40         *on { arg window,bounds,margin,background;
41                 ^super.new.initOn(window,bounds,margin,background)
42         }
43         initOn { arg argWindow,bounds,argMargin,background;
44                 window = argWindow;
45                 view = FlowView.new(window,bounds);
46                 if(argMargin.notNil,{
47                         view.decorator.margin_(argMargin);
48                 });
49                 autoRemoves = [];
50         }
51         asView { ^this.view.asView }
52         asFlowView { arg bounds;
53                 ^if(bounds.notNil,{
54                         FlowView(this,bounds)
55                 },{
56                         this.view
57                 })
58         }
59         bounds { ^this.view.bounds }
60         add { arg view;
61                 this.view.add(view);
62         }
63         asPageLayout { arg name,bounds;
64                 if(isClosed,{
65                         ^this.class.new(name,bounds)
66                 },{
67                         ^this
68                 })
69         }
70         startRow {
71                 this.view.startRow;
72         }
73         indentedRemaining { ^this.view.indentedRemaining }
74         *guify { arg parent,title,width,height,background;
75                 ^parent ?? {
76                         this.new(title,width,height,background: background )
77                 }
78         }
80         // act like a GUI window
81         checkNotClosed { ^isClosed.not }
82         front {
83                 window.front
84         }
85         hide {
86                 window.alpha = 0.0;
87         }
88         show {
89                 window.alpha = 1.0;
90         }
91         close { // called when the GUI.window closes
92                 if(isClosed.not,{
93                         isClosed = true;
94                         autoRemoves.do({ arg updater; updater.remove(false) });
95                         autoRemoves = nil;
96                         window.close;
97                         onClose.value;
98                         NotificationCenter.notify(window,\didClose);
99                         window=view=nil;
100                 });
101         }
102         refresh {
103                 window.refresh
104         }
105         hr { arg color,height=8,borderStyle=1;
106                 this.view.hr;
107         }
109         focus { arg index=0;
110                 var first;
111                 first = this.window.views.at(index);
112                 if(first.notNil,{first.focus });
113         }
115         background_ { arg c; this.view.background_(c) }
117         removeOnClose { arg dependant;
118                 autoRemoves = autoRemoves.add(dependant);
119         }
121         resizeToFit { arg reflow=false,center=false;
122                 var fs, b,wb,wbw,wbh;
124                 b = this.view.resizeToFit(reflow);
125                 if(GUI.scheme.id == \cocoa,{
126                         wbw = b.width + 4;
127                         wbh = b.height + 17;
128                 },{
129                         wbw = b.width + 11;
130                         wbh = b.height + 15;
131                 });
132                 window.setInnerExtent(wbw,wbh);
134                 if(center and: {window.respondsTo(\setTopLeftBounds)}) {
135                         // this should be a window method
136                         fs = GUI.window.screenBounds;
137                         wb = window.bounds;
138                         // bounds are inaccurate until the end of the code cycle/refresh
139                         wb.width = wbw;
140                         wb.height = wbh;
141                         // if height is less than 60% of full screen
142                         if(wbh <= (fs.height * 0.6),{
143                                 // then move its top to be level at golden ratio
144                                 wb.top = fs.height - (fs.height / 1.6180339887);
145                         },{
146                                 wb.top = 0;
147                         });
148                         // center it horizontally
149                         wb.left = (fs.width - wbw) / 2;
150                         window.setTopLeftBounds(wb);
151                 }
152         }
153         reflowAll {
154                 view.reflowAll;
155         }
156         fullScreen {
157                 window.bounds = GUI.window.screenBounds.insetAll(10,20,0,25);
158         }
159         endFullScreen {
160                 window.endFullScreen
161         }
162         flow { arg func,bounds;
163                 ^this.view.flow(func,bounds)
164         }
165         vert { arg func,bounds,spacing;
166                 ^this.view.vert(func,bounds,spacing)
167         }
168         horz { arg func,bounds,spacing;
169                 ^this.view.horz(func,bounds,spacing)
170         }
171         comp { arg func,bounds;
172                 ^this.view.comp(func,bounds)
173         }
174         scroll { arg ... args;
175                 ^this.view.performList(\scroll,args)
176         }