From 28972a1e64ca9acb9a26000ca35b594a7a1d024b Mon Sep 17 00:00:00 2001 From: Clement Tsang <34804052+ClementTsang@users.noreply.github.com> Date: Mon, 29 Jul 2024 09:03:35 +0000 Subject: [PATCH] refactor: refactor styling options (#1499) Introduce a new configuration system for styling. --- CHANGELOG.md | 5 +- .../configuration/command-line-options.md | 2 +- .../configuration/config-file/flags.md | 1 - .../configuration/config-file/styling.md | 159 +++++ .../configuration/config-file/theming.md | 33 - docs/content/troubleshooting.md | 17 +- docs/mkdocs.yml | 2 +- sample_configs/default_config.toml | 88 +-- sample_configs/demo_config.toml | 3 + schema/nightly/bottom.json | 573 +++++++++++++----- src/app.rs | 16 +- src/canvas.rs | 42 +- src/canvas/components/data_table/styling.rs | 6 +- src/canvas/dialogs/dd_dialog.rs | 10 +- src/canvas/styling.rs | 305 ---------- src/canvas/widgets/battery_display.rs | 8 +- src/canvas/widgets/cpu_basic.rs | 2 +- src/canvas/widgets/cpu_graph.rs | 6 +- src/canvas/widgets/mem_basic.rs | 2 +- src/canvas/widgets/mem_graph.rs | 2 +- src/canvas/widgets/process_table.rs | 8 +- src/constants.rs | 346 ++--------- src/main.rs | 16 +- src/options.rs | 109 ++-- src/options/args.rs | 6 +- src/options/colours.rs | 47 -- src/options/config.rs | 53 +- src/options/config/flags.rs | 45 ++ src/options/config/layout.rs | 14 +- src/options/config/style.rs | 260 ++++++++ src/options/config/style/battery.rs | 12 + src/options/config/style/cpu.rs | 18 + src/options/config/style/graphs.rs | 13 + src/options/config/style/memory.rs | 15 + src/options/config/style/network.rs | 19 + src/options/config/style/tables.rs | 10 + src/options/config/style/themes.rs | 20 + src/options/config/style/themes/default.rs | 110 ++++ src/options/config/style/themes/gruvbox.rs | 127 ++++ src/options/config/style/themes/nord.rs | 103 ++++ .../config/style/utils.rs} | 99 ++- src/options/config/style/widgets.rs | 16 + src/widgets/cpu_graph.rs | 21 +- src/widgets/disk_table.rs | 14 +- src/widgets/process_table.rs | 22 +- src/widgets/temperature_table.rs | 14 +- tests/integration/valid_config_tests.rs | 15 + tests/invalid_configs/invalid_colour_hex.toml | 4 +- .../invalid_configs/invalid_colour_hex_2.toml | 4 +- .../invalid_configs/invalid_colour_hex_3.toml | 4 +- .../invalid_configs/invalid_colour_name.toml | 4 +- tests/invalid_configs/invalid_colour_rgb.toml | 4 +- .../invalid_configs/invalid_colour_rgb_2.toml | 4 +- .../invalid_colour_string.toml | 4 +- tests/valid_configs/styling.toml | 13 + tests/valid_configs/styling_2.toml | 53 ++ tests/valid_configs/theme.toml | 4 + 57 files changed, 1763 insertions(+), 1169 deletions(-) create mode 100644 docs/content/configuration/config-file/styling.md delete mode 100644 docs/content/configuration/config-file/theming.md delete mode 100644 src/canvas/styling.rs delete mode 100644 src/options/colours.rs create mode 100644 src/options/config/flags.rs create mode 100644 src/options/config/style.rs create mode 100644 src/options/config/style/battery.rs create mode 100644 src/options/config/style/cpu.rs create mode 100644 src/options/config/style/graphs.rs create mode 100644 src/options/config/style/memory.rs create mode 100644 src/options/config/style/network.rs create mode 100644 src/options/config/style/tables.rs create mode 100644 src/options/config/style/themes.rs create mode 100644 src/options/config/style/themes/default.rs create mode 100644 src/options/config/style/themes/gruvbox.rs create mode 100644 src/options/config/style/themes/nord.rs rename src/{canvas/styling/colour_utils.rs => options/config/style/utils.rs} (75%) create mode 100644 src/options/config/style/widgets.rs create mode 100644 tests/valid_configs/styling.toml create mode 100644 tests/valid_configs/styling_2.toml create mode 100644 tests/valid_configs/theme.toml diff --git a/CHANGELOG.md b/CHANGELOG.md index d7130cce..58a88759 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `expanded_on_startup` is now `expanded`. - `left_legend` is now `cpu_left_legend`. - [#1472](https://github.com/ClementTsang/bottom/pull/1472): The following arguments have changed names: - - `mem_as_value` is now `process_memory_as_value`. + - `--mem_as_value` is now `process_memory_as_value`. - [#1472](https://github.com/ClementTsang/bottom/pull/1472): The following config fields have changed names: - `mem_as_value` is now `process_memory_as_value`. - [#1481](https://github.com/ClementTsang/bottom/pull/1481): The following config fields have changed names: @@ -33,6 +33,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `mount_filter` is now `disk.mount_filter`. - `temp_filter` is now `temperature.sensor_filter` - `net_filter` is now `network.interface_filter` +- [#1499](https://github.com/ClementTsang/bottom/pull/1499): Redesign how styling is configured. +- [#1499](https://github.com/ClementTsang/bottom/pull/1499): The following arguments have changed names: + - `--colors` is now `--theme` ### Bug Fixes diff --git a/docs/content/configuration/command-line-options.md b/docs/content/configuration/command-line-options.md index e32a059b..03384166 100644 --- a/docs/content/configuration/command-line-options.md +++ b/docs/content/configuration/command-line-options.md @@ -86,7 +86,7 @@ see information on these options by running `btm -h`, or run `btm --help` to dis | Option | Behaviour | | ------------------------ | ------------------------------------------ | -| `--color ` | Use a color scheme, use `--help` for info. | +| `--theme ` | Use a color scheme, use `--help` for info. | ## Other Options diff --git a/docs/content/configuration/config-file/flags.md b/docs/content/configuration/config-file/flags.md index 87c825b8..73b83d84 100644 --- a/docs/content/configuration/config-file/flags.md +++ b/docs/content/configuration/config-file/flags.md @@ -35,7 +35,6 @@ each time: | `default_widget_type` | String (one of ["cpu", "proc", "net", "temp", "mem", "disk"], same as layout options) | Sets the default widget type, use --help for more info. | | `default_widget_count` | Unsigned Int (represents which `default_widget_type`) | Sets the n'th selected widget type as the default. | | `disable_click` | Boolean | Disables mouse clicks. | -| `color` | String (one of ["default", "default-light", "gruvbox", "gruvbox-light", "nord", "nord-light"]) | Use a color scheme, use --help for supported values. | | `enable_cache_memory` | Boolean | Enable cache and buffer memory stats (not available on Windows). | | `process_memory_as_value` | Boolean | Defaults to showing process memory usage by value. | | `tree` | Boolean | Defaults to showing the process widget in tree mode. | diff --git a/docs/content/configuration/config-file/styling.md b/docs/content/configuration/config-file/styling.md new file mode 100644 index 00000000..5a533480 --- /dev/null +++ b/docs/content/configuration/config-file/styling.md @@ -0,0 +1,159 @@ +# Styling + +Various parts of the bottom can be styled, using either built-in themes or custom theming. + +## Precedence + +As there are a few ways styles can be applied to bottom, the order of which styles are prioritized are, in order of +highest precedence to lowest precedence: + +1. Built-in themes set via command-line args (e.g. `btm --theme gruvbox`) +2. Custom themes set via config file +3. Built-in themes set via config file + +If nothing is set, it will fall back to the default theme. + +## Built-in styles + +bottom has a few built-in themes: + +- Default +- [Nord](https://www.nordtheme.com/) +- [Gruvbox](https://github.com/morhetz/gruvbox) + +These themes all also have light variants to support terminals using lighter colours. + +To set the theme from the command line: + +```bash +btm --theme gruvbox +``` + +To set the theme using the config file: + +```toml +[styles] +theme = "gruvbox" +``` + +## Custom styling + +bottom's components can also be individually styled by the user to control the colour of the text style. + +### Colours + +You can configure the colours for components with strings that are either hex colours (e.g. `"#ffffff"`), RGB colours +(e.g. `"255, 255, 255"`), or named colours. Named colours are one of the following strings: + +- `"Black"` +- `"Red"` +- `"Green"` +- `"Yellow"` +- `"Blue"` +- `"Magenta"` +- `"Cyan"` +- `"Gray"` +- `"DarkGray"` +- `"LightRed"` +- `"LightGreen"` +- `"LightYellow"` +- `"LightBlue"` +- `"LightMagenta"` +- `"LightCyan"` +- `"White"` + +### Text + +Text can generally be styled using the following TOML table: + +```toml +[field] +# The foreground colour of text. +color = "black" + +# The background colour of text. +bg_color = "blue" + +# Whether to make the text bold. +bold = false + +# Inline table version +field = { color = "black", bg_color = "blue", bold = false } +``` + +All fields are optional; by default if `bg_color` is not set then there will be no background color. + +### Configuration + +#### CPU + +These can be set under `[styles.cpu]`: + +| Config field | Details | Examples | +| ----------------- | ---------------------------------------------------------------- | -------------------------------------------- | +| `all_entry_color` | The colour of the "All" CPU label | `all_entry_color = "Red"` | +| `avg_entry_color` | The colour of the average CPU label and graph line | `avg_entry_color = "255, 0, 255"` | +| `cpu_core_colors` | Colour of each CPU threads' label and graph line. Read in order. | `cpu_core_colors = ["Red", "Blue", "Green"]` | + +#### Memory + +These can be set under `[styles.memory]`: + +| Config field | Details | Examples | +| ------------ | ------------------------------------------------------------------------------ | --------------------------------- | +| `ram` | The colour of the RAM label and graph line | `ram = "Red"` | +| `cache` | The colour of the cache label and graph line. Does not do anything on Windows. | `cache = "#ffffff"` | +| `swap` | The colour of the swap label and graph line | `swap = "255, 0, 255"` | +| `arc` | The colour of the ARC label and graph line | `arc = "Blue"` | +| `gpus` | Colour of each GPU's memory label and graph line. Read in order. | `gpus = ["Red", "Blue", "Green"]` | + +#### Network + +These can be set under `[styles.network]`: + +| Config field | Details | Examples | +| ------------ | --------------------------------------------------------- | ---------------------- | +| `rx` | The colour of the RX (download) label and graph line | `rx = "Red"` | +| `tx` | The colour of the TX (upload) label and graph line. | `tx = "#ffffff"` | +| `rx_total` | The colour of the total RX (download) label in basic mode | `rx_total = "0, 0, 0"` | +| `tx_total` | The colour of the total TX (upload) label in basic mode | `tx_total = "#000"` | + +#### Battery + +These can be set under `[styles.battery]`: + +| Config field | Details | Examples | +| ---------------- | ------------------------------------------------------------------------ | ---------------------------- | +| `high_battery` | The colour of the battery widget bar when the battery is over 50% | `high_battery = "Red"` | +| `medium_battery` | The colour of the battery widget bar when the battery between 10% to 50% | `medium_battery = "#ffffff"` | +| `low_battery` | The colour of the battery widget bar when the battery is under 10% | `low_battery = "0, 0, 0"` | + +#### Tables + +These can be set under `[styles.tables]`: + +| Config field | Details | Examples | +| ------------ | ------------------------------ | -------------------------------------------------------------- | +| `headers` | Text styling for table headers | `headers = { color = "red", bg_color = "black", bold = true }` | + +#### Graphs + +These can be set under `[styles.graphs]`: + +| Config field | Details | Examples | +| ------------- | -------------------------------------------- | ------------------------------------------------------------------- | +| `graph_color` | The general colour of the parts of the graph | `graph_color = "white"` | +| `legend_text` | Text styling for graph's legend text | `legend_text = { color = "black", bg_color = "blue", bold = true }` | + +#### General widget settings + +These can be set under `[styles.widgets]`: + +| Config field | Details | Examples | +| ----------------- | ------------------------------------------------------------ | --------------------------------------------------------------------- | +| `border` | The colour of the widgets' borders | `border = "white"` | +| `selected_border` | The colour of a widget's borders when the widget is selected | `selected_border = "white"` | +| `widget_title` | Text styling for a widget's title | `widget_title = { color = "black", bg_color = "blue", bold = true }` | +| `text` | Text styling for text in general | `text = { color = "black", bg_color = "blue", bold = true }` | +| `selected_text` | Text styling for text when representing something selected | `selected_text = { color = "black", bg_color = "blue", bold = true }` | +| `disabled_text` | Text styling for text when representing something disabled | `disabled_text = { color = "black", bg_color = "blue", bold = true }` | diff --git a/docs/content/configuration/config-file/theming.md b/docs/content/configuration/config-file/theming.md deleted file mode 100644 index 4d9e03f1..00000000 --- a/docs/content/configuration/config-file/theming.md +++ /dev/null @@ -1,33 +0,0 @@ -# Theming - -!!! Warning - - This section is in progress, and is just copied from the old documentation. - -The config file can be used to set custom colours for parts of the application under the `[colors]` object. The following labels are customizable with strings that are hex colours, RGB colours, or specific named colours. - -Supported named colours are one of the following strings: `Reset, Black, Red, Green, Yellow, Blue, Magenta, Cyan, Gray, DarkGray, LightRed, LightGreen, LightYellow, LightBlue, LightMagenta, LightCyan, White`. - -| Labels | Details | Example | -| ------------------------------- | ------------------------------------------------------- | ------------------------------------------------------- | -| Table header colours | Colour of table headers | `table_header_color="255, 255, 255"` | -| CPU colour per core | Colour of each core. Read in order. | `cpu_core_colors=["#ffffff", "white", "255, 255, 255"]` | -| Average CPU colour | The average CPU color | `avg_cpu_color="White"` | -| All CPUs colour | The colour for the "All" CPU label | `all_cpu_color="White"` | -| RAM | The colour RAM will use | `ram_color="#ffffff"` | -| SWAP | The colour SWAP will use | `swap_color="#ffffff"` | -| RX | The colour rx will use | `rx_color="#ffffff"` | -| TX | The colour tx will use | `tx_color="#ffffff"` | -| Widget title colour | The colour of the label each widget has | `widget_title_color="#ffffff"` | -| Border colour | The colour of the border of unselected widgets | `border_color="#ffffff"` | -| Selected border colour | The colour of the border of selected widgets | `highlighted_border_color="#ffffff"` | -| Text colour | The colour of most text | `text_color="#ffffff"` | -| Graph colour | The colour of the lines and text of the graph | `graph_color="#ffffff"` | -| Cursor colour | The cursor's colour | `cursor_color="#ffffff"` | -| Selected text colour | The colour of text that is selected | `scroll_entry_text_color="#ffffff"` | -| Selected text background colour | The background colour of text that is selected | `scroll_entry_bg_color="#ffffff"` | -| High battery level colour | The colour used for a high battery level (100% to 50%) | `high_battery_color="green"` | -| Medium battery level colour | The colour used for a medium battery level (50% to 10%) | `medium_battery_color="yellow"` | -| Low battery level colour | The colour used for a low battery level (10% to 0%) | `low_battery_color="red"` | -| GPU colour per gpu | Colour of each gpu. Read in order. | `gpu_core_colors=["#ffffff", "white", "255, 255, 255"]` | -| ARC | The colour ARC will use | `arc_color="#ffffff"` | diff --git a/docs/content/troubleshooting.md b/docs/content/troubleshooting.md index 45292c85..3a56fcec 100644 --- a/docs/content/troubleshooting.md +++ b/docs/content/troubleshooting.md @@ -106,23 +106,28 @@ If your configuration files aren't working, here are a few things to try: ### Check the formatting -It may be handy to refer to the automatically generated config files or the [sample configuration files](https://github.com/ClementTsang/bottom/tree/main/sample_configs). -The config files also follow the [TOML](https://toml.io/en/) format. +It may be handy to refer to the automatically generated config files or the +[sample configuration files](https://github.com/ClementTsang/bottom/tree/main/sample_configs). The config files also +follow the [TOML](https://toml.io/en/) format. -Also make sure your config options are under the right table - for example, to set your temperature type, you must set it under the `[flags]` table: +Also make sure your config options are under the right table - for example, to set your temperature type, you must +set it under the `[flags]` table: ```toml [flags] temperature_type = "f" ``` -Meanwhile, if you want to set a custom color scheme, it would be under the `[colors]` table: +Meanwhile, if you want to set a custom color scheme, it would be under the `[styles]` table: ```toml -[colors] -table_header_color="LightBlue" +[styles.tables.headers] +color="LightBlue" ``` +To help validate your configuration files, there is [JSON Schema](https://json-schema.org/) support if your IDE/editor +supports it. + ### Check the configuration file location Make sure bottom is reading the right configuration file. By default, bottom looks for config files at these locations: diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index c87b6c94..df31da81 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -166,7 +166,7 @@ nav: - "Config File": - configuration/config-file/index.md - "Flags": configuration/config-file/flags.md - - "Theming": configuration/config-file/theming.md + - "Styling": configuration/config-file/styling.md - "Layout": configuration/config-file/layout.md - "Data Filtering": configuration/config-file/data-filtering.md - "Processes": configuration/config-file/processes.md diff --git a/sample_configs/default_config.toml b/sample_configs/default_config.toml index f5ab351f..ce116e2e 100644 --- a/sample_configs/default_config.toml +++ b/sample_configs/default_config.toml @@ -127,43 +127,57 @@ # These are all the components that support custom theming. Note that colour support # will depend on terminal support. -#[colors] # Uncomment if you want to use custom colors -# Represents the colour of table headers (processes, CPU, disks, temperature). -#table_header_color="LightBlue" -# Represents the colour of the label each widget has. -#widget_title_color="Gray" -# Represents the average CPU color. -#avg_cpu_color="Red" -# Represents the colour the core will use in the CPU legend and graph. -#cpu_core_colors=["LightMagenta", "LightYellow", "LightCyan", "LightGreen", "LightBlue", "LightRed", "Cyan", "Green", "Blue", "Red"] -# Represents the colour RAM will use in the memory legend and graph. -#ram_color="LightMagenta" -# Represents the colour SWAP will use in the memory legend and graph. -#swap_color="LightYellow" -# Represents the colour ARC will use in the memory legend and graph. -#arc_color="LightCyan" -# Represents the colour the GPU will use in the legend and graph. -#gpu_core_colors=["LightGreen", "LightBlue", "LightRed", "Cyan", "Green", "Blue", "Red"] -# Represents the colour rx will use in the network legend and graph. -#rx_color="LightCyan" -# Represents the colour tx will use in the network legend and graph. -#tx_color="LightGreen" -# Represents the colour of the border of unselected widgets. -#border_color="Gray" -# Represents the colour of the border of selected widgets. -#highlighted_border_color="LightBlue" -# Represents the colour of most text. -#text_color="Gray" -# Represents the colour of text that is selected. -#selected_text_color="Black" -# Represents the background colour of text that is selected. -#selected_bg_color="LightBlue" -# Represents the colour of the lines and text of the graph. -#graph_color="Gray" -# Represents the colours of the battery based on charge -#high_battery_color="green" -#medium_battery_color="yellow" -#low_battery_color="red" +#[styles] # Uncomment if you want to use custom styling + +# Built-in themes. Valid values are: +# - "default" +# - "default-light" +# - "gruvbox" +# - "gruvbox-light" +# - "nord" +# - "nord-light". +# +# This will have the lowest precedence if a custom colour palette is set, +# or overriden if the command-line flag for a built-in theme is set. +#theme = "default" + +#[styles.cpu] +#all_entry_color = "green" +#avg_entry_color = "red" +#cpu_core_colors = ["light magenta", "light yellow", "light cyan", "light green", "light blue", "cyan", "green", "blue"] + +#[styles.memory] +#ram = "light magenta" +#cache = "light red" +#swap = "light yellow" +#arc = "light cyan" +#gpus = ["light blue", "light red", "cyan", "green", "blue", "red"] + +#[styles.network] +#rx = "light magenta" +#tx = "light yellow" +#rx_total = "light cyan" +#tx_total = "light green" + +#[styles.battery] +#high_battery = "green" +#medium_battery = "yellow" +#low_battery = "red" + +#[styles.tables] +#headers = {color = "light blue"} + +#[styles.graphs] +#graph_color = "gray" +#legend_text = {color = "gray"} + +#[styles.widgets] +#border = "gray" +#selected_border = "light blue" +#widget_title = {color = "gray"} +#text = {color = "gray"} +#selected_text = {color = "black", bg_color = "light blue"} +#disabled_text = {color = "dark gray"} # Layout - layouts follow a pattern like this: # [[row]] represents a row in the application. diff --git a/sample_configs/demo_config.toml b/sample_configs/demo_config.toml index 32dd50cd..4a4db938 100644 --- a/sample_configs/demo_config.toml +++ b/sample_configs/demo_config.toml @@ -13,3 +13,6 @@ whole_word = false regex = true default_widget_type = "cpu" default_widget_count = 1 + +[styles] +theme = "gruvbox" diff --git a/schema/nightly/bottom.json b/schema/nightly/bottom.json index 22eecb4c..06dd6546 100644 --- a/schema/nightly/bottom.json +++ b/schema/nightly/bottom.json @@ -5,16 +5,6 @@ "description": "https://clementtsang.github.io/bottom/nightly/configuration/config-file", "type": "object", "properties": { - "colors": { - "anyOf": [ - { - "$ref": "#/definitions/ColoursConfig" - }, - { - "type": "null" - } - ] - }, "cpu": { "anyOf": [ { @@ -74,6 +64,16 @@ "$ref": "#/definitions/row" } }, + "styles": { + "anyOf": [ + { + "$ref": "#/definitions/StyleConfig" + }, + { + "type": "null" + } + ] + }, "temperature": { "anyOf": [ { @@ -86,162 +86,45 @@ } }, "definitions": { - "ColoursConfig": { - "description": "Colour configuration.", + "BatteryStyle": { + "description": "Styling specific to the battery widget.", "type": "object", "properties": { - "all_cpu_color": { - "type": [ - "string", - "null" + "high_battery": { + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } ] }, - "arc_color": { - "type": [ - "string", - "null" + "low_battery": { + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } ] }, - "avg_cpu_color": { - "type": [ - "string", - "null" - ] - }, - "border_color": { - "type": [ - "string", - "null" - ] - }, - "cache_color": { - "type": [ - "string", - "null" - ] - }, - "cpu_core_colors": { - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "disabled_text_color": { - "type": [ - "string", - "null" - ] - }, - "gpu_core_colors": { - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "graph_color": { - "type": [ - "string", - "null" - ] - }, - "high_battery_color": { - "type": [ - "string", - "null" - ] - }, - "highlighted_border_color": { - "type": [ - "string", - "null" - ] - }, - "low_battery_color": { - "type": [ - "string", - "null" - ] - }, - "medium_battery_color": { - "type": [ - "string", - "null" - ] - }, - "ram_color": { - "type": [ - "string", - "null" - ] - }, - "rx_color": { - "type": [ - "string", - "null" - ] - }, - "rx_total_color": { - "type": [ - "string", - "null" - ] - }, - "selected_bg_color": { - "type": [ - "string", - "null" - ] - }, - "selected_text_color": { - "type": [ - "string", - "null" - ] - }, - "swap_color": { - "type": [ - "string", - "null" - ] - }, - "table_header_color": { - "type": [ - "string", - "null" - ] - }, - "text_color": { - "type": [ - "string", - "null" - ] - }, - "tx_color": { - "type": [ - "string", - "null" - ] - }, - "tx_total_color": { - "type": [ - "string", - "null" - ] - }, - "widget_title_color": { - "type": [ - "string", - "null" + "medium_battery": { + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } ] } } }, + "ColorStr": { + "type": "string" + }, "CpuConfig": { "description": "CPU column settings.", "type": "object", @@ -259,6 +142,41 @@ "average" ] }, + "CpuStyle": { + "description": "Styling specific to the CPU widget.", + "type": "object", + "properties": { + "all_entry_color": { + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } + ] + }, + "avg_entry_color": { + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } + ] + }, + "cpu_core_colors": { + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/ColorStr" + } + } + } + }, "DiskConfig": { "description": "Disk configuration.", "type": "object", @@ -340,13 +258,6 @@ "null" ] }, - "color": { - "description": "For built-in colour palettes.", - "type": [ - "string", - "null" - ] - }, "cpu_left_legend": { "type": [ "boolean", @@ -565,6 +476,32 @@ } } }, + "GraphStyle": { + "description": "General styling for graph widgets.", + "type": "object", + "properties": { + "graph_color": { + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } + ] + }, + "legend_text": { + "anyOf": [ + { + "$ref": "#/definitions/TextStyleConfig" + }, + { + "type": "null" + } + ] + } + } + }, "IgnoreList": { "type": "object", "required": [ @@ -595,6 +532,61 @@ } } }, + "MemoryStyle": { + "description": "Styling specific to the memory widget.", + "type": "object", + "properties": { + "arc": { + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } + ] + }, + "cache": { + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } + ] + }, + "gpus": { + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/ColorStr" + } + }, + "ram": { + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } + ] + }, + "swap": { + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } + ] + } + } + }, "NetworkConfig": { "description": "Network configuration.", "type": "object", @@ -612,6 +604,54 @@ } } }, + "NetworkStyle": { + "description": "Styling specific to the network widget.", + "type": "object", + "properties": { + "rx": { + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } + ] + }, + "rx_total": { + "description": "Set the colour of the \"rx total\" text. This only affects basic mode.", + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } + ] + }, + "tx": { + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } + ] + }, + "tx_total": { + "description": "Set the colour of the \"tx total\" text. This only affects basic mode.", + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } + ] + } + } + }, "ProcColumn": { "description": "A column in the process widget.", "type": "string", @@ -696,6 +736,112 @@ } ] }, + "StyleConfig": { + "description": "Style-related configs.", + "type": "object", + "properties": { + "battery": { + "description": "Styling for the battery widget.", + "anyOf": [ + { + "$ref": "#/definitions/BatteryStyle" + }, + { + "type": "null" + } + ] + }, + "cpu": { + "description": "Styling for the CPU widget.", + "anyOf": [ + { + "$ref": "#/definitions/CpuStyle" + }, + { + "type": "null" + } + ] + }, + "graphs": { + "description": "Styling for graph widgets.", + "anyOf": [ + { + "$ref": "#/definitions/GraphStyle" + }, + { + "type": "null" + } + ] + }, + "memory": { + "description": "Styling for the memory widget.", + "anyOf": [ + { + "$ref": "#/definitions/MemoryStyle" + }, + { + "type": "null" + } + ] + }, + "network": { + "description": "Styling for the network widget.", + "anyOf": [ + { + "$ref": "#/definitions/NetworkStyle" + }, + { + "type": "null" + } + ] + }, + "tables": { + "description": "Styling for table widgets.", + "anyOf": [ + { + "$ref": "#/definitions/TableStyle" + }, + { + "type": "null" + } + ] + }, + "theme": { + "description": "A built-in theme.\n\nIf this is and a custom colour are both set, in the config file, the custom colour scheme will be prioritized first. If a theme is set in the command-line args, however, it will always be prioritized first.", + "type": [ + "string", + "null" + ] + }, + "widgets": { + "description": "Styling for general widgets.", + "anyOf": [ + { + "$ref": "#/definitions/WidgetStyle" + }, + { + "type": "null" + } + ] + } + } + }, + "TableStyle": { + "description": "General styling for table widgets.", + "type": "object", + "properties": { + "headers": { + "anyOf": [ + { + "$ref": "#/definitions/TextStyleConfig" + }, + { + "type": "null" + } + ] + } + } + }, "TempConfig": { "description": "Temperature configuration.", "type": "object", @@ -713,6 +859,107 @@ } } }, + "TextStyleConfig": { + "description": "A style for text.", + "type": "object", + "properties": { + "bg_color": { + "description": "A built-in ANSI colour, RGB hex, or RGB colour code.", + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } + ] + }, + "bold": { + "description": "Whether to make this text bolded or not. If not set, will default to built-in defaults.", + "type": [ + "boolean", + "null" + ] + }, + "color": { + "description": "A built-in ANSI colour, RGB hex, or RGB colour code.", + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } + ] + } + } + }, + "WidgetStyle": { + "description": "General styling for generic widgets.", + "type": "object", + "properties": { + "border": { + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } + ] + }, + "disabled_text": { + "anyOf": [ + { + "$ref": "#/definitions/TextStyleConfig" + }, + { + "type": "null" + } + ] + }, + "selected_border": { + "anyOf": [ + { + "$ref": "#/definitions/ColorStr" + }, + { + "type": "null" + } + ] + }, + "selected_text": { + "anyOf": [ + { + "$ref": "#/definitions/TextStyleConfig" + }, + { + "type": "null" + } + ] + }, + "text": { + "anyOf": [ + { + "$ref": "#/definitions/TextStyleConfig" + }, + { + "type": "null" + } + ] + }, + "widget_title": { + "anyOf": [ + { + "$ref": "#/definitions/TextStyleConfig" + }, + { + "type": "null" + } + ] + } + } + }, "row": { "description": "Represents a row. This has a length of some sort (optional) and a vector of children.", "type": "object", diff --git a/src/app.rs b/src/app.rs index ec0dd1bc..7cfe0af1 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1529,16 +1529,14 @@ impl App { } fn move_widget_selection_logic(&mut self, direction: &WidgetDirection) { - /* - The actual logic for widget movement. + // The actual logic for widget movement. - We follow these following steps: - 1. Send a movement signal in `direction`. - 2. Check if this new widget we've landed on is hidden. If not, halt. - 3. If it hidden, loop and either send: - - A signal equal to the current direction, if it is opposite of the reflection. - - Reflection direction. - */ + // We follow these following steps: + // 1. Send a movement signal in `direction`. + // 2. Check if this new widget we've landed on is hidden. If not, halt. + // 3. If it hidden, loop and either send: + // - A signal equal to the current direction, if it is opposite of the reflection. + // - Reflection direction. if !self.ignore_normal_keybinds() && !self.is_expanded { if let Some(new_widget_id) = &(match direction { diff --git a/src/canvas.rs b/src/canvas.rs index 35096ee5..3ecc446f 100644 --- a/src/canvas.rs +++ b/src/canvas.rs @@ -1,13 +1,9 @@ pub mod components; mod dialogs; mod drawing_utils; -pub mod styling; mod widgets; -use std::str::FromStr; - use itertools::izip; -use styling::*; use tui::{ backend::Backend, layout::{Constraint, Direction, Layout, Rect}, @@ -22,42 +18,12 @@ use crate::{ App, }, constants::*, - options::OptionError, + options::config::style::ColourPalette, }; -#[derive(Debug)] -pub enum ColourScheme { - Default, - DefaultLight, - Gruvbox, - GruvboxLight, - Nord, - NordLight, - Custom, -} - -impl FromStr for ColourScheme { - type Err = OptionError; - - fn from_str(s: &str) -> Result { - let lower_case = s.to_lowercase(); - match lower_case.as_str() { - "default" => Ok(ColourScheme::Default), - "default-light" => Ok(ColourScheme::DefaultLight), - "gruvbox" => Ok(ColourScheme::Gruvbox), - "gruvbox-light" => Ok(ColourScheme::GruvboxLight), - "nord" => Ok(ColourScheme::Nord), - "nord-light" => Ok(ColourScheme::NordLight), - _ => Err(OptionError::other(format!( - "'{s}' is an invalid built-in color scheme." - ))), - } - } -} - /// Handles the canvas' state. pub struct Painter { - pub colours: CanvasStyling, + pub colours: ColourPalette, previous_height: u16, previous_width: u16, @@ -81,7 +47,7 @@ pub enum LayoutConstraint { } impl Painter { - pub fn init(layout: BottomLayout, styling: CanvasStyling) -> anyhow::Result { + pub fn init(layout: BottomLayout, styling: ColourPalette) -> anyhow::Result { // Now for modularity; we have to also initialize the base layouts! // We want to do this ONCE and reuse; after this we can just construct // based on the console size. @@ -193,7 +159,7 @@ impl Painter { f.render_widget( Paragraph::new(Span::styled( "Frozen, press 'f' to unfreeze", - self.colours.currently_selected_text_style, + self.colours.selected_text_style, )), Layout::default() .horizontal_margin(1) diff --git a/src/canvas/components/data_table/styling.rs b/src/canvas/components/data_table/styling.rs index 80ce2b70..0006e8ec 100644 --- a/src/canvas/components/data_table/styling.rs +++ b/src/canvas/components/data_table/styling.rs @@ -1,6 +1,6 @@ use tui::style::Style; -use crate::canvas::styling::CanvasStyling; +use crate::options::config::style::ColourPalette; #[derive(Default)] pub struct DataTableStyling { @@ -13,13 +13,13 @@ pub struct DataTableStyling { } impl DataTableStyling { - pub fn from_colours(colours: &CanvasStyling) -> Self { + pub fn from_palette(colours: &ColourPalette) -> Self { Self { header_style: colours.table_header_style, border_style: colours.border_style, highlighted_border_style: colours.highlighted_border_style, text_style: colours.text_style, - highlighted_text_style: colours.currently_selected_text_style, + highlighted_text_style: colours.selected_text_style, title_style: colours.widget_title_style, } } diff --git a/src/canvas/dialogs/dd_dialog.rs b/src/canvas/dialogs/dd_dialog.rs index 225c95f8..f4b54a8b 100644 --- a/src/canvas/dialogs/dd_dialog.rs +++ b/src/canvas/dialogs/dd_dialog.rs @@ -211,12 +211,12 @@ impl Painter { if MAX_PROCESS_SIGNAL == 1 || !app_state.app_config_fields.is_advanced_kill { let (yes_button, no_button) = match app_state.delete_dialog_state.selected_signal { KillSignal::Kill(_) => ( - Span::styled("Yes", self.colours.currently_selected_text_style), + Span::styled("Yes", self.colours.selected_text_style), Span::styled("No", self.colours.text_style), ), KillSignal::Cancel => ( Span::styled("Yes", self.colours.text_style), - Span::styled("No", self.colours.currently_selected_text_style), + Span::styled("No", self.colours.selected_text_style), ), }; @@ -325,10 +325,8 @@ impl Painter { .map(|text| Span::styled(*text, self.colours.text_style)) .collect::>>(); buttons.insert(0, Span::styled(SIGNAL_TEXT[0], self.colours.text_style)); - buttons[selected - scroll_offset] = Span::styled( - SIGNAL_TEXT[selected], - self.colours.currently_selected_text_style, - ); + buttons[selected - scroll_offset] = + Span::styled(SIGNAL_TEXT[selected], self.colours.selected_text_style); app_state.delete_dialog_state.button_positions = layout .iter() diff --git a/src/canvas/styling.rs b/src/canvas/styling.rs deleted file mode 100644 index 5794f67d..00000000 --- a/src/canvas/styling.rs +++ /dev/null @@ -1,305 +0,0 @@ -mod colour_utils; - -use colour_utils::*; -use tui::style::{Color, Style}; - -use super::ColourScheme; -pub use crate::options::ConfigV1; -use crate::{ - constants::*, - options::{colours::ColoursConfig, OptionError, OptionResult}, -}; - -pub struct CanvasStyling { - pub currently_selected_text_colour: Color, - pub currently_selected_bg_colour: Color, - pub currently_selected_text_style: Style, - pub table_header_style: Style, - pub ram_style: Style, - #[cfg(not(target_os = "windows"))] - pub cache_style: Style, - pub swap_style: Style, - pub arc_style: Style, - pub gpu_colour_styles: Vec