Module: Scrollable

Included in:
RubyCurses::OldTextArea, RubyCurses::OldTextView
Defined in:
lib/rbcurse/scrollable.rb

Overview

———————- #### CAUTION: This is the worst piece of code ever written, pls do not go further. I will remove this very soon. – Shamefully yours. ———————- #### Provides the ability to scroll content, typically an array widget that includes may override on_enter_row and on_leave_row This was essentially copied and modifed from the pad scroller i think i can redo it and make it much simpler XXX

Instance Method Summary collapse

Instance Method Details

#down(num = 1) ⇒ Object

not that saving content_rows is buggy since we add rows.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/rbcurse/scrollable.rb', line 47

def down num=1
  #     $log.debug "inside down"
  num.times do 
  if @prow >= get_content().length-1
    #Ncurses.beep
    @message = "No more rows"
    return -1
  end
  if @winrow < @scrollatrow # 20
    @winrow += 1    # move cursor down
  else
    @toprow += 1    # scroll down a row
  end
  @prow += 1        # incr pad row
  end
end

#focussed_indexObject Also known as: current_index, selected_index

for user to know which row is being focussed on



211
212
213
# File 'lib/rbcurse/scrollable.rb', line 211

def focussed_index
  @prow
end

#goto_endObject



27
28
29
30
31
32
33
34
35
# File 'lib/rbcurse/scrollable.rb', line 27

def goto_end
  @prow = get_content().length-1 
  #@toprow = @prow
  #@winrow = 0     # not putting this was cause prow < toprow !!
  @toprow = @prow - @scrollatrow   # ensure screen is filled when we show last. so clear not required
  @toprow = 0 if @toprow < 0
  ## except what if very few rows
  @winrow = @scrollatrow
end

#goto_startObject

@right_margin ||= @left_margin

@scrollatrow ||= @height-2


22
23
24
25
26
# File 'lib/rbcurse/scrollable.rb', line 22

def goto_start
  @prow = 0
  @toprow = @prow
  @winrow = 0 
end

#init_scrollableObject



11
12
13
14
15
16
17
18
19
20
21
# File 'lib/rbcurse/scrollable.rb', line 11

def init_scrollable
  @toprow = @prow = @winrow = @pcol = 0
  @oldwinrow = @oldprow = @oldtoprow = 0
  @startrow = 1   # from where we start prniting, taking header row into account
  @cols = @width
  @left_margin ||= 2
  @show_focus = true if @show_focus.nil? 

#   @right_margin ||= @left_margin
#   @scrollatrow ||= @height-2
end

#leftObject

window_erase @win XXX



41
42
43
44
45
# File 'lib/rbcurse/scrollable.rb', line 41

def left
  @hscrollcols ||= @cols/2
  @pcol -= @hscrollcols if @pcol > 0
  @pcol = 0 if @pcol < 0
end

#next_match(char) ⇒ Object

2008-12-18 18:03 finds the next match for the char pressed returning the index



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/rbcurse/scrollable.rb', line 260

def next_match char
  data = get_content
  row = focussed_index
  currval = data[row].chomp
  row.upto(data.length-1) do |ix|
    val = data[ix].chomp
    if val[0,1] == char and val != currval
      return ix
    end
  end
  0.upto(row) do |ix|
    val = data[ix].chomp
    if val[0,1] == char and val != currval
      return ix
    end
  end
  return -1
end

#paintObject

call from repaint TODO i can simplif, i think

  • if user scrolls horizontally, use column as starting point



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
205
206
207
208
209
# File 'lib/rbcurse/scrollable.rb', line 155

def paint
  #$log.debug "called paint t:#{@toprow} p:#{@prow} w:#{@winrow}"
  list  = get_content
  @content_rows = list.length # rows can be added at any time
  win = get_window
  maxlen = @maxlen ||= @width-2
  if @bgcolor.is_a? String and @color.is_a? String
    acolor = ColorMap.get_color(@color, @bgcolor)
  else
    acolor = $datacolor
  end
  @color_pair = acolor
  0.upto(@height-2) {|r|
    if @toprow + r < @content_rows
      # this relates to selection of a row, as yet
      # check if any status of attribs for this row
      row_att = @list_attribs[@toprow+r] unless @list_attribs.nil?
      status = " "
      #bgcolor = $datacolor
      bgcolor = nil
      if !row_att.nil?
        status = row_att.fetch(:status, " ")
        bgcolor = row_att[:bgcolor]
      end
      # sanitize
      content = list[@toprow+r].chomp # don't display newline
      content.gsub!(/\t/, '  ') # don't display tab
      content.gsub!(/[^[:print:]]/, '')  # don't display non print characters

      #content = content[0..maxlen-1] if !content.nil? && content.length > maxlen # only show maxlen
      if !content.nil? 
        if content.length > maxlen # only show maxlen
          content = content[@pcol..@pcol+maxlen-1] 
        else
          content = content[@pcol..-1]
        end
      end

      width = @width-(@left_margin+1)
      @form.window.printstring @row+r+1, @col+@left_margin-1, "%s" % status, acolor, @attr if @implements_selectable
      @form.window.printstring  @row+r+1, @col+@left_margin, "%-*s" % [width,content], acolor, @attr
      win.mvchgat(y=r+@row+1, x=@col+@left_margin, max=width, Ncurses::A_NORMAL, bgcolor, nil) unless bgcolor.nil?
      dollar = "|"
      dollar = "$" if list[@toprow+r][-1,1]=="\r"
      @form.window.printstring  @row+r+1, @col+@width-1, dollar, acolor, @attr

    else
      # clear the displayed area
      @form.window.printstring @row+r+1, @col+@left_margin, " "*(@width-(@left_margin+1)), acolor
      dollar = "|"
      @form.window.printstring  @row+r+1, @col+@width-1, dollar, acolor, @attr
    end
  }
  show_focus if @show_focus
end

#post_keyObject

prior to repaint. but after keypress



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/rbcurse/scrollable.rb', line 108

def post_key
#    $log.debug "1 post_key w:#{@winrow} p:#{@prow} t:#{@toprow}"
@toprow = @prow if @prow < @toprow   # ensre search could be 
@toprow = @prow if @prow > @toprow + @scrollatrow   
@winrow = @prow - @toprow
#    $log.debug "2 post_key w:#{@winrow} p:#{@prow} t:#{@toprow}"
# wont work first time - added 2008-11-26 20:56 
if @oldprow != @prow
 $log.debug "going to call on leave and on enter"
  on_leave_row @oldprow if respond_to? :on_leave_row     # to be defined by widget that has included this
  on_enter_row @prow   if respond_to? :on_enter_row  # to be defined by widget that has included this
end
#@form.row =  @winrow
set_form_row

end

#pre_keyObject



102
103
104
105
106
# File 'lib/rbcurse/scrollable.rb', line 102

def pre_key
  @oldprow = @prow
  @oldtoprow = @toprow
  @oldwinrow = @winrow
end

#rightObject



36
37
38
39
40
# File 'lib/rbcurse/scrollable.rb', line 36

def right
  @hscrollcols ||= @cols/2
  @pcol += @hscrollcols if @pcol + @hscrollcols < @padcols
  #   window_erase @win XXX
end

#scroll_backwardObject



91
92
93
94
95
96
97
98
99
100
101
# File 'lib/rbcurse/scrollable.rb', line 91

def scroll_backward
  if @prow <= 0
    @message = "This is the first row"
    @prow = 0
    #next
  else
    @prow -=  (@scrollatrow+1) #(@rows-2)
    @prow = 0 if @prow < 0
  end
  @toprow = @prow
end

#scroll_forwardObject



81
82
83
84
85
86
87
88
89
90
# File 'lib/rbcurse/scrollable.rb', line 81

def scroll_forward
  if @toprow + @scrollatrow+1 >= get_content().length
    # so cursor goes to last line
    @prow +=  get_content().length - @prow - 1 # XXX 2008-11-27 14:18 
  else
    @toprow += @scrollatrow+1 # @rows-2 2008-11-13 23:41 put toprow here too
    $log.debug "space pr #{@prow}"
    @prow = @toprow
  end
end

#scrollable_handle_key(ch) ⇒ Object



220
221
222
223
224
225
226
227
228
229
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
# File 'lib/rbcurse/scrollable.rb', line 220

def scrollable_handle_key ch
  begin
    pre_key
    case ch
    when ?\C-n.getbyte(0)
      scroll_forward
    when 32
      scroll_forward
    when ?\C-p.getbyte(0)
      scroll_backward
    when ?0.getbyte(0)
      goto_start
    when ?9.getbyte(0)
      goto_end
    when ?[.getbyte(0)
    when ?[.getbyte(0)
    when KEY_UP
      #select_prev_row
      up
    when KEY_LEFT
    when KEY_RIGHT
    when KEY_DOWN
      down
      # select_next_row
    when KEY_ENTER, 10, 13
      if respond_to? :fire
        fire
      end
    when ?A.getbyte(0)..?Z.getbyte(0), ?a.getbyte(0)..?z.getbyte(0)
      ret = set_selection_for_char ch.chr
    else
      return :UNHANDLED #if ret == -1
    end
  ensure
    post_key
  end
end

#selected_itemObject

only to be used in single selection cases as focussed item FIXME.



215
216
217
# File 'lib/rbcurse/scrollable.rb', line 215

def selected_item
  get_content()[focussed_index()]
end

#set_focus_on(arow) ⇒ Object

2008-12-18 18:05 set focus on given index



288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/rbcurse/scrollable.rb', line 288

def set_focus_on arow
  return if arow > get_content().length-1 or arow < 0
  total = get_content().length
  @prow = arow
  sar = @scrollatrow + 1
  @toprow = (@prow / sar) * sar

  if total - @toprow < sar
    @toprow = (total - sar) 
  end
  @winrow = @prow - @toprow
end

#set_selection_for_char(char) ⇒ Object

2008-12-18 18:03 sets the selection to the next row starting with char



280
281
282
283
284
# File 'lib/rbcurse/scrollable.rb', line 280

def set_selection_for_char char
  ix = next_match char
  @prow = ix if ix != -1
  return ix
end

#show_focusObject

unfocus the previous row cursor was on and put focus on currrent row Called after repaint



147
148
149
150
151
# File 'lib/rbcurse/scrollable.rb', line 147

def show_focus
  show_focus_on_row(@oldwinrow, @oldprow, false)
  show_focus_on_row(@winrow, @prow, true)
  # printstr @form.window, 23, 10, @prow
end

#show_focus_on_row(row0, _prow, tf = true) ⇒ Object

caution, this now uses winrow not prow



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/rbcurse/scrollable.rb', line 126

def show_focus_on_row row0, _prow, tf=true
 # color = tf ? $reversecolor : $datacolor
  # if cursor on row, reverse else normal
  attr = tf ? Ncurses::A_REVERSE : Ncurses::A_NORMAL
  color = @color_pair
  r = row0+1 
  #check if row is selected or not
  row_att = @list_attribs[_prow] unless @list_attribs.nil?
  if !row_att.nil?
    status = row_att.fetch(:status, " ")
    attr1 = row_att[:bgcolor] 
    color = attr1 unless attr1.nil?
  end
  @datawidth ||= @width-2
  return if r > get_content().length
  @form.window.mvchgat(y=r+@row, x=1+@col, max=@datawidth, attr, color, nil)
end

#up(num = 1) ⇒ Object

UP



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/rbcurse/scrollable.rb', line 63

def up num=1  # UP
  num.times do
  if @prow <= 0
    #Ncurses.beep
    @message = "This is the first row"
    @prow = 0
    return -1
  else
    @prow -= 1 
  end
  if @winrow > 0 
    @winrow -= 1
  else
    @toprow -= 1 if @toprow > 0
  end
  @toprow = @prow if @prow < @toprow
  end
end