Class: RubyCurses::StackFlow

Inherits:
Widget
  • Object
show all
Includes:
BorderTitle, ModStack
Defined in:
lib/rbcurse/experimental/widgets/stackflow.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(form = nil, config = {}, &block) ⇒ StackFlow

Returns a new instance of StackFlow.



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 58

def initialize form=nil, config={}, &block
  @suppress_borders = false
  @row_offset = @col_offset = 1
  @_events ||= []
  @focusable = true
  @editable = false
  @components = [] # all components
  @focusables = [] # focusable components, makes checks easier
  @active     = []
  super

  init_vars
end

Instance Attribute Details

#componentsObject (readonly)

Returns the value of attribute components.



56
57
58
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 56

def components
  @components
end

#current_componentObject (readonly)

should container stack objects ignoring users row col this is esp needed since App sets row and col which is too early This is now the default value, till i can redo things dsl_accessor :stack



55
56
57
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 55

def current_component
  @current_component
end

Instance Method Details

#decrease_currentObject



419
420
421
422
423
424
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 419

def decrease_current
  c = @current_component
  p = c.config[:parent]
  $log.debug "XXX: INC increase current #{c} , #{p} "
  p.decrease c
end

#goto_component(comp) ⇒ Object

set focus on given component Sometimes you have the handle to component, and you want to move focus to it



406
407
408
409
410
411
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 406

def goto_component comp
  return if comp == @current_component
  leave_current_component
  @current_component = comp
  set_form_row
end

#goto_next_componentObject



321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 321

def goto_next_component
  if @current_component != nil 
    leave_current_component
    if on_last_component?
      #@_entered = false
      return :UNHANDLED
    end
    @current_index = @focusables.index(@current_component)
    index = @current_index + 1
    f = @focusables[index]
    if f
      @current_index = index
      @current_component = f
      return set_form_row
    end
  end
  @_entered = false
  return :UNHANDLED
end

#goto_prev_componentObject



340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 340

def goto_prev_component
  if @current_component != nil 
    leave_current_component
    if on_first_component?
      @_entered = false
      return :UNHANDLED
    end
    @current_index = @focusables.index(@current_component)
    index = @current_index -= 1
    f = @focusables[index]
    if f
      @current_index = index
      @current_component = f
      return set_form_row
    end
  end
  return :UNHANDLED
end

#handle_key(ch) ⇒ Object

called by parent or form, otherwise its private



230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 230

def handle_key ch
  $log.debug " STACKFLOW handle_key #{ch} "
  return if @components.empty?
  _multiplier = ($multiplier == 0 ? 1 : $multiplier )

  # should this go here 2011-10-19 
  unless @_entered
    $log.warn "XXX WARN: calling ON_ENTER since in this situation it was not called"
    on_enter
  end
  if ch == KEY_TAB
    $log.debug "STACKFLOW GOTO NEXT TAB"
    return goto_next_component
  elsif ch == KEY_BTAB
    return goto_prev_component
  end
  comp = @current_component
  $log.debug " STACKFLOW handle_key #{ch}: #{comp}" 
  if comp
    ret = comp.handle_key(ch) 
    $log.debug " STACKFLOW handle_key#{ch}: #{comp} returned #{ret} " 
    if ret != :UNHANDLED
      comp.repaint # NOTE: if we don;t do this, then it won't get repainted. I will have to repaint ALL
      # in repaint of this.
      return ret 
    end
    $log.debug "XXX STACKFLOW key unhandled by comp #{comp.name} "
  else
    $log.warn "XXX STACKFLOW key unhandled NULL comp"
  end
  case ch
  when ?\C-c.getbyte(0)
    $multiplier = 0
    return 0
  when ?0.getbyte(0)..?9.getbyte(0)
    $log.debug " VIM coming here to set multiplier #{$multiplier} "
    $multiplier *= 10 ; $multiplier += (ch-48)
    return 0
  end
  ret = process_key ch, self
  # allow user to map left and right if he wants
  if ret == :UNHANDLED
    case ch
    when KEY_UP
      # form will pick this up and do needful
      return goto_prev_component #unless on_first_component?
    when KEY_LEFT
      # if i don't check for first component, key will go back to form,
      # but not be processes. so focussed remain here, but be false.
      # In case of returnign an unhandled TAB, on_leave will happen and cursor will move to 
      # previous component outside of this.
      return goto_prev_component unless on_first_component?
    when KEY_RIGHT
      return goto_next_component #unless on_last_component?
    when KEY_DOWN
      return goto_next_component #unless on_last_component?
    else 
      @_entered = false
      return :UNHANDLED
    end
  end

  $multiplier = 0
  return 0
end

#increase_currentObject



413
414
415
416
417
418
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 413

def increase_current
  c = @current_component
  p = c.config[:parent]
  $log.debug "XXX: INC increase current #{c} , #{p} "
  p.increase c
end

#init_varsObject



71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 71

def init_vars
  @repaint_required = true
  @row_offset = @col_offset = 0 if @suppress_borders 
  @ctr = 0

  @internal_width = 2
  @internal_width = 1 if @suppress_borders
  @name ||= "a_stackflow"
  bind_key(?\M-1, :increase_current)
  bind_key(?\M-2, :decrease_current)
  #raise "NO components !" if @components.empty?
  calc_weightages2(@components, self) # FIXME this needs to move to basestack

end

#leave_current_componentObject

leave the component we are on. This should be followed by all containers, so that the on_leave action of earlier comp can be displayed, such as dimming components selections



382
383
384
385
386
387
388
389
390
391
392
393
394
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 382

def leave_current_component
  begin
    @current_component.on_leave
  rescue FieldValidationException => fve
    alert fve.to_s
  end
  # NOTE this is required, since repaint will just not happen otherwise
  # Some components are erroneously repainting all, after setting this to true so it is 
  # working there. 
  @current_component.repaint_required true
  $log.debug " after on_leave STACKFLOW XXX #{@current_component.focussed}   #{@current_component.name}"
  @current_component.repaint
end

#on_enterObject

Actually we should only go to current component if it accepted a key stroke. if user tabbed thru it, then no point going back to it. Go to first or last depending on TAB or BACKTAB otherwise. NOTE: if user comes in using DOWN or UP, last traversed component will get the focus



300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 300

def on_enter
  # if BTAB, the last comp XXX they must be focusable FIXME
  if $current_key == KEY_BTAB || $current_key == KEY_UP
    @current_component = @focusables.last
  elsif $current_key == KEY_TAB || $current_key == KEY_DOWN
    @current_component = @focusables.first
  else
    # let current component be, since an unhandled key may have resulted
    #  in on_enter being called again
  end
  return unless @current_component
  $log.debug " STACKFLOW came to ON_ENTER #{@current_component} "
  set_form_row
  @_entered = true
end

#on_first_component?Boolean

is focus on first component FIXME check for focusable

Returns:

  • (Boolean)


397
398
399
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 397

def on_first_component?
  @current_component == @focusables.first
end

#on_last_component?Boolean

is focus on last component FIXME check for focusable

Returns:

  • (Boolean)


401
402
403
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 401

def on_last_component?
  @current_component == @focusables.last
end

#on_leaveObject

we cannot be sure that this will be called especially if this is embedded inside some other component



317
318
319
320
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 317

def on_leave
  @_entered = false
  super
end

#repaintObject

repaint object called by Form, and sometimes parent component (if not form).



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 140

def repaint # stackflow
  my_win = @form ? @form.window : @target_window
  @graphic = my_win unless @graphic
  raise " #{@name} NO GRAPHIC set as yet                 STACKFLOW paint " unless @graphic
  # actually at this level we don't have margins set -- not yet.
  @margin_left   ||= 0
  @margin_right  ||= 0
  @margin_top    ||= 0
  @margin_bottom ||= 0
  r  = @row + @row_offset + @margin_top
  c  = @col + @col_offset + @margin_left
  ht = @height-2-(@margin_top + @margin_bottom)
  wd = @width -2-(@margin_left + @margin_right)
  # should this not happen only if repaint_required ?
  @components.each { |e| 
    e.parent_component = self
    e.row              = r
    e.col              = c
    # check that we are not trying to print outside bounds
    # by default we are stacking top level comps regardless of stack or flow
    #  otherwise too complicated
    if e.is_a? BaseStack 
      # using ||= allows us to use overrides given by user
      # but disallows us from calculating if size changes
        e.height           = (ht) * (e.weight * 0.01)
        e.height           = e.height.round 
        e.width            = wd 
        if e.row + e.height >= @row + @height
          #alert "is exceeding #{e.row} #{e.height} > #{@row} + #{@height} "
          e.height = @height - e.row - 1
        end
        r += e.height
        $log.debug "XXX: STACK r:#{e.row} e.h: #{e.height} w:#{e.weight} h: #{@height} "
      #if e.type == :flow
        #e.height           ||= (@height-2) * (e.weight * 0.01)
        #e.height           = e.height.round
        #e.width            ||= (@width-2) 
        #r += e.height
      #elsif e.type == :stack
        #e.width            ||= (@width-2) * (e.weight * 0.01)
        #e.width            = e.width.round
        #e.height           ||= (@height-2)
        #c += e.width
      #end
    end
    check_coords e
    attach_form e unless e.form
  } # seeme one if printing out
  last = @components.last
  if last.row + last.height < @row + @height
    last.height += 1 # @row + @height - last.row + last.height
  end

  # if some major change has happened then repaint everything
  # if multiple components then last row and col needs to be stored or else overlap will happen FIXME
  if @repaint_required
    $log.debug " STACKFLOW repaint graphic #{@graphic}, size:#{@components.size} "
    print_borders unless @suppress_borders # do this once only, unless everything changes
    @components.each { |e| e.repaint_all(true); e.repaint }
  else
    @components.each { |e| e.repaint }
  end # if repaint_required

  @repaint_required = false
end

#set_form_colObject



376
377
378
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 376

def set_form_col
  # override widget
end

#set_form_rowObject

private XXX why are we calling 3 methods in a row, why not OE manages these 3 There’s double calling going on.



361
362
363
364
365
366
367
368
369
370
371
372
373
374
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 361

def set_form_row
  return :UNHANDLED if @current_component.nil?
  cc = @current_component
  $log.debug "STACKFLOW #{@name} set_form_row calling sfr for #{cc.name}, r #{cc.row} c: #{cc.col} "
  $log.debug " STACKFLOW on enter sfr #{@current_component.name}  #{@current_component} "

  @current_component.on_enter
  @current_component.set_form_row # why was this missing in vimsplit. is it
  $log.debug "STACKFLOW #{@name} set_form_row calling sfr for #{cc.name}, r #{cc.row} c: #{cc.col} "
  # that on_enter does a set_form_row
  @current_component.set_form_col # XXX 
  @current_component.repaint # OMG this could happen before we've set row and col
  # XXX compo should do set_form_row and col if it has that
end

#widgetsObject



133
# File 'lib/rbcurse/experimental/widgets/stackflow.rb', line 133

def widgets; @components; end