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,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