rgw 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,22 @@
1
+ ## RGW Ruby Gtk Widgets
2
+
3
+ Rgw is a collection of [Gtk+](http://www.gtk.org/) widgets implemented in and for the
4
+ [ruby](https://www.ruby-lang.org) programming language.
5
+
6
+ **requirements**
7
+ ruby >= 2.0.0
8
+ ruby-gtk >= 2.2.0
9
+ gtk >= 3.10
10
+
11
+ **how to install**
12
+ ruby setup.rb config
13
+ ruby setup.rb setup
14
+ *get root / superuser*
15
+ ruby setup.rb install
16
+
17
+ At this point, the widgets are working, but special functionality may be missing. A TODO list is at
18
+ the head of every library file. Feel free to implement :-)
19
+
20
+ If you also have created gtk widgets in ruby and think, that they may be useful for others,
21
+ fork this project, include them and send me a pull request. Please attend, that you also provide
22
+ a small example of the widgets use under the *examples* directory.
@@ -0,0 +1,316 @@
1
+ #encoding: UTF-8
2
+
3
+ =begin
4
+ BigList is free software; you can redistribute it and/or
5
+ modify it under the terms of the GNU Lesser General Public
6
+ License as published by the Free Software Foundation; either
7
+ version 2.1 of the License, or (at your option) any later version.
8
+
9
+ BigList is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ Lesser General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Lesser General Public
15
+ License along with BigList; if not, write to the Free Software
16
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ Copyright 2014 Detlef Reichl detlef!reichl()gmx!org
19
+ =end
20
+
21
+
22
+ =begin
23
+ TODO:
24
+ get all colors from the system settings
25
+ make the columns resizable
26
+ use copy while scrolling
27
+ add a data provider that calls a block. For very big data pools or as backend for a DB
28
+ =end
29
+
30
+ require 'rgw/types'
31
+
32
+ # Rgw::BigList is a widget, that shows a data list from an array of arrays. It has no bells and
33
+ # whistles, but is _very_ fast.
34
+
35
+ module Rgw
36
+ class BigList < Gtk::Table
37
+
38
+ ROW_PADDING = 4 # @private
39
+ # Initializes a new Rgw::BigList object
40
+ #
41
+ # @param num_cols [Integer, nil] The number of columns the list sould have.
42
+ def initialize num_cols=1
43
+ super(2, 2, false)
44
+ raise ArgumentError, 'positive integer expected' unless (num_cols.is_a? Integer and num_cols > 0)
45
+ @numCols = num_cols
46
+ # the X poxitions of the column ends
47
+ @colsX = []
48
+ # current displayed top column
49
+ @col = 0
50
+ # current displayed left column
51
+ @row = 0
52
+
53
+ @data = nil
54
+ @heads = nil
55
+ @headHeight = 0.0
56
+ @separator = "\t"
57
+
58
+ @area = Gtk::DrawingArea.new
59
+ self.attach @area, 0, 1, 0, 2, Gtk::AttachOptions::EXPAND | Gtk::AttachOptions::FILL,
60
+ Gtk::AttachOptions::EXPAND | Gtk::AttachOptions::FILL
61
+
62
+ # I don't use the integrated double buffering, cause it flickers
63
+ # I can do it better myself
64
+ double_buffered = false
65
+ @backBuffer = nil
66
+
67
+ @area.add_events Gdk::Event::Mask::SCROLL_MASK
68
+
69
+ @area.signal_connect(:scroll_event) {|object, event| on_scroll event.direction; false}
70
+ @area.signal_connect(:draw) {|object, cc| redraw; false}
71
+ @area.signal_connect(:configure_event) {|object, event| on_configure event; false}
72
+
73
+ @scroll = Gtk::Scrollbar.new :vertical
74
+ self.attach @scroll, 1, 2, 1, 2, 0, Gtk::AttachOptions::EXPAND | Gtk::AttachOptions::FILL
75
+
76
+ dummy = Gtk::Label.new ' '
77
+ self.attach dummy, 1, 2, 0, 1, 0, 0
78
+ end
79
+
80
+ # @return [Array] The complete data of the list as set by {#data=} or
81
+ # nil if not.
82
+ attr_reader :data
83
+
84
+ # @return [Array<String>, nil] The heads of the list if set by {#heads=}
85
+ # or nil if not.
86
+ attr_reader :heads
87
+
88
+ # @return [String] The separator to split data strings as set by {#separator=}
89
+ attr_reader :separator
90
+
91
+ # @return [Integer] The number of columns for the list as set by {#num_cols=}
92
+ attr_reader :numCols
93
+
94
+
95
+ # Set the lists data
96
+ #
97
+ # @param data [Array] The data for the list. The array has to contain Strings, which will
98
+ # be split with [separator], or arrays of strings, which will be used directly.
99
+ def data=(data)
100
+ @data = data
101
+ configure_scrollbar
102
+ queue_draw
103
+ end
104
+
105
+
106
+ # Set the heads of the the list
107
+ # @param heads [Array<String>] The texts which should be displayed as the columns heads.
108
+ def heads=(heads)
109
+ unless heads.nil?
110
+ raise ArgumentError, "invalid type %s for heads; expect Array of String" % heads.class.to_s unless heads.is_a? Array
111
+ raise ArgumentError, "invalid size of heads" unless @numCols == heads.length
112
+ heads.each {|head| raise ArgumentError, "invalid type %s for head; expect String" % head.class.to_s unless head.is_a? String}
113
+ end
114
+ @heads = heads
115
+ calculate_rows
116
+ configure_scrollbar
117
+ end
118
+
119
+
120
+ # Set the column separator
121
+ #
122
+ # @param sep [String] For lists, where the data is provided as an array of strings the
123
+ # separator will be used to split the input to the text for each column.
124
+ def separator=(sep)
125
+ @separator = sep
126
+ queue_draw
127
+ end
128
+
129
+
130
+ # Sets the number of columns
131
+ #
132
+ # @param cols [Integer] The number of columns the list should display
133
+ # @raise [ArgumentError] if cols is not an Integer or less then 1
134
+ def num_cols=(cols)
135
+
136
+ raise ArgumentError, 'invalid column number' unless cols.is_a? Integer and cols > 0
137
+ @numCols = cols
138
+ @colsX = []
139
+ width = @width.to_f / @numCols.to_f
140
+ 0.upto(@numCols) {|col| @colsX << col.to_f * width}
141
+ queue_draw
142
+ end
143
+
144
+
145
+ # Get the row data from a given position
146
+ #
147
+ # @param x [Integer] Ignored for now.
148
+ # @param y [Integer] The vertical position in pixels from the list top position from where
149
+ # to get the data from
150
+ # @return [Array<String>] The rows data for the requested position. The data is owend
151
+ # by the list and should not be modified, because it will change your original data!
152
+ def row_at_pos x, y
153
+ @data[@row + y.to_f / @rowHeight]
154
+ end
155
+
156
+ private
157
+
158
+ def queue_draw
159
+ @area.queue_draw_area 0, 0, @area.allocation.width, @area.allocation.height
160
+ end
161
+
162
+
163
+ def on_scroll dir
164
+ return if @data.nil?
165
+ case dir
166
+ when Gdk::EventScroll::Direction::UP
167
+ return if @row == 0
168
+ @row -= 1
169
+ @scroll.adjustment.value = @row
170
+ queue_draw
171
+ when Gdk::EventScroll::Direction::DOWN
172
+ return if @row + @numRows > @data.length
173
+ @row += 1
174
+ @scroll.adjustment.value = @row
175
+ queue_draw
176
+ end
177
+ end
178
+
179
+
180
+ def configure_scrollbar
181
+ return if @data.nil? or @numRows.nil? or @height.nil?
182
+ if @numRows >= @data.length()
183
+ @scroll.hide
184
+ else
185
+ @scroll.show
186
+ @scroll.adjustment = Gtk::Adjustment.new 0, 0, @data.length(), 1, @numRows, @numRows
187
+ @scroll.adjustment.signal_connect(:value_changed) {on_scrollbar_change}
188
+ end
189
+ end
190
+
191
+
192
+ def on_scrollbar_change
193
+ @row = @scroll.value.to_i
194
+ queue_draw
195
+ end
196
+
197
+
198
+ def on_configure event
199
+ @width = event.width
200
+ @height = event.height
201
+ ctx = self.toplevel.style_context
202
+ fnt = ctx.get_font :normal
203
+ @ccFontSize = Pango.pixels(fnt.size) / 72.0 * self.toplevel.screen.resolution
204
+ @ccFontFamily = fnt.family
205
+ calculate_rows
206
+ configure_scrollbar
207
+ end
208
+
209
+
210
+ def calculate_rows
211
+ return if self.window.nil?
212
+ @backBuffer = Cairo::ImageSurface.new Cairo::Format::RGB24, @width, @height
213
+ cc = Cairo::Context.new @backBuffer
214
+ cc.font_size = @ccFontSize
215
+ @rowHeight = cc.text_extents('XgqT)!_').height.to_f + ROW_PADDING.to_f * 2.0
216
+ @headHeight = @heads.nil? ? 0.0 : @rowHeight + 4.0
217
+ @numRows = ((@height.to_f - @headHeight) / @rowHeight).ceil
218
+
219
+ if @colsX.length() == 0
220
+ width = @width.to_f / @numCols.to_f
221
+ 0.upto(@numCols) {|col| @colsX << col.to_f * width}
222
+ else
223
+ @colsX[-1] = @width.to_f
224
+ end
225
+ end
226
+
227
+
228
+ def redraw
229
+ return if self.window.nil?
230
+ cc = Cairo::Context.new @backBuffer
231
+ cc.antialias = :none
232
+ cc.set_source_rgb 1.0, 1.0, 1.0
233
+ cc.paint
234
+
235
+ # draw the head
236
+ unless @heads.nil?
237
+ cc.set_source_rgb 0.9, 0.9, 0.9
238
+ cc.rectangle 0, 0, @width, @headHeight
239
+ cc.fill.stroke
240
+ cc.antialias = :subpixel
241
+ cc.set_source_rgb 0.0, 0.0, 0.0
242
+ cc.font_size = @ccFontSize
243
+ cc.select_font_face @ccFontFamily, :normal, :bold
244
+
245
+ @heads.each_with_index do |head, col|
246
+ cc.move_to @colsX[col] + 4, @rowHeight - 4
247
+ cc.show_text head
248
+ cc.stroke
249
+ end
250
+ end
251
+
252
+ # draw the data
253
+ unless @data.nil?
254
+ colClips = []
255
+ cellData = []
256
+ (@row).upto(@row + @numRows - 1) do |row|
257
+ break if row >= @data.length()
258
+ textRow = @data[row]
259
+ if textRow.is_a? Array
260
+ cellData << textRow
261
+ else
262
+ cellData << textRow.split(@separator)
263
+ end
264
+ end
265
+
266
+ 0.upto(@numCols - 1) do |col|
267
+ cc = Cairo::Context.new @backBuffer
268
+ cc.antialias = :subpixel
269
+ cc.set_source_rgb 0.0, 0.0, 0.0
270
+ cc.font_size = @ccFontSize
271
+ cc.select_font_face @ccFontFamily, :normal, :normal
272
+
273
+ cc.rectangle @colsX[col], @headHeight, @colsX[col + 1] - @colsX[col], @height - @headHeight
274
+ cc.clip
275
+ cc.new_path
276
+ 0.upto(cellData.length() - 1) do |row|
277
+ tok = cellData[row][col]
278
+ next if tok.nil?
279
+ cc.move_to @colsX[col] + 4, (row + 1) * @rowHeight - 4 + @headHeight
280
+ cc.show_text tok
281
+ cc.stroke
282
+ cc.new_path
283
+ end
284
+ end
285
+ end
286
+ cc = Cairo::Context.new @backBuffer
287
+ cc.antialias = :none
288
+ cc.set_source_rgb 0.0, 0.0, 0.0
289
+ cc.line_width = 1.0
290
+ lg = @data.nil? ? 0 : @data.length()
291
+ lg += 1 unless @heads.nil?
292
+
293
+ # draw the vertical lines
294
+ 0.upto(@numCols - 1) do |col|
295
+ x = @colsX[col]
296
+ cc.move_to x, 0
297
+ cc.line_to x, @height.min(lg * @rowHeight)
298
+ end
299
+ cc.stroke
300
+
301
+ # draw the horizontal lines
302
+ 0.upto(@numRows.min(lg - 1)) do |row|
303
+ y = @rowHeight * row + @headHeight
304
+ cc.move_to 0, y
305
+ cc.line_to @width, y
306
+ end
307
+ cc.stroke
308
+
309
+ # copy backbuffer to the window
310
+ cb = @area.window.create_cairo_context
311
+ cb.set_source @backBuffer
312
+ cb.paint
313
+ false
314
+ end
315
+ end
316
+ end
@@ -0,0 +1,278 @@
1
+ # encoding: UTF-8
2
+
3
+ =begin
4
+ PropertyEditor is free software; you can redistribute it and/or
5
+ modify it under the terms of the GNU Lesser General Public
6
+ License as published by the Free Software Foundation; either
7
+ version 2.1 of the License, or (at your option) any later version.
8
+
9
+ PropertyEditor is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ Lesser General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Lesser General Public
15
+ License along with PropertyEditor; if not, write to the Free Software
16
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ Copyright 2014 Detlef Reichl detlef!reichl()gmx!org
19
+ =end
20
+
21
+ require 'rgw/synced-spin-button'
22
+ require 'rgw/radio-revealer'
23
+
24
+ module Rgw
25
+ class PropertyEditor < Gtk::Box
26
+
27
+ self.type_register
28
+ self.signal_new :property_changed, GLib::Signal::RUN_FIRST, nil, GLib::Type['void'], String, Object
29
+
30
+ def signal_do_property_changed foo, bla; end
31
+
32
+ def initialize props, type
33
+ super(:orientation => :vertical)
34
+ @widgetDefaults = []
35
+ @selectedElement = nil
36
+ table = create_prop_editor props, type
37
+ pack_start table, :expand => false, :fill => false, :padding => 4
38
+ end
39
+
40
+ attr_reader :selectedElement
41
+
42
+
43
+ def create_prop_editor props, type=nil
44
+ table = Gtk::Table.new props.length() + 1, 2
45
+ table.column_spacings = 8
46
+ table.row_spacings = 4
47
+
48
+ unless type.nil?
49
+ headline = Gtk::Label.new
50
+ headline.markup = '<b><big>' + type + '</big></b>'
51
+ headline.xalign = 0.1
52
+ table.attach headline, 0, 2, 0, 1, Gtk::AttachOptions::EXPAND | Gtk::AttachOptions::FILL,
53
+ Gtk::AttachOptions::EXPAND | Gtk::AttachOptions::FILL
54
+ end
55
+
56
+ 0.upto(props.length()-1) { |a| create_prop_entry props[a], table, a + 1}
57
+ table.show_all
58
+ table
59
+ end
60
+
61
+
62
+ def create_prop_entry data, table, row
63
+ label = Gtk::Label.new
64
+ label.xalign = 1.0
65
+ widget = nil
66
+
67
+ case data[:type]
68
+ when :iRadio
69
+ label.text = data[:label]
70
+ hbox = Gtk::Box.new :horizontal
71
+
72
+ i = 0
73
+ while true do
74
+ sym = ('img' + i.to_s).to_sym
75
+ break if data[sym].nil?
76
+ i += 1
77
+ end
78
+
79
+ group = nil
80
+ 0.upto(i-1) do |n|
81
+ if n == 0
82
+ button = Gtk::RadioButton.new
83
+ group = button
84
+ else
85
+ button = Gtk::RadioButton.new group
86
+ end
87
+ hbox.pack_start button, :expand => false, :fill => false, :padding => 2
88
+ button.draw_indicator = false
89
+ sym = ('img' + n.to_s).to_sym
90
+ # img = Gtk::Image.new(:file => Rgw::PIXMAP_PATH + data[sym] + '.png')
91
+ button.image = img
92
+ button.signal_connect(:toggled) do |widget|
93
+ 0.upto(widget.group.length() - 1) do |m|
94
+ if widget.group[m].active?
95
+ signal_emit :property_changed, data[:id0], widget.group.length() - 1 - m
96
+ break
97
+ end
98
+ end
99
+ end
100
+ end
101
+ group.group[i - 1 - data[:default0]].active = true
102
+ @widgetDefaults << [group, data]
103
+ hbox.show_all
104
+ widget = hbox
105
+ when :sSpin
106
+ label.text = data[:label]
107
+ widget = Rgw::SyncedSpinButton.new data[:range].first, data[:range].last, data[:step], data[:synced]
108
+ @widgetDefaults << [widget, data]
109
+ widget.set_values data[:default0], data[:default1]
110
+ widget.signal_connect(:value1_changed) {|wid, val| signal_emit :property_changed, data[:id0], val}
111
+ widget.signal_connect(:value2_changed) {|wid, val| signal_emit :property_changed, data[:id1], val}
112
+ when :spin
113
+ label.text = data[:label]
114
+ widget = Gtk::SpinButton.new data[:range].first, data[:range].last, data[:step]
115
+ widget.value = data[:default0]
116
+ @widgetDefaults << [widget, data]
117
+ widget.signal_connect(:value_changed) do |wid|
118
+ signal_emit :property_changed, data[:id0], wid.value
119
+ end
120
+ when :toggle
121
+ label.text = data[:label].split[0..-2].join(' ')
122
+ widget = Gtk::ToggleButton.new data[:label].split[-1]
123
+ widget.active = data[:default0]
124
+ @widgetDefaults << [widget, data]
125
+ widget.signal_connect(:toggled) do |wid|
126
+ signal_emit :property_changed, data[:id0], wid.active?
127
+ end
128
+ when :entry
129
+ label.text = data[:label]
130
+ widget = Gtk::Entry.new
131
+ widget.text = data[:default0]
132
+ @widgetDefaults << [widget, data]
133
+ widget.signal_connect(:changed) do |wid|
134
+ signal_emit :property_changed, data[:id0], wid.text
135
+ end
136
+ when :color
137
+ label.text = data[:label]
138
+ # fix for ruby gtk 2.2.0
139
+ col = data[:default0].map{|c| c * 0xffff}.take(3)
140
+ color = Gdk::Color.new *col
141
+ #color = Gdk::RGBA.new(*data[:default0])
142
+ widget = Gtk::ColorButton.new color
143
+ widget.use_alpha = true
144
+ @widgetDefaults << [widget, data]
145
+ widget.signal_connect(:color_set) do |wid|
146
+ cl = wid.rgba
147
+ signal_emit :property_changed, data[:id0], [cl.red, cl.green, cl.blue, cl.alpha]
148
+ end
149
+ when :combo
150
+ label.text = data[:label]
151
+ widget = Gtk::ComboBoxText.new
152
+ data[:entries].each {|entry| widget.append nil, entry}
153
+ @widgetDefaults << [widget, data]
154
+ widget.signal_connect(:changed) do |wid|
155
+ signal_emit :property_changed, data[:id0], wid.active
156
+ end
157
+ when :radioRevealer
158
+ rbox = Gtk::Box.new :vertical
159
+ table.attach_defaults rbox, 0, 2, row, row+1
160
+ rbox.pack_start Gtk::Separator.new(:horizontal), :expand => :false, :fill => :false
161
+ label.set_xalign(0.5)
162
+ label.markup = '<span size="large" weight="bold">' + data[:label] + '</span>'
163
+ rbox.pack_start label, :expand => :false, :fill => :false
164
+ widget = Rgw::RadioRevealer.new
165
+ rbox.pack_start widget, :expand => :false, :fill => :false
166
+ @widgetDefaults << [widget, data]
167
+ data[:revealSections].each do |section|
168
+ revealerChild = create_prop_editor section[:data]
169
+ label = Gtk::Label.new
170
+ label.markup = '<span size="medium" weight="bold">' + section[:section] + '</span>'
171
+ widget.create_entry label, revealerChild
172
+ widget.signal_connect(:revealed) do |wid, idx|
173
+ signal_emit :property_changed, data[:id0], idx
174
+ end
175
+ end
176
+ return
177
+ else
178
+ raise RuntimeError, 'invalid property type'
179
+ end
180
+ table.attach_defaults label, 0, 1, row, row+1
181
+ table.attach_defaults widget, 1, 2, row, row+1
182
+ end
183
+
184
+
185
+ def set_selected_element element
186
+ @selectedElement = element
187
+ end
188
+
189
+
190
+ def set_from_data
191
+ @widgetDefaults.each do |data|
192
+ val1 = @selectedElement.get_by_name data[1][:id0]
193
+ if data[1][:type] == :iRadio
194
+ data[0].group[data[0].group.length() - 1 - val1].active = true
195
+ elsif data[1][:type] == :toggle
196
+ data[0].active = val1
197
+ elsif data[1][:type] == :spin
198
+ data[0].value = val1
199
+ elsif data[1][:type] == :sSpin
200
+ val2 = @selectedElement.get_by_name data[1][:id1]
201
+ data[0].set_values val1, val2
202
+ elsif data[1][:type] == :entry
203
+ data[0].text = val1
204
+ elsif data[1][:type] == :color
205
+ col = Gdk::RGBA.new *val1
206
+ data[0].rgba = col
207
+ elsif data[1][:type] == :combo
208
+ data[0].active = val1
209
+ elsif data[1][:type] == :radioRevealer
210
+ data[0].active = val1
211
+ else
212
+ raise RuntimeError, 'invalid type in set_from_data'
213
+ end
214
+ end
215
+ end
216
+
217
+
218
+ def set_defaults
219
+ @widgetDefaults.each do |data|
220
+ # set from defaults
221
+ if data[1][:useDefault]
222
+ if data[1][:type] == :iRadio
223
+ # the buttons in a radio button group are orderd reverse. strange...
224
+ data[0].group[data[0].group.length() - 1 - data[1][:default0]].active = true
225
+ elsif data[1][:type] == :toggle
226
+ data[0].active = data[1][:default0]
227
+ elsif data[1][:type] == :spin
228
+ data[0].value = data[1][:default0]
229
+ elsif data[1][:type] == :sSpin
230
+ data[0].set_values data[1][:default0], data[1][:default1]
231
+ elsif data[1][:type] == :entry
232
+ data[0].text = data[1][:default0]
233
+ elsif data[1][:type] == :color
234
+ col = Gdk::RGBA.new(*data[1][:default0])
235
+ data[0].rgba = col
236
+ elsif data[1][:type] == :combo
237
+ data[0].active = data[1][:default0]
238
+ elsif data[1][:type] == :radioRevealer
239
+ data[0].active = data[1][:default0]
240
+ else
241
+ raise RuntimeError, 'invalid type in set_defaults useDefault'
242
+ end
243
+ # move from the widget into the data store
244
+ else
245
+ if data[1][:type] == :iRadio
246
+ nb = data[0].group.length
247
+ 0.upto(nb - 1) do |i|
248
+ if data[0].group[i].active?
249
+ signal_emit :property_changed, data[1][:id0], nb - 1 - i
250
+ break
251
+ end
252
+ end
253
+ elsif data[1][:type] == :toggle
254
+ f = data[0].active? ? 1.0 : 0.0
255
+ signal_emit :property_changed, data[1][:id0], f
256
+ elsif data[1][:type] == :spin
257
+ signal_emit :property_changed, data[1][:id0], data[0].value
258
+ elsif data[1][:type] == :sSpin
259
+ s1, s2 = *data[0].get_values
260
+ signal_emit :property_changed, data[1][:id0], s1 if s1 >= 0.0
261
+ signal_emit :property_changed, data[1][:id1], s2 if s2 >= 0.0
262
+ elsif data[1][:type] == :entry
263
+ signal_emit :property_changed, data[1][:id0], data[0].text
264
+ elsif data[1][:type] == :color
265
+ cl = data[0].rgba
266
+ signal_emit :property_changed, data[1][:id0], [cl.red, cl.green, cl.blue, cl.alpha]
267
+ elsif data[1][:type] == :combo
268
+ signal_emit :property_changed, data[1][:id0], data[0].active
269
+ elsif data[1][:type] == :radioRevealer
270
+ signal_emit :property_changed, data[1][:id0], data[0].active
271
+ else
272
+ raise RuntimeError, 'invalid type in set_defaults !useDefault'
273
+ end
274
+ end
275
+ end
276
+ end
277
+ end
278
+ end