Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions Crisp/App/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -684,8 +684,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
let toolshead = block("toolshead") {
VStack(alignment: .leading, spacing: 0) {
SectionDivider()
ExpandableRowStateful(icon: "wrench.and.screwdriver.fill", iconActive: false,
label: "Tools", state: state, key: \.showTools)
ToolsHeaderRow(state: state)
}
}
toolshead.liveInFlight = true
Expand Down Expand Up @@ -760,6 +759,15 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
.dropFirst()
.sink { [weak self] _ in self?.canvas.requestApply() }
.store(in: &canvasCancellables)
SettingsService.shared.$keepToolsExpanded
.dropFirst()
.receive(on: DispatchQueue.main)
.sink { [weak self] expanded in
guard let self else { return }
self.sectionState.showTools = expanded
self.canvas.requestApply()
}
.store(in: &canvasCancellables)
displayManager.$displays
.dropFirst()
.receive(on: DispatchQueue.main)
Expand Down
18 changes: 17 additions & 1 deletion Crisp/Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -2318,6 +2318,22 @@
}
}
},
"Keep Tools Expanded" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "保持工具展开"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "保持工具展開"
}
}
}
},
"Keep Awake" : {
"localizations" : {
"zh-Hans" : {
Expand Down Expand Up @@ -4303,4 +4319,4 @@
}
},
"version" : "1.0"
}
}
6 changes: 6 additions & 0 deletions Crisp/Services/SettingsService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ final class SettingsService: ObservableObject, @unchecked Sendable {
static let showVolumeSliders = "crisp.showVolumeSliders"
static let crossDisplayGaps = "crisp.crossDisplayGaps"
static let disconnectBuiltinWhenDocked = "crisp.disconnectBuiltinWhenDocked"
static let keepToolsExpanded = "crisp.keepToolsExpanded"
static let ddcCacheTTL = "crisp.ddcCacheTTL"
static let colorPickerHistory = "crisp.colorPickerHistory"
static let brightnessKeyTarget = "crisp.brightnessKeyTarget"
Expand Down Expand Up @@ -115,6 +116,10 @@ final class SettingsService: ObservableObject, @unchecked Sendable {
didSet { defaults.set(disconnectBuiltinWhenDocked, forKey: Keys.disconnectBuiltinWhenDocked) }
}

@Published var keepToolsExpanded: Bool = false {
didSet { defaults.set(keepToolsExpanded, forKey: Keys.keepToolsExpanded) }
}

@Published var ddcCacheTTL: Double = 5.0 {
didSet { defaults.set(ddcCacheTTL, forKey: Keys.ddcCacheTTL) }
}
Expand Down Expand Up @@ -257,6 +262,7 @@ final class SettingsService: ObservableObject, @unchecked Sendable {
? defaults.bool(forKey: Keys.showVolumeSliders) : true
crossDisplayGaps = defaults.bool(forKey: Keys.crossDisplayGaps)
disconnectBuiltinWhenDocked = defaults.bool(forKey: Keys.disconnectBuiltinWhenDocked)
keepToolsExpanded = defaults.bool(forKey: Keys.keepToolsExpanded)
ddcCacheTTL = defaults.object(forKey: Keys.ddcCacheTTL) != nil
? defaults.double(forKey: Keys.ddcCacheTTL) : 5.0
colorPickerHistory = defaults.stringArray(forKey: Keys.colorPickerHistory) ?? []
Expand Down
2 changes: 2 additions & 0 deletions Crisp/Views/MenuBarView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,8 @@ struct SettingsView: View {
// group and stays shown with no external connected (can be armed before docking).
AutoBrightnessView()

KeepToolsExpandedRow()

// Hidden unless more than one brightness slider exists, or "combined" would
// just duplicate the single slider.
if physicalDisplays.count > 1 {
Expand Down
6 changes: 5 additions & 1 deletion Crisp/Views/PanelBlocks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@ final class PanelSectionState: ObservableObject {
@Published var imageOpenIDs: Set<CGDirectDisplayID> = []
@Published var inputOpenIDs: Set<CGDirectDisplayID> = []

init() {
showTools = SettingsService.shared.keepToolsExpanded
}

/// Collapse every section so the panel reopens fresh; called once hidden.
func collapseAll() {
showTools = false
showTools = SettingsService.shared.keepToolsExpanded
showVirtualDisplays = false
showArrangement = false
showSettings = false
Expand Down
38 changes: 38 additions & 0 deletions Crisp/Views/ToolsExpansionView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import SwiftUI

struct ToolsHeaderRow: View {
@ObservedObject var state: PanelSectionState
@ObservedObject private var settings = SettingsService.shared

var body: some View {
ExpandableRow(
icon: "wrench.and.screwdriver.fill",
iconActive: false,
label: "Tools",
isExpanded: Binding(
get: { state.showTools },
set: { if !settings.keepToolsExpanded { state.showTools = $0 } }
)
)
}
}

struct KeepToolsExpandedRow: View {
@ObservedObject private var settings = SettingsService.shared

var body: some View {
Toggle(isOn: $settings.keepToolsExpanded) {
HStack(spacing: 8) {
MenuItemIcon(systemName: "wrench.and.screwdriver.fill", color: .gray,
active: settings.keepToolsExpanded)
.accessibilityHidden(true)
Text("Keep Tools Expanded").font(.body)
Spacer()
}
}
.toggleStyle(.switch)
.controlSize(.small)
.padding(.horizontal, 12)
.padding(.vertical, 3)
}
}