5 // a Window with a FlowView on it
6 // it also manages onClose handlers for use by ObjectGui's MVC model,
9 var <>isClosed=false,boundsWereExplicit=false,<>onClose;
13 *new { arg title,bounds,margin,background,scroll=true,front=true;
14 ^super.new.init(title,bounds,margin,background,scroll,front)
17 init { arg title,bounds,argMargin,background,argScroll=true,front=true;
20 boundsWereExplicit = true;
21 bounds = bounds.asRect
23 bounds = GUI.window.screenBounds.insetAll(10,20,0,25)
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)})
31 if(background.notNil,{
32 window.view.background_(background);
35 view = FlowView.new( window, window.view.bounds.insetAll(4,4,0,0) );
36 view.decorator.margin_(argMargin ?? {GUI.skin.margin});
38 if(front,{ window.front });
40 *on { arg window,bounds,margin,background;
41 ^super.new.initOn(window,bounds,margin,background)
43 initOn { arg argWindow,bounds,argMargin,background;
45 view = FlowView.new(window,bounds);
47 view.decorator.margin_(argMargin);
51 asView { ^this.view.asView }
52 asFlowView { arg bounds;
59 bounds { ^this.view.bounds }
63 asPageLayout { arg name,bounds;
65 ^this.class.new(name,bounds)
73 indentedRemaining { ^this.view.indentedRemaining }
74 *guify { arg parent,title,width,height,background;
76 this.new(title,width,height,background: background )
80 // act like a GUI window
81 checkNotClosed { ^isClosed.not }
91 close { // called when the GUI.window closes
94 autoRemoves.do({ arg updater; updater.remove(false) });
98 NotificationCenter.notify(window,\didClose);
105 hr { arg color,height=8,borderStyle=1;
111 first = this.window.views.at(index);
112 if(first.notNil,{first.focus });
115 background_ { arg c; this.view.background_(c) }
117 removeOnClose { arg dependant;
118 autoRemoves = autoRemoves.add(dependant);
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,{
132 window.setInnerExtent(wbw,wbh);
134 if(center and: {window.respondsTo(\setTopLeftBounds)}) {
135 // this should be a window method
136 fs = GUI.window.screenBounds;
138 // bounds are inaccurate until the end of the code cycle/refresh
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);
148 // center it horizontally
149 wb.left = (fs.width - wbw) / 2;
150 window.setTopLeftBounds(wb);
157 window.bounds = GUI.window.screenBounds.insetAll(10,20,0,25);
162 flow { arg func,bounds;
163 ^this.view.flow(func,bounds)
165 vert { arg func,bounds,spacing;
166 ^this.view.vert(func,bounds,spacing)
168 horz { arg func,bounds,spacing;
169 ^this.view.horz(func,bounds,spacing)
171 comp { arg func,bounds;
172 ^this.view.comp(func,bounds)
174 scroll { arg ... args;
175 ^this.view.performList(\scroll,args)