class Canis::Scrollbar

Public Class Methods

new(form, config={}) click to toggle source

TODO: if parent passed, we shold bind to ON_ENTER and get current_index, so no extra work is required.

Calls superclass method Canis::Widget::new
# File lib/canis/core/widgets/scrollbar.rb, line 38
def initialize form, config={}, &block

  # setting default first or else Widget will place its BW default
  #@color, @bgcolor = ColorMap.get_colors_for_pair $bottomcolor
  super
  @color_pair = get_color $datacolor, @color, @bgcolor
  @scroll_pair = get_color $bottomcolor, :green, :white
  #$log.debug "SCROLLBAR COLOR cp #{@color_pair} sp #{@scroll_pair} " if $log.debug?
  @window = form.window
  @editable = false
  @focusable = false
  @repaint_required = true
  @orientation = :V
  if @parent
    @parent.bind :ENTER_ROW do |p|
      # textview sent self, textpad sends textactionevent
      if p.instance_of? TextActionEvent
        p = p.source
      end
      # parent must implement row_count, and have a @current_index
      raise StandardError, "Parent (#{p.class.to_s}) must implement row_count" unless p.respond_to? :row_count
      self.current_index = p.current_index
      @repaint_required = true  #requred otherwise at end when same value sent, prop handler
      # will not be fired (due to optimization).
    end
    # in some cases, on leaving a listbox or other component redraws itself to reduce
    # selected or highlighted object, so the scrollbar gets overwritten. We need to repaint it.
    @parent.bind :LEAVE do |p|
      @repaint_required = true  
    end
  end
end

Public Instance Methods

repaint() click to toggle source

repaint the scrollbar Taking the data from parent as late as possible in case parent resized, or moved around by a container.

# File lib/canis/core/widgets/scrollbar.rb, line 75
def repaint
  if @parent
    @row = @parent.row+1
    @col = @parent.col + @parent.width - 1
    @length = @parent.height - 2
    @list_length = @parent.row_count 
    @current_index ||= @parent.current_index
    @border_attrib ||= @parent.border_attrib
  end
  raise ArgumentError, "current_index must be provided" unless @current_index
  raise ArgumentError, "list_length must be provided" unless @list_length
  my_win = @form ? @form.window : @target_window
  @graphic = my_win unless @graphic
  return unless @repaint_required

  # 2016-01-14 - replacing 1 with space in mvvline since junk is showing up in some cases.
  space_char = " ".codepoints.first

  # first print a right side vertical line
  #bc = $bottomcolor  # dark blue
  bc = $datacolor
  bordercolor = @border_color || bc
  borderatt = @border_attrib || Ncurses::A_REVERSE
  #$log.debug "SCROLL bordercolor #{bordercolor} , #{borderatt} " if $log.debug?


  @graphic.attron(Ncurses.COLOR_PAIR(bordercolor) | borderatt)
  #$log.debug " XXX SCROLL #{@row} #{@col} #{@length} "
  @graphic.mvvline(@row+0, @col, space_char, @length-0)
  @graphic.attroff(Ncurses.COLOR_PAIR(bordercolor) | borderatt)

  # now calculate and paint the scrollbar
  pht = @length
  listlen = @list_length * 1.0
  @current_index = 0 if @current_index < 0
  @current_index = listlen-1 if @current_index >= listlen
  sclen = (pht/listlen)* @length
  sclen = 1 if sclen < 1 # sometimes 0.7 for large lists 100 items 2011-10-1
  scloc = (@current_index/listlen)* @length
  scloc = (@length - sclen) if scloc > @length - sclen # don't exceed end
  if @current_index == @list_length - 1
    scloc = @length - sclen + 0 # earlier 1, but removed since sclen min 1 2011-10-1
  end
  @graphic.attron(Ncurses.COLOR_PAIR(@scroll_pair) | borderatt)
  r = @row + scloc
  c = @col + 0
  #$log.debug " XXX SCROLLBAR #{r} #{c} #{sclen} "
  @graphic.mvvline(r, c, space_char, sclen)
  @graphic.attroff(Ncurses.COLOR_PAIR(@scroll_pair) | borderatt)
  @repaint_required = false
end