extract-curves 0.1.1

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 (172) hide show
  1. data/Changelog +21 -0
  2. data/bin/ec_rect2polar +22 -0
  3. data/bin/ec_rect2polar.rb +22 -0
  4. data/bin/ec_rev_lines +5 -0
  5. data/bin/ec_rev_lines.rb +5 -0
  6. data/bin/ec_sph_area +30 -0
  7. data/bin/ec_sph_area.rb +30 -0
  8. data/bin/extract_curves +1670 -0
  9. data/bin/extract_curves.rb +1670 -0
  10. data/ruby_ext/pav/cstr.c +82 -0
  11. data/ruby_ext/pav/cstr.h +17 -0
  12. data/ruby_ext/pav/extconf.rb +22 -0
  13. data/ruby_ext/pav/pav.c +162 -0
  14. data/ruby_ext/pav/pgtk.c +40 -0
  15. data/ruby_ext/pav/pgtk.h +14 -0
  16. data/ruby_ext/pav/pix.c +806 -0
  17. data/ruby_ext/pav/pix.h +236 -0
  18. data/ruby_ext/pav/t.rb +35 -0
  19. data/ruby_ext/pav/t1.rb +35 -0
  20. data/ruby_libs/pav/attr_cache.rb +211 -0
  21. data/ruby_libs/pav/attr_cache.t1.rb +32 -0
  22. data/ruby_libs/pav/cache.rb +31 -0
  23. data/ruby_libs/pav/collection/std.rb +58 -0
  24. data/ruby_libs/pav/dbg_log.rb +458 -0
  25. data/ruby_libs/pav/floatsio.rb +53 -0
  26. data/ruby_libs/pav/generator_cache.rb +165 -0
  27. data/ruby_libs/pav/graph/node.rb +602 -0
  28. data/ruby_libs/pav/graph/node_grp.rb +865 -0
  29. data/ruby_libs/pav/gtk.rb +6 -0
  30. data/ruby_libs/pav/gtk/button.rb +118 -0
  31. data/ruby_libs/pav/gtk/dialog.rb +29 -0
  32. data/ruby_libs/pav/gtk/guiobj.rb +772 -0
  33. data/ruby_libs/pav/gtk/icons.rb +124 -0
  34. data/ruby_libs/pav/gtk/rulers.rb +264 -0
  35. data/ruby_libs/pav/gtk/toolbar.rb +189 -0
  36. data/ruby_libs/pav/guiobj.rb +2 -0
  37. data/ruby_libs/pav/guiobj/info_asm.rb +41 -0
  38. data/ruby_libs/pav/guiobj/method.rb +211 -0
  39. data/ruby_libs/pav/guiobj/obj.rb +134 -0
  40. data/ruby_libs/pav/guiobj/signals.rb +9 -0
  41. data/ruby_libs/pav/heap.rb +54 -0
  42. data/ruby_libs/pav/icons/alt_handle.xcf +0 -0
  43. data/ruby_libs/pav/icons/alt_handle.xpm +3832 -0
  44. data/ruby_libs/pav/icons/alt_handle_hover.xcf +0 -0
  45. data/ruby_libs/pav/icons/alt_handle_hover.xpm +3368 -0
  46. data/ruby_libs/pav/icons/alt_handle_pressed.xcf +0 -0
  47. data/ruby_libs/pav/icons/alt_handle_pressed.xpm +3828 -0
  48. data/ruby_libs/pav/icons/blob.gif +0 -0
  49. data/ruby_libs/pav/icons/clover_base.xcf +0 -0
  50. data/ruby_libs/pav/icons/contour.gif +0 -0
  51. data/ruby_libs/pav/icons/contour.xcf +0 -0
  52. data/ruby_libs/pav/icons/contour_carpet.gif +0 -0
  53. data/ruby_libs/pav/icons/contour_carpet.xcf +0 -0
  54. data/ruby_libs/pav/icons/curve.gif +0 -0
  55. data/ruby_libs/pav/icons/curve.xcf +0 -0
  56. data/ruby_libs/pav/icons/curve_carpet.gif +0 -0
  57. data/ruby_libs/pav/icons/curve_carpet.xcf +0 -0
  58. data/ruby_libs/pav/icons/expand_base.xcf +0 -0
  59. data/ruby_libs/pav/icons/expand_closed.xpm +1791 -0
  60. data/ruby_libs/pav/icons/expand_closed_hover.xpm +1775 -0
  61. data/ruby_libs/pav/icons/expand_open.xpm +1788 -0
  62. data/ruby_libs/pav/icons/expand_open_hover.xpm +1752 -0
  63. data/ruby_libs/pav/icons/extract_curves/extract_curves-icon-rgb.ppm +14 -0
  64. data/ruby_libs/pav/icons/extract_curves/extract_curves-logo-rgb.gif +0 -0
  65. data/ruby_libs/pav/icons/extract_curves/extract_curves-logo-rgb.xcf +0 -0
  66. data/ruby_libs/pav/icons/extract_curves/trace_mark.xcf +0 -0
  67. data/ruby_libs/pav/icons/extract_curves/trace_mark.xpm +38 -0
  68. data/ruby_libs/pav/icons/handle.xcf +0 -0
  69. data/ruby_libs/pav/icons/handle.xpm +213 -0
  70. data/ruby_libs/pav/icons/loop.gif +0 -0
  71. data/ruby_libs/pav/icons/loop.xcf +0 -0
  72. data/ruby_libs/pav/icons/loop_carpet.gif +0 -0
  73. data/ruby_libs/pav/icons/loop_carpet.xcf +0 -0
  74. data/ruby_libs/pav/icons/next.xpm +29 -0
  75. data/ruby_libs/pav/icons/next_hover.xpm +315 -0
  76. data/ruby_libs/pav/icons/next_pressed.xpm +144 -0
  77. data/ruby_libs/pav/icons/prev.xpm +29 -0
  78. data/ruby_libs/pav/icons/prev_hover.xpm +315 -0
  79. data/ruby_libs/pav/icons/prev_pressed.xpm +144 -0
  80. data/ruby_libs/pav/icons/shaved-core.gif +0 -0
  81. data/ruby_libs/pav/icons/vnext.xpm +29 -0
  82. data/ruby_libs/pav/icons/vprev.xpm +29 -0
  83. data/ruby_libs/pav/numeric/ext.rb +21 -0
  84. data/ruby_libs/pav/patterns/hsep.gif +0 -0
  85. data/ruby_libs/pav/patterns/tnode.gif +0 -0
  86. data/ruby_libs/pav/patterns/tnode_w_link.gif +0 -0
  87. data/ruby_libs/pav/patterns/vlink.gif +0 -0
  88. data/ruby_libs/pav/patterns/vsep.gif +0 -0
  89. data/ruby_libs/pav/patterns/yg_hrope.xpm +492 -0
  90. data/ruby_libs/pav/patterns/yg_hrope_thick.xpm +1904 -0
  91. data/ruby_libs/pav/patterns/yg_hrope_thin.xpm +130 -0
  92. data/ruby_libs/pav/patterns/yg_tnode.xpm +180 -0
  93. data/ruby_libs/pav/patterns/yg_tnode_thick.xpm +615 -0
  94. data/ruby_libs/pav/patterns/yg_tnode_thin.xpm +55 -0
  95. data/ruby_libs/pav/patterns/yg_tnode_w_link.xpm +190 -0
  96. data/ruby_libs/pav/patterns/yg_tnode_w_link_thick.xpm +676 -0
  97. data/ruby_libs/pav/patterns/yg_tnode_w_link_thin.xpm +62 -0
  98. data/ruby_libs/pav/patterns/yg_vrope.xpm +563 -0
  99. data/ruby_libs/pav/patterns/yg_vrope_thick.xpm +2047 -0
  100. data/ruby_libs/pav/patterns/yg_vrope_thin.xpm +166 -0
  101. data/ruby_libs/pav/pav_find.rb +90 -0
  102. data/ruby_libs/pav/pix.rb +402 -0
  103. data/ruby_libs/pav/pix/aapix.rb +378 -0
  104. data/ruby_libs/pav/pix/blob.rb +678 -0
  105. data/ruby_libs/pav/pix/circle.rb +73 -0
  106. data/ruby_libs/pav/pix/contour.rb +676 -0
  107. data/ruby_libs/pav/pix/contour/calc_situations.rb +9 -0
  108. data/ruby_libs/pav/pix/contour/carp_calc.rb +212 -0
  109. data/ruby_libs/pav/pix/contour/situations.dmp +0 -0
  110. data/ruby_libs/pav/pix/contour/situations.rb +21 -0
  111. data/ruby_libs/pav/pix/curve.rb +1544 -0
  112. data/ruby_libs/pav/pix/img_obj.rb +865 -0
  113. data/ruby_libs/pav/pix/node.rb +159 -0
  114. data/ruby_libs/pav/pix/shaved_core.rb +697 -0
  115. data/ruby_libs/pav/pix/subpix.rb +212 -0
  116. data/ruby_libs/pav/rand_accessible.rb +16 -0
  117. data/ruby_libs/pav/rangeset.rb +63 -0
  118. data/ruby_libs/pav/search.rb +210 -0
  119. data/ruby_libs/pav/set.rb +130 -0
  120. data/ruby_libs/pav/string/bits.rb +523 -0
  121. data/ruby_libs/pav/string/ext.rb +58 -0
  122. data/ruby_libs/pav/string/observable.rb +155 -0
  123. data/ruby_libs/pav/string/text.rb +79 -0
  124. data/ruby_libs/pav/string/words.rb +42 -0
  125. data/ruby_libs/pav/sub_arr.rb +56 -0
  126. data/ruby_libs/pav/traced_obj.rb +79 -0
  127. data/web/index.html +280 -0
  128. data/web/media/icons/alt_handle.xcf +0 -0
  129. data/web/media/icons/alt_handle.xpm +3832 -0
  130. data/web/media/icons/alt_handle_hover.xcf +0 -0
  131. data/web/media/icons/alt_handle_hover.xpm +3368 -0
  132. data/web/media/icons/alt_handle_pressed.xcf +0 -0
  133. data/web/media/icons/alt_handle_pressed.xpm +3828 -0
  134. data/web/media/icons/blob.gif +0 -0
  135. data/web/media/icons/clover_base.xcf +0 -0
  136. data/web/media/icons/contour.gif +0 -0
  137. data/web/media/icons/contour.xcf +0 -0
  138. data/web/media/icons/contour_carpet.gif +0 -0
  139. data/web/media/icons/contour_carpet.xcf +0 -0
  140. data/web/media/icons/curve.gif +0 -0
  141. data/web/media/icons/curve.xcf +0 -0
  142. data/web/media/icons/curve_carpet.gif +0 -0
  143. data/web/media/icons/curve_carpet.xcf +0 -0
  144. data/web/media/icons/expand_base.xcf +0 -0
  145. data/web/media/icons/expand_closed.xpm +1791 -0
  146. data/web/media/icons/expand_closed_hover.xpm +1775 -0
  147. data/web/media/icons/expand_open.xpm +1788 -0
  148. data/web/media/icons/expand_open_hover.xpm +1752 -0
  149. data/web/media/icons/extract_curves/extract_curves-icon-rgb.ppm +14 -0
  150. data/web/media/icons/extract_curves/extract_curves-logo-rgb.gif +0 -0
  151. data/web/media/icons/extract_curves/extract_curves-logo-rgb.xcf +0 -0
  152. data/web/media/icons/extract_curves/trace_mark.xcf +0 -0
  153. data/web/media/icons/extract_curves/trace_mark.xpm +38 -0
  154. data/web/media/icons/handle.xcf +0 -0
  155. data/web/media/icons/handle.xpm +213 -0
  156. data/web/media/icons/loop.gif +0 -0
  157. data/web/media/icons/loop.xcf +0 -0
  158. data/web/media/icons/loop_carpet.gif +0 -0
  159. data/web/media/icons/loop_carpet.xcf +0 -0
  160. data/web/media/icons/next.xpm +29 -0
  161. data/web/media/icons/next_hover.xpm +315 -0
  162. data/web/media/icons/next_pressed.xpm +144 -0
  163. data/web/media/icons/prev.xpm +29 -0
  164. data/web/media/icons/prev_hover.xpm +315 -0
  165. data/web/media/icons/prev_pressed.xpm +144 -0
  166. data/web/media/icons/shaved-core.gif +0 -0
  167. data/web/media/icons/vnext.xpm +29 -0
  168. data/web/media/icons/vprev.xpm +29 -0
  169. data/web/media/title.jpeg +0 -0
  170. data/web/media/title.xcf +0 -0
  171. data/web/stylesheets/default.css +20 -0
  172. metadata +229 -0
@@ -0,0 +1,6 @@
1
+ require 'pav/gtk/icons'
2
+ require 'pav/gtk/guiobj'
3
+ require 'pav/gtk/button'
4
+ require 'pav/gtk/dialog'
5
+ require 'pav/gtk/rulers'
6
+ require 'pav/gtk/toolbar'
@@ -0,0 +1,118 @@
1
+ require 'gtk2'
2
+ require 'pav/gtk/icons'
3
+
4
+ module PGtk
5
+
6
+ class Button < Gtk::EventBox
7
+ attr_reader :hovered, :pressed
8
+ attr_accessor :content, :content_hover, :content_pressed
9
+ attr_accessor :left_click_proc, :middle_click_proc,
10
+ :right_click_proc
11
+
12
+ def initialize(cont_spec=nil, w_cont_hover=nil, h_cont_hover=nil,
13
+ cont_hover=nil, cont_pressed=nil, &left_click_proc)
14
+ if cont_pressed
15
+ @content = PGtk.stock_pixbuf_of_size(cont_spec,
16
+ w_cont_hover, h_cont_hover)
17
+ @content_hover = PGtk.stock_pixbuf_of_size(cont_hover,
18
+ w_cont_hover, h_cont_hover)
19
+ @content_pressed = PGtk.stock_pixbuf_of_size(
20
+ cont_pressed, w_cont_hover, h_cont_hover)
21
+ elsif cont_hover
22
+ @content = PGtk.stock_pixbuf_of_size(cont_spec,
23
+ w_cont_hover, h_cont_hover)
24
+ @content_hover = PGtk.stock_pixbuf_of_size(cont_hover,
25
+ w_cont_hover, h_cont_hover)
26
+ elsif h_cont_hover
27
+ if w_cont_hover.kind_of?(Integer)
28
+ @content = PGtk.stock_pixbuf_of_size(cont_spec,
29
+ w_cont_hover, h_cont_hover)
30
+ @content_hover = nil
31
+ else
32
+ @content = Gdk::Pixbuf.new(cont_spec, h_cont_hover)
33
+ @content_hover = Gdk::Pixbuf.new(w_cont_hover,
34
+ h_cont_hover)
35
+ end
36
+ elsif w_cont_hover
37
+ if w_cont_hover.kind_of?(Symbol)
38
+ @content = Gdk::Pixbuf.new(cont_spec)
39
+ @content_hover = Gdk::Pixbuf.new(w_cont_hover)
40
+ else
41
+ @content = Gdk::Pixbuf.new(cont_spec, w_cont_hover)
42
+ @content_hover = nil
43
+ end
44
+ elsif cont_spec
45
+ @content = Gdk::Pixbuf.new(cont_spec)
46
+ @content_hover = nil
47
+ end
48
+ @left_click_proc = left_click_proc if block_given?
49
+ super()
50
+ @image = Gtk::Image.new(@content)
51
+ self << @image
52
+ self.events |= Gdk::Event::BUTTON_RELEASE_MASK |
53
+ Gdk::Event::BUTTON_PRESS_MASK |
54
+ Gdk::Event::ENTER_NOTIFY_MASK |
55
+ Gdk::Event::LEAVE_NOTIFY_MASK
56
+ self.signal_connect('button_press_event') { |wgt, ev|
57
+ @pressed = ev.button
58
+ if [@left_click_proc, @middle_click_proc,
59
+ @right_click_proc].at(@pressed-1) &&
60
+ @content_pressed
61
+ if @content_pressed
62
+ @image.pixbuf = @content_pressed
63
+ end
64
+ end
65
+ false
66
+ }
67
+ self.signal_connect('button_release_event') { |wgt, ev|
68
+ @pressed = nil
69
+ if @content_pressed
70
+ tmp=(@content_hover ? @content_hover : @content)
71
+ @image.pixbuf = tmp
72
+ end
73
+ if @hovered &&(tmp=[@left_click_proc,@middle_click_proc,
74
+ @right_click_proc].at(ev.button-1))
75
+ tmp.call(wgt, ev)
76
+ else
77
+ false
78
+ end
79
+ }
80
+ self.signal_connect('enter_notify_event') { |wgt, ev|
81
+ @hovered = true
82
+ if @pressed && [@left_click_proc, @middle_click_proc,
83
+ @right_click_proc].at(@pressed-1) &&
84
+ @content_pressed
85
+ @image.pixbuf = @content_pressed
86
+ elsif @content_hover
87
+ @image.pixbuf = @content_hover
88
+ end
89
+ false
90
+ }
91
+ self.signal_connect('leave_notify_event') { |wgt, ev|
92
+ @hovered = false
93
+ @image.pixbuf = @content
94
+ false
95
+ }
96
+ end
97
+
98
+ def set_icons(*pixbufs)
99
+ @content, @content_hover, @content_pressed = *pixbufs
100
+ if @pressed
101
+ if @content_pressed
102
+ @image.pixbuf = @content_pressed
103
+ else
104
+ @image.pixbuf = @content
105
+ end
106
+ elsif @hovered
107
+ if @content_hover
108
+ @image.pixbuf = @content_hover
109
+ else
110
+ @image.pixbuf = @content
111
+ end
112
+ else
113
+ @image.pixbuf = @content
114
+ end
115
+ end
116
+ end
117
+
118
+ end
@@ -0,0 +1,29 @@
1
+ module PGtk
2
+ def self.overwrite_dialog(path)
3
+ dialog = Gtk::Dialog.new('Overwrite output file?', nil, 0,
4
+ ['Overwrite', Gtk::Dialog::RESPONSE_ACCEPT],
5
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL])
6
+ hbox = Gtk::HBox.new(false, 0)
7
+ hbox.set_border_width(8)
8
+ dialog.vbox.pack_start(hbox, false, false, 0)
9
+ hbox.pack_start(Gtk::Image.new(
10
+ Gtk::Stock::DIALOG_QUESTION, Gtk::IconSize::DIALOG),
11
+ false, false, 0)
12
+ label = Gtk::Label.new
13
+ label.markup = "File <b>#{path}</b> already exists."
14
+ hbox.pack_start(label, false, false, 0)
15
+ hbox.show_all
16
+ resp = dialog.run
17
+ dialog.destroy
18
+ resp == Gtk::Dialog::RESPONSE_ACCEPT
19
+ end
20
+
21
+ def self.show_exc_dialog(exc=$!)
22
+ dialog = Gtk::MessageDialog.new(nil,0,Gtk::MessageDialog::ERROR,
23
+ Gtk::MessageDialog::BUTTONS_CLOSE)
24
+ dialog.title = exc.class.name
25
+ dialog.markup = "<b>#{exc.class.name}:</b> <b><i>#{exc.to_s}</i></b>\n\tfrom #{exc.backtrace.join("\n\tfrom ")}"
26
+ dialog.run
27
+ dialog.destroy
28
+ end
29
+ end
@@ -0,0 +1,772 @@
1
+ require 'gtk2'
2
+ require 'pav/guiobj'
3
+ require 'pav/gtk/dialog'
4
+ require 'pav/gtk/rulers'
5
+ require 'pav/string/ext'
6
+ require 'pav/numeric/ext'
7
+
8
+ module PGtk
9
+
10
+ module GuiObj
11
+
12
+ class LinearHBox < Gtk::HBox
13
+ def initialize(expand=false, padding=3)
14
+ super(expand, padding)
15
+ end
16
+
17
+ def append(wgt)
18
+ self.pack_start(wgt, false, false, 0)
19
+ end
20
+
21
+ def append_space
22
+ self.pack_start(sep=PGtk::VSep.new, false, false, 3)
23
+ sep.show_all
24
+ end
25
+ end
26
+
27
+ class LinearVBox < Gtk::VBox
28
+ def initialize(expand=false, padding=3)
29
+ super(expand, padding)
30
+ end
31
+
32
+ def append(wgt)
33
+ self.pack_start(wgt, false, false, 0)
34
+ end
35
+
36
+ def append_space
37
+ self.pack_start(sep=PGtk::HSep.new, false, false, 3)
38
+ sep.show_all
39
+ end
40
+ end
41
+
42
+ class LinearBox
43
+ def self.new(dir=Gtk::Orientation::HORIZONTAL)
44
+ if dir == Gtk::Orientation::HORIZONTAL
45
+ LinearHBox.new
46
+ else
47
+ LinearVBox.new
48
+ end
49
+ end
50
+ end
51
+
52
+ module InfoStrTTip
53
+ def pguiobj_info_str=(str)
54
+ (cfg = self.pguiobj_proto.pguiobj_config).info_str = str
55
+ ttips = cfg.gtk_tooltips || @pguiobj_ttips ||
56
+ (@pguiobj_ttips = Gtk::Tooltips.new)
57
+ for wgt in self.pguiobj_ttip_wgts
58
+ ttips.set_tip(wgt, str, nil)
59
+ end
60
+ end
61
+ end
62
+
63
+ class Argument < LinearHBox
64
+ attr_reader :arg
65
+
66
+ @type_handlers = []
67
+
68
+ def self.add_type_handler(type, handler_class)
69
+ @type_handlers << [type, handler_class]
70
+ end
71
+
72
+ def self.create(arg)
73
+ type = arg.pguiobj_type_class
74
+ if type.kind_of?(PGuiObj::PMethod)
75
+ return GeneratedArgument.new(arg)
76
+ elsif type.kind_of?(Class)
77
+ @type_handlers.each { |h|
78
+ if type <= h[0]
79
+ return h[1].new(arg)
80
+ end
81
+ }
82
+ end
83
+ raise ArgumentError, "Unrecognized argument class: #{
84
+ type} of argument #{arg}!"
85
+ end
86
+
87
+ def initialize(arg)
88
+ @arg = arg
89
+ super()
90
+ self.append(Gtk::Label.new(arg.pguiobj_name.cap_first.
91
+ concat(': ')))
92
+ end
93
+
94
+ def method_missing(id, *args, &block)
95
+ @arg.send(id, *args, &block)
96
+ end
97
+ end
98
+
99
+ class GeneratedArgument < Argument
100
+ attr_reader :meth
101
+
102
+ def initialize(arg)
103
+ super(arg)
104
+ self.append(@meth=PNoResMethod.create(arg.pguiobj_type_class,
105
+ nil, false))
106
+ end
107
+
108
+ def value
109
+ @meth.call
110
+ end
111
+ end
112
+
113
+ class BoolArgument < Argument
114
+ attr_reader :check_btn
115
+
116
+ def initialize(arg)
117
+ super(arg)
118
+ self.append(@check_btn = Gtk::CheckButton.new)
119
+ @check_btn.active = arg.pguiobj_default
120
+ @check_btn.signal_connect('toggled') { |btn,ev|
121
+ self.pguiobj_value_changed_flag.changed
122
+ self.pguiobj_value_changed_flag.notify_observers(self)
123
+ }
124
+ end
125
+
126
+ def value
127
+ @check_btn.active?
128
+ end
129
+ end
130
+
131
+ Argument.add_type_handler(PGuiObj::Bool, BoolArgument)
132
+
133
+ class AdjArgument < Argument
134
+ attr_reader :adj, :spin_btn
135
+
136
+ def initialize(arg, deflt_dgts_cnt=2)
137
+ super(arg)
138
+ if (cnstr = arg.pguiobj_type_constraints)
139
+ if cnstr.min
140
+ min = cnstr.min
141
+ else
142
+ min = -1.0; min*= 2.0 while (min*2.0).finite?
143
+ end
144
+ if cnstr.max
145
+ max = cnstr.max
146
+ else
147
+ max = 1.0; max *= 2.0 while (max*2.0).finite?
148
+ end
149
+ else
150
+ min = -1.0; min*= 2.0 while (min*2.0).finite?
151
+ max = 1.0; max *= 2.0 while (max*2.0).finite?
152
+ end
153
+ cfg = arg.pguiobj_config
154
+ step = cfg.step || 1.0
155
+ page_step = cfg.page_step || 10.0
156
+ page_size = cfg.page_size || 10.0
157
+ climb_rate = cfg.climb_rate || 0.0
158
+ n_digits = cfg.frac_digits_cnt || deflt_dgts_cnt
159
+ @adj = Gtk::Adjustment.new(arg.pguiobj_default || 0.0, min, max,
160
+ step, page_step, page_size)
161
+ @spin_btn = Gtk::SpinButton.new(@adj, climb_rate, n_digits)
162
+ @spin_btn.numeric = true
163
+ if arg.pguiobj_descr
164
+ ttips=Gtk::Tooltips.new unless (ttips=cfg.gtk_tooltips)
165
+ ttips.set_tip(@spin_btn, arg.pguiobj_descr, nil)
166
+ end
167
+ self.append(@spin_btn)
168
+ self.append(Gtk::Label.new(cfg.units)) if cfg.units
169
+ @spin_btn.signal_connect('value-changed') { |btn,ev|
170
+ self.pguiobj_value_changed_flag.changed
171
+ self.pguiobj_value_changed_flag.notify_observers(self)
172
+ }
173
+ end
174
+
175
+ def value
176
+ @spin_btn.value
177
+ end
178
+ end
179
+
180
+ class IntArgument < AdjArgument
181
+ def initialize(arg)
182
+ super(arg, 0)
183
+ #self.spin_btn.snap_to_ticks = true
184
+ end
185
+
186
+ def value
187
+ self.spin_btn.value_as_int
188
+ end
189
+ end
190
+
191
+ Argument.add_type_handler(Integer, IntArgument)
192
+ Argument.add_type_handler(Numeric, AdjArgument)
193
+
194
+ class EnumArgument < Argument
195
+ attr_reader :combo, :impl_args
196
+
197
+ def initialize(arg)
198
+ super(arg)
199
+ self.append(@combo = Gtk::ComboBox.new)
200
+ arg.pguiobj_type_constraints.each_name { |name|
201
+ @combo.append_text(name) }
202
+ @impl_args = []
203
+ @combo.active = arg.pguiobj_default || 0
204
+ if arg.pguiobj_descr
205
+ ttips = Gtk::Tooltips.new unless
206
+ ttips=arg.pguiobj_config.tooltips
207
+ ttips.set_tip(@combo, arg.pguiobj_descr, nil)
208
+ end
209
+ chld_pos = self.children.length
210
+ @combo.signal_connect('changed') { |combo,ev|
211
+ chld_pos.upto(self.children.length-1) { |i|
212
+ self.children.at(i).hide
213
+ }
214
+ if (val=self.arg.pguiobj_type_constraints.value(
215
+ idx=@combo.active)).class <= PGuiObj::MArgument
216
+ unless @impl_args.at(idx)
217
+ self.append(@impl_args[idx]=Argument.create(val))
218
+ end
219
+ @impl_args.at(idx).show_all
220
+ elsif val.class <= PGuiObj::PMMethod
221
+ unless @impl_args.at(idx)
222
+ self.append(@impl_args[idx]=PNoResMethod.
223
+ create(val, nil, false))
224
+ end
225
+ @impl_args.at(idx).show_all
226
+ end
227
+ self.pguiobj_value_changed_flag.changed
228
+ self.pguiobj_value_changed_flag.notify_observers(self)
229
+ }
230
+ @combo.signal_emit('changed')
231
+ end
232
+
233
+ def value
234
+ if (res=@impl_args.at(idx=@combo.active))
235
+ if res.kind_of?(Argument)
236
+ return res.value
237
+ else
238
+ return res.call
239
+ end
240
+ end
241
+ self.arg.pguiobj_type_constraints.value(idx)
242
+ end
243
+
244
+ def set(idx)
245
+ @combo.active = idx
246
+ end
247
+ end
248
+
249
+ Argument.add_type_handler(PGuiObj::Enum, EnumArgument)
250
+
251
+ class PNoResMethod < LinearVBox
252
+ attr_reader :pguiobj_proto, :impl_obj, :pguiobj_impl_args, :btn,
253
+ :impl_args_box, :subobjs_box, :enabled
254
+
255
+ def self.create(meth, obj, *args)
256
+ self.new(meth, obj, *args)
257
+ end
258
+
259
+ def initialize(meth, obj, show_title=true)
260
+ @pguiobj_proto = meth
261
+ @impl_obj = obj
262
+ @enabled = true
263
+ super()
264
+ #self.orientation = Gtk::Orientation::VERTICAL
265
+ self.append(@impl_args_box = LinearHBox.new)
266
+ if !meth.pguiobj_config.no_show_title && show_title
267
+ @impl_args_box.append(@btn=Gtk::Button.new)
268
+ @btn.add(box=Gtk::HBox.new)
269
+ box.pack_start(((icon=@pguiobj_proto.pguiobj_config.icon) &&
270
+ (img=PGtk.image_new(icon,Gtk::IconSize::BUTTON,0,0))) ||
271
+ Gtk::Image.new(Gtk::Stock::EXECUTE,
272
+ Gtk::IconSize::BUTTON))
273
+ box.pack_start(Gtk::Label.new(@pguiobj_proto.pguiobj_name.
274
+ cap_first))
275
+ @btn.signal_connect('clicked') { |btn,ev| self.call; true }
276
+ end
277
+ @pguiobj_impl_args = []
278
+ @pguiobj_proto.pguiobj_args.each { |arg|
279
+ @pguiobj_impl_args << Argument.create(arg)
280
+ @impl_args_box.append(@pguiobj_impl_args.last)
281
+ }
282
+ @pguiobj_implementation = @pguiobj_proto.pguiobj_implementation
283
+ @pguiobj_proto.pguiobj_children = []
284
+ end
285
+
286
+ def call
287
+ return unless @enabled
288
+ @pguiobj_proto.pguiobj_pre_call_flag.changed
289
+ begin
290
+ @pguiobj_proto.pguiobj_pre_call_flag.notify_observers(
291
+ @impl_obj, self)
292
+ rescue PGuiObj::CancelCall
293
+ @pguiobj_proto.pguiobj_cancel_call_flag.changed
294
+ @pguiobj_proto.pguiobj_cancel_call_flag.notify_observers(
295
+ @impl_obj, self)
296
+ return
297
+ end
298
+ res = @pguiobj_implementation.call(*@pguiobj_impl_args.
299
+ collect{|a| a.value})
300
+ @pguiobj_proto.pguiobj_post_call_flag.changed
301
+ @pguiobj_proto.pguiobj_post_call_flag.notify_observers(
302
+ @impl_obj, self, res, nil)
303
+ if res.respond_to?(:to_pguiobj)
304
+ @pguiobj_proto.pguiobj_children << res
305
+ elsif @pguiobj_proto.pguiobj_config.keep_not_guiobj_subobjs
306
+ @pguiobj_proto.pguiobj_children << res
307
+ end
308
+ res
309
+ end
310
+
311
+ def disable
312
+ @btn.sensitive = false
313
+ @enabled = false
314
+ end
315
+
316
+ def enable
317
+ @btn.sensitive = true
318
+ @enabled = true
319
+ end
320
+
321
+ def pguiobj_clear_children
322
+ @pguiobj_proto.pguiobj_clear_children
323
+ end
324
+
325
+ def pguiobj_each_child
326
+ end
327
+
328
+ def method_missing(id, *args, &block)
329
+ @pguiobj_proto.send(id, *args, &block)
330
+ end
331
+ end
332
+
333
+ class PResMethodChildDeathObserver
334
+ attr_reader :hbox
335
+ attr_accessor :link, :prev_link, :prev_hbox, :next_obs
336
+
337
+ def initialize(subobjs_box, hbox)
338
+ @subobjs_box = subobjs_box
339
+ @hbox = hbox
340
+ @link = nil
341
+ @prev_hbox = nil
342
+ end
343
+
344
+ def update(gui_obj, obj)
345
+ if hbox.children[0].end_node?
346
+ if @prev_hbox
347
+ @subobjs_box.remove(@prev_link)
348
+ @prev_hbox.children[0].end_node = true
349
+ end
350
+ else
351
+ @next_obs.prev_hbox = @prev_hbox
352
+ @next_obs.prev_link = @prev_link
353
+ @subobjs_box.remove(@link) if @link
354
+ end
355
+ @subobjs_box.remove(hbox)
356
+ end
357
+ end
358
+
359
+ class PResMethod < LinearVBox
360
+ attr_reader :pguiobj_proto, :pguiobj_impl_args, :btn, :impl_args_box,
361
+ :subobjs_box, :impl_obj, :enabled
362
+
363
+ def self.create(meth, obj)
364
+ self.new(meth, obj)
365
+ end
366
+
367
+ def initialize(meth, obj)
368
+ @pguiobj_proto = meth
369
+ @impl_obj = obj
370
+ @enabled = true
371
+ super()
372
+ obj_vbox = self
373
+ #obj_vbox.orientation = Gtk::Orientation::VERTICAL
374
+ obj_vbox.append(@impl_args_box = LinearHBox.new)
375
+ @impl_args_box.append(@btn=Gtk::Button.new)
376
+ @btn.add(box=Gtk::HBox.new)
377
+ box.pack_start(((icon=@pguiobj_proto.pguiobj_config.icon) &&
378
+ (img=PGtk.image_new(icon,Gtk::IconSize::BUTTON,0,0))) ||
379
+ Gtk::Image.new(Gtk::Stock::EXECUTE,
380
+ Gtk::IconSize::BUTTON))
381
+ box.pack_start(Gtk::Label.new(@pguiobj_proto.pguiobj_name.
382
+ cap_first))
383
+ @btn.signal_connect('clicked') { |btn,ev| self.call; true }
384
+ @pguiobj_impl_args = []
385
+ @pguiobj_proto.pguiobj_args.each { |arg|
386
+ @pguiobj_impl_args << Argument.create(arg)
387
+ @impl_args_box.append(@pguiobj_impl_args.last)
388
+ }
389
+ obj_vbox.append(@subobjs_box = LinearVBox.new(false, 0))
390
+ #@subobjs_box.orientation = Gtk::Orientation::VERTICAL
391
+ @pguiobj_proto.pguiobj_children = []
392
+ @pguiobj_implementation = @pguiobj_proto.pguiobj_implementation
393
+ end
394
+
395
+ def disable
396
+ @btn.sensitive = false
397
+ @enabled = false
398
+ end
399
+
400
+ def enable
401
+ @btn.sensitive = true
402
+ @enabled = true
403
+ end
404
+
405
+ def call
406
+ return unless @enabled
407
+ @pguiobj_proto.pguiobj_pre_call_flag.changed
408
+ begin
409
+ @pguiobj_proto.pguiobj_pre_call_flag.notify_observers(
410
+ @impl_obj, self)
411
+ rescue PGuiObj::CancelCall
412
+ @pguiobj_proto.pguiobj_cancel_call_flag.changed
413
+ @pguiobj_proto.pguiobj_cancel_call_flag.notify_observers(
414
+ @impl_obj, self)
415
+ return
416
+ end
417
+ res = @pguiobj_implementation.call(*@pguiobj_impl_args.
418
+ collect{|a| a.value})
419
+ @pguiobj_proto.pguiobj_post_call_pre_gui_flag.changed
420
+ @pguiobj_proto.pguiobj_post_call_pre_gui_flag.notify_observers(
421
+ @impl_obj, self, res)
422
+ if res.respond_to?(:to_pguiobj)
423
+ prev_hbox = nil
424
+ if @subobjs_box.children.length > 0
425
+ (prev_hbox=@subobjs_box.children.last).children[
426
+ 0].end_node = false
427
+ @subobjs_box.append(pgtk_lk=PGtk::TreeLink.new)
428
+ (prev_obs=prev_hbox.children[1].
429
+ pgtkguiobj_death_observer).link = pgtk_lk
430
+ end
431
+ @subobjs_box.append(hbox=Gtk::HBox.new)
432
+ hbox.pack_start(pgtk_node=PGtk::TreeNodePadding.new(
433
+ true), false, false, 0)
434
+ res.pguiobj_post_destroy_flag.add_observer(obs =
435
+ PResMethodChildDeathObserver.new(@subobjs_box,hbox))
436
+ if prev_hbox
437
+ obs.prev_hbox = prev_hbox
438
+ obs.prev_link = pgtk_lk
439
+ prev_obs.next_obs = obs
440
+ end
441
+ hbox.pack_start(gobj=MObj.create(res.to_pguiobj,
442
+ false, pgtk_node), false, false, 0)
443
+ hbox.show_all
444
+ gobj.pgtkguiobj_death_observer = obs
445
+ @pguiobj_proto.pguiobj_children << res
446
+ res.pguiobj_parent_meth = @pguiobj_proto
447
+ elsif @pguiobj_proto.pguiobj_config.keep_not_guiobj_subobjs
448
+ @pguiobj_proto.pguiobj_children << res
449
+ gobj = nil
450
+ end
451
+ @pguiobj_proto.pguiobj_post_call_flag.changed
452
+ @pguiobj_proto.pguiobj_post_call_flag.notify_observers(
453
+ @impl_obj, self, res, gobj)
454
+ res
455
+ end
456
+
457
+ def pguiobj_clear_children
458
+ while !@subobjs_box.children.empty?
459
+ child = @subobjs_box.children.first
460
+ @subobjs_box.remove(child)
461
+ child.destroy unless child.destroyed?
462
+ end
463
+ @pguiobj_proto.pguiobj_clear_children
464
+ end
465
+
466
+ def pguiobj_each_child
467
+ @subobjs_box.children.each { |sbc|
468
+ if sbc.kind_of?(Gtk::HBox)
469
+ yield(sbc.children[1])
470
+ end
471
+ }
472
+ end
473
+
474
+ def method_missing(id, *args, &block)
475
+ @pguiobj_proto.send(id, *args, &block)
476
+ end
477
+ end
478
+
479
+ class PMethod
480
+ def self.create(meth, obj, *args)
481
+ if meth.pguiobj_config.no_res
482
+ PNoResMethod.create(meth, obj, *args)
483
+ else
484
+ PResMethod.create(meth, obj, *args)
485
+ end
486
+ end
487
+ end
488
+
489
+ module MObj
490
+ include InfoStrTTip
491
+
492
+ attr_reader :pguiobj_guiobj, :destroy_btn, :marshal_dump_btn,
493
+ :dump_to_s_btn, :dump_inspect_btn, :pguiobj_ttip_wgts
494
+ attr_accessor :pgtkguiobj_death_observer
495
+
496
+ alias_method :pguiobj_proto, :pguiobj_guiobj
497
+
498
+ def self.create(obj, destroy=true, tree_node=nil)
499
+ if obj.kind_of?(PGuiObj::MObjCollection) ||
500
+ obj.kind_of?(PGuiObj::ObjCollection)
501
+ impl_obj=ObjCollection.new(obj, destroy, tree_node)
502
+ else
503
+ impl_obj=Obj.new(obj, destroy, tree_node)
504
+ end
505
+ obj.pguiobj_impl_obj = impl_obj
506
+ end
507
+
508
+ def self.save_dialog(title)
509
+ dialog = Gtk::FileChooserDialog.new(title, nil,
510
+ Gtk::FileChooser::ACTION_SAVE, "gnome-vfs",
511
+ [Gtk::Stock::SAVE,Gtk::Dialog::RESPONSE_ACCEPT],
512
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL])
513
+ resp = dialog.run
514
+ path = dialog.filename
515
+ dialog.destroy
516
+ return if resp != Gtk::Dialog::RESPONSE_ACCEPT
517
+ if FileTest.exist?(path)
518
+ return unless PGtk.overwrite_dialog(path)
519
+ end
520
+ begin
521
+ open(path, 'w') { |file| yield(file) }
522
+ rescue IOError
523
+ PGtk.show_exc_dialog
524
+ end
525
+ end
526
+
527
+ def obj_pack_id(obj, title_box, cfg)
528
+ has_id = false
529
+ id_box = Gtk::HBox.new(false, 3)
530
+ if (icon = cfg.icon) && (img = PGtk.image_new(icon,
531
+ Gtk::IconSize::LARGE_TOOLBAR, 3, 3))
532
+ id_box.pack_start(img, false, false, 0)
533
+ has_id = true
534
+ end
535
+ if cfg.name
536
+ id_box.pack_start(Gtk::Label.new(
537
+ cfg.name.cap_first), false, false, 0)
538
+ has_id = true
539
+ end
540
+ id_box.pack_start(Gtk::Label.new('<' + obj.class.name+ ':' +
541
+ obj.object_id.mem_hex+'>'), false, false, 0) unless has_id
542
+ ev_box = Gtk::EventBox.new
543
+ ev_box.add(id_box)
544
+ id_box = ev_box
545
+ @pguiobj_ttip_wgts = [id_box]
546
+ if cfg.info_str
547
+ self.pguiobj_info_str = cfg.info_str
548
+ end
549
+ title_box.pack_start(id_box, false, false, 0)
550
+ end
551
+
552
+ def obj_pack_title_box(obj, title_box, cfg)
553
+ self.obj_pack_id(obj, title_box, cfg)
554
+ title_box.pack_end(Gtk::HBox.new,true,true,0)
555
+ unless cfg && cfg.destroy_btn == false
556
+ title_box.pack_end(@destroy_btn=Gtk::Button.new,
557
+ false, false, 0)
558
+ @destroy_btn.add(hbox=Gtk::HBox.new(false, 0))
559
+ hbox.pack_start(Gtk::Image.new(Gtk::Stock::DELETE,
560
+ Gtk::IconSize::BUTTON), false, false, 0)
561
+ hbox.pack_start(Gtk::Label.new('Destroy'),false,false,0)
562
+ @destroy_btn.signal_connect('clicked') { |btn,ev|
563
+ begin
564
+ @pguiobj_guiobj.pguiobj_pre_destroy_flag.changed
565
+ @pguiobj_guiobj.pguiobj_pre_destroy_flag.
566
+ notify_observers(self)
567
+ rescue PGuiObj::CancelCall
568
+ return true
569
+ end
570
+ @pguiobj_guiobj.pguiobj_parent_meth.
571
+ pguiobj_remove_child(@pguiobj_guiobj) if
572
+ @pguiobj_guiobj.pguiobj_parent_meth
573
+ @pguiobj_guiobj.pguiobj_post_destroy_flag.changed
574
+ @pguiobj_guiobj.pguiobj_post_destroy_flag.
575
+ notify_observers(self, @pguiobj_guiobj)
576
+ if @destroy
577
+ self.destroy
578
+ end
579
+ true
580
+ }
581
+ end
582
+ unless cfg && cfg.marshal_dump_btn == false
583
+ title_box.pack_end(@marshal_dump_btn=Gtk::Button.new,
584
+ false, false, 0)
585
+ @marshal_dump_btn.add(hbox=Gtk::HBox.new(false, 0))
586
+ hbox.pack_start(Gtk::Image.new(Gtk::Stock::SAVE,
587
+ Gtk::IconSize::BUTTON), false, false, 0)
588
+ hbox.pack_start(Gtk::Label.new('Dump (Marshal)'),
589
+ false,false,0)
590
+ @marshal_dump_btn.signal_connect('clicked') { |btn,ev|
591
+ MObj.save_dialog("Marshal.dump object to file"){|file|
592
+ Marshal.dump(@pguiobj_guiobj, file, 1500) }
593
+ }
594
+ end
595
+ unless cfg && cfg.dump_to_s_btn == false
596
+ title_box.pack_end(@dump_to_s_btn=Gtk::Button.new,
597
+ false, false, 0)
598
+ @dump_to_s_btn.add(hbox=Gtk::HBox.new(false, 0))
599
+ hbox.pack_start(Gtk::Image.new(Gtk::Stock::SAVE,
600
+ Gtk::IconSize::BUTTON), false, false, 0)
601
+ hbox.pack_start(Gtk::Label.new('Dump (to_s)'),
602
+ false,false,0)
603
+ @dump_to_s_btn.signal_connect('clicked') { |btn,ev|
604
+ MObj.save_dialog("Save object.to_s to file") { |file|
605
+ file.write(@pguiobj_guiobj.to_s) }
606
+ }
607
+ end
608
+ unless cfg && cfg.dump_inspect_btn == false
609
+ title_box.pack_end(@dump_inspect_btn=Gtk::Button.new,
610
+ false, false, 0)
611
+ @dump_inspect_btn.add(hbox=Gtk::HBox.new(false, 0))
612
+ hbox.pack_start(Gtk::Image.new(Gtk::Stock::SAVE,
613
+ Gtk::IconSize::BUTTON), false, false, 0)
614
+ hbox.pack_start(Gtk::Label.new('Dump (inspect)'),
615
+ false,false,0)
616
+ @dump_inspect_btn.signal_connect('clicked') { |btn,ev|
617
+ MObj.save_dialog("Save object.inspect to file"){|file|
618
+ file.write(@pguiobj_guiobj.inspect) }
619
+ }
620
+ end
621
+ title_box
622
+ end
623
+
624
+ def pguiobj_sig_changed(change)
625
+ @pguiobj_guiobj.pguiobj_changed_flag.changed
626
+ @pguiobj_guiobj.pguiobj_changed_flag.notify_observers(
627
+ self, change)
628
+ end
629
+
630
+ def method_missing(id, *args, &block)
631
+ @pguiobj_guiobj.send(id, *args, &block)
632
+ end
633
+ end
634
+
635
+ class Obj < LinearVBox
636
+ attr_reader :contents_box, :method_box
637
+ attr_accessor :destroy, :pguiobj_key
638
+ include MObj
639
+
640
+ sz = Gtk::IconSize.lookup(Gtk::IconSize::BUTTON)
641
+ @@img_collapse = PGtk.stock_pixbuf_of_size(:"pgtk-collapse",sz[0],sz[1])
642
+ @@img_collapse_hover = PGtk.stock_pixbuf_of_size(
643
+ :"pgtk-collapse-hover", sz[0], sz[0])
644
+ @@img_expand = PGtk.stock_pixbuf_of_size(:"pgtk-expand", sz[0], sz[1])
645
+ @@img_expand_hover=PGtk.stock_pixbuf_of_size(:"pgtk-expand-hover",
646
+ sz[0],sz[1])
647
+
648
+ def initialize(obj, destroy=true, tree_node=nil)
649
+ @pguiobj_guiobj = obj
650
+ @destroy = destroy
651
+ super()
652
+ #self.orientation = Gtk::Orientation::VERTICAL
653
+ cfg = @pguiobj_guiobj.pguiobj_config
654
+ @title_box = Gtk::HBox.new(false, 5)
655
+ if tree_node
656
+ @expanded = true
657
+ @expand_btn=PGtk::Button.new(:"pgtk-collapse",
658
+ @@img_expand.width, @@img_expand.height,
659
+ :"pgtk-collapse-hover") { |wgt,ev|
660
+ if @expanded
661
+ @expanded = false
662
+ @expand_btn.set_icons(@@img_expand,
663
+ @@img_expand_hover)
664
+ @contents_box.hide
665
+ else
666
+ @expanded = true
667
+ @expand_btn.set_icons(@@img_collapse,
668
+ @@img_collapse_hover)
669
+ @contents_box.show
670
+ end
671
+ }
672
+ tree_node.add_title_widget(@expand_btn)
673
+ end
674
+ self.append(@title_box)
675
+ self.obj_pack_title_box(obj, @title_box, cfg)
676
+ self.append(@contents_box=LinearVBox.new)
677
+ @contents_box.append(@method_box=LinearVBox.new)
678
+ @pguiobj_guiobj.pguiobj_methods.each { |meth|
679
+ @method_box.append(PMethod.create(meth, self)) }
680
+ end
681
+
682
+ def pguiobj_add_method(meth)
683
+ if (res = PMethod.create(meth, self)).pguiobj_config.no_res
684
+ @title_box.pack_start(res, false, false, 0)
685
+ else
686
+ @method_box.append(res)
687
+ end
688
+ res.show_all
689
+ res
690
+ end
691
+
692
+ def pguiobj_each_method
693
+ @title_box.children.each { |child|
694
+ yield(child) if child.kind_of?(PResMethod) ||
695
+ child.kind_of?(PNoResMethod) }
696
+ @method_box.children.each { |meth| yield(meth) }
697
+ end
698
+ end
699
+
700
+ class ObjCollectionChildDestroyer
701
+ attr_reader :collection, :idx_wgt
702
+
703
+ def initialize(collection, idx_wgt)
704
+ @collection = collection
705
+ @idx_wgt = idx_wgt
706
+ end
707
+
708
+ def update(child, under_child)
709
+ @collection.contents_table.remove(child)
710
+ @collection.contents_table.remove(@idx_wgt)
711
+ end
712
+ end
713
+
714
+ class ObjCollection < Obj
715
+ attr_reader :contents_table
716
+ attr_accessor :destroy, :pguiobj_key
717
+ include MObj
718
+
719
+ def initialize(obj, destroy=true, tree_node=nil)
720
+ if (info = obj.pguiobj_config.info_str)
721
+ info << ' '
722
+ else
723
+ info = obj.pguiobj_config.info_str = ''
724
+ end
725
+ info << "#{obj.pguiobj_length} element#{obj.pguiobj_length==1 ?
726
+ '' : 's'}."
727
+ super(obj, destroy, tree_node)
728
+ self.contents_box.append(@contents_table=Gtk::Table.new(
729
+ @pguiobj_guiobj.pguiobj_length, 2, false))
730
+ row = 0
731
+ @pguiobj_children = []
732
+ first = true
733
+ @pguiobj_guiobj.pguiobj_each_key_value { |k, val|
734
+ unless first
735
+ @contents_table.attach(PGtk::HSep.new,0,2, row,row+=1,
736
+ Gtk::EXPAND|Gtk::FILL, 0, 0, 0)
737
+ end
738
+ @contents_table.attach(idx_wgt=
739
+ Gtk::Label.new('• '+k.to_s+' '),
740
+ 0, 1, row, row+1, 0, 0, 0, 0)
741
+ @contents_table.attach(o=MObj.create(val), 1,2,
742
+ row,row+1, 0, 0, 0, 0)
743
+ o.pguiobj_post_destroy_flag.add_observer(
744
+ ObjCollectionChildDestroyer.new(self,idx_wgt))
745
+ o.pguiobj_key = k
746
+ @pguiobj_children << o
747
+ row += 1
748
+ first = false
749
+ }
750
+ end
751
+
752
+ def self.widget_each_child(wgt, &block)
753
+ yield(wgt)
754
+ if wgt.kind_of?(Gtk::Container)
755
+ wgt.children.each { |child|
756
+ self.widget_each_child(child, &block) }
757
+ end
758
+ end
759
+
760
+ def pguiobj_each_key_value
761
+ @pguiobj_children.each { |child|
762
+ yield(child.pguiobj_key, child) }
763
+ end
764
+
765
+ def pguiobj_each_value
766
+ @pguiobj_children.each { |child| yield(child) }
767
+ end
768
+ end
769
+
770
+ end
771
+
772
+ end