From e1eac3200aacada277aeb4c4c644527c5497355f Mon Sep 17 00:00:00 2001 From: JP Etcheber Date: Sun, 12 Jun 2022 23:13:41 -0700 Subject: [PATCH] docs: update colors docs and examples --- dashport/colors.py | 11 +-- dashport/dash.py | 21 +++--- docs/colors.md | 96 ++++++++++++++++++++++++--- examples/boilerplate/color_example.py | 15 +++++ examples/boilerplate/rectangle.py | 6 +- 5 files changed, 125 insertions(+), 24 deletions(-) create mode 100755 examples/boilerplate/color_example.py diff --git a/dashport/colors.py b/dashport/colors.py index 6f9384d..a3cb53f 100644 --- a/dashport/colors.py +++ b/dashport/colors.py @@ -41,10 +41,13 @@ def color_foregrounds(color_index, color_int_background, color_dict, color_str_b return color_dict - -def color_pair_integer(default, color_int=None): - if not color_int: - return curses.color_pair(default) +def color_pair_integer(app, color_int=None): + if not color_int and not app.color_default: + return curses.color_pair(0) + elif not color_int: + return curses.color_pair(app.color_default) + elif isinstance(color_int, str): + return curses.color_pair(app.color_names[color_int]) else: return curses.color_pair(color_int) diff --git a/dashport/dash.py b/dashport/dash.py index 394c669..3b423ba 100644 --- a/dashport/dash.py +++ b/dashport/dash.py @@ -32,7 +32,6 @@ def __init__(self, stdscr, **kwargs): self.controls = dict() self.cursor_x = 0 self.cursor_y = 0 - self.color_default = kwargs.get("color_default", 8) self.panels = dict() self.panel_dimensions = [] self.panel_scroll = [] @@ -49,7 +48,13 @@ def __init__(self, stdscr, **kwargs): self.screen.setscrreg(0, self.rows - 1) curses.start_color() curses.use_default_colors() - self.color_names, self.color_backgrounds = color_names(kwargs.get("color_names")) + if kwargs.get("color_map", True): + self.color_names, self.color_backgrounds = color_names(kwargs.get("color_names")) + else: + self.color_names = dict() + self.color_backgrounds = [] + self.color_default = kwargs.get("color_default", None) + def curs_set(self, set_cursor): curses.curs_set(set_cursor) @@ -131,7 +136,7 @@ def print(self, content="", color=None, **kwargs): color = self.color_names[color] if not isinstance(panel, list): self.screen.addstr(set_y, set_x, content, - cpi(self.color_default, color) + cpi(self, color) | format_text_list[0] | format_text_list[1] | format_text_list[2] @@ -167,7 +172,7 @@ def print(self, content="", color=None, **kwargs): panel_y = self.panel_dimensions[panel[1]][0] - border_offset self.panels[panel[0]][panel[1]].addstr( panel_y, panel_x, content, - cpi(self.color_default, color) + cpi(self, color) | format_text_list[0] | format_text_list[1] | format_text_list[2] @@ -215,7 +220,7 @@ def insstr(self, char="", x=None, y=None, color=None, **kwargs): color = self.color_default elif isinstance(color, str): color = self.color_names[color] - self.screen.insstr(y, x, char, cpi(self.color_default, color) + self.screen.insstr(y, x, char, cpi(self, color) | format_text_list[0] | format_text_list[1] | format_text_list[2] @@ -247,7 +252,7 @@ def addstr(self, content, x, y, color=None, **kwargs): elif isinstance(color, str): color = self.color_names[color] self.screen.addstr(y + self.title_offset, x, content, - cpi(self.color_default, color) + cpi(self, color) | format_text_list[0] | format_text_list[1] | format_text_list[2] @@ -274,7 +279,7 @@ def rectangle(self, x, y, width, height, color=None): for j in range(y + self.title_offset, y + height - self.title_bottom_offset): for i in range(x, x + width): - self.screen.addstr(j, i, " ", cpi(self.color_default, color)) + self.screen.addstr(j, i, " ", cpi(self, color)) def background(self, color): """ @@ -283,7 +288,7 @@ def background(self, color): for j in range(0 + self.title_offset, self.rows - self.title_bottom_offset): for i in range(0, self.cols): - self.screen.insstr(j, i, " ", cpi(self.color_default, color)) + self.screen.insstr(j, i, " ", cpi(self, color)) def layout(self, layout_name, **kwargs): self.panels["layout"] = getattr(layout, layout_name)(self, **kwargs) diff --git a/docs/colors.md b/docs/colors.md index e1044ec..b7eb885 100644 --- a/docs/colors.md +++ b/docs/colors.md @@ -1,9 +1,32 @@ # Colors -Color text in curses is usually done via a `color_pairs` method. With Dashport, color pairs (foreground and background) are defined with a single integer which sets both backgrounnd and foreground. +Color text in curses is usually done via a `color_pairs` method. With Dashport, color pairs (foreground and background) are defined with a single string which sets both background and foreground using plain English words connected by the string `_on_`. So, if you want red text on a white background, the color definition would be `red_on_white`. Set the `color_default` value when starting a Dashport object to set the default text color value. Setting the color_default to `None` will set the default color to the default colors of the terminal session. +``` +from dashport.dash import Dashport, Info +from dashport.run import wrap + +def info(stdscr): + return Info(stdscr) + +def dashport(stdscr): + app = Dashport(stdscr, color_default="green_on_white") + app.print("hello world", color="red_on_white") + app.print("plain text, colored with color_default") + app.print("black on blue text", color="black_on_blue") + while True: + app.refresh() + + +if __name__ == '__main__': + wrap(dashport, info) + +``` + + + The `background` method will fill the background with the background for the `color` selected. It does this by setting down a space character in every text position. It's best to use background before any other printing commands. Use the `rectangle` method to draw a rectangle. It's best to keep rectangles away from the edges or corners of the screen, or filling up the entire screen. Use `background` to fill the screen with a color, or insstr to insert a string into the corner. @@ -16,11 +39,11 @@ def info(stdscr): return Info(stdscr) def dashport(stdscr): - app = Dashport(stdscr, color_default=8) - app.print("this text won't show", color=3) - app.background(color=18) - app.print("some color text", x=20, color=3) - app.rectangle(10, 10, 12, 12, color=98) + app = Dashport(stdscr, color_default="yellow_on_blue") + app.print("this text won't show") + app.background(color="white_on_maroon") + app.print("some color text", x=20, color="blue_on_yellow") + app.rectangle(10, 10, 12, 12, color="blue_on_yellow") while True: app.refresh() @@ -29,9 +52,64 @@ if __name__ == '__main__': wrap(dashport, info) ``` -Use this table to find the color scheme appropriate for your app: +## Default Color Definitions + +In Python's implementation of curses there are 255 color pair positions available to define colors, and by default, Dashport uses those color pairs for color definitions. These are the colors Dashport defines. Run the `examples/util/color_palette.py` program in the examples folder for an interactive guide in showing how all the colors will look on your screen: + +- default +- black +- maroon +- green +- olive +- navy +- purple +- teal +- silver +- grey +- red +- lime +- yellow +- blue +- fuchsia +- aqua +- white + +Whenever a Dashport command, like `print`, uses a `color` argument, you can use the standard `_on_` formatted string to define the foreground and background. -![color palette for dashport](images/color_palette.png) +``` +# This creates blue color text with a yellow background. +app.print("some color text", color="blue_on_yellow") +``` + +Due to the limit of 255 color pairs, the `olive` and `teal` colors are not available as background colors, but you can still use them as background colors, simply by formatting them with an A_REVERSE argument in the print command: + +``` +# This creates black text on an olive background. +app.print("some color text", color="olive_on_black", A_REVERSE=True) +``` + +# Defining your own color definitions with curses + +You can still use regular color pairs you've defined in curses, if you want to get an exact color. When initiating Dashport, set the color_map option to False, and then create color pairs just as you would with the normal curses library. You can still use Dashport's `print` and other string commands, passing in the integer of the color pair you've defined, rather than a string. + +``` +from dashport.dash import Dashport +from dashport.run import wrap +import curses + +def dashport(stdscr): + app = Dashport(stdscr, color_map=False) + curses.init_pair(1, 2, 4) + app.print("plain text") + app.print("plain text, colored with a curses color pair", color=1) + while True: + app.refresh() + + +if __name__ == '__main__': + wrap(dashport) + +``` # Formatting text @@ -46,7 +124,7 @@ def info(stdscr): return Info(stdscr) def dashport(stdscr): - app = Dashport(stdscr, color_default=8) + app = Dashport(stdscr, color_default="green_on_white") app.print("This text is bold.", A_BOLD=True) app.print("This text is italic.", A_ITALIC=True) while True: diff --git a/examples/boilerplate/color_example.py b/examples/boilerplate/color_example.py new file mode 100755 index 0000000..e4c5b1d --- /dev/null +++ b/examples/boilerplate/color_example.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 +from dashport.dash import Dashport +from dashport.run import wrap + +def dashport(stdscr): + app = Dashport(stdscr, color_default="green_on_white") + app.print("hello world", color="red_on_white") + app.print("plain text, colored with color_default") + app.print("black text on blue background", color="black_on_blue") + while True: + app.refresh() + + +if __name__ == '__main__': + wrap(dashport) diff --git a/examples/boilerplate/rectangle.py b/examples/boilerplate/rectangle.py index 64e9d7b..e19c64b 100755 --- a/examples/boilerplate/rectangle.py +++ b/examples/boilerplate/rectangle.py @@ -12,15 +12,15 @@ def quit(stdscr): def dashport(stdscr): - app = Dashport(stdscr, color_default=17) + app = Dashport(stdscr, color_default="yellow_on_blue") app.add_control("q", quit, case_sensitive=False) # This text won't show because the background will overwrite it. app.print("This text won't show.", x=5, y=5) # Color 109 is a blue background - app.background(color=109) + app.background(color="white_on_maroon") # This text will show because it comes after the background. app.print("printing on top of text") - app.rectangle(10, 10, 12, 12, color=98) + app.rectangle(10, 10, 12, 12, color="blue_on_yellow") while True: app.refresh()