diff --git a/ios/Stemify/UI/Screens/NowPlayingScreen.swift b/ios/Stemify/UI/Screens/NowPlayingScreen.swift index 2870ae4..0394b05 100644 --- a/ios/Stemify/UI/Screens/NowPlayingScreen.swift +++ b/ios/Stemify/UI/Screens/NowPlayingScreen.swift @@ -681,8 +681,10 @@ private struct MixerPanel: View { let names = pm.stemNames let stems = pm.source == .Stems GeometryReader { geo in - // Spread spare height across the rows (stems + master) instead of leaving it all at the bottom. - let rowH = roomy ? Self.roomyRow : min(62, max(46, (geo.size.height - 80) / CGFloat(names.count + 1))) + // Spread spare height across the stem rows instead of leaving it all at the bottom. + let count = CGFloat(max(names.count, 1)) + let rowH = roomy ? min(80, max(Self.roomyRow, (geo.size.height - Self.roomyChrome) / count)) + : min(62, max(46, (geo.size.height - 64) / count)) ScrollView { VStack(alignment: .leading, spacing: 0) { if pm.source == .Original { @@ -750,11 +752,7 @@ private struct MixerPanel: View { } } } - p.separator.frame(height: 0.5).padding(.vertical, 6) - FaderRow(dot: nil, label: "Master", percent: Int(pm.master * 100), dim: false, height: rowH, stacked: roomy) { - FaderSlider(value: pm.master, fill: p.label, thumb: roomy ? 30 : 24, onChange: pm.setMaster) - } trailing: { EmptyView() } - Spacer(minLength: 16) + Spacer(minLength: roomy ? 8 : 16) } .padding(.horizontal, 24) } @@ -766,9 +764,11 @@ private struct MixerPanel: View { } extension MixerPanel { - static let roomyRow: CGFloat = 60 - /// Height that shows the presets, every stem and the master without scrolling, roomy rows. - static func roomyHeight(_ stems: Int) -> CGFloat { 48 + CGFloat(stems + 1) * roomyRow + 13 + 16 } + static let roomyRow: CGFloat = 66 + /// Preset chips plus the bottom gap. + static let roomyChrome: CGFloat = 56 + /// Height that shows the presets and every stem without scrolling, roomy rows. + static func roomyHeight(_ stems: Int) -> CGFloat { roomyChrome + CGFloat(stems) * roomyRow } } /// [Chip] in the sheet's own colours: selected is the label colour, so it reads on any tint. @@ -807,7 +807,7 @@ private struct StemFader: View { let color = Color(hex: Stems.color(name)) FaderRow(dot: setting.muted ? p.label3 : color, label: Stems.label(name), percent: Int(stemTaper(setting.level) * 100), dim: setting.muted, height: height, stacked: roomy) { VStack(spacing: 0) { - FaderSlider(value: setting.level, fill: setting.muted ? p.label3 : color, detent: StemSetting.unity, enabled: enabled, thumb: roomy ? 30 : 24) { + FaderSlider(value: setting.level, fill: setting.muted ? p.label3 : color, detent: StemSetting.unity, enabled: enabled, thumb: roomy ? 26 : 24) { pm.setStemLevel(name, $0) } // Live level under the fader, -48..0 dBFS. @@ -845,7 +845,8 @@ struct FaderRow: View { @Environment(\.palette) private var p var body: some View { if stacked { - VStack(alignment: .leading, spacing: 0) { + // Bottom-aligned with a gap under, so each name sits clear of the meter above it. + VStack(alignment: .leading, spacing: 2) { HStack(spacing: 6) { if let dot { Circle().fill(dot).frame(width: 8, height: 8) } Text(label).font(.subheadline.weight(.semibold)).foregroundStyle(dim ? p.label2 : p.label).lineLimit(1) @@ -855,7 +856,8 @@ struct FaderRow: View { .frame(height: 18) HStack(spacing: 8) { fader; trailing } } - .frame(height: height) + .padding(.bottom, 4) + .frame(height: height, alignment: .bottom) } else { row } @@ -888,7 +890,7 @@ struct ToggleBox: View { var body: some View { Button(action: action) { Text(text).font(.footnote.bold()).foregroundStyle(on ? .black : p.label2) - .frame(width: big ? 38 : 30, height: big ? 32 : 26) + .frame(width: big ? 34 : 30, height: big ? 28 : 26) .background(on ? onColor : p.fill, in: RoundedRectangle(cornerRadius: 7, style: .continuous)) } .buttonStyle(.plain) @@ -913,7 +915,7 @@ struct FaderSlider: View { self.value = value; self.fill = fill; self.detent = detent; self.enabled = enabled; self.thumb = thumb; self.onChange = onChange } - private var bar: CGFloat { thumb >= 28 ? 6 : 4 } + private var bar: CGFloat { thumb >= 26 ? 5 : 4 } var body: some View { GeometryReader { geo in @@ -966,7 +968,7 @@ struct NowPlayingDeck: View { Text("Stems").font(.headline).foregroundStyle(c.label) .frame(maxWidth: .infinity, alignment: .leading).padding(.horizontal, 24) // As much as the stems need to show without scrolling, leaving the queue a few rows. - MixerPanel(roomy: true).frame(height: min(MixerPanel.roomyHeight(max(g.playback.stemNames.count, 4)), geo.size.height * 0.68)) + MixerPanel(roomy: true).frame(height: min(MixerPanel.roomyHeight(max(g.playback.stemNames.count, 4)), geo.size.height * 0.72)) Rectangle().fill(c.label3.opacity(0.35)).frame(height: 0.5).padding(.horizontal, 24).padding(.bottom, 8) QueuePanel() }