lib/ruco/screen.rb in ruco-0.1.14 vs lib/ruco/screen.rb in ruco-0.2.0.beta
- old
+ new
@@ -1,23 +1,29 @@
module Ruco
class Screen
+ @@styles = {}
+
def initialize(options)
@options = options
@cache = []
end
def self.open(options, &block)
new(options).open(&block)
end
def open(&block)
+ if $ruco_colors and ENV['TERM'] == 'xterm'
+ ENV['TERM'] += '-256color' # activate 256 colors
+ end
Curses.noecho # do not show typed chars
Curses.nonl # turn off newline translation
Curses.stdscr.keypad(true) # enable arrow keys
Curses.raw # give us all other keys
Curses.stdscr.nodelay = 1 # do not block -> we can use timeouts
Curses.init_screen
+ Curses.start_color if $ruco_colors and Curses.has_colors?
yield self
ensure
Curses.clear # needed to clear the menu/status bar on windows
Curses.close_screen
end
@@ -86,16 +92,64 @@
return if @cache[key] == args # would not change the line -> nothing to do
@cache[key] = args # store current line
yield # render the line
end
- STYLES = {
- :normal => 0,
- :reverse => Curses::A_REVERSE
- }
-
def self.curses_style(style)
- return 0 unless style
- STYLES[style] or raise("Unknown style #{style.inspect}")
+ @@styles[style] ||= begin
+ if $ruco_colors
+ foreground = $ruco_foreground || '#ffffff'
+ background = $ruco_background || '#000000'
+
+ foreground, background = if style == :normal
+ [foreground, background]
+ elsif style == :reverse
+ ['#000000', '#ffffff']
+ else
+ # :red or [:red, :blue]
+ f,b = style
+ b ||= background
+ [f,b]
+ end
+
+ foreground = html_to_terminal_color(foreground)
+ background = html_to_terminal_color(background)
+ color_id(foreground, background)
+ else # no colors
+ if style == :reverse
+ Curses::A_REVERSE
+ else
+ Curses::A_NORMAL
+ end
+ end
+ end
+ end
+
+ # create a new color from foreground+background or reuse old
+ # and return color-id
+ def self.color_id(foreground, background)
+ @@color_ids ||= {}
+ @@color_ids[[foreground, background]] ||= begin
+ # make a new pair with a unique id
+ @@max_color_id ||= 0
+ id = (@@max_color_id += 1)
+ unless defined? RSpec # stops normal text-output, do not use in tests
+ Curses::init_pair(id, foreground, background)
+ end
+ Curses.color_pair(id)
+ end
+ end
+
+ COLOR_SOURCE_VALUES = 256
+ COLOR_TARGET_VALUES = 5
+ COLOR_DIVIDE = COLOR_SOURCE_VALUES / COLOR_TARGET_VALUES
+ TERM_COLOR_BASE = 16
+
+ def self.html_to_terminal_color(html_color)
+ return unless html_color
+ r = (html_color[1..2].to_i(16) / COLOR_DIVIDE) * 36
+ g = (html_color[3..4].to_i(16) / COLOR_DIVIDE) * 6
+ b = (html_color[5..6].to_i(16) / COLOR_DIVIDE) * 1
+ TERM_COLOR_BASE + r + g + b
end
end
end