mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-28 15:44:32 +00:00
Update minimum sizing
This commit is contained in:
parent
326e51cd3d
commit
3a99bad78d
4 changed files with 123 additions and 9 deletions
|
|
@ -219,6 +219,30 @@ class DynamicIslandViewCoordinator: ObservableObject {
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
handleExtensionExperienceSnapshot(extensionNotchExperienceManager.activeExperiences)
|
handleExtensionExperienceSnapshot(extensionNotchExperienceManager.activeExperiences)
|
||||||
|
|
||||||
|
// Observe all tab-affecting settings to enforce minimum notch width
|
||||||
|
Publishers.MergeMany(
|
||||||
|
Defaults.publisher(.showStandardMediaControls).map { _ in () }.eraseToAnyPublisher(),
|
||||||
|
Defaults.publisher(.showCalendar).map { _ in () }.eraseToAnyPublisher(),
|
||||||
|
Defaults.publisher(.showMirror).map { _ in () }.eraseToAnyPublisher(),
|
||||||
|
Defaults.publisher(.dynamicShelf).map { _ in () }.eraseToAnyPublisher(),
|
||||||
|
Defaults.publisher(.enableTimerFeature).map { _ in () }.eraseToAnyPublisher(),
|
||||||
|
Defaults.publisher(.timerDisplayMode).map { _ in () }.eraseToAnyPublisher(),
|
||||||
|
Defaults.publisher(.enableStatsFeature).map { _ in () }.eraseToAnyPublisher(),
|
||||||
|
Defaults.publisher(.enableNotes).map { _ in () }.eraseToAnyPublisher(),
|
||||||
|
Defaults.publisher(.enableClipboardManager).map { _ in () }.eraseToAnyPublisher(),
|
||||||
|
Defaults.publisher(.clipboardDisplayMode).map { _ in () }.eraseToAnyPublisher(),
|
||||||
|
Defaults.publisher(.enableTerminalFeature).map { _ in () }.eraseToAnyPublisher(),
|
||||||
|
Defaults.publisher(.enableMinimalisticUI).map { _ in () }.eraseToAnyPublisher()
|
||||||
|
)
|
||||||
|
.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main)
|
||||||
|
.sink { _ in
|
||||||
|
enforceMinimumNotchWidth()
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
// Enforce minimum width on launch for existing configurations
|
||||||
|
enforceMinimumNotchWidth()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleStatsTabTransition(from oldValue: NotchViews, to newValue: NotchViews) {
|
private func handleStatsTabTransition(from oldValue: NotchViews, to newValue: NotchViews) {
|
||||||
|
|
|
||||||
|
|
@ -1068,6 +1068,18 @@
|
||||||
"isCommentAutoGenerated" : true,
|
"isCommentAutoGenerated" : true,
|
||||||
"shouldTranslate" : false
|
"shouldTranslate" : false
|
||||||
},
|
},
|
||||||
|
"%lld tab%@ enabled · min %lld px" : {
|
||||||
|
"comment" : "A label displaying the number of enabled tabs, the recommended minimum notch width, and a button to reset the notch width to its recommended minimum value. The first argument is the count of enabled tabs. The second argument is the recommended minimum notch width as a formatted pixel count.",
|
||||||
|
"isCommentAutoGenerated" : true,
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "new",
|
||||||
|
"value" : "%1$lld tab%2$@ enabled · min %3$lld px"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"%lld%%" : {
|
"%lld%%" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"ar" : {
|
"ar" : {
|
||||||
|
|
|
||||||
|
|
@ -3468,8 +3468,12 @@ struct Appearance: View {
|
||||||
@State private var url: String = ""
|
@State private var url: String = ""
|
||||||
@State private var speed: CGFloat = 1.0
|
@State private var speed: CGFloat = 1.0
|
||||||
|
|
||||||
private let notchWidthRange: ClosedRange<Double> = 640...900
|
private var notchWidthRange: ClosedRange<Double> {
|
||||||
private let defaultOpenNotchWidth: CGFloat = 640
|
Double(currentRecommendedMinimumNotchWidth())...900
|
||||||
|
}
|
||||||
|
private var defaultOpenNotchWidth: CGFloat {
|
||||||
|
currentRecommendedMinimumNotchWidth()
|
||||||
|
}
|
||||||
|
|
||||||
private func highlightID(_ title: String) -> String {
|
private func highlightID(_ title: String) -> String {
|
||||||
SettingsTab.appearance.highlightID(for: title)
|
SettingsTab.appearance.highlightID(for: title)
|
||||||
|
|
@ -4019,10 +4023,14 @@ struct Appearance: View {
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private func notchWidthControls() -> some View {
|
private func notchWidthControls() -> some View {
|
||||||
Section {
|
Section {
|
||||||
|
let recommendedMin = currentRecommendedMinimumNotchWidth()
|
||||||
|
let tabCount = enabledStandardTabCount()
|
||||||
|
let dynamicRange = Double(recommendedMin)...900
|
||||||
|
|
||||||
let widthBinding = Binding<Double>(
|
let widthBinding = Binding<Double>(
|
||||||
get: { Double(openNotchWidth) },
|
get: { Double(openNotchWidth) },
|
||||||
set: { newValue in
|
set: { newValue in
|
||||||
let clamped = min(max(newValue, notchWidthRange.lowerBound), notchWidthRange.upperBound)
|
let clamped = min(max(newValue, dynamicRange.lowerBound), dynamicRange.upperBound)
|
||||||
let value = CGFloat(clamped)
|
let value = CGFloat(clamped)
|
||||||
if openNotchWidth != value {
|
if openNotchWidth != value {
|
||||||
openNotchWidth = value
|
openNotchWidth = value
|
||||||
|
|
@ -4033,7 +4041,7 @@ struct Appearance: View {
|
||||||
VStack(alignment: .leading, spacing: 10) {
|
VStack(alignment: .leading, spacing: 10) {
|
||||||
Slider(
|
Slider(
|
||||||
value: widthBinding,
|
value: widthBinding,
|
||||||
in: notchWidthRange,
|
in: dynamicRange,
|
||||||
step: 10
|
step: 10
|
||||||
) {
|
) {
|
||||||
HStack {
|
HStack {
|
||||||
|
|
@ -4047,22 +4055,28 @@ struct Appearance: View {
|
||||||
.settingsHighlight(id: highlightID("Expanded notch width"))
|
.settingsHighlight(id: highlightID("Expanded notch width"))
|
||||||
|
|
||||||
HStack {
|
HStack {
|
||||||
|
Text("\(tabCount) tab\(tabCount == 1 ? "" : "s") enabled · min \(Int(recommendedMin)) px")
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
Spacer()
|
Spacer()
|
||||||
Button("Reset Width") {
|
Button("Reset Width") {
|
||||||
openNotchWidth = defaultOpenNotchWidth
|
openNotchWidth = recommendedMin
|
||||||
}
|
}
|
||||||
.disabled(abs(openNotchWidth - defaultOpenNotchWidth) < 0.5)
|
.disabled(abs(openNotchWidth - recommendedMin) < 0.5)
|
||||||
.buttonStyle(.bordered)
|
.buttonStyle(.bordered)
|
||||||
}
|
}
|
||||||
|
|
||||||
let description = enableMinimalisticUI
|
let description = enableMinimalisticUI
|
||||||
? "Width adjustments apply only to the standard notch layout. Disable Minimalistic UI to edit this value."
|
? "Width adjustments apply only to the standard notch layout. Disable Minimalistic UI to edit this value."
|
||||||
: "Extend the notch span so the clipboard, colour picker, and other trailing icons remain visible on scaled displays (e.g. More Space)."
|
: "Recommended minimum width adjusts automatically based on the number of enabled tabs."
|
||||||
|
|
||||||
Text(description)
|
Text(description)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
}
|
}
|
||||||
|
.onAppear {
|
||||||
|
enforceMinimumNotchWidth()
|
||||||
|
}
|
||||||
} header: {
|
} header: {
|
||||||
HStack {
|
HStack {
|
||||||
Text("Notch Width")
|
Text("Notch Width")
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,72 @@ let downloadSneakSize: CGSize = .init(width: 65, height: 1)
|
||||||
let batterySneakSize: CGSize = .init(width: 160, height: 1)
|
let batterySneakSize: CGSize = .init(width: 160, height: 1)
|
||||||
|
|
||||||
var openNotchSize: CGSize {
|
var openNotchSize: CGSize {
|
||||||
let width = Defaults[.openNotchWidth]
|
let storedWidth = Defaults[.openNotchWidth]
|
||||||
return .init(width: width, height: 200) // Adjusted to a better middle ground
|
let minWidth = currentRecommendedMinimumNotchWidth()
|
||||||
|
let width = max(storedWidth, minWidth)
|
||||||
|
return .init(width: width, height: 200)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Tab-Based Notch Width
|
||||||
|
|
||||||
|
/// Counts the number of currently enabled standard notch tabs.
|
||||||
|
/// Mirrors the tab-building logic in ``TabSelectionView``.
|
||||||
|
func enabledStandardTabCount() -> Int {
|
||||||
|
var count = 0
|
||||||
|
|
||||||
|
// Home tab
|
||||||
|
if Defaults[.showStandardMediaControls] || Defaults[.showCalendar] || Defaults[.showMirror] {
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shelf tab
|
||||||
|
if Defaults[.dynamicShelf] {
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timer tab (only in .tab display mode)
|
||||||
|
if Defaults[.enableTimerFeature] && Defaults[.timerDisplayMode] == .tab {
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stats tab
|
||||||
|
if Defaults[.enableStatsFeature] {
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notes / Clipboard tab
|
||||||
|
if Defaults[.enableNotes] || (Defaults[.enableClipboardManager] && Defaults[.clipboardDisplayMode] == .separateTab) {
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Terminal tab
|
||||||
|
if Defaults[.enableTerminalFeature] {
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the recommended minimum notch width for the given tab count.
|
||||||
|
func recommendedMinimumNotchWidth(forTabCount count: Int) -> CGFloat {
|
||||||
|
if count >= 6 { return 770 }
|
||||||
|
if count >= 5 { return 690 }
|
||||||
|
return 640
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the recommended minimum notch width for the current tab configuration.
|
||||||
|
func currentRecommendedMinimumNotchWidth() -> CGFloat {
|
||||||
|
recommendedMinimumNotchWidth(forTabCount: enabledStandardTabCount())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enforces the minimum notch width based on current tab count.
|
||||||
|
/// Only adjusts when not in minimalistic mode.
|
||||||
|
func enforceMinimumNotchWidth() {
|
||||||
|
guard !Defaults[.enableMinimalisticUI] else { return }
|
||||||
|
let minWidth = currentRecommendedMinimumNotchWidth()
|
||||||
|
if Defaults[.openNotchWidth] < minWidth {
|
||||||
|
Defaults[.openNotchWidth] = minWidth
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private let minimalisticBaseOpenNotchSize: CGSize = .init(width: 420, height: 180)
|
private let minimalisticBaseOpenNotchSize: CGSize = .init(width: 420, height: 180)
|
||||||
private let minimalisticLyricsExtraHeight: CGFloat = 40
|
private let minimalisticLyricsExtraHeight: CGFloat = 40
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue