refactor(config)!: move non-style theme options to [ui]
This commit is contained in:
parent
37cd42c811
commit
534c4e3c64
12 changed files with 228 additions and 197 deletions
|
|
@ -69,6 +69,47 @@ arrows = ["◀", "▶"]
|
|||
# Whether clicking an arrow selects the tab next to the active one.
|
||||
clickable_arrows = true
|
||||
|
||||
[ui.title]
|
||||
# "left", "center" or "right".
|
||||
alignment = "left"
|
||||
|
||||
[ui.footer]
|
||||
alignment = "left"
|
||||
|
||||
[ui.border]
|
||||
enabled = true
|
||||
padding = [0, 0, 1, 1] # [top, bottom, left, right]
|
||||
# "hidden", "plain", "round", "thick" or "double".
|
||||
normal_set = "round"
|
||||
active_set = "round"
|
||||
|
||||
[ui.guilds_tree]
|
||||
auto_expand_folders = true
|
||||
# Give tree-like shape
|
||||
graphics = true
|
||||
|
||||
[ui.members_tree]
|
||||
# Give tree-like shape
|
||||
graphics = true
|
||||
|
||||
[ui.scroll_bar]
|
||||
visibility = "auto"
|
||||
# "minimal", "box_drawing", "vertical" or "double_vertical"
|
||||
symbol_set = "box_drawing"
|
||||
|
||||
[ui.messages_list]
|
||||
reply_indicator = ">"
|
||||
forwarded_indicator = "<"
|
||||
|
||||
[ui.mentions_list]
|
||||
# Note: width and height are capped to the available space
|
||||
# Minimum width
|
||||
# 0 = make the list as wide as possible
|
||||
min_width = 20
|
||||
# Maximum height
|
||||
# 0 = make the list as tall as needed
|
||||
max_height = 0
|
||||
|
||||
[timestamps]
|
||||
enabled = true
|
||||
# https://pkg.go.dev/time#Layout
|
||||
|
|
@ -259,31 +300,18 @@ select_bottom = "end"
|
|||
|
||||
# style = { foreground = "", background = "", attributes = "" or ["",""], underline = "", underline_color = "" }
|
||||
[theme.title]
|
||||
alignment = "left" # `"left"`, `"center"`, or `"right"`.
|
||||
normal_style = { attributes = "dim" }
|
||||
active_style = { foreground = "green", attributes = "bold" }
|
||||
|
||||
[theme.footer]
|
||||
alignment = "left"
|
||||
normal_style = { attributes = "dim" }
|
||||
active_style = { foreground = "green", attributes = "bold" }
|
||||
|
||||
[theme.border]
|
||||
enabled = true
|
||||
padding = [0, 0, 1, 1] # [top, bottom, left, right]
|
||||
|
||||
normal_style = { attributes = "dim" }
|
||||
active_style = { foreground = "green", attributes = "bold" }
|
||||
|
||||
# `"hidden"`, `"plain"`, `"round"`, `"thick"`, or `"double"`.
|
||||
normal_set = "round"
|
||||
active_set = "round"
|
||||
|
||||
[theme.guilds_tree]
|
||||
auto_expand_folders = true
|
||||
|
||||
# Give tree-like shape
|
||||
graphics = true
|
||||
graphics_color = "default"
|
||||
|
||||
# Direct-message recipient presence styles.
|
||||
|
|
@ -293,8 +321,6 @@ dnd_style = { foreground = "red" }
|
|||
offline_style = { foreground = "gray" }
|
||||
|
||||
[theme.members_tree]
|
||||
# Give tree-like shape
|
||||
graphics = true
|
||||
graphics_color = "default"
|
||||
|
||||
# Styles of the status dot before each member.
|
||||
|
|
@ -304,16 +330,10 @@ dnd_style = { foreground = "red" }
|
|||
offline_style = { foreground = "gray" }
|
||||
|
||||
[theme.scroll_bar]
|
||||
visibility = "auto"
|
||||
# "minimal", "box_drawing", "vertical", or "double_vertical"
|
||||
symbol_set = "box_drawing"
|
||||
track_style = { attributes = "dim" }
|
||||
thumb_style = {}
|
||||
|
||||
[theme.messages_list]
|
||||
reply_indicator = ">"
|
||||
forwarded_indicator = "<"
|
||||
|
||||
mention_style = { foreground = "blue", attributes = "bold" }
|
||||
emoji_style = { foreground = "green" }
|
||||
url_style = { foreground = "blue" }
|
||||
|
|
@ -336,14 +356,6 @@ footer_style = { attributes = ["dim", "italic"] }
|
|||
url_style = { foreground = "blue", underline = "solid" }
|
||||
|
||||
[theme.mentions_list]
|
||||
# Note: width and height are capped to the avaliable space
|
||||
# Minimum width
|
||||
# 0 = make the list as wide as possible
|
||||
min_width = 20
|
||||
# Maximum height
|
||||
# 0 = make the list as tall as needed
|
||||
max_height = 0
|
||||
|
||||
selected_style = { attributes = "reverse" }
|
||||
|
||||
[theme.dialog]
|
||||
|
|
|
|||
|
|
@ -6,33 +6,11 @@ import (
|
|||
|
||||
"github.com/ayn2op/arikawa/v3/discord"
|
||||
"github.com/ayn2op/tview"
|
||||
"github.com/ayn2op/tview/list"
|
||||
"github.com/ayn2op/tview/scrollbar"
|
||||
"github.com/gdamore/tcell/v3"
|
||||
)
|
||||
|
||||
var errInvalidType = errors.New("invalid type")
|
||||
|
||||
type AlignmentWrapper struct{ tview.Alignment }
|
||||
|
||||
func (aw *AlignmentWrapper) UnmarshalTOML(v any) error {
|
||||
s, ok := v.(string)
|
||||
if !ok {
|
||||
return errInvalidType
|
||||
}
|
||||
switch s {
|
||||
case "left":
|
||||
aw.Alignment = tview.AlignmentLeft
|
||||
case "center":
|
||||
aw.Alignment = tview.AlignmentCenter
|
||||
case "right":
|
||||
aw.Alignment = tview.AlignmentRight
|
||||
default:
|
||||
return fmt.Errorf("unknown value: %q", s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type StyleWrapper struct{ tview.Style }
|
||||
|
||||
func (sw *StyleWrapper) UnmarshalTOML(v any) error {
|
||||
|
|
@ -113,72 +91,6 @@ func (sw *StyleWrapper) parseAttr(s string) {
|
|||
}
|
||||
}
|
||||
|
||||
type BorderSetWrapper struct{ tview.BorderSet }
|
||||
|
||||
func (bw *BorderSetWrapper) UnmarshalTOML(val any) error {
|
||||
s, ok := val.(string)
|
||||
if !ok {
|
||||
return errInvalidType
|
||||
}
|
||||
switch s {
|
||||
case "hidden":
|
||||
bw.BorderSet = tview.BorderSetHidden()
|
||||
case "plain":
|
||||
bw.BorderSet = tview.BorderSetPlain()
|
||||
case "round":
|
||||
bw.BorderSet = tview.BorderSetRound()
|
||||
case "thick":
|
||||
bw.BorderSet = tview.BorderSetThick()
|
||||
case "double":
|
||||
bw.BorderSet = tview.BorderSetDouble()
|
||||
default:
|
||||
return fmt.Errorf("unknown value: %q", s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SymbolSetWrapper struct{ scrollbar.SymbolSet }
|
||||
|
||||
func (sw *SymbolSetWrapper) UnmarshalTOML(val any) error {
|
||||
s, ok := val.(string)
|
||||
if !ok {
|
||||
return errInvalidType
|
||||
}
|
||||
switch s {
|
||||
case "minimal":
|
||||
sw.SymbolSet = scrollbar.SymbolSet{Thumb: "█", Begin: "▲", End: "▼"}
|
||||
case "box_drawing", "boxdrawing", "box":
|
||||
sw.SymbolSet = scrollbar.SymbolSet{Track: "│", Thumb: "█", Begin: "▲", End: "▼"}
|
||||
case "vertical":
|
||||
sw.SymbolSet = scrollbar.SymbolSetVertical()
|
||||
case "double_vertical":
|
||||
sw.SymbolSet = scrollbar.SymbolSetDoubleVertical()
|
||||
default:
|
||||
return fmt.Errorf("unknown value: %q", s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ScrollBarVisibilityWrapper struct{ list.ScrollBarVisibility }
|
||||
|
||||
func (vw *ScrollBarVisibilityWrapper) UnmarshalTOML(val any) error {
|
||||
s, ok := val.(string)
|
||||
if !ok {
|
||||
return errInvalidType
|
||||
}
|
||||
switch s {
|
||||
case "automatic", "auto":
|
||||
vw.ScrollBarVisibility = list.ScrollBarVisibilityAutomatic
|
||||
case "always":
|
||||
vw.ScrollBarVisibility = list.ScrollBarVisibilityAlways
|
||||
case "never", "hidden", "off":
|
||||
vw.ScrollBarVisibility = list.ScrollBarVisibilityNever
|
||||
default:
|
||||
return fmt.Errorf("unknown value: %q", s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type (
|
||||
HelpTheme struct {
|
||||
ShortKeyStyle StyleWrapper `toml:"short_key_style"`
|
||||
|
|
@ -192,40 +104,14 @@ type (
|
|||
ActiveStyle StyleWrapper `toml:"active_style"`
|
||||
}
|
||||
|
||||
TitleTheme struct {
|
||||
ThemeStyle
|
||||
Alignment AlignmentWrapper `toml:"alignment"`
|
||||
}
|
||||
|
||||
FooterTheme struct {
|
||||
ThemeStyle
|
||||
Alignment AlignmentWrapper `toml:"alignment"`
|
||||
}
|
||||
|
||||
BorderTheme struct {
|
||||
ThemeStyle
|
||||
Enabled bool `toml:"enabled"`
|
||||
Padding [4]int `toml:"padding"`
|
||||
|
||||
NormalSet BorderSetWrapper `toml:"normal_set"`
|
||||
ActiveSet BorderSetWrapper `toml:"active_set"`
|
||||
}
|
||||
|
||||
GuildsTreeTheme struct {
|
||||
CommonTreeTheme
|
||||
AutoExpandFolders bool `toml:"auto_expand_folders"`
|
||||
}
|
||||
|
||||
MessagesListTheme struct {
|
||||
ReplyIndicator string `toml:"reply_indicator"`
|
||||
ForwardedIndicator string `toml:"forwarded_indicator"`
|
||||
AuthorStyle StyleWrapper `toml:"author_style"`
|
||||
MentionStyle StyleWrapper `toml:"mention_style"`
|
||||
EmojiStyle StyleWrapper `toml:"emoji_style"`
|
||||
URLStyle StyleWrapper `toml:"url_style"`
|
||||
AttachmentStyle StyleWrapper `toml:"attachment_style"`
|
||||
ReactionStyle StyleWrapper `toml:"reaction_style"`
|
||||
OwnReactionStyle StyleWrapper `toml:"own_reaction_style"`
|
||||
AuthorStyle StyleWrapper `toml:"author_style"`
|
||||
MentionStyle StyleWrapper `toml:"mention_style"`
|
||||
EmojiStyle StyleWrapper `toml:"emoji_style"`
|
||||
URLStyle StyleWrapper `toml:"url_style"`
|
||||
AttachmentStyle StyleWrapper `toml:"attachment_style"`
|
||||
ReactionStyle StyleWrapper `toml:"reaction_style"`
|
||||
OwnReactionStyle StyleWrapper `toml:"own_reaction_style"`
|
||||
|
||||
MessageStyle StyleWrapper `toml:"message_style"`
|
||||
SelectedMessageStyle StyleWrapper `toml:"selected_message_style"`
|
||||
|
|
@ -245,9 +131,6 @@ type (
|
|||
}
|
||||
|
||||
MentionsListTheme struct {
|
||||
MinWidth uint `toml:"min_width"`
|
||||
MaxHeight uint `toml:"max_height"`
|
||||
|
||||
SelectedStyle StyleWrapper `toml:"selected_style"`
|
||||
}
|
||||
|
||||
|
|
@ -257,17 +140,15 @@ type (
|
|||
}
|
||||
|
||||
ScrollBarTheme struct {
|
||||
Visibility ScrollBarVisibilityWrapper `toml:"visibility"`
|
||||
SymbolSet SymbolSetWrapper `toml:"symbol_set"`
|
||||
TrackStyle StyleWrapper `toml:"track_style"`
|
||||
ThumbStyle StyleWrapper `toml:"thumb_style"`
|
||||
TrackStyle StyleWrapper `toml:"track_style"`
|
||||
ThumbStyle StyleWrapper `toml:"thumb_style"`
|
||||
}
|
||||
|
||||
Theme struct {
|
||||
Title TitleTheme `toml:"title"`
|
||||
Footer FooterTheme `toml:"footer"`
|
||||
Border BorderTheme `toml:"border"`
|
||||
GuildsTree GuildsTreeTheme `toml:"guilds_tree"`
|
||||
Title ThemeStyle `toml:"title"`
|
||||
Footer ThemeStyle `toml:"footer"`
|
||||
Border ThemeStyle `toml:"border"`
|
||||
GuildsTree CommonTreeTheme `toml:"guilds_tree"`
|
||||
MembersTree CommonTreeTheme `toml:"members_tree"`
|
||||
ScrollBar ScrollBarTheme `toml:"scroll_bar"`
|
||||
MessagesList MessagesListTheme `toml:"messages_list"`
|
||||
|
|
@ -278,7 +159,6 @@ type (
|
|||
)
|
||||
|
||||
type CommonTreeTheme struct {
|
||||
Graphics bool `toml:"graphics"`
|
||||
GraphicsColor string `toml:"graphics_color"`
|
||||
|
||||
OnlineStyle StyleWrapper `toml:"online_style"`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,110 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ayn2op/tview"
|
||||
"github.com/ayn2op/tview/list"
|
||||
"github.com/ayn2op/tview/scrollbar"
|
||||
)
|
||||
|
||||
type AlignmentWrapper struct{ tview.Alignment }
|
||||
|
||||
func (aw *AlignmentWrapper) UnmarshalTOML(v any) error {
|
||||
s, ok := v.(string)
|
||||
if !ok {
|
||||
return errInvalidType
|
||||
}
|
||||
switch s {
|
||||
case "left":
|
||||
aw.Alignment = tview.AlignmentLeft
|
||||
case "center":
|
||||
aw.Alignment = tview.AlignmentCenter
|
||||
case "right":
|
||||
aw.Alignment = tview.AlignmentRight
|
||||
default:
|
||||
return fmt.Errorf("unknown value: %q", s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type BorderSetWrapper struct{ tview.BorderSet }
|
||||
|
||||
func (bw *BorderSetWrapper) UnmarshalTOML(val any) error {
|
||||
s, ok := val.(string)
|
||||
if !ok {
|
||||
return errInvalidType
|
||||
}
|
||||
switch s {
|
||||
case "hidden":
|
||||
bw.BorderSet = tview.BorderSetHidden()
|
||||
case "plain":
|
||||
bw.BorderSet = tview.BorderSetPlain()
|
||||
case "round":
|
||||
bw.BorderSet = tview.BorderSetRound()
|
||||
case "thick":
|
||||
bw.BorderSet = tview.BorderSetThick()
|
||||
case "double":
|
||||
bw.BorderSet = tview.BorderSetDouble()
|
||||
default:
|
||||
return fmt.Errorf("unknown value: %q", s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SymbolSetWrapper struct{ scrollbar.SymbolSet }
|
||||
|
||||
func (sw *SymbolSetWrapper) UnmarshalTOML(val any) error {
|
||||
s, ok := val.(string)
|
||||
if !ok {
|
||||
return errInvalidType
|
||||
}
|
||||
switch s {
|
||||
case "minimal":
|
||||
sw.SymbolSet = scrollbar.SymbolSet{Thumb: "█", Begin: "▲", End: "▼"}
|
||||
case "box_drawing", "boxdrawing", "box":
|
||||
sw.SymbolSet = scrollbar.SymbolSet{Track: "│", Thumb: "█", Begin: "▲", End: "▼"}
|
||||
case "vertical":
|
||||
sw.SymbolSet = scrollbar.SymbolSetVertical()
|
||||
case "double_vertical":
|
||||
sw.SymbolSet = scrollbar.SymbolSetDoubleVertical()
|
||||
default:
|
||||
return fmt.Errorf("unknown value: %q", s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ScrollBarVisibilityWrapper struct{ list.ScrollBarVisibility }
|
||||
|
||||
func (vw *ScrollBarVisibilityWrapper) UnmarshalTOML(val any) error {
|
||||
s, ok := val.(string)
|
||||
if !ok {
|
||||
return errInvalidType
|
||||
}
|
||||
switch s {
|
||||
case "automatic", "auto":
|
||||
vw.ScrollBarVisibility = list.ScrollBarVisibilityAutomatic
|
||||
case "always":
|
||||
vw.ScrollBarVisibility = list.ScrollBarVisibilityAlways
|
||||
case "never", "hidden", "off":
|
||||
vw.ScrollBarVisibility = list.ScrollBarVisibilityNever
|
||||
default:
|
||||
return fmt.Errorf("unknown value: %q", s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type (
|
||||
UIConfig struct {
|
||||
Tabs TabsConfig `toml:"tabs"`
|
||||
Tabs TabsConfig `toml:"tabs"`
|
||||
Title TitleConfig `toml:"title"`
|
||||
Footer TitleConfig `toml:"footer"`
|
||||
Border BorderConfig `toml:"border"`
|
||||
GuildsTree GuildsTreeConfig `toml:"guilds_tree"`
|
||||
MembersTree TreeConfig `toml:"members_tree"`
|
||||
ScrollBar ScrollBarConfig `toml:"scroll_bar"`
|
||||
MessagesList MessagesListConfig `toml:"messages_list"`
|
||||
MentionsList MentionsListConfig `toml:"mentions_list"`
|
||||
}
|
||||
|
||||
TabsConfig struct {
|
||||
|
|
@ -13,4 +115,39 @@ type (
|
|||
Arrows [2]string `toml:"arrows"`
|
||||
ClickableArrows bool `toml:"clickable_arrows"`
|
||||
}
|
||||
|
||||
TitleConfig struct {
|
||||
Alignment AlignmentWrapper `toml:"alignment"`
|
||||
}
|
||||
|
||||
BorderConfig struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
Padding [4]int `toml:"padding"`
|
||||
NormalSet BorderSetWrapper `toml:"normal_set"`
|
||||
ActiveSet BorderSetWrapper `toml:"active_set"`
|
||||
}
|
||||
|
||||
TreeConfig struct {
|
||||
Graphics bool `toml:"graphics"`
|
||||
}
|
||||
|
||||
GuildsTreeConfig struct {
|
||||
TreeConfig
|
||||
AutoExpandFolders bool `toml:"auto_expand_folders"`
|
||||
}
|
||||
|
||||
ScrollBarConfig struct {
|
||||
Visibility ScrollBarVisibilityWrapper `toml:"visibility"`
|
||||
SymbolSet SymbolSetWrapper `toml:"symbol_set"`
|
||||
}
|
||||
|
||||
MessagesListConfig struct {
|
||||
ReplyIndicator string `toml:"reply_indicator"`
|
||||
ForwardedIndicator string `toml:"forwarded_indicator"`
|
||||
}
|
||||
|
||||
MentionsListConfig struct {
|
||||
MinWidth uint `toml:"min_width"`
|
||||
MaxHeight uint `toml:"max_height"`
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ func (m *Model) box(focused bool) box.Widget {
|
|||
Keybind(m.editAction).
|
||||
Focused(focused && !m.disabled).
|
||||
OnChange(func(a textarea.Change) tview.Msg { return editMsg(a) })
|
||||
return ui.Box(text, &m.cfg.Theme, focused).Title(m.title()).Footer(m.footer())
|
||||
return ui.Box(text, m.cfg, focused).Title(m.title()).Footer(m.footer())
|
||||
}
|
||||
|
||||
// title returns what the composer is doing: editing, replying, or nothing.
|
||||
|
|
@ -523,16 +523,16 @@ func (p mentionsPopup) Handle(msg tview.Msg, area tview.Rectangle) tview.Msg {
|
|||
func (p mentionsPopup) area(area tview.Rectangle) tview.Rectangle {
|
||||
c := p.c
|
||||
borders := 0
|
||||
if c.cfg.Theme.Border.Enabled {
|
||||
if c.cfg.UI.Border.Enabled {
|
||||
borders = 1
|
||||
}
|
||||
x, _ := c.frame()
|
||||
maxW, maxH := area.Width, area.Height-c.Height()
|
||||
if t := int(c.cfg.Theme.MentionsList.MaxHeight); t != 0 {
|
||||
if t := int(c.cfg.UI.MentionsList.MaxHeight); t != 0 {
|
||||
maxH = min(maxH, t)
|
||||
}
|
||||
h := min(c.mentionsList.ItemCount()+borders, maxH) + borders + c.cfg.Theme.Border.Padding[1]
|
||||
w := int(c.cfg.Theme.MentionsList.MinWidth)
|
||||
h := min(c.mentionsList.ItemCount()+borders, maxH) + borders + c.cfg.UI.Border.Padding[1]
|
||||
w := int(c.cfg.UI.MentionsList.MinWidth)
|
||||
if w == 0 {
|
||||
w = maxW
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ func (m Model) View(focused bool) tview.Widget {
|
|||
m.root,
|
||||
m.selectionState,
|
||||
m.cfg,
|
||||
m.cfg.Theme.GuildsTree.CommonTreeTheme,
|
||||
m.cfg.Theme.GuildsTree,
|
||||
m.cfg.UI.GuildsTree.Graphics,
|
||||
m.cfg.Keybinds.GuildsTree.TreeKeybinds,
|
||||
focused,
|
||||
onChange,
|
||||
|
|
@ -163,7 +164,7 @@ func (m Model) createFolderNode(folder gateway.GuildFolder, guildsByID map[disco
|
|||
name = folder.Name
|
||||
}
|
||||
|
||||
folderNode := tree.NewNode(name).SetExpanded(m.cfg.Theme.GuildsTree.AutoExpandFolders)
|
||||
folderNode := tree.NewNode(name).SetExpanded(m.cfg.UI.GuildsTree.AutoExpandFolders)
|
||||
if folder.Color != 0 {
|
||||
folderStyle := tcell.StyleDefault.Foreground(tcell.NewHexColor(int32(folder.Color)))
|
||||
m.setNodeLineStyle(folderNode, folderStyle)
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ func (m *Model) SetChannel(channel *discord.Channel) tview.Cmd {
|
|||
func (m Model) View(focused bool) tview.Widget {
|
||||
onChange := func(c tree.Change) tview.Msg { return Msg(c) }
|
||||
onSelect := func(n *tree.Node) tview.Msg { return SelectedMsg{Node: n} }
|
||||
return uitree.New(m.root, m.selectionState, m.cfg, m.cfg.Theme.MembersTree, m.cfg.Keybinds.MembersTree, focused, onChange, onSelect).Title("Members")
|
||||
return uitree.New(m.root, m.selectionState, m.cfg, m.cfg.Theme.MembersTree, m.cfg.UI.MembersTree.Graphics, m.cfg.Keybinds.MembersTree, focused, onChange, onSelect).Title("Members")
|
||||
}
|
||||
|
||||
// Update returns m changed in response to msg and a command to run, or nil.
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ func NewModel(cfg *config.Config) Model {
|
|||
|
||||
// View shows the list in a box whose bottom corners join the composer's border below it.
|
||||
func (m Model) View() tview.Widget {
|
||||
set := m.cfg.Theme.Border.NormalSet.BorderSet
|
||||
set := m.cfg.UI.Border.NormalSet.BorderSet
|
||||
set.BottomLeft, set.BottomRight = set.BottomT, set.BottomT
|
||||
return ui.Box(m.listView(), &m.cfg.Theme, false).Title("Mentions").BorderSet(set)
|
||||
return ui.Box(m.listView(), m.cfg, false).Title("Mentions").BorderSet(set)
|
||||
}
|
||||
|
||||
func (Model) Init() tview.Cmd { return nil }
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ func NewModel(cfg *config.Config, state *ningen.State) Model {
|
|||
|
||||
// View shows the messages in a box titled with the channel and footed with footer, such as who is typing.
|
||||
func (m Model) View(focused bool, footer string) tview.Widget {
|
||||
return ui.Box(m.listView(focused), &m.cfg.Theme, focused).Title(m.title()).Footer(footer)
|
||||
return ui.Box(m.listView(focused), m.cfg, focused).Title(m.title()).Footer(footer)
|
||||
}
|
||||
|
||||
// title returns the selected channel and its topic, or "Messages" when none is selected.
|
||||
|
|
@ -97,11 +97,11 @@ func (m Model) title() string {
|
|||
}
|
||||
|
||||
func (m Model) listView(focused bool) list.Widget {
|
||||
cfg := m.cfg.Theme.ScrollBar
|
||||
cfg, theme := m.cfg.UI.ScrollBar, m.cfg.Theme.ScrollBar
|
||||
bar := scrollbar.New().
|
||||
SymbolSet(cfg.SymbolSet.SymbolSet).
|
||||
Style(cfg.TrackStyle.Style).
|
||||
ThumbStyle(cfg.ThumbStyle.Style)
|
||||
Style(theme.TrackStyle.Style).
|
||||
ThumbStyle(theme.ThumbStyle.Style)
|
||||
return list.New(m.selectionState, len(m.items), m.buildItem).
|
||||
SelectedStyle(m.cfg.Theme.MessagesList.SelectedMessageStyle.Style).
|
||||
ScrollBar(bar, cfg.Visibility.ScrollBarVisibility).
|
||||
|
|
@ -803,14 +803,14 @@ func (m Model) drawForwardedMessage(builder *richtext.Builder, message discord.M
|
|||
dimStyle := baseStyle.Dim(true)
|
||||
m.drawTimestamps(builder, message.Timestamp, baseStyle)
|
||||
m.drawAuthor(builder, message, baseStyle)
|
||||
builder.Write(m.cfg.Theme.MessagesList.ForwardedIndicator+" ", dimStyle)
|
||||
builder.Write(m.cfg.UI.MessagesList.ForwardedIndicator+" ", dimStyle)
|
||||
m.drawSnapshotContent(builder, message, message.MessageSnapshots[0].Message, baseStyle)
|
||||
builder.Write(" ("+m.formatTimestamp(message.MessageSnapshots[0].Message.Timestamp)+") ", dimStyle)
|
||||
}
|
||||
|
||||
func (m Model) drawReplyMessage(builder *richtext.Builder, message discord.Message, baseStyle tview.Style, width int) {
|
||||
dimStyle := baseStyle.Dim(true)
|
||||
builder.Write(m.cfg.Theme.MessagesList.ReplyIndicator+" ", dimStyle)
|
||||
builder.Write(m.cfg.UI.MessagesList.ReplyIndicator+" ", dimStyle)
|
||||
|
||||
if reference := message.ReferencedMessage; reference != nil {
|
||||
reference.GuildID = message.GuildID
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ func (m Model) View() tview.Widget {
|
|||
Content(content).
|
||||
Keybind(tabAction).
|
||||
OnSelect(func(i int) tview.Msg { return selectTabMsg(i) })
|
||||
return ui.Box(t, &m.cfg.Theme, false)
|
||||
return ui.Box(t, m.cfg, false)
|
||||
}
|
||||
|
||||
// tabs returns the login methods as tabs set up by the tabs config.
|
||||
|
|
|
|||
|
|
@ -28,17 +28,17 @@ func (Model) Init() tview.Cmd { return nil }
|
|||
func (m Model) View(onSelect func(picker.Item) tview.Msg, onCancel tview.Msg) tview.Widget {
|
||||
cfg := m.cfg
|
||||
bar := scrollbar.New().
|
||||
SymbolSet(cfg.Theme.ScrollBar.SymbolSet.SymbolSet).
|
||||
SymbolSet(cfg.UI.ScrollBar.SymbolSet.SymbolSet).
|
||||
Style(cfg.Theme.ScrollBar.TrackStyle.Style).
|
||||
ThumbStyle(cfg.Theme.ScrollBar.ThumbStyle.Style)
|
||||
p := picker.New(m.items, &m.searchState).
|
||||
ScrollBar(bar, cfg.Theme.ScrollBar.Visibility.ScrollBarVisibility).
|
||||
ScrollBar(bar, cfg.UI.ScrollBar.Visibility.ScrollBarVisibility).
|
||||
Keybind(bindKeys(cfg.Keybinds.Picker)).
|
||||
ListKeybind(ui.SelectionKeybind(cfg.Keybinds.Picker.SelectionKeybinds)).
|
||||
OnChange(func(c picker.Change) tview.Msg { return changeMsg(c) }).
|
||||
OnSelect(onSelect).
|
||||
OnCancel(onCancel)
|
||||
return ui.Box(p, &cfg.Theme, true).Title(m.title)
|
||||
return ui.Box(p, cfg, true).Title(m.title)
|
||||
}
|
||||
|
||||
func (m Model) Update(msg tview.Msg) (Model, tview.Cmd) {
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ import (
|
|||
"github.com/gdamore/tcell/v3"
|
||||
)
|
||||
|
||||
// New returns a boxed tree of the nodes under root, drawn with theme and moved with kbs, that turns changes and selected nodes into the messages onChange and onSelect return.
|
||||
func New(root *tree.Node, selectionState tree.SelectionState, cfg *config.Config, theme config.CommonTreeTheme, kbs config.TreeKeybinds, focused bool, onChange func(tree.Change) tview.Msg, onSelect func(*tree.Node) tview.Msg) box.Widget {
|
||||
set := cfg.Theme.Border.NormalSet.BorderSet
|
||||
// New returns a boxed tree of the nodes under root, drawn with theme and graphics and moved with kbs, that turns changes and selected nodes into the messages onChange and onSelect return.
|
||||
func New(root *tree.Node, selectionState tree.SelectionState, cfg *config.Config, theme config.CommonTreeTheme, graphics bool, kbs config.TreeKeybinds, focused bool, onChange func(tree.Change) tview.Msg, onSelect func(*tree.Node) tview.Msg) box.Widget {
|
||||
set := cfg.UI.Border.NormalSet.BorderSet
|
||||
if focused {
|
||||
set = cfg.Theme.Border.ActiveSet.BorderSet
|
||||
set = cfg.UI.Border.ActiveSet.BorderSet
|
||||
}
|
||||
t := tree.New(root, selectionState).
|
||||
TopLevel(1).
|
||||
|
|
@ -24,14 +24,14 @@ func New(root *tree.Node, selectionState tree.SelectionState, cfg *config.Config
|
|||
Collapsed: cfg.Sidebar.Markers.Collapsed,
|
||||
Leaf: cfg.Sidebar.Markers.Leaf,
|
||||
}).
|
||||
Graphics(theme.Graphics).
|
||||
Graphics(graphics).
|
||||
GraphicsSet(set).
|
||||
GraphicsStyle(tcell.StyleDefault.Foreground(tcell.GetColor(theme.GraphicsColor))).
|
||||
Keybind(bindKeys(kbs)).
|
||||
Focused(focused).
|
||||
OnChange(onChange).
|
||||
OnSelect(onSelect)
|
||||
return ui.Box(t, &cfg.Theme, focused)
|
||||
return ui.Box(t, cfg, focused)
|
||||
}
|
||||
|
||||
func bindKeys(kbs config.TreeKeybinds) func(tview.KeyMsg) tree.Action {
|
||||
|
|
|
|||
|
|
@ -12,24 +12,25 @@ import (
|
|||
"github.com/ayn2op/tview/box"
|
||||
)
|
||||
|
||||
// Box returns child in a box styled by the theme, highlighted while focused.
|
||||
func Box(child tview.Widget, theme *config.Theme, focused bool) box.Widget {
|
||||
padding := theme.Border.Padding
|
||||
// Box returns child in a box laid out and styled by cfg, highlighted while focused.
|
||||
func Box(child tview.Widget, cfg *config.Config, focused bool) box.Widget {
|
||||
ui, theme := cfg.UI, cfg.Theme
|
||||
padding := ui.Border.Padding
|
||||
b := box.New(child).
|
||||
Padding(padding[0], padding[1], padding[2], padding[3]).
|
||||
TitleAlignment(theme.Title.Alignment.Alignment).
|
||||
FooterAlignment(theme.Footer.Alignment.Alignment)
|
||||
if theme.Border.Enabled {
|
||||
TitleAlignment(ui.Title.Alignment.Alignment).
|
||||
FooterAlignment(ui.Footer.Alignment.Alignment)
|
||||
if ui.Border.Enabled {
|
||||
b = b.Borders(tview.BordersAll)
|
||||
}
|
||||
if focused {
|
||||
return b.BorderStyle(theme.Border.ActiveStyle.Style).
|
||||
BorderSet(theme.Border.ActiveSet.BorderSet).
|
||||
BorderSet(ui.Border.ActiveSet.BorderSet).
|
||||
TitleStyle(theme.Title.ActiveStyle.Style).
|
||||
FooterStyle(theme.Footer.ActiveStyle.Style)
|
||||
}
|
||||
return b.BorderStyle(theme.Border.NormalStyle.Style).
|
||||
BorderSet(theme.Border.NormalSet.BorderSet).
|
||||
BorderSet(ui.Border.NormalSet.BorderSet).
|
||||
TitleStyle(theme.Title.NormalStyle.Style).
|
||||
FooterStyle(theme.Footer.NormalStyle.Style)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue