Merge pull request #269 from CanonicalLtd/mwhudson/simplify-colors
refactor color / palette setup
This commit is contained in:
commit
26147d3cc3
|
@ -24,7 +24,7 @@ log = logging.getLogger('console_conf.core')
|
||||||
|
|
||||||
class Subiquity(Application):
|
class Subiquity(Application):
|
||||||
|
|
||||||
from subiquity.palette import PALETTE, STYLES, STYLES_MONO
|
from subiquity.palette import COLORS, STYLES, STYLES_MONO
|
||||||
|
|
||||||
project = "subiquity"
|
project = "subiquity"
|
||||||
|
|
||||||
|
|
|
@ -15,61 +15,18 @@
|
||||||
|
|
||||||
""" Palette definitions """
|
""" Palette definitions """
|
||||||
|
|
||||||
black = 'black' # index 0
|
|
||||||
dark_red = 'dark red' # index 1
|
|
||||||
dark_green = 'dark green' # index 2
|
|
||||||
brown = 'brown' # index 3
|
|
||||||
dark_blue = 'dark blue' # index 4 # This is overwritten to ubuntu orange at startup
|
|
||||||
dark_magenta = 'dark magenta' # index 5
|
|
||||||
dark_cyan = 'dark cyan' # index 6
|
|
||||||
light_gray = 'light gray' # index 7
|
|
||||||
dark_gray = 'dark gray' # index 8
|
|
||||||
light_red = 'light red' # index 9
|
|
||||||
light_green = 'light green' # index 10
|
|
||||||
yellow = 'yellow' # index 11
|
|
||||||
light_blue = 'light blue' # index 12
|
|
||||||
light_magenta = 'light magenta' # index 13
|
|
||||||
light_cyan = 'light cyan' # index 14
|
|
||||||
white = 'white' # index 15
|
|
||||||
|
|
||||||
|
COLORS = [
|
||||||
URWID_16_NAMES = [
|
("bg", (0x00, 0x00, 0x00)),
|
||||||
'black',
|
("orange", (0xe9, 0x54, 0x20)),
|
||||||
'dark red',
|
("danger", (0xff, 0x00, 0x00)),
|
||||||
'dark green',
|
("good", (0x00, 0xff, 0x00)),
|
||||||
'brown',
|
("neutral", (0x00, 0xff, 0xff)),
|
||||||
'dark blue',
|
("gray", (0x7f, 0x7f, 0x7f)),
|
||||||
'dark magenta',
|
("aubergine", (0x77, 0x21, 0x6f)),
|
||||||
'dark cyan',
|
("fg", (0xff, 0xff, 0xff)),
|
||||||
'light gray',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
URWID16 = {}
|
|
||||||
URWID256 = {}
|
|
||||||
|
|
||||||
PALETTE = bytearray(8*3)
|
|
||||||
|
|
||||||
colors = {
|
|
||||||
0: ("bg", (0x00, 0x00, 0x00)),
|
|
||||||
1: ("orange", (0xe9, 0x54, 0x20)),
|
|
||||||
2: ("danger", (0xff, 0x00, 0x00)),
|
|
||||||
3: ("good", (0x00, 0xff, 0x00)),
|
|
||||||
4: ("neutral", (0x00, 0xff, 0xff)),
|
|
||||||
5: ("gray", (0x7f, 0x7f, 0x7f)),
|
|
||||||
6: ("aubergine", (0x77, 0x21, 0x6f)),
|
|
||||||
7: ("fg", (0xff, 0xff, 0xff)),
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, (c, (r, g, b)) in colors.items():
|
|
||||||
URWID16[c] = URWID_16_NAMES[i]
|
|
||||||
PALETTE[i*3+0] = r
|
|
||||||
PALETTE[i*3+1] = g
|
|
||||||
PALETTE[i*3+2] = b
|
|
||||||
URWID256[c] = 'h' + str(i+16)
|
|
||||||
|
|
||||||
orange = "#e51"
|
|
||||||
warm_gray = "g15"
|
|
||||||
|
|
||||||
STYLES = [
|
STYLES = [
|
||||||
('frame_header', 'fg', 'orange'),
|
('frame_header', 'fg', 'orange'),
|
||||||
('frame_footer', 'fg', 'gray'),
|
('frame_footer', 'fg', 'gray'),
|
||||||
|
@ -102,22 +59,20 @@ focus_styles = set([
|
||||||
|
|
||||||
for i in range(len(STYLES)):
|
for i in range(len(STYLES)):
|
||||||
name, fg, bg = STYLES[i]
|
name, fg, bg = STYLES[i]
|
||||||
STYLES[i] = (name, URWID16[fg], URWID16[bg], '', URWID256[fg], URWID256[bg])
|
|
||||||
if name in focus_styles:
|
if name in focus_styles:
|
||||||
STYLES.append(
|
STYLES.append((name + ' focus', bg, fg))
|
||||||
(name + ' focus', URWID16[bg], URWID16[fg], '', URWID256[bg], URWID256[fg]))
|
|
||||||
|
|
||||||
STYLES_MONO = [
|
STYLES_MONO = [
|
||||||
('frame_header', white, black, '', '', ''),
|
('frame_header', 'white', 'black'),
|
||||||
('frame_footer', white, black, '', '', ''),
|
('frame_footer', 'white', 'black'),
|
||||||
('body', white, black, '', '', ''),
|
('body', 'white', 'black'),
|
||||||
('info_minor', white, black, '', '', ''),
|
('info_minor', 'white', 'black'),
|
||||||
('menu_button', '', '', '', white, ''),
|
('menu_button', '', ''),
|
||||||
('menu_button focus', '', '', '', white, ''),
|
('menu_button focus', '', ''),
|
||||||
('button', white, black, '', '', ''),
|
('button', 'white', 'black'),
|
||||||
('button focus', white, black, '', '', ''),
|
('button focus', 'white', 'black'),
|
||||||
('string_input', '', '', '', white, ''),
|
('string_input', '', ''),
|
||||||
('string_input focus', '', '', '', white, ''),
|
('string_input focus', '', ''),
|
||||||
('progress_incomplete', '', '', '', '', black),
|
('progress_incomplete', '', ''),
|
||||||
('progress_complete', '', '', '', '', white),
|
('progress_complete', '', ''),
|
||||||
]
|
]
|
||||||
|
|
|
@ -17,7 +17,6 @@ from concurrent import futures
|
||||||
import fcntl
|
import fcntl
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
import os
|
|
||||||
|
|
||||||
import urwid
|
import urwid
|
||||||
import yaml
|
import yaml
|
||||||
|
@ -42,21 +41,19 @@ PIO_CMAP = 0x4B71 # sets colour palette on VGA+
|
||||||
UO_R, UO_G, UO_B = 0xe9, 0x54, 0x20
|
UO_R, UO_G, UO_B = 0xe9, 0x54, 0x20
|
||||||
|
|
||||||
|
|
||||||
def setup_ubuntu_orange(pal, additional_opts):
|
class ISO_8613_3_Screen(urwid.raw_display.Screen):
|
||||||
"""Overwrite color 4 (usually "dark blue") to Ubuntu orange."""
|
|
||||||
if is_linux_tty():
|
def __init__(self, _urwid_name_to_rgb):
|
||||||
curpal = bytearray(16*3)
|
self._fg_to_rgb = _urwid_name_to_rgb.copy()
|
||||||
fcntl.ioctl(sys.stdout.fileno(), GIO_CMAP, curpal)
|
self._fg_to_rgb['default'] = _urwid_name_to_rgb['light gray']
|
||||||
curpal[:8] = pal
|
self._bg_to_rgb = _urwid_name_to_rgb.copy()
|
||||||
fcntl.ioctl(sys.stdout.fileno(), PIO_CMAP, curpal)
|
self._bg_to_rgb['default'] = _urwid_name_to_rgb['black']
|
||||||
elif os.environ['TERM'] == 'fbterm':
|
super().__init__()
|
||||||
print('\033[3;4;%i;%i;%i}' % (UO_R, UO_G, UO_B), flush=True)
|
|
||||||
else:
|
def _attrspec_to_escape(self, a):
|
||||||
additional_opts['screen'].set_terminal_properties(colors=256)
|
f_r, f_g, f_b = self._fg_to_rgb[a.foreground]
|
||||||
entries = []
|
b_r, b_g, b_b = self._bg_to_rgb[a.background]
|
||||||
for i in range(8):
|
return "\x1b[38;2;{};{};{};48;2;{};{};{}m".format(f_r, f_g, f_b, b_r, b_g, b_b)
|
||||||
entries.append((i+16, pal[i*3+0], pal[i*3+1], pal[i*3+2]))
|
|
||||||
additional_opts['screen'].modify_terminal_palette(entries)
|
|
||||||
|
|
||||||
|
|
||||||
def is_linux_tty():
|
def is_linux_tty():
|
||||||
|
@ -69,6 +66,56 @@ def is_linux_tty():
|
||||||
return r == b'\x02'
|
return r == b'\x02'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def setup_screen(colors, styles):
|
||||||
|
"""Return a palette and screen to be passed to MainLoop.
|
||||||
|
|
||||||
|
colors is a list of exactly 8 tuples (name, (r, g, b))
|
||||||
|
|
||||||
|
styles is a list of tuples (stylename, fg_color, bg_color) where
|
||||||
|
fg_color and bg_color are defined in 'colors'
|
||||||
|
"""
|
||||||
|
# The part that makes this "fun" is that urwid insists on referring
|
||||||
|
# to the basic colors by their "standard" names but we overwrite
|
||||||
|
# these colors to mean different things. So we convert styles into
|
||||||
|
# an urwid palette by mapping the names in colors to the standard
|
||||||
|
# name, and then either overwrite the first 8 colors to be the
|
||||||
|
# colors from 'colors' (on the linux vt) or use a custom screen
|
||||||
|
# class that displays maps the standard color name to the value
|
||||||
|
# specified in colors using 24-bit control codes.
|
||||||
|
if len(colors) != 8:
|
||||||
|
raise Exception("setup_screen must be passed a list of exactly 8 colors")
|
||||||
|
urwid_8_names = (
|
||||||
|
'black',
|
||||||
|
'dark red',
|
||||||
|
'dark green',
|
||||||
|
'brown',
|
||||||
|
'dark blue',
|
||||||
|
'dark magenta',
|
||||||
|
'dark cyan',
|
||||||
|
'light gray',
|
||||||
|
)
|
||||||
|
urwid_name = dict(zip([c[0] for c in colors], urwid_8_names))
|
||||||
|
|
||||||
|
urwid_palette = []
|
||||||
|
for name, fg, bg in styles:
|
||||||
|
urwid_palette.append((name, urwid_name[fg], urwid_name[bg]))
|
||||||
|
|
||||||
|
if is_linux_tty():
|
||||||
|
curpal = bytearray(16*3)
|
||||||
|
fcntl.ioctl(sys.stdout.fileno(), GIO_CMAP, curpal)
|
||||||
|
for i in range(8):
|
||||||
|
for j in range(3):
|
||||||
|
curpal[i*3+j] = colors[i][1][j]
|
||||||
|
fcntl.ioctl(sys.stdout.fileno(), PIO_CMAP, curpal)
|
||||||
|
return urwid.raw_display.Screen(), urwid_palette
|
||||||
|
else:
|
||||||
|
_urwid_name_to_rgb = {}
|
||||||
|
for i, n in enumerate(urwid_8_names):
|
||||||
|
_urwid_name_to_rgb[n] = colors[i][1]
|
||||||
|
return ISO_8613_3_Screen(_urwid_name_to_rgb), urwid_palette
|
||||||
|
|
||||||
|
|
||||||
class Application:
|
class Application:
|
||||||
|
|
||||||
# A concrete subclass must set project and controllers attributes, e.g.:
|
# A concrete subclass must set project and controllers attributes, e.g.:
|
||||||
|
@ -167,25 +214,17 @@ class Application:
|
||||||
def exit(self):
|
def exit(self):
|
||||||
raise urwid.ExitMainLoop()
|
raise urwid.ExitMainLoop()
|
||||||
|
|
||||||
def header_hotkeys(self, key):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
if not hasattr(self, 'loop'):
|
if not hasattr(self, 'loop'):
|
||||||
palette = self.STYLES
|
|
||||||
additional_opts = {
|
|
||||||
'screen': urwid.raw_display.Screen(),
|
|
||||||
'unhandled_input': self.header_hotkeys,
|
|
||||||
'handle_mouse': False,
|
|
||||||
'pop_ups': True,
|
|
||||||
}
|
|
||||||
if self.common['opts'].run_on_serial:
|
if self.common['opts'].run_on_serial:
|
||||||
palette = self.STYLES_MONO
|
palette = self.STYLES_MONO
|
||||||
|
screen = urwid.raw_display.Screen()
|
||||||
else:
|
else:
|
||||||
setup_ubuntu_orange(self.PALETTE, additional_opts)
|
screen, palette = setup_screen(self.COLORS, self.STYLES)
|
||||||
|
|
||||||
self.common['loop'] = urwid.MainLoop(
|
self.common['loop'] = urwid.MainLoop(
|
||||||
self.common['ui'], palette, **additional_opts)
|
self.common['ui'], palette=palette, screen=screen,
|
||||||
|
handle_mouse=False, pop_ups=True)
|
||||||
log.debug("Running event loop: {}".format(
|
log.debug("Running event loop: {}".format(
|
||||||
self.common['loop'].event_loop))
|
self.common['loop'].event_loop))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue