libguib 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.
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