canis 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +45 -0
  3. data/CHANGES +52 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +24 -0
  7. data/Rakefile +2 -0
  8. data/canis.gemspec +25 -0
  9. data/examples/alpmenu.rb +46 -0
  10. data/examples/app.sample +19 -0
  11. data/examples/appemail.rb +191 -0
  12. data/examples/atree.rb +105 -0
  13. data/examples/bline.rb +181 -0
  14. data/examples/common/devel.rb +319 -0
  15. data/examples/common/file.rb +93 -0
  16. data/examples/data/README.markdown +9 -0
  17. data/examples/data/brew.txt +38 -0
  18. data/examples/data/color.2 +37 -0
  19. data/examples/data/gemlist.txt +59 -0
  20. data/examples/data/lotr.txt +12 -0
  21. data/examples/data/ports.txt +136 -0
  22. data/examples/data/table.txt +37 -0
  23. data/examples/data/tasks.csv +88 -0
  24. data/examples/data/tasks.txt +27 -0
  25. data/examples/data/todo.txt +16 -0
  26. data/examples/data/todocsv.csv +28 -0
  27. data/examples/data/unix1.txt +21 -0
  28. data/examples/data/unix2.txt +11 -0
  29. data/examples/dbdemo.rb +506 -0
  30. data/examples/dirtree.rb +177 -0
  31. data/examples/newtabbedwindow.rb +100 -0
  32. data/examples/newtesttabp.rb +92 -0
  33. data/examples/tabular.rb +212 -0
  34. data/examples/tasks.rb +179 -0
  35. data/examples/term2.rb +88 -0
  36. data/examples/testbuttons.rb +307 -0
  37. data/examples/testcombo.rb +102 -0
  38. data/examples/testdb.rb +182 -0
  39. data/examples/testfields.rb +208 -0
  40. data/examples/testflowlayout.rb +43 -0
  41. data/examples/testkeypress.rb +98 -0
  42. data/examples/testlistbox.rb +187 -0
  43. data/examples/testlistbox1.rb +199 -0
  44. data/examples/testmessagebox.rb +144 -0
  45. data/examples/testprogress.rb +116 -0
  46. data/examples/testree.rb +107 -0
  47. data/examples/testsplitlayout.rb +53 -0
  48. data/examples/testsplitlayout1.rb +49 -0
  49. data/examples/teststacklayout.rb +48 -0
  50. data/examples/testwsshortcuts.rb +68 -0
  51. data/examples/testwsshortcuts2.rb +129 -0
  52. data/lib/canis.rb +16 -0
  53. data/lib/canis/core/docs/index.txt +104 -0
  54. data/lib/canis/core/docs/list.txt +16 -0
  55. data/lib/canis/core/docs/style_help.yml +34 -0
  56. data/lib/canis/core/docs/tabbedpane.txt +15 -0
  57. data/lib/canis/core/docs/table.txt +31 -0
  58. data/lib/canis/core/docs/textpad.txt +48 -0
  59. data/lib/canis/core/docs/tree.txt +23 -0
  60. data/lib/canis/core/include/.DS_Store +0 -0
  61. data/lib/canis/core/include/action.rb +83 -0
  62. data/lib/canis/core/include/actionmanager.rb +49 -0
  63. data/lib/canis/core/include/appmethods.rb +179 -0
  64. data/lib/canis/core/include/bordertitle.rb +49 -0
  65. data/lib/canis/core/include/canisparser.rb +100 -0
  66. data/lib/canis/core/include/colorparser.rb +437 -0
  67. data/lib/canis/core/include/defaultfilerenderer.rb +64 -0
  68. data/lib/canis/core/include/io.rb +320 -0
  69. data/lib/canis/core/include/layouts/SplitLayout.rb +161 -0
  70. data/lib/canis/core/include/layouts/abstractlayout.rb +213 -0
  71. data/lib/canis/core/include/layouts/flowlayout.rb +104 -0
  72. data/lib/canis/core/include/layouts/stacklayout.rb +109 -0
  73. data/lib/canis/core/include/listbindings.rb +89 -0
  74. data/lib/canis/core/include/listeditable.rb +319 -0
  75. data/lib/canis/core/include/listoperations.rb +61 -0
  76. data/lib/canis/core/include/listselectionmodel.rb +388 -0
  77. data/lib/canis/core/include/multibuffer.rb +173 -0
  78. data/lib/canis/core/include/ractionevent.rb +73 -0
  79. data/lib/canis/core/include/rchangeevent.rb +27 -0
  80. data/lib/canis/core/include/rhistory.rb +95 -0
  81. data/lib/canis/core/include/rinputdataevent.rb +47 -0
  82. data/lib/canis/core/include/textdocument.rb +111 -0
  83. data/lib/canis/core/include/vieditable.rb +175 -0
  84. data/lib/canis/core/include/widgetmenu.rb +66 -0
  85. data/lib/canis/core/system/colormap.rb +165 -0
  86. data/lib/canis/core/system/keydefs.rb +32 -0
  87. data/lib/canis/core/system/ncurses.rb +237 -0
  88. data/lib/canis/core/system/panel.rb +129 -0
  89. data/lib/canis/core/system/window.rb +1081 -0
  90. data/lib/canis/core/util/ansiparser.rb +119 -0
  91. data/lib/canis/core/util/app.rb +696 -0
  92. data/lib/canis/core/util/basestack.rb +412 -0
  93. data/lib/canis/core/util/defaultcolorparser.rb +84 -0
  94. data/lib/canis/core/util/extras/README +5 -0
  95. data/lib/canis/core/util/extras/bottomline.rb +1815 -0
  96. data/lib/canis/core/util/extras/padreader.rb +192 -0
  97. data/lib/canis/core/util/focusmanager.rb +31 -0
  98. data/lib/canis/core/util/helpmanager.rb +160 -0
  99. data/lib/canis/core/util/oldwidgetshortcuts.rb +304 -0
  100. data/lib/canis/core/util/promptmenu.rb +235 -0
  101. data/lib/canis/core/util/rcommandwindow.rb +933 -0
  102. data/lib/canis/core/util/rdialogs.rb +520 -0
  103. data/lib/canis/core/util/textutils.rb +74 -0
  104. data/lib/canis/core/util/viewer.rb +238 -0
  105. data/lib/canis/core/util/widgetshortcuts.rb +508 -0
  106. data/lib/canis/core/widgets/applicationheader.rb +103 -0
  107. data/lib/canis/core/widgets/box.rb +58 -0
  108. data/lib/canis/core/widgets/divider.rb +310 -0
  109. data/lib/canis/core/widgets/extras/README.md +12 -0
  110. data/lib/canis/core/widgets/extras/rtextarea.rb +960 -0
  111. data/lib/canis/core/widgets/extras/stackflow.rb +474 -0
  112. data/lib/canis/core/widgets/keylabelprinter.rb +194 -0
  113. data/lib/canis/core/widgets/listbox.rb +326 -0
  114. data/lib/canis/core/widgets/listfooter.rb +86 -0
  115. data/lib/canis/core/widgets/rcombo.rb +210 -0
  116. data/lib/canis/core/widgets/rcontainer.rb +415 -0
  117. data/lib/canis/core/widgets/rlink.rb +30 -0
  118. data/lib/canis/core/widgets/rmenu.rb +970 -0
  119. data/lib/canis/core/widgets/rmenulink.rb +30 -0
  120. data/lib/canis/core/widgets/rmessagebox.rb +400 -0
  121. data/lib/canis/core/widgets/rprogress.rb +118 -0
  122. data/lib/canis/core/widgets/rtabbedpane.rb +631 -0
  123. data/lib/canis/core/widgets/rtabbedwindow.rb +70 -0
  124. data/lib/canis/core/widgets/rwidget.rb +3634 -0
  125. data/lib/canis/core/widgets/scrollbar.rb +147 -0
  126. data/lib/canis/core/widgets/statusline.rb +113 -0
  127. data/lib/canis/core/widgets/table.rb +1072 -0
  128. data/lib/canis/core/widgets/tabular.rb +264 -0
  129. data/lib/canis/core/widgets/textpad.rb +1674 -0
  130. data/lib/canis/core/widgets/tree.rb +690 -0
  131. data/lib/canis/core/widgets/tree/treecellrenderer.rb +150 -0
  132. data/lib/canis/core/widgets/tree/treemodel.rb +432 -0
  133. data/lib/canis/version.rb +3 -0
  134. metadata +229 -0
@@ -0,0 +1,320 @@
1
+ #*******************************************************
2
+ # Some common io routines for getting data or putting
3
+ # at some point
4
+ # Current are:
5
+ # * rb_gets - get a string at bottom of screen
6
+ # * get_file
7
+ # * rb_getchar - get a char
8
+ #
9
+ # * Promptmenu creation
10
+ # requires rcommandwindow
11
+ #
12
+ # *
13
+ # * rb_getstr (and those it calls) (old and for backward compat)
14
+ # - rb_getstr is used by vieditable for edit_line and insert_line
15
+ # * display_cmenu and create_mitem
16
+ # Changes:
17
+ # 2011-12-6 : removed many old, outdated methods.
18
+ # 2014-04-25 - 12:36 moved Promptmenu to util/promptmenu.rb
19
+ #*******************************************************#
20
+ require 'pathname'
21
+ module Canis
22
+ module Io
23
+
24
+ # create a 2 line window at bottom to accept user input
25
+ #
26
+ def __create_footer_window h = 2 , w = Ncurses.COLS, t = Ncurses.LINES-2, l = 0
27
+ ewin = Canis::Window.new(h, w , t, l)
28
+ end
29
+ # 2011-11-27 I have replaced the getting of chars with a field
30
+
31
+ # get a string at the bottom of the screen
32
+ #
33
+ # @param [String] prompt - label to show
34
+ # @param [Hash] config - :default, :width of Field, :help_text, :tab_completion
35
+ # help_text is displayed on F1
36
+ # tab_completion is a proc which helps to complete user input
37
+ # @yield [Field] for overriding or customization
38
+ # @return [String, nil] String if entered, nil if canceled
39
+ def rb_gets(prompt, config={}) # yield field
40
+ if config.is_a? Hash
41
+ # okay
42
+ #
43
+ elsif config.is_a? Array
44
+ # an array is supplied, and tabbing helps complete from that
45
+ # array.
46
+ options = config
47
+ completion_proc = Proc.new{|str|
48
+ options.dup.grep Regexp.new("^#{str}");
49
+ }
50
+ config = {}
51
+ config[:tab_completion] = completion_proc
52
+ elsif config == Pathname
53
+ # we need to return a pathname TODO and prepend dirname
54
+ # allow user to specify startdir else take current
55
+ completion_proc = Proc.new {|str| Dir.glob(str +"*").collect { |f| File.directory?(f) ? f+"/" : f } }
56
+ help_text = "Enter start of filename and tab to get completion"
57
+ config = {}
58
+ config[:tab_completion] = completion_proc
59
+ config[:help_text] = help_text
60
+ elsif config == Integer
61
+ config = {}
62
+ config[:datatype] = 1.class
63
+ config[:type] = :integer
64
+ elsif config == Float
65
+ config = {}
66
+ v = 0.11
67
+ config[:datatype] = v.class
68
+ config[:type] = :float
69
+ elsif config == :phone
70
+
71
+ config = {}
72
+ end
73
+ begin
74
+ win = __create_footer_window
75
+ form = Form.new win
76
+ r = 0; c = 1;
77
+ default = config[:default] || ""
78
+ prompt = "#{prompt} [#{default}]:" if default.size > 0
79
+ _max = FFI::NCurses.COLS-1-prompt.size-4
80
+ displen = config[:width] || [config[:maxlen] || 999, _max].min
81
+ maxlen = config[:maxlen] || _max
82
+ field = LabeledField.new form, :row => r, :col => c, :maxlen => maxlen, :default => default, :label => prompt,
83
+ :width => displen
84
+ field.datatype(config[:datatype]) if config[:datatype]
85
+ field.type(config[:type]) if config[:type]
86
+ bg = Ncurses.COLORS >= 236 ? 233 : :blue
87
+ field.bgcolor = bg
88
+ field.cursor_end if default.size > 0
89
+ def field.default=(x); default(x);end
90
+
91
+ # if user wishes to use the yield and say "field.history = [x,y,z] then
92
+ # we should alredy have extended this, so lets make it permanent
93
+ require 'canis/core/include/rhistory'
94
+ field.extend(FieldHistory)
95
+ field.history = config[:history]
96
+
97
+ yield field if block_given?
98
+ form.repaint
99
+ win.wrefresh
100
+ prevchar = 0
101
+ entries = nil
102
+ oldstr = nil # for tab completion, origal word entered by user
103
+ while ((ch = win.getchar()) != 999)
104
+ if ch == 10 || ch == 13 || ch == KEY_ENTER
105
+ begin
106
+ # validate in case ranges or other validation given
107
+ field.on_leave
108
+ break
109
+ rescue FieldValidationException => err # added 2011-10-2 v1.3.1 so we can rollback
110
+ #alert err.to_s
111
+ # unable to use alert now, since closing alert repaints root window and clears the
112
+ # window this was on (command window in numbered menu).
113
+ print_this(win, err.to_s, $errorcolor, 1, 0)
114
+ form.setpos
115
+ rescue => err
116
+ Ncurses.beep
117
+ break
118
+ end
119
+ end
120
+ #return -1, nil if ch == ?\C-c.getbyte(0) || ch == ?\C-g.getbyte(0)
121
+ return nil if ch == ?\C-c.getbyte(0) || ch == ?\C-g.getbyte(0)
122
+ #if ch == ?\M-h.getbyte(0) # HELP KEY
123
+ #help_text = config[:help_text] || "No help provided"
124
+ #color = $datacolor
125
+ #print_help(win, r, c, color, help_text)
126
+ ## this will come over our text
127
+ #end
128
+ # tab completion and help_text print on F1
129
+ # that field objects can extend, same for tab completion and gmail completion
130
+ if ch == KEY_TAB
131
+ if config
132
+ str = field.text
133
+ # tab_completion
134
+ # if previous char was not tab, execute tab_completion_proc and push first entry
135
+ # else push the next entry
136
+ if prevchar == KEY_TAB
137
+ if !entries.nil? && !entries.empty?
138
+ str = entries.delete_at(0)
139
+ else
140
+ str = oldstr if oldstr
141
+ prevchar = ch = nil # so it can start again completing
142
+ end
143
+ else
144
+ tabc = config[:tab_completion] unless tabc
145
+ next unless tabc
146
+ oldstr = str.dup
147
+ entries = tabc.call(str).dup
148
+ $log.debug " tab got #{entries} for str=#{str}"
149
+ str = entries.delete_at(0) unless entries.nil? || entries.empty?
150
+ str = str.to_s.dup
151
+ end
152
+ if str
153
+ field.text = str
154
+ field.cursor_end
155
+ field.set_form_col # shit why are we doign this, text sets curpos to 0
156
+ end
157
+ form.repaint
158
+ win.wrefresh
159
+ end
160
+
161
+ elsif ch == KEY_F1
162
+ help_text = config[:help_text] || "No help provided. C-c/C-g aborts. <TAB> completion. Alt-h history. C-a/e"
163
+ print_status_message help_text, :wait => 7
164
+ else
165
+ form.handle_key ch
166
+ end
167
+ prevchar = ch
168
+ win.wrefresh
169
+ end
170
+ rescue => err
171
+ Ncurses.beep
172
+ textdialog [err.to_s, *err.backtrace], :title => "Exception"
173
+ $log.error "EXC in rb_getstr #{err} "
174
+ $log.error(err.backtrace.join("\n"))
175
+ ensure
176
+ win.destroy if win
177
+ end
178
+ config[:history] << field.text if config[:history] && field.text
179
+ return field.text
180
+ end
181
+
182
+ # get a character.
183
+ # unlike rb_gets allows user to enter control or alt or function character too.
184
+ # @param [String] prompt or label to show.
185
+ # @param [Hash] configuration such as default or regexp for validation
186
+ # @return [Fixnum] nil if canceled, or ret value of getchar which is numeric
187
+ # If default provided, then ENTER returns the default
188
+ def rb_getchar(prompt, config={}) # yield field
189
+ begin
190
+ win = __create_footer_window
191
+ #form = Form.new win
192
+ r = 0; c = 1;
193
+ default = config[:default]
194
+ prompt = "#{prompt} [#{default}] " if default
195
+ win.mvprintw(r, c, "%s: " % prompt);
196
+ bg = Ncurses.COLORS >= 236 ? 236 : :blue
197
+ color_pair = get_color($reversecolor, :white, bg)
198
+ win.printstring r, c + prompt.size + 2, " ", color_pair
199
+
200
+ win.wrefresh
201
+ prevchar = 0
202
+ entries = nil
203
+ while ((ch = win.getchar()) != 999)
204
+ return default.ord if default && (ch == 13 || ch == KEY_ENTER)
205
+ return nil if ch == ?\C-c.getbyte(0) || ch == ?\C-g.getbyte(0)
206
+ if ch == KEY_F1
207
+ help_text = config[:help_text] || "No help provided. C-c/C-g aborts."
208
+ print_status_message help_text, :wait => 7
209
+ win.wrefresh # nevr had to do this with ncurses, but have to with ffi-ncurses ??
210
+ next
211
+ end
212
+ if config[:regexp]
213
+ reg = config[:regexp]
214
+ if ch > 0 && ch < 256
215
+ chs = ch.chr
216
+ return ch if chs =~ reg
217
+ alert "Wrong character. #{reg} "
218
+ else
219
+ alert "Wrong character. #{reg} "
220
+ end
221
+ else
222
+ return ch
223
+ end
224
+ #form.handle_key ch
225
+ win.wrefresh
226
+ end
227
+ rescue => err
228
+ Ncurses.beep
229
+ $log.error "EXC in rb_getstr #{err} "
230
+ $log.error(err.backtrace.join("\n"))
231
+ ensure
232
+ win.destroy if win
233
+ end
234
+ return nil
235
+ end
236
+
237
+ # This is just experimental, trying out tab_completion
238
+ # Prompt user for a file name, allowing him to tab to complete filenames
239
+ # @see #choose_file from rcommandwindow.rb
240
+ # @param [String] label to print before field
241
+ # @param [Fixnum] max length of field
242
+ # @return [String] filename or blank if user cancelled
243
+ def get_file prompt, config={} #:nodoc:
244
+ maxlen = 70
245
+ tabc = Proc.new {|str| Dir.glob(str +"*") }
246
+ config[:tab_completion] ||= tabc
247
+ config[:maxlen] ||= maxlen
248
+ #config[:default] = "test"
249
+ #ret, str = rb_getstr(nil,0,0, prompt, maxlen, config)
250
+ # 2014-04-25 - 12:42 removed call to deprecated method
251
+ str = rb_gets(prompt, config)
252
+ #$log.debug " get_file returned #{ret} , #{str} "
253
+ str ||= ""
254
+ return str
255
+ end
256
+ def clear_this win, r, c, color, len
257
+ print_this(win, "%-*s" % [len," "], color, r, c)
258
+ end
259
+
260
+
261
+
262
+ ##
263
+ # prints given text to window, in color at x and y coordinates
264
+ # @param [Window] window to write to
265
+ # @param [String] text to print
266
+ # @param [int] color pair such as $datacolor or $promptcolor
267
+ # @param [int] x row
268
+ # @param [int] y col
269
+ # @see Window#printstring
270
+ def print_this(win, text, color, x, y)
271
+ raise "win nil in print_this" unless win
272
+ color=Ncurses.COLOR_PAIR(color);
273
+ win.attron(color);
274
+ #win.mvprintw(x, y, "%-40s" % text);
275
+ win.mvprintw(x, y, "%s" % text);
276
+ win.attroff(color);
277
+ win.refresh
278
+ end
279
+
280
+
281
+ #
282
+ # warn user: currently flashes and places error in log file
283
+ # experimental, may change interface later
284
+ # it does not say anything on screen
285
+ # @param [String] text of error/warning to put in log
286
+ # @since 1.1.5
287
+ def warn string
288
+ $log.warn string
289
+ Ncurses.beep
290
+ end
291
+
292
+
293
+ # routine to get a string at bottom of window.
294
+ # The first 3 params are no longer required since we create a window
295
+ # of our own.
296
+ # @param [String] prompt - label to show
297
+ # @param [Fixnum] maxlen - max length of input
298
+ # @param [Hash] config - :default, :width of Field, :help_text, :tab_completion
299
+ # help_text is displayed on F1
300
+ # tab_completion is a proc which helps to complete user input
301
+ # NOTE : This method is now only for **backward compatibility**
302
+ # rb_getstr had various return codes based on whether user asked for help
303
+ # possibly mimicking alpine, or because i could do nothing about it.
304
+ # Now, rb_getstr handles that and only returns if the user cancels or enters
305
+ # a string, so rb_getstr does not need to return other codes.
306
+ # @deprecated
307
+ def rb_getstr(nolongerused, r, c, prompt, maxlen, config={})
308
+ config[:maxlen] = maxlen
309
+ str = rb_gets(prompt, config)
310
+ if str
311
+ return 0, str
312
+ else
313
+ return -1, nil
314
+ end
315
+ end
316
+
317
+
318
+
319
+ end # module
320
+ end # module
@@ -0,0 +1,161 @@
1
+ # ----------------------------------------------------------------------------- #
2
+ # File: SplitLayout.rb
3
+ # Description:
4
+ # Author: j kepler http://github.com/mare-imbrium/canis/
5
+ # Date: 2014-05-10 - 13:48
6
+ # License: MIT
7
+ # Last update: 2014-05-10 20:19
8
+ # ----------------------------------------------------------------------------- #
9
+ # SplitLayout.rb Copyright (C) 2012-2014 j kepler
10
+ # ----
11
+ # This layout allows for complex arrangements of stacks and flows. One can divide the layout
12
+ # into splits (vertical or horizontal) and keep dividing a split, or placing a component in it.
13
+ # However, to keep it simple and reduce the testing, I am insisting that a weightage be specified
14
+ # with a split.
15
+ #
16
+ # layout = SplitLayout.new :height => -1, :top_margin => 1, :bottom_margin => 1, :left_margin => 1
17
+ # x, y = layout.vsplit( 0.30, 0.70)
18
+ # x.component = mylist
19
+ # y1, y2 = y.split( 0.40, 0.60 )
20
+ # y2.component = mytable
21
+ # y11,y12,y13 = y1.vsplit( 0.3, 0.3, 0.4)
22
+ # y11 = list1
23
+ # y12 = list2
24
+ # y13 = list3
25
+ #
26
+ # Or hopefully:
27
+ #
28
+ # layout.split(0.3, 0.7) do |x,y|
29
+ # x.component = mylist
30
+ # y.split(0.4, 0.6) do |a,b|
31
+ # b.component = mytable
32
+ # a.vsplit( 0.3, 0.3, 0.4) do | p,q,r |
33
+ # p.component = list1
34
+ # end
35
+ # end
36
+ # end
37
+ #
38
+ #
39
+ class Split
40
+
41
+ attr_reader :component
42
+ attr_accessor :name
43
+ attr_reader :splits
44
+ attr_accessor :height, :width, :top, :left
45
+ # link to parent
46
+ # own weight
47
+ attr_accessor :parent, :weight
48
+ # weights of child splits, given in cons
49
+ attr_accessor :split_wts
50
+ attr_reader :type
51
+
52
+ def initialize type, weight, parent
53
+ @type = type
54
+ @weight = weight
55
+ @parent = parent
56
+ end
57
+ def _split type, args, &block
58
+ @split_wts = args
59
+ @splits = []
60
+ args.each do |e|
61
+ @splits << Split.new(type, e, self)
62
+ end
63
+ if block_given?
64
+ yield @splits.flatten
65
+ else
66
+ return @splits.flatten
67
+ end
68
+ end
69
+ def split *args, &block
70
+ _split :h, args, &block
71
+ end
72
+ def vsplit *args, &block
73
+ _split :v, args, &block
74
+ end
75
+
76
+ # Set a component into a split.
77
+ # set name of component as name of split, more for debugging
78
+ def component=(c)
79
+ @component = c
80
+ @name = c.name || c.class.to_s
81
+ end
82
+
83
+ # shorthand to place a component in a split.
84
+ alias :<< :component=
85
+ end
86
+
87
+
88
+
89
+ require 'canis/core/include/layouts/abstractlayout'
90
+ class SplitLayout < AbstractLayout
91
+
92
+ # @param [Form] optional give a form
93
+ # @param [Hash] optional give settings/attributes which will be set into variables
94
+ def initialize arg, config={}, &block
95
+ super
96
+ @splits = nil
97
+ end
98
+ def _split type, args, &block
99
+ @splits = []
100
+ @split_wts = args
101
+ args.each do |e|
102
+ @splits << Split.new(type, e, self)
103
+ end
104
+ if block_given?
105
+ yield @splits.flatten
106
+ else
107
+ return @splits.flatten
108
+ end
109
+ end
110
+
111
+ def split *args, &block
112
+ raise "already split " if @splits
113
+ _split :h, args, &block
114
+ end
115
+ def vsplit *args, &block
116
+ raise "already split " if @splits
117
+ $log.debug " SPLIT GOT #{args} "
118
+ _split :v, args, &block
119
+ end
120
+ alias :top :top_margin
121
+ alias :left :left_margin
122
+
123
+
124
+ # This program lays out the widgets deciding their row and columm and height and weight.
125
+ # This program is called once at start of application, and again whenever a RESIZE event happens.
126
+ def do_layout
127
+ _init_layout
128
+ recalc @splits, @top_margin, @left_margin if @splits
129
+ #
130
+ $log.debug " layout finished "
131
+ end
132
+ def recalc splits, r, c
133
+ splits.each_with_index do |s,i|
134
+ $log.debug " recalc #{i}, #{s} "
135
+ p = s.parent
136
+ s.top = r
137
+ s.left = c
138
+ case s.type
139
+ when :v
140
+ s.width = (s.weight * p.width ).floor
141
+ s.height = p.height
142
+ c += s.width
143
+ when :h
144
+ s.height = (s.weight * p.height ).floor
145
+ s.width = p.width
146
+ r += s.height
147
+ end
148
+ if s.component
149
+ s.component.height = s.height
150
+ s.component.row = s.top
151
+ s.component.col = s.left
152
+ s.component.width = s.width
153
+ elsif s.splits
154
+ recalc s.splits, s.top, s.left if s.splits
155
+ else
156
+ raise "Neither splits nor a component placed in #{s} #{s.type}, #{s.weight} #{s.name}"
157
+ end
158
+ end
159
+
160
+ end
161
+ end