ncumbra 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG +14 -0
- data/README.md +21 -6
- data/examples/data/atp_matches_2017.csv +2887 -0
- data/examples/data/atp_matches_2018.csv +460 -0
- data/examples/data/import.sh +13 -0
- data/examples/data/schema.txt +51 -0
- data/examples/ex1.rb +2 -0
- data/examples/ex2.rb +1 -0
- data/examples/ex5.rb +1 -1
- data/examples/exbox.rb +3 -2
- data/examples/exm1.rb +1 -2
- data/examples/extab2.rb +170 -0
- data/examples/extab3.rb +306 -0
- data/examples/extabular.rb +123 -0
- data/examples/tasks.csv +88 -0
- data/lib/umbra/box.rb +38 -21
- data/lib/umbra/checkbox.rb +2 -2
- data/lib/umbra/dialog.rb +1 -2
- data/lib/umbra/eventhandler.rb +52 -4
- data/lib/umbra/field.rb +7 -3
- data/lib/umbra/form.rb +119 -55
- data/lib/umbra/keymappinghandler.rb +4 -4
- data/lib/umbra/label.rb +31 -17
- data/lib/umbra/labeledfield.rb +7 -8
- data/lib/umbra/listbox.rb +114 -341
- data/lib/umbra/messagebox.rb +93 -42
- data/lib/umbra/multiline.rb +476 -0
- data/lib/umbra/pad.rb +20 -14
- data/lib/umbra/radiobutton.rb +2 -2
- data/lib/umbra/table.rb +260 -0
- data/lib/umbra/tabular.rb +431 -0
- data/lib/umbra/textbox.rb +36 -223
- data/lib/umbra/togglebutton.rb +3 -5
- data/lib/umbra/version.rb +1 -1
- data/lib/umbra/widget.rb +72 -13
- data/lib/umbra/window.rb +59 -15
- data/lib/umbra.rb +82 -11
- data/umbra.gemspec +2 -2
- metadata +18 -4
@@ -0,0 +1,476 @@
|
|
1
|
+
require 'umbra/widget'
|
2
|
+
# ----------------------------------------------------------------------------- #
|
3
|
+
# File: multiline.rb
|
4
|
+
# Description: A base class for lists and textboxes and tables, i.e. components
|
5
|
+
# having multiple lines that are scrollable.
|
6
|
+
# Author: j kepler http://github.com/mare-imbrium/canis/
|
7
|
+
# Date: 2018-05-08 - 11:54
|
8
|
+
# License: MIT
|
9
|
+
# Last update: 2018-05-22 12:27
|
10
|
+
# ----------------------------------------------------------------------------- #
|
11
|
+
# multiline.rb Copyright (C) 2012-2018 j kepler
|
12
|
+
#
|
13
|
+
## TODO search through text and put cursor on next result.
|
14
|
+
#/
|
15
|
+
|
16
|
+
|
17
|
+
module Umbra
|
18
|
+
class Multiline < Widget
|
19
|
+
|
20
|
+
attr_reader :list # array containing data (usually Strings)
|
21
|
+
|
22
|
+
# index of focussed row, starting 0, index into the list supplied
|
23
|
+
attr_reader :current_index
|
24
|
+
|
25
|
+
def initialize config={}, &block # {{{
|
26
|
+
@focusable = false
|
27
|
+
@editable = false
|
28
|
+
@pstart = 0 # which row does printing start from
|
29
|
+
@current_index = 0 # index of row on which cursor is
|
30
|
+
#register_events([:LEAVE_ROW, :ENTER_ROW, :LIST_SELECTION_EVENT])
|
31
|
+
|
32
|
+
## PRESS event relates to pressing RETURN/ENTER (10)
|
33
|
+
register_events([:LEAVE_ROW, :ENTER_ROW, :PRESS])
|
34
|
+
|
35
|
+
super
|
36
|
+
|
37
|
+
map_keys
|
38
|
+
@row_offset = 0
|
39
|
+
@pcol = 0
|
40
|
+
@curpos = 0
|
41
|
+
@repaint_required = true
|
42
|
+
end
|
43
|
+
|
44
|
+
## Set list of data to be displayed.
|
45
|
+
## NOTE this can be called again and again, so we need to take care of change in size of data
|
46
|
+
## as well as things like current_index and selected_index or indices.
|
47
|
+
def list=(alist)
|
48
|
+
if !alist or alist.size == 0
|
49
|
+
self.focusable=(false)
|
50
|
+
else
|
51
|
+
self.focusable=(true)
|
52
|
+
end
|
53
|
+
@list = alist
|
54
|
+
@repaint_required = true
|
55
|
+
@pstart = @current_index = 0
|
56
|
+
@pcol = 0
|
57
|
+
$log.debug " before multiline list= CHANGED "
|
58
|
+
fire_handler(:CHANGED, self) ## added 2018-05-08 -
|
59
|
+
end
|
60
|
+
|
61
|
+
def row_count
|
62
|
+
@list.size
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
# Calculate dimensions as late as possible, since we can have some other container such as a box,
|
67
|
+
# determine the dimensions after creation.
|
68
|
+
## This is called by repaint.
|
69
|
+
private def _calc_dimensions
|
70
|
+
raise "Dimensions not supplied to multiline" if @row.nil? or @col.nil? or @width.nil? or @height.nil?
|
71
|
+
@_calc_dimensions = true
|
72
|
+
#@int_width = self.width # internal width NOT USED ELSEWHERE
|
73
|
+
height = self.height
|
74
|
+
@scroll_lines ||= height/2
|
75
|
+
@page_lines = height
|
76
|
+
end
|
77
|
+
|
78
|
+
def getvalue
|
79
|
+
@list
|
80
|
+
end
|
81
|
+
|
82
|
+
# }}}
|
83
|
+
|
84
|
+
## repaints the entire multiline, called by +form+ {{{
|
85
|
+
def repaint
|
86
|
+
_calc_dimensions unless @_calc_dimensions
|
87
|
+
|
88
|
+
return unless @repaint_required
|
89
|
+
return unless @list
|
90
|
+
win = @graphic
|
91
|
+
r,c = self.row, self.col
|
92
|
+
_attr = @attr || NORMAL
|
93
|
+
_color = @color_pair || CP_WHITE
|
94
|
+
curpos = 1
|
95
|
+
coffset = 0
|
96
|
+
|
97
|
+
rows = getvalue
|
98
|
+
|
99
|
+
ht = self.height
|
100
|
+
cur = @current_index
|
101
|
+
st = pstart = @pstart # previous start
|
102
|
+
pend = pstart + ht -1 # previous end
|
103
|
+
if cur > pend
|
104
|
+
st = (cur -ht) + 1
|
105
|
+
elsif cur < pstart
|
106
|
+
st = cur
|
107
|
+
end
|
108
|
+
$log.debug "REPAINT #{self.class} : cur = #{cur} st = #{st} pstart = #{pstart} pend = #{pend} listsize = #{@list.size} "
|
109
|
+
$log.debug "REPAINT ML : row = #{r} col = #{c} width = #{width}/#{@width}, height = #{ht}/#{@height} ( #{FFI::NCurses.COLS} #{FFI::NCurses.LINES} "
|
110
|
+
y = 0
|
111
|
+
ctr = 0
|
112
|
+
filler = " "*(self.width)
|
113
|
+
rows.each_with_index {|_f, y|
|
114
|
+
next if y < st
|
115
|
+
|
116
|
+
curpos = ctr if y == cur ## used for setting row_offset
|
117
|
+
|
118
|
+
#_state = state_of_row(y) ## XXX should be move this into paint_row
|
119
|
+
|
120
|
+
win.printstring(ctr + r, coffset+c, filler, _color ) ## print filler
|
121
|
+
|
122
|
+
#paint_row( win, ctr+r, coffset+c, _f, y, _state)
|
123
|
+
paint_row( win, ctr+r, coffset+c, _f, y)
|
124
|
+
|
125
|
+
|
126
|
+
ctr += 1
|
127
|
+
@pstart = st
|
128
|
+
break if ctr >= ht
|
129
|
+
}
|
130
|
+
## if counter < ht then we need to clear the rest in case there was data earlier {{{
|
131
|
+
if ctr < ht
|
132
|
+
while ctr < ht
|
133
|
+
win.printstring(ctr + r, coffset+c, filler, _color )
|
134
|
+
ctr += 1
|
135
|
+
end
|
136
|
+
end # }}}
|
137
|
+
@row_offset = curpos ## used by +widget+ in +rowcol+ called by +Form+
|
138
|
+
#@col_offset = coffset ## NOTE listbox had this line, but it interferes with textbox
|
139
|
+
@repaint_required = false
|
140
|
+
end # }}}
|
141
|
+
|
142
|
+
## Paint given row. {{{
|
143
|
+
## This is not be be called by user, but may be overridden if caller wishes
|
144
|
+
## to completely change the presentation of each row. In most cases, it should suffice
|
145
|
+
## to override just +print_row+ or +value_of_row+ or +_format_color+.
|
146
|
+
##
|
147
|
+
## @param [Window] window pointer for printing
|
148
|
+
## @param [Integer] row number to print on
|
149
|
+
## @param [Integer] col: column to print on
|
150
|
+
## @param [String] line to be printed, usually String. Whatever was passed in to +list+ method.
|
151
|
+
## @param [Integer] ctr: offset of row starting zero
|
152
|
+
## @param [String] state: state of row (SELECTED CURRENT HIGHLIGHTED NORMAL)
|
153
|
+
def paint_row(win, row, col, line, ctr)
|
154
|
+
|
155
|
+
state = state_of_row(ctr)
|
156
|
+
|
157
|
+
ff = value_of_row(line, ctr, state)
|
158
|
+
|
159
|
+
ff = _truncate_to_width( ff ) ## truncate and handle panning
|
160
|
+
|
161
|
+
print_row(win, row, col, ff, ctr, state)
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
# do the actual printing of the row, depending on index and state
|
166
|
+
# This method starts with underscore since it is only required to be overriden
|
167
|
+
# if an object has special printing needs.
|
168
|
+
def print_row(win, row, col, str, index, state)
|
169
|
+
arr = color_of_row index, state
|
170
|
+
win.printstring(row, col, str, arr[0], arr[1])
|
171
|
+
end
|
172
|
+
|
173
|
+
# Each row can be in one of the following states:
|
174
|
+
# 1. HIGHLIGHTED: cursor is on the row, and the list is focussed (user is in it)
|
175
|
+
# 2. CURRENT : cursor was on this row, now user has exited the list
|
176
|
+
# 3. SELECTED : user has selected this row (this can also have above two states actually)
|
177
|
+
# 4. NORMAL : All other rows: not selected, not under cursor
|
178
|
+
# returns color, attrib for given row
|
179
|
+
# @param index of row in the list
|
180
|
+
# @param state of row in the list (see above states)
|
181
|
+
def color_of_row index, state
|
182
|
+
arr = case state
|
183
|
+
#when :SELECTED
|
184
|
+
#[@selected_color_pair, @selected_attr]
|
185
|
+
when :HIGHLIGHTED
|
186
|
+
[@highlight_color_pair || CP_WHITE, @highlight_attr || REVERSE]
|
187
|
+
when :CURRENT
|
188
|
+
[@color_pair, @attr]
|
189
|
+
when :NORMAL
|
190
|
+
_color = CP_CYAN
|
191
|
+
_color = CP_WHITE if index % 2 == 0
|
192
|
+
#_color = @alt_color_pair if index % 2 == 0
|
193
|
+
[@color_pair || _color, @attr || NORMAL]
|
194
|
+
end
|
195
|
+
return arr
|
196
|
+
end
|
197
|
+
alias :_format_color :color_of_row
|
198
|
+
|
199
|
+
|
200
|
+
|
201
|
+
|
202
|
+
# how to convert the line of the array to a simple String.
|
203
|
+
# This is only required to be overridden if the list passed in is not an array of Strings.
|
204
|
+
# @param the current row which could be a string or array or whatever was passed in in +list=()+.
|
205
|
+
# @return [String] string to print. A String must be returned.
|
206
|
+
def value_of_row line, ctr, state
|
207
|
+
line
|
208
|
+
end
|
209
|
+
alias :_format_value :value_of_row
|
210
|
+
|
211
|
+
def state_of_row ix
|
212
|
+
_st = :NORMAL
|
213
|
+
cur = @current_index
|
214
|
+
if ix == cur # current row, row on which cursor is or was
|
215
|
+
## highlight only if object is focussed, otherwise just show mark
|
216
|
+
if @state == :HIGHLIGHTED
|
217
|
+
_st = :HIGHLIGHTED
|
218
|
+
else
|
219
|
+
## cursor was on this row, but now user has tabbed out
|
220
|
+
_st = :CURRENT
|
221
|
+
end
|
222
|
+
end
|
223
|
+
return _st
|
224
|
+
end
|
225
|
+
# }}}
|
226
|
+
|
227
|
+
|
228
|
+
## truncate string to width, and handle panning {{{
|
229
|
+
def _truncate_to_width ff
|
230
|
+
_width = self.width
|
231
|
+
if ff
|
232
|
+
if ff.size > _width
|
233
|
+
# pcol can be greater than width then we get null
|
234
|
+
if @pcol < ff.size
|
235
|
+
ff = ff[@pcol..@pcol+_width-1]
|
236
|
+
else
|
237
|
+
ff = ""
|
238
|
+
end
|
239
|
+
else
|
240
|
+
if @pcol < ff.size
|
241
|
+
ff = ff[@pcol..-1]
|
242
|
+
else
|
243
|
+
ff = ""
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
ff = "" unless ff
|
248
|
+
return ff
|
249
|
+
end # }}}
|
250
|
+
|
251
|
+
|
252
|
+
## mapping of keys for multiline {{{
|
253
|
+
def map_keys
|
254
|
+
return if @keys_mapped
|
255
|
+
bind_keys([?k,FFI::NCurses::KEY_UP], "Up") { cursor_up }
|
256
|
+
bind_keys([?j,FFI::NCurses::KEY_DOWN], "Down") { cursor_down }
|
257
|
+
bind_keys([?l,FFI::NCurses::KEY_RIGHT], "Right") { cursor_forward }
|
258
|
+
bind_keys([?h,FFI::NCurses::KEY_LEFT], "Left") { cursor_backward }
|
259
|
+
bind_key(?g, 'goto_start') { goto_start }
|
260
|
+
bind_key(?G, 'goto_end') { goto_end }
|
261
|
+
bind_key(FFI::NCurses::KEY_CTRL_A, 'cursor_home') { cursor_home }
|
262
|
+
bind_key(FFI::NCurses::KEY_CTRL_E, 'cursor_end') { cursor_end }
|
263
|
+
bind_key(FFI::NCurses::KEY_CTRL_F, 'page_forward') { page_forward }
|
264
|
+
bind_key(32, 'page_forward') { page_forward }
|
265
|
+
bind_key(FFI::NCurses::KEY_CTRL_B, 'page_backward'){ page_backward }
|
266
|
+
bind_key(FFI::NCurses::KEY_CTRL_U, 'scroll_up') { scroll_up }
|
267
|
+
bind_key(FFI::NCurses::KEY_CTRL_D, 'scroll_down') { scroll_down }
|
268
|
+
## C-h was not working, so trying C-j
|
269
|
+
bind_key(FFI::NCurses::KEY_CTRL_J, 'scroll_left') { scroll_left }
|
270
|
+
bind_key(FFI::NCurses::KEY_CTRL_L, 'scroll_right') { scroll_right }
|
271
|
+
@keys_mapped = true
|
272
|
+
end
|
273
|
+
|
274
|
+
## on enter of this multiline
|
275
|
+
def on_enter
|
276
|
+
super
|
277
|
+
on_enter_row @current_index
|
278
|
+
# basically I need to only highlight the current index, not repaint all OPTIMIZE
|
279
|
+
touch ; repaint
|
280
|
+
end
|
281
|
+
|
282
|
+
# on leave of this multiline
|
283
|
+
def on_leave
|
284
|
+
super
|
285
|
+
on_leave_row @current_index
|
286
|
+
# basically I need to only unhighlight the current index, not repaint all OPTIMIZE
|
287
|
+
touch ; repaint
|
288
|
+
end
|
289
|
+
|
290
|
+
## called when user leaves a row and when object is exited.
|
291
|
+
def on_leave_row index
|
292
|
+
fire_handler(:LEAVE_ROW, [index]) # 2018-03-26 - improve this
|
293
|
+
end
|
294
|
+
# called whenever a row entered.
|
295
|
+
# Call when object entered, also.
|
296
|
+
def on_enter_row index
|
297
|
+
fire_handler(:ENTER_ROW, [@current_index]) # 2018-03-26 - improve this
|
298
|
+
# if cursor ahead of blen then fix it
|
299
|
+
blen = current_row().size-1
|
300
|
+
if @curpos > blen
|
301
|
+
@col_offset = blen - @pcol
|
302
|
+
@curpos = blen
|
303
|
+
if @pcol > blen
|
304
|
+
@pcol = blen - self.width ## @int_width 2018-05-22 -
|
305
|
+
@pcol = 0 if @pcol < 0
|
306
|
+
@col_offset = blen - @pcol
|
307
|
+
end
|
308
|
+
end
|
309
|
+
@col_offset = 0 if @col_offset < 0
|
310
|
+
end
|
311
|
+
def cursor_up
|
312
|
+
@current_index -= 1
|
313
|
+
end
|
314
|
+
# go to next row
|
315
|
+
def cursor_down
|
316
|
+
@current_index += 1
|
317
|
+
end
|
318
|
+
# position cursor at start of field
|
319
|
+
def cursor_home
|
320
|
+
@curpos = 0
|
321
|
+
@pcol = 0
|
322
|
+
set_col_offset 0
|
323
|
+
end
|
324
|
+
# goto end of line.
|
325
|
+
# This should be consistent with moving the cursor to the end of the row with right arrow
|
326
|
+
def cursor_end
|
327
|
+
blen = current_row().length
|
328
|
+
if blen < self.width
|
329
|
+
set_col_offset blen # just after the last character
|
330
|
+
@pcol = 0
|
331
|
+
else
|
332
|
+
@pcol = blen-self.width #+2 # 2 is due to mark and space XXX could be a problem with textbox
|
333
|
+
set_col_offset blen # just after the last character
|
334
|
+
end
|
335
|
+
@curpos = blen # this is position in array where editing or motion is to happen regardless of what you see
|
336
|
+
# regardless of pcol (panning)
|
337
|
+
end
|
338
|
+
# returns current row as String
|
339
|
+
# 2018-04-11 - NOTE this may not be a String so we convert it to string before returning
|
340
|
+
# @return [String] row the cursor/user is on
|
341
|
+
def current_row
|
342
|
+
s = @list[@current_index]
|
343
|
+
value_of_row s, @current_index, :CURRENT
|
344
|
+
end
|
345
|
+
# move cursor forward one character, called with KEY_RIGHT action.
|
346
|
+
def cursor_forward
|
347
|
+
blen = current_row().size # -1
|
348
|
+
if @curpos < blen
|
349
|
+
if add_col_offset(1)==-1 # go forward if you can, else scroll
|
350
|
+
#@pcol += 1 if @pcol < self.width
|
351
|
+
@pcol += 1 if @pcol < blen
|
352
|
+
end
|
353
|
+
@curpos += 1
|
354
|
+
end
|
355
|
+
end
|
356
|
+
def cursor_backward
|
357
|
+
|
358
|
+
if @col_offset > 0
|
359
|
+
@curpos -= 1
|
360
|
+
add_col_offset -1
|
361
|
+
else
|
362
|
+
# cur is on the first col, then scroll left
|
363
|
+
if @pcol > 0
|
364
|
+
@pcol -= 1
|
365
|
+
@curpos -= 1
|
366
|
+
else
|
367
|
+
# do nothing
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
# advance col_offset (where cursor will be displayed on screen)
|
372
|
+
# @param [Integer] advance by n (can be negative or positive)
|
373
|
+
# @return -1 if cannot advance
|
374
|
+
private def add_col_offset num
|
375
|
+
x = @col_offset + num
|
376
|
+
return -1 if x < 0
|
377
|
+
return -1 if x > self.width ## @int_width 2018-05-22 -
|
378
|
+
# is it a problem that i am directly changing col_offset ??? XXX
|
379
|
+
@col_offset += num
|
380
|
+
end
|
381
|
+
# sets the visual cursor on the window at correct place
|
382
|
+
# NOTE be careful of curpos - pcol being less than 0
|
383
|
+
# @param [Integer] position in data on the line
|
384
|
+
private def set_col_offset x=@curpos
|
385
|
+
@curpos = x || 0 # NOTE we set the index of cursor here - WHY TWO THINGS ??? XXX
|
386
|
+
#return -1 if x < 0
|
387
|
+
#return -1 if x > @width
|
388
|
+
_w = self.width
|
389
|
+
if x >= _w
|
390
|
+
x = _w
|
391
|
+
@col_offset = _w
|
392
|
+
return
|
393
|
+
end
|
394
|
+
@col_offset = x
|
395
|
+
@col_offset = _w if @col_offset > _w
|
396
|
+
return
|
397
|
+
end
|
398
|
+
def scroll_right ## cursor_forward
|
399
|
+
blen = current_row().size-1
|
400
|
+
@pcol += 1 if @pcol < blen
|
401
|
+
end
|
402
|
+
def scroll_left ##cursor_backward
|
403
|
+
@pcol -= 1 if @pcol > 0
|
404
|
+
end
|
405
|
+
# go to start of file (first line)
|
406
|
+
def goto_start
|
407
|
+
@current_index = 0
|
408
|
+
@pcol = @curpos = 0
|
409
|
+
set_col_offset 0
|
410
|
+
end
|
411
|
+
# go to end of file (last line)
|
412
|
+
def goto_end
|
413
|
+
@current_index = @list.size-1
|
414
|
+
@pcol = @curpos = 0
|
415
|
+
end
|
416
|
+
def scroll_down
|
417
|
+
@current_index += @scroll_lines
|
418
|
+
end
|
419
|
+
def scroll_up
|
420
|
+
@current_index -= @scroll_lines
|
421
|
+
end
|
422
|
+
def page_backward
|
423
|
+
@current_index -= @page_lines
|
424
|
+
end
|
425
|
+
def page_forward
|
426
|
+
@current_index += @page_lines
|
427
|
+
end
|
428
|
+
# }}}
|
429
|
+
|
430
|
+
|
431
|
+
## Multiline key handling. {{{
|
432
|
+
## Called by +form+ from form's +handle_key+ when this object is in focus.
|
433
|
+
## @param [Integer] ch: key caught by getch of window
|
434
|
+
def handle_key ch
|
435
|
+
old_current_index = @current_index
|
436
|
+
old_pcol = @pcol
|
437
|
+
old_col_offset = @col_offset
|
438
|
+
|
439
|
+
ret = super
|
440
|
+
return ret
|
441
|
+
ensure
|
442
|
+
## NOTE: it is possible that a block called above may have cleared the list.
|
443
|
+
## In that case, the on_enter_row will crash. I had put a check here, but it
|
444
|
+
## has vanished ???
|
445
|
+
@current_index = 0 if @current_index < 0
|
446
|
+
@current_index = @list.size-1 if @current_index >= @list.size
|
447
|
+
if @current_index != old_current_index
|
448
|
+
on_leave_row old_current_index
|
449
|
+
on_enter_row @current_index
|
450
|
+
@repaint_required = true
|
451
|
+
end
|
452
|
+
@repaint_required = true if old_pcol != @pcol or old_col_offset != @col_offset
|
453
|
+
end
|
454
|
+
|
455
|
+
## convenience method for calling most used event of a widget
|
456
|
+
## Called by user programs.
|
457
|
+
def command *args, &block
|
458
|
+
bind_event :ENTER_ROW, *args, &block
|
459
|
+
end # }}}
|
460
|
+
|
461
|
+
#
|
462
|
+
# event when user hits ENTER on a row, user would bind :PRESS
|
463
|
+
# callers may use w.current_index or w.current_row or w.curpos.
|
464
|
+
#
|
465
|
+
# obj.bind :PRESS { |w| w.current_row }
|
466
|
+
#
|
467
|
+
def fire_action_event
|
468
|
+
return if @list.nil? || @list.size == 0
|
469
|
+
#require 'canis/core/include/ractionevent'
|
470
|
+
#aev = text_action_event
|
471
|
+
#fire_handler :PRESS, aev
|
472
|
+
fire_handler :PRESS, self
|
473
|
+
end
|
474
|
+
end # class
|
475
|
+
end # module
|
476
|
+
|
data/lib/umbra/pad.rb
CHANGED
@@ -2,11 +2,12 @@
|
|
2
2
|
* Name: PadReader.rb
|
3
3
|
* Description : This is an independent file viewer that uses a Pad and traps keys
|
4
4
|
I am using only ffi-ncurses and not window.rb or any other support classes
|
5
|
-
so this can be used anywhere else.
|
5
|
+
so this can be used anywhere else. This however, limits the pad to very simple
|
6
|
+
printing.
|
6
7
|
* Author: jkepler
|
7
8
|
* Date: 2018-03-28 14:30
|
8
9
|
* License: MIT
|
9
|
-
* Last update: 2018-04-
|
10
|
+
* Last update: 2018-04-26 08:29
|
10
11
|
|
11
12
|
== CHANGES
|
12
13
|
== TODO
|
@@ -25,11 +26,12 @@ class Pad
|
|
25
26
|
# You may pass height, width, row and col for creating a window otherwise a fullscreen window
|
26
27
|
# will be created. If you pass a window from caller then that window will be used.
|
27
28
|
# Some keys are trapped, jkhl space, pgup, pgdown, end, home, t b
|
28
|
-
#
|
29
|
-
#
|
29
|
+
# NOTE: this is very minimal, and uses no widgets, so I am unable to yield an object
|
30
|
+
# for further configuration. If we used a textbox, I could have yielded that.
|
31
|
+
# TODO handle passed block
|
30
32
|
def initialize config={}, &block
|
31
33
|
|
32
|
-
$log.debug " inside pad contructor"
|
34
|
+
$log.debug " inside pad contructor" if $log
|
33
35
|
@config = config
|
34
36
|
@rows = FFI::NCurses.LINES-1
|
35
37
|
@cols = FFI::NCurses.COLS-1
|
@@ -62,7 +64,7 @@ class Pad
|
|
62
64
|
@rows -=3 # 3 is since print_border_only reduces one from width, to check whether this is correct
|
63
65
|
@cols -=3
|
64
66
|
end
|
65
|
-
$log.debug "top and left are: #{top} #{left} "
|
67
|
+
$log.debug "top and left are: #{top} #{left} " if $log
|
66
68
|
#@window.box # 2018-03-28 -
|
67
69
|
FFI::NCurses.box @pointer, 0, 0
|
68
70
|
title(config[:title])
|
@@ -120,21 +122,25 @@ class Pad
|
|
120
122
|
destroy_pad
|
121
123
|
@content_rows, @content_cols = content_dimensions(content)
|
122
124
|
pad = FFI::NCurses.newpad(@content_rows, @content_cols)
|
123
|
-
FFI::NCurses.wbkgd(pad, FFI::NCurses.COLOR_PAIR(@color_pair) | @attr);
|
124
125
|
FFI::NCurses.keypad(pad, true); # function and arrow keys
|
125
126
|
|
126
127
|
FFI::NCurses.update_panels
|
127
|
-
|
128
|
-
|
129
|
-
|
128
|
+
render(content, pad, @color_pair, @attr)
|
129
|
+
return pad
|
130
|
+
end
|
131
|
+
# renders the content in a loop.
|
132
|
+
# NOTE: separated in the hope that caller can override.
|
133
|
+
def render content, pad, color_pair, attr
|
134
|
+
cp = color_pair
|
135
|
+
FFI::NCurses.wbkgd(pad, FFI::NCurses.COLOR_PAIR(color_pair) | attr);
|
136
|
+
FFI::NCurses.wattron(pad, FFI::NCurses.COLOR_PAIR(cp) | attr)
|
130
137
|
# WRITE
|
131
|
-
filler = " "*@content_cols
|
138
|
+
#filler = " "*@content_cols
|
132
139
|
content.each_index { |ix|
|
133
140
|
#FFI::NCurses.mvwaddstr(pad,ix, 0, filler)
|
134
141
|
FFI::NCurses.mvwaddstr(pad,ix, 0, content[ix])
|
135
142
|
}
|
136
|
-
FFI::NCurses.wattroff(pad, FFI::NCurses.COLOR_PAIR(cp) |
|
137
|
-
return pad
|
143
|
+
FFI::NCurses.wattroff(pad, FFI::NCurses.COLOR_PAIR(cp) | attr)
|
138
144
|
end
|
139
145
|
|
140
146
|
# receive array as content source
|
@@ -174,7 +180,7 @@ class Pad
|
|
174
180
|
x.getbyte(0)
|
175
181
|
end
|
176
182
|
def content_cols content
|
177
|
-
#
|
183
|
+
# next line bombs if content contains integer or nil.
|
178
184
|
#longest = content.max_by(&:length)
|
179
185
|
#longest.length
|
180
186
|
max = 1
|
data/lib/umbra/radiobutton.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# Author: j kepler http://github.com/mare-imbrium/canis/
|
5
5
|
# Date: 2018-04-02 - 10:37
|
6
6
|
# License: MIT
|
7
|
-
# Last update: 2018-
|
7
|
+
# Last update: 2018-05-14 14:31
|
8
8
|
# ----------------------------------------------------------------------------- #
|
9
9
|
# radiobutton.rb Copyright (C) 2012-2018 j kepler
|
10
10
|
|
@@ -21,7 +21,7 @@ module Umbra
|
|
21
21
|
# radiobuttons of this group is fired.
|
22
22
|
|
23
23
|
class RadioButton < ToggleButton
|
24
|
-
|
24
|
+
attr_property :align_right # the button will be on the right
|
25
25
|
attr_accessor :button_group # group that this button belongs to.
|
26
26
|
|
27
27
|
def initialize config={}, &block
|