amfora/config/theme.go
2021-12-03 12:34:41 -05:00

134 lines
4.6 KiB
Go

package config
import (
"fmt"
"sync"
"github.com/gdamore/tcell/v2"
)
// Functions to allow themeing configuration.
// UI element colors are mapped to a string key, such as "error" or "tab_bg"
// These are the same keys used in the config file.
var themeMu = sync.RWMutex{}
var theme = map[string]tcell.Color{
// Default values below
"bg": tcell.ColorBlack, // Used for cview.Styles.PrimitiveBackgroundColor
"tab_num": tcell.Color30, // xterm:Turquoise4, #008787
"tab_divider": tcell.ColorWhite,
"bottombar_label": tcell.Color30,
"bottombar_text": tcell.ColorBlack,
"bottombar_bg": tcell.ColorWhite,
"scrollbar": tcell.ColorWhite,
// Modals
"btn_bg": tcell.ColorNavy, // All modal buttons
"btn_text": tcell.ColorWhite,
"dl_choice_modal_bg": tcell.ColorPurple,
"dl_choice_modal_text": tcell.ColorWhite,
"dl_modal_bg": tcell.Color130, // xterm:DarkOrange3, #af5f00
"dl_modal_text": tcell.ColorWhite,
"info_modal_bg": tcell.ColorGray,
"info_modal_text": tcell.ColorWhite,
"error_modal_bg": tcell.ColorMaroon,
"error_modal_text": tcell.ColorWhite,
"yesno_modal_bg": tcell.ColorPurple,
"yesno_modal_text": tcell.ColorWhite,
"tofu_modal_bg": tcell.ColorMaroon,
"tofu_modal_text": tcell.ColorWhite,
"subscription_modal_bg": tcell.Color61, // xterm:SlateBlue3, #5f5faf
"subscription_modal_text": tcell.ColorWhite,
"input_modal_bg": tcell.ColorGreen,
"input_modal_text": tcell.ColorWhite,
"input_modal_field_bg": tcell.ColorBlue,
"input_modal_field_text": tcell.ColorWhite,
"bkmk_modal_bg": tcell.ColorTeal,
"bkmk_modal_text": tcell.ColorWhite,
"bkmk_modal_label": tcell.ColorYellow,
"bkmk_modal_field_bg": tcell.ColorBlue,
"bkmk_modal_field_text": tcell.ColorWhite,
"hdg_1": tcell.ColorRed,
"hdg_2": tcell.ColorLime,
"hdg_3": tcell.ColorFuchsia,
"amfora_link": tcell.Color33, // xterm:DodgerBlue1, #0087ff
"foreign_link": tcell.Color92, // xterm:DarkViolet, #8700d7
"link_number": tcell.ColorSilver,
"regular_text": tcell.ColorWhite,
"quote_text": tcell.ColorWhite,
"preformatted_text": tcell.Color229, // xterm:Wheat1, #ffffaf
"list_text": tcell.ColorWhite,
}
func SetColor(key string, color tcell.Color) {
themeMu.Lock()
theme[key] = color
themeMu.Unlock()
}
// GetColor will return tcell.ColorBlack if there is no color for the provided key.
func GetColor(key string) tcell.Color {
themeMu.RLock()
defer themeMu.RUnlock()
return theme[key].TrueColor()
}
// GetColorString returns a string that can be used in a cview color tag,
// for the given theme key.
// It will return "#000000" if there is no color for the provided key.
func GetColorString(key string) string {
themeMu.RLock()
defer themeMu.RUnlock()
color := theme[key].TrueColor()
if color == tcell.ColorDefault {
return "-"
}
return fmt.Sprintf("#%06x", color.Hex())
}
// GetContrastingColor returns ColorBlack if color is brighter than gray
// otherwise returns ColorWhite if color is dimmer than gray
// if color is ColorDefault (undefined luminance) this returns ColorDefault
func GetContrastingColor(color tcell.Color) tcell.Color {
if color == tcell.ColorDefault {
// color should never be tcell.ColorDefault
// only config keys which end in bg are allowed to be set to default
// and the only way the argument of this function is set to ColorDefault
// is if both the text and bg of an element in the UI are set to default
return tcell.ColorDefault
}
r, g, b := color.RGB()
luminance := (77*r + 150*g + 29*b + 1<<7) >> 8
const gray = 119 // The middle gray
if luminance > gray {
return tcell.ColorBlack
}
return tcell.ColorWhite
}
// GetTextColor is the Same as GetColor, unless the key is "default".
// This happens on focus of a UI element which has a bg of default, in which case
// It return tcell.ColorBlack or tcell.ColorWhite, depending on which is more readable
func GetTextColor(key, bg string) tcell.Color {
themeMu.RLock()
defer themeMu.RUnlock()
color := theme[key].TrueColor()
if color != tcell.ColorDefault {
return color
}
return GetContrastingColor(theme[bg].TrueColor())
}
// GetTextColorString is the Same as GetColorString, unless the key is "default".
// This happens on focus of a UI element which has a bg of default, in which case
// It return tcell.ColorBlack or tcell.ColorWhite, depending on which is more readable
func GetTextColorString(key, bg string) string {
color := GetTextColor(key, bg)
return fmt.Sprintf("#%06x", color.Hex())
}