Module: Canis::WidgetShortcuts

Included in:
App
Defined in:
lib/canis/core/util/widgetshortcuts.rb,
lib/canis/core/util/oldwidgetshortcuts.rb

Defined Under Namespace

Classes: Ws, WsFlow, WsStack

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.def_widget(path, klass, short = nil) ⇒ Object

create a shortcut for a class path is path of file to use in require starting with canis klass is name of class to instantiate



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/canis/core/util/widgetshortcuts.rb', line 89

def self.def_widget(path, klass, short=nil)
  p=""
   if path
    p="require \"#{path}\""
  end
   short ||= klass.to_s.downcase
    eval %{
      def #{short}(config={}, &block)
        if config.is_a? String
           _s = config
           config = {}
           config[:text] = _s
        end
        #{p}
        w = #{klass}.new nil, config
        _position w
        w.command &block if block_given?
        return w
      end
    }
end

Instance Method Details

#_configure(s) ⇒ Object

This configures a stack or flow not the objects inside



469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
# File 'lib/canis/core/util/widgetshortcuts.rb', line 469

def _configure s
  s[:row] ||= 0
  s[:col] ||= 0
  s[:row] += (s[:margin_top] || 0)
  s[:col] += (s[:margin_left] || 0)
  s[:width] = FFI::NCurses.COLS-s[:col] if s[:width] == :expand
  s[:height] = FFI::NCurses.LINES-s[:row] if s[:height] == :expand # 2011-11-30 
  last = @_ws_active.last
  if last
    if s[:width_pc]
      if last.is_a? WsStack
        s[:width] =           (last[:width] * (s[:width_pc].to_i * 0.01)).floor
      else
        # i think this width is picked up by next stack in this flow
        last[:item_width] =   (last[:width] * (s[:width_pc].to_i* 0.01)).floor
      end
    end
    if s[:height_pc]
      if last.is_a? WsFlow
        s[:height] =       ( (last[:height] * s[:height_pc].to_i)/100).floor
      else
        # this works only for flows within stacks not for an object unless
        # you put a single object in a flow
        s[:item_height] =  ( (last[:height] * s[:height_pc].to_i)/100).floor
      end
        #alert "item height set as #{s[:height]} for #{s} "
    end
    if last.is_a? WsStack
      s[:row] += (last[:row] || 0)
      s[:col] += (last[:col] || 0)  
    else
      s[:row] += (last[:row] || 0)
      s[:col] += (last[:col] || 0)  # we are updating with item_width as each st finishes
      s[:width] ||= last[:item_width] # 
    end
  else
    # this should be outer most flow or stack, if nothing mentioned
    # trying this out
    s[:width] ||= :expand
    s[:height] ||= :expand
    s[:width] = FFI::NCurses.COLS-s[:col] if s[:width] == :expand
    s[:height] = FFI::NCurses.LINES-s[:row] if s[:height] == :expand # 2011-11-30 
  end
  s[:components] = []
end

#_position(w) ⇒ Object

— }}}



295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
# File 'lib/canis/core/util/widgetshortcuts.rb', line 295

def _position w
  if @_ws_active.nil? || @_ws_active.empty?
    # no stack or flow, this is independent usage, or else we are outside stacks and flows
    #
    # this is outside any stack or flow, so we do the minimal
    # user should specify row and col
    w.row ||= 0
    w.col ||= 0
    #$log.debug "XXX:  LABEL #{w.row} , #{w.col} "
    w.set_form @form if @form # temporary,, only set if not inside an object FIXME
    if w.width == :expand  # calculate from current col, not 0 FIXME
      w.width = FFI::NCurses.COLS-w.col # or take windows width since this could be in a message box
    end
    if w.height == :expand
      # take from current row, and not zero  FIXME
      w.height = FFI::NCurses.LINES-w.row # or take windows width since this could be in a message box
    end
    return

  end
  # -------------------------- there is a stack or flow -------------------- #
  #
  cur = @_ws_active.last
  unless cur
    raise "This should have been handled previously.Somethings wrong, check/untested"
  end
  r = cur[:row] || 0
  c = cur[:col] || 0
  w.row = r
  w.col = c
  # if flow then take flows height, else use dummy value
  if w.height_pc
    w.height =       ( (cur[:height] * w.height_pc.to_i)/100).floor
  end
  if w.height == :expand
    if cur.is_a? WsFlow
      w.height = cur[:height] || 8 #or raise "height not known for flow"
    else
      w.height = cur[:item_height] || 8 #or raise "height not known for flow"
    end
    #alert "setting ht to #{w.height}, #{cur[:height]} , for #{cur} "
  end
  if w.width == :expand
    if cur.is_a? WsFlow
      if cur[:item_width]
        w.width = cur[:item_width] #or raise "item_Width not known for flow #{cur.class}, #{cur[:item_width]}, #{cur[:width]} , #{w.width_pc}  "
      elsif w.width_pc
        #w.width = w.width_pc * cur[:width]
        w.width = (cur[:width] * (w.width_pc.to_i * 0.01)).floor
      else
        w.width = cur[:width] 
      end
      raise "width could not be calculated. i need flow width and item width_pc" if w.width == :expand
    else
      w.width = cur[:width] or raise "Width not known for stack #{cur.class}, #{cur[:width]} "
    end
  end
  if cur.is_a? WsStack
    r += w.height || 1   # NOTE, we need to have height for this purpose defined BEFORE calling for list/text
    cur[:row] = r
  else
    wid = cur[:item_width] || w.width || 10
    c += wid + 1
    cur[:col] = c
  end
  #alert "set width to #{w.width} ,cur: #{cur[:width]} ,iw: #{cur[:item_width]} "
  if cur.is_a? WsFlow
    unless w.height
      w.height = cur[:height] #or raise "Height not known for flow"
    end
  end
  w.color   ||= cur[:color]
  w.bgcolor ||= cur[:bgcolor]
  w.set_form @form if @form # temporary
  @_ws_components << w
  cur[:components] << w
end

#app_header(title, config = {}, &block) ⇒ Object

add a standard application header

Example

header = app_header "canis ", :text_center => "Browser Demo", :text_right =>"New Improved!", 
     :color => :black, :bgcolor => :white, :attr => :bold


126
127
128
129
# File 'lib/canis/core/util/widgetshortcuts.rb', line 126

def app_header title, config={}, &block
  require 'canis/core/widgets/applicationheader'
  header = ApplicationHeader.new @form, title, config, &block
end

#blankObject

— shortcuts {{{



53
54
55
# File 'lib/canis/core/util/widgetshortcuts.rb', line 53

def blank
  label :text => ""
end

#box(config = {}, &block) ⇒ Object

flow and stack could have a border option



427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
# File 'lib/canis/core/util/widgetshortcuts.rb', line 427

def box config={}, &block
  require 'canis/core/widgets/box'
  # take current stacks row and col
  # advance row by one and col by one
  # at end note row and advance by one
  # draw a box around using these coordinates. width should be
  # provided unless we have item width or something.
  @_ws_active ||= []
  last = @_ws_active.last
  if last
    r = last[:row]
    c = last[:col]
    config[:row] = r
    config[:col] = c
    last[:row] += config[:margin_top] || 1
    last[:col] += config[:margin_left] || 1
    _box = Box.new @form, config # needs to be created first or will overwrite area after others painted
    yield_or_eval &block if block_given?
    # FIXME last[height] needs to account for row
    h = config[:height] || last[:height] || (last[:row] - r)
    h = 2 if h < 2
    w = config[:width] || last[:width] || 15 # tmp
    case last
    when WsFlow
      w = last[:col]
    when WsStack
      #h += 1
    end
    config[:row] = r
    config[:col] = c
    config[:height] = h
    config[:width] = w
    _box.row r
    _box.col c
    _box.height h
    _box.width w
    last[:row] += 1
    last[:col] += 1 # ??? XXX if flow we need to increment properly or not ?
  end
end

#button(config = {}, &block) ⇒ Object



84
85
86
87
88
89
90
91
# File 'lib/canis/core/util/oldwidgetshortcuts.rb', line 84

def button config={}, &block
  w = Button.new nil, config #, &block
  _position w
  if block
    w.bind(:PRESS, &block)
  end
  return w
end

#check(config = {}, &block) ⇒ Object

horizontal line TODO row = config || @app_row width = config || 20 _position config col = config || 1 @window.attron(Ncurses.COLOR_PAIR(@color_pair) | @attrib) @window.mvwhline( row, col, FFI::NCurses::ACS_HLINE, width) @window.attron(Ncurses.COLOR_PAIR(@color_pair) | @attrib)



76
77
78
79
80
81
82
83
# File 'lib/canis/core/util/oldwidgetshortcuts.rb', line 76

def check config={}, &block
  w = CheckBox.new nil, config #, &block
  _position w
  if block
    w.bind(:PRESS, &block)
  end
  return w
end

#dock(labels, config = {}, &block) ⇒ Object

prints pine-like key labels



198
199
200
201
# File 'lib/canis/core/util/widgetshortcuts.rb', line 198

def dock labels, config={}, &block
  require 'canis/core/widgets/keylabelprinter'
  klp = Canis::KeyLabelPrinter.new @form, labels, config, &block
end

#field(config = {}, &block) ⇒ Object



48
49
50
51
52
53
54
55
# File 'lib/canis/core/util/oldwidgetshortcuts.rb', line 48

def field config={}, &block 
  w = Field.new nil, config #, &block
  _position w
  if block
    w.bind(:CHANGED, &block)
  end
  return w
end

#flow(config = {}, &block) ⇒ Object

item_width - width to use per item

but the item width may apply to stacks inside not to items


403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
# File 'lib/canis/core/util/widgetshortcuts.rb', line 403

def flow config={}, &block
  s = WsFlow.new config
  @_ws_active ||= []
  _configure s
  @_ws_active << s
  yield_or_eval &block if block_given?
  @_ws_active.pop 
  last = @_ws_active.last
  if last 
    case last
    when WsStack
      if s[:height]
        last[:row] += s[:height] 
      else
        #last[:row] += last[:highest_row]  
        last[:row] += 1
      end
    when WsFlow
      last[:col] += last[:item_width] || 0 
    end
  end
end

#label(config = {}, &block) ⇒ Object



56
57
58
59
60
# File 'lib/canis/core/util/oldwidgetshortcuts.rb', line 56

def label config={}, &block 
  w = Label.new nil, config, &block
  _position w
  return w
end

#line(config = {}) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/canis/core/util/widgetshortcuts.rb', line 56

def line config={}
  #horizontal line TODO
  #row = config[:row] || @app_row
  #width = config[:width] || 20
  #_position config
  #col = config[:col] || 1
  #@color_pair = config[:color_pair] || $datacolor
  #@attrib = config[:attrib] || Ncurses::A_NORMAL
  #@window.attron(Ncurses.COLOR_PAIR(@color_pair) | @attrib)
  #@window.mvwhline( row, col, FFI::NCurses::ACS_HLINE, width)
  #@window.attron(Ncurses.COLOR_PAIR(@color_pair) | @attrib)
end


210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/canis/core/util/widgetshortcuts.rb', line 210

def link config={}, &block
      if config.is_a? String
         _s = config
         config = {}
         config[:text] = _s
      end
  require 'canis/core/widgets/rlink'
  events = [ :PRESS,  :LEAVE, :ENTER ]
  block_event = :PRESS
  config[:highlight_color] = "yellow"
  config[:highlight_bgcolor] = "red"
  toggle = Link.new nil, config
  _position(toggle)
  if block
    toggle.bind(block_event, toggle, &block)
  end
  return toggle
end

#listbox(config = {}, &block) ⇒ Object



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/canis/core/util/widgetshortcuts.rb', line 176

def listbox config={}, &block
  require 'canis/core/widgets/listbox'
  events = [ :PRESS, :ENTER_ROW, :LEAVE, :ENTER ]
  block_event = events[0]
  #_process_args args, config, block_event, events
  #config[:width] = config[:display_length] unless config.has_key? :width
  # if no width given, expand to flows width
  #config[:width] ||= @stack.last.width if @stack.last
  useform = nil
  #useform = @form if @current_object.empty?
  #w = List.new useform, config
  w = Listbox.new useform, config
  w.width = :expand unless w.width
  w.height ||= :expand # TODO We may need to push this before _position so it can be accounted for in stack
  _position(w)
  # need to expand to stack's width or flows itemwidth if given
  if block
    w.bind(block_event, &block)
  end
  return w
end


118
119
120
121
# File 'lib/canis/core/util/widgetshortcuts.rb', line 118

def menubar &block
  require 'canis/core/widgets/rmenu'
  Canis::MenuBar.new &block
end


228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/canis/core/util/widgetshortcuts.rb', line 228

def menulink config={}, &block
      if config.is_a? String
         _s = config
         config = {}
         config[:text] = _s
      end
  require 'canis/core/widgets/rmenulink'
  events = [ :PRESS,  :LEAVE, :ENTER ]
  block_event = :PRESS
  config[:highlight_color] = "yellow"
  config[:highlight_bgcolor] = "red"
  #config[:hotkey] = true
  w = MenuLink.new nil, config
  _position(w)
  if block
    w.bind(block_event, w, &block)
  end
  return w
end

#radio(config = {}, &block) ⇒ Object

horizontal line TODO row = config || @app_row width = config || 20 _position config col = config || 1 @window.attron(Ncurses.COLOR_PAIR(@color_pair) | @attrib) @window.mvwhline( row, col, FFI::NCurses::ACS_HLINE, width) @window.attron(Ncurses.COLOR_PAIR(@color_pair) | @attrib)



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/canis/core/util/widgetshortcuts.rb', line 68

def radio config={}, &block
  a = config[:group]
  # should we not check for a nil
  if @variables.has_key? a
    v = @variables[a]
  else
    v = Variable.new
    @variables[a] = v
  end
  config[:variable] = v
  config.delete(:group)
  w = RadioButton.new nil, config #, &block
  _position w
  if block
    w.bind(:PRESS, &block)
  end
  return w
end

#stack(config = {}, &block) ⇒ Object

make it as simple as possible, don’t try to be intelligent or clever, put as much on the user



376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
# File 'lib/canis/core/util/widgetshortcuts.rb', line 376

def stack config={}, &block
  s = WsStack.new config
  @_ws_active ||= []
  _configure s
  @_ws_active << s
  yield_or_eval &block if block_given?
  @_ws_active.pop 
  
  # ---- stack is finished now
  last = @_ws_active.last
  if last 
    case last
    when WsStack
    when WsFlow
      last[:col] += last[:item_width] || 0 
      # this tries to set height of outer flow based on highest row
      # printed, however that does not account for height of object,
      # so user should give a height to the flow.
      last[:height] = s[:row] if s[:row] > (last[:height]||0)
      $log.debug "XXX: STACK setting col to #{s[:col]} "
    end
  end

end

#status_line(config = {}, &block) ⇒ Object

prints a status line at bottom where mode’s statuses et can be reflected



205
206
207
208
# File 'lib/canis/core/util/widgetshortcuts.rb', line 205

def status_line config={}, &block
  require 'canis/core/widgets/statusline'
  sl = Canis::StatusLine.new @form, config, &block
end

#table(config = {}, &block) ⇒ Object

creates a simple readonly table, that allows users to click on rows and also on the header. Header clicking is for column-sorting.



273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/canis/core/util/widgetshortcuts.rb', line 273

def table config={}, &block
#def tabular_widget config={}, &block
  require 'canis/core/widgets/table'
  events = [:PROPERTY_CHANGE, :LEAVE, :ENTER, :CHANGE, :ENTER_ROW, :PRESS ]
  block_event = nil
  # if no width given, expand to stack width
  #config.delete :title
  useform = nil

  w = Table.new useform, config # NO BLOCK GIVEN
  w.width ||= :expand 
  w.height ||= :expand # TODO This has to come before other in stack next one will overwrite.
  _position(w)
  if block_given?
    #@current_object << w
    yield_or_eval &block
    #@current_object.pop
  end
  return w
end

#textarea(config = {}, &block) ⇒ Object

editable text area



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/canis/core/util/widgetshortcuts.rb', line 132

def textarea config={}, &block
  require 'canis/core/widgets/extras/rtextarea'
  # TODO confirm events many more
  events = [ :CHANGE,  :LEAVE, :ENTER ]
  block_event = events[0]
  #_process_args args, config, block_event, events
  #config[:width] = config[:display_length] unless config.has_key? :width
  # if no width given, expand to flows width
  #config[:width] ||= @stack.last.width if @stack.last
  useform = nil
  #useform = @form if @current_object.empty?
  w = TextArea.new useform, config
  w.width = :expand unless w.width
  w.height ||= :expand # TODO This has to come before other in stack next one will overwrite.
  _position(w)
  w.height ||= 8 # TODO
  # need to expand to stack's width or flows itemwidth if given
  if block
    w.bind(block_event, &block)
  end
  return w
end

#textpad(config = {}, &block) ⇒ Object Also known as: textview



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/canis/core/util/widgetshortcuts.rb', line 154

def textpad config={}, &block
  events = [ :LEAVE, :ENTER ]
  block_event = events[0]
  #_process_args args, config, block_event, events
  #config[:width] = config[:display_length] unless config.has_key? :width
  # if no width given, expand to flows width
  #config[:width] ||= @stack.last.width if @stack.last
  useform = nil
  #useform = @form if @current_object.empty?
  #w = TextView.new useform, config
  w = TextPad.new useform, config
  w.width = :expand unless w.width
  w.height ||= :expand # TODO This has to come before other in stack next one will overwrite.
  _position(w)
  # need to expand to stack's width or flows itemwidth if given
  if block
    w.bind(block_event, &block)
  end
  return w
end

#tree(config = {}, &block) ⇒ Object



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/canis/core/util/widgetshortcuts.rb', line 247

def tree config={}, &block
  require 'canis/core/widgets/tree'
  events = [:TREE_WILL_EXPAND_EVENT,
            :TREE_EXPANDED_EVENT,
            :TREE_SELECTION_EVENT,
            :PROPERTY_CHANGE,
            :LEAVE,
            :ENTER ,
            :ENTER_ROW,
            :TREE_COLLAPSED_EVENT,
            :TREE_WILL_EXPAND_EVENT] # EXPAND double?
  block_event = :TREE_WILL_EXPAND_EVENT
  #config[:height] ||= 10
  # if no width given, expand to flows width
  useform = nil
  #useform = @form if @current_object.empty?
  w = Tree.new useform, config, &block
  w.width ||= :expand 
  w.height ||= :expand # TODO This has to come before other in stack next one will overwrite.
  _position w
  # calling the block here was causing a problem since a tree may define root etc in the block
  # containers like to define elements in a block and not have an event called by default
  return w
end

#widget_shortcuts_initObject



45
46
47
48
49
50
51
# File 'lib/canis/core/util/widgetshortcuts.rb', line 45

def widget_shortcuts_init
  @_ws_app_row = @_ws_app_col = 0
  #@_ws_active = []
  @_ws_active = nil # so we can use shortcuts if no stack used
  @_ws_components = []
  @variables = {}
end