Skip to content

Commit 2b41f4d

Browse files
authored
iOS Widget: legible mode buttons on tinted/transparent home screens (#262)
1 parent 93a7dc1 commit 2b41f4d

1 file changed

Lines changed: 37 additions & 12 deletions

File tree

targets/widget/LoadpointViews.swift

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ struct LoadpointCard: View {
4949
let lp: Int
5050
@Environment(\.colorScheme) var scheme
5151
@Environment(\.widgetFamily) var family
52+
@Environment(\.widgetRenderingMode) var renderingMode
5253

5354
private var connected: Bool { vm.status != .disconnected }
5455

@@ -133,24 +134,48 @@ struct LoadpointCard: View {
133134
ForEach(vm.modes, id: \.self) { mode in
134135
let selected = mode == vm.currentMode
135136
Button(intent: SetModeIntent(serverId: serverId, lp: lp, mode: mode.rawValue)) {
136-
HStack(spacing: 4) {
137-
Text(L.t(mode.labelKey)).font(.system(size: 12, weight: .bold))
138-
if vm.alwaysChargeActive, mode.rawValue == ChargeMode.smart.rawValue {
139-
Image(systemName: "infinity").font(.system(size: 10, weight: .bold))
140-
}
141-
}
142-
.frame(maxWidth: .infinity, maxHeight: .infinity)
143-
.foregroundColor(selected ? (scheme == .dark ? .black : .white)
144-
: (scheme == .dark ? Color.modeTextDark : Color.modeTextLight))
145-
.background(selected ? AnyShapeStyle(.primary)
146-
: AnyShapeStyle((scheme == .dark ? Color.modeBgDark : Color.modeBgLight)),
147-
in: RoundedRectangle(cornerRadius: 9, style: .continuous))
137+
modeButtonLabel(mode, selected: selected)
148138
}
149139
.buttonStyle(.plain)
150140
}
151141
}
152142
.frame(maxHeight: .infinity)
153143
}
144+
145+
// Tinted/transparent home screens (accented rendering) flatten every color to
146+
// alpha-only white, so the full-color styling collapses to white-on-white.
147+
// There: unselected uses opacity contrast, selected punches the label out of
148+
// the pill via destinationOut (black text would render white too).
149+
@ViewBuilder private func modeButtonLabel(_ mode: ModeItem, selected: Bool) -> some View {
150+
let label = HStack(spacing: 4) {
151+
Text(L.t(mode.labelKey)).font(.system(size: 12, weight: .bold))
152+
if vm.alwaysChargeActive, mode.rawValue == ChargeMode.smart.rawValue {
153+
Image(systemName: "infinity").font(.system(size: 10, weight: .bold))
154+
}
155+
}
156+
.frame(maxWidth: .infinity, maxHeight: .infinity)
157+
let shape = RoundedRectangle(cornerRadius: 9, style: .continuous)
158+
159+
if renderingMode != .fullColor {
160+
if selected {
161+
label
162+
.blendMode(.destinationOut)
163+
.background(.white, in: shape)
164+
.compositingGroup()
165+
} else {
166+
label
167+
.foregroundColor(.primary)
168+
.background(Color.white.opacity(0.15), in: shape)
169+
}
170+
} else {
171+
label
172+
.foregroundColor(selected ? (scheme == .dark ? .black : .white)
173+
: (scheme == .dark ? Color.modeTextDark : Color.modeTextLight))
174+
.background(selected ? AnyShapeStyle(.primary)
175+
: AnyShapeStyle((scheme == .dark ? Color.modeBgDark : Color.modeBgLight)),
176+
in: shape)
177+
}
178+
}
154179
}
155180

156181
struct ProgressBar: View {

0 commit comments

Comments
 (0)