Skip to content

Commit 52df185

Browse files
committed
Hiding interface now remembers better
- When hiding interface it will better be able to handle hidden elements being enabled, and then showing the interface again. - Moved some logic from ViewCommands to CodeEditWindowController, as it seems like a more appropriate place. - Added a bool shouldAnimate to function toggleFirstPanel. This is by default on, and thus using the default animation. When explicitly called with off, the function will not animate.
1 parent b1fbbe5 commit 52df185

3 files changed

Lines changed: 114 additions & 43 deletions

File tree

CodeEdit/Features/Documents/Controllers/CodeEditWindowController.swift

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ import SwiftUI
1010
import Combine
1111

1212
final class CodeEditWindowController: NSWindowController, NSToolbarDelegate, ObservableObject, NSWindowDelegate {
13-
@Published var navigatorCollapsed = false
14-
@Published var inspectorCollapsed = false
15-
@Published var toolbarCollapsed = false
13+
@Published var navigatorCollapsed: Bool = false
14+
@Published var inspectorCollapsed: Bool = false
15+
@Published var toolbarCollapsed: Bool = false
16+
@Published var interfaceHidden: Bool = false
1617

1718
// These variables store the state of the windows when using "Hide interface"
1819
@Published var prevNavigatorCollapsed: Bool?
@@ -209,4 +210,94 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate, Obs
209210
workspace = nil
210211
return true
211212
}
213+
214+
/// Function for toggling the interface elements on or off
215+
///
216+
/// - Parameter shouldHide: Pass `true` to hide all interface panels (and remember their current states),
217+
/// or `false` to restore them to how they were before hiding.
218+
func toggleInterface(shouldHide: Bool) {
219+
interfaceHidden = shouldHide
220+
221+
// When hiding, store how the interface looks now
222+
if shouldHide {
223+
storeInterfaceCollapseState()
224+
}
225+
226+
// Determine the desired collapsed/visible state for every interface element
227+
let navigatorTargetState = determineDesiredCollapseState(
228+
shouldHide: shouldHide,
229+
currentlyCollapsed: navigatorCollapsed,
230+
previouslyCollapsed: prevNavigatorCollapsed,
231+
)
232+
let inspectorTargetState = determineDesiredCollapseState(
233+
shouldHide: shouldHide,
234+
currentlyCollapsed: inspectorCollapsed,
235+
previouslyCollapsed: prevInspectorCollapsed,
236+
)
237+
let utilityAreaTargetState = determineDesiredCollapseState(
238+
shouldHide: shouldHide,
239+
currentlyCollapsed: workspace?.utilityAreaModel?.isCollapsed ?? true,
240+
previouslyCollapsed: prevUtilityAreaCollapsed,
241+
)
242+
let toolbarTargetState = determineDesiredCollapseState(
243+
shouldHide: shouldHide,
244+
currentlyCollapsed: toolbarCollapsed,
245+
previouslyCollapsed: prevToolbarCollapsed,
246+
)
247+
248+
// Toggle only the parts that need to change
249+
if navigatorCollapsed != navigatorTargetState {
250+
toggleFirstPanel(shouldAnimate: false)
251+
}
252+
if inspectorCollapsed != inspectorTargetState {
253+
toggleLastPanel()
254+
}
255+
if workspace?.utilityAreaModel?.isCollapsed != utilityAreaTargetState {
256+
CommandManager.shared.executeCommand("open.drawer")
257+
}
258+
if toolbarCollapsed != toolbarTargetState {
259+
toggleToolbar()
260+
}
261+
262+
// If enabling interface, reset the visibility states
263+
if !shouldHide {
264+
resetStoredInterfaceCollapseState()
265+
}
266+
}
267+
268+
/// Calculates the collapse state an interface element should have after a hide / show toggle.
269+
/// - Parameters:
270+
/// - shouldHide: `true` when we’re hiding the whole interface.
271+
/// - currentlyCollapsed: The panels current state
272+
/// - previouslyCollapsed: The state we saved the last time we hid the UI, if any.
273+
/// - Returns: `true` for visible element, `false` for collapsed element
274+
func determineDesiredCollapseState(shouldHide: Bool, currentlyCollapsed: Bool, previouslyCollapsed: Bool?) -> Bool {
275+
// If ShouldHide, everything should close
276+
if shouldHide { return true }
277+
278+
// If currently visible and !shouldHide, it should not collapse
279+
if !currentlyCollapsed && !shouldHide { return false }
280+
281+
// If we have a previous state, return that one.
282+
if let remembered = previouslyCollapsed { return remembered }
283+
284+
// If there is no stored state, return the current state.
285+
return currentlyCollapsed
286+
}
287+
288+
/// Function for storing the current interface visibility states
289+
func storeInterfaceCollapseState() {
290+
prevNavigatorCollapsed = navigatorCollapsed
291+
prevInspectorCollapsed = inspectorCollapsed
292+
prevUtilityAreaCollapsed = workspace?.utilityAreaModel?.isCollapsed
293+
prevToolbarCollapsed = toolbarCollapsed
294+
}
295+
296+
/// Function for resetting the stored interface visibility states
297+
func resetStoredInterfaceCollapseState() {
298+
prevNavigatorCollapsed = nil
299+
prevInspectorCollapsed = nil
300+
prevUtilityAreaCollapsed = nil
301+
prevToolbarCollapsed = nil
302+
}
212303
}

CodeEdit/Features/Documents/Controllers/CodeEditWindowControllerExtensions.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,21 @@ import Combine
1111
extension CodeEditWindowController {
1212
@objc
1313
func toggleFirstPanel() {
14+
toggleFirstPanel(shouldAnimate: true)
15+
}
16+
17+
/// Toggles the navigator pane, optionally without animation.
18+
func toggleFirstPanel(shouldAnimate: Bool = true) {
1419
guard let firstSplitView = splitViewController?.splitViewItems.first else { return }
15-
firstSplitView.animator().isCollapsed.toggle()
20+
21+
if shouldAnimate {
22+
// Standard animated toggle
23+
firstSplitView.animator().isCollapsed.toggle()
24+
} else {
25+
// Instant toggle (no animation)
26+
firstSplitView.isCollapsed.toggle()
27+
}
28+
1629
splitViewController?.saveNavigatorCollapsedState(isCollapsed: firstSplitView.isCollapsed)
1730
}
1831

CodeEdit/Features/WindowCommands/ViewCommands.swift

Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -111,42 +111,9 @@ extension ViewCommands {
111111
windowController?.toolbarCollapsed ?? true
112112
}
113113

114-
var isAnythingVisible: Bool {
115-
!navigatorCollapsed || !inspectorCollapsed || !utilityAreaCollapsed || !toolbarCollapsed
116-
}
117-
118-
func toggleInterface(shouldHide: Bool) {
119-
// When hiding, store how the interface looks now
120-
if shouldHide {
121-
storeInterfaceVisibilityState()
122-
}
123-
124-
// Check what each elemtent state should be
125-
let navigatorTargetState = shouldHide ? true : (windowController?.prevNavigatorCollapsed ?? false)
126-
let inspectorTargetState = shouldHide ? true : (windowController?.prevInspectorCollapsed ?? false)
127-
let utilityAreaTargetState = shouldHide ? true : (windowController?.prevUtilityAreaCollapsed ?? false)
128-
let toolbarTargetState = shouldHide ? true : (windowController?.prevToolbarCollapsed ?? true)
129-
130-
// Toggle only the parts that need to change
131-
if navigatorCollapsed != navigatorTargetState {
132-
windowController?.toggleFirstPanel()
133-
}
134-
if inspectorCollapsed != inspectorTargetState {
135-
windowController?.toggleLastPanel()
136-
}
137-
if utilityAreaCollapsed != utilityAreaTargetState {
138-
CommandManager.shared.executeCommand("open.drawer")
139-
}
140-
if toolbarCollapsed != toolbarTargetState {
141-
windowController?.toggleToolbar()
142-
}
143-
}
144-
145-
func storeInterfaceVisibilityState() {
146-
windowController?.prevNavigatorCollapsed = navigatorCollapsed
147-
windowController?.prevInspectorCollapsed = inspectorCollapsed
148-
windowController?.prevUtilityAreaCollapsed = utilityAreaCollapsed
149-
windowController?.prevToolbarCollapsed = toolbarCollapsed
114+
var isInterfaceHidden: Bool {
115+
return windowController?.interfaceHidden ?? false
116+
//navigatorCollapsed && inspectorCollapsed && utilityAreaCollapsed && toolbarCollapsed
150117
}
151118

152119
var body: some View {
@@ -174,11 +141,11 @@ extension ViewCommands {
174141
.disabled(windowController == nil)
175142
.keyboardShortcut("t", modifiers: [.option, .command])
176143

177-
Button("\(isAnythingVisible ? "Hide" : "Show") Interface") {
178-
toggleInterface(shouldHide: isAnythingVisible)
144+
Button("\(isInterfaceHidden ? "Show" : "Hide") Interface") {
145+
windowController?.toggleInterface(shouldHide: !isInterfaceHidden)
179146
}
180147
.disabled(windowController == nil)
181-
.keyboardShortcut("i", modifiers: [.option, .command])
148+
.keyboardShortcut(".", modifiers: .command)
182149
}
183150
}
184151
}

0 commit comments

Comments
 (0)