Seconds per clock, and type that scales with the bar height
Seconds move from one bar-wide switch to a per-clock setting. A clock's own `showSeconds` wins, the top-level one is the default for clocks with no opinion, and the centre clock gets `local.showSeconds` since it has no entry in `clocks[]`. An explicit false on a clock beats a true default, so the check is for the property's presence rather than its truthiness. The tick rate follows what is actually displayed: `anyShowsSeconds()` decides between a per-second and a per-minute SystemClock, so a bar showing no seconds does not wake the shell sixty times as often to redraw an identical minute. `barSize` is now editable from the popup, and everything drawn on the bar is sized against the theme's own bar height rather than pinned to the theme's 12px type. A taller bar carries proportionally larger text, gaps and rule; at the theme's own height the scale is exactly 1, so nothing moves. Heights are clamped to 12-120 rather than rejected, so a value the editor can produce can never be one the config layer silently discards. Fixes a latent bug this surfaced: updateRow() rebuilt a draft row from a fixed pair of fields, so editing a clock's label would have thrown away its own seconds setting. It now copies every key the row had. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MhxtL7WzL5XmuTd8GHbcTY
This commit is contained in:
+93
-7
@@ -24,6 +24,9 @@ Item {
|
||||
property int workStart: 8
|
||||
property int workEnd: 18
|
||||
property bool dimOutside: true
|
||||
property bool defaultSeconds: false
|
||||
property bool localSeconds: false
|
||||
property int barSize: 0
|
||||
|
||||
readonly property color background: Color.popups.background
|
||||
readonly property color foreground: Color.popups.text
|
||||
@@ -56,24 +59,38 @@ Item {
|
||||
var cfg = root.configFile ? root.configFile.config : null
|
||||
var clocks = cfg && Array.isArray(cfg.clocks) ? cfg.clocks : []
|
||||
var copy = []
|
||||
for (var i = 0; i < clocks.length; i++)
|
||||
copy.push({ label: String(clocks[i].label || ""), timezone: String(clocks[i].timezone || "") })
|
||||
for (var i = 0; i < clocks.length; i++) {
|
||||
var row = { label: String(clocks[i].label || ""), timezone: String(clocks[i].timezone || "") }
|
||||
if (typeof clocks[i].showSeconds === "boolean") row.showSeconds = clocks[i].showSeconds
|
||||
copy.push(row)
|
||||
}
|
||||
root.draft = copy
|
||||
if (cfg && cfg.workingHours) {
|
||||
root.workStart = Number(cfg.workingHours.start)
|
||||
root.workEnd = Number(cfg.workingHours.end)
|
||||
}
|
||||
root.dimOutside = cfg ? cfg.dimOutsideWorkingHours !== false : true
|
||||
root.defaultSeconds = cfg ? cfg.showSeconds === true : false
|
||||
root.localSeconds = Model.showsSeconds(cfg ? cfg.local : null, root.defaultSeconds)
|
||||
root.barSize = cfg && cfg.barSize > 0 ? cfg.barSize : 0
|
||||
}
|
||||
|
||||
// What a row's toggle shows: its own setting when it has one, otherwise the
|
||||
// bar-wide default it is inheriting.
|
||||
function rowShowsSeconds(row) { return Model.showsSeconds(row, root.defaultSeconds) }
|
||||
|
||||
// QML only re-renders a var array when the reference changes, so every
|
||||
// mutation rebuilds it rather than editing in place.
|
||||
function replaceDraft(next) { root.draft = next }
|
||||
|
||||
// Copies every key the row already had. Rebuilding it from a fixed pair of
|
||||
// fields silently dropped anything else on it — editing a label would have
|
||||
// thrown away that clock's own seconds setting.
|
||||
function updateRow(index, key, value) {
|
||||
var next = root.draft.slice()
|
||||
if (!next[index]) return
|
||||
var row = { label: next[index].label, timezone: next[index].timezone }
|
||||
var row = {}
|
||||
for (var k in next[index]) row[k] = next[index][k]
|
||||
row[key] = value
|
||||
next[index] = row
|
||||
replaceDraft(next)
|
||||
@@ -99,7 +116,11 @@ Item {
|
||||
var tz = String(root.draft[i].timezone || "").replace(/^\s+|\s+$/g, "")
|
||||
if (!tz) continue
|
||||
var label = String(root.draft[i].label || "").replace(/^\s+|\s+$/g, "")
|
||||
out.push({ label: label || tz.split("/").pop().replace(/_/g, " "), timezone: tz })
|
||||
var row = { label: label || tz.split("/").pop().replace(/_/g, " "), timezone: tz }
|
||||
// Only clocks the user actually set keep an explicit flag; the rest go
|
||||
// on inheriting the bar-wide default.
|
||||
if (typeof root.draft[i].showSeconds === "boolean") row.showSeconds = root.draft[i].showSeconds
|
||||
out.push(row)
|
||||
}
|
||||
return out
|
||||
}
|
||||
@@ -116,8 +137,9 @@ Item {
|
||||
workdays: cfg && cfg.workingHours ? cfg.workingHours.workdays : [1, 2, 3, 4, 5]
|
||||
},
|
||||
dimOutsideWorkingHours: root.dimOutside,
|
||||
showSeconds: cfg ? cfg.showSeconds === true : false,
|
||||
barSize: cfg ? cfg.barSize : 0
|
||||
showSeconds: root.defaultSeconds,
|
||||
local: { showSeconds: root.localSeconds },
|
||||
barSize: root.barSize
|
||||
})
|
||||
close()
|
||||
}
|
||||
@@ -211,7 +233,7 @@ Item {
|
||||
spacing: Style.space(8)
|
||||
|
||||
TextField {
|
||||
Layout.preferredWidth: Style.space(74)
|
||||
Layout.preferredWidth: Style.space(66)
|
||||
text: row.modelData.label
|
||||
placeholderText: "Label"
|
||||
foreground: root.foreground
|
||||
@@ -245,6 +267,18 @@ Item {
|
||||
font.pixelSize: Style.font.caption
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "SS"
|
||||
bordered: true
|
||||
selected: root.rowShowsSeconds(row.modelData)
|
||||
tooltipText: root.rowShowsSeconds(row.modelData)
|
||||
? "Showing seconds — click for HH:MM"
|
||||
: "Show seconds on this clock"
|
||||
foreground: root.foreground
|
||||
accent: root.accent
|
||||
onClicked: root.updateRow(row.index, "showSeconds", !root.rowShowsSeconds(row.modelData))
|
||||
}
|
||||
|
||||
Button {
|
||||
iconText: ""
|
||||
tooltipText: "Remove this clock"
|
||||
@@ -346,6 +380,58 @@ Item {
|
||||
|
||||
PanelSeparator { Layout.fillWidth: true }
|
||||
|
||||
PanelSectionHeader {
|
||||
Layout.fillWidth: true
|
||||
text: "Bar"
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.space(8)
|
||||
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
text: "Seconds on your local clock"
|
||||
color: root.foreground
|
||||
elide: Text.ElideRight
|
||||
font.family: Style.font.family
|
||||
font.pixelSize: Style.font.body
|
||||
}
|
||||
|
||||
ToggleSwitch {
|
||||
checked: root.localSeconds
|
||||
foreground: root.foreground
|
||||
accent: root.accent
|
||||
onToggled: root.localSeconds = !root.localSeconds
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.space(8)
|
||||
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
text: "Bar height — 0 follows the theme. Text scales with it."
|
||||
color: root.muted
|
||||
elide: Text.ElideRight
|
||||
font.family: Style.font.family
|
||||
font.pixelSize: Style.font.caption
|
||||
}
|
||||
|
||||
NumberField {
|
||||
Layout.preferredWidth: Style.spacing.numberFieldWidth
|
||||
value: root.barSize
|
||||
from: 0
|
||||
to: 120
|
||||
foreground: root.foreground
|
||||
accent: root.accent
|
||||
onModified: function (v) { root.barSize = v }
|
||||
}
|
||||
}
|
||||
|
||||
PanelSeparator { Layout.fillWidth: true }
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.space(8)
|
||||
|
||||
Reference in New Issue
Block a user