| 1 | pragma Singleton |
| 2 | import QtQuick |
| 3 | import Quickshell |
| 4 | import Quickshell.Io |
| 5 | |
| 6 | // Reads ~/.cache/wal/colors.json (pywal16) and hot-reloads whenever `wal` runs. |
| 7 | Singleton { |
| 8 | id: root |
| 9 | |
| 10 | // ---- knobs -------------------------------------------------------- |
| 11 | property string font: "JetBrainsMono Nerd Font" // any Nerd Font mono |
| 12 | property int fontSize: 12 |
| 13 | property real panelAlpha: 0.88 |
| 14 | // -1 = auto-pick the most vivid of color1..color6, or force 0..15 |
| 15 | property int accentIndex: -1 |
| 16 | |
| 17 | readonly property string walFile: Quickshell.env("HOME") + "/.cache/wal/colors.json" |
| 18 | |
| 19 | FileView { |
| 20 | path: root.walFile |
| 21 | watchChanges: true |
| 22 | onFileChanged: reload() |
| 23 | adapter: JsonAdapter { |
| 24 | id: wal |
| 25 | property JsonObject special: JsonObject { |
| 26 | property string background: "#0b1514" |
| 27 | property string foreground: "#cfe3df" |
| 28 | property string cursor: "#cfe3df" |
| 29 | } |
| 30 | property JsonObject colors: JsonObject { |
| 31 | property string color0: "#0b1514" |
| 32 | property string color1: "#c0616b" |
| 33 | property string color2: "#3fa593" |
| 34 | property string color3: "#7fb6a8" |
| 35 | property string color4: "#3a8f8a" |
| 36 | property string color5: "#5f9f9a" |
| 37 | property string color6: "#4fbfae" |
| 38 | property string color7: "#cfe3df" |
| 39 | property string color8: "#4a5f5c" |
| 40 | property string color9: "#d97a84" |
| 41 | property string color10: "#52c2ae" |
| 42 | property string color11: "#9ad0c3" |
| 43 | property string color12: "#4fb0a9" |
| 44 | property string color13: "#78b8b2" |
| 45 | property string color14: "#6fd6c5" |
| 46 | property string color15: "#e3f2ef" |
| 47 | } |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | readonly property var pal: [ |
| 52 | wal.colors.color0, wal.colors.color1, wal.colors.color2, wal.colors.color3, |
| 53 | wal.colors.color4, wal.colors.color5, wal.colors.color6, wal.colors.color7, |
| 54 | wal.colors.color8, wal.colors.color9, wal.colors.color10, wal.colors.color11, |
| 55 | wal.colors.color12, wal.colors.color13, wal.colors.color14, wal.colors.color15 |
| 56 | ] |
| 57 | |
| 58 | function mix(a, b, t) { |
| 59 | return Qt.rgba(a.r + (b.r - a.r) * t, a.g + (b.g - a.g) * t, a.b + (b.b - a.b) * t, 1) |
| 60 | } |
| 61 | |
| 62 | function autoAccent() { |
| 63 | var best = 4, score = -1 |
| 64 | for (var i = 1; i <= 6; i++) { |
| 65 | var c = Qt.color(pal[i]) |
| 66 | var s = c.hsvSaturation * c.hsvValue |
| 67 | if (s > score) { score = s; best = i } |
| 68 | } |
| 69 | return Qt.color(pal[best]) |
| 70 | } |
| 71 | |
| 72 | // ---- palette ------------------------------------------------------ |
| 73 | readonly property color bg: wal.special.background |
| 74 | readonly property color fg: wal.special.foreground |
| 75 | readonly property color accent: accentIndex >= 0 ? Qt.color(pal[accentIndex]) : autoAccent() |
| 76 | readonly property color accentDim: mix(bg, accent, 0.45) |
| 77 | readonly property color surface: mix(bg, fg, 0.06) |
| 78 | readonly property color surfaceHi: mix(bg, fg, 0.14) |
| 79 | readonly property color line: mix(bg, accent, 0.35) |
| 80 | readonly property color dim: mix(bg, fg, 0.55) |
| 81 | readonly property color err: Qt.color(pal[1]) |
| 82 | readonly property color bgA: Qt.rgba(bg.r, bg.g, bg.b, panelAlpha) |
| 83 | |
| 84 | // ---- Nerd Font (Material Design) glyphs --------------------------- |
| 85 | function cp(c) { |
| 86 | c -= 0x10000 |
| 87 | return String.fromCharCode(0xD800 + (c >> 10), 0xDC00 + (c & 0x3FF)) |
| 88 | } |
| 89 | readonly property string iHome: cp(0xF02DC) |
| 90 | readonly property string iVolHigh: cp(0xF057E) |
| 91 | readonly property string iVolMed: cp(0xF0580) |
| 92 | readonly property string iVolLow: cp(0xF057F) |
| 93 | readonly property string iVolOff: cp(0xF0581) |
| 94 | readonly property string iMic: cp(0xF036C) |
| 95 | readonly property string iMicOff: cp(0xF036D) |
| 96 | readonly property string iWifi: cp(0xF05A9) |
| 97 | readonly property string iWifiOff: cp(0xF05AA) |
| 98 | readonly property string iBt: cp(0xF00AF) |
| 99 | readonly property string iBtOff: cp(0xF00B2) |
| 100 | readonly property string iBtConn: cp(0xF00B1) |
| 101 | readonly property string iPower: cp(0xF0425) |
| 102 | readonly property string iClose: cp(0xF0156) |
| 103 | readonly property string iPrev: cp(0xF04AE) |
| 104 | readonly property string iNext: cp(0xF04AD) |
| 105 | readonly property string iPlay: cp(0xF040A) |
| 106 | readonly property string iPause: cp(0xF03E4) |
| 107 | readonly property string iBright: cp(0xF00DF) |
| 108 | readonly property string iLock: cp(0xF033E) |
| 109 | readonly property string iLogout: cp(0xF0343) |
| 110 | readonly property string iSleep: cp(0xF04B2) |
| 111 | readonly property string iReboot: cp(0xF0709) |
| 112 | readonly property string iRefresh: cp(0xF0450) |
| 113 | readonly property string iHeadphones: cp(0xF02CB) |
| 114 | readonly property string iSpeaker: cp(0xF04C3) |
| 115 | readonly property string iMusic: cp(0xF075A) |
| 116 | readonly property string iTrash: cp(0xF01B4) |
| 117 | readonly property string iCheck: cp(0xF012C) |
| 118 | readonly property string iMouse: cp(0xF037D) |
| 119 | readonly property string iKeyboard: cp(0xF030C) |
| 120 | readonly property string iPhone: cp(0xF011C) |
| 121 | readonly property string iGamepad: cp(0xF0297) |
| 122 | readonly property string iSearch: cp(0xF0349) |
| 123 | |
| 124 | function volIcon(v, muted) { |
| 125 | if (muted || v <= 0) return iVolOff |
| 126 | return v < 0.34 ? iVolLow : (v < 0.67 ? iVolMed : iVolHigh) |
| 127 | } |
| 128 | function wifiIcon(sig) { |
| 129 | return cp(sig >= 75 ? 0xF0928 : sig >= 50 ? 0xF0925 : sig >= 25 ? 0xF0922 : 0xF091F) |
| 130 | } |
| 131 | } |