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