mirror of https://github.com/nicolargo/glances
Refactor colors Class for Curses UI
parent
e086625f1a
commit
6b036ec0ac
|
@ -720,6 +720,10 @@ Examples of use:
|
|||
args.time = 1
|
||||
args.disable_history = True
|
||||
|
||||
# Unicode => No separator
|
||||
if args.disable_unicode:
|
||||
args.enable_separator = False
|
||||
|
||||
def parse_args(self):
|
||||
"""Parse command line arguments."""
|
||||
args = self.init_args().parse_args()
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
#
|
||||
# This file is part of Glances.
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2024 Nicolas Hennion <nicolas@nicolargo.com>
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-3.0-only
|
||||
#
|
||||
|
||||
"""Glances colors."""
|
||||
|
||||
import sys
|
||||
|
||||
from glances.logger import logger
|
||||
|
||||
try:
|
||||
import curses
|
||||
except ImportError:
|
||||
logger.critical("Curses module not found. Glances cannot start in standalone mode.")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
class GlancesColors:
|
||||
"""Class to manage colors in Glances UI
|
||||
For the moment limited to Curses interface.
|
||||
But will be used in the WebUI through the issue #2048"""
|
||||
|
||||
def __init__(self, args) -> None:
|
||||
self.args = args
|
||||
|
||||
# Define "home made" bold
|
||||
self.A_BOLD = 0 if args.disable_bold else curses.A_BOLD
|
||||
|
||||
# Set defaults curses colors
|
||||
try:
|
||||
if hasattr(curses, 'start_color'):
|
||||
curses.start_color()
|
||||
logger.debug(f'Curses interface compatible with {curses.COLORS} colors')
|
||||
if hasattr(curses, 'use_default_colors'):
|
||||
# Use -1 to use the default foregound/background color
|
||||
curses.use_default_colors()
|
||||
if hasattr(curses, 'assume_default_colors'):
|
||||
# Define the color index 0 with -1 and -1 for foregound/background
|
||||
# = curses.init_pair(0, -1, -1)
|
||||
curses.assume_default_colors(-1, -1)
|
||||
except Exception as e:
|
||||
logger.warning(f'Error initializing terminal color ({e})')
|
||||
|
||||
if curses.has_colors():
|
||||
# The screen is compatible with a colored design
|
||||
# ex: export TERM=xterm-256color
|
||||
# export TERM=xterm-color
|
||||
self.__define_colors()
|
||||
else:
|
||||
# The screen is NOT compatible with a colored design
|
||||
# switch to B&W text styles
|
||||
# ex: export TERM=xterm-mono
|
||||
self.__define_bw()
|
||||
|
||||
def __repr__(self) -> dict:
|
||||
return self.get()
|
||||
|
||||
def __define_colors(self) -> None:
|
||||
curses.init_pair(1, -1, -1)
|
||||
if self.args.disable_bg:
|
||||
curses.init_pair(2, curses.COLOR_RED, -1)
|
||||
curses.init_pair(3, curses.COLOR_GREEN, -1)
|
||||
curses.init_pair(5, curses.COLOR_MAGENTA, -1)
|
||||
else:
|
||||
curses.init_pair(2, -1, curses.COLOR_RED)
|
||||
curses.init_pair(3, curses.COLOR_BLACK, curses.COLOR_GREEN)
|
||||
curses.init_pair(5, -1, curses.COLOR_MAGENTA)
|
||||
curses.init_pair(4, curses.COLOR_BLUE, -1)
|
||||
curses.init_pair(6, curses.COLOR_RED, -1)
|
||||
curses.init_pair(7, curses.COLOR_GREEN, -1)
|
||||
curses.init_pair(8, curses.COLOR_MAGENTA, -1)
|
||||
|
||||
# Colors text styles
|
||||
self.DEFAULT = curses.color_pair(1)
|
||||
self.OK_LOG = curses.color_pair(3) | self.A_BOLD
|
||||
self.NICE = curses.color_pair(8)
|
||||
self.CPU_TIME = curses.color_pair(8)
|
||||
self.CAREFUL_LOG = curses.color_pair(4) | self.A_BOLD
|
||||
self.WARNING_LOG = curses.color_pair(5) | self.A_BOLD
|
||||
self.CRITICAL_LOG = curses.color_pair(2) | self.A_BOLD
|
||||
self.OK = curses.color_pair(7)
|
||||
self.CAREFUL = curses.color_pair(4)
|
||||
self.WARNING = curses.color_pair(8) | self.A_BOLD
|
||||
self.CRITICAL = curses.color_pair(6) | self.A_BOLD
|
||||
self.INFO = curses.color_pair(4)
|
||||
self.FILTER = self.A_BOLD
|
||||
self.SELECTED = self.A_BOLD
|
||||
self.SEPARATOR = curses.color_pair(1)
|
||||
|
||||
if curses.COLORS > 8:
|
||||
# ex: export TERM=xterm-256color
|
||||
try:
|
||||
curses.init_pair(9, curses.COLOR_CYAN, -1)
|
||||
curses.init_pair(10, curses.COLOR_YELLOW, -1)
|
||||
except Exception:
|
||||
curses.init_pair(9, -1, -1)
|
||||
curses.init_pair(10, -1, -1)
|
||||
self.FILTER = curses.color_pair(9) | self.A_BOLD
|
||||
self.SELECTED = curses.color_pair(10) | self.A_BOLD
|
||||
|
||||
# Define separator line style
|
||||
try:
|
||||
curses.init_color(11, 500, 500, 500)
|
||||
curses.init_pair(11, curses.COLOR_BLACK, -1)
|
||||
self.SEPARATOR = curses.color_pair(11)
|
||||
except Exception:
|
||||
# Catch exception in TMUX
|
||||
pass
|
||||
|
||||
def __define_bw(self) -> None:
|
||||
# The screen is NOT compatible with a colored design
|
||||
# switch to B&W text styles
|
||||
# ex: export TERM=xterm-mono
|
||||
self.DEFAULT = -1
|
||||
self.OK_LOG = -1
|
||||
self.NICE = self.A_BOLD
|
||||
self.CPU_TIME = self.A_BOLD
|
||||
self.CAREFUL_LOG = self.A_BOLD
|
||||
self.WARNING_LOG = curses.A_UNDERLINE
|
||||
self.CRITICAL_LOG = curses.A_REVERSE
|
||||
self.OK = -1
|
||||
self.CAREFUL = self.A_BOLD
|
||||
self.WARNING = curses.A_UNDERLINE
|
||||
self.CRITICAL = curses.A_REVERSE
|
||||
self.INFO = self.A_BOLD
|
||||
self.FILTER = self.A_BOLD
|
||||
self.SELECTED = self.A_BOLD
|
||||
self.SEPARATOR = -1
|
||||
|
||||
def get(self) -> dict:
|
||||
return {
|
||||
'DEFAULT': self.DEFAULT,
|
||||
'UNDERLINE': curses.A_UNDERLINE,
|
||||
'BOLD': self.A_BOLD,
|
||||
'SORT': curses.A_UNDERLINE | self.A_BOLD,
|
||||
'OK': self.OK,
|
||||
'MAX': self.OK | self.A_BOLD,
|
||||
'FILTER': self.FILTER,
|
||||
'TITLE': self.A_BOLD,
|
||||
'PROCESS': self.OK,
|
||||
'PROCESS_SELECTED': self.OK | curses.A_UNDERLINE,
|
||||
'STATUS': self.OK,
|
||||
'NICE': self.NICE,
|
||||
'CPU_TIME': self.CPU_TIME,
|
||||
'CAREFUL': self.CAREFUL,
|
||||
'WARNING': self.WARNING,
|
||||
'CRITICAL': self.CRITICAL,
|
||||
'OK_LOG': self.OK_LOG,
|
||||
'CAREFUL_LOG': self.CAREFUL_LOG,
|
||||
'WARNING_LOG': self.WARNING_LOG,
|
||||
'CRITICAL_LOG': self.CRITICAL_LOG,
|
||||
'PASSWORD': curses.A_PROTECT,
|
||||
'SELECTED': self.SELECTED,
|
||||
'INFO': self.INFO,
|
||||
'ERROR': self.SELECTED,
|
||||
'SEPARATOR': self.SEPARATOR,
|
||||
}
|
|
@ -14,6 +14,7 @@ import sys
|
|||
from glances.events_list import glances_events
|
||||
from glances.globals import MACOS, WINDOWS, disable, enable, itervalues, nativestr, u
|
||||
from glances.logger import logger
|
||||
from glances.outputs.glances_colors import GlancesColors
|
||||
from glances.outputs.glances_unicode import unicode_message
|
||||
from glances.processes import glances_processes, sort_processes_key_list
|
||||
from glances.timer import Timer
|
||||
|
@ -162,7 +163,7 @@ class _GlancesCurses:
|
|||
self._init_cursor()
|
||||
|
||||
# Init the colors
|
||||
self.colors_list = build_colors_list(args)
|
||||
self.colors_list = GlancesColors(args).get()
|
||||
|
||||
# Init main window
|
||||
self.term_window = self.screen.subwin(0, 0)
|
||||
|
@ -1179,128 +1180,3 @@ class GlancesTextboxYesNo(Textbox):
|
|||
|
||||
def do_command(self, ch):
|
||||
return super().do_command(ch)
|
||||
|
||||
|
||||
def build_colors_list(args):
|
||||
"""Init the Curses color layout."""
|
||||
# Set curses options
|
||||
try:
|
||||
if hasattr(curses, 'start_color'):
|
||||
curses.start_color()
|
||||
logger.debug(f'Curses interface compatible with {curses.COLORS} colors')
|
||||
if hasattr(curses, 'use_default_colors'):
|
||||
curses.use_default_colors()
|
||||
except Exception as e:
|
||||
logger.warning(f'Error initializing terminal color ({e})')
|
||||
|
||||
# Init colors
|
||||
if args.disable_bold:
|
||||
A_BOLD = 0
|
||||
args.disable_bg = True
|
||||
else:
|
||||
A_BOLD = curses.A_BOLD
|
||||
|
||||
title_color = A_BOLD
|
||||
|
||||
if curses.has_colors():
|
||||
# The screen is compatible with a colored design
|
||||
# ex: export TERM=xterm-256color
|
||||
# export TERM=xterm-color
|
||||
|
||||
curses.init_pair(1, -1, -1)
|
||||
if args.disable_bg:
|
||||
curses.init_pair(2, curses.COLOR_RED, -1)
|
||||
curses.init_pair(3, curses.COLOR_GREEN, -1)
|
||||
curses.init_pair(5, curses.COLOR_MAGENTA, -1)
|
||||
else:
|
||||
curses.init_pair(2, -1, curses.COLOR_RED)
|
||||
curses.init_pair(3, 0, curses.COLOR_GREEN)
|
||||
curses.init_pair(5, -1, curses.COLOR_MAGENTA)
|
||||
curses.init_pair(4, curses.COLOR_BLUE, -1)
|
||||
curses.init_pair(6, curses.COLOR_RED, -1)
|
||||
curses.init_pair(7, curses.COLOR_GREEN, -1)
|
||||
curses.init_pair(8, curses.COLOR_MAGENTA, -1)
|
||||
|
||||
# Colors text styles
|
||||
no_color = curses.color_pair(1)
|
||||
default_color = curses.color_pair(3) | A_BOLD
|
||||
nice_color = curses.color_pair(8)
|
||||
cpu_time_color = curses.color_pair(8)
|
||||
ifCAREFUL_color = curses.color_pair(4) | A_BOLD
|
||||
ifWARNING_color = curses.color_pair(5) | A_BOLD
|
||||
ifCRITICAL_color = curses.color_pair(2) | A_BOLD
|
||||
default_color2 = curses.color_pair(7)
|
||||
ifCAREFUL_color2 = curses.color_pair(4)
|
||||
ifWARNING_color2 = curses.color_pair(8) | A_BOLD
|
||||
ifCRITICAL_color2 = curses.color_pair(6) | A_BOLD
|
||||
ifINFO_color = curses.color_pair(4)
|
||||
filter_color = A_BOLD
|
||||
selected_color = A_BOLD
|
||||
separator = curses.color_pair(1)
|
||||
|
||||
if curses.COLORS > 8:
|
||||
# ex: export TERM=xterm-256color
|
||||
colors_list = [curses.COLOR_CYAN, curses.COLOR_YELLOW]
|
||||
for i in range(0, 3):
|
||||
try:
|
||||
curses.init_pair(i + 9, colors_list[i], -1)
|
||||
except Exception:
|
||||
curses.init_pair(i + 9, -1, -1)
|
||||
filter_color = curses.color_pair(9) | A_BOLD
|
||||
selected_color = curses.color_pair(10) | A_BOLD
|
||||
# Define separator line style
|
||||
try:
|
||||
curses.init_color(11, 500, 500, 500)
|
||||
curses.init_pair(11, curses.COLOR_BLACK, -1)
|
||||
separator = curses.color_pair(11)
|
||||
except Exception:
|
||||
# Catch exception in TMUX
|
||||
pass
|
||||
else:
|
||||
# The screen is NOT compatible with a colored design
|
||||
# switch to B&W text styles
|
||||
# ex: export TERM=xterm-mono
|
||||
no_color = -1
|
||||
default_color = -1
|
||||
nice_color = A_BOLD
|
||||
cpu_time_color = A_BOLD
|
||||
ifCAREFUL_color = A_BOLD
|
||||
ifWARNING_color = curses.A_UNDERLINE
|
||||
ifCRITICAL_color = curses.A_REVERSE
|
||||
default_color2 = -1
|
||||
ifCAREFUL_color2 = A_BOLD
|
||||
ifWARNING_color2 = curses.A_UNDERLINE
|
||||
ifCRITICAL_color2 = curses.A_REVERSE
|
||||
ifINFO_color = A_BOLD
|
||||
filter_color = A_BOLD
|
||||
selected_color = A_BOLD
|
||||
separator = -1
|
||||
|
||||
# Define the colors list (hash table) for stats
|
||||
return {
|
||||
'DEFAULT': no_color,
|
||||
'UNDERLINE': curses.A_UNDERLINE,
|
||||
'BOLD': A_BOLD,
|
||||
'SORT': curses.A_UNDERLINE | A_BOLD,
|
||||
'OK': default_color2,
|
||||
'MAX': default_color2 | A_BOLD,
|
||||
'FILTER': filter_color,
|
||||
'TITLE': title_color,
|
||||
'PROCESS': default_color2,
|
||||
'PROCESS_SELECTED': default_color2 | curses.A_UNDERLINE,
|
||||
'STATUS': default_color2,
|
||||
'NICE': nice_color,
|
||||
'CPU_TIME': cpu_time_color,
|
||||
'CAREFUL': ifCAREFUL_color2,
|
||||
'WARNING': ifWARNING_color2,
|
||||
'CRITICAL': ifCRITICAL_color2,
|
||||
'OK_LOG': default_color,
|
||||
'CAREFUL_LOG': ifCAREFUL_color,
|
||||
'WARNING_LOG': ifWARNING_color,
|
||||
'CRITICAL_LOG': ifCRITICAL_color,
|
||||
'PASSWORD': curses.A_PROTECT,
|
||||
'SELECTED': selected_color,
|
||||
'INFO': ifINFO_color,
|
||||
'ERROR': selected_color,
|
||||
'SEPARATOR': separator,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue