class Canis::Divider
This is a horizontal or vertical bar (like a scrollbar), at present attached to a widget that is focusable, and allows user to press arrow keys. It highlights on focus, the caller can expand and contract components in a container or even screen, based on arrow movements. This allows for a visual resizing of components. @example
lb = list_box .... rb = Divider.new @form, :parent => lb, :side => :right
NOTE: since this can be deactivated, containers need to check focusable before passing focus in
2010-10-07 23:56 made focusable false by default. Add divider to FocusManager when creating, so F3 can be used to set focusable See rvimsplit.rb for example
Public Class Methods
TODO: if parent passed, we shold bind to ON_ENTER and get current_index, so no extra work is required.
# File lib/canis/core/widgets/divider.rb, line 51 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 @height = 1 @color_pair = get_color $datacolor, @color, @bgcolor @scroll_pair = get_color $bottomcolor, :green, :white #@window = form.window @editable = false # you can set to true upon creation, or use F3 on vimsplit to # toggle focusable @focusable = false @repaint_required = true @_events.push(:DRAG_EVENT) map_keys unless @parent raise ArgumentError, "row col and length should be provided" if !@row || !@col || !@length end #if @parent #@parent.bind :ENTER_ROW do |p| ## parent must implement row_count, and have a @current_index #raise StandardError, "Parent 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 #end end
Public Instance Methods
# File lib/canis/core/widgets/divider.rb, line 159 def convert_attrib_to_sym attr case attr when 'reverse' Ncurses::A_REVERSE when 'bold' Ncurses::A_BOLD when 'normal' Ncurses::A_NORMAL when 'blink' Ncurses::A_BLINK when 'underline' Ncurses::A_UNDERLINE else Ncurses::A_REVERSE end end
deactivate all dividers The application has to provide a key or button to activate all or just this one.
# File lib/canis/core/widgets/divider.rb, line 178 def deactivate_all tf=true $deactivate_dividers = tf @focusable = !tf end
is this a horizontal divider
# File lib/canis/core/widgets/divider.rb, line 255 def h? @side == :right || @side == :left end
# File lib/canis/core/widgets/divider.rb, line 182 def handle_key ch # all dividers have been deactivated if $deactivate_dividers || !@focusable @focusable = false return :UNHANDLED end case @side when :right, :left case ch when KEY_RIGHT fire_handler :DRAG_EVENT, DragEvent.new(self, ch) when KEY_LEFT fire_handler :DRAG_EVENT, DragEvent.new(self, ch) else ret = process_key ch, self return ret if ret == :UNHANDLED end set_form_col when :top, :bottom case ch when KEY_UP fire_handler :DRAG_EVENT, DragEvent.new(self, ch) when KEY_DOWN fire_handler :DRAG_EVENT, DragEvent.new(self, ch) else ret = process_key ch, self return ret if ret == :UNHANDLED end set_form_col else end @repaint_required = true return 0 end
# File lib/canis/core/widgets/divider.rb, line 80 def map_keys if !defined? $deactivate_dividers $deactivate_dividers = false end # deactivate only this bar bind_key(?f) {@focusable=false; } # deactivate all bars, i've had nuff! bind_key(?F) {deactivate_all(true)} end
# File lib/canis/core/widgets/divider.rb, line 216 def on_enter if $deactivate_dividers || !@focusable @focusable = false return :UNHANDLED end # since it is over border of component, we need to repaint @focussed = true @repaint_required = true repaint end
# File lib/canis/core/widgets/divider.rb, line 226 def on_leave @focussed = false @repaint_required = true repaint # TODO: we should review this since its not over the parent any longer if @parent # since it is over border of component, we need to clear @parent.repaint_required # if we don't paint now, parent paints over other possible dividers @parent.repaint end end
repaint the scrollbar Taking the data from parent as late as possible in case parent resized, or moved around by a container. NOTE: sometimes if this is inside another object, the divider repaints but then is wiped out when that objects print_border is called. So such an obkect (e.g. vimsplit) should call repaint after its has done its own repaint. that does mean the repaint happens twice during movement
# File lib/canis/core/widgets/divider.rb, line 98 def repaint woffset = 2 coffset = 1 # 2016-01-14 - replacing 1 with space since junk is showing up in some cases (in mvvline/mvhline) space_char = " ".codepoints.first if @parent woffset = 0 if @parent.suppress_borders @border_attrib ||= @parent.border_attrib case @side when :right @row = @parent.row+1 @col = @parent.col + @parent.width - 0 @length = @parent.height - woffset when :left @row = @parent.row+1 @col = @parent.col+0 #+ @parent.width - 1 @length = @parent.height - woffset when :top @row = @parent.row+0 @col = @parent.col + @parent.col_offset #+ @parent.width - 1 @length = @parent.width - woffset when :bottom @row = @parent.row+@parent.height-0 #1 @col = @parent.col+@parent.col_offset #+ @parent.width - 1 @length = @parent.width - woffset end else # row, col and length should be passed end my_win = @form ? @form.window : @target_window @graphic = my_win unless @graphic raise "graphic is nil in divider, perhaps form was nil when creating" unless @graphic return unless @repaint_required # first print a right side vertical line #bc = $bottomcolor # dark blue bc = get_color($datacolor, :cyan, :black) bordercolor = @border_color || bc borderatt = @border_attrib || Ncurses::A_REVERSE if @focussed bordercolor = $promptcolor || bordercolor end borderatt = convert_attrib_to_sym(borderatt) if borderatt.is_a? Symbol @graphic.attron(Ncurses.COLOR_PAIR(bordercolor) | borderatt) $log.debug " XXX DIVIDER #{@row} #{@col} #{@length} " case @side when :right, :left @graphic.mvvline(@row, @col, space_char, @length) when :top, :bottom @graphic.mvhline(@row, @col, space_char, @length) end @graphic.attroff(Ncurses.COLOR_PAIR(bordercolor) | borderatt) _paint_marker #alert "divider repaint at #{row} #{col} " @repaint_required = false end
set the cursor on first point of bar
# File lib/canis/core/widgets/divider.rb, line 244 def set_form_col return unless @focusable # need to set it to first point, otherwise it could be off the widget r,c = rowcol setrowcol r, c end
# File lib/canis/core/widgets/divider.rb, line 238 def set_form_row return unless @focusable r,c = rowcol setrowcol r, c end
is this a vertical divider
# File lib/canis/core/widgets/divider.rb, line 251 def v? @side == :top || @side == :bottom end