class LessCurse::Screen

Attributes

focused_widget[RW]
grid[RW]
header[RW]
popups[RW]
size[RW]
windows[RW]

Public Class Methods

new() click to toggle source
# File lib/less_curse/screen.rb, line 11
def initialize
  # Need to initialize screen to access the terminal size
  FFI::NCurses.initscr

  height,width =  FFI::NCurses::getmaxyx(FFI::NCurses::stdscr)
  @size = LessCurse::Geometry::Size.new(width,height)
  @windows = {}
  @focused_widget = nil
  @grid    = LessCurse::Grid.new [[]]
  @popups  = {}
end

Public Instance Methods

add(widget_or_grid) click to toggle source
# File lib/less_curse/screen.rb, line 23
def add widget_or_grid
  if widget_or_grid.is_a? LessCurse::Grid
    @grid = widget_or_grid
  else
    @grid.add widget_or_grid
  end
  recalc_window_sizes
end
focus_next() click to toggle source

Focus next element in widgets

# File lib/less_curse/screen.rb, line 89
def focus_next
  cycle_focus(+1)
end
focus_previous() click to toggle source

Focus next element in widgets

# File lib/less_curse/screen.rb, line 94
def focus_previous
  cycle_focus(-1)
end
header=(new_header) click to toggle source

Set header text (first, top line of screen)

# File lib/less_curse/screen.rb, line 99
def header= new_header
  @header = new_header
  recalc_window_sizes
end
repaint() click to toggle source

Repaint the screen and all contained widgets

# File lib/less_curse/screen.rb, line 50
def repaint
  FFI::NCurses.refresh

  # 'Draw' header and/or footer
  if @header && !@header.empty?
    FFI::NCurses::mvaddstr 0, 0, @header
  end
  if @footer && !@footer.empty?
    FFI::NCurses::mvaddstr @size.height - 1, 0, @footer
  end

  # Let all Widgets redraw themselfes
  widgets.each  do |widget|
    window = @windows[widget]
    FFI::NCurses.wclear   window
    widget.draw           window
    FFI::NCurses.wrefresh window
  end

  @popups.each do |popup, window|
    FFI::NCurses.wclear   window
    popup.draw            window
    FFI::NCurses.wrefresh window
  end
end
show() click to toggle source
# File lib/less_curse/screen.rb, line 36
def show
  @focused_widget = widgets.first
  @focused_widget.focus if @focused_widget
  # Note that FFI::NCurses.initscr is called in initialize
  FFI::NCurses.cbreak # can ctrl-c, not waiting for newlines to end input.
  #FFI::NCurses.raw    # TODO this overrides cbreak ...
  FFI::NCurses.noecho # do not echo input in win.
  FFI::NCurses.keypad FFI::NCurses::stdscr, true # recognize KEY_UP etc.
  FFI::NCurses.clear
  FFI::NCurses.refresh
  repaint
end
show_popup(type=:info, content='Popup') click to toggle source
# File lib/less_curse/screen.rb, line 76
def show_popup type=:info, content='Popup'
  # Lets take up quarter of screen and draw a boxed window
  popup_widget = LessCurse::Widgets::Button.new title: content.to_s
  popup_widget.focus = true
  area = LessCurse::Geometry::Rectangle.new @size.width / 4,
    @size.height / 4,
    @size.width  / 2,
    @size.height / 2

  @popups[popup_widget] = LessCurse.window area
end
widgets() click to toggle source
# File lib/less_curse/screen.rb, line 32
def widgets
  @grid.widgets
end

Private Instance Methods

cycle_focus(step=1) click to toggle source

Switch focus to step next (or previous) widget

# File lib/less_curse/screen.rb, line 113
def cycle_focus step=1
  focused_widget_idx = widgets.index(@focused_widget) || 0
  @focused_widget.unfocus
  @focused_widget = widgets[(focused_widget_idx + step) % widgets.size]
  @focused_widget.focus
end
recalc_window_sizes() click to toggle source
# File lib/less_curse/screen.rb, line 120
def recalc_window_sizes
  header_height = (@header.nil? || @header.empty?) ? 0 : 1
  footer_height = (@footer.nil? || @footer.empty?) ? 0 : 1

  row_height = (@size.height - header_height - footer_height) / @grid.rows.count

  @grid.rows.each_with_index do |row_widgets, row_idx|
    element_width = @size.width / (row_widgets.size)
    row_y         = header_height + row_idx * row_height
    row_widgets.each_with_index do |widget, idx|
      area = LessCurse::Geometry::Rectangle.new element_width * idx, #x
                                                row_y, #y
                                                element_width - 1, #width
                                                row_height #height
      if @windows[widget].nil?
        @windows[widget] = LessCurse.window area
      else
        FFI::NCurses.wresize(@windows[widget],
                             area.size.height, area.size.width)
        FFI::NCurses.mvwin(@windows[widget],
                           area.position.y, area.position.x)
      end
    end
  end
end