4 select view(s) and apple-drag between windows to copy
5 select view(s) and apple-drag inside a window, or press c, to copy
9 sclang integration by jan trutzschler
13 var <window,<userview,>parent,isSelected=false;
15 var selection,<selectedViews,views;
17 var <gridStep = 10,<gridOn = false,dragging,indent,multipleDragBy;
19 var resizeHandles,resizeFixed, dropX, dropY;
22 *new { |window, bounds| ^super.new.init(window, bounds) }
28 views = window.view.children ? Array.new;
30 window.constructionView = userview;
42 if(gridOn, { window.refresh })
46 var w = window.bounds.width, h = window.bounds.height;
48 userview !? { userview.remove };
49 userview = SCConstructionView(window,Rect(0,0,w,h)).resize_(5);
51 userview.beginDragAction = {
54 if ( selectedViews.size > 0,{
55 #classes, rects = flop(selectedViews.collect({ |view|
56 [ view.class, view.bounds ]
59 SCIBMultipleDrag(classes,rects)
63 userview.keyDownAction = { |v,c,m,u| this.panelSelect.keyDown(c,u) };
64 userview.mouseDownAction = { |v,x,y| this.panelSelect.mouseDown(x,y) };
65 userview.mouseUpAction = { |v,x,y| this.panelSelect.mouseUp };
67 userview.mouseOverAction = { |v,x,y| dropX = x; dropY = y };
69 userview.canReceiveDragHandler = {
70 SCView.currentDrag.isKindOf( SCIBDrag )
73 userview.receiveDragHandler = {
74 var addedViews = Array.new;
76 SCView.currentDrag.do({ |class, rect|
77 rect = rect.moveBy( dropX, dropY );
78 addedViews = addedViews.add( class.paletteExample(window,rect).enabled_(false) );
81 views = views.addAll( addedViews );
84 selectedViews = addedViews;
85 indent = dropX@dropY - views.last.bounds.origin;
87 this.makeUserview.updateResizeHandles;
93 userview.mouseMoveAction = { |v,x,y| this.drag(x,y) };
100 userview.drawFunc = {
104 b = window.view.bounds;
108 Color.yellow(1,0.4).set;
111 (n-1).do({ |i| i=i+1*gridStep;
112 Pen.moveTo(0@i).lineTo(w@i).stroke;
116 (n-1).do({ |i| i=i+1*gridStep;
117 Pen.moveTo(i@0).lineTo(i@h).stroke;
124 Pen.width_(4).strokeRect(window.bounds.moveTo(0,0));
127 selectedViews.do({ |v|
128 Pen.strokeRect(v.bounds)
132 resizeHandles.do({ |r|
136 if(selection.notNil, {
137 Pen.strokeRect(selection.rect)
148 updateResizeHandles { var r,d=4;
149 resizeHandles = if( selectedViews.size == 1,{
150 r = selectedViews.first.bounds;
151 [ r.leftTop, r.rightTop, r.rightBottom, r.leftBottom ]
152 .collect({ |center| Rect.aboutPoint(center,d,d) })
160 { parent.panelSelect(this) })
164 setResizeFixed { |resizeHandle|
165 var r = selectedViews.first.bounds,i = resizeHandles.indexOf(resizeHandle);
166 resizeFixed=r.perform([ \rightBottom, \leftBottom, \leftTop, \rightTop ][i])
175 if( resizeHandles.notNil and: {
176 (handle = resizeHandles.detect({ |h| h.containsPoint(p) }) ).notNil
179 this.setResizeFixed(handle)
183 view = this.viewContainingPoint(p);
185 dragging = view.notNil;
188 indent = p - view.bounds.origin;
190 if( (selectedViews.size > 1) and:
191 { selectedViews.includes(view) },
193 multipleDragBy = view
196 multipleDragBy = nil;
197 selectedViews = [ view ]
201 selection = SCIBAreaSelection(p)
204 // this.debug(selectedViews);
205 this.updateResizeHandles
212 if( resizeFixed.isNil,
214 if(multipleDragBy.notNil,
216 f = p - ( multipleDragBy.bounds.origin + indent );
218 selectedViews.do({ |v|
219 this.quantSetBounds(v,v.bounds.moveBy(f.x,f.y))
222 view = selectedViews.first;
223 this.quantSetBounds(view,view.bounds.moveToPoint(p-indent));
225 this.updateResizeHandles
228 if(gridOn,{ p = p.round(gridStep) });
229 selectedViews.first.bounds = Rect.fromPoints(p,resizeFixed);
230 this.updateResizeHandles
234 selection.mouseDrag(p);
235 selectedViews = views.select({ |view|
236 selection.selects(view.bounds)
243 if(selection.notNil,{
244 selection = nil; window.refresh
253 if(selectedViews.isEmpty.not,{
254 selectedViews.do({ |v|
255 views.remove(v.remove);
259 this.updateResizeHandles
263 {(c==$c) or: (c==$C)},{
264 if(selectedViews.isEmpty.not,{
265 newViews=selectedViews.collect({ |v|
266 v.class.paletteExample(window,v.bounds.moveBy(40,40))
268 views=views++newViews;
269 selectedViews=newViews;
271 this.makeUserview.updateResizeHandles
277 quantSetBounds { |view,rect|
278 view.bounds=if(gridOn,
279 { rect.moveToPoint(rect.origin.round(gridStep)) },
284 viewContainingPoint { |point|
285 // this.debug(views);
287 if(view.bounds.containsPoint(point),
295 views.do({ |v| str = str ++ format("%.new(w,%);\n",v.class,v.bounds) });
296 ^format( "(\nvar w = SCWindow.new(\"\",%).front;\n%\n)",window.bounds,str )
304 var <window,viewPallatte,panels,selectedPanel, <gridStep=20, gridOn=false;
308 shared = SCIBToolboxWindow.new;
315 *new { ^super.new.init }
319 panel = SCIBPanelWindow.new(win).parent_(this);
320 win.bounds = win.bounds.moveTo(window.bounds.left+window.bounds.width,window.bounds.height);
321 // win.view.children.do{|it| it.enabled_(false)};
322 panels = panels.add(panel);
323 this.debug(this.gridStep);
324 panel.gridOn_(gridOn).gridStep_(this.gridStep);
328 var panel = SCIBPanelWindow.new(win).parent_(this), indx;
329 win.view.children.copy.do{|it|
331 if(it.isKindOf(SCConstructionView)){it.remove;}
333 indx = this.findPanelIndexForWindow(win);
335 panels.removeAt(indx);
339 findPanelIndexForWindow{|win|
341 if(it.window == win){^i}
346 enableGridWithSize{|flag, gridsize|
350 panel.gridOn_(gridOn).gridStep_(gridStep);
356 var vh = 24, vw = 260,gridNB,gridBut;
358 var height = 20 + 4 * (vh + 2) +2, os=0;
361 var funcButCol = Color.blue;
363 window = SCWindow("IB",Rect(50,800,vw+8,height)).front
364 .onClose_({shared=nil});
365 window.view.decorator = FlowLayout(window.view.bounds);
369 SCButton(window,Rect(2,os,vw,vh)).states_([["New Window",nil,funcButCol]])
370 .canFocus_(false).action = {
371 this.addWindow(SCWindow("pane",Rect(100,100,400,400)).front)
374 SCButton(window,Rect(2,os,vw,vh)).states_([ ["-> Code",nil,funcButCol]])
375 .canFocus_(false).action_{ if ( selectedPanel.notNil,
377 Document("window construction code", selectedPanel.asSCIBCompileString);
381 SCButton(window,Rect(2,os,vw,vh)).states_([ ["Toggle Edit",nil,funcButCol]])
382 .canFocus_(false).action = {
383 selectedPanel.window.toggleEditMode;
386 gridBut = SCButton(window,Rect(2,os,vw2-8,vh))
387 .canFocus_(false).action_{ |v|
388 gridNB.visible = v.value == 1;
389 this.enableGridWithSize(v.value == 1, gridNB.value);
392 .states_([["Q On",nil,funcButCol],["Q Off",nil,funcButCol]]);
394 gridNB = SCNumberBox(window,Rect(2+vw2,os,vw2,vh))
396 v.value = v.value.asInt.clip(3,40);
397 panels.do({ |panel| panel.gridStep = v.value })
399 .align_(\center).value_(10).visible_(false);
401 viewPallatte = SCIBViewPallatte(window,Rect(2, 2, vw, (height - window.view.decorator.top)));
405 panelSelect { |panel|
406 if( panel !== selectedPanel,{
407 if(selectedPanel.notNil,{ selectedPanel.deselect });
408 selectedPanel = panel
415 // classvar <viewList;
416 var showExamples = false;
418 *new { |window,rect,parent|
419 ^super.new.init(window,rect,parent)
422 init { |window,rect,parent|
423 var x = rect.top, y = rect.left;
424 var bW = rect.width, bH = rect.height, list, scroll;
426 list = SCView.allSubclasses.reject{|it|
427 (it.superclasses.indexOf(SCContainerView).notNil
428 or: (it.name === 'SCContainerView')
429 or: (it.name ==='SCStaticTextBase')
430 or: (it.name === 'SCSliderBase')
431 or: (it.name === 'SCControlView')
432 or: (it.name === 'SCDragView'))
434 scroll = SCScrollView(window, Rect(0,0,bW-2, bH-34))
436 scroll.decorator = FlowLayout(scroll.bounds.moveTo(0,0));
438 var drag = SCIBPallatteDrag(class,Rect(0,0,100,20));
439 SCDragSource(scroll,((bW*0.5)-12)@24)
440 .string_(class.asString).align_(\center).object_(drag);
443 class.paletteExample(scroll, Rect(0,0,(bW*0.5)-12,24));
445 "no paletteExample found".warn;
447 scroll.decorator.nextLine;
460 // SCMultiSliderView,
478 var click,round,<rect;
480 *new { |p,r| r !? { p = round(p,r) };
481 ^super.newCopyArgs(p,r).mouseDrag(p)
485 round !? { drag = round(drag,round) };
486 rect = Rect.fromPoints(click,drag)
490 ^rect.intersects(aRect)
497 SCIBMultipleDrag : SCIBDrag
499 var classes,rects,minX, minY;
501 *new { |classes, rects|
502 ^super.newCopyArgs( classes, rects ).init
509 if ( r.left < minX, { minX = r.left });
510 if ( r.top < minY, { minY = r.top })
517 classes.do({ |class,i|
518 func.( class, rects[ i ].moveBy( minX, minY ), i )
523 SCIBPallatteDrag : SCIBDrag
528 ^super.newCopyArgs( class, rect )
531 do { |func| func.(class,rect,0) }
533 asString { ^class.asString }