theme.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. package config
  2. import (
  3. "errors"
  4. "github.com/ayn2op/tview"
  5. "github.com/gdamore/tcell/v3"
  6. )
  7. var errInvalidType = errors.New("invalid type")
  8. type AlignmentWrapper struct{ tview.Alignment }
  9. func (aw *AlignmentWrapper) UnmarshalTOML(v any) error {
  10. s, ok := v.(string)
  11. if !ok {
  12. return errInvalidType
  13. }
  14. switch s {
  15. case "left":
  16. aw.Alignment = tview.AlignmentLeft
  17. case "center":
  18. aw.Alignment = tview.AlignmentCenter
  19. case "right":
  20. aw.Alignment = tview.AlignmentRight
  21. }
  22. return nil
  23. }
  24. type StyleWrapper struct{ tcell.Style }
  25. func (sw *StyleWrapper) UnmarshalTOML(v any) error {
  26. m, ok := v.(map[string]any)
  27. if !ok {
  28. return errInvalidType
  29. }
  30. // Reset on new styles
  31. sw.Style = tcell.StyleDefault
  32. for key, val := range m {
  33. switch key {
  34. case "foreground":
  35. if s, ok := val.(string); ok {
  36. sw.Style = sw.Foreground(tcell.GetColor(s))
  37. }
  38. case "background":
  39. if s, ok := val.(string); ok {
  40. sw.Style = sw.Background(tcell.GetColor(s))
  41. }
  42. case "attributes":
  43. switch val := val.(type) {
  44. case string:
  45. sw.parseAttr(val)
  46. case []any:
  47. for _, attr := range val {
  48. if s, ok := attr.(string); ok {
  49. sw.parseAttr(s)
  50. }
  51. }
  52. }
  53. case "underline":
  54. if s, ok := val.(string); ok {
  55. switch s {
  56. case "":
  57. sw.Style = sw.Underline(tcell.UnderlineStyleNone)
  58. case "solid":
  59. sw.Style = sw.Underline(tcell.UnderlineStyleSolid)
  60. case "double":
  61. sw.Style = sw.Underline(tcell.UnderlineStyleDouble)
  62. case "curly":
  63. sw.Style = sw.Underline(tcell.UnderlineStyleCurly)
  64. case "dotted":
  65. sw.Style = sw.Underline(tcell.UnderlineStyleDotted)
  66. case "dashed":
  67. sw.Style = sw.Underline(tcell.UnderlineStyleDashed)
  68. }
  69. }
  70. case "underline_color":
  71. if s, ok := val.(string); ok {
  72. sw.Style = sw.Underline(tcell.GetColor(s))
  73. }
  74. }
  75. }
  76. return nil
  77. }
  78. func (sw *StyleWrapper) parseAttr(s string) {
  79. switch s {
  80. case "underline":
  81. sw.Style = sw.Underline(true)
  82. case "bold":
  83. sw.Style = sw.Bold(true)
  84. case "blink":
  85. sw.Style = sw.Blink(true)
  86. case "reverse":
  87. sw.Style = sw.Reverse(true)
  88. case "dim":
  89. sw.Style = sw.Dim(true)
  90. case "italic":
  91. sw.Style = sw.Italic(true)
  92. case "strikethrough":
  93. sw.Style = sw.StrikeThrough(true)
  94. }
  95. }
  96. type BorderSetWrapper struct{ tview.BorderSet }
  97. func (bw *BorderSetWrapper) UnmarshalTOML(val any) error {
  98. s, ok := val.(string)
  99. if !ok {
  100. return errInvalidType
  101. }
  102. switch s {
  103. case "hidden":
  104. bw.BorderSet = tview.BorderSetHidden()
  105. case "plain":
  106. bw.BorderSet = tview.BorderSetPlain()
  107. case "round":
  108. bw.BorderSet = tview.BorderSetRound()
  109. case "thick":
  110. bw.BorderSet = tview.BorderSetThick()
  111. case "double":
  112. bw.BorderSet = tview.BorderSetDouble()
  113. }
  114. return nil
  115. }
  116. type GlyphSetWrapper struct{ tview.GlyphSet }
  117. func (gw *GlyphSetWrapper) UnmarshalTOML(val any) error {
  118. s, ok := val.(string)
  119. if !ok {
  120. return errInvalidType
  121. }
  122. switch s {
  123. case "minimal":
  124. gw.GlyphSet = tview.MinimalGlyphSet()
  125. case "box_drawing", "boxdrawing", "box":
  126. gw.GlyphSet = tview.BoxDrawingGlyphSet()
  127. case "unicode":
  128. gw.GlyphSet = tview.UnicodeGlyphSet()
  129. }
  130. return nil
  131. }
  132. type ScrollBarVisibilityWrapper struct{ tview.ScrollBarVisibility }
  133. func (vw *ScrollBarVisibilityWrapper) UnmarshalTOML(val any) error {
  134. s, ok := val.(string)
  135. if !ok {
  136. return errInvalidType
  137. }
  138. switch s {
  139. case "automatic", "auto":
  140. vw.ScrollBarVisibility = tview.ScrollBarVisibilityAutomatic
  141. case "always":
  142. vw.ScrollBarVisibility = tview.ScrollBarVisibilityAlways
  143. case "never", "hidden", "off":
  144. vw.ScrollBarVisibility = tview.ScrollBarVisibilityNever
  145. }
  146. return nil
  147. }
  148. type (
  149. HelpTheme struct {
  150. ShortKeyStyle StyleWrapper `toml:"short_key_style"`
  151. ShortDescStyle StyleWrapper `toml:"short_desc_style"`
  152. FullKeyStyle StyleWrapper `toml:"full_key_style"`
  153. FullDescStyle StyleWrapper `toml:"full_desc_style"`
  154. }
  155. ThemeStyle struct {
  156. NormalStyle StyleWrapper `toml:"normal_style"`
  157. ActiveStyle StyleWrapper `toml:"active_style"`
  158. }
  159. TitleTheme struct {
  160. ThemeStyle
  161. Alignment AlignmentWrapper `toml:"alignment"`
  162. }
  163. FooterTheme struct {
  164. ThemeStyle
  165. Alignment AlignmentWrapper `toml:"alignment"`
  166. }
  167. BorderTheme struct {
  168. ThemeStyle
  169. Enabled bool `toml:"enabled"`
  170. Padding [4]int `toml:"padding"`
  171. NormalSet BorderSetWrapper `toml:"normal_set"`
  172. ActiveSet BorderSetWrapper `toml:"active_set"`
  173. }
  174. GuildsTreeTheme struct {
  175. AutoExpandFolders bool `toml:"auto_expand_folders"`
  176. Graphics bool `toml:"graphics"`
  177. GraphicsColor string `toml:"graphics_color"`
  178. Indents GuildsTreeIndents `toml:"indents"`
  179. }
  180. GuildsTreeIndents struct {
  181. Guild int `toml:"guild"`
  182. Category int `toml:"category"`
  183. Channel int `toml:"channel"`
  184. Forum int `toml:"forum"`
  185. GroupDM int `toml:"group_dm"`
  186. DM int `toml:"dm"`
  187. }
  188. MessagesListTheme struct {
  189. ReplyIndicator string `toml:"reply_indicator"`
  190. ForwardedIndicator string `toml:"forwarded_indicator"`
  191. AuthorStyle StyleWrapper `toml:"author_style"`
  192. MentionStyle StyleWrapper `toml:"mention_style"`
  193. EmojiStyle StyleWrapper `toml:"emoji_style"`
  194. URLStyle StyleWrapper `toml:"url_style"`
  195. AttachmentStyle StyleWrapper `toml:"attachment_style"`
  196. MessageStyle StyleWrapper `toml:"message_style"`
  197. SelectedMessageStyle StyleWrapper `toml:"selected_message_style"`
  198. Embeds MessagesListEmbedsTheme `toml:"embeds"`
  199. }
  200. MessagesListEmbedsTheme struct {
  201. ProviderStyle StyleWrapper `toml:"provider_style"`
  202. AuthorStyle StyleWrapper `toml:"author_style"`
  203. TitleStyle StyleWrapper `toml:"title_style"`
  204. DescriptionStyle StyleWrapper `toml:"description_style"`
  205. FieldNameStyle StyleWrapper `toml:"field_name_style"`
  206. FieldValueStyle StyleWrapper `toml:"field_value_style"`
  207. FooterStyle StyleWrapper `toml:"footer_style"`
  208. URLStyle StyleWrapper `toml:"url_style"`
  209. }
  210. MentionsListTheme struct {
  211. MinWidth uint `toml:"min_width"`
  212. MaxHeight uint `toml:"max_height"`
  213. }
  214. DialogTheme struct {
  215. Style StyleWrapper `toml:"style"`
  216. BackgroundStyle StyleWrapper `toml:"background_style"`
  217. }
  218. ScrollBarTheme struct {
  219. Visibility ScrollBarVisibilityWrapper `toml:"visibility"`
  220. GlyphSet GlyphSetWrapper `toml:"glyph_set"`
  221. TrackStyle StyleWrapper `toml:"track_style"`
  222. ThumbStyle StyleWrapper `toml:"thumb_style"`
  223. }
  224. Theme struct {
  225. Title TitleTheme `toml:"title"`
  226. Footer FooterTheme `toml:"footer"`
  227. Border BorderTheme `toml:"border"`
  228. GuildsTree GuildsTreeTheme `toml:"guilds_tree"`
  229. ScrollBar ScrollBarTheme `toml:"scroll_bar"`
  230. MessagesList MessagesListTheme `toml:"messages_list"`
  231. MentionsList MentionsListTheme `toml:"mentions_list"`
  232. Dialog DialogTheme `toml:"dialog"`
  233. Help HelpTheme `toml:"help"`
  234. }
  235. )