foxguib 1.1.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.
Files changed (109) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/changelog.txt +128 -0
  4. data/doc/www/index.html +173 -0
  5. data/doc/www/upload.rb +9 -0
  6. data/examples/event_handler.rb +67 -0
  7. data/examples/event_handlers.rbin +0 -0
  8. data/examples/guib_testdialog.rb +31 -0
  9. data/examples/testdialog.rb +29 -0
  10. data/exe/foxguib +1 -0
  11. data/foxGUIb-debug.rb +37 -0
  12. data/foxGUIb.rb +88 -0
  13. data/foxGUIb_win32.rbw +1 -0
  14. data/foxguib.gemspec +26 -0
  15. data/license.txt +49 -0
  16. data/readme.txt +1 -0
  17. data/release_notes.txt +68 -0
  18. data/src/assert.rb +8 -0
  19. data/src/cfgman.rb +27 -0
  20. data/src/code-gen/code-generator.rb +171 -0
  21. data/src/code-gen/property-generators.rb +65 -0
  22. data/src/code-gen/widget-generator.rb +22 -0
  23. data/src/convert.rb +60 -0
  24. data/src/direct_widget_manipulation.rb +343 -0
  25. data/src/docman.rb +260 -0
  26. data/src/document.rb +405 -0
  27. data/src/event_categories.yaml +85 -0
  28. data/src/event_listener.rb +57 -0
  29. data/src/events.yaml +77 -0
  30. data/src/events_docu.yaml +228 -0
  31. data/src/get_events.rb +64 -0
  32. data/src/gui/ArrowButton.tga +0 -0
  33. data/src/gui/BoxMinus.tga +0 -0
  34. data/src/gui/BoxPlus.tga +0 -0
  35. data/src/gui/Button.tga +0 -0
  36. data/src/gui/CheckButton.tga +0 -0
  37. data/src/gui/ComboBox.tga +0 -0
  38. data/src/gui/Dial.tga +0 -0
  39. data/src/gui/GroupBox.tga +0 -0
  40. data/src/gui/HorizontalFrame.tga +0 -0
  41. data/src/gui/HorizontalSeparator.tga +0 -0
  42. data/src/gui/Label.tga +0 -0
  43. data/src/gui/MDIChild.tga +0 -0
  44. data/src/gui/MDIClient.tga +0 -0
  45. data/src/gui/Matrix.tga +0 -0
  46. data/src/gui/MenuCaption.tga +0 -0
  47. data/src/gui/MenuCascade.tga +0 -0
  48. data/src/gui/MenuCheck.tga +0 -0
  49. data/src/gui/MenuCommand.tga +0 -0
  50. data/src/gui/MenuPane.tga +0 -0
  51. data/src/gui/MenuRadio.tga +0 -0
  52. data/src/gui/MenuSeparator.tga +0 -0
  53. data/src/gui/MenuTitle.tga +0 -0
  54. data/src/gui/Menubar.tga +0 -0
  55. data/src/gui/Packer.tga +0 -0
  56. data/src/gui/ProgressBar.tga +0 -0
  57. data/src/gui/RadioButton.tga +0 -0
  58. data/src/gui/RadioMutex.tga +0 -0
  59. data/src/gui/ScrollWindow.tga +0 -0
  60. data/src/gui/Scrollbar.tga +0 -0
  61. data/src/gui/Shutter.tga +0 -0
  62. data/src/gui/ShutterItem.tga +0 -0
  63. data/src/gui/Slider.tga +0 -0
  64. data/src/gui/Spinner.tga +0 -0
  65. data/src/gui/Splitter.tga +0 -0
  66. data/src/gui/StatusBar.tga +0 -0
  67. data/src/gui/Statusline.tga +0 -0
  68. data/src/gui/Switcher.tga +0 -0
  69. data/src/gui/TabBar.tga +0 -0
  70. data/src/gui/TabBook.tga +0 -0
  71. data/src/gui/TabItem.tga +0 -0
  72. data/src/gui/Text.tga +0 -0
  73. data/src/gui/TextField.tga +0 -0
  74. data/src/gui/ToggleButton.tga +0 -0
  75. data/src/gui/Toolbar.tga +0 -0
  76. data/src/gui/VerticalFrame.tga +0 -0
  77. data/src/gui/VerticalSeparator.tga +0 -0
  78. data/src/gui/_guib_event_editor.rb +185 -0
  79. data/src/gui/_guib_event_editor.rbin +0 -0
  80. data/src/gui/_guib_genruby.rb +414 -0
  81. data/src/gui/_guib_genruby.rbin +0 -0
  82. data/src/gui/_guib_mainwin.rb +574 -0
  83. data/src/gui/_guib_mainwin.rbin +0 -0
  84. data/src/gui/event_editor.rb +180 -0
  85. data/src/gui/genruby.rb +155 -0
  86. data/src/gui/guib__console.rb +265 -0
  87. data/src/gui/mainwin.rb +71 -0
  88. data/src/gui/ruby_console.rb +263 -0
  89. data/src/gui/svg/Matrix.svg +87 -0
  90. data/src/gui/svg/MenuCheck.svg +135 -0
  91. data/src/gui/svg/MenuRadio.svg +130 -0
  92. data/src/gui/svg/RadioMutex.svg +119 -0
  93. data/src/gui/textview.rb +101 -0
  94. data/src/gui/textview.rbin +0 -0
  95. data/src/minitest.rb +60 -0
  96. data/src/prop-lists.rb +323 -0
  97. data/src/prop-types.rb +606 -0
  98. data/src/properties.rb +119 -0
  99. data/src/propman.rb +88 -0
  100. data/src/relink_mechanisms.rb +95 -0
  101. data/src/serialize.rb +167 -0
  102. data/src/state_machine.rb +73 -0
  103. data/src/version.rb +6 -0
  104. data/src/widget-lists.rb +118 -0
  105. data/src/widget-selector.rb +85 -0
  106. data/src/widgettree-controls.rb +183 -0
  107. data.tar.gz.sig +0 -0
  108. metadata +236 -0
  109. metadata.gz.sig +0 -0
data/src/prop-types.rb ADDED
@@ -0,0 +1,606 @@
1
+ # Copyright (c) 2004-2006 by Henon (meinrad dot recheis at gmail dot com)
2
+ require "libGUIb16"
3
+ require "code-gen/property-generators"
4
+ include Fox
5
+ include FX
6
+
7
+ # for consistency; add dup method to all classes that don't support it (i.e. Nilclass)
8
+ class Object
9
+ def dup
10
+ self
11
+ end
12
+ end
13
+
14
+ # seems to be not needed any more
15
+ # ~ #pasted here to help independent compilation
16
+ # ~ class HorizontalFrame < Fox::FXHorizontalFrame
17
+ # ~ def initialize(p, opts=0)
18
+ # ~ super(p, opts|Fox::LAYOUT_FILL_X|Fox::LAYOUT_FILL_Y, 0,0,0,0,0,0,0,0,0,0)
19
+ # ~ end
20
+ # ~ end
21
+
22
+ # overwrite dup methods of Hash and Array with a real (recursive) duplication method
23
+ class Hash
24
+ def dup
25
+ h = {}
26
+ each { |k, v| h[k.dup] = v.dup }
27
+ h
28
+ end
29
+ end
30
+
31
+ class Array
32
+ def dup
33
+ collect { |e| e.dup }
34
+ end
35
+ end
36
+
37
+ # abstract property Manipulator base class
38
+ class SuperProp < HorizontalFrame
39
+ def initialize p, method, init_data = nil
40
+ super(p)
41
+ self.layoutHints = LAYOUT_FILL_X
42
+ self.frameStyle = 0
43
+ pad 0, 0, 0, 0
44
+ # flag for Container to know whether the property should be shown or not
45
+ @visible = true
46
+ @method = method
47
+ @controls = []
48
+ @enabled = false
49
+ @wdg = nil
50
+ @c = CheckButton.new(self) { |c|
51
+ c.text = ""
52
+ c.connect(SEL_COMMAND) {
53
+ set_enabled(@c.state)
54
+ }
55
+ }
56
+ @sep = VerticalSeparator.new(self, SEPARATOR_LINE) { |s| s.pad 0, 0, 0, 0 }
57
+ init
58
+ set_enabled false
59
+ end
60
+ attr_reader :method
61
+ attr_reader :enabled
62
+ # the current widget, needet for event callbacks
63
+ attr_accessor :wdg, :visible
64
+ def show
65
+ super if @visible and parent.shown?
66
+ end
67
+
68
+ # to be overridden by subclasses
69
+ def init
70
+ method_label
71
+ end
72
+
73
+ def method_label
74
+ l = Label.new(self) { |l|
75
+ l.text = @method
76
+ @controls << l
77
+ }
78
+ end
79
+
80
+ def method_s
81
+ method.gsub(/=$/, " = ")
82
+ end
83
+
84
+ # a text manipulator for textual properties
85
+ def text_input
86
+ @tf = TextField.new(self) { |tf|
87
+ tf.layoutHints = LAYOUT_RIGHT
88
+ tf.numColumns = 5
89
+ tf.disable
90
+ tf.connect(SEL_COMMAND) {
91
+ @wdg.update_wdg self if @wdg
92
+ }
93
+ tf.connect(SEL_CHANGED) {
94
+ @wdg.update_wdg self
95
+ }
96
+ @controls << tf
97
+ }
98
+ @tf
99
+ end
100
+
101
+ # a little texteditor dialog
102
+ def texteditor p
103
+ @texted = DialogBox.new p
104
+ @texted.resize(200, 150)
105
+ VerticalFrame.new(@texted) { |v|
106
+ v.pad 4, 4, 4, 4
107
+ VerticalFrame.new(v) { |tfr|
108
+ tfr.frameStyle = FRAME_SUNKEN
109
+ tfr.pad 0, 0, 0, 0
110
+ @text = Text.new(tfr) { |t|
111
+ t.text = @tf.text
112
+ }
113
+ }
114
+ HorizontalFrame.new(v) { |h|
115
+ Button.new(h, LAYOUT_RIGHT) { |b|
116
+ b.text = "Apply"
117
+ b.connect(SEL_COMMAND) {
118
+ @tf.text = @text.text
119
+ @wdg.update_wdg self if @wdg
120
+ @texted.destroy
121
+ }
122
+ }
123
+ Button.new(h, LAYOUT_RIGHT) { |b|
124
+ b.text = "Cancel"
125
+ b.connect(SEL_COMMAND) {
126
+ @texted.destroy
127
+ }
128
+ }
129
+ }
130
+ }
131
+ @texted.create
132
+ @texted.show(PLACEMENT_CURSOR)
133
+ end
134
+
135
+ # gets the data from the property widget
136
+ def get_data
137
+ if @tf
138
+ begin
139
+ data = deserialize(@tf.text)
140
+ @tf.textColor = FXRGB(0, 0, 0)
141
+ data
142
+ rescue Exception
143
+ @tf.textColor = FXRGB(255, 0, 0)
144
+ end
145
+ end
146
+ end
147
+
148
+ # sets the data value of the property widget
149
+ def set_data data
150
+ if @tf
151
+ @tf.textColor = FXRGB(0, 0, 0)
152
+ @tf.text = serialize(data)
153
+ end
154
+ end
155
+
156
+ # resets the widget and the prop-widget to the default state
157
+ def reset_default
158
+ @wdg.reset_default self if @wdg
159
+ end
160
+
161
+ # enables or disables the PropWidget
162
+ def set_enabled bool
163
+ reset_default unless bool
164
+ @enabled = bool
165
+ @c.state = bool
166
+ @controls.each { |w|
167
+ w.enabled = bool
168
+ change_text_color(w, bool)
169
+ }
170
+ end
171
+
172
+ # changes the text color of the prop-widget, so that it appears disabled or enabled
173
+ def change_text_color w, t
174
+ return unless w.respond_to? :textColor=
175
+ w.textColor = if t
176
+ FXRGB(0, 0, 0)
177
+ else
178
+ FXRGB(100, 100, 100)
179
+ end
180
+ end
181
+
182
+ def serialize data
183
+ data
184
+ end
185
+
186
+ def deserialize data
187
+ data
188
+ end
189
+ end
190
+
191
+ class NameProp < SuperProp
192
+ def initialize p
193
+ super(p, "Name:")
194
+ @c.hide
195
+ @sep.hide
196
+ method_label
197
+ text_input
198
+ @tf.enable
199
+ @tf.connect(SEL_CHANGED) {
200
+ @tf.textColor = FXRGB(255, 0, 0)
201
+ }
202
+ @tf.numColumns = 15
203
+ @tf.connect(SEL_COMMAND) {
204
+ begin
205
+ @tf.textColor = FXRGB(0, 0, 0) if @wdg.userData.manager.rename_wdg @wdg, @tf.text
206
+ rescue Exception
207
+ puts "oops, trying to rename a deleted widget!"
208
+ end
209
+ }
210
+ end
211
+
212
+ def init
213
+ end
214
+ end
215
+
216
+ class StringProp < SuperProp
217
+ include StringPropCodeGen
218
+ def init
219
+ super
220
+ Button.new(self) { |b|
221
+ b.text = "..."
222
+ b.layoutHints = LAYOUT_RIGHT
223
+ b.connect(SEL_COMMAND) {
224
+ texteditor self
225
+ }
226
+ @controls << b
227
+ }
228
+ text_input
229
+ @tf.numColumns = 15
230
+ end
231
+ end
232
+
233
+ class IntProp < SuperProp
234
+ include IntPropCodeGen
235
+ def init
236
+ method_label
237
+ text_input
238
+ end
239
+
240
+ def deserialize data
241
+ data.to_i
242
+ end
243
+ end
244
+
245
+ class BoolProp < SuperProp
246
+ include BoolPropCodeGen
247
+ def init
248
+ method_label
249
+ @ck = CheckButton.new(self) { |c|
250
+ # ~ c.checkState=@datum
251
+ c.text = ""
252
+ c.layoutHints = LAYOUT_RIGHT
253
+ c.disable
254
+ c.connect(SEL_COMMAND) {
255
+ @wdg.update_wdg self if @wdg
256
+ }
257
+ }
258
+ @controls << @ck
259
+ end
260
+
261
+ def get_data
262
+ @ck.state
263
+ end
264
+
265
+ def set_data data
266
+ @ck.state = data
267
+ end
268
+ end
269
+
270
+ class ColorProp < SuperProp
271
+ include ColorPropCodeGen
272
+ def init
273
+ method_label
274
+ VerticalFrame.new(self) { |pa|
275
+ pa.pad 0, 0, 0, 0
276
+ pa.frameStyle = FRAME_LINE
277
+ pa.layoutHints = LAYOUT_RIGHT
278
+ @b = Button.new(pa) { |b|
279
+ b.text = " C "
280
+ b.frameStyle = FRAME_NONE
281
+ b.connect(SEL_COMMAND) {
282
+ $color_dlg.rgba = deserialize(@tf.text)
283
+ if $color_dlg.execute == 1
284
+ set_data $color_dlg.getRGBA
285
+ @wdg.update_wdg self if @wdg
286
+ end
287
+ }
288
+ @controls << b
289
+ }
290
+ }
291
+ text_input
292
+ @tf.numColumns = 15
293
+ end
294
+
295
+ def get_data
296
+ color = super
297
+ @b.backColor = color if color
298
+ color
299
+ end
300
+
301
+ def set_data(color)
302
+ super
303
+ @b.backColor = color
304
+ end
305
+
306
+ def serialize data
307
+ Color.new.from_FXColor(data).to_s
308
+ end
309
+
310
+ def deserialize data
311
+ Color.new.from_s(data).to_FXColor
312
+ end
313
+ end
314
+
315
+ class FontProp < SuperProp
316
+ include FontPropCodeGen
317
+ def init
318
+ method_label
319
+ VerticalFrame.new(self) { |pa|
320
+ pa.pad 0, 0, 0, 0
321
+ pa.frameStyle = FRAME_LINE
322
+ pa.layoutHints = LAYOUT_RIGHT
323
+ @b = Button.new(pa) { |b|
324
+ b.text = " F "
325
+ b.frameStyle = FRAME_NONE
326
+ b.connect(SEL_COMMAND) {
327
+ fd = Fox::FXFontDesc.new
328
+ $font_dlg.fontSelection = fd.from_s(@tf.text)
329
+ if $font_dlg.execute == 1
330
+ fd = $font_dlg.fontSelection
331
+ font = Font.new
332
+ font.fd = fd
333
+ @tf.text = fd.to_s
334
+ @wdg.update_wdg self if @wdg
335
+ end
336
+ }
337
+ @controls << b
338
+ }
339
+ }
340
+ text_input
341
+ @tf.numColumns = 15
342
+ end
343
+
344
+ def serialize data
345
+ data.fontDesc.to_s
346
+ end
347
+
348
+ def deserialize data
349
+ Font.new.from_s(data).to_FXFont
350
+ end
351
+ end
352
+
353
+ class ConstProp < SuperProp
354
+ include ConstPropCodeGen
355
+ def initialize p, method, array
356
+ @array = array
357
+ super
358
+ end
359
+
360
+ def init
361
+ method_label
362
+ dropdown
363
+ end
364
+
365
+ def dropdown
366
+ @b = MenuButton.new(self) { |b|
367
+ @controls << b
368
+ b.text = ""
369
+ b.layoutHints = LAYOUT_RIGHT
370
+ }
371
+ @checklist = []
372
+ Popup.new(@b) { |popup|
373
+ @b.menu = popup
374
+ popup.connect(SEL_MAP) {
375
+ state = @wdg.send(@method.chop) if @wdg
376
+ set_data state
377
+ }
378
+ VerticalFrame.new(popup) { |v|
379
+ @array.each { |const|
380
+ CheckButton.new(v) { |c|
381
+ @checklist << c
382
+ c.text = const
383
+ c.layoutHints = LAYOUT_LEFT
384
+ c.connect(SEL_COMMAND) {
385
+ @wdg.update_wdg self if @wdg
386
+ }
387
+ }
388
+ }
389
+ }
390
+ HorizontalSeparator.new popup
391
+ MenuCommand.new(popup) { |ok| ok.text = "OK" }
392
+ HorizontalSeparator.new popup
393
+ Button.new(popup) { |checkall|
394
+ checkall.text = "check all"
395
+ checkall.frameStyle = FRAME_NONE
396
+ checkall.connect(SEL_COMMAND) { checkall true }
397
+ }
398
+ Button.new(popup) { |uncheckall|
399
+ uncheckall.text = "uncheck all"
400
+ uncheckall.frameStyle = FRAME_NONE
401
+ uncheckall.connect(SEL_COMMAND) { checkall false }
402
+ }
403
+ }
404
+ end
405
+
406
+ def get_data
407
+ a = []
408
+ @checklist.each { |c|
409
+ a << "Fox::" + c.text if c.state
410
+ }
411
+ state = eval(a.join("|"))
412
+ state || 0
413
+ end
414
+
415
+ def set_data(state)
416
+ return unless @wdg
417
+ @wdg.send(@method, 0)
418
+ sticky = @wdg.send(@method.chop)
419
+ @wdg.send(@method, eval(@array.join("|")))
420
+ unmod = @wdg.send(@method.chop)
421
+ @wdg.send(@method, state)
422
+ @checklist.each { |child|
423
+ const = eval(child.text)
424
+ child.check = ((state & const == const) ? true : false)
425
+ child.disable if sticky & const == const
426
+ child.disable unless unmod & const == const
427
+ }
428
+ end
429
+
430
+ def checkall b
431
+ a = []
432
+ @checklist.each { |child|
433
+ child.check = b if child.enabled
434
+ a << child.text
435
+ }
436
+ state = eval(a.join("|"))
437
+ @wdg.update_wdg self if @wdg
438
+ end
439
+ end
440
+
441
+ class IconProp < SuperProp
442
+ include IconPropCodeGen
443
+ def init
444
+ super
445
+ Button.new(self) { |b|
446
+ b.text = "..."
447
+ b.layoutHints = LAYOUT_RIGHT
448
+ b.connect(SEL_COMMAND) {
449
+ dlg = IconDialog.new self
450
+ filename = dlg.start
451
+ set_data deserialize(filename)
452
+ @wdg.update_wdg self if @wdg
453
+ }
454
+ @controls << b
455
+ }
456
+ text_input
457
+ @tf.numColumns = 15
458
+ end
459
+ # ~ def deserialize data
460
+ # ~ Icon.new(data).img
461
+ # ~ fail unless File.exist?( data)
462
+ # ~ return data
463
+ # ~ end
464
+ end
465
+
466
+ class RangeProp < SuperProp
467
+ include RangePropCodeGen
468
+ def init
469
+ super
470
+ text_input
471
+ @tf.numColumns = 15
472
+ @tf.connect(SEL_CHANGED) {
473
+ update
474
+ }
475
+ @tf.connect(SEL_COMMAND) {
476
+ update
477
+ }
478
+ end
479
+
480
+ def update
481
+ range = deserialize(@tf.text)
482
+ @wdg.update_wdg self if @wdg
483
+ @tf.textColor = FXRGB(0, 0, 0)
484
+ rescue Exception
485
+ @tf.textColor = FXRGB(255, 0, 0)
486
+ puts $!
487
+ puts $!.backtrace
488
+ end
489
+
490
+ def deserialize data
491
+ begin
492
+ range = eval(data)
493
+ fail unless range.is_a? Range
494
+ fail unless range.first.is_a? Numeric
495
+ fail unless range.last.is_a? Numeric
496
+ rescue Exception
497
+ range = 0..0
498
+ puts $!
499
+ puts $!.backtrace
500
+ end
501
+ range
502
+ end
503
+
504
+ def serialize data
505
+ data.inspect
506
+ end
507
+ end
508
+
509
+ # unit testing code
510
+ if __FILE__ == $0
511
+ require "minitest"
512
+ test("Range Property Manipulator") {
513
+ app = FX::App.new
514
+ w = FX::MainWindow.new app
515
+ s = FX::Spinner.new w
516
+ rangeInst = RangeProp.new(s, "range")
517
+ # testing deserialize
518
+ assert_equal 1..10, rangeInst.deserialize("1..10")
519
+ assert_raises(RuntimeError) {
520
+ rangeInst.deserialize("0")
521
+ }
522
+ assert_equal "-37..100", rangeInst.serialize(-37..100)
523
+ aRange = 1..2
524
+ rangeInst.set_data(aRange)
525
+ assert_equal aRange, rangeInst.get_data
526
+ true
527
+ }
528
+
529
+ test("Color Property Manipulator") {
530
+ app = FX::App.new
531
+ w = FX::MainWindow.new app
532
+ v = FX::VerticalFrame.new w
533
+ colorInst = ColorProp.new(v, "color")
534
+ color_data = "255,255,255,255"
535
+ # trying to get data before setting
536
+ data = colorInst.get_data
537
+ assert_equal 0, data
538
+ # testing deserialize and serialize
539
+ ser_data = colorInst.serialize(deser_data = colorInst.deserialize(color_data))
540
+ assert_equal color_data, ser_data
541
+ # testing get and set data
542
+ colorInst.set_data(colorInst.deserialize(color_data))
543
+ ser_data = colorInst.serialize(data = colorInst.get_data)
544
+ assert_equal color_data, ser_data
545
+ true
546
+ }
547
+
548
+ test("Font Property Manipulator") {
549
+ app = FX::App.new
550
+ w = FX::MainWindow.new app
551
+ t = FX::Text.new w
552
+ fontInst = FontProp.new(t, "font")
553
+ font_data = "Tahoma"
554
+ # testing serialize and deserialize
555
+ ser_data = fontInst.serialize(deser_data = fontInst.deserialize(font_data))
556
+ assert_equal Font.new.from_s(font_data).to_s, ser_data
557
+ true
558
+ }
559
+
560
+ test("Boolean Property Manipulator") {
561
+ app = FX::App.new
562
+ w = FX::MainWindow.new app
563
+ t = FX::Text.new w
564
+ boolInst = BoolProp.new(t, "bool")
565
+ bool_data = true
566
+ # getting data before setting it
567
+ assert_equal false, boolInst.get_data
568
+ # getting and setting data
569
+ boolInst.set_data bool_data
570
+ assert_equal bool_data, boolInst.get_data
571
+ true
572
+ }
573
+
574
+ test("Super Property Manipulator") {
575
+ app = FX::App.new
576
+ w = FX::MainWindow.new app
577
+ t = FX::Text.new w
578
+ superInst = SuperProp.new(t, "super")
579
+ data = "string"
580
+ # testing serialize and deserialize
581
+ ser_data = superInst.serialize superInst.deserialize(data)
582
+ assert_equal data, ser_data
583
+ # getting data before setting it
584
+ assert_nil superInst.get_data
585
+ assert_equal false, superInst.enabled
586
+ # enabling the property and testing get data before setting data
587
+ superInst.set_enabled true
588
+ assert_nil superInst.get_data
589
+ # setting and getting data
590
+ superInst.text_input
591
+ type_array = [
592
+ 5,
593
+ "string",
594
+ true,
595
+ ColorProp.new(t, "color").deserialize("255,255,255,255"),
596
+ FontProp.new(t, "font").deserialize("Tahoma"),
597
+ 1..5
598
+ ]
599
+ type_array.each { |var|
600
+ superInst.set_data var
601
+ assert_equal var.to_s, superInst.get_data
602
+ }
603
+ true
604
+ }
605
+
606
+ end
data/src/properties.rb ADDED
@@ -0,0 +1,119 @@
1
+ # Copyright (c) 2004-2006 by Henon (meinrad dot recheis at gmail dot com)
2
+
3
+ # extension module for Fox::FXWindow that is only mixed in at foxGUIb runtime.
4
+ module Properties
5
+ def create_defaults
6
+ # @defaults: { method_string=> default-value }
7
+ @defaults = {}
8
+ @wdgprops ||= []
9
+ for proplist in [$color_props, $general_props, $const_props, @wdgprops]
10
+ proplist.each { |method, type, array|
11
+ next unless respond_to? method
12
+ @defaults[method] = send(method.chop)
13
+ @defaults[method] = 1 if method.chop == "numColumns"
14
+ }
15
+ end
16
+ end
17
+ # list of property objects
18
+ attr_reader :defaults
19
+
20
+ # load the properties of the widget into the property manager
21
+ def update_properties
22
+ PropMan.instance.nameProp.wdg = self
23
+ PropMan.instance.nameProp.set_data userData.treeitem.to_s
24
+ PropMan.instance.type_lbl.text = self.class.to_s
25
+ PropMan.instance.props.each { |m, manip|
26
+ if @defaults.keys.member? m
27
+
28
+ next unless respond_to?(m.chop)
29
+ value = send(m.chop)
30
+ manip.wdg = self
31
+
32
+ if value.to_s == @defaults[m].to_s
33
+ manip.set_enabled false
34
+ value = @defaults[m]
35
+ else
36
+ manip.set_enabled true
37
+ end
38
+
39
+ manip.set_data value
40
+ manip.visible = true
41
+ manip.show
42
+ else
43
+ manip.visible = false
44
+ manip.hide
45
+ manip.recalc
46
+ end
47
+ }
48
+ EventEditor.instance.set_widget self
49
+ end
50
+
51
+ def reset_default prop_manip
52
+ value = @defaults[prop_manip.method]
53
+ prop_manip.set_data(value)
54
+
55
+ update_wdg prop_manip
56
+ end
57
+
58
+ # a property has been changed. update widget
59
+ def update_wdg prop_manip
60
+ value = prop_manip.get_data
61
+ m = prop_manip.method
62
+ begin
63
+ send(m, value)
64
+ rescue Exception
65
+ puts "error setting property: #{m}, value: #{value}"
66
+ puts $!
67
+ puts $!.backtrace
68
+ end
69
+ recalc
70
+ shell.forceRefresh
71
+ set_dirty
72
+ end
73
+
74
+ def set_name name
75
+ PropMan.instance.nameProp.set_data name
76
+ PropMan.instance.nameProp.wdg = self
77
+ end
78
+
79
+ def set_dirty
80
+ userData.manager.set_dirty
81
+ end
82
+
83
+ # serializes all properties into this hash
84
+ def serialize hash
85
+ @defaults.each { |m, default|
86
+ manip = PropMan.instance.props[m]
87
+ value = send(m.chop)
88
+ hash[m] = manip.serialize(value)
89
+ }
90
+ end
91
+
92
+ # loads all properties from the hash
93
+ def deserialize hash
94
+ hash.each { |method, value|
95
+ manip = PropMan.instance.props[method]
96
+ unless manip
97
+ puts "no property object for #{method}!!"
98
+ next
99
+ end
100
+ dvalue = manip.deserialize(value)
101
+ # ~ if ["icon=", "altIcon="].member?( method)
102
+ # ~ PropMan.instance.init_icons self
103
+ # ~ PropMan.instance.icons[self][method]=value
104
+ # ~ end
105
+ begin
106
+ send(method, dvalue) if respond_to? method
107
+ rescue Exception
108
+ puts "#{method}: invalid value, #{$!}"
109
+ puts $!.backtrace
110
+ end
111
+ recalc
112
+ shell.forceRefresh
113
+ }
114
+ end
115
+ end # module Properties
116
+
117
+ class Fox::FXWindow
118
+ include Properties
119
+ end