{
   "labels" : [
      "gui",
      "class",
      "launcher",
      "tool",
      "extension",
      "helper"
   ],
   "code" : "//Blog post describing this class: http://schemawound.tumblr.com/post/22662485300/supercollider-slimlauncher\r\n\r\n/*\r\nSlimLauncher\r\nby Jonathan Siemasko\r\nContact: schemawound@yahoo.com\r\nHomepage: http://newkirk.biz/schemawound/\r\nBlog: http://schemawound.tumblr.com/\r\nSoundcloud: http://soundcloud.com/schemawound\r\nTwitter: https://twitter.com/Schemawound\r\n\r\nThis is a launcher for frequently used windows.\r\n\r\nuserButtonsDef - expects an array of events with the following fields:\r\n\tbuttonName: Display name for the button\r\n\talwaysOnTop: true/false - window should always be on top?\r\n\tbounds: Bounds for the window.  This is something you will want to change based on the resolution of your machine and your personal preferences. In order \r\n\t\tto find the proper values set the windows the way you like them and hit the POS button.  This will post the current bounds for each window to the post \r\n\t\twindow.  You can then edit the code with these values to set it for the future. (NOTE: ONLY WORKS FOR WINDOWS, NOT VIEWS)\r\n\tshowButton: The function that should be called to show your button.  Should return a window or a view for other functions to work correctly.\r\n\r\nlauncherBounds: The bounds for the launcher window\r\n\r\nshowPositionButton: true/false - display position button.  This is used for setting up the position of your buttons.  See the description of windowsBounds above.\r\n\t\r\nshowGlobalButtons: This is a pair of buttons to show/hide all windows.  \t\r\n\r\nEXAMPLE:\r\n\tvar userButtons = [\r\n\t\t(buttonName: \"Server\",\t\talwaysOnTop: true,\tbounds: Rect(1285, 490, 290, 100),\tshowButton: {\r\n\t\t\tvar window = Server.internal.makeWindow; \r\n\t\t\twindow.window\r\n\t\t}),\r\n\t\t(buttonName: \"Scope\", \t\talwaysOnTop: true,\tbounds: Rect(1285, 203, 290, 250), \tshowButton: {\r\n\t\t\tvar window = Server.internal.scope; \r\n\t\t\twindow.window\r\n\t\t}),\r\n\t\t(buttonName: \"Freq\", \t\talwaysOnTop: true,\tbounds: Rect(1610, 78, 712, 250), \tshowButton: {\r\n\t\t\tvar window = FreqScope.new; \r\n\t\t\twindow.window\r\n\t\t}),\r\n\t\t(buttonName: \"Class\", \t\talwaysOnTop: true,\tbounds: Rect(1608, 366, 712, 697), \tshowButton: {\r\n\t\t\tvar window; \r\n\t\t\tObject.browse; \r\n\t\t\tWindow.allWindows.do{|win| \r\n\t\t\t\tif(win.name == \"class browser\", {window = win})\r\n\t\t\t}; \r\n\t\t\twindow\r\n\t\t}),\r\n\t\t(buttonName: \"SynthDef\",\talwaysOnTop: true,\tbounds: Rect(1608, 366, 712, 697), \tshowButton: {\r\n\t\t\tvar window;\r\n\t\t\tSynthDescLib.global.read; \r\n\t\t\tSynthDescLib.global.browse; \r\n\t\t\tWindow.allWindows.do{|win| \r\n\t\t\t\tif(win.name == \"SynthDef browser\", {window = win})\r\n\t\t\t};\r\n\t\t\twindow\r\n\t\t}),\r\n\t\t(buttonName: \"SCCode\",\t\talwaysOnTop: true,\tbounds: Rect(2335, 135, 535, 986), \tshowButton: {\r\n\t\t\tWebView()\r\n\t\t\t\t.bounds_(Rect(2335, 135, 535, 986))\r\n\t\t\t\t.url_(\"http://doc.sccode.org/Search.html\")\r\n\t\t\t\t.front\r\n\t\t})\r\n\t];\r\n\tSlimLauncher.show(userButtons, Rect(1409, 923, 182, 205), false, true);\r\n*/\r\n\r\nSlimLauncher{\r\n\tclassvar userButtons;\r\n\r\n\t*show{|userButtonsDef, launcherBounds, showPositionButton = true, showGlobalButtons = true|\r\n\t\t//----------VARIABLES----------\r\n\t\tvar posButton, hideAllButton, showAllButton, nonUserButtonLayout, launcherWindow;\r\n\t\tuserButtons = userButtonsDef;\r\n\t\t//----------CREATE WINDOW----------\r\n\t\tlauncherWindow = Window(\"Launcher\", launcherBounds)\r\n\t\t\t.layout_(VLayout())\r\n\t\t\t.alwaysOnTop_(true)\r\n\t\t\t.onClose_({userButtons.do({|buttonDef| this.closeWindow(buttonDef)})})\r\n\t\t\t.front;  //Create Window\r\n\t\t//----------ADD BUTTONS----------\r\n\t\tuserButtons.do({|ev, index| ev.button = this.createButton(ev); launcherWindow.layout.add(ev.button)}); \r\n\t\t//----------NON-USER BUTTONs----------\r\n\t\tposButton = Button()\r\n\t\t\t.states_([[\"Pos\", Color.white, Color.grey]])\r\n\t\t\t.action_({Window.allWindows.do { |win| [win.name.asCompileString, win.bounds].postln}});\r\n\t\thideAllButton = Button()\r\n\t\t\t.states_([[\"Hide All\", Color.white, Color.grey]])\r\n\t\t\t.action_({userButtons.do({|buttonDef| \r\n\t\t\t\tif(buttonDef.window != nil, {buttonDef.button.valueAction = 0})})});\r\n\t\tshowAllButton = Button()\r\n\t\t\t.states_([[\"Show All\", Color.white, Color.grey]])\r\n\t\t\t.action_({userButtons.do({|buttonDef| \r\n\t\t\t\tif(buttonDef.window == nil, {buttonDef.button.valueAction = 1})})});\r\n\t\tnonUserButtonLayout = HLayout();\r\n\t\tif(showPositionButton == true, {nonUserButtonLayout.add(posButton)});\r\n\t\tif(showGlobalButtons == true, {\r\n\t\t\tnonUserButtonLayout.add(hideAllButton);\r\n\t\t\tnonUserButtonLayout.add(showAllButton);\r\n\t\t});\r\n\t\tif(showPositionButton == true || showGlobalButtons == true, {launcherWindow.layout.add(nonUserButtonLayout)});\r\n\t}\r\n\t\r\n\t*closeWindow{|buttonDef| if (buttonDef.window != nil, {buttonDef.button.value = 0; buttonDef.window.close; buttonDef.window = nil})}\r\n\r\n\t*setWindowOptions{|window, bounds, alwaysOnTop| window.bounds_(bounds).alwaysOnTop_(alwaysOnTop).userCanClose_(false)}\r\n\r\n\t*createButton{|buttonDef| //take an event and make a button out of it\r\n\t\tvar\tstates = [[buttonDef.buttonName, Color.white, Color.grey],[buttonDef.buttonName, Color.white, Color.red]];\r\n\t\tvar action = {|butt| if(butt.value == 1, \r\n\t\t\t{\r\n\t\t\t\tbuttonDef.window = buttonDef.showButton;\r\n\t\t\t\tbuttonDef.bound.postln;\r\n\t\t\t\tthis.setWindowOptions(buttonDef.window, buttonDef.bounds, buttonDef.alwaysOnTop);\r\n\t\t\t}, \r\n\t\t\t{this.closeWindow(buttonDef)}\r\n\t\t)};\r\n\t\t^Button().states_(states).action_(action)\r\n\t}\r\n}",
   "is_private" : null,
   "id" : "1-4GX",
   "name" : "SlimLauncher 1.0",
   "author" : "Schemawound",
   "ancestor_list" : [],
   "description" : "Blog post describing this class:\r\nhttp://schemawound.tumblr.com/post/22662485300/supercollider-slimlauncher"
}
