canis 0.0.4

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 (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,30 @@
1
+ require 'canis/core/widgets/rlink'
2
+ ##
3
+ module Canis
4
+ class MenuLink < Link
5
+ dsl_property :description
6
+
7
+ def initialize form, config={}, &block
8
+ config[:hotkey] = true
9
+ super
10
+ @col_offset = -1 * (@col || 1)
11
+ @row_offset = -1 * (@row || 1)
12
+ # in this case, we wish to use ENTER for firing
13
+ bind_key( KEY_ENTER, "fire" ) { fire }
14
+ # next did not work
15
+ #bind_key( KEY_ENTER, "fire" ) { get_action( 32 ) }
16
+ # next 2 work
17
+ #bind_key( KEY_ENTER, "fire" ) { @form.window.ungetch(32) }
18
+ #@_key_map[KEY_ENTER] = @_key_map[32]
19
+ #get_action_map()[KEY_ENTER] = get_action(32)
20
+ end
21
+ # added for some standardization 2010-09-07 20:28
22
+ # alias :text :getvalue # NEXT VERSION
23
+ # change existing text to label
24
+
25
+ def getvalue_for_paint
26
+ "%s %-12s - %-s" % [ @mnemonic , getvalue(), @description ]
27
+ end
28
+ ##
29
+ end # class
30
+ end # module
@@ -0,0 +1,400 @@
1
+ # --------------------------------------------------------------------------------- #
2
+ # File: rmessagebox.rb
3
+ # Description: This is a cleaner attempt at messagebox on the lines of
4
+ # the new tabbedpane and window.
5
+ # Author: jkepler http://github.com/mare-imbrium/canis/
6
+ # Date: 03.11.11 - 22:15
7
+ # License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
8
+ # Last update: 2014-07-08 18:05
9
+ # == CHANGES
10
+ # == TODO
11
+ # _ <ENTER> should result in OK being pressed if its default, ESC should result in cancel esp 2 time
12
+ # ensure that text and message are used in isolation and not with other things
13
+ #
14
+ # _ determine window size, but we are doing instance eval later.
15
+ #
16
+ # _ maybe have shortcuts for some widgets field, buttons, text and label and
17
+ # share with app and otherszz
18
+ #
19
+ # _ stack, flow and grid
20
+ #
21
+ # --------------------------------------------------------------------------------- #
22
+
23
+ require 'canis'
24
+ require 'canis/core/include/bordertitle'
25
+
26
+ include Canis
27
+ module Canis
28
+ extend self
29
+ class MessageBox
30
+ include BorderTitle
31
+ include Canis::Utils
32
+
33
+ attr_reader :form
34
+ attr_reader :window
35
+ dsl_accessor :button_type
36
+ dsl_accessor :default_button
37
+ #
38
+ # a message to be printed, usually this will be the only thing supplied
39
+ # with an OK button. This should be a short string, a label will be used
40
+ # and input_config passed to it
41
+
42
+ #dsl_accessor :message
43
+ # you can also set button_orientation : :right, :left, :center
44
+ #
45
+ def initialize config={}, &block
46
+
47
+ h = config.fetch(:height, nil)
48
+ w = config.fetch(:width, nil)
49
+ t = config.fetch(:row, nil)
50
+ l = config.fetch(:col, nil)
51
+ if h && w && t && l
52
+ @window = Canis::Window.new :height => h, :width => w, :top => t, :left => l
53
+ @graphic = @window
54
+ end
55
+ @form = Form.new @window
56
+
57
+ config.each_pair { |k,v| instance_variable_set("@#{k}",v) }
58
+ @config = config
59
+ @row = 0
60
+ @col = 0
61
+ @row_offset = 1
62
+ @col_offset = 2
63
+ #bordertitle_init
64
+ @color ||= :black
65
+ @bgcolor ||= :white
66
+ # 2014-05-31 - 11:44 adding form color
67
+ # try not to set buttons color in this program, let button pick up user or form colors
68
+ @form.color = @color
69
+ @form.bgcolor = @bgcolor
70
+ @maxrow = 3
71
+
72
+ #instance_eval &block if block_given?
73
+ yield_or_eval &block if block_given?
74
+
75
+ end
76
+ def item widget
77
+ # remove from existing form if set, problem with this is mnemonics -- rare situation.
78
+ if widget.form
79
+ f = widget.form
80
+ f.remove_widget widget
81
+ end
82
+ @maxrow ||= 3
83
+ widget.set_form @form
84
+ widget.row ||= 0
85
+ widget.col ||= 0
86
+ if widget.row == 0
87
+ widget.row = [@maxrow+1, 3].max if widget.row == 0
88
+ else
89
+ widget.row += @row_offset
90
+ end
91
+ if widget.col === 0
92
+ widget.col = 5 if widget.col === 0
93
+ else
94
+ # i don't know button_offset as yet
95
+ widget.col += @col_offset
96
+ end
97
+ # in most cases this override is okay, but what if user has set it
98
+ # The problem is that widget and field are doing a default setting so i don't know
99
+ # if user has set or widget has done a default setting. NOTE
100
+ # 2014-05-31 - 12:40 CANIS BUTTONCOLOR i have commented out since it should take from form
101
+ # to see effect
102
+ if false
103
+ widget.color ||= @color # we are overriding colors, how to avoid since widget sets it
104
+ widget.bgcolor ||= @bgcolor
105
+ widget.attr = @attr if @attr # we are overriding what user has put. DARN !
106
+ end
107
+ @maxrow = widget.row if widget.row > @maxrow
108
+ @suggested_h = @height || @maxrow+6
109
+ @suggested_w ||= 0
110
+ @suggested_w = widget.col + 15 if widget.col > @suggested_w
111
+ # if w's given col is > width then add to suggested_w or text.length
112
+ end
113
+ alias :add :item
114
+ # returns button index
115
+ # Call this after instantiating the window
116
+ def run
117
+ repaint
118
+ @form.repaint
119
+ @window.wrefresh
120
+ return handle_keys
121
+ end
122
+ def repaint
123
+ _create_window unless @window
124
+ acolor = get_color $reverscolor, @color, @bgcolor
125
+ $log.debug " MESSAGE BOX bg:#{@bgcolor} , co:#{@color} , colorpair:#{acolor}"
126
+ @window.wbkgd(Ncurses.COLOR_PAIR(acolor)); # does not work on xterm-256color
127
+
128
+ #print_borders unless @suppress_borders # do this once only, unless everything changes
129
+ #@window.print_border_mb 1,2, @height, @width, $normalcolor, FFI::NCurses::A_REVERSE
130
+ @color_pair = get_color($datacolor, @color, @bgcolor)
131
+ bordercolor = @border_color || @color_pair
132
+ borderatt = @border_attrib || Ncurses::A_NORMAL
133
+ @window.wattron(Ncurses.COLOR_PAIR(bordercolor) | (borderatt || FFI::NCurses::A_NORMAL))
134
+ @window.print_border_mb 1,2, @height, @width, bordercolor, borderatt
135
+ @window.wattroff(Ncurses.COLOR_PAIR(bordercolor) | (borderatt || FFI::NCurses::A_NORMAL))
136
+ @title ||= "+-+"
137
+ title = " "+@title+" "
138
+ @window.printstring(@row=1,@col=(@width-title.length)/2,title, color=$normalcolor)
139
+ #print_message if @message
140
+ create_action_buttons unless @action_buttons
141
+ end
142
+ # Pass a short message to be printed.
143
+ # This creates a label for a short message, and a field for a long one.
144
+ # @yield field created
145
+ # @param [String] text to display
146
+ def message message # yield label or field being used for display for further customization
147
+ @suggested_h = @height || 10
148
+ message = message.gsub(/[\n\r\t]/,' ') rescue message
149
+ message_col = 5
150
+ @suggested_w = @width || [message.size + 8 + message_col , FFI::NCurses.COLS-2].min
151
+ r = 3
152
+ len = message.length
153
+ @suggested_w = len + 8 + message_col if len < @suggested_w - 8 - message_col
154
+
155
+ display_length = @suggested_w-8
156
+ display_length -= message_col
157
+ message_height = 2
158
+ clr = @color || :white
159
+ bgclr = @bgcolor || :black
160
+
161
+ # trying this out. sometimes very long labels get truncated, so i give a field in wchich user
162
+ # can use arrow key or C-a and C-e
163
+ if message.size > display_length
164
+ message_label = Canis::Field.new @form, {:text => message, :name=>"message_label",
165
+ :row => r, :col => message_col, :width => display_length,
166
+ :bgcolor => bgclr , :color => clr, :editable => false}
167
+ else
168
+ message_label = Canis::Label.new @form, {:text => message, :name=>"message_label",
169
+ :row => r, :col => message_col, :width => display_length,
170
+ :height => message_height, :bgcolor => bgclr , :color => clr}
171
+ end
172
+ @maxrow = 3
173
+ yield message_label if block_given?
174
+ end
175
+ alias :message= :message
176
+
177
+ # This is for larger messages, or messages where the size is not known.
178
+ # A textview object is created and yielded.
179
+ #
180
+ def text message
181
+ @suggested_w = @width || (FFI::NCurses.COLS * 0.80).floor
182
+ @suggested_h = @height || (FFI::NCurses.LINES * 0.80).floor
183
+
184
+ message_col = 3
185
+ r = 2
186
+ display_length = @suggested_w-4
187
+ display_length -= message_col
188
+ clr = @color || :white
189
+ bgclr = @bgcolor || :black
190
+
191
+ if message.is_a? Array
192
+ l = longest_in_list message
193
+ if l > @suggested_w
194
+ if l < FFI::NCurses.COLS
195
+ #@suggested_w = l
196
+ @suggested_w = FFI::NCurses.COLS-2
197
+ else
198
+ @suggested_w = FFI::NCurses.COLS-2
199
+ end
200
+ display_length = @suggested_w-6
201
+ end
202
+ # reduce width and height if you can based on array contents
203
+ else
204
+ message = wrap_text(message, display_length).split("\n")
205
+ end
206
+ # now that we have moved to textpad that +8 was causing black lines to remain after the text
207
+ message_height = message.size #+ 8
208
+ # reduce if possible if its not required.
209
+ #
210
+ r1 = (FFI::NCurses.LINES-@suggested_h)/2
211
+ r1 = r1.floor
212
+ w = @suggested_w
213
+ c1 = (FFI::NCurses.COLS-w)/2
214
+ c1 = c1.floor
215
+ @suggested_row = r1
216
+ @suggested_col = c1
217
+ brow = @button_row || @suggested_h-4
218
+ available_ht = brow - r + 1
219
+ message_height = [message_height, available_ht].min
220
+ # replaced 2014-04-14 - 23:51
221
+ message_label = Canis::TextPad.new @form, {:name=>"message_label", :text => message,
222
+ :row => r, :col => message_col, :width => display_length, :suppress_borders => true,
223
+ :height => message_height, :bgcolor => bgclr , :color => clr}
224
+ #message_label.set_content message
225
+ yield message_label if block_given?
226
+
227
+ end
228
+ alias :text= :text
229
+
230
+ # returns button index (or in some cases, whatever value was thrown
231
+ # if user did not specify any button_type but gave his own and did throw (:close, x)
232
+ private
233
+ def handle_keys
234
+ buttonindex = catch(:close) do
235
+ while((ch = @window.getchar()) != FFI::NCurses::KEY_F10 )
236
+ break if ch == ?\C-q.getbyte(0) || ch == 2727 # added double esc
237
+ begin
238
+ @form.handle_key(ch)
239
+ @window.wrefresh
240
+ rescue => err
241
+ $log.debug( err) if err
242
+ $log.debug(err.backtrace.join("\n")) if err
243
+ textdialog ["Error in Messagebox: #{err} ", *err.backtrace], :title => "Exception"
244
+ @window.refresh # otherwise the window keeps showing (new FFI-ncurses issue)
245
+ $error_message.value = ""
246
+ ensure
247
+ end
248
+
249
+ end # while loop
250
+ end # close
251
+ $log.debug "XXX: CALLER BEING RETURNED #{buttonindex} "
252
+ @window.destroy
253
+ # added 2014-05-01 - 18:10 hopefully to refresh root_window.
254
+ #Window.refresh_all
255
+ return buttonindex
256
+ end
257
+ private
258
+ def create_action_buttons
259
+ return unless @button_type
260
+ @default_button = 0 if !@default_button
261
+ case @button_type.to_s.downcase
262
+ when "ok"
263
+ make_buttons ["&OK"]
264
+ when "ok_cancel" #, "input", "list", "field_list"
265
+ make_buttons %w[&OK &Cancel]
266
+ when "ok_apply_cancel" #, "input", "list", "field_list"
267
+ make_buttons %w[&OK &Apply &Cancel]
268
+ when "yes_no"
269
+ make_buttons %w[&Yes &No]
270
+ when "yes_no_cancel"
271
+ make_buttons ["&Yes", "&No", "&Cancel"]
272
+ when "custom"
273
+ raise "Blank list of buttons passed to custom" if @buttons.nil? or @buttons.size == 0
274
+ make_buttons @buttons
275
+ else
276
+ $log.warn "No buttontype passed for creating tabbedpane. Not creating any"
277
+ #make_buttons ["&OK"]
278
+ end
279
+ end
280
+ private
281
+ def make_buttons names
282
+ @action_buttons = []
283
+ $log.debug "XXX: came to NTP make buttons FORM= #{@form.name} names #{names} "
284
+ total = names.inject(0) {|total, item| total + item.length + 4}
285
+ bcol = align_buttons total, @button_orientation
286
+
287
+ # this craps out when height is zero
288
+ brow = @row + @height-4
289
+ brow = FFI::NCurses.LINES-2 if brow < 0
290
+ @button_row = brow
291
+ #color_pair = get_color($normalcolor)
292
+ #@window.wattron(Ncurses.COLOR_PAIR(color_pair) | (@attrib || FFI::NCurses::A_NORMAL))
293
+ #@window.mvwhline( brow-1, @col+1, Ncurses::ACS_HLINE, @width-2)
294
+ #@window.wattroff(Ncurses.COLOR_PAIR(color_pair) | (@attrib || FFI::NCurses::A_NORMAL))
295
+ $log.debug "XXX: putting buttons :on #{brow} , #{bcol} : #{@row} , #{@height} "
296
+ button_ct =0
297
+ tpp = self
298
+ _color = @color
299
+ _bgcolor = @bgcolor
300
+ # 2014-05-31 - 12:50 CANIS BUTTONCOLOR not setting color since it should pick from form
301
+ names.each_with_index do |bname, ix|
302
+ text = bname
303
+
304
+ button = Button.new @form do
305
+ text text
306
+ name bname
307
+ row brow
308
+ col bcol
309
+ highlight_bgcolor $reversecolor
310
+ # commented off 2014-05-31 - 12:50 BUTTONCOLOR
311
+ #color _color
312
+ #bgcolor _bgcolor
313
+ end
314
+ @action_buttons << button
315
+ button.form = @form
316
+ button.override_graphic @graphic
317
+ button.default_button(true) if (@default_button && @default_button == ix)
318
+ index = button_ct
319
+ tpp = self
320
+ button.command { |form| @selected_index = index; @stop = true;
321
+ # ActionEvent has source event and action_command
322
+ action = ActionEvent.new(tpp, index, button.text)
323
+ if @command
324
+ @command.call(action, @args)
325
+ else
326
+ # default action if you don't specify anything
327
+ throw(:close, @selected_index)
328
+ end
329
+ }
330
+ # we map the key of the button to the alphabet so user can press just the mnemonic, and not
331
+ # just the Alt combination.
332
+ mn = button.mnemonic
333
+ @form.bind_key(mn.downcase) { button.fire} if mn
334
+ button_ct += 1
335
+ bcol += text.length+6
336
+ end
337
+ end
338
+ def _create_window
339
+
340
+ @width ||= @suggested_w || 60
341
+ @height = @suggested_h || 10
342
+ if @suggested_row
343
+ @row = @suggested_row
344
+ else
345
+ @row = ((FFI::NCurses.LINES-@height)/2).floor
346
+ end
347
+ if @suggested_col
348
+ @col = @suggested_col
349
+ else
350
+ w = @width
351
+ @col = ((FFI::NCurses.COLS-w)/2).floor
352
+ end
353
+ @window = Canis::Window.new :height => @height, :width => @width, :top => @row, :left => @col
354
+ @graphic = @window
355
+ @form.window = @window
356
+ end
357
+ #
358
+ # specify a code block to be fired when an action button is pressed
359
+ # This will supply (to the code block) an ActionEvent followed by
360
+ # whatever args that were given.
361
+ # ActionEvent contains source, event, action_command which map to
362
+ # the messagebox, selected_index (base 0) and button title.
363
+ #
364
+ public
365
+ def command *args, &blk
366
+ @command = blk
367
+ @args = args
368
+ end
369
+ # returns array of widgets declared for querying
370
+ def widgets
371
+ @form.widgets
372
+ end
373
+ # returns a widget based on offset, or name (if you gave it a :name)
374
+ # e.g. a list was declared and we wish to know the selected_indices
375
+ def widget n
376
+ case n
377
+ when Fixnum
378
+ @form.widgets[n]
379
+ when String, Symbol
380
+ @form.by_name[n]
381
+ else
382
+ raise "messagebox.widget can't handle #{n.class} "
383
+ end
384
+ end
385
+
386
+ # returns starting column for buttons to start painting
387
+ # Not very correct in case of :right
388
+ private
389
+ def align_buttons textlen, orient=:center
390
+ case orient
391
+ when :left
392
+ return @col+@col_offset
393
+ when :right
394
+ return (@width-textlen)-5
395
+ else
396
+ return (@width-textlen)/2
397
+ end
398
+ end
399
+ end
400
+ end
@@ -0,0 +1,118 @@
1
+ #require 'ncurses'
2
+ require 'logger'
3
+ require 'canis'
4
+
5
+ #include Ncurses # FFI 2011-09-8
6
+ include Canis
7
+ module Canis
8
+ extend self
9
+ ##
10
+ # TODO user may want to print a label on progress: like not started or complete.
11
+ class Progress < Widget
12
+ dsl_property :width # please give this to ensure the we only print this much
13
+ dsl_property :fraction # how much to cover
14
+ dsl_property :char # what char to use for filling, default space
15
+ dsl_property :text # text to put over bar
16
+ dsl_accessor :style # :old or nil/anything else
17
+ dsl_accessor :surround_chars # "[]"
18
+
19
+ def initialize form, config={}, &block
20
+
21
+ @row = config.fetch("row",-1)
22
+ @col = config.fetch("col",-1)
23
+ @bgcolor = config.fetch("bgcolor", $def_bg_color)
24
+ @color = config.fetch("color", $def_fg_color)
25
+ @name = config.fetch("name", "pbar")
26
+ @editable = false
27
+ @focusable = false
28
+ super
29
+ @surround_chars ||= "[]" # for :old style
30
+ @repaint_required = true
31
+ end
32
+ def getvalue
33
+ @fraction || 0.0
34
+ end
35
+
36
+ ##
37
+ #
38
+ def repaint
39
+ return unless @repaint_required
40
+ $log.debug " XXXX PBAR inside repaint #{@color} , #{@fraction} "
41
+ r,c = rowcol
42
+ #value = getvalue_for_paint
43
+ acolor = get_color @bgcolor
44
+ bcolor = get_color @color
45
+ @graphic = @form.window if @graphic.nil? ## HACK messagebox givig this in repaint, 423 not working ??
46
+ len = 0
47
+ w2 = @width - 6 #2 account for brackets and printing of percentage
48
+ if @fraction
49
+ @fraction = 1.0 if @fraction > 1.0
50
+ @fraction = 0 if @fraction < 0
51
+ if @fraction > 0
52
+ len = @fraction * @width
53
+ end
54
+ end
55
+ if @style == :old
56
+ ftext=""
57
+ char = @char || "="
58
+ if @fraction && @fraction >= 0
59
+ len = @fraction * (w2)
60
+ ftext << sprintf("%3d%s",(@fraction * 100).to_i, "%")
61
+ end
62
+ incomplete = w2 - len
63
+ complete = len
64
+ # I am printing 2 times since sometimes the ending bracket gets printed one position less
65
+ str = @surround_chars[0] + " "*w2 + @surround_chars[1] + ftext
66
+ @graphic.printstring r, c, str , acolor,@attr
67
+ str = char*complete
68
+ str[-1] = ">" if char == "=" && complete > 2
69
+ @graphic.printstring r, c+1, str , acolor,@attr
70
+ else
71
+
72
+ char = @char || " "
73
+ # first print the background horizonal bar
74
+ @graphic.printstring r, c, " " * @width , acolor,@attr
75
+
76
+ # if the user has passed a percentage we need to print that in @color
77
+ if @fraction
78
+ #bcolor = get_color @color
79
+ #@fraction = 1.0 if @fraction > 1.0
80
+ #@fraction = 0 if @fraction < 0
81
+ #if @fraction > 0
82
+ #len = @fraction * @width
83
+ #char = @char || " "
84
+
85
+ # if text is to printed over the bar
86
+ if @text
87
+ textcolor = get_color $datacolor, 'black'
88
+ txt = @text
89
+ txt = @text[0..@width] if @text.length > @width
90
+ textattr = 'bold'
91
+ # write the text in a color that contrasts with the background
92
+ # typically black
93
+ @graphic.printstring r, c, txt , textcolor, textattr if @text
94
+
95
+ # now write the text again, in a color that contrasts with the progress
96
+ # bar color that is expanding. However, the text must be padded to len and truncated
97
+ # to len as well. it must be exactly len in size.
98
+ txt = sprintf("%-*s", len, txt)
99
+ if len > 0
100
+ if len < txt.length
101
+ txt = txt[0..len]
102
+ end
103
+ textcolor = get_color $datacolor, 'white', @color
104
+ @graphic.printstring r, c, txt , textcolor, textattr if @text
105
+ end
106
+ else
107
+ # no text was given just print a horizontal bar
108
+ @graphic.printstring r, c, char * len , bcolor, 'reverse'
109
+ end
110
+ end # frac > 0
111
+ end # fraction
112
+ end # style
113
+ @repaint_required = false
114
+ end
115
+ def repaint_old
116
+ end
117
+ # ADD HERE progress
118
+ end