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
data/lib/umbra/form.rb
CHANGED
@@ -10,6 +10,11 @@ require 'umbra/keymappinghandler' # for bind_key and process_key
|
|
10
10
|
# has bound the key via +bind_key+.
|
11
11
|
# NOTE : 2018-03-08 - now using @focusables instead of @widgets in traversal.
|
12
12
|
# active_index is now index into focusables.
|
13
|
+
## Events: RESIZE (allows listener to reposition objects that have variable widths or heights)
|
14
|
+
## NOTE: active_index: 2018-05-17 - is being set to 0 even though no field is active. Thus, first time
|
15
|
+
# on_enter does not fire. It should only be set after a field is focused and its on_enter has succeeded.
|
16
|
+
#
|
17
|
+
|
13
18
|
module Umbra
|
14
19
|
class Form
|
15
20
|
# array of widgets, and those that can be traversed
|
@@ -69,9 +74,9 @@ class Form
|
|
69
74
|
end
|
70
75
|
# maintain a list of focusable objects so form can traverse between them easily.
|
71
76
|
def update_focusables
|
72
|
-
|
77
|
+
#$log.debug "1 inside update_focusables #{@focusables.count} "
|
73
78
|
@focusables = @widgets.select { |w| w.focusable }
|
74
|
-
|
79
|
+
#$log.debug "2 inside update_focusables #{@focusables.count} "
|
75
80
|
end
|
76
81
|
# Decide layout of objects. User has to call this after creating components
|
77
82
|
# More may come here.
|
@@ -108,6 +113,42 @@ class Form
|
|
108
113
|
self
|
109
114
|
end
|
110
115
|
|
116
|
+
## set focussed widget to given fld.
|
117
|
+
## This ensures that whenever a widget is given focus, the on_leave of the previous widget
|
118
|
+
## is called, and the on_enter of this field is called.
|
119
|
+
## 2018-05-18 - rewrite of select_field which did not call on_leave
|
120
|
+
def focussed_widget fld
|
121
|
+
|
122
|
+
return nil unless fld ## no focusable
|
123
|
+
|
124
|
+
if fld.is_a? Integer
|
125
|
+
fld = @focusables[fld]
|
126
|
+
end
|
127
|
+
|
128
|
+
return unless fld.focusable
|
129
|
+
|
130
|
+
## leave existing widget if there was one
|
131
|
+
fw = @_focussed_widget
|
132
|
+
return if fw == fld
|
133
|
+
|
134
|
+
if fw
|
135
|
+
on_leave fw
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
## enter given widget
|
140
|
+
on_enter fld
|
141
|
+
@_focussed_widget = fld
|
142
|
+
ix = @focusables.index fld
|
143
|
+
@active_index = ix
|
144
|
+
|
145
|
+
@row, @col = fld.rowcol
|
146
|
+
_setrowcol @row, @col
|
147
|
+
repaint # 2018-03-21 - handle_key calls repaint, is this for cases not involving keypress ?
|
148
|
+
@window.refresh
|
149
|
+
end
|
150
|
+
alias :select_field :focussed_widget
|
151
|
+
|
111
152
|
|
112
153
|
# form repaint,calls repaint on each widget which will repaint it only if it has been modified since last call.
|
113
154
|
# called after each keypress and on select_field.
|
@@ -122,6 +163,7 @@ class Form
|
|
122
163
|
f.graphic = @window unless f.graphic # messageboxes may not have a window till very late
|
123
164
|
f.repaint
|
124
165
|
f.repaint_required = false
|
166
|
+
f.instance_variable_set(:@_object_created, true) ## after this property_change handlers will fire
|
125
167
|
end
|
126
168
|
end
|
127
169
|
|
@@ -134,10 +176,23 @@ class Form
|
|
134
176
|
@window.wrefresh
|
135
177
|
end
|
136
178
|
# @return [Widget, nil] current field, nil if no focusable field
|
179
|
+
## NOTE 2018-05-17 - this is called by form in the very beginning when no field is actually focussed
|
180
|
+
## but active_index has been set to 0, so the on_enter has not been executed, but the handle_key
|
181
|
+
## is invoked.
|
137
182
|
def get_current_field
|
183
|
+
=begin
|
138
184
|
#select_next_field if @active_index == -1
|
139
185
|
return nil if @active_index.nil? # for forms that have no focusable field 2009-01-08 12:22
|
140
186
|
@focusables[@active_index]
|
187
|
+
=end
|
188
|
+
|
189
|
+
|
190
|
+
## rewrite on 2018-05-18 - so that on_enter is called for first field
|
191
|
+
if @_focussed_widget.nil? ## when form handle_key first called
|
192
|
+
focussed_widget @focusables.first
|
193
|
+
end
|
194
|
+
return @_focussed_widget
|
195
|
+
|
141
196
|
end
|
142
197
|
alias :current_widget :get_current_field
|
143
198
|
# take focus to first focusable field
|
@@ -162,7 +217,7 @@ class Form
|
|
162
217
|
# puts focus on the given field/widget index
|
163
218
|
# @param index of field in @widgets (or can be a Widget too)
|
164
219
|
# XXX if called externally will not run a on_leave of previous field
|
165
|
-
def
|
220
|
+
def OLDselect_field ix0
|
166
221
|
if ix0.is_a? Widget
|
167
222
|
ix0 = @focusables.index(ix0)
|
168
223
|
end
|
@@ -183,41 +238,27 @@ class Form
|
|
183
238
|
$log.debug "inside select field ENABLED FALSE : act #{@active_index} ix0 #{ix0}"
|
184
239
|
end
|
185
240
|
end
|
186
|
-
|
187
|
-
# run validate_field on a field, usually whatevers current
|
188
|
-
# before transferring control
|
189
|
-
# We should try to automate this so developer does not have to remember to call it.
|
190
|
-
# # @param field object
|
191
|
-
# @return [0, -1] for success or failure
|
192
|
-
# NOTE : catches exception and sets $error_message, check if -1
|
193
|
-
def validate_field f=@focusables[@active_index]
|
194
|
-
begin
|
195
|
-
on_leave f
|
196
|
-
rescue => err
|
197
|
-
$log.error "form: validate_field caught EXCEPTION #{err}"
|
198
|
-
$log.error(err.backtrace.join("\n"))
|
199
|
-
# $error_message = "#{err}" # changed 2010
|
200
|
-
#$error_message.value = "#{err}" # 2018-03-18 - commented off since no Variable any longer
|
201
|
-
FFI::NCurses.beep
|
202
|
-
return -1
|
203
|
-
end
|
204
|
-
return 0
|
205
|
-
end
|
241
|
+
|
206
242
|
# put focus on next field
|
207
243
|
# will cycle by default, unless navigation policy not :CYCLICAL
|
208
244
|
# in which case returns :NO_NEXT_FIELD.
|
209
|
-
# FIXME: in the beginning it comes in as -1 and does an on_leave of last field
|
210
245
|
# 2018-03-07 - UMBRA: let us force user to run validation when he does next field
|
211
246
|
def select_next_field
|
212
247
|
return :UNHANDLED if @focusables.nil? || @focusables.empty?
|
213
|
-
|
248
|
+
index = nil
|
249
|
+
if @_focussed_widget
|
250
|
+
index = @focusables.index @_focussed_widget
|
251
|
+
end
|
252
|
+
index = index ? index+1 : 0
|
253
|
+
index = 0 if index >= @focusables.length # CYCLICAL 2018-03-11 -
|
254
|
+
focussed_widget @focusables[index]
|
255
|
+
=begin
|
256
|
+
return :UNHANDLED if @focusables.nil? || @focusables.empty?
|
214
257
|
if @active_index.nil? || @active_index == -1 # needs to be tested out A LOT
|
215
|
-
|
216
|
-
@active_index = -1
|
217
|
-
@active_index = 0 # 2018-03-08 - NOT_SURE
|
258
|
+
@active_index = 0
|
218
259
|
end
|
219
260
|
f = @focusables[@active_index]
|
220
|
-
# we need to call on_leave of this field or else state will never change back to normal
|
261
|
+
# we need to call on_leave of this field or else state will never change back to normal
|
221
262
|
on_leave f
|
222
263
|
#index = @focusables.index(f)
|
223
264
|
index = @active_index
|
@@ -232,6 +273,7 @@ class Form
|
|
232
273
|
#
|
233
274
|
$log.debug "inside sele nxt field : NO NEXT #{@active_index} WL:#{@widgets.length}"
|
234
275
|
return :NO_NEXT_FIELD
|
276
|
+
=end
|
235
277
|
end
|
236
278
|
##
|
237
279
|
# put focus on previous field
|
@@ -240,6 +282,17 @@ class Form
|
|
240
282
|
# @return [nil, :NO_PREV_FIELD] nil if cyclical and it finds a field
|
241
283
|
# if not cyclical, and no more fields then :NO_PREV_FIELD
|
242
284
|
def select_prev_field
|
285
|
+
return :UNHANDLED if @focusables.nil? or @focusables.empty?
|
286
|
+
index = nil
|
287
|
+
if @_focussed_widget
|
288
|
+
index = @focusables.index @_focussed_widget
|
289
|
+
else
|
290
|
+
index = @focusables.length
|
291
|
+
end
|
292
|
+
index -= 1
|
293
|
+
index = @focusables.length-1 if index < 0 # CYCLICAL 2018-03-11 -
|
294
|
+
focussed_widget @focusables[index]
|
295
|
+
=begin
|
243
296
|
return :UNHANDLED if @focusables.nil? or @focusables.empty?
|
244
297
|
#$log.debug "insdie sele prev field : #{@active_index} WL:#{@widgets.length}"
|
245
298
|
if @active_index.nil?
|
@@ -258,6 +311,7 @@ class Form
|
|
258
311
|
end
|
259
312
|
|
260
313
|
return :NO_PREV_FIELD
|
314
|
+
=end
|
261
315
|
end
|
262
316
|
|
263
317
|
private
|
@@ -312,7 +366,7 @@ class Form
|
|
312
366
|
f.on_enter if f.respond_to? :on_enter
|
313
367
|
end
|
314
368
|
|
315
|
-
def
|
369
|
+
def OLD_process_key keycode, object, window
|
316
370
|
return :UNHANDLED if @_key_map.nil?
|
317
371
|
blk = @_key_map[keycode]
|
318
372
|
$log.debug "XXX: _process key keycode #{keycode} #{blk.class}, #{self.class} "
|
@@ -338,9 +392,9 @@ class Form
|
|
338
392
|
# returns UNHANDLED if no block for it
|
339
393
|
# after form handles basic keys, it gives unhandled key to current field, if current field returns
|
340
394
|
# unhandled, then it checks this map.
|
341
|
-
# Please update widget with any changes here.
|
395
|
+
# Please update widget with any changes here.
|
342
396
|
|
343
|
-
def
|
397
|
+
def OLDprocess_key keycode, object # already there in keymappinghandler
|
344
398
|
return _process_key keycode, object, @window
|
345
399
|
end # }}}
|
346
400
|
|
@@ -355,7 +409,6 @@ class Form
|
|
355
409
|
@keys_mapped = true
|
356
410
|
end
|
357
411
|
|
358
|
-
=begin
|
359
412
|
# repaint all # {{{
|
360
413
|
# this forces a repaint of all visible widgets and has been added for the case of overlapping
|
361
414
|
# windows, since a black rectangle is often left when a window is destroyed. This is internally
|
@@ -364,20 +417,21 @@ class Form
|
|
364
417
|
# the window itself may need recreating ? 2014-08-18 - 21:03
|
365
418
|
def repaint_all_widgets
|
366
419
|
$log.debug " REPAINT ALL in FORM called "
|
367
|
-
raise "it has come to repaint_all"
|
420
|
+
#raise "it has come to repaint_all"
|
368
421
|
@widgets.each do |w|
|
369
422
|
next if w.visible == false
|
370
423
|
#next if w.class.to_s == "Canis::MenuBar"
|
371
424
|
$log.debug " ---- REPAINT ALL #{w.name} "
|
372
|
-
|
373
|
-
w.repaint_all true
|
425
|
+
w.repaint_required = true
|
426
|
+
#w.repaint_all true
|
374
427
|
w.repaint
|
375
428
|
end
|
376
429
|
$log.debug " REPAINT ALL in FORM complete "
|
377
430
|
# place cursor on current_widget
|
378
431
|
_setpos
|
379
432
|
end # }}}
|
380
|
-
|
433
|
+
|
434
|
+
|
381
435
|
## forms handle keys {{{
|
382
436
|
# mainly traps tab and backtab to navigate between widgets.
|
383
437
|
# I know some widgets will want to use tab, e.g edit boxes for entering a tab
|
@@ -392,42 +446,52 @@ class Form
|
|
392
446
|
when -1
|
393
447
|
#repaint # only for continuous updates, and will need to use wtimeout and not nodelay in getch
|
394
448
|
return
|
395
|
-
|
396
|
-
when 1000, 12
|
449
|
+
when 1000, 18 # what if someone has trapped this.
|
397
450
|
# NOTE this works if widgets cover entire screen like text areas and lists but not in
|
398
451
|
# dialogs where there is blank space. only widgets are painted.
|
399
|
-
# testing out 12 is C-l
|
452
|
+
# testing out 12 is C-l, 18 is C-r
|
400
453
|
$log.debug " form REFRESH_ALL repaint_all HK #{ch} #{self}, #{@name} "
|
454
|
+
FFI::NCurses.endwin
|
455
|
+
@window.wrefresh ## endwin must be followed by refresh
|
456
|
+
@window.repaint
|
401
457
|
repaint_all_widgets
|
402
|
-
|
458
|
+
@window.wrefresh
|
459
|
+
return 0
|
403
460
|
when FFI::NCurses::KEY_RESIZE # SIGWINCH # UNTESTED XXX
|
461
|
+
## NOTE: this works but boxes are not resized since hardcoded height and width were given.
|
462
|
+
## 2018-05-13 - only if a layout is used, can a recalc happen.
|
404
463
|
# note that in windows that have dialogs or text painted on window such as title or
|
405
464
|
# box, the clear call will clear it out. these are not redrawn.
|
406
|
-
|
407
|
-
cols = FFI::NCurses.COLS
|
408
|
-
x = FFI::NCurses.stdscr.getmaxy
|
409
|
-
y = FFI::NCurses.stdscr.getmaxx
|
410
|
-
$log.debug " form RESIZE HK #{ch} #{self}, #{@name}, #{ch}, x #{x} y #{y} lines #{lines} , cols: #{cols} "
|
411
|
-
#alert "SIGWINCH WE NEED TO RECALC AND REPAINT resize #{lines}, #{cols}: #{x}, #{y} "
|
412
|
-
|
465
|
+
|
413
466
|
# next line may be causing flicker, can we do without.
|
414
467
|
FFI::NCurses.endwin
|
415
468
|
@window.wrefresh
|
416
469
|
@window.wclear
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
470
|
+
lines = FFI::NCurses.LINES
|
471
|
+
cols = FFI::NCurses.COLS
|
472
|
+
#x = FFI::NCurses.stdscr.getmaxy
|
473
|
+
x = @window.getmaxy
|
474
|
+
#y = FFI::NCurses.stdscr.getmaxx
|
475
|
+
y = @window.getmaxx
|
476
|
+
@window.wresize(x,y)
|
477
|
+
$log.debug " form RESIZE SIGWINCH HK #{ch} #{self}, #{@name}, #{ch}, x #{x} y #{y} lines #{lines} , cols: #{cols} "
|
478
|
+
#alert "SIGWINCH WE NEED TO RECALC AND REPAINT resize #{lines}, #{cols}: #{x}, #{y} "
|
479
|
+
|
480
|
+
repaint_all_widgets
|
481
|
+
#if @layout_manager
|
482
|
+
#@layout_manager.do_layout
|
483
|
+
## we need to redo statusline and others that layout ignores
|
484
|
+
#else
|
485
|
+
#end
|
423
486
|
## added RESIZE on 2012-01-5
|
424
487
|
## stuff that relies on last line such as statusline dock etc will need to be redrawn.
|
425
488
|
fire_handler :RESIZE, self
|
426
|
-
|
489
|
+
@window.wrefresh
|
427
490
|
else
|
428
491
|
field = get_current_field
|
429
492
|
handled = :UNHANDLED
|
430
493
|
handled = field.handle_key ch unless field.nil? # no field focussable
|
494
|
+
## next line "field" can print entire content of a list or table if to_s is large
|
431
495
|
$log.debug "handled inside Form #{ch} from #{field} got #{handled} "
|
432
496
|
# some widgets like textarea and list handle up and down
|
433
497
|
if handled == :UNHANDLED or handled == -1 or field.nil?
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# Author: j kepler http://github.com/mare-imbrium/canis/
|
5
5
|
# Date: 2018-04-05 - 08:34
|
6
6
|
# License: MIT
|
7
|
-
# Last update: 2018-04-
|
7
|
+
# Last update: 2018-04-22 23:01
|
8
8
|
# ----------------------------------------------------------------------------- #
|
9
9
|
# keymappinghandler.rb Copyright (C) 2018 j kepler
|
10
10
|
|
@@ -74,7 +74,7 @@ module Umbra
|
|
74
74
|
def _process_key keycode, object, window
|
75
75
|
return :UNHANDLED if @_key_map.nil?
|
76
76
|
blk = @_key_map[keycode]
|
77
|
-
|
77
|
+
#$log.debug "XXX: _process key keycode #{keycode} #{blk.class}, #{self.class} "
|
78
78
|
return :UNHANDLED if blk.nil?
|
79
79
|
|
80
80
|
if blk.is_a? Symbol
|
@@ -82,12 +82,12 @@ module Umbra
|
|
82
82
|
return send(blk, *@_key_args[keycode])
|
83
83
|
else
|
84
84
|
## 2013-03-05 - 19:50 why the hell is there an alert here, nowhere else
|
85
|
-
$log.error "This ( #{self.class} ) does not respond to #{blk.to_s} [PROCESS-KEY]"
|
85
|
+
$log.error "This ( #{self.class} ) does not respond to #{blk.to_s} [PROCESS-KEY]" if $log
|
86
86
|
# added 2013-03-05 - 19:50 so called can know
|
87
87
|
return :UNHANDLED
|
88
88
|
end
|
89
89
|
else
|
90
|
-
|
90
|
+
#$log.debug "rwidget BLOCK called _process_key " if $log.debug?
|
91
91
|
return blk.call object, *@_key_args[keycode]
|
92
92
|
end
|
93
93
|
end
|
data/lib/umbra/label.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# Author: j kepler http://github.com/mare-imbrium/canis/
|
6
6
|
# Date: 2018-03-08 - 14:04
|
7
7
|
# License: MIT
|
8
|
-
# Last update: 2018-
|
8
|
+
# Last update: 2018-05-22 23:36
|
9
9
|
# ----------------------------------------------------------------------------- #
|
10
10
|
# label.rb Copyright (C) 2018- j kepler
|
11
11
|
#
|
@@ -16,7 +16,7 @@ module Umbra
|
|
16
16
|
class Label < Widget
|
17
17
|
|
18
18
|
# justify required a display length, esp if center.
|
19
|
-
|
19
|
+
attr_property :justify #:right, :left, :center
|
20
20
|
attr_accessor :mnemonic # alt-key that passes focus to related field
|
21
21
|
attr_accessor :related_widget # field related to this label. See +mnemonic+.
|
22
22
|
|
@@ -45,7 +45,9 @@ class Label < Widget
|
|
45
45
|
def repaint
|
46
46
|
return unless @repaint_required
|
47
47
|
raise "Label row or col is nil #{@row} , #{@col}, #{@text} " if @row.nil? || @col.nil?
|
48
|
-
r,c = rowcol
|
48
|
+
#r,c = rowcol
|
49
|
+
r = self.row
|
50
|
+
c = self.col
|
49
51
|
$log.debug "label repaint #{r} #{c} #{@text} "
|
50
52
|
|
51
53
|
# value often nil so putting blank, but usually some application error
|
@@ -55,29 +57,40 @@ class Label < Widget
|
|
55
57
|
value = value.join " "
|
56
58
|
end
|
57
59
|
# ensure we do not exceed
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
60
|
+
# ## TODO do this in the format commented on 2018-05-22 -
|
61
|
+
_width = self.width
|
62
|
+
#if _width
|
63
|
+
#if value.length > _width
|
64
|
+
#value = value[0.._width-1]
|
65
|
+
#end
|
66
|
+
#end
|
67
|
+
len = _width || value.length
|
64
68
|
acolor = @color_pair || 0
|
65
|
-
str = @justify.to_sym == :right ? "%*s" : "%-*s" # added 2008-12-22 19:05
|
69
|
+
#str = @justify.to_sym == :right ? "%*s" : "%-*s" # added 2008-12-22 19:05
|
70
|
+
str = @justify.to_sym == :right ? "%#{len}.#{len}s" : "%-#{len}.#{len}s" # added 2008-12-22 19:05
|
66
71
|
|
67
|
-
#@graphic ||= @form.window
|
68
72
|
# clear the area
|
69
73
|
@graphic.printstring r, c, " " * len , acolor, @attr
|
70
74
|
if @justify.to_sym == :center
|
71
|
-
padding = (
|
75
|
+
padding = (_width - value.length)/2
|
72
76
|
value = " "*padding + value + " "*padding # so its cleared if we change it midway
|
73
77
|
end
|
74
|
-
|
78
|
+
## move this into paint_label or something so we can override.
|
79
|
+
# try a block which was passed earlier which gets a string TODO
|
80
|
+
#@graphic.printstring r, c, str % [value], acolor, @attr
|
81
|
+
print_label @graphic, r, c, str , value, acolor, @attr
|
75
82
|
if @mnemonic
|
76
83
|
ulindex = value.index(@mnemonic) || value.index(@mnemonic.swapcase)
|
77
84
|
@graphic.mvchgat(y=r, x=c+ulindex, max=1, BOLD|UNDERLINE, acolor, nil)
|
78
85
|
end
|
79
86
|
@repaint_required = false
|
80
87
|
end
|
88
|
+
|
89
|
+
## The mwthod that finally prints the label text.
|
90
|
+
## Override this to do any customised printing such as multiple colors.
|
91
|
+
def print_label(win, row, col, format, value, _color, _attr)
|
92
|
+
win.printstring row, col, format % [value], _color, _attr
|
93
|
+
end
|
81
94
|
# Added 2011-10-22 to prevent some naive components from putting focus here.
|
82
95
|
def on_enter
|
83
96
|
raise "Cannot enter Label"
|
@@ -86,10 +99,11 @@ class Label < Widget
|
|
86
99
|
raise "Cannot leave Label"
|
87
100
|
end
|
88
101
|
# overriding so that label is redrawn, since this is the main property that is used.
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
102
|
+
## 2018-05-21 - we are now using attr_property so not required
|
103
|
+
#def text=(_text)
|
104
|
+
#@text = _text
|
105
|
+
#self.touch
|
106
|
+
#end
|
93
107
|
# ADD HERE LABEL
|
94
108
|
end # }}}
|
95
109
|
end # module
|
data/lib/umbra/labeledfield.rb
CHANGED
@@ -4,12 +4,11 @@
|
|
4
4
|
# Author: j kepler http://github.com/mare-imbrium/canis/
|
5
5
|
# Date: 2018-04-12 - 23:35
|
6
6
|
# License: MIT
|
7
|
-
# Last update: 2018-
|
7
|
+
# Last update: 2018-05-14 14:34
|
8
8
|
# ----------------------------------------------------------------------------- #
|
9
9
|
# labeledfield.rb Copyright (C) 2018 j kepler
|
10
10
|
require 'umbra/field'
|
11
11
|
module Umbra
|
12
|
-
# TODO should be able to add a mnemonic here for the label since the association exists
|
13
12
|
# TODO we should consider creating a Label, so user can have more control. Or allow user
|
14
13
|
# to supply a Label i/o a String ???
|
15
14
|
#
|
@@ -30,15 +29,15 @@ module Umbra
|
|
30
29
|
# It is initialized exactly like a Field, with the addition of label (and optionally label_color_pair,
|
31
30
|
# label_attr, and lcol, lrow)
|
32
31
|
#
|
33
|
-
|
32
|
+
attr_property :label # label of field, just a String
|
34
33
|
# if lrow and lcol are specified then label is printed exactly at that spot.
|
35
34
|
# If they are omitted, then label is printed on left of field. Omit the lcol if you want
|
36
35
|
# the fields to be aligned, one under another, with the labels right-aligned.
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
36
|
+
attr_property :lrow, :lcol # coordinates of the label
|
37
|
+
attr_property :label_color_pair # label of field color_pair
|
38
|
+
attr_property :label_attr # label of field attribute
|
39
|
+
attr_property :label_highlight_color_pair # label of field high color_pair
|
40
|
+
attr_property :label_highlight_attr # label of field high attribute
|
42
41
|
attr_accessor :mnemonic # mnemonic of field which shows up on label
|
43
42
|
attr_accessor :related_widget # to keep sync with label
|
44
43
|
def initialize config={}, &block
|