libguib 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/libGUIb14.rb ADDED
@@ -0,0 +1,1617 @@
1
+ # libGUIb: Copyright (c) by Meinrad Recheis aka Henon, 2006
2
+ # THIS SOFTWARE IS PROVIDED IN THE HOPE THAT IT WILL BE USEFUL
3
+ # WITHOUT ANY IMPLIED WARRANTY OR FITNESS FOR ANY PURPOSE.
4
+ $VERBOSE = nil # <--- this is to overcome a bug in ruby 1.8.x that yields a whole lot of warnings when loading fxruby
5
+ require "fox14"
6
+ def rel_path(a, b)
7
+ raise TypeError unless a.is_a? String and b.is_a? String
8
+ a.tr!("\\", "/")
9
+ b.tr!("\\", "/")
10
+ a = a.split("/")
11
+ b = b.split("/")
12
+ i = 0
13
+ while (a[i] == b[i]) && (i < a.size)
14
+ i += 1
15
+ end
16
+ "../" * (a.size - i) + b[i..-1].join("/")
17
+ end
18
+
19
+ module FX
20
+ class App < Fox::FXApp
21
+ def initialize a = "", b = ""
22
+ super
23
+ @created = false
24
+ $app = $fxapp = self
25
+ end
26
+
27
+ def create(*args)
28
+ super
29
+ @created = true
30
+ end
31
+
32
+ def created?
33
+ @created
34
+ end
35
+ end
36
+ end # FX
37
+
38
+ module MiddleBtn
39
+ def handleMMB_Events
40
+ FXMAPFUNC(Fox::SEL_MIDDLEBUTTONPRESS, 0, :onMiddleBtnPress)
41
+ FXMAPFUNC(Fox::SEL_MIDDLEBUTTONRELEASE, 0, :onMiddleBtnRelease)
42
+ end
43
+
44
+ def onMiddleBtnPress(sender, sel, evt)
45
+ if enabled?
46
+ if !target.nil? && (target.handle(self, MKUINT(selector, Fox::SEL_MIDDLEBUTTONPRESS), evt) != 0)
47
+ return 1
48
+ end
49
+ end
50
+ 0
51
+ end
52
+
53
+ def onMiddleBtnRelease(sender, sel, evt)
54
+ if enabled?
55
+ if !target.nil? && (target.handle(self, MKUINT(selector, Fox::SEL_MIDDLEBUTTONRELEASE), evt) != 0)
56
+ return 1
57
+ end
58
+ end
59
+ 0
60
+ end
61
+ end
62
+
63
+ module RightBtn
64
+ def handleRMB_Events
65
+ FXMAPFUNC(Fox::SEL_MIDDLEBUTTONPRESS, 0, :onMiddleBtnPress)
66
+ FXMAPFUNC(Fox::SEL_MIDDLEBUTTONRELEASE, 0, :onMiddleBtnRelease)
67
+ end
68
+
69
+ def onRightBtnPress(sender, sel, evt)
70
+ if enabled?
71
+ if !target.nil? && (target.handle(self, MKUINT(selector, Fox::SEL_RIGHTBUTTONPRESS), evt) != 0)
72
+ return 1
73
+ end
74
+ end
75
+ 0
76
+ end
77
+
78
+ def onRightBtnRelease(sender, sel, evt)
79
+ if enabled?
80
+ if !target.nil? && (target.handle(self, MKUINT(selector, Fox::SEL_RIGHTBUTTONRELEASE), evt) != 0)
81
+ return 1
82
+ end
83
+ end
84
+ 0
85
+ end
86
+ end
87
+
88
+ def loadImageToString filename
89
+ data = nil
90
+ File.open(filename, "rb") { |f| data = f.read }
91
+ data.unpack1("h#{data.size * 2}")
92
+ end
93
+
94
+ def loadImageFromString s, icon_class = Fox::FXPNGIcon
95
+ raise TypeError unless $fxapp
96
+ imgdata = [s].pack("h#{s.size * 2}")
97
+ img = icon_class.new($fxapp, imgdata, Fox::IMAGE_KEEP | Fox::IMAGE_SHMI | Fox::IMAGE_SHMP)
98
+ img.create
99
+ img
100
+ end
101
+
102
+ def load_dummy
103
+ raise TypeError unless $fxapp
104
+ imgdata = "9805e474d0a0a1a0000000d0948444250000000100000001803000000082d2f035000000a247548547342756164796f6e6024596d65600d4f60293026456260223030343021363a33363a3133302b2031303037c63ded4000000704794d454704d2090f0627041559b9c00000090078495370000b0210000b021102ddde7cf000000407614d41400001bf8b0cf16500000003305c44554000000ffefeffff0f0ffc1c1ffcbcbff7878ff5b5bffc5c5ff7979ff9292ffadadff2f2fff7171ff4747ffb4b4ff6e6eff8383bfe98b0d000000104725e43500046e8d66000000b59444144587ad58ec1ee008028040069333b223d7ff7adec6a39c5b57f38d8f406a3992ea61d0508294b382bda9d373840c595953630f0c1c930ece73e940ee8506f8dc0446f14600fddfa260877711b0c50971c4f5ff898f7819b1678020e2a25402a2000000009454e444ea240628"
105
+ imgdata = [imgdata].pack("h#{imgdata.size * 2}")
106
+ $dummy_img = img = Fox::FXPNGIcon.new($fxapp, imgdata, Fox::IMAGE_KEEP | Fox::IMAGE_SHMI | Fox::IMAGE_SHMP)
107
+ img.create
108
+ img
109
+ end
110
+
111
+ def hasExtension(filename, ext)
112
+ File.basename(filename, ext) != File.basename(filename)
113
+ end
114
+
115
+ def loadImage(file)
116
+ img = load_dummy unless $dummy_img
117
+ unless File.exist? file
118
+ return img
119
+ end
120
+ begin
121
+ opts = Fox::IMAGE_KEEP | Fox::IMAGE_SHMI | Fox::IMAGE_SHMP
122
+ if hasExtension(file, ".gif")
123
+ img = Fox::FXGIFIcon.new($fxapp, nil, opts)
124
+ elsif hasExtension(file, ".bmp")
125
+ img = Fox::FXBMPIcon.new($fxapp, nil, opts)
126
+ elsif hasExtension(file, ".xpm")
127
+ img = Fox::FXXPMIcon.new($fxapp, nil, opts)
128
+ elsif hasExtension(file, ".png")
129
+ img = Fox::FXPNGIcon.new($fxapp, nil, opts)
130
+ elsif hasExtension(file, ".jpg")
131
+ img = Fox::FXJPGIcon.new($fxapp, nil, opts)
132
+ elsif hasExtension(file, ".pcx")
133
+ img = Fox::FXPCXIcon.new($fxapp, nil, opts)
134
+ elsif hasExtension(file, ".tif")
135
+ img = Fox::FXTIFIcon.new($fxapp, nil, opts)
136
+ elsif hasExtension(file, ".tga")
137
+ img = Fox::FXTGAIcon.new($fxapp, nil, opts)
138
+ elsif hasExtension(file, ".ico")
139
+ img = Fox::FXICOIcon.new($fxapp, nil, opts)
140
+ end
141
+ unless img
142
+ puts("Unsupported image type: #{file}")
143
+ return img
144
+ end
145
+ Fox::FXFileStream.open(file, Fox::FXStreamLoad) { |stream| img.loadPixels(stream) }
146
+ img.filename = file
147
+ img.create
148
+ rescue Exception
149
+ puts "load Image: #{$!}"
150
+ end
151
+ img
152
+ end
153
+
154
+ module FX
155
+ class Icon
156
+ def initialize filename
157
+ if filename
158
+ @filename = filename
159
+ @img = loadImage(filename)
160
+ end
161
+ end
162
+ attr_accessor :img
163
+ def to_s
164
+ @filename
165
+ end
166
+
167
+ def self.LoadFromString s, icon_class = Fox::FXPNGIcon
168
+ icon = Icon.new nil
169
+ icon.img = loadImageFromString s, icon_class
170
+ icon
171
+ end
172
+ end
173
+
174
+ class Color
175
+ attr_accessor :r, :g, :b, :a
176
+ def initialize r = 0, g = 0, b = 0, a = nil
177
+ @r, @g, @b, @a = r, g, b, a
178
+ end
179
+
180
+ def to_FXColor
181
+ @a ? Fox::FXRGBA(@r, @g, @b, @a) : Fox::FXRGB(@r, @g, @b)
182
+ end
183
+
184
+ def from_FXColor c
185
+ @r = Fox::FXREDVAL(c)
186
+ @g = Fox::FXGREENVAL(c)
187
+ @b = Fox::FXBLUEVAL(c)
188
+ @a = Fox::FXALPHAVAL(c)
189
+ self
190
+ end
191
+
192
+ def from_name(name)
193
+ from_FXColor(Fox.fxcolorfromname(name))
194
+ self
195
+ end
196
+
197
+ def serialize
198
+ Fox.fxencodeColorData(to_FXColor)
199
+ end
200
+
201
+ def deserialize(data)
202
+ from_FXColor(Fox.fxdecodeColorData(data))
203
+ self
204
+ end
205
+
206
+ def to_s
207
+ (@a ? [@r, @g, @b, @a] : [@r, @g, @b]).join(",")
208
+ end
209
+
210
+ def from_s s
211
+ s = "0, 0, 0, 0" if s.size < 5
212
+ @r, @g, @b, @a = s.split(",").collect { |c| c.to_i }
213
+ self
214
+ end
215
+ end
216
+
217
+ class Font
218
+ def initialize
219
+ @fd = Fox::FXFontDesc.new
220
+ end
221
+ attr_accessor :fd
222
+ def to_s
223
+ @fd.to_s
224
+ end
225
+
226
+ def from_s s
227
+ @fd.from_s s
228
+ self
229
+ end
230
+
231
+ def to_FXFont
232
+ f = Fox::FXFont.new $fxapp, @fd
233
+ f.create
234
+ f
235
+ end
236
+
237
+ def from_FXFont f
238
+ @fd = f.fontDesc
239
+ self
240
+ end
241
+ end
242
+ end # module
243
+
244
+ class Fox::FXIcon
245
+ attr_accessor :filename
246
+ def to_s
247
+ filename || ""
248
+ end
249
+ end
250
+
251
+ class Fox::FXFontDesc
252
+ def to_s
253
+ [face,
254
+ size,
255
+ weight,
256
+ slant,
257
+ encoding,
258
+ setwidth,
259
+ flags].join("|")
260
+ end
261
+
262
+ def from_s(s)
263
+ begin
264
+ a = s.split("|")
265
+ self.face = a[0]
266
+ self.size = a[1].to_i
267
+ self.weight = a[2].to_i
268
+ self.slant = a[3].to_i
269
+ self.encoding = a[4].to_i
270
+ self.setwidth = a[5].to_i
271
+ self.flags = a[6].to_i
272
+ rescue Exception
273
+ puts "error parsing string representation: #{$!}"
274
+ puts $!.backtrace.join($/)
275
+ return nil
276
+ end
277
+ self
278
+ end
279
+
280
+ def init fd
281
+ if fd.is_a? Fox::FXFontDesc
282
+ self.face = fd.face
283
+ self.size = fd.size
284
+ self.weight = fd.weight
285
+ self.slant = fd.slant
286
+ self.encoding = fd.encoding
287
+ self.setwidth = fd.setwidth
288
+ self.flags = fd.flags
289
+ elsif fd.is_a? String
290
+ from_s fd
291
+ end
292
+ end
293
+ end
294
+
295
+ class Fox::FXFont
296
+ def to_s
297
+ fontDesc.to_s
298
+ end
299
+ end
300
+
301
+ class Fox::FXIcon
302
+ attr_accessor :filename
303
+ def to_s
304
+ filename || ""
305
+ end
306
+ end
307
+
308
+ class Module
309
+ def __sends__ *args
310
+ args.each { |arg|
311
+ class_eval <<-CEEND, __FILE__, __LINE__ + 1
312
+ def on_#{arg}(&callback)
313
+ @#{arg}_observers ||= {}
314
+ @#{arg}_observers[caller[0]]=callback
315
+ return caller[0]
316
+ end
317
+ def del_#{arg}(id)
318
+ @#{arg}_observers ||= {}
319
+ return @#{arg}_observers.delete( id)
320
+ end
321
+ private
322
+ def #{arg} *the_args
323
+ @#{arg}_observers ||= {}
324
+ @#{arg}_observers.each { |caller, cb|
325
+ cb.call *the_args
326
+ }
327
+ end
328
+ CEEND
329
+ }
330
+ end
331
+ end
332
+
333
+ module FX
334
+ class RadioGroup
335
+ __sends__ :event_selected
336
+ def initialize
337
+ @radio_widgets = []
338
+ @selected = nil
339
+ end
340
+ attr_reader :radio_widgets
341
+ def add_radio(radio_widget, &block)
342
+ @radio_widgets << radio_widget
343
+ radio_widget.connect(Fox::SEL_COMMAND) {
344
+ select(radio_widget)
345
+ yield if block
346
+ }
347
+ end
348
+ alias_method :<<, :add_radio
349
+ def select radio_widget
350
+ @selected = radio_widget
351
+ event_selected @selected
352
+ for w in @radio_widgets
353
+ w.state = (w == @selected) # only the selected widget is checked.
354
+ end
355
+ end
356
+
357
+ attr_reader :selected
358
+ end
359
+ end # fx
360
+ if Fox.fxrubyversion == "1.4.4"
361
+ class Fox::FXMenuCaption
362
+ def text= text
363
+ @text = text
364
+ setText(text)
365
+ end
366
+
367
+ attr_reader :text
368
+ end
369
+ end
370
+ module FX
371
+ module CheckState
372
+ def state=(x)
373
+ setCheck(x ? Fox::TRUE : Fox::FALSE)
374
+ end
375
+
376
+ def state
377
+ ((getCheckState == Fox::TRUE) ? true : false)
378
+ end
379
+ end
380
+
381
+ module RangeAccessor
382
+ def range= val
383
+ val = val.last..val.first if val.last < val.first
384
+ setRange val
385
+ end
386
+
387
+ def range
388
+ getRange
389
+ end
390
+ end
391
+
392
+ module RadioMutexInterface
393
+ def init_radio_mutex
394
+ @radioGroup = RadioGroup.new
395
+ @radioGroup.on_event_selected { |r| event_selected(r) }
396
+ end
397
+
398
+ def add_radio_option widget
399
+ @radioGroup << widget
400
+ end
401
+
402
+ def selected_radio
403
+ @radioGroup.selected
404
+ end
405
+ end
406
+
407
+ class ArrowButton < Fox::FXArrowButton
408
+ def initialize(p, opts = 0)
409
+ super(p, nil, 0, opts | Fox::ARROW_NORMAL)
410
+ end
411
+ end
412
+
413
+ class Button < Fox::FXButton
414
+ include Responder
415
+ include RightBtn
416
+ include MiddleBtn
417
+ def initialize(p, opts = 0)
418
+ super(p, "Button", nil, nil, 0, Fox::BUTTON_NORMAL | opts)
419
+ handleMMB_Events
420
+ handleRMB_Events
421
+ end
422
+
423
+ def state=(x)
424
+ if x == true
425
+ setState(Fox::STATE_DOWN)
426
+ elsif x == false
427
+ setState(Fox::STATE_UP)
428
+ elsif x.class == Integer
429
+ setState(x)
430
+ end
431
+ end
432
+
433
+ def state
434
+ if getState == Fox::STATE_DOWN then return true
435
+ elsif getState == Fox::STATE_CHECKED then return true
436
+ end
437
+ false
438
+ end
439
+ alias_method :buttonButtonStyle=, :buttonStyle=
440
+ alias_method :buttonButtonStyle, :buttonStyle
441
+ end
442
+
443
+ class Canvas < Fox::FXCanvas
444
+ def initialize(p, opts = 0)
445
+ super(p)
446
+ end
447
+ end
448
+
449
+ class CheckButton < Fox::FXCheckButton
450
+ def initialize(p, opts = 0)
451
+ super(p, "CheckButton")
452
+ end
453
+ include CheckState
454
+ end
455
+
456
+ class ComboBox < Fox::FXComboBox
457
+ def initialize(p, opts = 0)
458
+ super(p, 10, nil, 0, opts | Fox::FRAME_SUNKEN)
459
+ end
460
+
461
+ def comboItems= string
462
+ c = currentItem
463
+ clearItems
464
+ array = string.split(/\r?\n/)
465
+ array.each { |s|
466
+ appendItem s
467
+ }
468
+ self.numVisible = array.size
469
+ self.currentItem = c
470
+ end
471
+
472
+ def comboItems
473
+ array = []
474
+ each { |text, d|
475
+ array << text
476
+ }
477
+ array.join("\n")
478
+ end
479
+
480
+ def auto_resize
481
+ size = 0
482
+ each { |text, d|
483
+ size = text.size if size < text.size
484
+ }
485
+ self.numColumns = size
486
+ self.numVisible = numItems
487
+ end
488
+ end
489
+
490
+ class Dial < Fox::FXDial
491
+ def initialize(p, opts = 0)
492
+ super(p, nil, 0, opts | Fox::DIAL_NORMAL)
493
+ end
494
+ end
495
+
496
+ class DialogBox < Fox::FXDialogBox
497
+ def initialize(p, opts = 0)
498
+ super(p, "title", Fox::DECOR_ALL)
499
+ pad(0, 0, 0, 0)
500
+ handleMMB_Events
501
+ end
502
+ include Responder
503
+ include MiddleBtn
504
+ end
505
+
506
+ class DirBox < Fox::FXDirBox
507
+ def initialize(p, opts = 0)
508
+ super(p, nil, 0, opts | Fox::FRAME_SUNKEN | Fox::TREELISTBOX_NORMAL)
509
+ end
510
+ end
511
+
512
+ class DirList < Fox::FXDirList
513
+ def initialize(p, opts = 0)
514
+ super(p, nil, 0, opts)
515
+ end
516
+ end
517
+
518
+ class DriveBox < Fox::FXDriveBox
519
+ def initialize(p, opts = 0)
520
+ super(p, nil, 0, opts | Fox::FRAME_SUNKEN | Fox::LISTBOX_NORMAL)
521
+ end
522
+ end
523
+
524
+ class FileList < Fox::FXFileList
525
+ def initialize(p, opts = 0)
526
+ super(p, nil, 0, opts | Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y)
527
+ end
528
+ end
529
+
530
+ class Header < Fox::FXHeader
531
+ def initialize(p, opts = 0)
532
+ super(p, nil, 0, opts | Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y | Fox::HEADER_NORMAL)
533
+ end
534
+ end
535
+
536
+ class GroupBox < Fox::FXGroupBox
537
+ def initialize(p, opts = 0)
538
+ super(p, "GroupBox", opts | Fox::FRAME_GROOVE, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4)
539
+ end
540
+ end
541
+
542
+ class HorizontalFrame < Fox::FXHorizontalFrame
543
+ def initialize(p, opts = 0)
544
+ super(p, opts | Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
545
+ end
546
+ end
547
+
548
+ class HorizontalSeparator < Fox::FXHorizontalSeparator
549
+ def initialize(p, opts = Fox::SEPARATOR_GROOVE)
550
+ super(p, Fox::LAYOUT_FILL_X | opts)
551
+ end
552
+ end
553
+
554
+ class IconList < Fox::FXIconList
555
+ def initialize(p, opts = 0)
556
+ super(p, nil, 0, opts | Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y | Fox::HEADER_NORMAL)
557
+ end
558
+ alias_method :iconListStyle=, :listStyle=
559
+ alias_method :iconListStyle, :listStyle
560
+ def addItems names, imagefiles
561
+ names.size.times do |i|
562
+ img = loadImage(imagefiles[i])
563
+ appendItem(names[i], nil, img)
564
+ end
565
+ end
566
+ end
567
+
568
+ class Label < Fox::FXLabel
569
+ def initialize(p, opts = 0)
570
+ super(p, "Label")
571
+ end
572
+ end
573
+
574
+ class List < Fox::FXList
575
+ def initialize(p, opts = 0)
576
+ super(p, nil, 0, opts | Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y | Fox::LIST_NORMAL)
577
+ end
578
+ alias_method :listListStyle=, :listStyle=
579
+ alias_method :listListStyle, :listStyle
580
+ end
581
+
582
+ class ListBox < Fox::FXListBox
583
+ def initialize(p, opts = 0)
584
+ super(p, nil, 0, opts | Fox::FRAME_SUNKEN | Fox::LISTBOX_NORMAL)
585
+ end
586
+ end
587
+
588
+ class MainWindow < Fox::FXMainWindow
589
+ def initialize(p, opts = 0)
590
+ p = p.app if p.is_a? Fox::FXId
591
+ super(p, "MainWindow", nil, nil, Fox::DECOR_ALL)
592
+ end
593
+ end
594
+
595
+ class Matrix < Fox::FXMatrix
596
+ def initialize(p, opts = 0)
597
+ super(p, 1, opts | Fox::MATRIX_BY_ROWS | Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y)
598
+ @cols = self.numColumns = 1
599
+ @rows = self.numRows = 1
600
+ end
601
+
602
+ def matrixStyle=code
603
+ super
604
+ numColumns = @cols
605
+ numRows = @rows
606
+ end
607
+
608
+ def numColumns=(int)
609
+ super(@cols = dim_check(int))
610
+ end
611
+
612
+ def numRows=(int)
613
+ super(@rows = dim_check(int))
614
+ end
615
+
616
+ def dim_check int
617
+ return 1 if int < 1
618
+ return 1 unless int.is_a?(Numeric)
619
+ int
620
+ end
621
+ end
622
+
623
+ class MDIClient < Fox::FXMDIClient
624
+ def initialize(p, opts = 0)
625
+ super(p, opts | Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y)
626
+ end
627
+ end
628
+
629
+ class MenuButton < Fox::FXMenuButton
630
+ include Responder
631
+ include MiddleBtn
632
+ def initialize(p, opts = 0)
633
+ super(p, "MenuButton", nil, nil, opts | Fox::JUSTIFY_NORMAL | Fox::ICON_BEFORE_TEXT | Fox::MENUBUTTON_DOWN)
634
+ handleMMB_Events
635
+ end
636
+ alias_method :menuButtonStyle=, :buttonStyle=
637
+ alias_method :menuButtonStyle, :buttonStyle
638
+ end
639
+
640
+ class MenuCaption < Fox::FXMenuCaption
641
+ include Responder
642
+ include MiddleBtn
643
+ def initialize(p, opts = 0)
644
+ @text = text if Fox.fxrubyversion == "1.4.4"
645
+ super(p, "MenuCaption")
646
+ handleMMB_Events
647
+ end
648
+ end
649
+
650
+ class MenuCascade < Fox::FXMenuCascade
651
+ include Responder
652
+ include MiddleBtn
653
+ def initialize(p, text = "MenuCascade")
654
+ @text = text if Fox.fxrubyversion == "1.4.4"
655
+ super
656
+ handleMMB_Events
657
+ end
658
+ end
659
+
660
+ class MenuCheck < Fox::FXMenuCheck
661
+ include Responder
662
+ include MiddleBtn
663
+ include CheckState
664
+ def initialize(p, text = "MenuCheck")
665
+ @text = text if Fox.fxrubyversion == "1.4.4"
666
+ super
667
+ end
668
+ end
669
+
670
+ class MenuCommand < Fox::FXMenuCommand
671
+ include Responder
672
+ include MiddleBtn
673
+ def initialize(p, text = "MenuCommand")
674
+ @text = text if Fox.fxrubyversion == "1.4.4"
675
+ super
676
+ handleMMB_Events
677
+ end
678
+ end
679
+
680
+ class MenuPane < Fox::FXMenuPane
681
+ include Responder
682
+ include MiddleBtn
683
+ include RadioMutexInterface
684
+ def initialize(p, opts = 0)
685
+ init_radio_mutex
686
+ super(p)
687
+ p.menu = self
688
+ handleMMB_Events
689
+ end
690
+ end
691
+
692
+ class MenuRadio < Fox::FXMenuRadio
693
+ include Responder
694
+ include MiddleBtn
695
+ include CheckState
696
+ def initialize(p, text = "MenuRadio")
697
+ @text = text if Fox.fxrubyversion == "1.4.4"
698
+ super
699
+ parent.add_radio_option self if parent.respond_to? :add_radio_option
700
+ end
701
+ end
702
+
703
+ class MenuTitle < Fox::FXMenuTitle
704
+ include Responder
705
+ include MiddleBtn
706
+ def initialize(p, text = "MenuTitle")
707
+ @text = text if Fox.fxrubyversion == "1.4.4"
708
+ super
709
+ handleMMB_Events
710
+ end
711
+ end
712
+
713
+ class MenuBar < Fox::FXMenuBar
714
+ def initialize(p, opts = 0)
715
+ super(p, opts | Fox::LAYOUT_FILL_X)
716
+ handleMMB_Events
717
+ end
718
+ include Responder
719
+ include MiddleBtn
720
+ end
721
+
722
+ class MenuSeparator < Fox::FXMenuSeparator
723
+ def initialize(p, opts = 0)
724
+ super
725
+ handleMMB_Events
726
+ end
727
+ include Responder
728
+ include MiddleBtn
729
+ end
730
+
731
+ class Option < Fox::FXOption
732
+ def initialize(p, opts = 0)
733
+ super(p, "Option", nil, nil, 0, opts | Fox::JUSTIFY_NORMAL | Fox::ICON_BEFORE_TEXT)
734
+ handleMMB_Events
735
+ end
736
+ include Responder
737
+ include MiddleBtn
738
+ end
739
+
740
+ class OptionMenu < Fox::FXOptionMenu
741
+ def initialize(p, opts = 0)
742
+ super(p, nil, opts | Fox::JUSTIFY_NORMAL | Fox::ICON_BEFORE_TEXT)
743
+ handleMMB_Events
744
+ end
745
+ include Responder
746
+ include MiddleBtn
747
+ end
748
+
749
+ class Packer < Fox::FXPacker
750
+ def initialize(p, opts = 0)
751
+ super(p, opts | Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0)
752
+ end
753
+ end
754
+
755
+ class Popup < Fox::FXPopup
756
+ def initialize(p, opts = 0)
757
+ init_radio_mutex
758
+ super(p, opts | Fox::POPUP_VERTICAL | Fox::FRAME_RAISED | Fox::FRAME_THICK)
759
+ handleMMB_Events
760
+ end
761
+ include Responder
762
+ include MiddleBtn
763
+ include RadioMutexInterface
764
+ end
765
+
766
+ class ProgressBar < Fox::FXProgressBar
767
+ def initialize(p, opts = 0)
768
+ super(p, nil, 0, opts | Fox::LAYOUT_FILL_X)
769
+ self.displayText = Fox::TRUE
770
+ end
771
+
772
+ def displayText=bool
773
+ @displaysText = bool
774
+ bool ? showNumber : hideNumber
775
+ end
776
+
777
+ def displayText
778
+ @displaysText = Fox::FALSE if @displaysText.nil?
779
+ @displaysText
780
+ end
781
+ end
782
+
783
+ class RadioButton < Fox::FXRadioButton
784
+ def initialize(p, opts = 0)
785
+ super(p, "RadioButton", nil, 0, opts | Fox::ICON_BEFORE_TEXT)
786
+ parent.add_radio_option self if parent.respond_to? :add_radio_option
787
+ end
788
+ include CheckState
789
+ end
790
+
791
+ class ScrollArea < Fox::FXScrollArea
792
+ def initialize(p, opts = 0)
793
+ super(p)
794
+ self.layoutHints = Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y
795
+ end
796
+ end
797
+
798
+ class ScrollBar < Fox::FXScrollBar
799
+ def initialize(p, opts = 0)
800
+ super(p)
801
+ end
802
+ alias_method :contentSize, :range
803
+ alias_method :contentSize=, :range=
804
+ end
805
+
806
+ class ScrollWindow < Fox::FXScrollWindow
807
+ def initialize(p, opts = 0)
808
+ super(p)
809
+ self.layoutHints = Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y
810
+ end
811
+ end
812
+
813
+ class Shutter < Fox::FXShutter
814
+ def initialize(p, opts = 0)
815
+ super(p, nil, 0, opts | Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y | Fox::LAYOUT_TOP | Fox::LAYOUT_LEFT | Fox::FRAME_SUNKEN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
816
+ handleMMB_Events
817
+ end
818
+ include Responder
819
+ include MiddleBtn
820
+ end
821
+
822
+ class ShutterItem < Fox::FXShutterItem
823
+ def initialize(p, opts = 0)
824
+ super(p, "ShutterItem", nil, opts | Fox::LAYOUT_FILL_X | Fox::LAYOUT_TOP | Fox::LAYOUT_LEFT, 0, 0, 0, 0, 2, 2, 4, 4, 4, 4)
825
+ button.padBottom = 3
826
+ button.padTop = 3
827
+ button.padLeft = 5
828
+ button.padRight = 5
829
+ handleMMB_Events
830
+ end
831
+
832
+ def text=(text)
833
+ button.text = text
834
+ end
835
+
836
+ def text
837
+ button.text
838
+ end
839
+ include Responder
840
+ include MiddleBtn
841
+ end
842
+
843
+ class Slider < Fox::FXSlider
844
+ def initialize(p, opts = 0)
845
+ super(p, nil, 0, opts | Fox::SLIDER_NORMAL | Fox::LAYOUT_FILL_X)
846
+ end
847
+ include RangeAccessor
848
+ end
849
+
850
+ class Spinner < Fox::FXSpinner
851
+ def initialize(p, opts = 0)
852
+ super(p, 3, nil, 0, opts | Fox::FRAME_SUNKEN)
853
+ end
854
+ include RangeAccessor
855
+ end
856
+
857
+ class Splitter < Fox::FXSplitter
858
+ def initialize(p, opts = 0)
859
+ super(p)
860
+ self.layoutHints = Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y
861
+ end
862
+ end
863
+
864
+ class Switcher < Fox::FXSwitcher
865
+ def initialize(p, opts = 0)
866
+ super
867
+ end
868
+
869
+ def current=(*args)
870
+ super
871
+ rescue Exception
872
+ end
873
+ end
874
+
875
+ class StatusBar < Fox::FXStatusBar
876
+ def initialize(p, opts = 0)
877
+ super(p, opts | Fox::LAYOUT_FILL_X)
878
+ end
879
+ end
880
+
881
+ class StatusLine < Fox::FXStatusLine
882
+ def initialize(p, opts = 0)
883
+ super(p)
884
+ end
885
+ end
886
+
887
+ module TabBarInterface
888
+ attr_reader :tabs
889
+ def create_tab(text = "TabItem")
890
+ @tabs ||= []
891
+ TabItem.new(self) { |i|
892
+ @tabs << i
893
+ i.text = text
894
+ }
895
+ end
896
+
897
+ def remove_tab tab
898
+ @tabs.delete tab
899
+ removeChild(tab)
900
+ end
901
+ end
902
+
903
+ class TabBar < Fox::FXTabBar
904
+ include TabBarInterface
905
+ def initialize(p, opts = 0)
906
+ super(p, nil, 0, opts | Fox::LAYOUT_FILL_X)
907
+ end
908
+ end
909
+
910
+ class TabBook < Fox::FXTabBook
911
+ include TabBarInterface
912
+ def initialize(p, opts = 0)
913
+ super(p, nil, 0, opts | Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y)
914
+ end
915
+ end
916
+
917
+ class TabItem < Fox::FXTabItem
918
+ def initialize(p, opts = 0)
919
+ super(p, "TabItem")
920
+ end
921
+
922
+ def index
923
+ parent.tabs.index(self)
924
+ end
925
+ end
926
+
927
+ class Text < Fox::FXText
928
+ def initialize(p, opts = 0)
929
+ super(p, nil, 0, opts | Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y)
930
+ text = "Text"
931
+ end
932
+ alias_method :textTextStyle=, :textStyle=
933
+ alias_method :textTextStyle, :textStyle
934
+ end
935
+
936
+ class TextField < Fox::FXTextField
937
+ def initialize(p, opts = 0)
938
+ super(p, 10, nil, 0, opts | Fox::FRAME_SUNKEN)
939
+ text = "TextField"
940
+ end
941
+
942
+ def text=(*args)
943
+ args.collect! { |a| a.to_s }
944
+ super
945
+ end
946
+ alias_method :textFieldTextStyle=, :textStyle=
947
+ alias_method :textFieldTextStyle, :textStyle
948
+ end
949
+
950
+ class ToggleButton < Fox::FXToggleButton
951
+ def initialize p, opts = 0
952
+ super(p, "Toggle", "Button", nil, nil, nil, 0, opts | Fox::TOGGLEBUTTON_KEEPSTATE)
953
+ end
954
+
955
+ def altImg= filename
956
+ if filename.size > 0
957
+ setAltIcon loadImage(filename)
958
+ @alt_icon_filename = filename
959
+ end
960
+ end
961
+
962
+ def altImg
963
+ @alt_icon_filename.to_s
964
+ end
965
+ end
966
+
967
+ class ToolBar < Fox::FXToolBar
968
+ def initialize(p, opts = 0)
969
+ super(p, opts | Fox::LAYOUT_FILL_X)
970
+ end
971
+ end
972
+
973
+ class TreeList < Fox::FXTreeList
974
+ def initialize(p, opts = 0)
975
+ super(p, nil, 0, opts | Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y)
976
+ end
977
+ alias_method :treeListStyle=, :listStyle=
978
+ alias_method :treeListStyle, :listStyle
979
+ def initialize_language_ids
980
+ each { |ti|
981
+ ti.initialize_language_ids
982
+ }
983
+ end
984
+ end
985
+
986
+ class VerticalFrame < Fox::FXVerticalFrame
987
+ def initialize(p, opts = 0)
988
+ super(p, opts | Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
989
+ end
990
+ end
991
+
992
+ class VerticalSeparator < Fox::FXVerticalSeparator
993
+ def initialize(p, opts = Fox::SEPARATOR_GROOVE)
994
+ super(p, Fox::LAYOUT_FILL_Y | opts)
995
+ end
996
+ end
997
+
998
+ class WidgetTable < GroupBox
999
+ def initialize(p, opts = 0)
1000
+ @c = {}
1001
+ @r = []
1002
+ @nc = 0
1003
+ super
1004
+ self.text = ""
1005
+ self.vSpacing = 0
1006
+ self.frameStyle = FRAME_NONE
1007
+ pad 2, 2, 2, 2
1008
+ end
1009
+
1010
+ def rows
1011
+ @r.size
1012
+ end
1013
+
1014
+ def cols
1015
+ @nc
1016
+ end
1017
+
1018
+ def size=(w, h)
1019
+ end
1020
+
1021
+ def add_col
1022
+ @nc += 1
1023
+ @r.each_with_index { |r, y|
1024
+ VerticalFrame.new(r) { |f|
1025
+ @c[[@nc - 1, y]] = f
1026
+ f.pad 0, 0, 0, 0
1027
+ }
1028
+ }
1029
+ end
1030
+
1031
+ def add_row
1032
+ HorizontalFrame.new(self) { |h|
1033
+ h.frameStyle = FRAME_NONE
1034
+ h.pad 0, 0, 0, 0
1035
+ h.layoutHints = Fox::LAYOUT_FILL_X # |Fox::LAYOUT_FILL_Y
1036
+ @r << h
1037
+ @nc.times { |x|
1038
+ VerticalFrame.new(h) { |f|
1039
+ @c[[x, rows - 1]] = f
1040
+ f.pad 0, 0, 0, 0
1041
+ }
1042
+ }
1043
+ }
1044
+ end
1045
+
1046
+ def cell(x, y)
1047
+ @c[[x, y]]
1048
+ end
1049
+ end
1050
+
1051
+ class RadioMutex < FX::VerticalFrame
1052
+ __sends__ :event_selected
1053
+ def initialize(p)
1054
+ init_radio_mutex
1055
+ super
1056
+ end
1057
+ include RadioMutexInterface
1058
+ end
1059
+ Menubar = MenuBar
1060
+ Toolbar = ToolBar
1061
+ Scrollbar = ScrollBar
1062
+ Statusbar = StatusBar
1063
+ Statusline = StatusLine
1064
+ end # module FX
1065
+
1066
+ class Fox::FXId
1067
+ attr_accessor :wdg_name # a user-given name to identify the wdg
1068
+ def app
1069
+ $fxapp
1070
+ end
1071
+ end
1072
+
1073
+ class Fox::FXWindow
1074
+ def enabled=bool
1075
+ bool ? enable : disable
1076
+ end
1077
+ alias_method :enabled, :enabled?
1078
+ def visible=bool
1079
+ bool ? show : hide
1080
+ end
1081
+ alias_method :visible?, :shown
1082
+ alias_method :visible, :shown
1083
+ def pad(*args)
1084
+ args[0] ? self.padLeft = args[0] : nil
1085
+ args[1] ? self.padRight = args[1] : nil
1086
+ args[2] ? self.padTop = args[2] : nil
1087
+ args[3] ? self.padBottom = args[3] : nil
1088
+ end
1089
+
1090
+ def padding
1091
+ [padLeft, padRight, padTop, padBottom]
1092
+ end
1093
+
1094
+ def recursive(&block) # {|wdg| ... }
1095
+ if block
1096
+ yield(self)
1097
+ children.each { |child| child.recursive(&block) }
1098
+ end
1099
+ end
1100
+ end
1101
+
1102
+ module ImgAccessors
1103
+ def img= filename
1104
+ raise TypeError unless filename.is_a? String
1105
+ if filename.size > 0
1106
+ setIcon loadImage(filename)
1107
+ @icon_filename = filename
1108
+ end
1109
+ end
1110
+
1111
+ def img
1112
+ @icon_filename.to_s
1113
+ end
1114
+ end
1115
+
1116
+ class Fox::FXLabel
1117
+ include ImgAccessors
1118
+ end
1119
+
1120
+ class Fox::FXMenuCaption
1121
+ include ImgAccessors
1122
+ end
1123
+
1124
+ class FileSelector
1125
+ def initialize(parent)
1126
+ construct_widget_tree(parent)
1127
+ init if respond_to? :init
1128
+ end
1129
+
1130
+ def construct_widget_tree(parent)
1131
+ @topwin =
1132
+ FX::HorizontalFrame.new(parent) { |w|
1133
+ @FileSelector = w
1134
+ w.padLeft = 0
1135
+ w.frameStyle = 0
1136
+ w.padRight = 0
1137
+ w.hSpacing = 2
1138
+ w.height = 21
1139
+ w.layoutHints = 1024
1140
+ FX::Label.new(@FileSelector) { |w|
1141
+ @label = w
1142
+ w.text = "File:"
1143
+ w.width = 24
1144
+ w.x = 0
1145
+ }
1146
+ FX::TextField.new(@FileSelector) { |w|
1147
+ @textfield = w
1148
+ w.width = 297
1149
+ w.y = 0
1150
+ w.layoutHints = 1024
1151
+ w.x = 26
1152
+ }
1153
+ FX::Button.new(@FileSelector) { |w|
1154
+ @browse = w
1155
+ w.text = "Browse..."
1156
+ w.padLeft = 4
1157
+ w.width = 59
1158
+ w.padRight = 4
1159
+ w.y = 0
1160
+ w.x = 325
1161
+ }
1162
+ }
1163
+ end
1164
+ attr_accessor :topwin,
1165
+ :FileSelector,
1166
+ :label,
1167
+ :textfield,
1168
+ :browse,
1169
+ :__foxGUIb__last__
1170
+ end
1171
+
1172
+ class FileSelector
1173
+ def init
1174
+ @title = "File Dialog"
1175
+ @relative_path = false
1176
+ @filename = ""
1177
+ @directory = Dir.getwd
1178
+ @dialog = Fox::FXFileDialog.new(@topwin, @title)
1179
+ @patterns = ["All Files (*)"]
1180
+ @currentPattern = 0
1181
+ @browse.connect(Fox::SEL_COMMAND, method(:onBrowse))
1182
+ end
1183
+ attr_accessor :directory, :patterns, :currentPattern, :title, :filename, :relative_path
1184
+ attr_accessor :onNewFilenameBlock
1185
+ def description=text
1186
+ @label.text = text
1187
+ end
1188
+
1189
+ def description
1190
+ @label.text
1191
+ end
1192
+
1193
+ def onBrowse(*args)
1194
+ @dialog.title = @title
1195
+ @dialog.directory = @directory
1196
+ @dialog.patternList = @patterns
1197
+ @currentPattern = 0 if @currentPattern >= @patterns.size
1198
+ @dialog.currentPattern = @currentPattern
1199
+ @dialog.filename = filename.to_s
1200
+ if @dialog.execute != 0
1201
+ @filename = @textfield.text = if @relative_path
1202
+ rel_path(Dir.getwd, @dialog.filename)
1203
+ else
1204
+ @dialog.filename
1205
+ end
1206
+ @onNewFilenameBlock.call if @onNewFilenameBlock.respond_to? :call
1207
+ end
1208
+ end
1209
+ end
1210
+
1211
+ class PathSelector
1212
+ def initialize(parent)
1213
+ construct_widget_tree(parent)
1214
+ init if respond_to? :init
1215
+ end
1216
+
1217
+ def construct_widget_tree(parent)
1218
+ @topwin =
1219
+ FX::HorizontalFrame.new(parent) { |w|
1220
+ @PathSelector = w
1221
+ w.padLeft = 0
1222
+ w.frameStyle = 0
1223
+ w.padRight = 0
1224
+ w.hSpacing = 2
1225
+ w.height = 21
1226
+ w.layoutHints = 1024
1227
+ FX::Label.new(@PathSelector) { |w|
1228
+ @label = w
1229
+ w.text = "Path:"
1230
+ w.width = 30
1231
+ w.x = 0
1232
+ }
1233
+ FX::TextField.new(@PathSelector) { |w|
1234
+ @textfield = w
1235
+ w.width = 291
1236
+ w.y = 0
1237
+ w.layoutHints = 1024
1238
+ w.x = 32
1239
+ }
1240
+ FX::Button.new(@PathSelector) { |w|
1241
+ @browse = w
1242
+ w.text = "Browse..."
1243
+ w.padLeft = 4
1244
+ w.width = 59
1245
+ w.padRight = 4
1246
+ w.y = 0
1247
+ w.x = 325
1248
+ }
1249
+ }
1250
+ end
1251
+ attr_accessor :topwin,
1252
+ :PathSelector,
1253
+ :label,
1254
+ :textfield,
1255
+ :browse,
1256
+ :__foxGUIb__last__
1257
+ end
1258
+ s = "PathSelector-extension.rb"
1259
+ require s if File.exist?(s)
1260
+ module FX
1261
+ class Container < FX::VerticalFrame
1262
+ attr_reader :header, :hsep
1263
+ def initialize(parent)
1264
+ super
1265
+ boxMinusPNG_Str =
1266
+ "9805e474d0a0a1a0000000d09484442500000090000000904030000010568bb25b000000704794d4" +
1267
+ "54704d50016041822c41f2b600000090078495370000b0210000b021102ddde7cf000000407614d4" +
1268
+ "1400001bf8b0cf16500000009005c44554484848ffffff0000003e75793f000000229444144587ad" +
1269
+ "3606082062011a404cc82801c0402828c024a80221c2c28288584000525c10091d50980600000000" +
1270
+ "9454e444ea240628"
1271
+ boxPlusPNG_Str =
1272
+ "9805e474d0a0a1a0000000d09484442500000090000000904030000010568bb25b000000704794d4" +
1273
+ "54704d50016041c0ef71bcab00000090078495370000b0210000b021102ddde7cf000000407614d4" +
1274
+ "1400001bf8b0cf16500000009005c44554484848ffffff0000003e75793f000000729444144587ad" +
1275
+ "3606082062011a404cc8a801c0402828c024a8022142c2802a91505119840a8000c25a100daa1682" +
1276
+ "d9000000009454e444ea240628"
1277
+ self.padLeft = 0
1278
+ self.frameStyle = 12288
1279
+ self.layoutHints = Fox::LAYOUT_FILL_X
1280
+ self.padRight = 0
1281
+ @openIcon = Icon.LoadFromString boxMinusPNG_Str
1282
+ @closedIcon = Icon.LoadFromString boxPlusPNG_Str
1283
+ FX::Label.new(self) { |w|
1284
+ @header = w
1285
+ w.layoutHints = Fox::LAYOUT_FILL_X
1286
+ w.iconPosition = Fox::ICON_BEFORE_TEXT
1287
+ w.justify = Fox::JUSTIFY_LEFT
1288
+ w.icon = @openIcon.img
1289
+ @open = true
1290
+ }
1291
+ FX::HorizontalSeparator.new(self) { |w|
1292
+ @hsep = w
1293
+ w.padLeft = 0
1294
+ w.padRight = 0
1295
+ }
1296
+ @header.connect(SEL_LEFTBUTTONPRESS) {
1297
+ if @open
1298
+ close_body
1299
+ else
1300
+ open_body
1301
+ end
1302
+ }
1303
+ end
1304
+
1305
+ def close_body
1306
+ @open = false
1307
+ @header.icon = @closedIcon.img
1308
+ children.each { |ch|
1309
+ next if ch == @header
1310
+ ch.hide
1311
+ }
1312
+ if layoutHints & LAYOUT_FILL_Y == LAYOUT_FILL_Y
1313
+ self.layoutHints -= LAYOUT_FILL_Y
1314
+ @fill_y = true
1315
+ else
1316
+ @fill_y = false
1317
+ end
1318
+ recalc
1319
+ end
1320
+
1321
+ def open_body
1322
+ @open = true
1323
+ @header.icon = @openIcon.img
1324
+ children.each { |ch|
1325
+ next if ch == @header
1326
+ ch.show
1327
+ }
1328
+ self.layoutHints |= LAYOUT_FILL_Y if @fill_y
1329
+ recalc
1330
+ end
1331
+
1332
+ def title=(text)
1333
+ @header.text = text
1334
+ end
1335
+
1336
+ def title
1337
+ @header.text
1338
+ end
1339
+ end
1340
+ end
1341
+
1342
+ module RadioGroup1
1343
+ def RadioGroup1_initialize
1344
+ @RadioGroup1_initialized = true
1345
+ @RadioGroup1_listeners ||= []
1346
+ end
1347
+
1348
+ def radio_command w
1349
+ RadioGroup1_initialize unless @RadioGroup1_initialized
1350
+ return if @selected_radio_widget == w
1351
+ if @selected_radio_widget
1352
+ @selected_radio_widget.set_radio_state false
1353
+ end
1354
+ @selected_radio_widget = w
1355
+ @RadioGroup1_listeners.each { |l|
1356
+ l.on_event(@selected_radio_widget)
1357
+ }
1358
+ end
1359
+ attr_accessor :selected_radio_widget, :RadioGroup1_listeners
1360
+ end
1361
+
1362
+ module RadioWidget
1363
+ def radio_initialize col = FX::Color.new(255, 255, 255)
1364
+ @radio_initialized = true
1365
+ @radioBackColor = FX::Color.new.from_FXColor(backColor)
1366
+ @radioSelectColor ||= col
1367
+ @state = false
1368
+ connect(SEL_LEFTBUTTONPRESS, method(:lmb_press))
1369
+ end
1370
+ attr_accessor :radioSelectColor, :radioSelectColor
1371
+ def set_radio_state state
1372
+ @state = state
1373
+ change_radio_selection
1374
+ end
1375
+
1376
+ def change_radio_selection
1377
+ self.backColor = @state ? @radioSelectColor.to_FXColor : @radioBackColor.to_FXColor
1378
+ end
1379
+ attr_accessor :state, :group, :lmbdown
1380
+ def lmb_press(*args)
1381
+ if @group and @group.respond_to?(:radio_command)
1382
+ set_radio_state true
1383
+ @group.radio_command(self)
1384
+ else
1385
+ set_radio_state(!@state)
1386
+ end
1387
+ @lmbdown = true
1388
+ 0
1389
+ end
1390
+ end
1391
+
1392
+ module FX
1393
+ class RadioMatrix < Fox::FXMatrix
1394
+ include RadioGroup1
1395
+ def initialize(p)
1396
+ super
1397
+ end
1398
+ end
1399
+
1400
+ class RadioLabel < Label
1401
+ include RadioWidget
1402
+ def initialize(p)
1403
+ super
1404
+ radio_initialize
1405
+ end
1406
+ end
1407
+ end
1408
+
1409
+ module FX
1410
+ class TableWidget < FX::VerticalFrame
1411
+ HEADER_COLOR = Fox::FXRGB(200, 200, 200)
1412
+ def initialize(*args)
1413
+ super
1414
+ @autoresize_titles = true
1415
+ Header.new(self) { |w|
1416
+ @header = w
1417
+ w.headerStyle = HEADER_HORIZONTAL | HEADER_TRACKING
1418
+ w.frameStyle = 0
1419
+ w.backColor = HEADER_COLOR
1420
+ w.connect(SEL_CONFIGURE) {
1421
+ set_title_widths
1422
+ }
1423
+ w.layoutHints = LAYOUT_FILL_X | LAYOUT_FIX_HEIGHT
1424
+ w.height = 20
1425
+ }
1426
+ FXMatrix.new(self, 1) { |w|
1427
+ @matrix = w
1428
+ }
1429
+ end
1430
+ attr_accessor :autoresize_titles
1431
+ def create
1432
+ super
1433
+ end
1434
+
1435
+ def set_titles stringarr
1436
+ stringarr.each { |str|
1437
+ @header.appendItem(" " + str)
1438
+ }
1439
+ set_cols stringarr.size
1440
+ set_title_widths
1441
+ end
1442
+
1443
+ def set_title_widths numarray = nil
1444
+ if numarray
1445
+ else # ok, calculate the item widths from their titles
1446
+ total = 0
1447
+ totalsize = 0
1448
+ i = 0
1449
+ @header.each { |item|
1450
+ total += item.text.size
1451
+ totalsize += item.size
1452
+ item.data = i
1453
+ i += 1
1454
+ }
1455
+ if @autoresize_titles or totalsize == 0
1456
+ quant = (@header.width / total.to_f)
1457
+ offset = 0
1458
+ @header.each { |item|
1459
+ i = item.data
1460
+ size = (item.text.size * quant).to_i
1461
+ @header.setItemSize i, size
1462
+ offset += size
1463
+ }
1464
+ end
1465
+ end
1466
+ end
1467
+
1468
+ def set_cols n
1469
+ end
1470
+
1471
+ def set_rows n
1472
+ end
1473
+ end
1474
+ end
1475
+
1476
+ class StyleVisitor
1477
+ def apply_to(widget, recursive = true)
1478
+ widget.recursive { |w|
1479
+ identifier = "#{w.class.to_s.gsub(/Fox|::|FX/, "")}_style"
1480
+ send identifier, w # if respond_to? identifier
1481
+ break unless recursive
1482
+ }
1483
+ end
1484
+ end
1485
+
1486
+ class FlatStyle < StyleVisitor
1487
+ attr_accessor :frameColor
1488
+ def initialize
1489
+ @frameColor = Fox::FXRGB 0, 0, 0
1490
+ @backColor = Fox::FXRGB 230, 230, 230
1491
+ end
1492
+
1493
+ def Button_style w
1494
+ w.frameStyle = Fox::FRAME_LINE
1495
+ w.hiliteColor = @frameColor
1496
+ w.shadowColor = @frameColor
1497
+ w.backColor = @backColor
1498
+ end
1499
+
1500
+ def TextField_style w
1501
+ w.frameStyle = Fox::FRAME_LINE
1502
+ w.borderColor = Fox::FXRGB 168, 168, 168
1503
+ end
1504
+
1505
+ def method_missing(*args)
1506
+ identifier, w = args
1507
+ unless /style/.match?(identifier.to_s)
1508
+ raise args.join(",")
1509
+ end
1510
+ w.backColor = @backColor
1511
+ end
1512
+ end
1513
+
1514
+ module FX
1515
+ class DCWindow < Fox::FXDCWindow
1516
+ def initialize(*args)
1517
+ super
1518
+ setOrigin(0, 0)
1519
+ end
1520
+
1521
+ def getOrigin
1522
+ [@xOrigin, @yOrigin]
1523
+ end
1524
+
1525
+ def setOrigin x = 0, y = 0
1526
+ @xOrigin = x
1527
+ @yOrigin = y
1528
+ @originStack = [x, y]
1529
+ end
1530
+
1531
+ def pushOrigin x = 0, y = 0
1532
+ @xOrigin += x
1533
+ @yOrigin += y
1534
+ @originStack.push [@xOrigin, @yOrigin]
1535
+ end
1536
+
1537
+ def popOrigin
1538
+ @originStack.pop if @originStack.size > 1
1539
+ @xOrigin, @yOrigin = @originStack.last
1540
+ end
1541
+
1542
+ def drawText x, y, text, bg = false
1543
+ if bg
1544
+ drawImageText(@xOrigin + x, @yOrigin + y, text)
1545
+ else
1546
+ super(@xOrigin + x, @yOrigin + y, text)
1547
+ end
1548
+ end
1549
+
1550
+ def drawImageText x, y, text
1551
+ super(@xOrigin + x, @yOrigin + y, text)
1552
+ end
1553
+
1554
+ def drawLine x, y, x1, y1
1555
+ super(@xOrigin + x, @yOrigin + y, @xOrigin + x1, @yOrigin + y1)
1556
+ end
1557
+
1558
+ def fillRectangle x, y, w, h
1559
+ super(@xOrigin + x, @yOrigin + y, w, h)
1560
+ end
1561
+
1562
+ def drawRectangle x, y, w, h
1563
+ super(@xOrigin + x, @yOrigin + y, w, h)
1564
+ end
1565
+ end
1566
+
1567
+ class DrawingCanvas < Canvas
1568
+ __sends__ :event_draw
1569
+ def initialize parent
1570
+ super(parent, Fox::LAYOUT_FILL_X | Fox::LAYOUT_FILL_Y)
1571
+ @stdFont = Fox::FXFont.new($fxapp, "[helvetica] 90 700 1 1 0 0")
1572
+ @stdFont.create
1573
+ connect(Fox::SEL_PAINT) { |sender, sel, event|
1574
+ resize parent.width, parent.height if width != parent.width or height != parent.height
1575
+ dc = DCWindow.new self
1576
+ dc.font = @stdFont
1577
+ event_draw(dc, event, self)
1578
+ dc.end
1579
+ }
1580
+ end
1581
+ end
1582
+ end
1583
+
1584
+ class PathSelector
1585
+ def init
1586
+ @title = "Directory Dialog"
1587
+ @relative_path = false
1588
+ @directory = Dir.getwd
1589
+ update(@directory)
1590
+ @dialog = FXDirDialog.new(@topwin, @title)
1591
+ @browse.connect(SEL_COMMAND, method(:onBrowse))
1592
+ end
1593
+ attr_accessor :directory, :title, :filename, :relative_path
1594
+ def description=text
1595
+ @label.text = text
1596
+ end
1597
+
1598
+ def description
1599
+ @label.text
1600
+ end
1601
+
1602
+ def onBrowse(*args)
1603
+ @dialog.title = @title
1604
+ @dialog.directory = @directory
1605
+ if @dialog.execute != 0
1606
+ update(@dialog.directory)
1607
+ end
1608
+ end
1609
+
1610
+ def update(path)
1611
+ @directory = @textfield.text = if @relative_path
1612
+ rel_path(Dir.getwd, path)
1613
+ else
1614
+ path
1615
+ end
1616
+ end
1617
+ end