Class: Redwood::Colormap

Inherits:
Object show all
Defined in:
lib/sup/colormap.rb

Constant Summary collapse

CURSES_COLORS =
[Curses::COLOR_BLACK, Curses::COLOR_RED, Curses::COLOR_GREEN,
Curses::COLOR_YELLOW, Curses::COLOR_BLUE,
Curses::COLOR_MAGENTA, Curses::COLOR_CYAN,
Curses::COLOR_WHITE]
NUM_COLORS =
15
@@instance =
nil

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize {|_self| ... } ⇒ Colormap

Returns a new instance of Colormap.

Yields:

  • (_self)

Yield Parameters:



12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/sup/colormap.rb', line 12

def initialize
  raise "only one instance can be created" if @@instance
  @@instance = self
  @entries = {}
  @color_pairs = {[Curses::COLOR_WHITE, Curses::COLOR_BLACK] => 0}
  @users = []
  @next_id = 0
  yield self if block_given?
  @entries[highlight_sym(:none)] = highlight_for(Curses::COLOR_WHITE,
                                                 Curses::COLOR_BLACK,
                                                 []) + [nil]
end

Class Method Details

.instanceObject



109
# File 'lib/sup/colormap.rb', line 109

def self.instance; @@instance; end

.method_missing(meth, *a) ⇒ Object



110
111
112
113
# File 'lib/sup/colormap.rb', line 110

def self.method_missing meth, *a
  Colorcolors.new unless @@instance
  @@instance.send meth, *a
end

Instance Method Details

#add(sym, fg, bg, attr = nil, opts = {}) ⇒ Object

Raises:

  • (ArgumentError)


25
26
27
28
29
30
31
32
33
# File 'lib/sup/colormap.rb', line 25

def add sym, fg, bg, attr=nil, opts={}
  raise ArgumentError, "color for #{sym} already defined" if @entries.member? sym
  raise ArgumentError, "color '#{fg}' unknown" unless CURSES_COLORS.include? fg
  raise ArgumentError, "color '#{bg}' unknown" unless CURSES_COLORS.include? bg
  attrs = [attr].flatten.compact

  @entries[sym] = [fg, bg, attrs, nil]
  @entries[highlight_sym(sym)] = opts[:highlight] ? @entries[opts[:highlight]] : highlight_for(fg, bg, attrs) + [nil]
end

#color_for(sym, highlight = false) ⇒ Object

Raises:

  • (ArgumentError)


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/sup/colormap.rb', line 72

def color_for sym, highlight=false
  sym = highlight_sym(sym) if highlight
  return Curses::COLOR_BLACK if sym == :none
  raise ArgumentError, "undefined color #{sym}" unless @entries.member? sym

  ## if this color is cached, return it
  fg, bg, attrs, color = @entries[sym]
  return color if color

  if(cp = @color_pairs[[fg, bg]])
    ## nothing
  else ## need to get a new colorpair
    @next_id = (@next_id + 1) % NUM_COLORS
    @next_id += 1 if @next_id == 0 # 0 is always white on black
    id = @next_id
    Redwood::log "colormap: for color #{sym}, using id #{id} -> #{fg}, #{bg}"
    Curses.init_pair id, fg, bg or raise ArgumentError,
      "couldn't initialize curses color pair #{fg}, #{bg} (key #{id})"

    cp = @color_pairs[[fg, bg]] = Curses.color_pair(id)
    ## delete the old mapping, if it exists
    if @users[cp]
      @users[cp].each do |usym|
        Redwood::log "dropping color #{usym} (#{id})"
        @entries[usym][3] = nil
      end
      @users[cp] = []
    end
  end

  ## by now we have a color pair
  color = attrs.inject(cp) { |color, attr| color | attr }
  @entries[sym][3] = color # fill the cache
  (@users[cp] ||= []) << sym # record entry as a user of that color pair
  color
end

#highlight_for(fg, bg, attrs) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/sup/colormap.rb', line 39

def highlight_for fg, bg, attrs
  hfg =
    case fg
    when Curses::COLOR_BLUE
      Curses::COLOR_WHITE
    when Curses::COLOR_YELLOW, Curses::COLOR_GREEN
      fg
    else
      Curses::COLOR_BLACK
    end

  hbg = 
    case bg
    when Curses::COLOR_CYAN
      Curses::COLOR_YELLOW
    else
      Curses::COLOR_CYAN
    end

  attrs =
    if fg == Curses::COLOR_WHITE && attrs.include?(Curses::A_BOLD)
      [Curses::A_BOLD]
    else
      case hfg
      when Curses::COLOR_BLACK
        []
      else
        [Curses::A_BOLD]
      end
    end
  [hfg, hbg, attrs]
end

#highlight_sym(sym) ⇒ Object



35
36
37
# File 'lib/sup/colormap.rb', line 35

def highlight_sym sym
  "#{sym}_highlight".intern
end