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