foxguib 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/changelog.txt +128 -0
  4. data/doc/www/index.html +173 -0
  5. data/doc/www/upload.rb +9 -0
  6. data/examples/event_handler.rb +67 -0
  7. data/examples/event_handlers.rbin +0 -0
  8. data/examples/guib_testdialog.rb +31 -0
  9. data/examples/testdialog.rb +29 -0
  10. data/exe/foxguib +1 -0
  11. data/foxGUIb-debug.rb +37 -0
  12. data/foxGUIb.rb +88 -0
  13. data/foxGUIb_win32.rbw +1 -0
  14. data/foxguib.gemspec +26 -0
  15. data/license.txt +49 -0
  16. data/readme.txt +1 -0
  17. data/release_notes.txt +68 -0
  18. data/src/assert.rb +8 -0
  19. data/src/cfgman.rb +27 -0
  20. data/src/code-gen/code-generator.rb +171 -0
  21. data/src/code-gen/property-generators.rb +65 -0
  22. data/src/code-gen/widget-generator.rb +22 -0
  23. data/src/convert.rb +60 -0
  24. data/src/direct_widget_manipulation.rb +343 -0
  25. data/src/docman.rb +260 -0
  26. data/src/document.rb +405 -0
  27. data/src/event_categories.yaml +85 -0
  28. data/src/event_listener.rb +57 -0
  29. data/src/events.yaml +77 -0
  30. data/src/events_docu.yaml +228 -0
  31. data/src/get_events.rb +64 -0
  32. data/src/gui/ArrowButton.tga +0 -0
  33. data/src/gui/BoxMinus.tga +0 -0
  34. data/src/gui/BoxPlus.tga +0 -0
  35. data/src/gui/Button.tga +0 -0
  36. data/src/gui/CheckButton.tga +0 -0
  37. data/src/gui/ComboBox.tga +0 -0
  38. data/src/gui/Dial.tga +0 -0
  39. data/src/gui/GroupBox.tga +0 -0
  40. data/src/gui/HorizontalFrame.tga +0 -0
  41. data/src/gui/HorizontalSeparator.tga +0 -0
  42. data/src/gui/Label.tga +0 -0
  43. data/src/gui/MDIChild.tga +0 -0
  44. data/src/gui/MDIClient.tga +0 -0
  45. data/src/gui/Matrix.tga +0 -0
  46. data/src/gui/MenuCaption.tga +0 -0
  47. data/src/gui/MenuCascade.tga +0 -0
  48. data/src/gui/MenuCheck.tga +0 -0
  49. data/src/gui/MenuCommand.tga +0 -0
  50. data/src/gui/MenuPane.tga +0 -0
  51. data/src/gui/MenuRadio.tga +0 -0
  52. data/src/gui/MenuSeparator.tga +0 -0
  53. data/src/gui/MenuTitle.tga +0 -0
  54. data/src/gui/Menubar.tga +0 -0
  55. data/src/gui/Packer.tga +0 -0
  56. data/src/gui/ProgressBar.tga +0 -0
  57. data/src/gui/RadioButton.tga +0 -0
  58. data/src/gui/RadioMutex.tga +0 -0
  59. data/src/gui/ScrollWindow.tga +0 -0
  60. data/src/gui/Scrollbar.tga +0 -0
  61. data/src/gui/Shutter.tga +0 -0
  62. data/src/gui/ShutterItem.tga +0 -0
  63. data/src/gui/Slider.tga +0 -0
  64. data/src/gui/Spinner.tga +0 -0
  65. data/src/gui/Splitter.tga +0 -0
  66. data/src/gui/StatusBar.tga +0 -0
  67. data/src/gui/Statusline.tga +0 -0
  68. data/src/gui/Switcher.tga +0 -0
  69. data/src/gui/TabBar.tga +0 -0
  70. data/src/gui/TabBook.tga +0 -0
  71. data/src/gui/TabItem.tga +0 -0
  72. data/src/gui/Text.tga +0 -0
  73. data/src/gui/TextField.tga +0 -0
  74. data/src/gui/ToggleButton.tga +0 -0
  75. data/src/gui/Toolbar.tga +0 -0
  76. data/src/gui/VerticalFrame.tga +0 -0
  77. data/src/gui/VerticalSeparator.tga +0 -0
  78. data/src/gui/_guib_event_editor.rb +185 -0
  79. data/src/gui/_guib_event_editor.rbin +0 -0
  80. data/src/gui/_guib_genruby.rb +414 -0
  81. data/src/gui/_guib_genruby.rbin +0 -0
  82. data/src/gui/_guib_mainwin.rb +574 -0
  83. data/src/gui/_guib_mainwin.rbin +0 -0
  84. data/src/gui/event_editor.rb +180 -0
  85. data/src/gui/genruby.rb +155 -0
  86. data/src/gui/guib__console.rb +265 -0
  87. data/src/gui/mainwin.rb +71 -0
  88. data/src/gui/ruby_console.rb +263 -0
  89. data/src/gui/svg/Matrix.svg +87 -0
  90. data/src/gui/svg/MenuCheck.svg +135 -0
  91. data/src/gui/svg/MenuRadio.svg +130 -0
  92. data/src/gui/svg/RadioMutex.svg +119 -0
  93. data/src/gui/textview.rb +101 -0
  94. data/src/gui/textview.rbin +0 -0
  95. data/src/minitest.rb +60 -0
  96. data/src/prop-lists.rb +323 -0
  97. data/src/prop-types.rb +606 -0
  98. data/src/properties.rb +119 -0
  99. data/src/propman.rb +88 -0
  100. data/src/relink_mechanisms.rb +95 -0
  101. data/src/serialize.rb +167 -0
  102. data/src/state_machine.rb +73 -0
  103. data/src/version.rb +6 -0
  104. data/src/widget-lists.rb +118 -0
  105. data/src/widget-selector.rb +85 -0
  106. data/src/widgettree-controls.rb +183 -0
  107. data.tar.gz.sig +0 -0
  108. metadata +236 -0
  109. metadata.gz.sig +0 -0
data/src/propman.rb ADDED
@@ -0,0 +1,88 @@
1
+ # Copyright (c) 2004-2006 by Henon (meinrad dot recheis at gmail dot com)
2
+ require "singleton"
3
+ require "prop-lists"
4
+ include FX
5
+ require "prop-types"
6
+ # require 'container'
7
+ class PropMan
8
+ include Singleton
9
+ @@created = false
10
+ def initialize
11
+ @props = {}
12
+ end
13
+
14
+ def self.created?
15
+ @@created
16
+ end
17
+ attr_accessor :type_lbl
18
+ # widget name manipulator
19
+ attr_reader :nameProp, :props, :icons
20
+
21
+ def refresh
22
+ # ~ @sh.recalc
23
+ # ~ @sh.forceRefresh
24
+ end
25
+
26
+ def make_container(p, title)
27
+ c = Container.new(p)
28
+ c.title = title
29
+ c.header.backColor = HEADER_COLOR
30
+ c
31
+ end
32
+
33
+ def create width
34
+ @@created = true
35
+ v = p = MAINWIN.prop_Frame
36
+ v.vSpacing = 2
37
+ v.packingHints = PACK_UNIFORM_WIDTH
38
+ Label.new(v) { |l|
39
+ @type_lbl = l
40
+ l.text = " "
41
+ }
42
+ @nameProp = NameProp.new(v)
43
+ i = make_container v, "Flags"
44
+ add_prop_manipulators $const_props, i
45
+ i = make_container v, "General"
46
+ add_prop_manipulators $general_props, i
47
+ i = make_container v, "Color Properties"
48
+ add_prop_manipulators $color_props, i
49
+ $font_dlg = Fox::FXFontDialog.new p, "Font Selection Dialog"
50
+ $color_dlg = Fox::FXColorDialog.new p, "Color Selection Dialog"
51
+ p.recursive { |w|
52
+ w.baseColor = STD_BACK_COLOR
53
+ next if w.is_a? TextField
54
+ next if w.backColor == HEADER_COLOR
55
+ w.backColor = STD_BACK_COLOR
56
+ }
57
+ end
58
+
59
+ # creates all the propmanipulators and adds them to the parent p
60
+ def add_prop_manipulators list, p
61
+ list.each { |method, type, array|
62
+ # ~ next unless respond_to? method
63
+ begin
64
+ c = Object.const_get(type)
65
+ @props[method] = c.new(p, method, array)
66
+ rescue
67
+ puts "type #{type}:"
68
+ puts $!
69
+ puts $!.backtrace.join("\n")
70
+ next
71
+ end
72
+ }
73
+ end
74
+
75
+ def reset_props
76
+ # puts "reset_props"
77
+ @type_lbl.text = " "
78
+ @nameProp.set_data ""
79
+ @props.each { |m, manip|
80
+ manip.wdg = nil
81
+ manip.set_enabled(false)
82
+ manip.visible = true
83
+ manip.show
84
+ manip.forceRefresh
85
+ }
86
+ MAINWIN.prop_Frame.recalc
87
+ end
88
+ end
@@ -0,0 +1,95 @@
1
+ # Copyright (c) 2004-2006 by Henon (meinrad dot recheis at gmail dot com)
2
+
3
+ module RelinkMechanisms
4
+ def self.relink_possible?(source, where, target)
5
+ # general
6
+ return false if source.nil? or target.nil?
7
+ return false if source == target
8
+ return false if target.childOf? source
9
+ insert_possible?(where, target)
10
+ end
11
+
12
+ def self.insert_possible? where, target
13
+ raise TypeError unless where.is_a? String and target.is_a? Fox::FXWindow
14
+ return false if where == "inside" and !target.composite?
15
+ return false if where == "before" and target.is_a? Fox::FXTopWindow
16
+ return false if where == "after" and target.is_a? Fox::FXTopWindow
17
+ true
18
+ end
19
+
20
+ def self.relink_wdg source, where, target
21
+ return unless relink_possible?(source, where, target)
22
+ if where == "before"
23
+ # puts "link #{source} before #{target}"
24
+ source.reparent target.parent, target if source.parent != target.parent
25
+ source.linkBefore target
26
+ elsif where == "after"
27
+ # puts "link #{source} after #{target}"
28
+ source.reparent target.parent, target.next if source.parent != target.parent
29
+ source.linkAfter target
30
+ elsif where == "inside"
31
+ # puts "reparent #{source} under #{target}"
32
+ source.reparent target, target.children.last
33
+ source.linkAfter target.children.last
34
+ else
35
+ return
36
+ end
37
+ source.shell.forceRefresh
38
+ end
39
+
40
+ def self.mouse_relink(source, target)
41
+ # puts "mouse_relink [#{source}] -> [#{target}]"
42
+ if target.composite?
43
+ relink_wdg source, "inside", target
44
+ elsif source.next == target
45
+ relink_wdg source, "after", target
46
+ else
47
+ relink_wdg source, "before", target
48
+ end
49
+ end
50
+
51
+ def self.mouse_relink_test(source, target)
52
+ if target.composite?
53
+ return relink_possible?(source, "inside", target)
54
+ elsif source.next == target
55
+ return relink_possible?(source, "after", target)
56
+ else
57
+ return relink_possible?(source, "before", target)
58
+ end
59
+ false
60
+ end
61
+
62
+ def self.keyboard_relink source, event
63
+ return unless source
64
+ target = where = nil
65
+ if source
66
+ if [CURSOR_UP, CURSOR_LEFT].include? event.code
67
+ where = "before"
68
+ target = source.prev
69
+ unless $CTRL
70
+ if target
71
+ where = "inside" if target.composite?
72
+ else
73
+ target = source.parent
74
+ end
75
+ end
76
+ elsif [CURSOR_DOWN, CURSOR_RIGHT].include? event.code
77
+ where = "after"
78
+ target = source.next
79
+ unless $CTRL
80
+ if target
81
+ if target.children.size > 0
82
+ where = "before"
83
+ target = target.children[0]
84
+ elsif target.composite?
85
+ where = "inside"
86
+ end
87
+ else
88
+ target = source.parent
89
+ end
90
+ end
91
+ end
92
+ end
93
+ RelinkMechanisms.relink_wdg(source, where, target)
94
+ end
95
+ end
data/src/serialize.rb ADDED
@@ -0,0 +1,167 @@
1
+ # Copyright (c) 2004-2006 by Henon (meinrad dot recheis at gmail dot com)
2
+
3
+ require "minitest"
4
+ require "pp"
5
+ require "yaml"
6
+
7
+ class PP < PrettyPrint
8
+ module PPMethods
9
+ def pp_hash(obj)
10
+ group(1, "{", "}") {
11
+ seplist(obj.to_a.sort { |a, b| a[0].to_s <=> b[0].to_s }, nil, :each) { |kv|
12
+ k, v = *kv
13
+ group {
14
+ pp k
15
+ text "=>"
16
+ group(1) {
17
+ breakable ""
18
+ pp v
19
+ }
20
+ }
21
+ }
22
+ obj
23
+ }
24
+ end
25
+ end
26
+ end
27
+
28
+ class Loader
29
+ def initialize dir = "."
30
+ @home = dir
31
+ on_fail { |filename, msg| puts "error loading <#{filename}>: \n\t#{msg}" }
32
+ end
33
+
34
+ def load(filename) # {|data| ... }
35
+ assert block_given?
36
+ open(filename) { |f|
37
+ begin
38
+ data = specialized_load(f)
39
+ yield data
40
+ rescue Exception
41
+ fail(filename, $!.to_s)
42
+ end
43
+ }
44
+ end
45
+
46
+ def on_fail(&block) # {|filename, msg| ... }
47
+ assert block
48
+ @fail = block
49
+ end
50
+
51
+ protected
52
+
53
+ def specialized_load(f)
54
+ f.read
55
+ end
56
+
57
+ def open(filename, &block) # {|f| ... }
58
+ assert block
59
+ path = File.join(@home, filename)
60
+ unless File.exist? path
61
+ fail(filename, "File does not exist in \"#{path}\"!")
62
+ return
63
+ end
64
+ begin
65
+ File.open(path, "rb", &block)
66
+ rescue Exception
67
+ fail(filename, $!)
68
+ end
69
+ end
70
+
71
+ def fail(filename, msg)
72
+ @fail.call(filename, msg)
73
+ end
74
+ end
75
+
76
+ class YamlLoader < Loader
77
+ def specialized_load(f)
78
+ YAML.load(f.read)
79
+ end
80
+ end
81
+
82
+ class RbinLoader < Loader
83
+ def specialized_load(f)
84
+ Marshal.load(f.read)
85
+ end
86
+ end
87
+
88
+ class RubyLoader < Loader
89
+ def specialized_load(f)
90
+ eval(f.read)
91
+ end
92
+ end
93
+
94
+ # deprecated !!
95
+ module Serialize
96
+ def load_from_file filename
97
+ data = nil
98
+ f = nil
99
+ if filename.split(".").pop == "pp"
100
+ f = File.new(filename)
101
+ # ~ puts 'pp load'
102
+ begin
103
+ data = eval(f.read)
104
+ rescue Exception
105
+ error "pp load error: ", $!.to_s
106
+ end
107
+ else
108
+ f = File.new(filename, "rb")
109
+ # ~ puts 'binary load'
110
+ begin
111
+ data = Marshal.load(f.read)
112
+ rescue Exception
113
+ error "binary load error: ", $!.to_s
114
+ end
115
+ end
116
+ f.close
117
+ data
118
+ end
119
+
120
+ def save_to_file filename, data
121
+ if filename.split(".").pop == "pp"
122
+ begin
123
+ out = $stdout
124
+ $stdout = File.new(filename.tr("\\", "/"), "w")
125
+ pp data
126
+ $stdout.flush
127
+ rescue Exception
128
+ filename += ".rbin"
129
+ puts "rescue marshal to: " + filename
130
+ puts $!
131
+ puts $!.backtrace.join($/)
132
+ try_marshal = true
133
+ ensure
134
+ $stdout.close
135
+ $stdout = out
136
+ end
137
+ else
138
+ try_marshal = true
139
+ end
140
+ if try_marshal
141
+ f = File.new(filename.tr("\\", "/"), "wb")
142
+ Marshal.dump data, f
143
+ f.flush
144
+ f.close
145
+ end
146
+ end
147
+
148
+ def load_yaml filename
149
+ data = nil
150
+ File.open(filename, "rb") { |f|
151
+ data = YAML.load(f.read)
152
+ }
153
+ data
154
+ end
155
+ end # module
156
+
157
+ if __FILE__ == $0
158
+ HOME = "."
159
+
160
+ loader = YamlLoader.new(HOME)
161
+ # loader.on_fail{|filename, msg| puts "error loading <#{filename}>: event editor cannot proceed!\n\t#{msg}"}
162
+
163
+ events = nil
164
+ loader.load("events.yaml") { |data| events = data }
165
+ pp events
166
+
167
+ end
@@ -0,0 +1,73 @@
1
+ # Copyright (c) 2004-2006 by Henon (meinrad dot recheis at gmail dot com)
2
+
3
+ class StateMachine
4
+ def initialize
5
+ @states = []
6
+ @state_transitions = {}
7
+ end
8
+
9
+ # first state is initial state
10
+ def add_states(*states)
11
+ @states |= states
12
+ end
13
+
14
+ def state_transition(state1, state2, condition, action = nil)
15
+ array = @state_transitions.fetch(state1) { @state_transitions[state1] = [] }
16
+ array << [state2, condition, action]
17
+ end
18
+
19
+ def start
20
+ @__state__ = @states[0]
21
+ end
22
+
23
+ def input data
24
+ old_state = @__state__
25
+ old_state.input = data
26
+ a = @state_transitions[old_state]
27
+ return unless a
28
+ a.each { |record|
29
+ new_state, condition, action = record
30
+ if condition.call(old_state, new_state)
31
+ @__state__ = new_state
32
+ action.call(old_state, new_state) if action
33
+ break
34
+ end
35
+ }
36
+ end
37
+
38
+ def state
39
+ @__state__
40
+ end
41
+ end
42
+
43
+ class State
44
+ attr_accessor :input
45
+ def initialize name
46
+ @name = name
47
+ @data = {}
48
+ end
49
+
50
+ def []=(k, v)
51
+ @data[k] = v
52
+ end
53
+
54
+ def [](k)
55
+ @data[k]
56
+ end
57
+
58
+ def to_s
59
+ @name.to_s
60
+ end
61
+ end
62
+
63
+ if __FILE__ == $0
64
+ sm = StateMachine.new
65
+ sm.add_states :UNSELECTED, :SELECTED
66
+ condition = proc { true }
67
+ action = proc { |o, n| puts "#{o}-->#{n}" }
68
+ sm.state_transition :UNSELECTED, :SELECTED, condition, action
69
+ sm.state_transition :SELECTED, :UNSELECTED, condition, action
70
+ sm.start
71
+ sm.input nil
72
+ sm.input nil
73
+ end
data/src/version.rb ADDED
@@ -0,0 +1,6 @@
1
+ # Copyright (c) 2004-2006 by Henon (meinrad dot recheis at gmail dot com)
2
+
3
+ FOXGUIB_NAME = "foxGUIb"
4
+ FOXGUIB_VERSION = "1.1.0"
5
+ FOXGUIB = "#{FOXGUIB_NAME} #{FOXGUIB_VERSION}"
6
+ FOXGUIB_LIBRARY = "libGUIb16"
@@ -0,0 +1,118 @@
1
+ # Copyright (c) 2004-2006 by Henon (meinrad dot recheis at gmail dot com)
2
+
3
+ $all_widgets = [
4
+ # ~ "ArrowButton",
5
+ # ~ "Button",
6
+ # "Calendar",
7
+ "Canvas",
8
+ # ~ "CheckButton",
9
+ # ~ "ComboBox",
10
+ # ~ "Dial",
11
+ "DirBox",
12
+ "DirList",
13
+ "DriveBox",
14
+ "FileList",
15
+ # ~ "GroupBox",
16
+ "Header",
17
+ # ~ "HorizontalFrame",
18
+ "HorizontalSeparator",
19
+ "IconList",
20
+ # ~ "Label",
21
+ "List",
22
+ "ListBox",
23
+ # ~ "MDIClient",
24
+ "MenuButton",
25
+ # ~ "MenuCaption",
26
+ # ~ "MenuCascade",
27
+ # ~ "MenuCommand",
28
+ # ~ "MenuPane",
29
+ # ~ "MenuSeparator",
30
+ # ~ "MenuTitle",
31
+ # ~ "Menubar",
32
+ "Option",
33
+ "OptionMenu",
34
+ # ~ "Packer",
35
+ # ~ 'ProgressBar',
36
+ # ~ "RadioButton",
37
+ # "Scintilla",
38
+ "ScrollArea",
39
+ # ~ "ScrollBar",
40
+ # ~ "ScrollWindow",
41
+ # ~ "Shutter",
42
+ # ~ "ShutterItem",
43
+ # ~ 'Slider',
44
+ # ~ "Spinner",
45
+ # ~ "Splitter",
46
+ # ~ "StatusBar",
47
+ # ~ 'StatusLine',
48
+ # ~ "Switcher",
49
+ # ~ "TabBar",
50
+ # ~ "TabBook",
51
+ # ~ "TabItem",
52
+ # ~ "Text",
53
+ # ~ "TextField",
54
+ # ~ "ToggleButton",
55
+ # ~ "Toolbar",
56
+ "TreeList",
57
+ # ~ "VerticalFrame",
58
+ "VerticalSeparator"
59
+ ]
60
+
61
+ ## input
62
+ $input_display_widgets = [
63
+ "ArrowButton",
64
+ "Button",
65
+ "CheckButton",
66
+ "ComboBox",
67
+ "Dial",
68
+ "Label",
69
+ "RadioButton",
70
+ "Text",
71
+ "TextField",
72
+ "ToggleButton",
73
+ "Slider",
74
+ "Spinner",
75
+ "ScrollBar",
76
+ "ProgressBar"
77
+ ]
78
+ # ~ 'GroupBox',
79
+ # ~ 'HorizontalFrame',
80
+ # ~ 'VerticalFrame',
81
+ $menu_widgets = [
82
+ "MenuBar",
83
+ "MenuCaption",
84
+ "MenuCascade",
85
+ "MenuCommand",
86
+ "MenuCheck",
87
+ "MenuRadio",
88
+ "MenuSeparator",
89
+ "MenuTitle",
90
+ "MenuPane"
91
+ ]
92
+ $bar_widgets = [
93
+ "MenuBar",
94
+ "ToolBar",
95
+ "StatusBar",
96
+ "StatusLine"
97
+ ]
98
+ $tab_widgets = [
99
+ "TabBar",
100
+ "TabBook",
101
+ "TabItem",
102
+ "Switcher"
103
+ ]
104
+ $container_widgets = [
105
+ "VerticalFrame",
106
+ "HorizontalFrame",
107
+ "RadioMutex",
108
+ "Packer",
109
+ "GroupBox",
110
+ "ScrollWindow",
111
+ "Shutter",
112
+ "ShutterItem",
113
+ "Splitter",
114
+ "Matrix",
115
+ "MDIClient"
116
+ ]
117
+
118
+ ALL_WIDGETS = $all_widgets + $container_widgets + $tab_widgets + $bar_widgets + $menu_widgets + $input_display_widgets
@@ -0,0 +1,85 @@
1
+ # Copyright (c) 2004-2006 by Henon (meinrad dot recheis at gmail dot com)
2
+ require "singleton"
3
+ require "widget-lists"
4
+ # require 'container'
5
+ class WidgetSelector
6
+ include Singleton
7
+ def initialize
8
+ # ~ create_dlg
9
+ # ~ add $popular_widgets, @popular, @pop_cols, @pop_cnt
10
+ # ~ add $container_widgets, @container, @cont_cols, @cont_cnt
11
+ # ~ add $all_widgets, @all, @all_cols, @all_cnt
12
+ @dlg = MAINWIN.wdg_Frame
13
+ @dlg.vSpacing = 2
14
+ create_popup @dlg
15
+ generate($input_display_widgets, "Input and Display").open_body
16
+ generate($container_widgets, "Container and Layoutmanager").open_body
17
+ generate $menu_widgets, "Menubar and Menu"
18
+ generate $bar_widgets, "Bars"
19
+ generate $tab_widgets, "Switchers"
20
+ generate $all_widgets, "Others"
21
+ end
22
+
23
+ def make_container(p, title)
24
+ c = Container.new(p)
25
+ c.title = title
26
+ c.header.backColor = HEADER_COLOR
27
+ m = FXMatrix.new c, 3, MATRIX_BY_COLUMNS
28
+ m.pad 1, 1, 1, 1
29
+ m.hSpacing = 1
30
+ m.vSpacing = 1
31
+ m.backColor = FXRGB(255, 255, 255)
32
+ [c, m]
33
+ end
34
+
35
+ def generate list, title
36
+ c, m = make_container(@dlg, title)
37
+ list.each { |classname|
38
+ b = Button.new m
39
+ b.backColor = FXRGB(255, 255, 255)
40
+ b.justify = JUSTIFY_LEFT
41
+ b.iconPosition = ICON_BEFORE_TEXT
42
+ b.buttonStyle = BUTTON_TOOLBAR
43
+ iconfile = "src/gui/#{classname}.tga"
44
+ # puts "#{iconfile} does not exist." if $DEBUG and !File.exist?( iconfile)
45
+ b.icon = Icon.new(iconfile).img
46
+ b.text = classname.to_s
47
+ b.layoutHints = LAYOUT_FIX_HEIGHT | LAYOUT_FIX_WIDTH
48
+ b.height = 40
49
+ b.width = 120
50
+ b.connect(SEL_COMMAND) { DocMan.instance.add_widget classname.to_s }
51
+ b.connect(SEL_RIGHTBUTTONPRESS) { |s, x, e|
52
+ @classname = classname.to_s
53
+ @classname_caption.text = "[#{@classname}]"
54
+ @popup.popup nil, e.root_x, e.root_y
55
+ }
56
+ }
57
+ c.close_body
58
+ c
59
+ end
60
+
61
+ def create_popup(p)
62
+ @popup = Popup.new(p) { |po|
63
+ @classname_caption = MenuCaption.new(po) { |c|
64
+ c.text = "..."
65
+ }
66
+ MenuSeparator.new(po)
67
+ MenuCommand.new(po) { |c|
68
+ c.text = "add before"
69
+ c.connect(SEL_COMMAND) { DocMan.instance.add_widget @classname, "before" }
70
+ }
71
+ MenuCommand.new(po) { |c|
72
+ c.text = "add after"
73
+ c.connect(SEL_COMMAND) { DocMan.instance.add_widget @classname }
74
+ }
75
+ MenuCommand.new(po) { |c|
76
+ c.text = "add inside"
77
+ c.connect(SEL_COMMAND) { DocMan.instance.add_widget @classname, "inside" }
78
+ }
79
+ MenuSeparator.new(po)
80
+ MenuCommand.new(po) { |c|
81
+ c.text = "cancel"
82
+ }
83
+ }
84
+ end
85
+ end