|
1 | 1 | const Clutter = imports.gi.Clutter; |
| 2 | +const GObject = imports.gi.GObject; |
2 | 3 | const Pango = imports.gi.Pango; |
3 | | -const Cinnamon = imports.gi.Cinnamon; |
4 | 4 | const St = imports.gi.St; |
5 | | -const Signals = imports.signals; |
6 | 5 |
|
7 | | -const Lang = imports.lang; |
8 | | - |
9 | | -function RadioButtonContainer() { |
10 | | - this._init(); |
11 | | -} |
12 | | -RadioButtonContainer.prototype = { |
13 | | - _init: function() { |
14 | | - this.actor = new Cinnamon.GenericContainer({ y_align: St.Align.MIDDLE }); |
15 | | - this.actor.connect('get-preferred-width', |
16 | | - Lang.bind(this, this._getPreferredWidth)); |
17 | | - this.actor.connect('get-preferred-height', |
18 | | - Lang.bind(this, this._getPreferredHeight)); |
19 | | - this.actor.connect('allocate', |
20 | | - Lang.bind(this, this._allocate)); |
21 | | - this.actor.connect('style-changed', Lang.bind(this, |
22 | | - function() { |
23 | | - let node = this.actor.get_theme_node(); |
24 | | - this._spacing = node.get_length('spacing'); |
25 | | - })); |
26 | | - this.actor.request_mode = Clutter.RequestMode.HEIGHT_FOR_WIDTH; |
| 6 | +var RadioButton = GObject.registerClass( |
| 7 | +class RadioButton extends St.Button { |
| 8 | + _init(label) { |
| 9 | + let container = new St.BoxLayout(); |
| 10 | + super._init({ |
| 11 | + style_class: 'radiobutton', |
| 12 | + important: true, |
| 13 | + child: container, |
| 14 | + button_mask: St.ButtonMask.ONE, |
| 15 | + toggle_mode: true, |
| 16 | + can_focus: true, |
| 17 | + x_fill: true, |
| 18 | + y_fill: true, |
| 19 | + }); |
27 | 20 |
|
28 | 21 | this._box = new St.Bin(); |
29 | | - this.actor.add_actor(this._box); |
30 | | - |
31 | | - this.label = new St.Label(); |
32 | | - this.label.clutter_text.set_line_wrap(false); |
33 | | - this.label.clutter_text.set_ellipsize(Pango.EllipsizeMode.NONE); |
34 | | - this.actor.add_actor(this.label); |
35 | | - |
36 | | - this._spacing = 0; |
37 | | - }, |
38 | | - |
39 | | - _getPreferredWidth: function(actor, forHeight, alloc) { |
40 | | - let [minWidth, natWidth] = this._box.get_preferred_width(forHeight); |
41 | | - |
42 | | - alloc.min_size = minWidth + this._spacing; |
43 | | - alloc.natural_size = natWidth + this._spacing; |
44 | | - }, |
45 | | - |
46 | | - _getPreferredHeight: function(actor, forWidth, alloc) { |
47 | | - let [minBoxHeight, natBoxHeight] = |
48 | | - this._box.get_preferred_height(-1); |
49 | | - let [minLabelHeight, natLabelHeight] = |
50 | | - this.label.get_preferred_height(-1); |
51 | | - |
52 | | - alloc.min_size = Math.max(minBoxHeight, 2 * minLabelHeight); |
53 | | - alloc.natural_size = Math.max(natBoxHeight, 2 * natLabelHeight); |
54 | | - }, |
55 | | - |
56 | | - _allocate: function(actor, box, flags) { |
57 | | - let availWidth = box.x2 - box.x1; |
58 | | - let availHeight = box.y2 - box.y1; |
59 | | - |
60 | | - let childBox = new Clutter.ActorBox(); |
61 | | - let [minBoxWidth, natBoxWidth] = |
62 | | - this._box.get_preferred_width(-1); |
63 | | - let [minBoxHeight, natBoxHeight] = |
64 | | - this._box.get_preferred_height(-1); |
65 | | - childBox.x1 = box.x1; |
66 | | - childBox.x2 = box.x1 + natBoxWidth; |
67 | | - childBox.y1 = box.y1; |
68 | | - childBox.y2 = box.y1 + natBoxHeight; |
69 | | - this._box.allocate(childBox, flags); |
70 | | - |
71 | | - childBox.x1 = box.x1 + natBoxWidth + this._spacing; |
72 | | - childBox.x2 = availWidth - childBox.x1; |
73 | | - childBox.y1 = box.y1; |
74 | | - childBox.y2 = box.y2; |
75 | | - this.label.allocate(childBox, flags); |
76 | | - } |
77 | | -}; |
78 | | - |
79 | | -function RadioBox(state) { |
80 | | - this._init(state); |
81 | | -} |
82 | | - |
83 | | -RadioBox.prototype = { |
84 | | - _init: function(state) { |
85 | | - this.actor = new St.Button({ style_class: 'radiobutton', |
86 | | - button_mask: St.ButtonMask.ONE, |
87 | | - toggle_mode: true, |
88 | | - can_focus: true, |
89 | | - x_fill: true, |
90 | | - y_fill: true, |
91 | | - y_align: St.Align.MIDDLE }); |
92 | | - |
93 | | - this.actor._delegate = this; |
94 | | - this.actor.checked = state; |
95 | | - this._container = new St.Bin(); |
96 | | - this.actor.set_child(this._container); |
97 | | - }, |
98 | | - |
99 | | - setToggleState: function(state) { |
100 | | - this.actor.checked = state; |
101 | | - }, |
102 | | - |
103 | | - toggle: function() { |
104 | | - this.setToggleState(!this.actor.checked); |
105 | | - }, |
| 22 | + this._box.set_y_align(Clutter.ActorAlign.START); |
| 23 | + container.add_child(this._box); |
106 | 24 |
|
107 | | - destroy: function() { |
108 | | - this.actor.destroy(); |
109 | | - } |
110 | | -}; |
111 | | - |
112 | | -function RadioButton(label) { |
113 | | - this._init(label); |
114 | | -} |
115 | | - |
116 | | -RadioButton.prototype = { |
117 | | - __proto__: RadioBox.prototype, |
118 | | - |
119 | | - _init: function(label) { |
120 | | - RadioBox.prototype._init.call(this, false); |
121 | | - this._container.destroy(); |
122 | | - this._container = new RadioButtonContainer(); |
123 | | - this.actor.set_child(this._container.actor); |
| 25 | + this._label = new St.Label({ y_align: Clutter.ActorAlign.CENTER }); |
| 26 | + this._label.clutter_text.set_line_wrap(true); |
| 27 | + this._label.clutter_text.set_ellipsize(Pango.EllipsizeMode.NONE); |
| 28 | + container.add_child(this._label); |
124 | 29 |
|
125 | 30 | if (label) |
126 | 31 | this.setLabel(label); |
127 | | - }, |
128 | | - |
129 | | - setLabel: function(label) { |
130 | | - this._container.label.set_text(label); |
131 | | - }, |
132 | | - |
133 | | - getLabelActor: function() { |
134 | | - return this._container.label; |
135 | 32 | } |
136 | | -}; |
137 | | - |
138 | | -function RadioButtonGroup() { |
139 | | - this._init(); |
140 | | -} |
141 | | - |
142 | | -RadioButtonGroup.prototype = { |
143 | | - _init: function() { |
144 | | - this.actor = new St.BoxLayout({ vertical: true, width: 250 }); |
145 | | - this._buttons = []; |
146 | | - this._activeId = null; |
147 | | - }, |
148 | 33 |
|
149 | | - addButton: function(buttonId, label) { |
150 | | - this.radioButton = new RadioButton(label); |
151 | | - this.radioButton.actor.connect("clicked", |
152 | | - Lang.bind(this, function(actor) { |
153 | | - this.buttonClicked(actor, buttonId); |
154 | | - })); |
155 | | - |
156 | | - this._buttons.push({ id: buttonId, button: this.radioButton }); |
157 | | - this.actor.add(this.radioButton.actor, { x_fill: true, y_fill: false, y_align: St.Align.MIDDLE }); |
158 | | - }, |
159 | | - |
160 | | - radioChanged: function(actor) { |
161 | | - |
162 | | - }, |
163 | | - |
164 | | - buttonClicked: function(actor, buttonId) { |
165 | | - for (const button of this._buttons) { |
166 | | - if (buttonId !== button['id'] && button['button'].actor.checked) { |
167 | | - button['button'].actor.checked = false; |
168 | | - } |
169 | | - else if (buttonId === button['id'] && !button['button'].actor.checked) { |
170 | | - button['button'].actor.checked = true; |
171 | | - } |
172 | | - } |
173 | | - |
174 | | - // Only trigger real changes to radio selection. |
175 | | - if (buttonId !== this._activeId) { |
176 | | - this._activeId = buttonId; |
177 | | - this.emit('radio-changed', this._activeId); |
178 | | - } |
179 | | - }, |
180 | | - |
181 | | - setActive: function(buttonId) { |
182 | | - for (const button of this._buttons) { |
183 | | - button['button'].actor.checked = buttonId === button['id']; |
184 | | - } |
185 | | - |
186 | | - if (this._activeId != buttonId) { |
187 | | - this._activeId = buttonId; |
188 | | - this.emit('radio-changed', this._activeId); |
189 | | - } |
190 | | - }, |
| 34 | + setLabel(label) { |
| 35 | + this._label.set_text(label); |
| 36 | + } |
191 | 37 |
|
192 | | - getActive: function() { |
193 | | - return this._activeId; |
194 | | - } |
195 | | -} |
196 | | -Signals.addSignalMethods(RadioButtonGroup.prototype); |
| 38 | + getLabelActor() { |
| 39 | + return this._label; |
| 40 | + } |
| 41 | +}); |
0 commit comments