diff --git a/src/musikbox/cursespp/Colors.cpp b/src/musikbox/cursespp/Colors.cpp index d1a73dab9..a74bea425 100755 --- a/src/musikbox/cursespp/Colors.cpp +++ b/src/musikbox/cursespp/Colors.cpp @@ -39,16 +39,35 @@ using namespace cursespp; /* if the terminal supports custom colors, these are the palette indicies we'll use to store them */ -#define COLOR_CUSTOM_WHITE 16 -#define COLOR_CUSTOM_BLUE 17 -#define COLOR_CUSTOM_RED 18 -#define COLOR_CUSTOM_YELLOW 19 -#define COLOR_CUSTOM_GREEN 20 -#define COLOR_CUSTOM_BLACK 21 -#define COLOR_CUSTOM_GREY 22 -#define COLOR_CUSTOM_SELECTED_LIST_ITEM_BG 23 -#define COLOR_CUSTOM_ORANGE 24 -#define COLOR_CUSTOM_DARK_RED 25 +#define THEME_COLOR_BACKGROUND 16 +#define THEME_COLOR_FOREGROUND 17 +#define THEME_COLOR_FOCUSED_BORDER 18 +#define THEME_COLOR_TEXT_FOCUSED 19 +#define THEME_COLOR_TEXT_ACTIVE 20 +#define THEME_COLOR_TEXT_DISABLED 21 +#define THEME_COLOR_TEXT_HIDDEN 22 +#define THEME_COLOR_TEXT_WARNING 23 +#define THEME_COLOR_TEXT_ERROR 24 +#define THEME_COLOR_OVERLAY_BACKGROUND 25 +#define THEME_COLOR_OVERLAY_FOREGROUND 26 +#define THEME_COLOR_OVERLAY_BORDER 27 +#define THEME_COLOR_OVERLAY_FOCUSED_BORDER 28 +#define THEME_COLOR_SHORTCUTS_BACKGROUND 29 +#define THEME_COLOR_SHORTCUTS_FOREGROUND 30 +#define THEME_COLOR_SHORTCUTS_BACKGROUND_FOCUSED 31 +#define THEME_COLOR_SHORTCUTS_FOREGROUND_FOCUSED 32 +#define THEME_COLOR_BUTTON_BACKGROUND_NORMAL 33 +#define THEME_COLOR_BUTTON_FOREGROUND_NORMAL 34 +#define THEME_COLOR_BUTTON_BACKGROUND_ACTIVE 35 +#define THEME_COLOR_BUTTON_FOREGROUND_ACTIVE 36 +#define THEME_COLOR_BANNER_BACKGROUND 37 +#define THEME_COLOR_BANNER_FOREGROUND 38 +#define THEME_COLOR_LIST_HEADER_BACKGROUND 39 +#define THEME_COLOR_LIST_HEADER_FOREGROUND 40 +#define THEME_COLOR_LIST_ITEM_HIGHLIGHTED_BACKGROUND 41 +#define THEME_COLOR_LIST_ITEM_HIGHLIGHTED_FOREGROUND 42 +#define THEME_COLOR_LIST_ITEM_ACTIVE_BACKGROUND 43 +#define THEME_COLOR_LIST_ITEM_ACTIVE_FOREGROUND 44 /* if we can't set custom colors, but we have the full 256 color palette, use ones that most closely match our desired colors */ @@ -61,27 +80,214 @@ palette, use ones that most closely match our desired colors */ #define COLOR_256_BLUE 123 #define COLOR_256_OFFWHITE 251 -/* vars that hold our actual color definitions. these may change -later during init if the terminal supports > 8 colors */ -static int white = COLOR_WHITE; -static int blue = COLOR_BLUE; -static int red = COLOR_RED; -static int darkRed = COLOR_RED; -static int yellow = COLOR_YELLOW; -static int green = COLOR_GREEN; -static int black = COLOR_BLACK; -static int orange = COLOR_YELLOW; -static int foreground = -1; -static int background = -1; -static int selected = -1; -static int grey = -1; - #define SCALE(x) ((x * 1000) / 255) -static int initColor(int id, int r, int g, int b) { - init_color(id, SCALE(r), SCALE(g), SCALE(b)); - return id; -} +struct Theme { + struct Color { + enum Mode { Standard, Palette, Custom }; + + Color() { + Set(-1, -1, -1); + } + + void Set(int colorId, int hex, int palette) { + this->colorId = colorId; + this->r = hex >> 16; + this->g = (hex >> 8) & 0x0000ff; + this->b = hex & 0x0000ff; + this->palette = palette; + } + + void Set(int colorId, int r, int g, int b, int palette) { + this->colorId = colorId; + this->r = r; + this->g = g; + this->b = b; + this->palette = palette; + } + + int Id(Mode mode, int defaultValue) { + if (mode == Standard) { + return defaultValue; + } + else if (mode == Palette) { + return this->palette; + } + + init_color(this->colorId, SCALE(this->r), SCALE(this->g), SCALE(this->b)); + return this->colorId; + } + + int colorId; + int r, g, b; + int palette; + }; + + /* initialized with default values. the user can override them, then call Apply() */ + Theme() { + /* main */ + background.Set(THEME_COLOR_BACKGROUND, 0, 0, 0, COLOR_BLACK); + foreground.Set(THEME_COLOR_FOREGROUND, 230, 230, 230, COLOR_256_OFFWHITE); + focusedBorder.Set(THEME_COLOR_FOCUSED_BORDER, 220, 82, 86, COLOR_256_RED); + + /* text */ + textFocused.Set(THEME_COLOR_TEXT_FOCUSED, 220, 82, 86, COLOR_256_RED); + textActive.Set(THEME_COLOR_TEXT_ACTIVE, 166, 226, 46, COLOR_256_GREEN); + textDisabled.Set(THEME_COLOR_TEXT_DISABLED, 128, 128, 128, COLOR_256_MEDIUM_GRAY); + textHidden.Set(THEME_COLOR_TEXT_HIDDEN, 0, 0, 0, COLOR_BLACK); + textWarning.Set(THEME_COLOR_TEXT_WARNING, 230, 220, 116, COLOR_256_YELLOW); + textWarning.Set(THEME_COLOR_TEXT_ERROR, 220, 82, 86, COLOR_256_RED); + + /* overlay */ + overlayBackground.Set(THEME_COLOR_OVERLAY_BACKGROUND, 66, 66, 56, COLOR_256_MEDIUM_GRAY); + overlayForeground.Set(THEME_COLOR_OVERLAY_FOREGROUND, 230, 230, 230, COLOR_256_OFFWHITE); + overlayBorder.Set(THEME_COLOR_OVERLAY_BORDER, 102, 217, 238, COLOR_256_BLUE); + overlayFocusedBorder.Set(THEME_COLOR_OVERLAY_FOCUSED_BORDER, 220, 82, 86, COLOR_256_RED); + + /* shortcut bar */ + shortcutsBackground.Set(THEME_COLOR_SHORTCUTS_BACKGROUND, 66, 66, 56, COLOR_256_MEDIUM_GRAY); + shortcutsForeground.Set(THEME_COLOR_SHORTCUTS_FOREGROUND, 230, 220, 116, COLOR_256_YELLOW); + focusedShortcutsBackground.Set(THEME_COLOR_SHORTCUTS_BACKGROUND_FOCUSED, 175, 66, 71, COLOR_256_DARK_RED); + focusedShortcutsForeground.Set(THEME_COLOR_SHORTCUTS_FOREGROUND_FOCUSED, 230, 230, 230, COLOR_256_OFFWHITE); + + /* buttons */ + buttonBackgroundNormal.Set(THEME_COLOR_BUTTON_BACKGROUND_NORMAL, 230, 220, 116, COLOR_256_YELLOW); + buttonForegroundNormal.Set(THEME_COLOR_BUTTON_FOREGROUND_NORMAL, 0, 0, 0, COLOR_BLACK); + buttonBackgroundActive.Set(THEME_COLOR_BUTTON_BACKGROUND_ACTIVE, 166, 226, 46, COLOR_256_GREEN); + buttonForegroundActive.Set(THEME_COLOR_BUTTON_FOREGROUND_ACTIVE, 0, 0, 0, COLOR_BLACK); + + /* banner */ + bannerBackground.Set(THEME_COLOR_BANNER_BACKGROUND, 255, 150, 32, COLOR_256_ORANGE); + bannerForeground.Set(THEME_COLOR_BANNER_FOREGROUND, 0, 0, 0, COLOR_BLACK); + + /* listview */ + listHeaderBackground.Set(THEME_COLOR_LIST_HEADER_BACKGROUND, 0, 0, 0, COLOR_BLACK); + listHeaderForeground.Set(THEME_COLOR_LIST_HEADER_FOREGROUND, 166, 226, 46, COLOR_256_GREEN); + listHighlightedBackground.Set(THEME_COLOR_LIST_ITEM_HIGHLIGHTED_BACKGROUND, 166, 226, 46, COLOR_256_GREEN); + listHighlightedForeground.Set(THEME_COLOR_LIST_ITEM_HIGHLIGHTED_FOREGROUND, 0, 0, 0, COLOR_BLACK); + listActiveBackground.Set(THEME_COLOR_LIST_ITEM_ACTIVE_BACKGROUND, 66, 66, 56, COLOR_256_MEDIUM_GRAY); + listActiveForeground.Set(THEME_COLOR_LIST_ITEM_ACTIVE_FOREGROUND, 230, 220, 116, COLOR_256_YELLOW); + } + + /* initializes all of the color pairs from the specified colors, then applies them + to the current session! */ + void Apply(Color::Mode mode) { + int backgroundId = background.Id(mode, COLOR_BLACK); + int foregroundId = foreground.Id(mode, COLOR_WHITE); + + /* main */ + init_pair(CURSESPP_DEFAULT_CONTENT_COLOR, foregroundId, backgroundId); + init_pair(CURSESPP_DEFAULT_FRAME_COLOR, foregroundId, backgroundId); + init_pair(CURSESPP_FOCUSED_FRAME_COLOR, focusedBorder.Id(mode, COLOR_RED),backgroundId); + + /* text */ + init_pair(CURSESPP_TEXT_DEFAULT, foregroundId, backgroundId); + init_pair(CURSESPP_TEXT_DISABLED, textDisabled.Id(mode, COLOR_WHITE), backgroundId); + init_pair(CURSESPP_TEXT_FOCUSED, textFocused.Id(mode, COLOR_RED), backgroundId); + init_pair(CURSESPP_TEXT_ACTIVE, textActive.Id(mode, COLOR_GREEN), backgroundId); + init_pair(CURSESPP_TEXT_WARNING, textWarning.Id(mode, COLOR_YELLOW), backgroundId); + init_pair(CURSESPP_TEXT_ERROR, textError.Id(mode, COLOR_RED), backgroundId); + init_pair(CURSESPP_TEXT_HIDDEN, textHidden.Id(mode, COLOR_BLACK), backgroundId); + + /* overlay */ + int overlayBgId = overlayBackground.Id(mode, COLOR_BLACK); + init_pair(CURSESPP_OVERLAY_FRAME, overlayBorder.Id(mode, COLOR_BLUE), overlayBgId); + init_pair(CURSESPP_OVERLAY_CONTENT, overlayForeground.Id(mode, COLOR_WHITE), overlayBgId); + init_pair(CURSESPP_OVERLAY_INPUT_FRAME, overlayFocusedBorder.Id(mode, COLOR_RED), overlayBgId); + + /* shortcuts */ + init_pair( + CURSESPP_SHORTCUT_ROW_NORMAL, + shortcutsForeground.Id(mode, COLOR_YELLOW), + shortcutsBackground.Id(mode, COLOR_BLACK)); + + init_pair( + CURSESPP_SHORTCUT_ROW_FOCUSED, + focusedShortcutsForeground.Id(mode, COLOR_WHITE), + focusedShortcutsBackground.Id(mode, COLOR_RED)); + + /* buttons */ + init_pair( + CURSESPP_BUTTON_NORMAL, + buttonForegroundNormal.Id(mode, COLOR_BLACK), + buttonBackgroundNormal.Id(mode, COLOR_YELLOW)); + + init_pair( + CURSESPP_BUTTON_HIGHLIGHTED, + buttonForegroundActive.Id(mode, COLOR_BLACK), + buttonBackgroundActive.Id(mode, COLOR_GREEN)); + + /* banner */ + init_pair( + CURSESPP_BANNER, + bannerForeground.Id(mode, COLOR_BLACK), + bannerBackground.Id(mode, COLOR_YELLOW)); + + /* list items */ + init_pair( + CURSESPP_LIST_ITEM_HEADER, + listHeaderForeground.Id(mode, COLOR_GREEN), + listHeaderBackground.Id(mode, COLOR_BLACK)); + + init_pair( + CURSESPP_SELECTED_LIST_ITEM, + listActiveForeground.Id(mode, COLOR_YELLOW), + listActiveBackground.Id(mode, COLOR_BLACK)); + + init_pair( + CURSESPP_HIGHLIGHTED_LIST_ITEM, + listHighlightedForeground.Id(mode, COLOR_BLACK), + listHighlightedBackground.Id(mode, COLOR_GREEN)); + + init_pair( /* note: swap active fg/bg */ + CURSESPP_HIGHLIGHTED_SELECTED_LIST_ITEM, + listActiveBackground.Id(mode, COLOR_BLACK), + listActiveForeground.Id(mode, COLOR_YELLOW)); + } + + /* main */ + Color background; + Color foreground; + Color focusedBorder; + + /* text */ + Color textFocused; + Color textActive; + Color textDisabled; + Color textHidden; + Color textWarning; + Color textError; + + /* overlay */ + Color overlayBackground; + Color overlayForeground; + Color overlayBorder; + Color overlayFocusedBorder; + + /* shortcut bar */ + Color shortcutsBackground; + Color shortcutsForeground; + Color focusedShortcutsBackground; + Color focusedShortcutsForeground; + + /* buttons */ + Color buttonBackgroundNormal; + Color buttonForegroundNormal; + Color buttonBackgroundActive; + Color buttonForegroundActive; + + /* banner */ + Color bannerBackground; + Color bannerForeground; + + /* listview */ + Color listHeaderBackground; + Color listHeaderForeground; + Color listHighlightedBackground; + Color listHighlightedForeground; + Color listActiveForeground; + Color listActiveBackground; +}; /* some terminals report custom colors are supported, and also don't error when calling init_color(), but don't actually work. */ @@ -104,68 +310,17 @@ static bool canChangeColors() { Colors::Colors() { } +static Theme defaultTheme; + void Colors::Init(bool disableCustomColors) { start_color(); use_default_colors(); - /* the default colors are a bit harsh for my taste, so - let's use custom colors if the terminal supports it. in - the future we'll allow users to configure this via setting */ + using Color = Theme::Color; + Color::Mode mode = Color::Standard; if (!disableCustomColors && COLORS > 8) { - if (canChangeColors()) { - red = initColor(COLOR_CUSTOM_RED, 220, 82, 86); - darkRed = initColor(COLOR_CUSTOM_DARK_RED, 175, 66, 71); - green = initColor(COLOR_CUSTOM_GREEN, 166, 226, 46); - yellow = initColor(COLOR_CUSTOM_YELLOW, 230, 220, 116); - selected = initColor(COLOR_CUSTOM_SELECTED_LIST_ITEM_BG, 66, 66, 56); - grey = initColor(COLOR_CUSTOM_GREY, 128, 128, 128); - orange = initColor(COLOR_CUSTOM_ORANGE, 255, 150, 32); - blue = initColor(COLOR_CUSTOM_BLUE, 102, 217, 238); - white = initColor(COLOR_CUSTOM_WHITE, 230, 230, 230); - foreground = COLOR_CUSTOM_WHITE; - } - else if (COLORS >= 256) { - green = COLOR_256_GREEN; - red = COLOR_256_RED; - darkRed = COLOR_256_DARK_RED; - yellow = COLOR_256_YELLOW; - selected = COLOR_256_MEDIUM_GRAY; - grey = COLOR_256_MEDIUM_GRAY; - orange = COLOR_256_ORANGE; - blue = COLOR_256_BLUE; - white = COLOR_256_OFFWHITE; - foreground = COLOR_256_OFFWHITE; - } + mode = canChangeColors() ? Color::Custom : Color::Palette; } - init_pair(CURSESPP_SELECTED_LIST_ITEM, yellow, selected); - init_pair(CURSESPP_HIGHLIGHTED_LIST_ITEM, black, green); - init_pair(CURSESPP_HIGHLIGHTED_SELECTED_LIST_ITEM, black, yellow); - init_pair(CURSESPP_LIST_ITEM_HEADER, green, background); - - init_pair(CURSESPP_DEFAULT_CONTENT_COLOR, foreground, background); - init_pair(CURSESPP_DEFAULT_FRAME_COLOR, foreground, background); - init_pair(CURSESPP_FOCUSED_FRAME_COLOR, red, background); - - init_pair(CURSESPP_TEXT_DEFAULT, white, background); - init_pair(CURSESPP_TEXT_DISABLED, grey, background); - init_pair(CURSESPP_TEXT_FOCUSED, red, background); - init_pair(CURSESPP_TEXT_ACTIVE, green, background); - init_pair(CURSESPP_TEXT_WARNING, yellow, background); - init_pair(CURSESPP_TEXT_ERROR, red, background); - init_pair(CURSESPP_TEXT_HIDDEN, black, background); - init_pair(CURSESPP_TEXT_SEPARATOR, orange, background); - - init_pair(CURSESPP_BUTTON_NORMAL, black, yellow); - init_pair(CURSESPP_BUTTON_NEGATIVE, white, red); - init_pair(CURSESPP_BUTTON_HIGHLIGHTED, black, green); - - init_pair(CURSESPP_SHORTCUT_ROW_NORMAL, yellow, selected); - init_pair(CURSESPP_SHORTCUT_ROW_FOCUSED, white, darkRed); - - init_pair(CURSESPP_OVERLAY_FRAME, blue, selected); - init_pair(CURSESPP_OVERLAY_BACKGROUND, white, selected); - init_pair(CURSESPP_OVERLAY_INPUT_FRAME, red, selected); - - init_pair(CURSESPP_BANNER, black, orange); + defaultTheme.Apply(mode); } diff --git a/src/musikbox/cursespp/Colors.h b/src/musikbox/cursespp/Colors.h index 81259c20c..b145503d3 100755 --- a/src/musikbox/cursespp/Colors.h +++ b/src/musikbox/cursespp/Colors.h @@ -54,17 +54,15 @@ #define CURSESPP_TEXT_WARNING 12 #define CURSESPP_TEXT_ERROR 13 #define CURSESPP_TEXT_HIDDEN 14 -#define CURSESPP_TEXT_SEPARATOR 15 #define CURSESPP_BUTTON_NORMAL 16 -#define CURSESPP_BUTTON_NEGATIVE 17 #define CURSESPP_BUTTON_HIGHLIGHTED 18 #define CURSESPP_SHORTCUT_ROW_NORMAL 19 #define CURSESPP_SHORTCUT_ROW_FOCUSED 20 #define CURSESPP_OVERLAY_FRAME 21 -#define CURSESPP_OVERLAY_BACKGROUND 22 +#define CURSESPP_OVERLAY_CONTENT 22 #define CURSESPP_OVERLAY_INPUT_FRAME 23 #define CURSESPP_BANNER 24 diff --git a/src/musikbox/cursespp/DialogOverlay.cpp b/src/musikbox/cursespp/DialogOverlay.cpp index 63db1e8c3..83fa5491c 100644 --- a/src/musikbox/cursespp/DialogOverlay.cpp +++ b/src/musikbox/cursespp/DialogOverlay.cpp @@ -46,7 +46,7 @@ using namespace cursespp; DialogOverlay::DialogOverlay() { this->SetFrameVisible(true); this->SetFrameColor(CURSESPP_OVERLAY_FRAME); - this->SetContentColor(CURSESPP_OVERLAY_BACKGROUND); + this->SetContentColor(CURSESPP_OVERLAY_CONTENT); this->width = this->height = 0; this->autoDismiss = true; diff --git a/src/musikbox/cursespp/InputOverlay.cpp b/src/musikbox/cursespp/InputOverlay.cpp index 270f2b9ea..0f2728b0d 100644 --- a/src/musikbox/cursespp/InputOverlay.cpp +++ b/src/musikbox/cursespp/InputOverlay.cpp @@ -53,16 +53,16 @@ using namespace cursespp; InputOverlay::InputOverlay() { this->SetFrameVisible(true); this->SetFrameColor(CURSESPP_OVERLAY_FRAME); - this->SetContentColor(CURSESPP_OVERLAY_BACKGROUND); + this->SetContentColor(CURSESPP_OVERLAY_CONTENT); this->width = this->height = this->setWidth = 0; this->textInput.reset(new TextInput()); this->textInput->SetFocusOrder(0); this->textInput->SetFrameColor(CURSESPP_OVERLAY_FRAME); - this->textInput->SetContentColor(CURSESPP_OVERLAY_BACKGROUND); + this->textInput->SetContentColor(CURSESPP_OVERLAY_CONTENT); this->textInput->SetFocusedFrameColor(CURSESPP_OVERLAY_INPUT_FRAME); - this->textInput->SetFocusedContentColor(CURSESPP_OVERLAY_BACKGROUND); + this->textInput->SetFocusedContentColor(CURSESPP_OVERLAY_CONTENT); this->textInput->EnterPressed.connect(this, &InputOverlay::OnInputEnterPressed); this->textInput->TextChanged.connect(this, &InputOverlay::OnInputKeyPress); this->AddWindow(this->textInput); diff --git a/src/musikbox/cursespp/ListOverlay.cpp b/src/musikbox/cursespp/ListOverlay.cpp index cf715504c..5aa98a6ad 100644 --- a/src/musikbox/cursespp/ListOverlay.cpp +++ b/src/musikbox/cursespp/ListOverlay.cpp @@ -46,7 +46,7 @@ using namespace cursespp; ListOverlay::ListOverlay() { this->SetFrameVisible(true); this->SetFrameColor(CURSESPP_OVERLAY_FRAME); - this->SetContentColor(CURSESPP_OVERLAY_BACKGROUND); + this->SetContentColor(CURSESPP_OVERLAY_CONTENT); this->autoDismiss = true; @@ -54,8 +54,8 @@ ListOverlay::ListOverlay() { this->setWidth = this->setWidthPercent = 0; this->listWindow.reset(new ListWindow()); - this->listWindow->SetContentColor(CURSESPP_OVERLAY_BACKGROUND); - this->listWindow->SetFocusedContentColor(CURSESPP_OVERLAY_BACKGROUND); + this->listWindow->SetContentColor(CURSESPP_OVERLAY_CONTENT); + this->listWindow->SetFocusedContentColor(CURSESPP_OVERLAY_CONTENT); this->listWindow->SetFrameVisible(false); this->listWindow->SetFocusOrder(0); this->AddWindow(this->listWindow);