mirror of
https://github.com/VladimirMarkelov/clui.git
synced 2025-04-26 13:49:01 +08:00
theme loading from file
This commit is contained in:
parent
2430ca0bda
commit
8b83266c57
125
composer.go
125
composer.go
@ -1,7 +1,7 @@
|
||||
package clui
|
||||
|
||||
import (
|
||||
"github.com/nsf/termbox-go"
|
||||
term "github.com/nsf/termbox-go"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
@ -22,9 +22,9 @@ type Composer struct {
|
||||
themeManager *ThemeManager
|
||||
|
||||
// multi key sequences support. The flag below are true if the last keyboard combination was Ctrl+S or Ctrl+W respectively
|
||||
ctrlKey termbox.Key
|
||||
ctrlKey term.Key
|
||||
// last pressed key - to make repeatable actions simpler, e.g, at first one presses Ctrl+S and then just repeatedly presses arrow lest to resize View
|
||||
lastKey termbox.Key
|
||||
lastKey term.Key
|
||||
|
||||
//debug
|
||||
logger *log.Logger
|
||||
@ -37,15 +37,15 @@ func (c *Composer) initBuffer() {
|
||||
|
||||
// Initialize library and starts console management
|
||||
func InitLibrary() *Composer {
|
||||
err := termbox.Init()
|
||||
err := term.Init()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
c := new(Composer)
|
||||
c.ctrlKey = termbox.KeyEsc
|
||||
c.ctrlKey = term.KeyEsc
|
||||
|
||||
termbox.HideCursor()
|
||||
term.HideCursor()
|
||||
|
||||
file, _ := os.OpenFile("debugui.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
c.logger = log.New(file, "", log.Ldate|log.Ltime|log.Lshortfile)
|
||||
@ -55,12 +55,12 @@ func InitLibrary() *Composer {
|
||||
|
||||
c.views = make([]View, 0)
|
||||
|
||||
c.width, c.height = termbox.Size()
|
||||
c.width, c.height = term.Size()
|
||||
c.initBuffer()
|
||||
|
||||
c.themeManager = NewThemeManager()
|
||||
|
||||
termbox.SetInputMode(termbox.InputAlt | termbox.InputMouse)
|
||||
term.SetInputMode(term.InputAlt | term.InputMouse)
|
||||
|
||||
c.redrawAll()
|
||||
|
||||
@ -72,12 +72,12 @@ func (c *Composer) redrawAll() {
|
||||
for i := 0; i < c.width; i++ {
|
||||
sym, ok := c.canvas.Symbol(i, j)
|
||||
if ok {
|
||||
termbox.SetCell(i, j, sym.Ch, termbox.Attribute(sym.Fg), termbox.Attribute(sym.Bg))
|
||||
term.SetCell(i, j, sym.Ch, term.Attribute(sym.Fg), term.Attribute(sym.Bg))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
termbox.Flush()
|
||||
term.Flush()
|
||||
}
|
||||
|
||||
// Repaints all View on the screen. Now the method is not efficient: at first clears a console and then draws all Views starting from the bottom
|
||||
@ -176,7 +176,7 @@ func (c *Composer) moveActiveWindowToBottom() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *Composer) termboxEventToLocal(ev termbox.Event) Event {
|
||||
func (c *Composer) termboxEventToLocal(ev term.Event) Event {
|
||||
e := Event{Type: EventType(ev.Type), Ch: ev.Ch, Key: ev.Key, Err: ev.Err, X: ev.MouseX, Y: ev.MouseY, Mod: ev.Mod}
|
||||
return e
|
||||
}
|
||||
@ -198,7 +198,7 @@ func (c *Composer) topView() View {
|
||||
return c.views[len(c.views)-1]
|
||||
}
|
||||
|
||||
func (c *Composer) resizeTopView(ev termbox.Event) bool {
|
||||
func (c *Composer) resizeTopView(ev term.Event) bool {
|
||||
view := c.topView()
|
||||
if view == nil {
|
||||
return false
|
||||
@ -207,13 +207,13 @@ func (c *Composer) resizeTopView(ev termbox.Event) bool {
|
||||
w, h := view.Size()
|
||||
w1, h1 := w, h
|
||||
minW, minH := view.Constraints()
|
||||
if ev.Key == termbox.KeyArrowUp && minH < h {
|
||||
if ev.Key == term.KeyArrowUp && minH < h {
|
||||
h--
|
||||
} else if ev.Key == termbox.KeyArrowLeft && minW < w {
|
||||
} else if ev.Key == term.KeyArrowLeft && minW < w {
|
||||
w--
|
||||
} else if ev.Key == termbox.KeyArrowDown {
|
||||
} else if ev.Key == term.KeyArrowDown {
|
||||
h++
|
||||
} else if ev.Key == termbox.KeyArrowRight {
|
||||
} else if ev.Key == term.KeyArrowRight {
|
||||
w++
|
||||
}
|
||||
|
||||
@ -227,21 +227,21 @@ func (c *Composer) resizeTopView(ev termbox.Event) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *Composer) moveTopView(ev termbox.Event) bool {
|
||||
func (c *Composer) moveTopView(ev term.Event) bool {
|
||||
if len(c.views) > 0 {
|
||||
view := c.topView()
|
||||
if view != nil {
|
||||
x, y := view.Pos()
|
||||
w, h := view.Size()
|
||||
x1, y1 := x, y
|
||||
cx, cy := termbox.Size()
|
||||
if ev.Key == termbox.KeyArrowUp && y > 0 {
|
||||
cx, cy := term.Size()
|
||||
if ev.Key == term.KeyArrowUp && y > 0 {
|
||||
y--
|
||||
} else if ev.Key == termbox.KeyArrowDown && y+h < cy {
|
||||
} else if ev.Key == term.KeyArrowDown && y+h < cy {
|
||||
y++
|
||||
} else if ev.Key == termbox.KeyArrowLeft && x > 0 {
|
||||
} else if ev.Key == term.KeyArrowLeft && x > 0 {
|
||||
x--
|
||||
} else if ev.Key == termbox.KeyArrowRight && x+w < cx {
|
||||
} else if ev.Key == term.KeyArrowRight && x+w < cx {
|
||||
x++
|
||||
}
|
||||
|
||||
@ -258,32 +258,32 @@ func (c *Composer) moveTopView(ev termbox.Event) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Composer) isDeadKey(ev termbox.Event) bool {
|
||||
if ev.Key == termbox.KeyCtrlS || ev.Key == termbox.KeyCtrlW {
|
||||
func (c *Composer) isDeadKey(ev term.Event) bool {
|
||||
if ev.Key == term.KeyCtrlS || ev.Key == term.KeyCtrlP || ev.Key == term.KeyCtrlW {
|
||||
c.ctrlKey = ev.Key
|
||||
c.lastKey = termbox.KeyEsc
|
||||
c.lastKey = term.KeyEsc
|
||||
return true
|
||||
}
|
||||
|
||||
c.ctrlKey = termbox.KeyEsc
|
||||
c.ctrlKey = term.KeyEsc
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *Composer) processKeySeq(ev termbox.Event) bool {
|
||||
if c.ctrlKey == termbox.KeyEsc {
|
||||
func (c *Composer) processKeySeq(ev term.Event) bool {
|
||||
if c.ctrlKey == term.KeyEsc {
|
||||
return false
|
||||
}
|
||||
|
||||
if c.ctrlKey == termbox.KeyCtrlS {
|
||||
if c.lastKey == termbox.KeyEsc {
|
||||
if c.ctrlKey == term.KeyCtrlS {
|
||||
if c.lastKey == term.KeyEsc {
|
||||
c.lastKey = ev.Key
|
||||
} else if c.lastKey != ev.Key {
|
||||
c.ctrlKey = termbox.KeyEsc
|
||||
c.ctrlKey = term.KeyEsc
|
||||
return false
|
||||
}
|
||||
|
||||
switch ev.Key {
|
||||
case termbox.KeyArrowUp, termbox.KeyArrowDown, termbox.KeyArrowLeft, termbox.KeyArrowRight:
|
||||
case term.KeyArrowUp, term.KeyArrowDown, term.KeyArrowLeft, term.KeyArrowRight:
|
||||
evCopy := ev
|
||||
c.resizeTopView(evCopy)
|
||||
return true
|
||||
@ -292,34 +292,39 @@ func (c *Composer) processKeySeq(ev termbox.Event) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if c.ctrlKey == termbox.KeyCtrlW {
|
||||
if c.lastKey == termbox.KeyEsc {
|
||||
if c.ctrlKey == term.KeyCtrlP {
|
||||
if c.lastKey == term.KeyEsc {
|
||||
c.lastKey = ev.Key
|
||||
} else if c.lastKey != ev.Key {
|
||||
c.ctrlKey = termbox.KeyEsc
|
||||
c.ctrlKey = term.KeyEsc
|
||||
return false
|
||||
}
|
||||
|
||||
switch ev.Key {
|
||||
case termbox.KeyArrowUp, termbox.KeyArrowDown, termbox.KeyArrowLeft, termbox.KeyArrowRight:
|
||||
case term.KeyArrowUp, term.KeyArrowDown, term.KeyArrowLeft, term.KeyArrowRight:
|
||||
evCopy := ev
|
||||
c.moveTopView(evCopy)
|
||||
return true
|
||||
case termbox.KeyCtrlH:
|
||||
// if len(c.windowOrder) > 1 && ev.Mod&termbox.ModControl != 0 {
|
||||
// c.moveActiveWindowToBottom()
|
||||
// }
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
c.ctrlKey = termbox.KeyEsc
|
||||
if c.ctrlKey == term.KeyCtrlW {
|
||||
switch ev.Key {
|
||||
case term.KeyCtrlH:
|
||||
c.moveActiveWindowToBottom()
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
c.ctrlKey = term.KeyEsc
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *Composer) processKey(ev termbox.Event) bool {
|
||||
func (c *Composer) processKey(ev term.Event) bool {
|
||||
if c.processKeySeq(ev) {
|
||||
return false
|
||||
}
|
||||
@ -328,13 +333,13 @@ func (c *Composer) processKey(ev termbox.Event) bool {
|
||||
}
|
||||
|
||||
switch ev.Key {
|
||||
case termbox.KeyCtrlQ:
|
||||
case term.KeyCtrlQ:
|
||||
return true
|
||||
// case termbox.KeyArrowUp, termbox.KeyArrowDown, termbox.KeyArrowLeft, termbox.KeyArrowRight:
|
||||
// case term.KeyArrowUp, term.KeyArrowDown, term.KeyArrowLeft, term.KeyArrowRight:
|
||||
// if c.sendEventToActiveView(c.termboxEventToLocal(ev)) {
|
||||
// c.RefreshScreen()
|
||||
// }
|
||||
// case termbox.KeyEnd:
|
||||
// case term.KeyEnd:
|
||||
// if c.sendEventToActiveView(c.termboxEventToLocal(ev)) {
|
||||
// c.RefreshScreen()
|
||||
// }
|
||||
@ -348,7 +353,7 @@ func (c *Composer) processKey(ev termbox.Event) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *Composer) processMouseClick(ev termbox.Event) {
|
||||
func (c *Composer) processMouseClick(ev term.Event) {
|
||||
view, hit := c.checkWindowUnderMouse(ev.MouseX, ev.MouseY)
|
||||
|
||||
if view == nil {
|
||||
@ -445,10 +450,10 @@ func (c *Composer) Stop() {
|
||||
func (c *Composer) MainLoop() {
|
||||
// c.redrawAll()
|
||||
|
||||
eventQueue := make(chan termbox.Event)
|
||||
eventQueue := make(chan term.Event)
|
||||
go func() {
|
||||
for {
|
||||
eventQueue <- termbox.PollEvent()
|
||||
eventQueue <- term.PollEvent()
|
||||
}
|
||||
}()
|
||||
|
||||
@ -456,17 +461,17 @@ func (c *Composer) MainLoop() {
|
||||
select {
|
||||
case ev := <-eventQueue:
|
||||
switch ev.Type {
|
||||
case termbox.EventKey:
|
||||
case term.EventKey:
|
||||
if c.processKey(ev) {
|
||||
return
|
||||
}
|
||||
case termbox.EventMouse:
|
||||
case term.EventMouse:
|
||||
c.processMouseClick(ev)
|
||||
case termbox.EventError:
|
||||
case term.EventError:
|
||||
panic(ev.Err)
|
||||
// case termbox.EventResize:
|
||||
// termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
|
||||
// c.width, c.height = termbox.Size()
|
||||
// case term.EventResize:
|
||||
// term.Clear(term.ColorDefault, term.ColorDefault)
|
||||
// c.width, c.height = term.Size()
|
||||
// c.screen = c.initBuffer(c.width, c.height)
|
||||
// c.RefreshScreen()
|
||||
}
|
||||
@ -487,13 +492,13 @@ func (c *Composer) PutEvent(ev Event) {
|
||||
|
||||
// Closes console management and makes a console cursor visible
|
||||
func (c *Composer) Close() {
|
||||
termbox.SetCursor(3, 3)
|
||||
termbox.Close()
|
||||
term.SetCursor(3, 3)
|
||||
term.Close()
|
||||
}
|
||||
|
||||
// Shows consolse cursor at given position. Setting cursor to -1,-1 hides cursor
|
||||
func (c *Composer) SetCursorPos(x, y int) {
|
||||
termbox.SetCursor(x, y)
|
||||
term.SetCursor(x, y)
|
||||
}
|
||||
|
||||
func (c *Composer) DestroyWindow(view View) {
|
||||
|
@ -28,9 +28,6 @@ type (
|
||||
EventType int
|
||||
Direction int
|
||||
PackType int
|
||||
// EditBoxMode int
|
||||
ObjId string
|
||||
ColorId string
|
||||
)
|
||||
|
||||
// Internal event structure. Used by Windows and controls to communicate with Composer
|
||||
@ -145,7 +142,7 @@ const (
|
||||
// general colors
|
||||
ColorBack = "Back"
|
||||
ColorText = "Text"
|
||||
ColorDisabledText = "Gray"
|
||||
ColorDisabledText = "GrayText"
|
||||
ColorDisabledBack = "GrayBack"
|
||||
|
||||
// editable & listbox-like controls
|
||||
@ -169,7 +166,7 @@ const (
|
||||
ColorControlActiveText = "ControlActiveText"
|
||||
ColorControlDisabledBack = "ControlDisabledBack"
|
||||
ColorControlDisabledText = "ControlDisabledText"
|
||||
ColorControlShadow = "ControlShadow"
|
||||
ColorControlShadow = "ControlShadowBack"
|
||||
|
||||
// progressbar colors
|
||||
ColorProgressBack = "ProgressBack"
|
||||
|
47
ctrlutil.go
47
ctrlutil.go
@ -1,8 +1,8 @@
|
||||
package clui
|
||||
|
||||
import (
|
||||
_ "fmt"
|
||||
term "github.com/nsf/termbox-go"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func CalculateMinimalSize(c Control) (int, int) {
|
||||
@ -130,7 +130,7 @@ func RepositionControls(dx, dy int, c Control) {
|
||||
}
|
||||
}
|
||||
|
||||
func RealColor(tm Theme, clr term.Attribute, id ColorId) term.Attribute {
|
||||
func RealColor(tm Theme, clr term.Attribute, id string) term.Attribute {
|
||||
if clr != ColorDefault {
|
||||
return clr
|
||||
}
|
||||
@ -141,3 +141,46 @@ func RealColor(tm Theme, clr term.Attribute, id ColorId) term.Attribute {
|
||||
|
||||
return clr
|
||||
}
|
||||
|
||||
func StringToColor(str string) term.Attribute {
|
||||
var parts []string
|
||||
if strings.ContainsRune(str, '+') {
|
||||
parts = strings.Split(str, "+")
|
||||
} else if strings.ContainsRune(str, '|') {
|
||||
parts = strings.Split(str, "|")
|
||||
} else if strings.ContainsRune(str, ' ') {
|
||||
parts = strings.Split(str, " ")
|
||||
} else {
|
||||
parts = append(parts, str)
|
||||
}
|
||||
|
||||
var cmap = map[string]term.Attribute{
|
||||
"default": term.ColorDefault,
|
||||
"black": term.ColorBlack,
|
||||
"red": term.ColorRed,
|
||||
"green": term.ColorGreen,
|
||||
"yellow": term.ColorYellow,
|
||||
"blue": term.ColorBlue,
|
||||
"magenta": term.ColorMagenta,
|
||||
"cyan": term.ColorCyan,
|
||||
"white": term.ColorWhite,
|
||||
"bold": term.AttrBold,
|
||||
"bright": term.AttrBold, // windows make color brighter when it is bold
|
||||
"underline": term.AttrUnderline,
|
||||
"underlined": term.AttrUnderline,
|
||||
"reverse": term.AttrReverse,
|
||||
}
|
||||
|
||||
var clr term.Attribute
|
||||
for _, item := range parts {
|
||||
item = strings.Trim(item, " ")
|
||||
item = strings.ToLower(item)
|
||||
|
||||
c, ok := cmap[item]
|
||||
if ok {
|
||||
clr |= c
|
||||
}
|
||||
}
|
||||
|
||||
return clr
|
||||
}
|
||||
|
@ -26,8 +26,8 @@ type Canvas interface {
|
||||
}
|
||||
|
||||
type Theme interface {
|
||||
SysObject(ObjId) string
|
||||
SysColor(ColorId) term.Attribute
|
||||
SysObject(string) string
|
||||
SysColor(string) term.Attribute
|
||||
}
|
||||
|
||||
type View interface {
|
||||
|
142
theme.go
142
theme.go
@ -1,7 +1,11 @@
|
||||
package clui
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
term "github.com/nsf/termbox-go"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
@ -17,7 +21,9 @@ type ThemeManager struct {
|
||||
// available theme list
|
||||
themes map[string]theme
|
||||
// name of the current theme
|
||||
current string
|
||||
current string
|
||||
themePath string
|
||||
version string
|
||||
}
|
||||
|
||||
/*
|
||||
@ -27,21 +33,31 @@ theme object is not declared in the current one. If no parent is
|
||||
defined then the library uses default built-in theme.
|
||||
*/
|
||||
type theme struct {
|
||||
colors map[ColorId]term.Attribute
|
||||
objects map[ObjId]string
|
||||
colors map[string]term.Attribute
|
||||
objects map[string]string
|
||||
parent string
|
||||
title string
|
||||
author string
|
||||
version string
|
||||
}
|
||||
|
||||
const defaultTheme = "default"
|
||||
|
||||
func NewThemeManager() *ThemeManager {
|
||||
sm := new(ThemeManager)
|
||||
sm.current = defaultTheme
|
||||
sm.themes = make(map[string]theme, 0)
|
||||
|
||||
defTheme := theme{parent: ""}
|
||||
defTheme.colors = make(map[ColorId]term.Attribute, 0)
|
||||
defTheme.objects = make(map[ObjId]string, 0)
|
||||
sm.Reset()
|
||||
|
||||
return sm
|
||||
}
|
||||
|
||||
func (s *ThemeManager) Reset() {
|
||||
s.current = defaultTheme
|
||||
s.themes = make(map[string]theme, 0)
|
||||
|
||||
defTheme := theme{parent: "", title: "Default Theme", author: "V. Markelov", version: "1.0"}
|
||||
defTheme.colors = make(map[string]term.Attribute, 0)
|
||||
defTheme.objects = make(map[string]string, 0)
|
||||
|
||||
defTheme.objects[ObjSingleBorder] = "─│┌┐└┘"
|
||||
defTheme.objects[ObjDoubleBorder] = "═║╔╗╚╝"
|
||||
@ -84,12 +100,10 @@ func NewThemeManager() *ThemeManager {
|
||||
defTheme.colors[ColorProgressActiveText] = ColorBlack
|
||||
defTheme.colors[ColorProgressActiveBack] = ColorBlueBold
|
||||
|
||||
sm.themes[defaultTheme] = defTheme
|
||||
|
||||
return sm
|
||||
s.themes[defaultTheme] = defTheme
|
||||
}
|
||||
|
||||
func (s *ThemeManager) SysColor(color ColorId) term.Attribute {
|
||||
func (s *ThemeManager) SysColor(color string) term.Attribute {
|
||||
sch, ok := s.themes[s.current]
|
||||
if !ok {
|
||||
sch = s.themes[defaultTheme]
|
||||
@ -107,7 +121,7 @@ func (s *ThemeManager) SysColor(color ColorId) term.Attribute {
|
||||
return clr
|
||||
}
|
||||
|
||||
func (s *ThemeManager) SysObject(object ObjId) string {
|
||||
func (s *ThemeManager) SysObject(object string) string {
|
||||
sch, ok := s.themes[s.current]
|
||||
if !ok {
|
||||
sch = s.themes[defaultTheme]
|
||||
@ -123,9 +137,22 @@ func (s *ThemeManager) SysObject(object ObjId) string {
|
||||
}
|
||||
|
||||
func (s *ThemeManager) ThemeList() []string {
|
||||
str := make([]string, len(s.themes))
|
||||
for k := range s.themes {
|
||||
str = append(str, k)
|
||||
var str []string
|
||||
str = append(str, defaultTheme)
|
||||
|
||||
path := s.themePath
|
||||
if path == "" {
|
||||
path = "." + string(os.PathSeparator)
|
||||
}
|
||||
files, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
panic("Failed to read theme directory: " + s.themePath)
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
if !f.IsDir() {
|
||||
str = append(str, f.Name())
|
||||
}
|
||||
}
|
||||
|
||||
return str
|
||||
@ -136,9 +163,92 @@ func (s *ThemeManager) CurrentTheme() string {
|
||||
}
|
||||
|
||||
func (s *ThemeManager) SetCurrentTheme(name string) bool {
|
||||
if _, ok := s.themes[name]; !ok {
|
||||
tnames := s.ThemeList()
|
||||
for _, theme := range tnames {
|
||||
if theme == name {
|
||||
s.LoadTheme(theme)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := s.themes[name]; ok {
|
||||
s.current = name
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *ThemeManager) ThemePath() string {
|
||||
return s.themePath
|
||||
}
|
||||
|
||||
func (s *ThemeManager) SetThemePath(path string) {
|
||||
if path == s.themePath {
|
||||
return
|
||||
}
|
||||
|
||||
s.themePath = path
|
||||
s.Reset()
|
||||
}
|
||||
|
||||
func (s *ThemeManager) LoadTheme(name string) {
|
||||
if _, ok := s.themes[name]; ok {
|
||||
delete(s.themes, name)
|
||||
}
|
||||
|
||||
theme := theme{parent: "", title: "", author: ""}
|
||||
theme.colors = make(map[string]term.Attribute, 0)
|
||||
theme.objects = make(map[string]string, 0)
|
||||
|
||||
file, err := os.Open(s.themePath + string(os.PathSeparator) + name)
|
||||
if err != nil {
|
||||
panic("Failed to open theme " + name + " : " + err.Error())
|
||||
}
|
||||
defer file.Close()
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
line = strings.Trim(line, " ")
|
||||
|
||||
// skip comments
|
||||
if strings.HasPrefix(line, "#") || strings.HasPrefix(line, "/") {
|
||||
continue
|
||||
}
|
||||
|
||||
// skip invalid lines
|
||||
if !strings.Contains(line, "=") {
|
||||
continue
|
||||
}
|
||||
|
||||
parts := strings.SplitN(line, "=", 2)
|
||||
key := strings.Trim(parts[0], " ")
|
||||
value := strings.Trim(parts[1], " ")
|
||||
|
||||
low := strings.ToLower(key)
|
||||
if low == "parent" {
|
||||
theme.parent = value
|
||||
} else if low == "author" {
|
||||
theme.author = value
|
||||
} else if low == "name" || low == "title" {
|
||||
theme.title = value
|
||||
} else if low == "version" {
|
||||
theme.version = value
|
||||
} else if strings.HasSuffix(key, "Back") || strings.HasSuffix(key, "Text") {
|
||||
c := StringToColor(value)
|
||||
if c%32 == 0 {
|
||||
panic("Failed to read color: " + value)
|
||||
}
|
||||
theme.colors[key] = c
|
||||
} else {
|
||||
theme.objects[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
if theme.parent == "" {
|
||||
theme.parent = "default"
|
||||
}
|
||||
|
||||
s.themes[name] = theme
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user