Simplify GUI settings and build flags

This commit is contained in:
every_holiday
2026-06-26 09:16:46 +09:00
parent 4d77e67870
commit ae426244e0
22 changed files with 846 additions and 237 deletions

View File

@@ -2,6 +2,7 @@ package config
import (
"bufio"
"fmt"
"os"
"path/filepath"
"strconv"
@@ -13,6 +14,7 @@ import (
type Config struct {
OSC OSCConfig
VrcLog VrcLogConfig
GUI GUIConfig
}
type OSCConfig struct {
@@ -29,9 +31,15 @@ type VrcLogConfig struct {
LogPatterns []string
}
type GUIConfig struct {
TopMost bool
FontSize int
}
func Load(path string) (*Config, error) {
cfg := &Config{
OSC: OSCConfig{Host: "127.0.0.1", Port: 9001},
GUI: GUIConfig{FontSize: 18},
}
if path == "" {
path = filepath.Join(common.RootDir(), "config", "config.toml")
@@ -98,6 +106,15 @@ func Load(path string) (*Config, error) {
case "file":
cfg.VrcLog.GuestFile = val
}
case "gui":
switch key {
case "top_most":
cfg.GUI.TopMost = parseBool(val, cfg.GUI.TopMost)
case "font_size":
if n, err := strconv.Atoi(val); err == nil && n > 0 {
cfg.GUI.FontSize = n
}
}
}
}
if cfg.VrcLog.GuestFile != "" {
@@ -111,6 +128,19 @@ func Load(path string) (*Config, error) {
return cfg, scanner.Err()
}
func SaveGUI(path string, gui GUIConfig) error {
path = resolvePath(path)
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
return err
}
data, err := os.ReadFile(path)
if err != nil && !os.IsNotExist(err) {
return err
}
content := upsertGUISection(string(data), gui)
return os.WriteFile(path, []byte(content), 0o644)
}
func parseList(value string) []string {
value = strings.TrimSpace(value)
value = strings.TrimPrefix(value, "[")
@@ -129,6 +159,76 @@ func parseList(value string) []string {
return out
}
func parseBool(value string, fallback bool) bool {
switch strings.ToLower(strings.TrimSpace(value)) {
case "true", "1", "on", "yes":
return true
case "false", "0", "off", "no":
return false
default:
return fallback
}
}
func resolvePath(path string) string {
if path == "" {
return filepath.Join(common.RootDir(), "config", "config.toml")
}
if !filepath.IsAbs(path) {
return filepath.Join(common.RootDir(), path)
}
return path
}
func upsertGUISection(existing string, gui GUIConfig) string {
normalized := strings.ReplaceAll(existing, "\r\n", "\n")
lines := strings.Split(normalized, "\n")
out := make([]string, 0, len(lines)+6)
inGUI := false
replaced := false
for _, raw := range lines {
line := raw
trimmed := strings.TrimSpace(strings.TrimPrefix(line, "\ufeff"))
if strings.HasPrefix(trimmed, "[") && strings.HasSuffix(trimmed, "]") {
section := strings.Trim(trimmed, "[]")
if section == "gui" {
if !replaced {
appendGUISection(&out, gui)
replaced = true
}
inGUI = true
continue
}
if inGUI {
inGUI = false
}
out = append(out, line)
continue
}
if inGUI {
continue
}
out = append(out, line)
}
if !replaced {
if len(out) > 0 && strings.TrimSpace(out[len(out)-1]) != "" {
out = append(out, "")
}
appendGUISection(&out, gui)
}
content := strings.Join(out, "\n")
content = strings.TrimRight(content, "\n")
return content + "\n"
}
func appendGUISection(out *[]string, gui GUIConfig) {
*out = append(*out,
"[gui]",
fmt.Sprintf("top_most = %t", gui.TopMost),
fmt.Sprintf("font_size = %d", gui.FontSize),
)
}
func loadLines(path string) ([]string, error) {
data, err := os.ReadFile(path)
if err != nil {

View File

@@ -3,6 +3,7 @@ package config
import (
"os"
"path/filepath"
"strings"
"testing"
)
@@ -31,3 +32,44 @@ func TestLoadOSCValues(t *testing.T) {
}
}
func TestLoadGUIValues(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "config.toml")
if err := os.WriteFile(path, []byte("[gui]\ntop_most = true\nfont_size = 24\n"), 0o600); err != nil {
t.Fatalf("WriteFile: %v", err)
}
cfg, err := Load(path)
if err != nil {
t.Fatalf("Load returned error: %v", err)
}
if cfg.GUI.TopMost != true || cfg.GUI.FontSize != 24 {
t.Fatalf("unexpected gui values: %+v", cfg.GUI)
}
}
func TestSaveGUIUpdatesSection(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "config.toml")
initial := []byte("[self]\nname = \"alice\"\n\n[gui]\ntop_most = false\nfont_size = 18\n")
if err := os.WriteFile(path, initial, 0o600); err != nil {
t.Fatalf("WriteFile: %v", err)
}
if err := SaveGUI(path, GUIConfig{TopMost: true, FontSize: 26}); err != nil {
t.Fatalf("SaveGUI returned error: %v", err)
}
cfg, err := Load(path)
if err != nil {
t.Fatalf("Load returned error: %v", err)
}
if cfg.GUI.TopMost != true || cfg.GUI.FontSize != 26 {
t.Fatalf("unexpected saved gui values: %+v", cfg.GUI)
}
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("ReadFile: %v", err)
}
text := string(data)
if !strings.Contains(text, "[self]") || !strings.Contains(text, "name = \"alice\"") {
t.Fatalf("non-gui config content was lost: %s", text)
}
}