diff --git a/_sample_configs/dynamic_sizing.yml b/_sample_configs/dynamic_sizing.yml new file mode 100644 index 00000000..ce0e966b --- /dev/null +++ b/_sample_configs/dynamic_sizing.yml @@ -0,0 +1,21 @@ +wtf: + mods: + battery: + type: power + title: "⚡️" + enabled: true + position: + top: 0 + left: 0 + height: 1 + width: 1 + refreshInterval: 15 + security_info: + type: security + enabled: true + position: + top: 0 + left: 1 + height: 1 + width: 1 + refreshInterval: 3600 \ No newline at end of file diff --git a/app/display.go b/app/display.go index 3163f8c3..a5dfd2cf 100644 --- a/app/display.go +++ b/app/display.go @@ -20,7 +20,13 @@ func NewDisplay(widgets []wtf.Wtfable, config *config.Config) *Display { config: config, } - display.Grid.SetBackgroundColor(wtf.ColorFor(config.UString("wtf.colors.background", "transparent"))) + firstWidget := widgets[0] + display.Grid.SetBackgroundColor( + wtf.ColorFor( + firstWidget.CommonSettings().Colors.WidgetTheme.Background, + ), + ) + display.build(widgets) return &display diff --git a/app/focus_tracker.go b/app/focus_tracker.go index 0d6ef821..a66f72bd 100644 --- a/app/focus_tracker.go +++ b/app/focus_tracker.go @@ -158,7 +158,11 @@ func (tracker *FocusTracker) blur(idx int) { view := widget.TextView() view.Blur() - view.SetBorderColor(wtf.ColorFor(widget.BorderColor())) + view.SetBorderColor( + wtf.ColorFor( + widget.BorderColor(), + ), + ) tracker.IsFocused = false } @@ -178,7 +182,11 @@ func (tracker *FocusTracker) focus(idx int) { } view := widget.TextView() - view.SetBorderColor(wtf.ColorFor(tracker.config.UString("wtf.colors.border.focused", "gray"))) + view.SetBorderColor( + wtf.ColorFor( + widget.CommonSettings().Colors.BorderTheme.Focused, + ), + ) tracker.App.SetFocus(view) } diff --git a/app/wtf_app.go b/app/wtf_app.go index 7236a5ab..953e4f21 100644 --- a/app/wtf_app.go +++ b/app/wtf_app.go @@ -41,8 +41,6 @@ func NewWtfApp(app *tview.Application, config *config.Config, configFilePath str return false }) - wtfApp.pages.Box.SetBackgroundColor(wtf.ColorFor(config.UString("wtf.colors.background", "transparent"))) - wtfApp.app.SetInputCapture(wtfApp.keyboardIntercept) wtfApp.widgets = MakeWidgets(wtfApp.app, wtfApp.pages, wtfApp.config) wtfApp.display = NewDisplay(wtfApp.widgets, wtfApp.config) @@ -54,6 +52,13 @@ func NewWtfApp(app *tview.Application, config *config.Config, configFilePath str wtfApp.validator.Validate(wtfApp.widgets) + firstWidget := wtfApp.widgets[0] + wtfApp.pages.Box.SetBackgroundColor( + wtf.ColorFor( + firstWidget.CommonSettings().Colors.WidgetTheme.Background, + ), + ) + return &wtfApp } diff --git a/cfg/common_settings.go b/cfg/common_settings.go index da30ba84..ed8aedf1 100644 --- a/cfg/common_settings.go +++ b/cfg/common_settings.go @@ -7,24 +7,6 @@ import ( "github.com/olebedev/config" ) -type Colors struct { - Background string - BorderFocusable string - BorderFocused string - BorderNormal string - Checked string - Foreground string - HighlightBack string - HighlightFore string - Text string - Title string - - Rows struct { - Even string - Odd string - } -} - type Module struct { Name string Type string @@ -42,11 +24,11 @@ type Sigils struct { } type Common struct { - Colors Module PositionSettings `help:"Defines where in the grid this module’s widget will be displayed."` Sigils + Colors ColorTheme Bordered bool `help:"Whether or not the module should be displayed with a border." values:"true, false" optional:"true" default:"true"` Enabled bool `help:"Whether or not this module is executed and if its data displayed onscreen." values:"true, false" optional:"true" default:"false"` Focusable bool `help:"Whether or not this module is focusable." values:"true, false" optional:"true" default:"false"` @@ -57,23 +39,44 @@ type Common struct { focusChar int `help:"Define one of the number keys as a short cut key to access the widget." optional:"true"` } +// NewCommonSettingsFromModule returns a common settings configuration tailed to the given module func NewCommonSettingsFromModule(name, defaultTitle string, defaultFocusable bool, moduleConfig *config.Config, globalSettings *config.Config) *Common { - colorsConfig, _ := globalSettings.Get("wtf.colors") - sigilsPath := "wtf.sigils" + baseColors := NewDefaultColorTheme() + + colorsConfig, err := globalSettings.Get("wtf.colors") + if err != nil && strings.Contains(err.Error(), "Nonexistent map") { + // Create a default colors config to fill in for the missing one + // This comes into play when the configuration file does not contain a `colors:` key, i.e: + // + // wtf: + // # colors: <- missing + // refreshInterval: 1 + // openFileUtil: "open" + // + colorsConfig, _ = NewDefaultColorConfig() + } + + // And finally create a third instance to be the final default fallback in case there are empty or nil values in + // the colors extracted from the config file (aka colorsConfig) + defaultColorTheme := NewDefaultColorTheme() + + baseColors.BorderTheme.Focusable = moduleConfig.UString("colors.border.focusable", colorsConfig.UString("border.focusable", defaultColorTheme.BorderTheme.Focusable)) + baseColors.BorderTheme.Focused = moduleConfig.UString("colors.border.focused", colorsConfig.UString("border.focused", defaultColorTheme.BorderTheme.Focused)) + baseColors.BorderTheme.Unfocusable = moduleConfig.UString("colors.border.normal", colorsConfig.UString("border.normal", defaultColorTheme.BorderTheme.Unfocusable)) + + baseColors.CheckboxTheme.Checked = moduleConfig.UString("colors.checked", colorsConfig.UString("checked", defaultColorTheme.CheckboxTheme.Checked)) + + baseColors.RowTheme.EvenForeground = moduleConfig.UString("colors.rows.even", colorsConfig.UString("rows.even", defaultColorTheme.RowTheme.EvenForeground)) + baseColors.RowTheme.OddForeground = moduleConfig.UString("colors.rows.odd", colorsConfig.UString("rows.odd", defaultColorTheme.RowTheme.OddForeground)) + + baseColors.TextTheme.Subheading = moduleConfig.UString("colors.subheading", colorsConfig.UString("subheading", defaultColorTheme.TextTheme.Subheading)) + baseColors.TextTheme.Text = moduleConfig.UString("colors.text", colorsConfig.UString("text", defaultColorTheme.TextTheme.Text)) + baseColors.TextTheme.Title = moduleConfig.UString("colors.title", colorsConfig.UString("title", defaultColorTheme.TextTheme.Title)) + + baseColors.WidgetTheme.Background = moduleConfig.UString("colors.background", colorsConfig.UString("background", defaultColorTheme.WidgetTheme.Background)) common := Common{ - Colors: Colors{ - Background: moduleConfig.UString("colors.background", colorsConfig.UString("background", "transparent")), - BorderFocusable: moduleConfig.UString("colors.border.focusable", colorsConfig.UString("border.focusable", "red")), - BorderFocused: moduleConfig.UString("colors.border.focused", colorsConfig.UString("border.focused", "orange")), - BorderNormal: moduleConfig.UString("colors.border.normal", colorsConfig.UString("border.normal", "gray")), - Checked: moduleConfig.UString("colors.checked", colorsConfig.UString("checked", "white")), - Foreground: moduleConfig.UString("colors.foreground", colorsConfig.UString("foreground", "white")), - HighlightFore: moduleConfig.UString("colors.highlight.fore", colorsConfig.UString("highlight.fore", "black")), - HighlightBack: moduleConfig.UString("colors.highlight.back", colorsConfig.UString("highlight.back", "green")), - Text: moduleConfig.UString("colors.text", colorsConfig.UString("text", "white")), - Title: moduleConfig.UString("colors.title", colorsConfig.UString("title", "white")), - }, + Colors: baseColors, Module: Module{ Name: name, @@ -92,12 +95,10 @@ func NewCommonSettingsFromModule(name, defaultTitle string, defaultFocusable boo focusChar: moduleConfig.UInt("focusChar", -1), } - common.Colors.Rows.Even = moduleConfig.UString("colors.rows.even", colorsConfig.UString("rows.even", "white")) - common.Colors.Rows.Odd = moduleConfig.UString("colors.rows.odd", colorsConfig.UString("rows.odd", "lightblue")) + sigilsPath := "wtf.sigils" common.Sigils.Checkbox.Checked = globalSettings.UString(sigilsPath+".checkbox.checked", "x") common.Sigils.Checkbox.Unchecked = globalSettings.UString(sigilsPath+".checkbox.unchecked", " ") - common.Sigils.Paging.Normal = globalSettings.UString(sigilsPath+".paging.normal", globalSettings.UString("wtf.paging.pageSigil", "*")) common.Sigils.Paging.Selected = globalSettings.UString(sigilsPath+".paging.select", globalSettings.UString("wtf.paging.selectedSigil", "_")) @@ -107,11 +108,19 @@ func NewCommonSettingsFromModule(name, defaultTitle string, defaultFocusable boo /* -------------------- Exported Functions -------------------- */ func (common *Common) DefaultFocusedRowColor() string { - return fmt.Sprintf("%s:%s", common.Colors.HighlightFore, common.Colors.HighlightBack) + return fmt.Sprintf( + "%s:%s", + common.Colors.RowTheme.HighlightedForeground, + common.Colors.RowTheme.HighlightedBackground, + ) } func (common *Common) DefaultRowColor() string { - return fmt.Sprintf("%s:%s", common.Colors.Foreground, common.Colors.Background) + return fmt.Sprintf( + "%s:%s", + common.Colors.RowTheme.EvenForeground, + common.Colors.RowTheme.EvenBackground, + ) } func (common *Common) FocusChar() string { @@ -124,10 +133,10 @@ func (common *Common) FocusChar() string { func (common *Common) RowColor(idx int) string { if idx%2 == 0 { - return common.Colors.Rows.Even + return common.Colors.RowTheme.EvenForeground } - return common.Colors.Rows.Odd + return common.Colors.RowTheme.OddForeground } func (common *Common) RightAlignFormat(width int) string { diff --git a/cfg/default_color_theme.go b/cfg/default_color_theme.go new file mode 100644 index 00000000..62771353 --- /dev/null +++ b/cfg/default_color_theme.go @@ -0,0 +1,106 @@ +package cfg + +import ( + "github.com/olebedev/config" + "gopkg.in/yaml.v2" +) + +// BorderTheme defines the default color scheme for drawing widget borders +type BorderTheme struct { + Focusable string + Focused string + Unfocusable string +} + +// CheckboxTheme defines the default color scheme for drawing checkable rows in widgets +type CheckboxTheme struct { + Checked string +} + +// RowTheme defines the default color scheme for row text +type RowTheme struct { + EvenBackground string + EvenForeground string + + OddBackground string + OddForeground string + + HighlightedBackground string + HighlightedForeground string +} + +// TextTheme defines the default color scheme for text rendering +type TextTheme struct { + Subheading string + Text string + Title string +} + +type WidgetTheme struct { + Background string +} + +// ColorTheme is an alamgam of all the default color settings +type ColorTheme struct { + BorderTheme + CheckboxTheme + RowTheme + TextTheme + WidgetTheme +} + +// NewDefaultColorTheme creates and returns an instance of DefaultColorTheme +func NewDefaultColorTheme() ColorTheme { + defaultTheme := ColorTheme{ + BorderTheme: BorderTheme{ + Focusable: "blue", + Focused: "orange", + Unfocusable: "gray", + }, + + CheckboxTheme: CheckboxTheme{ + Checked: "gray", + }, + + RowTheme: RowTheme{ + EvenBackground: "transparent", + EvenForeground: "white", + + OddBackground: "transparent", + OddForeground: "lightblue", + + HighlightedForeground: "black", + HighlightedBackground: "green", + }, + + TextTheme: TextTheme{ + Subheading: "red", + Text: "white", + Title: "green", + }, + + WidgetTheme: WidgetTheme{ + Background: "transparent", + }, + } + + return defaultTheme +} + +// NewDefaultColorConfig creates and returns a config.Config-compatible configuration struct +// using a DefaultColorTheme to pre-populate all the relevant values +func NewDefaultColorConfig() (*config.Config, error) { + colorTheme := NewDefaultColorTheme() + + yamlBytes, err := yaml.Marshal(colorTheme) + if err != nil { + return nil, err + } + + cfg, err := config.ParseYamlBytes(yamlBytes) + if err != nil { + return nil, err + } + + return cfg, nil +} diff --git a/cfg/default_color_theme_test.go b/cfg/default_color_theme_test.go new file mode 100644 index 00000000..a51a1fdf --- /dev/null +++ b/cfg/default_color_theme_test.go @@ -0,0 +1,26 @@ +package cfg + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_NewDefaultColorTheme(t *testing.T) { + theme := NewDefaultColorTheme() + + assert.Equal(t, "orange", theme.BorderTheme.Focused) + assert.Equal(t, "red", theme.TextTheme.Subheading) + assert.Equal(t, "transparent", theme.WidgetTheme.Background) +} + +func Test_NewDefaultColorConfig(t *testing.T) { + cfg, err := NewDefaultColorConfig() + + assert.Nil(t, err) + + assert.Equal(t, "orange", cfg.UString("bordertheme.focused")) + assert.Equal(t, "red", cfg.UString("texttheme.subheading")) + assert.Equal(t, "transparent", cfg.UString("widgettheme.background")) + assert.Equal(t, "", cfg.UString("widgettheme.missing")) +} diff --git a/cfg/position_validation_test.go b/cfg/position_validation_test.go index e5a3e182..a3c9b92d 100644 --- a/cfg/position_validation_test.go +++ b/cfg/position_validation_test.go @@ -4,7 +4,7 @@ import ( "errors" "testing" - "github.com/alecthomas/assert" + "github.com/stretchr/testify/assert" ) var ( diff --git a/go.mod b/go.mod index e11c79e0..39a739ce 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,6 @@ require ( github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect github.com/VictorAvelar/devto-api-go v1.0.0 github.com/adlio/trello v1.4.0 - github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 github.com/alecthomas/chroma v0.6.8 github.com/andygrunwald/go-gerrit v0.0.0-20190825170856-5959a9bf9ff8 github.com/briandowns/openweathermap v0.0.0-20180804155945-5f41b7c9d92d diff --git a/modules/datadog/widget.go b/modules/datadog/widget.go index 5b6ded93..c416a484 100644 --- a/modules/datadog/widget.go +++ b/modules/datadog/widget.go @@ -85,7 +85,10 @@ func (widget *Widget) content() (string, string, bool) { if len(triggeredMonitors) > 0 { str += fmt.Sprintf( " %s\n", - "[red]Triggered Monitors[white]", + fmt.Sprintf( + "[%s]Triggered Monitors[white]", + widget.settings.common.Colors.Subheading, + ), ) for idx, triggeredMonitor := range triggeredMonitors { row := fmt.Sprintf(`[%s][red] %s[%s]`, diff --git a/modules/docker/client.go b/modules/docker/client.go index c1944f06..d61e0a63 100644 --- a/modules/docker/client.go +++ b/modules/docker/client.go @@ -41,13 +41,13 @@ func (widget *Widget) getSystemInfo() string { }{ { name: "name:", - value: fmt.Sprintf("[%s]%s", widget.settings.common.Foreground, info.Name), + value: fmt.Sprintf("[%s]%s", widget.settings.common.Colors.RowTheme.EvenForeground, info.Name), }, { name: "version:", - value: fmt.Sprintf("[%s]%s", widget.settings.common.Foreground, info.ServerVersion), + value: fmt.Sprintf("[%s]%s", widget.settings.common.Colors.RowTheme.EvenForeground, info.ServerVersion), }, { name: "root:", - value: fmt.Sprintf("[%s]%s", widget.settings.common.Foreground, info.DockerRootDir), + value: fmt.Sprintf("[%s]%s", widget.settings.common.Colors.RowTheme.EvenForeground, info.DockerRootDir), }, { name: "containers:", @@ -57,15 +57,15 @@ func (widget *Widget) getSystemInfo() string { }, { name: "images:", - value: fmt.Sprintf("[%s]%d", widget.settings.common.Foreground, info.Images), + value: fmt.Sprintf("[%s]%d", widget.settings.common.Colors.RowTheme.EvenForeground, info.Images), }, { name: "volumes:", - value: fmt.Sprintf("[%s]%v", widget.settings.common.Foreground, len(diskUsage.Volumes)), + value: fmt.Sprintf("[%s]%v", widget.settings.common.Colors.RowTheme.EvenForeground, len(diskUsage.Volumes)), }, { name: "memory limit:", - value: fmt.Sprintf("[%s]%s", widget.settings.common.Foreground, humanize.Bytes(uint64(info.MemTotal))), + value: fmt.Sprintf("[%s]%s", widget.settings.common.Colors.RowTheme.EvenForeground, humanize.Bytes(uint64(info.MemTotal))), }, { name: "disk usage:", @@ -76,19 +76,19 @@ func (widget *Widget) getSystemInfo() string { [%s]* [::b]total: [%s]%s[::-] `, widget.settings.labelColor, - widget.settings.common.Foreground, + widget.settings.common.Colors.RowTheme.EvenForeground, humanize.Bytes(uint64(duContainer)), widget.settings.labelColor, - widget.settings.common.Foreground, + widget.settings.common.Colors.RowTheme.EvenForeground, humanize.Bytes(uint64(duImg)), widget.settings.labelColor, - widget.settings.common.Foreground, + widget.settings.common.Colors.RowTheme.EvenForeground, humanize.Bytes(uint64(duVol)), widget.settings.labelColor, - widget.settings.common.Foreground, + widget.settings.common.Colors.RowTheme.EvenForeground, humanize.Bytes(uint64(duContainer+duImg+duVol))), }, } diff --git a/modules/feedreader/widget.go b/modules/feedreader/widget.go index 3fa40f18..5648684b 100644 --- a/modules/feedreader/widget.go +++ b/modules/feedreader/widget.go @@ -140,7 +140,7 @@ func (widget *Widget) content() (string, string, bool) { // Grays out viewed items in the list, while preserving background highlighting when selected rowColor = "gray" if idx == widget.Selected { - rowColor = fmt.Sprintf("gray:%s", widget.settings.common.Colors.HighlightBack) + rowColor = fmt.Sprintf("gray:%s", widget.settings.common.Colors.RowTheme.HighlightedBackground) } } diff --git a/modules/gerrit/display.go b/modules/gerrit/display.go index c5ee6ece..1444c690 100644 --- a/modules/gerrit/display.go +++ b/modules/gerrit/display.go @@ -23,13 +23,13 @@ func (widget *Widget) content() (string, string, bool) { _, _, width, _ := widget.View.GetRect() str := widget.settings.common.SigilStr(len(widget.GerritProjects), widget.Idx, width) + "\n" - str += " [red]Stats[white]\n" + str += fmt.Sprintf(" [%s]Stats[white]\n", widget.settings.common.Colors.Subheading) str += widget.displayStats(project) str += "\n" - str += " [red]Open Incoming Reviews[white]\n" + str += fmt.Sprintf(" [%s]Open Incoming Reviews[white]\n", widget.settings.common.Colors.Subheading) str += widget.displayMyIncomingReviews(project, widget.settings.username) str += "\n" - str += " [red]My Outgoing Reviews[white]\n" + str += fmt.Sprintf(" [%s]My Outgoing Reviews[white]\n", widget.settings.common.Colors.Subheading) str += widget.displayMyOutgoingReviews(project, widget.settings.username) return title, str, false diff --git a/modules/git/display.go b/modules/git/display.go index 14c983ce..25c62e59 100644 --- a/modules/git/display.go +++ b/modules/git/display.go @@ -16,11 +16,15 @@ func (widget *Widget) content() (string, string, bool) { return widget.CommonSettings().Title, " Git repo data is unavailable ", false } - title := fmt.Sprintf("%s - [green]%s[white]", widget.CommonSettings().Title, repoData.Repository) + title := fmt.Sprintf( + "%s - %s[white]", + widget.CommonSettings().Title, + repoData.Repository, + ) _, _, width, _ := widget.View.GetRect() str := widget.settings.common.SigilStr(len(widget.GitRepos), widget.Idx, width) + "\n" - str += " [red]Branch[white]\n" + str += fmt.Sprintf(" [%s]Branch[white]\n", widget.settings.common.Colors.Subheading) str += fmt.Sprintf(" %s", repoData.Branch) str += "\n" str += widget.formatChanges(repoData.ChangedFiles) @@ -31,7 +35,7 @@ func (widget *Widget) content() (string, string, bool) { } func (widget *Widget) formatChanges(data []string) string { - str := " [red]Changed Files[white]\n" + str := fmt.Sprintf(" [%s]Changed Files[white]\n", widget.settings.common.Colors.Subheading) if len(data) == 1 { str += " [grey]none[white]\n" @@ -68,7 +72,7 @@ func (widget *Widget) formatChange(line string) string { } func (widget *Widget) formatCommits(data []string) string { - str := " [red]Recent Commits[white]\n" + str := fmt.Sprintf(" [%s]Recent Commits[white]\n", widget.settings.common.Colors.Subheading) for _, line := range data { str += widget.formatCommit(line) diff --git a/modules/github/display.go b/modules/github/display.go index 6e6db7e7..633dde52 100644 --- a/modules/github/display.go +++ b/modules/github/display.go @@ -34,14 +34,14 @@ func (widget *Widget) content() (string, string, bool) { _, _, width, _ := widget.View.GetRect() str := widget.settings.common.SigilStr(len(widget.GithubRepos), widget.Idx, width) + "\n" - str += " [red]Stats[white]\n" + str += fmt.Sprintf(" [%s]Stats[white]\n", widget.settings.common.Colors.Subheading) str += widget.displayStats(repo) - str += "\n [red]Open Review Requests[white]\n" + str += fmt.Sprintf("\n [%s]Open Review Requests[white]\n", widget.settings.common.Colors.Subheading) str += widget.displayMyReviewRequests(repo, username) - str += "\n [red]My Pull Requests[white]\n" + str += fmt.Sprintf("\n [%s]My Pull Requests[white]\n", widget.settings.common.Colors.Subheading) str += widget.displayMyPullRequests(repo, username) for _, customQuery := range widget.settings.customQueries { - str += fmt.Sprintf("\n [red]%s[white]\n", customQuery.title) + str += fmt.Sprintf("\n [%s]%s[white]\n", widget.settings.common.Colors.Subheading, customQuery.title) str += widget.displayCustomQuery(repo, customQuery.filter, customQuery.perPage) } @@ -127,7 +127,12 @@ func (widget *Widget) displayStats(repo *GithubRepo) string { } func (widget *Widget) title(repo *GithubRepo) string { - return fmt.Sprintf("[green]%s - %s[white]", repo.Owner, repo.Name) + return fmt.Sprintf( + "[%s]%s - %s[white]", + widget.settings.common.Colors.TextTheme.Title, + repo.Owner, + repo.Name, + ) } var mergeIcons = map[string]string{ diff --git a/modules/gitlab/display.go b/modules/gitlab/display.go index 17aee1df..8978531c 100644 --- a/modules/gitlab/display.go +++ b/modules/gitlab/display.go @@ -19,19 +19,19 @@ func (widget *Widget) content() (string, string, bool) { _, _, width, _ := widget.View.GetRect() str := widget.settings.common.SigilStr(len(widget.GitlabProjects), widget.Idx, width) + "\n" - str += " [red]Stats[white]\n" + str += fmt.Sprintf(" [%s]Stats[white]\n", widget.settings.common.Colors.Subheading) str += widget.displayStats(project) str += "\n" - str += " [red]Open Assigned Merge Requests[white]\n" + str += fmt.Sprintf(" [%s]Open Assigned Merge Requests[white]\n", widget.settings.common.Colors.Subheading) str += widget.displayMyAssignedMergeRequests(project, widget.settings.username) str += "\n" - str += " [red]My Merge Requests[white]\n" + str += fmt.Sprintf(" [%s]My Merge Requests[white]\n", widget.settings.common.Colors.Subheading) str += widget.displayMyMergeRequests(project, widget.settings.username) str += "\n" - str += " [red]Open Assigned Issues[white]\n" + str += fmt.Sprintf(" [%s]Open Assigned Issues[white]\n", widget.settings.common.Colors.Subheading) str += widget.displayMyAssignedIssues(project, widget.settings.username) str += "\n" - str += " [red]My Issues[white]\n" + str += fmt.Sprintf(" [%s]My Issues[white]\n", widget.settings.common.Colors.Subheading) str += widget.displayMyIssues(project, widget.settings.username) return title, str, false diff --git a/modules/jira/widget.go b/modules/jira/widget.go index bd85ef43..8cf3e253 100644 --- a/modules/jira/widget.go +++ b/modules/jira/widget.go @@ -2,6 +2,7 @@ package jira import ( "fmt" + "github.com/rivo/tview" "github.com/wtfutil/wtf/utils" "github.com/wtfutil/wtf/view" @@ -78,7 +79,7 @@ func (widget *Widget) content() (string, string, bool) { title := fmt.Sprintf("%s- [green]%s[white]", widget.CommonSettings().Title, widget.settings.projects) - str := " [red]Assigned Issues[white]\n" + str := fmt.Sprintf(" [%s]Assigned Issues[white]\n", widget.settings.common.Colors.Subheading) if widget.result == nil || len(widget.result.Issues) == 0 { return title, "No results to display", false diff --git a/modules/kubernetes/widget.go b/modules/kubernetes/widget.go index 865a7b38..818c8768 100644 --- a/modules/kubernetes/widget.go +++ b/modules/kubernetes/widget.go @@ -56,7 +56,7 @@ func (widget *Widget) Refresh() { widget.Redraw(func() (string, string, bool) { return title, "[red] Error getting node data [white]\n", true }) return } - content += "[red]Nodes[white]\n" + content += fmt.Sprintf("[%s]Nodes[white]\n", widget.settings.common.Colors.Subheading) for _, node := range nodeList { content += fmt.Sprintf("%s\n", node) } @@ -69,7 +69,7 @@ func (widget *Widget) Refresh() { widget.Redraw(func() (string, string, bool) { return title, "[red] Error getting deployment data [white]\n", true }) return } - content += "[red]Deployments[white]\n" + content += fmt.Sprintf("[%s]Deployments[white]\n", widget.settings.common.Colors.Subheading) for _, deployment := range deploymentList { content += fmt.Sprintf("%s\n", deployment) } @@ -82,7 +82,7 @@ func (widget *Widget) Refresh() { widget.Redraw(func() (string, string, bool) { return title, "[red] Error getting pod data [white]\n", false }) return } - content += "[red]Pods[white]\n" + content += fmt.Sprintf("[%s]Pods[white]\n", widget.settings.common.Colors.Subheading) for _, pod := range podList { content += fmt.Sprintf("%s\n", pod) } diff --git a/modules/mercurial/display.go b/modules/mercurial/display.go index 8107c377..82235251 100644 --- a/modules/mercurial/display.go +++ b/modules/mercurial/display.go @@ -16,11 +16,15 @@ func (widget *Widget) content() (string, string, bool) { return widget.CommonSettings().Title, " Mercurial repo data is unavailable ", false } - title := fmt.Sprintf("%s - [green]%s[white]", widget.CommonSettings().Title, repoData.Repository) + title := fmt.Sprintf( + "%s - %s[white]", + widget.settings.common.Colors.TextTheme.Title, + repoData.Repository, + ) _, _, width, _ := widget.View.GetRect() str := widget.settings.common.SigilStr(len(widget.Data), widget.Idx, width) + "\n" - str += " [red]Branch:Bookmark[white]\n" + str += fmt.Sprintf(" [%s]Branch:Bookmark[white]\n", widget.settings.common.Colors.Subheading) str += fmt.Sprintf(" %s:%s\n", repoData.Branch, repoData.Bookmark) str += "\n" str += widget.formatChanges(repoData.ChangedFiles) @@ -31,7 +35,7 @@ func (widget *Widget) content() (string, string, bool) { } func (widget *Widget) formatChanges(data []string) string { - str := " [red]Changed Files[white]\n" + str := fmt.Sprintf(" [%s]Changed Files[white]\n", widget.settings.common.Colors.Subheading) if len(data) == 1 { str += " [grey]none[white]\n" @@ -68,7 +72,7 @@ func (widget *Widget) formatChange(line string) string { } func (widget *Widget) formatCommits(data []string) string { - str := " [red]Recent Commits[white]\n" + str := fmt.Sprintf(" [%s]Recent Commits[white]\n", widget.settings.common.Colors.Subheading) for _, line := range data { str += widget.formatCommit(line) diff --git a/modules/nbascore/widget.go b/modules/nbascore/widget.go index cb231570..7867c896 100644 --- a/modules/nbascore/widget.go +++ b/modules/nbascore/widget.go @@ -79,8 +79,9 @@ func (widget *Widget) nbascore() (string, string, bool) { } result := map[string]interface{}{} json.Unmarshal(contents, &result) - allGame := "" // store result in allgame - allGame += (" " + "[red]" + (cur.Format(utils.FriendlyDateFormat) + "\n\n") + "[white]") + + allGame := fmt.Sprintf(" [%s]", widget.settings.common.Colors.Subheading) + (cur.Format(utils.FriendlyDateFormat) + "\n\n") + "[white]" + for _, game := range result["games"].([]interface{}) { vTeam, hTeam, vScore, hScore := "", "", "", "" quarter := 0. diff --git a/modules/newrelic/display.go b/modules/newrelic/display.go index 2e6a326f..3f451b6d 100644 --- a/modules/newrelic/display.go +++ b/modules/newrelic/display.go @@ -37,7 +37,10 @@ func (widget *Widget) content() (string, string, bool) { func (widget *Widget) contentFrom(deploys []nr.ApplicationDeployment) string { str := fmt.Sprintf( " %s\n", - "[red]Latest Deploys[white]", + fmt.Sprintf( + "[%s]Latest Deploys[white]", + widget.settings.common.Colors.Subheading, + ), ) revisions := []string{} diff --git a/modules/pagerduty/widget.go b/modules/pagerduty/widget.go index f8fb3858..28d77c59 100644 --- a/modules/pagerduty/widget.go +++ b/modules/pagerduty/widget.go @@ -70,7 +70,7 @@ func (widget *Widget) contentFrom(onCalls []pagerduty.OnCall, incidents []pagerd if len(incidents) > 0 { str += "[yellow]Incidents[white]\n" for _, incident := range incidents { - str += fmt.Sprintf("[red]%s[white]\n", incident.Summary) + str += fmt.Sprintf("[%s]%s[white]\n", widget.settings.common.Colors.Subheading, incident.Summary) str += fmt.Sprintf("Status: %s\n", incident.Status) str += fmt.Sprintf("Service: %s\n", incident.Service.Summary) str += fmt.Sprintf("Escalation: %s\n", incident.EscalationPolicy.Summary) @@ -100,14 +100,26 @@ func (widget *Widget) contentFrom(onCalls []pagerduty.OnCall, incidents []pagerd sort.Strings(keys) if len(keys) > 0 { - str += "[red] Schedules[white]\n" + str += fmt.Sprintf("[%s] Schedules[white]\n", widget.settings.common.Colors.Subheading) + // Print out policies, and escalation order of users for _, key := range keys { - str += fmt.Sprintf("\n [green::b]%s\n", key) + str += fmt.Sprintf( + "\n [%s]%s\n", + widget.settings.common.Colors.Subheading, + key, + ) + values := tree[key] sort.Sort(ByEscalationLevel(values)) + for _, item := range values { - str += fmt.Sprintf(" [white]%d - %s\n", item.EscalationLevel, item.User.Summary) + str += fmt.Sprintf( + " [%s]%d - %s\n", + widget.settings.common.Colors.Text, + item.EscalationLevel, + item.User.Summary, + ) } } } diff --git a/modules/resourceusage/widget.go b/modules/resourceusage/widget.go index 6990e234..02fc3bd9 100644 --- a/modules/resourceusage/widget.go +++ b/modules/resourceusage/widget.go @@ -58,12 +58,12 @@ func MakeGraph(widget *Widget) { stat = math.Max(0, stat) var label string - if (widget.settings.cpuCombined) { + if widget.settings.cpuCombined { label = "CPU" } else { label = fmt.Sprint(i) } - + bar := view.Bar{ Label: label, Percent: int(stat), @@ -122,13 +122,12 @@ func MakeGraph(widget *Widget) { // Refresh & update after interval time func (widget *Widget) Refresh() { - if widget.Disabled() { return } widget.app.QueueUpdateDraw(func() { - widget.View.Clear() + widget.View.Clear() display(widget) }) } diff --git a/modules/security/widget.go b/modules/security/widget.go index 0baf2dd5..fc37b58d 100644 --- a/modules/security/widget.go +++ b/modules/security/widget.go @@ -40,21 +40,21 @@ func (widget *Widget) Refresh() { func (widget *Widget) content() (string, string, bool) { data := NewSecurityData() data.Fetch() - str := " [red]WiFi[white]\n" + str := fmt.Sprintf(" [%s]WiFi[white]\n", widget.settings.common.Colors.Subheading) str += fmt.Sprintf(" %8s: %s\n", "Network", data.WifiName) str += fmt.Sprintf(" %8s: %s\n", "Crypto", data.WifiEncryption) str += "\n" - str += " [red]Firewall[white]\n" + str += fmt.Sprintf(" [%s]Firewall[white]\n", widget.settings.common.Colors.Subheading) str += fmt.Sprintf(" %8s: %4s\n", "Status", data.FirewallEnabled) str += fmt.Sprintf(" %8s: %4s\n", "Stealth", data.FirewallStealth) str += "\n" - str += " [red]Users[white]\n" + str += fmt.Sprintf(" [%s]Users[white]\n", widget.settings.common.Colors.Subheading) str += fmt.Sprintf(" %s", strings.Join(data.LoggedInUsers, "\n ")) str += "\n\n" - str += " [red]DNS[white]\n" + str += fmt.Sprintf(" [%s]DNS[white]\n", widget.settings.common.Colors.Subheading) str += fmt.Sprintf(" %12s\n", data.DnsAt(0)) str += fmt.Sprintf(" %12s\n", data.DnsAt(1)) str += "\n" diff --git a/modules/textfile/widget.go b/modules/textfile/widget.go index a401ea08..eda142ea 100644 --- a/modules/textfile/widget.go +++ b/modules/textfile/widget.go @@ -71,7 +71,11 @@ func (widget *Widget) HelpText() string { /* -------------------- Unexported Functions -------------------- */ func (widget *Widget) content() (string, string, bool) { - title := fmt.Sprintf("[green]%s[white]", widget.CurrentSource()) + title := fmt.Sprintf( + "[%s]%s[white]", + widget.settings.common.Colors.TextTheme.Title, + widget.CurrentSource(), + ) _, _, width, _ := widget.View.GetRect() text := widget.settings.common.SigilStr(len(widget.Sources), widget.Idx, width) + "\n" diff --git a/modules/todo/display.go b/modules/todo/display.go index ca577aee..e5956f6e 100644 --- a/modules/todo/display.go +++ b/modules/todo/display.go @@ -41,25 +41,23 @@ func (widget *Widget) content() (string, string, bool) { return widget.CommonSettings().Title, str, false } -func (widget *Widget) formattedItemLine(idx int, item *checklist.ChecklistItem, selectedItem *checklist.ChecklistItem, maxLen int) string { - foreColor, backColor := widget.settings.common.Colors.Text, widget.settings.common.Colors.Background +func (widget *Widget) formattedItemLine(idx int, currItem *checklist.ChecklistItem, selectedItem *checklist.ChecklistItem, maxLen int) string { + rowColor := widget.RowColor(idx) - if item.Checked { - foreColor = widget.settings.common.Colors.Checked + if currItem.Checked { + rowColor = widget.settings.common.Colors.CheckboxTheme.Checked } - if widget.View.HasFocus() && (item == selectedItem) { - foreColor = widget.settings.common.Colors.HighlightFore - backColor = widget.settings.common.Colors.HighlightBack + if widget.View.HasFocus() && (currItem == selectedItem) { + rowColor = widget.RowColor(idx) } row := fmt.Sprintf( - ` [%s:%s]|%s| %s[white]`, - foreColor, - backColor, - item.CheckMark(), - tview.Escape(item.Text), + ` [%s]|%s| %s[white]`, + rowColor, + currItem.CheckMark(), + tview.Escape(currItem.Text), ) - return utils.HighlightableHelper(widget.View, row, idx, len(item.Text)) + return utils.HighlightableHelper(widget.View, row, idx, len(currItem.Text)) } diff --git a/modules/todoist/display.go b/modules/todoist/display.go index 35fffd1f..49caa56d 100644 --- a/modules/todoist/display.go +++ b/modules/todoist/display.go @@ -18,7 +18,11 @@ func (widget *Widget) content() (string, string, bool) { return widget.CommonSettings().Title, proj.err.Error(), true } - title := fmt.Sprintf("[green]%s[white]", proj.Project.Name) + title := fmt.Sprintf( + "[%s]%s[white]", + widget.settings.common.Colors.TextTheme.Title, + proj.Project.Name, + ) str := "" diff --git a/modules/trello/widget.go b/modules/trello/widget.go index abd66be6..01bb706d 100644 --- a/modules/trello/widget.go +++ b/modules/trello/widget.go @@ -62,7 +62,7 @@ func (widget *Widget) content() (string, string, bool) { widget.settings.board, ) for list, cardArray := range searchResult.TrelloCards { - content += fmt.Sprintf(" [red]%s[white]\n", list) + content += fmt.Sprintf(" [%s]%s[white]\n", widget.settings.common.Colors.Subheading, list) for _, card := range cardArray { content += fmt.Sprintf(" %s[white]\n", card.Name) diff --git a/modules/twitterstats/widget.go b/modules/twitterstats/widget.go index 985f226e..bbf029cb 100644 --- a/modules/twitterstats/widget.go +++ b/modules/twitterstats/widget.go @@ -10,13 +10,16 @@ import ( type Widget struct { view.TextWidget - client *Client + client *Client + settings *Settings } func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { widget := Widget{ TextWidget: view.NewTextWidget(app, settings.common), - client: NewClient(settings), + + client: NewClient(settings), + settings: settings, } widget.View.SetBorderPadding(1, 1, 1, 1) @@ -31,18 +34,25 @@ func (widget *Widget) Refresh() { } func (widget *Widget) content() (string, string, bool) { - usernames := widget.client.screenNames + // Add header row + str := fmt.Sprintf( + "[%s]%-12s %10s %8s[white]\n", + widget.settings.common.Colors.Subheading, + "Username", + "Followers", + "Tweets", + ) + stats := widget.client.GetStats() - // Add header row - str := fmt.Sprintf("%-16s %8s %8s\n", "Username", "Followers", "Tweets") - // Add rows for each of the followed usernames - for i, username := range usernames { - followerCount := stats[i].FollowerCount - tweetCount := stats[i].TweetCount - - str += fmt.Sprintf("%-16s %8d %8d\n", username, followerCount, tweetCount) + for i, username := range widget.client.screenNames { + str += fmt.Sprintf( + "%-12s %10d %8d\n", + username, + stats[i].FollowerCount, + stats[i].TweetCount, + ) } return "Twitter Stats", str, true diff --git a/modules/zendesk/widget.go b/modules/zendesk/widget.go index cdb8c1d7..286a4fb2 100644 --- a/modules/zendesk/widget.go +++ b/modules/zendesk/widget.go @@ -74,7 +74,7 @@ func (widget *Widget) content() (string, string, bool) { func (widget *Widget) format(ticket Ticket, idx int) string { textColor := widget.settings.common.Colors.Background if idx == widget.GetSelected() { - textColor = widget.settings.common.Colors.BorderFocused + textColor = widget.settings.common.Colors.BorderTheme.Focused } requesterName := widget.parseRequester(ticket) diff --git a/view/bargraph.go b/view/bargraph.go index 12706dc8..3a08d8c0 100644 --- a/view/bargraph.go +++ b/view/bargraph.go @@ -107,12 +107,12 @@ func (widget *BarGraph) TextView() *tview.TextView { func (widget *BarGraph) createView(bordered bool) *tview.TextView { view := tview.NewTextView() - view.SetBackgroundColor(wtf.ColorFor(widget.commonSettings.Colors.Background)) + view.SetBackgroundColor(wtf.ColorFor(widget.commonSettings.Colors.WidgetTheme.Background)) view.SetBorder(bordered) view.SetBorderColor(wtf.ColorFor(widget.BorderColor())) view.SetDynamicColors(true) view.SetTitle(widget.ContextualTitle(widget.CommonSettings().Title)) - view.SetTitleColor(wtf.ColorFor(widget.commonSettings.Colors.Title)) + view.SetTitleColor(wtf.ColorFor(widget.commonSettings.Colors.TextTheme.Title)) view.SetWrap(false) return view diff --git a/view/base.go b/view/base.go index 78c3dca7..0196e08f 100644 --- a/view/base.go +++ b/view/base.go @@ -47,12 +47,13 @@ func (base *Base) Bordered() bool { return base.bordered } +// BorderColor returns the color that the border of this widget should be drawn in func (base *Base) BorderColor() string { if base.Focusable() { - return base.commonSettings.Colors.BorderFocusable + return base.commonSettings.Colors.BorderTheme.Focusable } - return base.commonSettings.Colors.BorderNormal + return base.commonSettings.Colors.BorderTheme.Unfocusable } func (base *Base) CommonSettings() *cfg.Common { @@ -69,10 +70,10 @@ func (base *Base) ContextualTitle(defaultStr string) string { } else if defaultStr != "" && base.FocusChar() == "" { return fmt.Sprintf(" %s ", defaultStr) } else if defaultStr == "" && base.FocusChar() != "" { - return fmt.Sprintf(" [darkgray::u]%s[::-][green] ", base.FocusChar()) - } else { - return fmt.Sprintf(" %s [darkgray::u]%s[::-][green] ", defaultStr, base.FocusChar()) + return fmt.Sprintf(" [darkgray::u]%s[::-][white] ", base.FocusChar()) } + + return fmt.Sprintf(" %s [darkgray::u]%s[::-][white] ", defaultStr, base.FocusChar()) } func (base *Base) Disable() { diff --git a/view/text_widget.go b/view/text_widget.go index 41f96a9b..176bda88 100644 --- a/view/text_widget.go +++ b/view/text_widget.go @@ -44,12 +44,12 @@ func (widget *TextWidget) Redraw(data func() (string, string, bool)) { func (widget *TextWidget) createView(bordered bool) *tview.TextView { view := tview.NewTextView() - view.SetBackgroundColor(wtf.ColorFor(widget.commonSettings.Colors.Background)) + view.SetBackgroundColor(wtf.ColorFor(widget.commonSettings.Colors.WidgetTheme.Background)) view.SetBorder(bordered) view.SetBorderColor(wtf.ColorFor(widget.BorderColor())) view.SetDynamicColors(true) - view.SetTextColor(wtf.ColorFor(widget.commonSettings.Colors.Text)) - view.SetTitleColor(wtf.ColorFor(widget.commonSettings.Colors.Title)) + view.SetTextColor(wtf.ColorFor(widget.commonSettings.Colors.TextTheme.Text)) + view.SetTitleColor(wtf.ColorFor(widget.commonSettings.Colors.TextTheme.Title)) view.SetWrap(false) return view