Refactor Hyprland configs, introduce Sithego for theming, and add supporting scripts
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
[ColorScheme]
|
||||
active_colors={{ .Theme.Colors.Semantic.Text.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.SurfaceAlt.Value }}, {{ .Theme.Colors.Semantic.Surface.Value }}, {{ .Theme.Colors.Semantic.Disabled.Value }}, {{ .Theme.Colors.Semantic.Text.Value }}, {{ .Theme.Colors.Semantic.Text.Value }}, {{ .Theme.Colors.Semantic.Text.Value }}, {{ .Theme.Colors.Semantic.Text.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.Border.Value }}, {{ .Theme.Colors.Semantic.Accent.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.Accent.Value }}, {{ .Theme.Colors.Semantic.Warn.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.Text.Value }}, {{ .Theme.Colors.Semantic.Accent.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.Accent.Alpha .Theme.Colors.Semantic.Background 0.3 }}
|
||||
disabled_colors={{ .Theme.Colors.Semantic.Disabled.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.SurfaceAlt.Value }}, {{ .Theme.Colors.Semantic.Surface.Value }}, {{ .Theme.Colors.Semantic.Disabled.Value }}, {{ .Theme.Colors.Semantic.Disabled.Value }}, {{ .Theme.Colors.Semantic.Disabled.Value }}, {{ .Theme.Colors.Semantic.Disabled.Value }}, {{ .Theme.Colors.Semantic.Disabled.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.Border.Value }}, {{ .Theme.Colors.Semantic.Disabled.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.Disabled.Value }}, {{ .Theme.Colors.Semantic.Warn.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.Disabled.Value }}, {{ .Theme.Colors.Semantic.Disabled.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.Disabled.Value }}
|
||||
inactive_colors={{ .Theme.Colors.Semantic.Text.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.SurfaceAlt.Value }}, {{ .Theme.Colors.Semantic.Surface.Value }}, {{ .Theme.Colors.Semantic.Disabled.Value }}, {{ .Theme.Colors.Semantic.Text.Value }}, {{ .Theme.Colors.Semantic.Text.Value }}, {{ .Theme.Colors.Semantic.Text.Value }}, {{ .Theme.Colors.Semantic.Text.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.Border.Value }}, {{ .Theme.Colors.Semantic.Accent.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.Accent.Value }}, {{ .Theme.Colors.Semantic.Warn.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.Text.Value }}, {{ .Theme.Colors.Semantic.Accent.Value }}, {{ .Theme.Colors.Semantic.Background.Value }}, {{ .Theme.Colors.Semantic.Accent.Alpha .Theme.Colors.Semantic.Background 0.3 }}
|
||||
@@ -0,0 +1,105 @@
|
||||
package qt
|
||||
|
||||
import (
|
||||
"Sithego/themer"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
type Adapter struct {
|
||||
OutputDir string
|
||||
}
|
||||
|
||||
type Option func(*Adapter)
|
||||
|
||||
func WithOutputDir(dir string) Option {
|
||||
return func(a *Adapter) {
|
||||
a.OutputDir = dir
|
||||
}
|
||||
}
|
||||
|
||||
func New(opt ...Option) *Adapter {
|
||||
home, _ := os.UserHomeDir()
|
||||
a := &Adapter{
|
||||
OutputDir: home + "/.config/",
|
||||
}
|
||||
for _, o := range opt {
|
||||
o(a)
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *Adapter) Name() string {
|
||||
return "Qt"
|
||||
}
|
||||
|
||||
func (a *Adapter) Generate(t themer.Theme) error {
|
||||
qssComponents := []string{
|
||||
"template.qss",
|
||||
}
|
||||
outputDir := filepath.Join(a.OutputDir, "qt6ct")
|
||||
if err := os.MkdirAll(outputDir, 0775); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, component := range qssComponents {
|
||||
templatePath := filepath.Join("themer/adapters/qt", component)
|
||||
templ, err := template.ParseFiles(templatePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
qssOutputDir := filepath.Join(outputDir, "qss")
|
||||
err = os.MkdirAll(qssOutputDir, 0775)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
outputPath := filepath.Join(qssOutputDir, t.Meta.Name+".qss")
|
||||
|
||||
file, err := os.Create(outputPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = templ.Execute(file, struct {
|
||||
Theme themer.Theme
|
||||
}{
|
||||
Theme: t,
|
||||
})
|
||||
_ = file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Generate qt5ct/qt6ct color scheme (.conf)
|
||||
confTemplatePath := "themer/adapters/qt/colors.conf"
|
||||
if _, err := os.Stat(confTemplatePath); err == nil {
|
||||
templ, err := template.ParseFiles(confTemplatePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
confOutputDir := filepath.Join(outputDir, "colors")
|
||||
err = os.MkdirAll(confOutputDir, 0775)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
outputPath := filepath.Join(confOutputDir, t.Meta.Name+".conf")
|
||||
file, err := os.Create(outputPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = templ.Execute(file, struct {
|
||||
Theme themer.Theme
|
||||
}{
|
||||
Theme: t,
|
||||
})
|
||||
_ = file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/* Global Styles */
|
||||
QWidget {
|
||||
background-color: {{ .Theme.Colors.Semantic.Background.Value }};
|
||||
color: {{ .Theme.Colors.Semantic.Text.Value }};
|
||||
selection-background-color: {{ .Theme.Colors.Semantic.Accent.Value }};
|
||||
selection-color: {{ .Theme.Colors.Semantic.Background.Value }};
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
QPushButton {
|
||||
background-color: {{ .Theme.Colors.Semantic.SurfaceAlt.Value }};
|
||||
border: 1px solid {{ .Theme.Colors.Semantic.Border.Value }};
|
||||
border-radius: {{ .Theme.Spacing.Radius }};
|
||||
padding: {{ .Theme.Spacing.Padding }};
|
||||
}
|
||||
|
||||
QPushButton:hover {
|
||||
background-color: {{ .Theme.Colors.Semantic.Border.Value }};
|
||||
}
|
||||
|
||||
QPushButton:pressed {
|
||||
background-color: {{ .Theme.Colors.Semantic.Accent.Value }};
|
||||
color: {{ .Theme.Colors.Semantic.Background.Value }};
|
||||
}
|
||||
|
||||
QPushButton:disabled {
|
||||
background-color: {{ .Theme.Colors.Semantic.Background.Value }};
|
||||
color: {{ .Theme.Colors.Semantic.Disabled.Value }};
|
||||
border-color: {{ .Theme.Colors.Semantic.Disabled.Value }};
|
||||
}
|
||||
|
||||
/* Input Fields */
|
||||
QLineEdit, QTextEdit, QPlainTextEdit {
|
||||
background-color: {{ .Theme.Colors.Semantic.Surface.Value }};
|
||||
border: 1px solid {{ .Theme.Colors.Semantic.Border.Value }};
|
||||
border-radius: {{ .Theme.Spacing.Radius }};
|
||||
padding: {{ .Theme.Spacing.PaddingSmall }};
|
||||
}
|
||||
|
||||
QLineEdit:focus {
|
||||
border: 1px solid {{ .Theme.Colors.Semantic.Accent.Value }};
|
||||
}
|
||||
|
||||
/* Menus and Lists */
|
||||
QListView, QTreeView, QTableView {
|
||||
background-color: {{ .Theme.Colors.Semantic.Surface.Value }};
|
||||
border: 1px solid {{ .Theme.Colors.Semantic.Border.Value }};
|
||||
border-radius: {{ .Theme.Spacing.Radius }};
|
||||
alternate-background-color: {{ .Theme.Colors.Semantic.SurfaceAlt.Value }};
|
||||
}
|
||||
|
||||
QListView::item:selected, QTreeView::item:selected, QTableView::item:selected {
|
||||
background-color: {{ .Theme.Colors.Semantic.Accent.Alpha .Theme.Colors.Semantic.Background 0.3 }};
|
||||
border: 1px solid {{ .Theme.Colors.Semantic.Accent.Value }};
|
||||
color: {{ .Theme.Colors.Semantic.Text.Value }};
|
||||
}
|
||||
|
||||
/* Scrollbars */
|
||||
QScrollBar:vertical {
|
||||
background: {{ .Theme.Colors.Semantic.SurfaceAlt.Value }};
|
||||
width: 12px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
QScrollBar::handle:vertical {
|
||||
background: {{ .Theme.Colors.Semantic.Border.Value }};
|
||||
min-height: 20px;
|
||||
border-radius: {{ .Theme.Spacing.RadiusSmall }};
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
QScrollBar::handle:vertical:hover {
|
||||
background: {{ .Theme.Colors.Semantic.Accent.Value }};
|
||||
}
|
||||
|
||||
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
/* Tabs */
|
||||
QTabBar::tab {
|
||||
background: {{ .Theme.Colors.Semantic.Surface.Value }};
|
||||
border: 1px solid {{ .Theme.Colors.Semantic.Border.Value }};
|
||||
padding: {{ .Theme.Spacing.Padding }};
|
||||
border-top-left-radius: {{ .Theme.Spacing.Radius }};
|
||||
border-top-right-radius: {{ .Theme.Spacing.Radius }};
|
||||
}
|
||||
|
||||
QTabBar::tab:selected {
|
||||
background: {{ .Theme.Colors.Semantic.Background.Value }};
|
||||
border-bottom-color: {{ .Theme.Colors.Semantic.Accent.Value }};
|
||||
}
|
||||
|
||||
/* Checkboxes and Radio Buttons */
|
||||
QCheckBox::indicator, QRadioButton::indicator {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border: 1px solid {{ .Theme.Colors.Semantic.Border.Value }};
|
||||
background-color: {{ .Theme.Colors.Semantic.SurfaceAlt.Value }};
|
||||
border-radius: {{ .Theme.Spacing.Radius }};
|
||||
}
|
||||
|
||||
QRadioButton::indicator {
|
||||
border-radius: 9px;
|
||||
}
|
||||
|
||||
QCheckBox::indicator:checked {
|
||||
border-color: {{ .Theme.Colors.Semantic.Accent.Value }};
|
||||
background-color: {{ .Theme.Colors.Semantic.Accent.Value }};
|
||||
}
|
||||
|
||||
QRadioButton::indicator:checked {
|
||||
border-color: {{ .Theme.Colors.Semantic.Accent.Value }};
|
||||
background-color: {{ .Theme.Colors.Semantic.Accent.Value }};
|
||||
}
|
||||
Reference in New Issue
Block a user