1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
ObjectGui : SCViewHolder {
/*
this is a controller class:
it creates the views and implements the relationship between them and the model
model: the object for which this is a graphical user interface
view: this.view is the flow view (aka the arg layout) that is passed to guiBody
individual views/widgets are placed in it and their actions talk to either this object or the model
*/
var <model,<dragSource;
guiBody { arg layout,bounds ... args;
/* implement this method in your gui subclass */
// if your model implement guiBody then call that
// this is a lazy way to write simple guis for simple objects
// where model/gui code separation is not especially important
// and where the controller class doesn't need to maintain any state or vars
if(model.respondsTo(\guiBody) and: {model.isKindOf(ObjectGui).not},{
model.guiBody(layout,bounds,*args)
})
}
*new { arg model;
var new;
new = super.new;
new.model_(model);
^new
}
gui { arg parent, bounds ... args;
var layout;
layout=this.guify(parent,bounds);
layout.flow({ arg layout;
this.view = layout;
this.writeName(layout);
this.performList(\guiBody,[layout,bounds] ++ args);
},bounds).background_(this.background);
//if you created it, front it
if(parent.isNil,{
layout.resizeToFit(true,true);
layout.front;
});
}
guify { arg parent,bounds,title;
// converts the parent to a FlowView or compatible object
// thus creating a window from nil if needed
// registers to remove self as dependent on model if window closes
if(bounds.notNil,{
bounds = bounds.asRect;
});
if(parent.isNil,{
parent = PageLayout(title ?? {model.asString.copyRange(0,50)},bounds,front:false);
},{
parent = parent.asPageLayout(bounds);
});
// i am not really a view in the hierarchy
parent.removeOnClose(this);
^parent
}
model_ { |newModel|
if(model.notNil,{ // a view has its model swapped with another
model.removeDependant(this);
model = newModel;
model.addDependant(this);
this.update;
},{
model = newModel;
model.addDependant(this);
})
}
viewDidClose {
model.removeDependant(this);
model = nil;
super.viewDidClose;
}
background { ^Color.clear }
writeName { |layout|
this.prWriteName(layout,model.asString)
}
prWriteName { arg layout,name;
var string,font;
font = GUI.font.new(*GUI.skin.fontSpecs);
string = " " ++ (name);
if(string.size > 40,{
string = string.copyRange(0,40) ++ "...";
});
dragSource = GUI.dragSource.new(layout,Rect(0,0,(string.bounds(font).width + 10).max(70),GUI.skin.buttonHeight))
.stringColor_(Color.new255(70, 130, 200))
.font_(font)
.background_(Color.white)
.align_(\left)
.beginDragAction_({ model })
.object_(string);
}
}
|