ncumbra 0.1.0 → 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.
data/lib/umbra/textbox.rb CHANGED
@@ -4,26 +4,21 @@
4
4
  # Author: j kepler http://github.com/mare-imbrium/canis/
5
5
  # Date: 2018-03-24 - 12:39
6
6
  # License: MIT
7
- # Last update: 2018-04-20 12:58
7
+ # Last update: 2018-05-10 11:06
8
8
  # ----------------------------------------------------------------------------- #
9
9
  # textbox.rb Copyright (C) 2012-2018 j kepler
10
10
  ## TODO -----------------------------------
11
11
  # improve the object sent when row change or cursor movement
12
- #
12
+ ## 2018-05-08 - extend Multiline
13
13
  #
14
14
  # ----------------------------------------
15
15
  ## CHANGELOG
16
16
  #
17
17
  # ----------------------------------------
18
- require 'umbra/widget'
18
+ require 'umbra/multiline'
19
19
  module Umbra
20
- class Textbox < Widget
21
- attr_reader :list # list containing data
20
+ class Textbox < Multiline
22
21
  attr_accessor :file_name # filename passed in for reading
23
- attr_accessor :selection_key # key used to select a row
24
- attr_accessor :selected_index # row selected, may change to plural
25
- attr_accessor :selected_color_pair # row selected color_pair
26
- attr_accessor :selected_attr # row selected color_pair
27
22
  #attr_accessor :cursor # position of cursor in line ??
28
23
  =begin
29
24
  attr_accessor :selected_mark # row selected character
@@ -32,55 +27,18 @@ class Textbox < Widget
32
27
  =end
33
28
 
34
29
  def initialize config={}, &block
35
- @focusable = false # will only be set true if data is set
36
- @editable = false
37
- @pstart = 0 # which row does printing start from
38
- @current_index = 0 # index of row on which cursor is
39
- @selected_index = nil # index of row selected
40
- @selection_key = 0 # presently no selection. Actually 0 is Ctrl-Space.
41
30
  @highlight_attr = FFI::NCurses::A_BOLD
42
- @to_print_border = false
43
31
  @row_offset = 0
44
32
  @col_offset = 0
45
- @pcol = 0
46
33
  @curpos = 0 # current cursor position in buffer (NOT screen/window/field)
47
- =begin
48
-
49
- @selected_color_pair = CP_RED
50
- @selected_attr = REVERSE
51
- @selected_mark = 'x' # row selected character
52
- @unselected_mark = ' ' # row unselected character (usually blank)
53
- @current_mark = '>' # row current character (default is >)
54
- =end
55
- register_events([:ENTER_ROW, :LEAVE_ROW, :CURSOR_MOVE]) #
34
+ #register_events([:ENTER_ROW, :LEAVE_ROW, :CURSOR_MOVE]) #
35
+ register_events([:CURSOR_MOVE]) #
56
36
  super
57
37
 
58
- map_keys
59
- # internal width and height
60
- @repaint_required = true
61
38
  end
62
- def _calculate_dimensions
63
- @int_width = @width
64
- @int_height = @height # used here only
65
- @scroll_lines ||= @int_height/2 # fix these to be perhaps half and one of ht
66
- @page_lines = @int_height
67
- @calculate_dimensions = true
68
- end
69
- # set list of data to be displayed.
39
+ # set list of data to be displayed from filename. {{{
70
40
  # NOTE this can be called again and again, so we need to take care of change in size of data
71
41
  # as well as things like current_index and selected_index or indices.
72
- def list=(alist)
73
- if !alist or alist.size == 0
74
- self.focusable=(false)
75
- else
76
- self.focusable=(true)
77
- end
78
- @list = alist
79
- @repaint_required = true
80
- @pstart = @current_index = 0
81
- @selected_index = nil
82
- @focusable = true # too late since form is not rechecking its array
83
- end
84
42
  def file_name=(fp)
85
43
  raise "File #{fp} not readable" unless File.readable? fp
86
44
  return Dir.new(fp).entries if File.directory? fp
@@ -106,126 +64,28 @@ class Textbox < Widget
106
64
  self.list = content
107
65
  raise "list not set" unless @list
108
66
 
109
- end
110
-
111
- def repaint
112
- _calculate_dimensions unless @calculate_dimensions
113
- return unless @repaint_required
114
- return unless @list
115
- win = @graphic
116
- r,c = @row, @col
117
- _attr = @attr || NORMAL
118
- _color = @color_pair || CP_WHITE
119
- #_bordercolor = @border_color_pair || CP_BLUE
120
- rowpos = 1
121
- coffset = 0
122
- #width = win.width-1
123
- width = @width
124
- files = @list
125
-
126
- #ht = win.height-2
127
- ht = @height
128
- cur = @current_index
129
- st = pstart = @pstart # previous start
130
- pend = pstart + ht -1 #- previous end
131
- if cur > pend
132
- st = (cur -ht) + 1 #+
133
- elsif cur < pstart
134
- st = cur
135
- end
136
- $log.debug "LISTBOX: cur = #{cur} st = #{st} pstart = #{pstart} pend = #{pend} listsize = #{@list.size} "
137
- hl = cur
138
- y = 0
139
- ctr = 0
140
- filler = " "*(width)
141
- files.each_with_index {|f, y|
142
- next if y < st
143
- colr = CP_WHITE # white on bg -1
144
- mark = @unselected_mark
145
- if y == hl
146
- attr = @highlight_attr #FFI::NCurses::A_REVERSE
147
- mark = @current_mark
148
- rowpos = ctr
149
- else
150
- attr = FFI::NCurses::A_NORMAL
151
- end
152
- if y == @selected_index
153
- colr = @selected_color_pair
154
- attr = @selected_attr
155
- mark = @selected_mark
156
- end
157
- #ff = "#{mark} #{f}"
158
- ff = f
159
- if ff
160
- if ff.size > width
161
- #ff = ff[0...width]
162
- # pcol can be greater than width then we get null
163
- if @pcol < ff.size
164
- ff = ff[@pcol..@pcol+width-1]
165
- else
166
- ff = ""
167
- end
168
- else
169
- if @pcol < ff.size
170
- ff = ff[@pcol..-1]
171
- else
172
- ff = ""
173
- end
174
- end
175
- end
176
- ff = "" unless ff
177
-
178
- win.printstring(ctr + r, coffset+c, filler, colr )
179
- win.printstring(ctr + r, coffset+c, ff, colr, attr)
180
- ctr += 1
181
- @pstart = st
182
- break if ctr >= ht #-
183
- }
184
- ## if counter < ht then we need to clear the rest in case there was data earlier {{{
185
- if ctr < ht
186
- while ctr < ht
187
- win.printstring(ctr + r, coffset+c, filler, _color )
188
- ctr += 1
189
- end
190
- end # }}}
191
- @row_offset = rowpos
192
- #@col_offset = coffset # this way form can pick it up XXX can't override it like this
193
- @repaint_required = false
194
- end
195
-
196
- def getvalue
197
- @list
198
- end
67
+ end # }}}
199
68
 
200
- # ensure text has been passed or action
201
- def getvalue_for_paint
202
- raise
203
- ret = getvalue
204
- #@text_offset = @surround_chars[0].length
205
- #@surround_chars[0] + ret + @surround_chars[1]
69
+ # returns current row
70
+ def current_row
71
+ @list[@current_index]
206
72
  end
207
73
 
208
74
 
209
- def map_keys
210
- return if @keys_mapped
211
- bind_keys([?k,FFI::NCurses::KEY_UP], "Up") { cursor_up }
212
- bind_keys([?j,FFI::NCurses::KEY_DOWN], "Down") { cursor_down }
213
- bind_keys([?l,FFI::NCurses::KEY_RIGHT], "Right") { cursor_forward }
214
- bind_keys([?h,FFI::NCurses::KEY_LEFT], "Left") { cursor_backward }
215
- bind_key(?g, 'goto_start') { goto_start }
216
- bind_key(?G, 'goto_end') { goto_end }
217
- bind_key(FFI::NCurses::KEY_CTRL_A, 'cursor_home') { cursor_home }
218
- bind_key(FFI::NCurses::KEY_CTRL_E, 'cursor_end') { cursor_end }
219
- bind_key(FFI::NCurses::KEY_CTRL_F, 'page_forward') { page_forward }
220
- bind_key(32, 'page_forward') { page_forward }
221
- bind_key(FFI::NCurses::KEY_CTRL_B, 'page_backward'){ page_backward }
222
- bind_key(FFI::NCurses::KEY_CTRL_U, 'scroll_up') { scroll_up }
223
- bind_key(FFI::NCurses::KEY_CTRL_D, 'scroll_down') { scroll_down }
224
- @keys_mapped = true
225
- end
226
-
227
- # listbox key handling
75
+ ## textbox key handling
76
+ ## Textbox varies from multiline in that it fires a cursor_move event whrease the parent
77
+ ## fires a cursor_move event which is mostly used for testing out
228
78
  def handle_key ch
79
+ begin
80
+ ret = super
81
+ return ret
82
+ ensure
83
+ if @repaint_required
84
+ fire_handler(:CURSOR_MOVE, [@col_offset, @current_index, @curpos, @pcol, ch ]) # 2018-03-25 - improve this
85
+ end
86
+ end
87
+ end
88
+ def OLDhandle_key ch # {{{
229
89
  return :UNHANDLED unless @list
230
90
  # save old positions so we know movement has happened
231
91
  old_current_index = @current_index
@@ -233,18 +93,8 @@ class Textbox < Widget
233
93
  old_col_offset = @col_offset
234
94
 
235
95
  begin
236
- case ch
237
- when @selection_key
238
- @repaint_required = true
239
- if @selected_index == @current_index
240
- @selected_index = nil
241
- else
242
- @selected_index = @current_index
243
- end
244
- else
245
96
  ret = super
246
97
  return ret
247
- end
248
98
  ensure
249
99
  @current_index = 0 if @current_index < 0
250
100
  @current_index = @list.size-1 if @current_index >= @list.size
@@ -253,30 +103,25 @@ class Textbox < Widget
253
103
  if @current_index != old_current_index
254
104
  on_leave_row old_current_index
255
105
  on_enter_row @current_index
256
- #fire_handler(:CHANGE_ROW, [old_current_index, @current_index, ch ]) # 2018-03-26 - improve this
257
106
  end
258
107
  @repaint_required = true
259
108
  fire_handler(:CURSOR_MOVE, [@col_offset, @current_index, @curpos, @pcol, ch ]) # 2018-03-25 - improve this
260
109
  end
261
110
  end
262
- end
263
- # advance col_offset (where cursor will be displayed on screen)
111
+ end # }}}
112
+ # advance col_offset (where cursor will be displayed on screen) {{{
264
113
  # @param [Integer] advance by n (can be negative or positive)
265
114
  # @return -1 if cannot advance
266
- private def add_col_offset num
115
+ private def OLDadd_col_offset num
267
116
  x = @col_offset + num
268
117
  return -1 if x < 0
269
118
  return -1 if x > @int_width
270
119
  # is it a problem that i am directly changing col_offset ??? XXX
271
120
  @col_offset += num
272
121
  end
273
- # returns current row
274
- def current_row
275
- @list[@current_index]
276
- end
277
122
 
278
123
  # move cursor forward one character, called with KEY_RIGHT action.
279
- def cursor_forward
124
+ def OLDcursor_forward
280
125
  blen = current_row().size-1
281
126
  if @curpos < blen
282
127
  if add_col_offset(1)==-1 # go forward if you can, else scroll
@@ -286,7 +131,7 @@ class Textbox < Widget
286
131
  @curpos += 1
287
132
  end
288
133
  end
289
- def cursor_backward
134
+ def OLDcursor_backward
290
135
 
291
136
  if @col_offset > 0
292
137
  @curpos -= 1
@@ -302,14 +147,14 @@ class Textbox < Widget
302
147
  end
303
148
  end
304
149
  # position cursor at start of field
305
- def cursor_home
150
+ def OLDcursor_home
306
151
  @curpos = 0
307
152
  @pcol = 0
308
153
  set_col_offset 0
309
154
  end
310
155
  # goto end of line.
311
156
  # This should be consistent with moving the cursor to the end of the row with right arrow
312
- def cursor_end
157
+ def OLDcursor_end
313
158
  blen = current_row().length
314
159
  if blen < @int_width
315
160
  set_col_offset blen # just after the last character
@@ -322,31 +167,19 @@ class Textbox < Widget
322
167
  # regardless of pcol (panning)
323
168
  end
324
169
  # go to start of file (first line)
325
- def goto_start
170
+ def OLDgoto_start
326
171
  @current_index = 0
327
172
  @pcol = @curpos = 0
328
173
  set_col_offset 0
329
174
  end
330
175
  # go to end of file (last line)
331
- def goto_end
176
+ def OLDgoto_end
332
177
  @current_index = @list.size-1
333
178
  end
334
- def scroll_down
335
- @current_index += @scroll_lines
336
- end
337
- def scroll_up
338
- @current_index -= @scroll_lines
339
- end
340
- def page_backward
341
- @current_index -= @page_lines
342
- end
343
- def page_forward
344
- @current_index += @page_lines
345
- end
346
179
  # sets the visual cursor on the window at correct place
347
180
  # NOTE be careful of curpos - pcol being less than 0
348
181
  # @param [Integer] position in data on the line
349
- private def set_col_offset x=@curpos
182
+ private def OLD_set_col_offset x=@curpos
350
183
  @curpos = x || 0 # NOTE we set the index of cursor here - WHY TWO THINGS ??? XXX
351
184
  #return -1 if x < 0
352
185
  #return -1 if x > @width
@@ -359,29 +192,9 @@ class Textbox < Widget
359
192
  @col_offset = @int_width if @col_offset > @int_width
360
193
  return
361
194
  end
362
- def cursor_up
363
- @current_index -= 1
364
- end
365
- # go to next row
366
- def cursor_down
367
- @current_index += 1
368
- end
369
- def on_enter
370
- super
371
- return unless @list
372
- on_enter_row @current_index
373
- end
374
- def on_leave
375
- super
376
- on_leave_row @current_index
377
- end
378
- # called when object leaves a row and when object is exited.
379
- def on_leave_row index
380
- fire_handler(:LEAVE_ROW, [index]) # 2018-03-26 - improve this
381
- end
382
195
  # called whenever a row entered.
383
196
  # Call when object entered, also.
384
- def on_enter_row index
197
+ def OLD_on_enter_row index
385
198
  #fire_handler(:ENTER_ROW, [old_current_index, @current_index, ch ]) # 2018-03-26 - improve this
386
199
  fire_handler(:ENTER_ROW, [@current_index]) # 2018-03-26 - improve this
387
200
  # if cursor ahead of blen then fix it
@@ -396,7 +209,7 @@ class Textbox < Widget
396
209
  end
397
210
  end
398
211
  @col_offset = 0 if @col_offset < 0
399
- end
212
+ end # }}}
400
213
  ## border {{{
401
214
  private def print_border row, col, height, width, color, att=FFI::NCurses::A_NORMAL
402
215
  raise
@@ -6,7 +6,7 @@ require 'umbra/button'
6
6
  # Author: j kepler http://github.com/mare-imbrium/umbra/
7
7
  # Date: 2018-03-17 - 22:50
8
8
  # License: MIT
9
- # Last update: 2018-04-07 23:08
9
+ # Last update: 2018-05-14 14:35
10
10
  # ----------------------------------------------------------------------------- #
11
11
  # togglebutton.rb Copyright (C) 2012-2018 j kepler
12
12
  #
@@ -50,14 +50,12 @@ class ToggleButton < Button
50
50
  # boolean, which value to use currently, onvalue or offvalue
51
51
  attr_accessor :value
52
52
  # characters to use for surround, array, default square brackets
53
- attr_accessor :surround_chars
53
+ attr_property :surround_chars
54
54
  # 2018-04-02 - removing variable
55
55
  #attr_accessor :variable # value linked to this variable which is a boolean
56
56
  # background to use when selected, if not set then default
57
57
  # 2018-04-02 - unused so commenting off. color_pair is not used here or in checkbox
58
- #attr_accessor :selected_bgcolor
59
- #attr_accessor :selected_color
60
- attr_accessor :selected_color_pair
58
+ attr_property :selected_color_pair
61
59
 
62
60
  def initialize config={}, &block
63
61
  super
data/lib/umbra/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Umbra
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/umbra/widget.rb CHANGED
@@ -3,10 +3,39 @@
3
3
  # extend this, if it wants to be repainted or wants focus. Otherwise.
4
4
  # form will be unaware of it.
5
5
  # 2018-03-08 -
6
- #require 'umbra/form' # for EventHandler !!!
6
+
7
7
  require 'umbra/eventhandler' # for register_events and fire_handler etc
8
8
  require 'umbra/keymappinghandler' # for bind_key and process_key
9
9
 
10
+ class Module # {{{
11
+
12
+ def attr_property(*symbols)
13
+ symbols.each { |sym|
14
+ class_eval %{
15
+ def #{sym}=(val)
16
+ oldvalue = @#{sym}
17
+ newvalue = val
18
+ if @_object_created.nil?
19
+ @#{sym} = newvalue
20
+ end
21
+ # return(self) if oldvalue.nil? || @_object_created.nil?
22
+ return(self) if @_object_created.nil?
23
+
24
+ if oldvalue != newvalue
25
+ begin
26
+ fire_property_change("#{sym}", oldvalue, newvalue)
27
+ @#{sym} = newvalue
28
+ rescue PropertyVetoException
29
+ $log.warn "PropertyVetoException for #{sym}:" + oldvalue.to_s + "-> "+ newvalue.to_s
30
+ end
31
+ end # oldvalue !=
32
+ self
33
+ end # def
34
+ attr_reader sym
35
+ }
36
+ }
37
+ end # def
38
+ end # module }}}
10
39
  module Umbra
11
40
  class FieldValidationException < RuntimeError
12
41
  end
@@ -14,27 +43,29 @@ class Widget
14
43
  include EventHandler
15
44
  include KeyMappingHandler
16
45
  # common interface for text related to a field, label, textview, button etc
17
- attr_accessor :text, :width, :height
46
+ attr_property :text
47
+ attr_property :width, :height ## FIXME this won't trigger repaint or property !!!
18
48
 
19
49
  # foreground and background colors when focussed. Currently used with buttons and field
20
50
  # Form checks and repaints on entry if these are set.
21
- attr_accessor :highlight_color_pair
22
- attr_accessor :highlight_attr
51
+ attr_property :highlight_color_pair
52
+ attr_property :highlight_attr
23
53
 
24
54
  # NOTE: 2018-03-04 - user will have to call repaint_required if he changes color or coordinates.
25
- attr_accessor :row, :col # location of object
55
+ attr_accessor :col # location of object
56
+ attr_writer :row # location of object
26
57
  #attr_writer :color, :bgcolor # normal foreground and background 2018-03-08 - now color_pair
27
58
  # moved to a method which calculates color 2011-11-12
28
- attr_accessor :color_pair # instead of colors give just color_pair
29
- attr_accessor :attr # attribute bold, normal, reverse
59
+ attr_property :color_pair # instead of colors give just color_pair
60
+ attr_property :attr # attribute bold, normal, reverse
30
61
  attr_accessor :name # name to refr to or recall object by_name
31
62
  attr_accessor :curpos # cursor position inside object - column, not row.
32
- attr_reader :config # can be used for popping user objects too
63
+ attr_reader :config # can be used for popping user objects too. NOTE unused
33
64
  #attr_accessor :form # made accessor 2008-11-27 22:32 so menu can set
34
65
  attr_accessor :graphic # window which should be set by form when adding 2018-03-19
35
66
  attr_accessor :state # normal, selected, highlighted
36
67
  attr_reader :row_offset, :col_offset # where should the cursor be placed to start with
37
- attr_accessor :visible # boolean # 2008-12-09 11:29
68
+ attr_property :visible # boolean # 2008-12-09 11:29
38
69
  # if changing focusable property of a field after form creation, you may need to call
39
70
  # pack again, or atl east update_focusables
40
71
  attr_reader :focusable # boolean can this get focus # 2018-03-21 - 23:13
@@ -104,7 +135,7 @@ class Widget
104
135
  #alias :modified :set_modified
105
136
 
106
137
  # triggered whenever a widget is entered.
107
- # TODO should we not fix cursor at this point ?
138
+ # NOTE should we not fix cursor at this point (on_enter) ?
108
139
  def on_enter
109
140
  @state = :HIGHLIGHTED # duplicating since often these are inside containers
110
141
  @focussed = true
@@ -126,7 +157,7 @@ class Widget
126
157
  # row and col is where a widget starts. offsets usually take into account borders.
127
158
  # the offsets typically are where the cursor should be positioned inside, upon on_enter.
128
159
  def rowcol
129
- return @row+@row_offset, @col+@col_offset
160
+ return self.row+@row_offset, self.col+@col_offset
130
161
  end
131
162
  ## return the value of the widget.
132
163
  def getvalue
@@ -144,12 +175,13 @@ class Widget
144
175
  r,c = rowcol
145
176
  $log.debug("widget repaint : r:#{r} c:#{c} col:#{@color_pair}" )
146
177
  value = getvalue_for_paint
147
- len = @width || value.length
178
+ len = self.width || value.length
148
179
  acolor = @color_pair
149
180
  @graphic.printstring r, c, "%-*s" % [len, value], acolor, attr()
150
181
  end
151
182
 
152
183
  def destroy
184
+ raise "what is this dong here still SHOULD Not be CALLED"
153
185
  $log.debug "DESTROY : widget #{@name} "
154
186
  panel = @window.panel
155
187
  Ncurses::Panel.del_panel(panel.pointer) if !panel.nil?
@@ -186,10 +218,13 @@ class Widget
186
218
  # is the entire widget to be repainted including things like borders and titles
187
219
  # earlier took a default of true, now must be explicit. Perhaps, not used currently.
188
220
  def repaint_all(tf)
221
+ # NOTE NOT USED
222
+ raise " not used repaint all"
189
223
  @repaint_all = tf
190
224
  @repaint_required = tf
191
225
  end
192
226
  # shortcut for users to indicate that a widget should be redrawn since some property has been changed.
227
+ # Now that I have created attr_property this may not be needed
193
228
  def touch
194
229
  @repaint_required = true
195
230
  end
@@ -210,10 +245,34 @@ class Widget
210
245
  @_form = aform
211
246
  end
212
247
  def focusable=(bool)
213
- $log.debug " inside focusable= with #{bool} "
248
+ #$log.debug " inside focusable= with #{bool} "
214
249
  @focusable = bool
215
250
  @_form.update_focusables if @_form
216
251
  end
252
+
253
+ ## TODO maybe check for decimal between 0 and 1 which will be percentage of width
254
+ def width
255
+ return nil unless @width ## this is required otherwise checking for nil will fail
256
+ if @width < 0
257
+ return ( FFI::NCurses.COLS + @width ) - self.col + 1
258
+ #return ( FFI::NCurses.COLS + @width ) #- self.col + 1
259
+ end
260
+ @width
261
+ end
262
+ def height
263
+ return nil unless @height
264
+ if @height < 0
265
+ return ((FFI::NCurses.LINES + @height) - self.row) + 1
266
+ #return (FFI::NCurses.LINES + @height)
267
+ end
268
+ @height
269
+ end
270
+ def row
271
+ if @row < 0
272
+ return FFI::NCurses.LINES + @row
273
+ end
274
+ @row
275
+ end
217
276
  #
218
277
  ## ADD HERE WIDGET
219
278
  end #
data/lib/umbra/window.rb CHANGED
@@ -1,22 +1,35 @@
1
1
  require 'ffi-ncurses'
2
2
  require 'ffi-ncurses/widechars'
3
3
 
4
+ ## NOTE: conflict between KEY_RESIZE and wtimeout or halfdelay.
5
+ ## Setting a timeout or delay allows an application to respond to updates without a keypress,
6
+ ## such as continuous updates.
7
+ ## However, this means that KEY_RESIZE will not work unless a key is pressed.
8
+ ## If resizing is important, then caller may set $ncurses_timeout to -1.
9
+
10
+
11
+
12
+
4
13
  module Umbra
5
14
 
6
- # attribute constants, use them to specify an attrib for a widget or window.
7
- BOLD = FFI::NCurses::A_BOLD
8
- REVERSE = FFI::NCurses::A_REVERSE
9
- UNDERLINE = FFI::NCurses::A_UNDERLINE
10
- NORMAL = FFI::NCurses::A_NORMAL
11
-
12
- # color constants, use these when creating a color
13
- COLOR_BLACK = FFI::NCurses::BLACK
14
- COLOR_WHITE = FFI::NCurses::WHITE
15
- COLOR_BLUE = FFI::NCurses::BLUE
16
- COLOR_RED = FFI::NCurses::RED
17
- COLOR_GREEN = FFI::NCurses::GREEN
18
- COLOR_CYAN = FFI::NCurses::CYAN
19
- COLOR_MAGENTA = FFI::NCurses::MAGENTA
15
+ ## attribute constants, use them to specify an attrib for a widget or window.
16
+ BOLD = FFI::NCurses::A_BOLD
17
+ REVERSE = FFI::NCurses::A_REVERSE
18
+ UNDERLINE = FFI::NCurses::A_UNDERLINE
19
+ NORMAL = FFI::NCurses::A_NORMAL
20
+
21
+ ## color constants, use these when creating a color
22
+ COLOR_BLACK = FFI::NCurses::BLACK
23
+ COLOR_WHITE = FFI::NCurses::WHITE
24
+ COLOR_BLUE = FFI::NCurses::BLUE
25
+ COLOR_RED = FFI::NCurses::RED
26
+ COLOR_GREEN = FFI::NCurses::GREEN
27
+ COLOR_CYAN = FFI::NCurses::CYAN
28
+ COLOR_MAGENTA = FFI::NCurses::MAGENTA
29
+
30
+ ## key constants
31
+ KEY_ENTER = 13 ## FFI::NCurses::KEY_ENTER is 343 ???
32
+ KEY_RETURN = 10 ## already defined by ffi
20
33
 
21
34
  # Initialize ncurses before any program.
22
35
  # Reduce the value of $ncurses_timeout if you want a quicker response to Escape keys or continuous updates.
@@ -125,6 +138,19 @@ module Umbra
125
138
  return @pointer
126
139
  end
127
140
 
141
+ ## create a window and return window, or yield window to block
142
+ def self.create h=0, w=0, top=0, left=0
143
+ win = Window.new h, w, top, left
144
+ return win unless block_given?
145
+
146
+ begin
147
+ yield win
148
+ ensure
149
+ win.destroy
150
+ end
151
+
152
+ end
153
+
128
154
  # print string at x, y coordinates. replace this with the original one below
129
155
  # @deprecated
130
156
  def printstr(str, x=0,y=0)
@@ -253,18 +279,36 @@ module Umbra
253
279
  end # }}}
254
280
  # make a box around the window. Just a wrapper
255
281
  def box
282
+ @box = true
256
283
  FFI::NCurses.box(@pointer, 0, 0)
257
284
  end
258
- # print a centered title on top of window
285
+ # Print a centered title on top of window.
286
+ # NOTE : the string is not stored, so it can be overwritten.
259
287
  # This should be called after box, or else box will erase the title
260
288
  # @param str [String] title to print
261
289
  # @param color [Integer] color_pair
262
290
  # @param att [Integer] attribute constant
263
291
  def title str, color=0, att=BOLD
292
+ ## save so we can repaint if required
293
+ @title_data = [str, color, att]
264
294
  strl = str.length
265
295
  col = (@width - strl)/2
266
296
  printstring(0,col, str, color, att)
267
297
  end
268
298
 
299
+ ## repaints windows objects like title and box.
300
+ ## To be called from form on pressing redraw, and SIGWINCH
301
+ def repaint
302
+ curses.wclear(@pointer)
303
+ if @box
304
+ self.box
305
+ end
306
+ if @title_data
307
+ str, color, att = @title_data
308
+ self.title str, color, att
309
+ end
310
+ end
311
+
312
+
269
313
  end # window
270
314
  end # module