File: ObjectGui.sc

package info (click to toggle)
supercollider 1%3A3.13.0%2Brepack-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 80,292 kB
  • sloc: cpp: 476,363; lisp: 84,680; ansic: 77,685; sh: 25,509; python: 7,909; makefile: 3,440; perl: 1,964; javascript: 974; xml: 826; java: 677; yacc: 314; lex: 175; objc: 152; ruby: 136
file content (99 lines) | stat: -rw-r--r-- 2,770 bytes parent folder | download | duplicates (6)
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);
	}
}