Class: RubyCurses::ScrollForm

Inherits:
Form
  • Object
show all
Defined in:
lib/rbcurse/experimental/widgets/rscrollform.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(win, &block) ⇒ ScrollForm

Returns a new instance of ScrollForm.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 41

def initialize win, &block
  @target_window = win
  super
  @pminrow = @pmincol = 0
  @row_offset = @col_offset = 0
  @scroll_unit = 3
  @cols_panned = @rows_panned = 0
  @repaint_all = true

  # take display dimensions from window. It is safe to override immediately after form creation
  @display_h = win.height
  @display_w = win.width
  if @display_h == 0
    @display_h = (Ncurses.LINES - win.top - 2)
  else
    @display_h = win.height - 2
  end
  if @display_w == 0
    @display_w = (Ncurses.COLS - win.left - 2) 
  else
    # copywin fails unless u use rootwindow, so what gives in this case
    @display_w = win.width - 2
  end
  
  init_vars
end

Instance Attribute Details

#col_offsetObject

attr_accessor :display_w # width of screen display NOW METHODS attr_accessor :display_h # ht of screen display



35
36
37
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 35

def col_offset
  @col_offset
end

#cols_pannedObject (readonly)

Returns the value of attribute cols_panned.



40
41
42
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 40

def cols_panned
  @cols_panned
end

#nameObject

Returns the value of attribute name.



39
40
41
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 39

def name
  @name
end

#orig_leftObject (readonly)

Returns the value of attribute orig_left.



37
38
39
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 37

def orig_left
  @orig_left
end

#orig_topObject (readonly)

Returns the value of attribute orig_top.



37
38
39
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 37

def orig_top
  @orig_top
end

#pmincolObject

the pad prints from this col to window



30
31
32
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 30

def pmincol
  @pmincol
end

#pminrowObject

the pad prints from this row to window, usually 0



32
33
34
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 32

def pminrow
  @pminrow
end

#row_offsetObject

attr_accessor :display_w # width of screen display NOW METHODS attr_accessor :display_h # ht of screen display



35
36
37
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 35

def row_offset
  @row_offset
end

#rows_pannedObject (readonly)

Returns the value of attribute rows_panned.



40
41
42
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 40

def rows_panned
  @rows_panned
end

#scroll_unitObject

by how much should be scroll



36
37
38
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 36

def scroll_unit
  @scroll_unit
end

#windowObject (readonly)

Returns the value of attribute window.



38
39
40
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 38

def window
  @window
end

Instance Method Details

#_print_more_columns_marker(tf) ⇒ Object

XXX needs to be called from repaint and print_border

Parameters:

  • should (boolean)

    marker be printed or not



396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 396

def _print_more_columns_marker tf
  tf = false
  if @pmincol + @display_w < @pad_w
    tf = true
  end
  marker = tf ?  Ncurses::ACS_CKBOARD : Ncurses::ACS_HLINE
  h = @display_h; w = @display_w
  r = @orig_top
  c = @orig_left
  @target_window.mvwaddch r+h, c+w-2, marker
  #
  # show if columns to left or not
  marker = @pmincol > 0 ?  Ncurses::ACS_CKBOARD : Ncurses::ACS_HLINE
  @target_window.mvwaddch r+h, c+1, marker
end

#_print_more_data_marker(tf) ⇒ Object

XXX needs to be called from repaint and print_border

Parameters:

  • should (boolean)

    marker be printed or not



377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 377

def _print_more_data_marker tf
  tf = false
  # the bottom marker meaning there's more data below
  if @pminrow + @display_h < @pad_h
    tf = true
  end
  marker = tf ?  Ncurses::ACS_CKBOARD : Ncurses::ACS_VLINE
  h = @display_h; w = @display_w
  r = @orig_top
  c = @orig_left
  $log.debug " more data #{r+h-1}, #{c+w-1} : row #{r} h #{h} w #{w} col #{c} "
  @target_window.mvwaddch r+h-1, c+w-0, marker
  # the top marker to show that there is data above
  marker = @pminrow > 0 ?  Ncurses::ACS_CKBOARD : Ncurses::ACS_VLINE
  @target_window.mvwaddch r+1, c+w-0, marker
end

#add_widget(w) ⇒ Object



322
323
324
325
326
327
328
329
330
331
332
333
334
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 322

def add_widget w
  super
  $log.debug " inside add_widget #{w.name}  pad w #{@pad_w} #{w.col}, #{@pad_h}  "
  if w.col >= @pad_w
    @pad_w += 10 # XXX currently just a guess value, we need length and maybe some extra
    @window.wresize(@pad_h, @pad_w) if @pad
  end
  if w.row >= @pad_h
    @pad_h += 10 # XXX currently just a guess value, we need length and maybe some extra
    $log.debug " SCROLL add_widget ..."
    @window.wresize(@pad_h, @pad_w) if @pad
  end
end

#create_padObject

create a pad to work on. XXX We reuse window, which is already the main window So if we try creating pad later, then old external window is used. However, many methods in superclass operate on window so we needed to overwrite. What do i do ? private



135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 135

def create_pad
  #raise "Pad already created" if @pad
  return @pad if @pad
  r = @top
  c = @left
  layout = { :height => @pad_h, :width => @pad_w, :top => r, :left => c } 
  @window = VER::Pad.create_with_layout(layout)
  
  @window.name = "Pad::ScrollPad" # 2010-02-02 20:01 
  @name = "Form::ScrollForm"
  @pad = @window
  return @window
end

#display_h(*val) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 98

def display_h(*val)
  if val.empty?
    return @display_h
  else
    #raise ArgumentError "display_h should be ... " if val[0] ...
    oldvalue = @display_h
    @display_h = val[0]
    $log.debug "XXX:given display_h to #{@display_h} "
    @display_h = [@display_h, @target_window.height - 2].min unless @target_window.height == 0
    $log.debug "XXX:set display_h to #{@display_h} "
    #fire_property_handler(:display_h, oldvalue, @display_h)
  end
  self
end

#display_w(*val) ⇒ Object

By default we are determining these 2 values based on window’s dims. However, if you use a widget that is smaller than the window, then you will want to overwrite these values.



116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 116

def display_w(*val)
  if val.empty?
    return @display_w
  else
    #raise ArgumentError "display_h should be ... " if val[0] ...
    oldvalue = @display_w
    @display_w = val[0]
    @display_w = [@display_w, @target_window.width - 2].min unless @target_window.width == 0
    $log.debug "XXX:set display_w to #{@display_w} "
    #fire_property_handler(:display_h, oldvalue, @display_h)
  end
  self
end

#first_visible_component_indexindex, -1

returns index of first visible component. Currently using column index I am doing this for horizontal scrolling presently

Returns:

  • (index, -1)

    -1 if none visible, else index/offset



350
351
352
353
354
355
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 350

def first_visible_component_index
  @widgets.each_with_index do |w, ix|
    return ix if visible?(w) and focusable?(w)
  end
  return -1
end

#focusable?(w) ⇒ Boolean

Returns:

  • (Boolean)


371
372
373
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 371

def focusable?(w)
  w.focusable and visible?(w)
end

#init_varsObject



67
68
69
70
71
72
73
74
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 67

def init_vars
  # maybe we should use C-x combinations rather than these keys which might be used
  #  by other widgets, apps
  bind_key(?\M-h, :scroll_left)
  bind_key(?\M-l, :scroll_right)
  bind_key(?\M-n, :scroll_down)
  bind_key(?\M-p, :scroll_up)
end

#last_visible_component_indexObject



356
357
358
359
360
361
362
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 356

def last_visible_component_index
  ret = -1
  @widgets.each_with_index do |w, ix|
    ret = ix if visible?(w) and focusable?(w)
  end
  return ret
end

#prefreshObject

refresh pad onto window I am now copying onto main window, else prefresh has funny effects



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
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 235

def prefresh
  ## reduce so we don't go off in top+h and top+w
  $log.debug "  start ret = @buttonpad.prefresh( #{@pminrow} , #{@pmincol} , #{@top} , #{@left} , top + #{@display_h} left + #{@display_w} ) "
  if @pminrow + @display_h > @orig_top + @pad_h
    $log.debug " if #{@pminrow} + #{@display_h} > #{@orig_top} +#{@pad_h} "
    $log.debug " ERROR 1 "
    #return -1
  end
  if @pmincol + @display_w > @orig_left + @pad_w
  $log.debug " if #{@pmincol} + #{@display_w} > #{@orig_left} +#{@pad_w} "
    $log.debug " ERROR 2 "
    return -1
  end
  # actually if there is a change in the screen, we may still need to allow update
  # but ensure that size does not exceed
  if @top + @display_h > @orig_top + @pad_h
  $log.debug " if #{@top} + #{@display_h} > #{@orig_top} +#{@pad_h} "
    $log.debug " ERROR 3 "
    return -1
  end
  if @left + @display_w > @orig_left + @pad_w
  $log.debug " if #{@left} + #{@display_w} > #{@orig_left} +#{@pad_w} "
    $log.debug " ERROR 4 "
    return -1
  end
  # maybe we should use copywin to copy onto @target_window
  $log.debug "   ret = @window.prefresh( #{@pminrow} , #{@pmincol} , #{@top} , #{@left} , #{@top} + #{@display_h}, #{@left} + #{@display_w} ) "
  omit = 0
  # this works but if want to avoid copying border
  #ret = @window.prefresh(@pminrow, @pmincol, @top+@row_offset, @left+@col_offset, @top + @display_h - @row_offset , @left + @display_w - @col_offset)
  #
  $log.debug "ret = @window.copywin( #{@pminrow} , #{@pmincol} , #{@top+@row_offset} , #{@left+@col_offset} , #{@top} + #{@display_h} - #{@row_offset} , #{@left} + #{@display_w} - #{@col_offset} ,  0)"
  ## Haha , we are back to the old notorious copywin which has given mankind
  # so much grief that it should be removed in the next round of creation.
  ret = @window.copywin(@target_window.get_window, @pminrow, @pmincol, @top+@row_offset, @left+@col_offset, 
        @top + @display_h - @row_offset , @left + @display_w - @col_offset,  0)

  $log.debug " copywin ret = #{ret} "
end

print a border on the main window, just for kicks



205
206
207
208
209
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 205

def print_border
  $log.debug " SCROLL print_border ..."
  #@window.print_border_only(@top-@rows_panned, @left+@cols_panned, @display_h, @display_w, $datacolor)
  @target_window.print_border_only(@top, @left, @display_h, @display_w+1, $datacolor)
end


210
211
212
213
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 210

def print_footer
  footer = "Lines %d-%d (%d)  Cols %d-%d (%d) " % [ @pminrow, @pminrow + @display_h, @orig_top + @pad_h, @pmincol, @pmincol + @display_w, @orig_left + @pad_w ] 
  @target_window.printstring(@top +@display_h, @left + 3, footer, $datacolor)
end

#repaintObject

XXX what if we want a static area at bottom ? maybe we should rename targetwindow to window

and window to pad
super may need target window


218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 218

def repaint
  print_border if @repaint_all and @print_border_flag
  print_footer if @print_border_flag
  $log.debug " scrollForm repaint calling parent #{@row} #{@col}+ #{@cols_panned} #{@col_offset} "
  super
  prefresh
  if @print_border_flag
    _print_more_data_marker true
    _print_more_columns_marker true
  end
  #$log.debug " @target_window.wmove #{@row+@rows_panned+@row_offset}, #{@col+@cols_panned+@col_offset}  "
  @target_window.wmove @row+@rows_panned+@row_offset, @col+@cols_panned+@col_offset
  @window.modified = false
  @repaint_all = false
end

#req_first_fieldObject



363
364
365
366
367
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 363

def req_first_field
  index = first_visible_component_index
  ret = select_field(index)
  return ret
end

#req_last_fieldObject



368
369
370
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 368

def req_last_field
  select_field(last_visible_component_index)
end

#scroll_downObject



178
179
180
181
182
183
184
185
186
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 178

def scroll_down
  s = @scroll_unit + $multiplier; $multiplier = 0
  return false if !validate_scroll_row(@pminrow + s)
  @pminrow += s # some check is required or we'll crash
  @rows_panned -= s
  @window.modified = true
  #@repaint_all = true
  return 0
end

#scroll_leftObject

validate fails once unit + mult > 1. Then it won’t go further unit should be one by default.



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 163

def scroll_left
  s = @scroll_unit + $multiplier
  $log.debug " scroll_left #{s} m: #{$multiplier} "
  $multiplier = 0
  #return false if !validate_scroll_col(@pmincol - s)
  if !validate_scroll_col(@pmincol - s)
    @pmincol = 0
    @cols_panned  = 0 
  else
    @pmincol -= s # some check is required or we'll crash
    @cols_panned += s
  end
  @window.modified = true
  return 0
end

#scroll_rightObject



149
150
151
152
153
154
155
156
157
158
159
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 149

def scroll_right
  s = @scroll_unit + $multiplier
  $log.debug " scroll_right #{s} m: #{$multiplier} "
  $multiplier = 0
  return false if !validate_scroll_col(@pmincol + s)
  @pmincol += s # some check is required or we'll crash
  @cols_panned -= s
  $log.debug " handled ch M-l in ScrollForm"
  @window.modified = true
  return 0
end

#scroll_upObject



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 187

def scroll_up
  s = @scroll_unit + $multiplier; $multiplier = 0
  $log.debug " scroll_up #{s} "
  #return false if !validate_scroll_row(@pminrow - s)
  if !validate_scroll_row(@pminrow - s)
    @pminrow = 0
    @rows_panned = 0
    $log.debug " !valid #{@pminrow} "
  else
    @pminrow -= s # some check is required or we'll crash
    @rows_panned += s
    $log.debug " valid #{@pminrow} "
  end
  @window.modified = true
  #@repaint_all = true
  return 0
end

#set_layout(h, w, t, l) ⇒ Object

Deprecated.

use set_pad_dimensions

old program tabbed pane uses this. fix



95
96
97
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 95

def set_layout h,w,t,l
  set_pad_dimensions t,l,h,w
end

#set_pad_dimensions(t, l, h, w) ⇒ Object

This is how we set size of pad and where it prints on screen This is all that’s needed after constructor.

Parameters:

  • t (Fixnum)

    top (row on screen to print pad on)

  • l (Fixnum)

    left (col on screen to print)

  • h (Fixnum)

    height (how many lines in Pad, usually more that screens actual height)

  • w (Fixnum)

    width (how many cols in Pad, often more than screens width)



86
87
88
89
90
91
92
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 86

def set_pad_dimensions(t, l, h, w )
  @pad_h = h
  @pad_w = w
  @top = @orig_top = t
  @left = @orig_left = l
  create_pad
end

#should_print_border(flag = true) ⇒ Object



75
76
77
78
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 75

def should_print_border flag=true
  @print_border_flag = flag
  @row_offset = @col_offset = 1
end

#visible?(component) ⇒ Boolean

Is a component visible, typically used to prevent traversal into the field

Returns:

  • (Boolean)


337
338
339
340
341
342
343
344
345
346
# File 'lib/rbcurse/experimental/widgets/rscrollform.rb', line 337

def visible? component
  r, c = component.rowcol
  return false if c+@cols_panned < @orig_left
  return false if c+@cols_panned > @orig_left + @display_w
  # XXX TODO for rows UNTESTED for rows
  return false if r + @rows_panned < @orig_top
  return false if r + @rows_panned > @orig_top + @display_h - 2

  return true
end