ncumbra 0.1.0

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.
@@ -0,0 +1,71 @@
1
+ # ----------------------------------------------------------------------------- #
2
+ # File: radiobutton.rb
3
+ # Description: a member of a group of buttons, only one can be selected at a time.
4
+ # Author: j kepler http://github.com/mare-imbrium/canis/
5
+ # Date: 2018-04-02 - 10:37
6
+ # License: MIT
7
+ # Last update: 2018-04-03 14:22
8
+ # ----------------------------------------------------------------------------- #
9
+ # radiobutton.rb Copyright (C) 2012-2018 j kepler
10
+
11
+ module Umbra
12
+ ##
13
+ # A selectable button that has a text value. It is based on a Variable that
14
+ # is shared by other radio buttons. Only one is selected at a time, unlike checkbox
15
+ # +text+ is the value to display, which can include an ampersand for a hotkey
16
+ # +value+ is the value returned if selected, which usually is similar to text (or a short word)
17
+ # +width+ is helpful if placing the brackets to right of text, used to align round brackets
18
+ # By default, radio buttons place the button on the left of the text.
19
+ #
20
+ # Typically, the variable's update_command is passed a block to execute whenever any of the
21
+ # radiobuttons of this group is fired.
22
+
23
+ class RadioButton < ToggleButton
24
+ attr_accessor :align_right # the button will be on the right
25
+ attr_accessor :button_group # group that this button belongs to.
26
+
27
+ def initialize config={}, &block
28
+ @surround_chars = ['(', ')'] if @surround_chars.nil?
29
+ super
30
+ $log.warn "XXX: FIXME Please set 'value' for radiobutton. If not sure, try setting it to the same value as 'text'" unless @value
31
+ @value ||= @text
32
+ end
33
+
34
+ # all radio buttons will return the value of the selected value, not the offered value
35
+ def getvalue
36
+ @button_group.value
37
+ end
38
+
39
+ def getvalue_for_paint
40
+ buttontext = getvalue() == @value ? "o" : " "
41
+ $log.debug "called get_value_for paint for buttong #{@value} :#{buttontext} "
42
+ dtext = @width.nil? ? text : "%-*s" % [@width, text]
43
+ if @align_right
44
+ @text_offset = 0
45
+ @col_offset = dtext.length + @surround_chars[0].length + 1
46
+ return "#{dtext} " + @surround_chars[0] + buttontext + @surround_chars[1]
47
+ else
48
+ pretext = @surround_chars[0] + buttontext + @surround_chars[1]
49
+ @text_offset = pretext.length + 1
50
+ @col_offset = @surround_chars[0].length
51
+ return pretext + " #{dtext}"
52
+ end
53
+ end
54
+
55
+ def toggle
56
+ fire
57
+ end
58
+
59
+ ##
60
+ # If user has pressed on this then set the group to this button.
61
+ def checked tf
62
+
63
+ if @button_group.value == value
64
+ @button_group.value = ""
65
+ else
66
+ @button_group.value = value
67
+ end
68
+ end
69
+
70
+ end # class radio
71
+ end # module
@@ -0,0 +1,417 @@
1
+ # ----------------------------------------------------------------------------- #
2
+ # File: textbox.rb
3
+ # Description: a multiline text view
4
+ # Author: j kepler http://github.com/mare-imbrium/canis/
5
+ # Date: 2018-03-24 - 12:39
6
+ # License: MIT
7
+ # Last update: 2018-04-20 12:58
8
+ # ----------------------------------------------------------------------------- #
9
+ # textbox.rb Copyright (C) 2012-2018 j kepler
10
+ ## TODO -----------------------------------
11
+ # improve the object sent when row change or cursor movement
12
+ #
13
+ #
14
+ # ----------------------------------------
15
+ ## CHANGELOG
16
+ #
17
+ # ----------------------------------------
18
+ require 'umbra/widget'
19
+ module Umbra
20
+ class Textbox < Widget
21
+ attr_reader :list # list containing data
22
+ 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
+ #attr_accessor :cursor # position of cursor in line ??
28
+ =begin
29
+ attr_accessor :selected_mark # row selected character
30
+ attr_accessor :unselected_mark # row unselected character (usually blank)
31
+ attr_accessor :current_mark # row current character (default is >)
32
+ =end
33
+
34
+ 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
+ @highlight_attr = FFI::NCurses::A_BOLD
42
+ @to_print_border = false
43
+ @row_offset = 0
44
+ @col_offset = 0
45
+ @pcol = 0
46
+ @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]) #
56
+ super
57
+
58
+ map_keys
59
+ # internal width and height
60
+ @repaint_required = true
61
+ 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.
70
+ # NOTE this can be called again and again, so we need to take care of change in size of data
71
+ # 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
+ def file_name=(fp)
85
+ raise "File #{fp} not readable" unless File.readable? fp
86
+ return Dir.new(fp).entries if File.directory? fp
87
+ case File.extname(fp)
88
+ when '.tgz','.gz'
89
+ cmd = "tar -ztvf #{fp}"
90
+ content = %x[#{cmd}]
91
+ when '.zip'
92
+ cmd = "unzip -l #{fp}"
93
+ content = %x[#{cmd}]
94
+ when '.jar', '.gem'
95
+ cmd = "tar -tvf #{fp}"
96
+ content = %x[#{cmd}]
97
+ when '.png', '.out','.jpg', '.gif','.pdf'
98
+ content = "File #{fp} not displayable"
99
+ when '.sqlite'
100
+ cmd = "sqlite3 #{fp} 'select name from sqlite_master;'"
101
+ content = %x[#{cmd}]
102
+ else
103
+ #content = File.open(fp,"r").readlines # this keeps newlines which mess with output
104
+ content = File.open(fp,"r").read.split("\n")
105
+ end
106
+ self.list = content
107
+ raise "list not set" unless @list
108
+
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
199
+
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]
206
+ end
207
+
208
+
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
228
+ def handle_key ch
229
+ return :UNHANDLED unless @list
230
+ # save old positions so we know movement has happened
231
+ old_current_index = @current_index
232
+ old_pcol = @pcol
233
+ old_col_offset = @col_offset
234
+
235
+ 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
+ ret = super
246
+ return ret
247
+ end
248
+ ensure
249
+ @current_index = 0 if @current_index < 0
250
+ @current_index = @list.size-1 if @current_index >= @list.size
251
+ @repaint_required = true if @current_index != old_current_index
252
+ if @current_index != old_current_index or @pcol != old_pcol or @col_offset != old_col_offset
253
+ if @current_index != old_current_index
254
+ on_leave_row old_current_index
255
+ on_enter_row @current_index
256
+ #fire_handler(:CHANGE_ROW, [old_current_index, @current_index, ch ]) # 2018-03-26 - improve this
257
+ end
258
+ @repaint_required = true
259
+ fire_handler(:CURSOR_MOVE, [@col_offset, @current_index, @curpos, @pcol, ch ]) # 2018-03-25 - improve this
260
+ end
261
+ end
262
+ end
263
+ # advance col_offset (where cursor will be displayed on screen)
264
+ # @param [Integer] advance by n (can be negative or positive)
265
+ # @return -1 if cannot advance
266
+ private def add_col_offset num
267
+ x = @col_offset + num
268
+ return -1 if x < 0
269
+ return -1 if x > @int_width
270
+ # is it a problem that i am directly changing col_offset ??? XXX
271
+ @col_offset += num
272
+ end
273
+ # returns current row
274
+ def current_row
275
+ @list[@current_index]
276
+ end
277
+
278
+ # move cursor forward one character, called with KEY_RIGHT action.
279
+ def cursor_forward
280
+ blen = current_row().size-1
281
+ if @curpos < blen
282
+ if add_col_offset(1)==-1 # go forward if you can, else scroll
283
+ #@pcol += 1 if @pcol < @width
284
+ @pcol += 1 if @pcol < blen
285
+ end
286
+ @curpos += 1
287
+ end
288
+ end
289
+ def cursor_backward
290
+
291
+ if @col_offset > 0
292
+ @curpos -= 1
293
+ add_col_offset -1
294
+ else
295
+ # cur is on the first col, then scroll left
296
+ if @pcol > 0
297
+ @pcol -= 1
298
+ @curpos -= 1
299
+ else
300
+ # do nothing
301
+ end
302
+ end
303
+ end
304
+ # position cursor at start of field
305
+ def cursor_home
306
+ @curpos = 0
307
+ @pcol = 0
308
+ set_col_offset 0
309
+ end
310
+ # goto end of line.
311
+ # This should be consistent with moving the cursor to the end of the row with right arrow
312
+ def cursor_end
313
+ blen = current_row().length
314
+ if blen < @int_width
315
+ set_col_offset blen # just after the last character
316
+ @pcol = 0
317
+ else
318
+ @pcol = blen-@int_width
319
+ set_col_offset blen
320
+ end
321
+ @curpos = blen # this is position in array where editing or motion is to happen regardless of what you see
322
+ # regardless of pcol (panning)
323
+ end
324
+ # go to start of file (first line)
325
+ def goto_start
326
+ @current_index = 0
327
+ @pcol = @curpos = 0
328
+ set_col_offset 0
329
+ end
330
+ # go to end of file (last line)
331
+ def goto_end
332
+ @current_index = @list.size-1
333
+ 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
+ # sets the visual cursor on the window at correct place
347
+ # NOTE be careful of curpos - pcol being less than 0
348
+ # @param [Integer] position in data on the line
349
+ private def set_col_offset x=@curpos
350
+ @curpos = x || 0 # NOTE we set the index of cursor here - WHY TWO THINGS ??? XXX
351
+ #return -1 if x < 0
352
+ #return -1 if x > @width
353
+ if x >= @int_width
354
+ x = @int_width
355
+ @col_offset = @int_width
356
+ return
357
+ end
358
+ @col_offset = x
359
+ @col_offset = @int_width if @col_offset > @int_width
360
+ return
361
+ 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
+ # called whenever a row entered.
383
+ # Call when object entered, also.
384
+ def on_enter_row index
385
+ #fire_handler(:ENTER_ROW, [old_current_index, @current_index, ch ]) # 2018-03-26 - improve this
386
+ fire_handler(:ENTER_ROW, [@current_index]) # 2018-03-26 - improve this
387
+ # if cursor ahead of blen then fix it
388
+ blen = current_row().size-1
389
+ if @curpos > blen
390
+ @col_offset = blen - @pcol
391
+ @curpos = blen
392
+ if @pcol > blen
393
+ @pcol = blen - @int_width
394
+ @pcol = 0 if @pcol < 0
395
+ @col_offset = blen - @pcol
396
+ end
397
+ end
398
+ @col_offset = 0 if @col_offset < 0
399
+ end
400
+ ## border {{{
401
+ private def print_border row, col, height, width, color, att=FFI::NCurses::A_NORMAL
402
+ raise
403
+ pointer = @graphic.pointer
404
+ FFI::NCurses.wattron(pointer, FFI::NCurses.COLOR_PAIR(color) | att)
405
+ FFI::NCurses.mvwaddch pointer, row, col, FFI::NCurses::ACS_ULCORNER
406
+ FFI::NCurses.mvwhline( pointer, row, col+1, FFI::NCurses::ACS_HLINE, width-2)
407
+ FFI::NCurses.mvwaddch pointer, row, col+width-1, FFI::NCurses::ACS_URCORNER
408
+ FFI::NCurses.mvwvline( pointer, row+1, col, FFI::NCurses::ACS_VLINE, height-2)
409
+
410
+ FFI::NCurses.mvwaddch pointer, row+height-1, col, FFI::NCurses::ACS_LLCORNER
411
+ FFI::NCurses.mvwhline(pointer, row+height-1, col+1, FFI::NCurses::ACS_HLINE, width-2)
412
+ FFI::NCurses.mvwaddch pointer, row+height-1, col+width-1, FFI::NCurses::ACS_LRCORNER
413
+ FFI::NCurses.mvwvline( pointer, row+1, col+width-1, FFI::NCurses::ACS_VLINE, height-2)
414
+ FFI::NCurses.wattroff(pointer, FFI::NCurses.COLOR_PAIR(color) | att)
415
+ end # }}}
416
+ end
417
+ end # module
@@ -0,0 +1,140 @@
1
+ require 'umbra/button'
2
+ ##
3
+ # ----------------------------------------------------------------------------- #
4
+ # File: togglebutton.rb
5
+ # Description: a button that has two states, on and off
6
+ # Author: j kepler http://github.com/mare-imbrium/umbra/
7
+ # Date: 2018-03-17 - 22:50
8
+ # License: MIT
9
+ # Last update: 2018-04-07 23:08
10
+ # ----------------------------------------------------------------------------- #
11
+ # togglebutton.rb Copyright (C) 2012-2018 j kepler
12
+ #
13
+ #
14
+ module Umbra
15
+ ##
16
+ # an event fired when an item that can be selected is toggled/selected
17
+ class ItemEvent # {{{
18
+ # http://java.sun.com/javase/6/docs/api/java/awt/event/ItemEvent.html
19
+ attr_reader :state # :SELECTED :DESELECTED
20
+ attr_reader :item # the item pressed such as toggle button
21
+ attr_reader :item_selectable # item originating event such as list or collection
22
+ attr_reader :item_first # if from a list
23
+ attr_reader :item_last #
24
+ attr_reader :param_string # for debugging etc
25
+ =begin
26
+ def initialize item, item_selectable, state, item_first=-1, item_last=-1, paramstring=nil
27
+ @item, @item_selectable, @state, @item_first, @item_last =
28
+ item, item_selectable, state, item_first, item_last
29
+ @param_string = "Item event fired: #{item}, #{state}"
30
+ end
31
+ =end
32
+ # i think only one is needed per object, so create once only
33
+ def initialize item, item_selectable
34
+ @item, @item_selectable =
35
+ item, item_selectable
36
+ end
37
+ def set state, item_first=-1, item_last=-1, param_string=nil
38
+ @state, @item_first, @item_last, @param_string =
39
+ state, item_first, item_last, param_string
40
+ @param_string = "Item event fired: #{item}, #{state}" if param_string.nil?
41
+ end
42
+ end # }}}
43
+ # A button that may be switched off an on.
44
+ # Extended by RadioButton and checkbox.
45
+ # WARNING, pls do not override +text+ otherwise checkboxes etc will stop functioning.
46
+ # TODO: add editable here nd prevent toggling if not so.
47
+ class ToggleButton < Button
48
+ # text for on value and off value
49
+ attr_accessor :onvalue, :offvalue
50
+ # boolean, which value to use currently, onvalue or offvalue
51
+ attr_accessor :value
52
+ # characters to use for surround, array, default square brackets
53
+ attr_accessor :surround_chars
54
+ # 2018-04-02 - removing variable
55
+ #attr_accessor :variable # value linked to this variable which is a boolean
56
+ # background to use when selected, if not set then default
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
61
+
62
+ def initialize config={}, &block
63
+ super
64
+
65
+ #@value ||= (@variable.nil? ? false : @variable.get_value(@name)==true)
66
+ # TODO may need to do this when this is added to button_group
67
+ end
68
+ def getvalue
69
+ @value ? @onvalue : @offvalue
70
+ end
71
+
72
+ # WARNING, pls do not override +text+ otherwise checkboxes etc will stop functioning.
73
+
74
+ # added for some standardization 2010-09-07 20:28
75
+ # alias :text :getvalue # NEXT VERSION
76
+ # change existing text to label
77
+ ##
78
+ # is the button on or off
79
+ # added 2008-12-09 19:05
80
+ def checked?
81
+ @value
82
+ end
83
+ alias :selected? :checked?
84
+
85
+ def getvalue_for_paint
86
+ # when the width is set externally then the surround chars sit outside the width
87
+ #unless @width
88
+ if @onvalue && @offvalue
89
+ @width = [ @onvalue.length, @offvalue.length ].max
90
+ end
91
+ #end
92
+ buttontext = getvalue().center(@width)
93
+ @text_offset = @surround_chars[0].length
94
+ @surround_chars[0] + buttontext + @surround_chars[1]
95
+ end
96
+
97
+ # toggle button handle key
98
+ # @param [int] key received
99
+ #
100
+ def handle_key ch
101
+ if ch == 32
102
+ toggle
103
+ @repaint_required = true # need to change the label
104
+ else
105
+ super
106
+ end
107
+ end
108
+
109
+ ##
110
+ # toggle the button value
111
+ def toggle
112
+ fire
113
+ end
114
+
115
+ # called on :PRESS event
116
+ # caller should check state of itemevent passed to block
117
+ # NOTE i have not brought ItemEvent in here.
118
+ def fire
119
+ checked(!@value)
120
+ @item_event = ItemEvent.new self, self if @item_event.nil?
121
+ @item_event.set(@value ? :SELECTED : :DESELECTED)
122
+ fire_handler :PRESS, @item_event # should the event itself be ITEM_EVENT
123
+ end
124
+ ##
125
+ # set the value to true or false
126
+ # user may programmatically want to check or uncheck
127
+ def checked tf
128
+ @value = tf
129
+ =begin
130
+ if @variable
131
+ if @value
132
+ @variable.set_value((@onvalue || 1), @name)
133
+ else
134
+ @variable.set_value((@offvalue || 0), @name)
135
+ end
136
+ end
137
+ =end
138
+ end
139
+ end # class
140
+ end # module
@@ -0,0 +1,3 @@
1
+ module Umbra
2
+ VERSION = "0.1.0"
3
+ end