ruby / curses

Ruby binding for curses, ncurses, and PDCurses. Formerly part of the ruby standard library.
Other
297 stars 34 forks source link

Understanding how to redefine colors and pairs #42

Closed kaspergrubbe closed 6 years ago

kaspergrubbe commented 6 years ago

Hi,

This has been bugging me for a while, and I do not know if I am doing something wrong, or if it is a bug in either curses, ncurses or in my terminal.

I have created a fairly elaborate script that first loads in a colorscheme, I have stolen the material colors scheme from Android to work with (please see the material-colors.json file here: https://gist.github.com/kaspergrubbe/f6e64178e3962a3609e93569dc7722ce). It then reads all the hex values, and converts it to ncurses (between 0 and 1000) like this:

@red = 'ff'
@green = 'ff'
@blue = 'ff'
[@red, @green, @blue].map{|h| h.hex / 0.255}.map(&:to_i)
#=> [1000, 1000, 1000]

I then read the materials-colors.json file, it is grouped by colorname and a weight like so:

{
  "red": {
    "50": "#ffebee",
    "100": "#ffcdd2",
    "300": "#e57373",
    "500": "#f44336",
    "700": "#d32f2f",
    "800": "#c62828",
    "900": "#b71c1c"
  },
  "pink": {
    "50": "#fce4ec",
    "100": "#f8bbd0",
    "300": "#f06292",
    "500": "#e91e63",
snipped

I then load in all the individual colours, calculate all possible combination of colour pairs where each color can be both front and back, and then I initialise curses and get it to setup the colours.

I then print lol 5 times:

  fg = @colour_map['grey']['50']
  bg = @colour_map['lightblue']['900']
  pair = @colour_map.pair(fg, bg)

  paint_effect(win, Curses.color_pair(pair.number) | Curses::A_UNDERLINE) do
    win.setpos(1,1)
    win.addstr('lol')
  end

  paint_effect(win, Curses.color_pair(1337) | Curses::A_UNDERLINE) do
    win.setpos(2,2)
    win.addstr('lol')
  end

  paint_effect(win, Curses.color_pair(10337) | Curses::A_UNDERLINE) do
    win.setpos(3,3)
    win.addstr('lol')
  end

  paint_effect(win, Curses.color_pair(0)) do
    win.setpos(4,4)
    win.addstr('lol')
  end

  paint_effect(win, Curses.color_pair(@colour_map.pair(@colour_map['grey']['50'], @colour_map['blue']['900']).number)) do
    win.setpos(5,5)
    win.addstr('lol')
  end

But the results are very strange. This is how iTerm renders it:

screenie_1540816453_064939

If you hover over it, you can see that it writes some text:

screenie_1540816517_8422852

And the OSX Terminal.app renders it very differently:

ncurses_terminal_render

However, while Terminal.app manages to reset the colors after the program exits, the same cannot be said about iTerm:

Before:

screenie_1540816908_153203

After:

screenie_1540816926_967733

I have made a whole repo here: https://github.com/kaspergrubbe/curses_colortest the only thing to test is just cloning the repo and running ruby colortest.rb.

Can you see something I can't?

kaspergrubbe commented 6 years ago

I would like to add a $50 bug bounty that fixes this issue, or help me get https://github.com/kaspergrubbe/curses_colortest to render properly.

@shugo or @hsbt if you know anyone I could reach out to that might be interested in looking into this issue please point them in this direction, please.

kaspergrubbe commented 6 years ago

It seems to mess up the characters when I use a color_pair higher than 16383:

screenie_1541552199_000484

But under works fine:

screenie_1541552257_2636921
kaspergrubbe commented 6 years ago

Everything is working when using ncurses 6.1 by compiling curses with ncurses from Homebrew:

bundle config build.curses --with-cflags="-I$(brew --prefix)/opt/ncurses/include" --with-ldflags="-L$(brew --prefix)/opt/ncurses/lib"
rubyFeedback commented 1 year ago

Can you also add the code for the .rb file? I'd love to reproduce this.

kaspergrubbe commented 1 year ago

@rubyFeedback Hi, first: Thanks for your interest in curses in Ruby, it's something I haven't played with for a while, but it's a fascinating world creating TUIs, it's a dark art, and things are a bit low-level and sometimes a little wonky :)

I think all the code is available here: https://github.com/kaspergrubbe/curses_colortest is there anything else you're missing? :)