2 classvar <>allWindows, <currentFullScreen, <>initAction;
4 var dataptr, <name, <>onClose, <view, <userCanClose=true;
5 var <alwaysOnTop=false;
7 var <acceptsMouseOver=false;
9 var <acceptsClickThrough = true;
10 var <> toFrontAction, <> endFrontAction;
11 var <editable=false, <>constructionView;
12 var <currentSheet; // current modal sheet attached to this window, if it exists
15 ShutDown.add { this.closeAll };
18 *new { arg name = "panel", bounds, resizable = true, border = true, server, scroll = false;
19 ^super.new.initSCWindow(name, bounds, resizable, border, scroll)
21 // appmodal is a private flag used to disable the close button
22 initSCWindow { arg argName, argBounds, resizable, border, scroll, appmodal = false;
23 name = argName.asString;
24 argBounds = argBounds ?? {Rect(128, 64, 400, 400)};
25 allWindows = allWindows.add(this);
27 view = SCScrollTopView(nil, argBounds.moveTo(0,0));
29 view = SCTopView(nil, argBounds.moveTo(0,0));
31 this.prInit(name, argBounds, resizable, border, scroll, view, appmodal);
32 initAction.value(this);
36 add { arg aView; view.add(aView) }
38 addFlowLayout { |margin, gap|
39 view.decorator_( FlowLayout( view.bounds.moveTo(0,0), margin, gap ) );
45 list = allWindows.copy;
46 allWindows = Array.new(8);
47 list.do({ arg window; window.close; });
51 if (isClosed) { ^this };
56 onClose.value; // call user function
59 allWindows.remove(this);
62 addToOnClose { | function | onClose = onClose.addFunc(function) }
64 removeFromOnClose { | function | onClose = onClose.removeFunc(function) }
67 currentFullScreen.notNil.if({currentFullScreen.endFullScreen});
69 currentFullScreen = this;
73 currentFullScreen = nil;
77 _SCWindow_BeginFullScreen
81 _SCWindow_EndFullScreen
84 userCanClose_ { arg boo;
85 _SCWindow_SetShouldClose
88 acceptsMouseOver_{arg bool;
89 acceptsMouseOver = bool;
90 this.prSetAcceptMouseOver(bool);
97 alwaysOnTop_{|bool=true|
99 this.prSetAlwaysOnTop(bool);
102 prSetAlwaysOnTop{|boolean=true|
103 _SCWindow_AlwaysOnTop
106 acceptsClickThrough_{|boolean=true|
107 acceptsClickThrough = boolean;
108 this.prSetAcceptsClickThrough(boolean);
111 prSetAcceptsClickThrough{|boolean=true|
112 _SCWindow_AcceptsClickThrough
117 ^this.primitiveFailed
121 ^this.primitiveFailed
125 ^this.primitiveFailed
129 name = argName.asString;
130 this.prSetName(name);
132 // bounds are relative to the bottom left corner origin
133 bounds_ { arg argBounds;
134 this.prSetBounds(argBounds);
136 // set bounds relative to top left corner
137 setTopLeftBounds { |rect,menuSpacer=45|
139 // 45 is the height of the mac os menu
140 // if you are in full screen mode you would want to pass in 0
141 rect.top = SCWindow.screenBounds.height - rect.height - rect.top - menuSpacer;
144 setInnerExtent { arg w,h; // resize window keeping top left corner fixed
149 this.bounds = Rect(b.left,b.top + (b.height - h), w,h);
152 ^this.prGetBounds(Rect.new);
155 ^this.prGetScreenBounds(Rect.new);
160 if (dataptr.notNil, {
173 prInit { arg argName, argBounds, resizable, border, scroll, view, appmodal = false;
175 ^this.primitiveFailed
179 ^this.primitiveFailed
181 prSetName { arg argName;
183 ^this.primitiveFailed
185 prGetBounds { arg argBounds;
187 ^this.primitiveFailed
189 prSetBounds { arg argBounds;
191 ^this.primitiveFailed
193 prSetAcceptMouseOver{arg bool;
194 _SCWindow_SetAcceptMouseOver
195 ^this.primitiveFailed
197 *prGetScreenBounds { arg argBounds;
198 _SCWindow_GetScreenBounds
199 ^this.primitiveFailed
202 drawFunc.value(this);
206 toFrontAction.value(this);
210 endFrontAction.value(this);
215 editable = editable.not;
217 SCIBToolboxWindow.front.addWindow(this);
220 SCIBToolboxWindow.front.removeWindow(this);
223 setCurrentSheet {|sheet| currentSheet = sheet;}
227 w = SCWindow("View Palette", Rect(532, 64, 300, 320), scroll: true).front;
228 w.view.decorator = f = FlowLayout(w.view.bounds);
229 SCButton(w, 300@20).states_([ ["-> CODE"]])
230 .canFocus_(false).action_{
231 Document("window construction code", win.asConstructionCompileString);
233 w.view.decorator.nextLine;
234 // c = [SCSlider, SCRangeSlider, SC2DSlider, SCPopUpMenu, SCButton,
235 // SCNumberBox, SCMultiSliderView,
236 // SCStaticText, SCDragSource, SCDragSink, SCDragBoth,
238 c = SCView.allSubclasses.reject{|it|
239 (it.superclasses.indexOf(SCContainerView).notNil
240 or: (it.name === 'SCContainerView')
241 or: (it.name ==='SCStaticTextBase')
242 or: (it.name === 'SCSliderBase')
243 or: (it.name === 'SCControlView'))
248 n = SCDragSource(w, Rect(0, 0, 140, 24));
252 item.paletteExample(w, Rect(0,0,140,24));
254 "no paletteExample found".warn;
256 w.view.decorator.nextLine;
260 Document("window construction code", win.asConstructionCompileString);
267 storeArgs{^[name, this.bounds]}
268 storeModifiersOn{|stream|
273 SCAbstractModalWindow : SCWindow {
276 this.shouldNotImplement(thisMethod);
280 this.shouldNotImplement(thisMethod);
285 SCModalWindow : SCAbstractModalWindow {
289 *new { arg name = "panel", bounds, resizable = false, border = true, server, scroll = false;
290 // app modal flag is true
291 ^super.new(name, bounds, resizable, border, nil, scroll).setCurrent.runModal;
294 // override to set appmodal to true
295 initSCWindow {|argName, argBounds, resizable, border, scroll, appmodal|
296 ^super.initSCWindow(argName, argBounds !? {argBounds.asRect}, resizable, border, scroll, true);
302 setCurrent { current = this; }
306 ^this.primitiveFailed;
311 ^this.primitiveFailed;
314 closed { current = nil; super.closed }
318 SCModalSheet : SCAbstractModalWindow {
321 *new { arg window, bounds, resizable = false, border = true, server, scroll = false;
322 ^window.isClosed.not.if({
323 super.new("", bounds !? {bounds.asRect}, resizable, border, nil, scroll)
331 setCurrent { |window|
332 parentWindow = window;
333 parentWindow.setCurrentSheet(this);
337 _SCWindow_RunModalSheet
338 ^this.primitiveFailed;
342 _SCWindow_StopModalSheet
343 ^this.primitiveFailed;
346 closed { parentWindow.setCurrentSheet(nil); super.closed }