diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index ac27f59038..48c7c157d9 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -202,15 +202,14 @@ 58822528292C280D00E83CDE /* StatusBarEncodingSelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5882250E292C280D00E83CDE /* StatusBarEncodingSelector.swift */; }; 58822529292C280D00E83CDE /* StatusBarLineEndSelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5882250F292C280D00E83CDE /* StatusBarLineEndSelector.swift */; }; 5882252A292C280D00E83CDE /* StatusBarToggleUtilityAreaButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58822510292C280D00E83CDE /* StatusBarToggleUtilityAreaButton.swift */; }; - 5882252B292C280D00E83CDE /* StatusBarCursorLocationLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58822511292C280D00E83CDE /* StatusBarCursorLocationLabel.swift */; }; + 5882252B292C280D00E83CDE /* StatusBarCursorPositionLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58822511292C280D00E83CDE /* StatusBarCursorPositionLabel.swift */; }; 5882252C292C280D00E83CDE /* UtilityAreaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58822513292C280D00E83CDE /* UtilityAreaView.swift */; }; - 5882252D292C280D00E83CDE /* StatusBarSplitTerminalButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58822515292C280D00E83CDE /* StatusBarSplitTerminalButton.swift */; }; - 5882252E292C280D00E83CDE /* StatusBarMaximizeButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58822516292C280D00E83CDE /* StatusBarMaximizeButton.swift */; }; - 5882252F292C280D00E83CDE /* StatusBarClearButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58822517292C280D00E83CDE /* StatusBarClearButton.swift */; }; - 58822530292C280D00E83CDE /* FilterTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58822518292C280D00E83CDE /* FilterTextField.swift */; }; + 5882252D292C280D00E83CDE /* UtilityAreaSplitTerminalButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58822515292C280D00E83CDE /* UtilityAreaSplitTerminalButton.swift */; }; + 5882252E292C280D00E83CDE /* UtilityAreaMaximizeButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58822516292C280D00E83CDE /* UtilityAreaMaximizeButton.swift */; }; + 5882252F292C280D00E83CDE /* UtilityAreaClearButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58822517292C280D00E83CDE /* UtilityAreaClearButton.swift */; }; + 58822530292C280D00E83CDE /* UtilityAreaFilterTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58822518292C280D00E83CDE /* UtilityAreaFilterTextField.swift */; }; 58822531292C280D00E83CDE /* View+isHovering.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5882251A292C280D00E83CDE /* View+isHovering.swift */; }; 58822532292C280D00E83CDE /* UtilityAreaViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5882251C292C280D00E83CDE /* UtilityAreaViewModel.swift */; }; - 58822534292C280D00E83CDE /* CursorLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5882251E292C280D00E83CDE /* CursorLocation.swift */; }; 588847632992A2A200996D95 /* CEWorkspaceFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 588847622992A2A200996D95 /* CEWorkspaceFile.swift */; }; 588847692992ABCA00996D95 /* Array+SortURLs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 588847682992ABCA00996D95 /* Array+SortURLs.swift */; }; 5894E59729FEF7740077E59C /* CEWorkspaceFile+Recursion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5894E59629FEF7740077E59C /* CEWorkspaceFile+Recursion.swift */; }; @@ -287,6 +286,10 @@ 661EF7B82BEE215300C3E577 /* ImageFileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 661EF7B72BEE215300C3E577 /* ImageFileView.swift */; }; 661EF7BD2BEE215300C3E577 /* LoadingFileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 661EF7BC2BEE215300C3E577 /* LoadingFileView.swift */; }; 669BC4082BED306400D1197C /* AnyFileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669BC4072BED306400D1197C /* AnyFileView.swift */; }; + 66AF6CE22BF17CC300D83C9D /* StatusBarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66AF6CE12BF17CC300D83C9D /* StatusBarViewModel.swift */; }; + 66AF6CE42BF17F6800D83C9D /* StatusBarFileInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66AF6CE32BF17F6800D83C9D /* StatusBarFileInfoView.swift */; }; + 66AF6CE72BF17FFB00D83C9D /* UpdateStatusBarInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66AF6CE62BF17FFB00D83C9D /* UpdateStatusBarInfo.swift */; }; + 66AF6CF02BF183CA00D83C9D /* ImageDimensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66AF6CEF2BF183CA00D83C9D /* ImageDimensions.swift */; }; 66F2C8C42BEAA939004674F7 /* PDFFileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66F2C8C32BEAA939004674F7 /* PDFFileView.swift */; }; 66F370342BEE537B00D3B823 /* NonTextFileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66F370332BEE537B00D3B823 /* NonTextFileView.swift */; }; 6C049A372A49E2DB00D42923 /* DirectoryEventStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C049A362A49E2DB00D42923 /* DirectoryEventStream.swift */; }; @@ -768,15 +771,14 @@ 5882250E292C280D00E83CDE /* StatusBarEncodingSelector.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusBarEncodingSelector.swift; sourceTree = ""; }; 5882250F292C280D00E83CDE /* StatusBarLineEndSelector.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusBarLineEndSelector.swift; sourceTree = ""; }; 58822510292C280D00E83CDE /* StatusBarToggleUtilityAreaButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusBarToggleUtilityAreaButton.swift; sourceTree = ""; }; - 58822511292C280D00E83CDE /* StatusBarCursorLocationLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusBarCursorLocationLabel.swift; sourceTree = ""; }; + 58822511292C280D00E83CDE /* StatusBarCursorPositionLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusBarCursorPositionLabel.swift; sourceTree = ""; }; 58822513292C280D00E83CDE /* UtilityAreaView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UtilityAreaView.swift; sourceTree = ""; }; - 58822515292C280D00E83CDE /* StatusBarSplitTerminalButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusBarSplitTerminalButton.swift; sourceTree = ""; }; - 58822516292C280D00E83CDE /* StatusBarMaximizeButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusBarMaximizeButton.swift; sourceTree = ""; }; - 58822517292C280D00E83CDE /* StatusBarClearButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusBarClearButton.swift; sourceTree = ""; }; - 58822518292C280D00E83CDE /* FilterTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FilterTextField.swift; sourceTree = ""; }; + 58822515292C280D00E83CDE /* UtilityAreaSplitTerminalButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UtilityAreaSplitTerminalButton.swift; sourceTree = ""; }; + 58822516292C280D00E83CDE /* UtilityAreaMaximizeButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UtilityAreaMaximizeButton.swift; sourceTree = ""; }; + 58822517292C280D00E83CDE /* UtilityAreaClearButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UtilityAreaClearButton.swift; sourceTree = ""; }; + 58822518292C280D00E83CDE /* UtilityAreaFilterTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UtilityAreaFilterTextField.swift; sourceTree = ""; }; 5882251A292C280D00E83CDE /* View+isHovering.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "View+isHovering.swift"; sourceTree = ""; }; 5882251C292C280D00E83CDE /* UtilityAreaViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UtilityAreaViewModel.swift; sourceTree = ""; }; - 5882251E292C280D00E83CDE /* CursorLocation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CursorLocation.swift; sourceTree = ""; }; 588847622992A2A200996D95 /* CEWorkspaceFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CEWorkspaceFile.swift; sourceTree = ""; }; 588847682992ABCA00996D95 /* Array+SortURLs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+SortURLs.swift"; sourceTree = ""; }; 5894E59629FEF7740077E59C /* CEWorkspaceFile+Recursion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CEWorkspaceFile+Recursion.swift"; sourceTree = ""; }; @@ -853,6 +855,10 @@ 661EF7B72BEE215300C3E577 /* ImageFileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageFileView.swift; sourceTree = ""; }; 661EF7BC2BEE215300C3E577 /* LoadingFileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingFileView.swift; sourceTree = ""; }; 669BC4072BED306400D1197C /* AnyFileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyFileView.swift; sourceTree = ""; }; + 66AF6CE12BF17CC300D83C9D /* StatusBarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarViewModel.swift; sourceTree = ""; }; + 66AF6CE32BF17F6800D83C9D /* StatusBarFileInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarFileInfoView.swift; sourceTree = ""; }; + 66AF6CE62BF17FFB00D83C9D /* UpdateStatusBarInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateStatusBarInfo.swift; sourceTree = ""; }; + 66AF6CEF2BF183CA00D83C9D /* ImageDimensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageDimensions.swift; sourceTree = ""; }; 66F2C8C32BEAA939004674F7 /* PDFFileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PDFFileView.swift; sourceTree = ""; }; 66F370332BEE537B00D3B823 /* NonTextFileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonTextFileView.swift; sourceTree = ""; }; 6C049A362A49E2DB00D42923 /* DirectoryEventStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DirectoryEventStream.swift; sourceTree = ""; }; @@ -1997,7 +2003,9 @@ 588224FF292C280D00E83CDE /* StatusBar */ = { isa = PBXGroup; children = ( - 5882251B292C280D00E83CDE /* Models */, + 66AF6CEE2BF183C500D83C9D /* Models */, + 66AF6CE52BF17FEF00D83C9D /* ViewModifiers */, + 66AF6CE02BF17CB100D83C9D /* ViewModels */, 58822508292C280D00E83CDE /* Views */, ); path = StatusBar; @@ -2022,7 +2030,8 @@ 5882250E292C280D00E83CDE /* StatusBarEncodingSelector.swift */, 5882250F292C280D00E83CDE /* StatusBarLineEndSelector.swift */, 58822510292C280D00E83CDE /* StatusBarToggleUtilityAreaButton.swift */, - 58822511292C280D00E83CDE /* StatusBarCursorLocationLabel.swift */, + 58822511292C280D00E83CDE /* StatusBarCursorPositionLabel.swift */, + 66AF6CE32BF17F6800D83C9D /* StatusBarFileInfoView.swift */, ); path = StatusBarItems; sourceTree = ""; @@ -2044,22 +2053,14 @@ 58822514292C280D00E83CDE /* Toolbar */ = { isa = PBXGroup; children = ( - 58822515292C280D00E83CDE /* StatusBarSplitTerminalButton.swift */, - 58822516292C280D00E83CDE /* StatusBarMaximizeButton.swift */, - 58822517292C280D00E83CDE /* StatusBarClearButton.swift */, - 58822518292C280D00E83CDE /* FilterTextField.swift */, + 58822515292C280D00E83CDE /* UtilityAreaSplitTerminalButton.swift */, + 58822516292C280D00E83CDE /* UtilityAreaMaximizeButton.swift */, + 58822517292C280D00E83CDE /* UtilityAreaClearButton.swift */, + 58822518292C280D00E83CDE /* UtilityAreaFilterTextField.swift */, ); path = Toolbar; sourceTree = ""; }; - 5882251B292C280D00E83CDE /* Models */ = { - isa = PBXGroup; - children = ( - 5882251E292C280D00E83CDE /* CursorLocation.swift */, - ); - path = Models; - sourceTree = ""; - }; 58822539292C333600E83CDE /* ViewModels */ = { isa = PBXGroup; children = ( @@ -2334,6 +2335,30 @@ path = FuzzySearch; sourceTree = ""; }; + 66AF6CE02BF17CB100D83C9D /* ViewModels */ = { + isa = PBXGroup; + children = ( + 66AF6CE12BF17CC300D83C9D /* StatusBarViewModel.swift */, + ); + path = ViewModels; + sourceTree = ""; + }; + 66AF6CE52BF17FEF00D83C9D /* ViewModifiers */ = { + isa = PBXGroup; + children = ( + 66AF6CE62BF17FFB00D83C9D /* UpdateStatusBarInfo.swift */, + ); + path = ViewModifiers; + sourceTree = ""; + }; + 66AF6CEE2BF183C500D83C9D /* Models */ = { + isa = PBXGroup; + children = ( + 66AF6CEF2BF183CA00D83C9D /* ImageDimensions.swift */, + ); + path = Models; + sourceTree = ""; + }; 6C092EDC2A53A63E00489202 /* Views */ = { isa = PBXGroup; children = ( @@ -3276,7 +3301,6 @@ 3000516C2BBD3A9500A98562 /* ServiceWrapper.swift in Sources */, 77A01E1F2BB33FB500F0EA38 /* CEWorkspaceSettingsView.swift in Sources */, 587B9DA029300ABD00AC7927 /* PanelDivider.swift in Sources */, - 58822534292C280D00E83CDE /* CursorLocation.swift in Sources */, 201169E52837B40300F92B46 /* SourceControlNavigatorRepositoryView.swift in Sources */, 587B9E6A29301D8F00AC7927 /* GitLabPermissions.swift in Sources */, B6EA1FF529DA380E001BF195 /* TextEditingSettingsView.swift in Sources */, @@ -3310,13 +3334,14 @@ 6C5B63DE29C76213005454BA /* WindowCodeFileView.swift in Sources */, 58F2EB08292FB2B0004A9BDE /* TextEditingSettings.swift in Sources */, 201169DB2837B34000F92B46 /* SourceControlNavigatorChangedFileView.swift in Sources */, - 5882252E292C280D00E83CDE /* StatusBarMaximizeButton.swift in Sources */, + 5882252E292C280D00E83CDE /* UtilityAreaMaximizeButton.swift in Sources */, 77A01E2E2BB4261200F0EA38 /* CEWorkspaceSettings.swift in Sources */, 6C4104E9297C970F00F472BA /* AboutDefaultView.swift in Sources */, 587B9E6F29301D8F00AC7927 /* GitLabProjectAccess.swift in Sources */, 587B9E6929301D8F00AC7927 /* GitLabEvent.swift in Sources */, B60718442B17DBE5009CDAB4 /* SourceControlNavigatorRepositoryItem.swift in Sources */, B67DB0F92AFDF638002DC647 /* IconButtonStyle.swift in Sources */, + 66AF6CE42BF17F6800D83C9D /* StatusBarFileInfoView.swift in Sources */, 587B9E5E29301D8F00AC7927 /* GitLabCommitRouter.swift in Sources */, 58F2EB0D292FB2B0004A9BDE /* ThemeSettings.swift in Sources */, 587B9D9F29300ABD00AC7927 /* SegmentedControl.swift in Sources */, @@ -3365,6 +3390,7 @@ 587B9E7329301D8F00AC7927 /* GitRouter.swift in Sources */, 6C2C156129B4F52F00EA60A5 /* SplitViewModifiers.swift in Sources */, 61A53A812B4449F00093BF8A /* WorkspaceDocument+Index.swift in Sources */, + 66AF6CE22BF17CC300D83C9D /* StatusBarViewModel.swift in Sources */, 201169DD2837B3AC00F92B46 /* SourceControlNavigatorToolbarBottom.swift in Sources */, 587B9E8B29301D8F00AC7927 /* GitHubAccount+deleteReference.swift in Sources */, 58798237292E30B90085B254 /* FeedbackView.swift in Sources */, @@ -3429,8 +3455,8 @@ 6C2C155A29B4F4CC00EA60A5 /* Variadic.swift in Sources */, 77A01E322BB4274B00F0EA38 /* TasksCEWorkspaceSettingsView.swift in Sources */, B6E41C8F29DE9CD80088F9F4 /* AccountsSettingsDetailsView.swift in Sources */, - 5882252B292C280D00E83CDE /* StatusBarCursorLocationLabel.swift in Sources */, - 5882252D292C280D00E83CDE /* StatusBarSplitTerminalButton.swift in Sources */, + 5882252B292C280D00E83CDE /* StatusBarCursorPositionLabel.swift in Sources */, + 5882252D292C280D00E83CDE /* UtilityAreaSplitTerminalButton.swift in Sources */, 58798238292E30B90085B254 /* FeedbackWindowController.swift in Sources */, 587B9E6C29301D8F00AC7927 /* GitLabNamespace.swift in Sources */, 6C48D8F22972DAFC00D6D205 /* Env+IsFullscreen.swift in Sources */, @@ -3477,7 +3503,7 @@ 850C631229D6B03400E1444C /* SettingsPage.swift in Sources */, 587B9E6729301D8F00AC7927 /* GitLabEventData.swift in Sources */, B66A4E4529C8E86D004573B4 /* CommandsFixes.swift in Sources */, - 5882252F292C280D00E83CDE /* StatusBarClearButton.swift in Sources */, + 5882252F292C280D00E83CDE /* UtilityAreaClearButton.swift in Sources */, 6CE622692A2A174A0013085C /* InspectorTab.swift in Sources */, 58F2EB04292FB2B0004A9BDE /* SourceControlSettings.swift in Sources */, 58710159298EB80000951BA4 /* CEWorkspaceFileManager.swift in Sources */, @@ -3529,6 +3555,7 @@ 587B9E8029301D8F00AC7927 /* GitHubConfiguration.swift in Sources */, 58822524292C280D00E83CDE /* StatusBarView.swift in Sources */, 581550D429FBD37D00684881 /* ProjectNavigatorToolbarBottom.swift in Sources */, + 66AF6CE72BF17FFB00D83C9D /* UpdateStatusBarInfo.swift in Sources */, 587B9E7E29301D8F00AC7927 /* GitHubGistRouter.swift in Sources */, B6AB09A52AAAC00F0003A3A6 /* EditorTabBarTrailingAccessories.swift in Sources */, 04BA7C0B2AE2A2D100584E1C /* GitBranch.swift in Sources */, @@ -3609,6 +3636,7 @@ 77A01E8E2BC9A09C00F0EA38 /* EditCETaskView.swift in Sources */, 58D01C97293167DC00C5B6B4 /* String+SHA256.swift in Sources */, B6EA1FFD29DB792C001BF195 /* ThemeSettingsColorPreview.swift in Sources */, + 66AF6CF02BF183CA00D83C9D /* ImageDimensions.swift in Sources */, 2806E904297958B9000040F4 /* ContributorRowView.swift in Sources */, 3000516A2BBD3A8200A98562 /* ServiceType.swift in Sources */, 6C578D8C29CD372700DC73B2 /* ExtensionCommands.swift in Sources */, @@ -3619,7 +3647,7 @@ 587B9E7629301D8F00AC7927 /* GitTime.swift in Sources */, 587B9E5D29301D8F00AC7927 /* GitLabUserRouter.swift in Sources */, 588847692992ABCA00996D95 /* Array+SortURLs.swift in Sources */, - 58822530292C280D00E83CDE /* FilterTextField.swift in Sources */, + 58822530292C280D00E83CDE /* UtilityAreaFilterTextField.swift in Sources */, 6C82D6B929BFE34900495C54 /* HelpCommands.swift in Sources */, 6C147C4929A32A080089B630 /* EditorLayoutView.swift in Sources */, 6C147C4129A328BF0089B630 /* EditorLayout.swift in Sources */, diff --git a/CodeEdit/Features/Documents/Controllers/CodeEditWindowController.swift b/CodeEdit/Features/Documents/Controllers/CodeEditWindowController.swift index 4e0720576d..3d496d873b 100644 --- a/CodeEdit/Features/Documents/Controllers/CodeEditWindowController.swift +++ b/CodeEdit/Features/Documents/Controllers/CodeEditWindowController.swift @@ -89,6 +89,7 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate, Obs WorkspaceView() .environmentObject(workspace) .environmentObject(workspace.editorManager) + .environmentObject(workspace.statusBarViewModel) .environmentObject(workspace.utilityAreaModel) } } diff --git a/CodeEdit/Features/Documents/WorkspaceDocument.swift b/CodeEdit/Features/Documents/WorkspaceDocument.swift index dff436bddb..f1fb5e725e 100644 --- a/CodeEdit/Features/Documents/WorkspaceDocument.swift +++ b/CodeEdit/Features/Documents/WorkspaceDocument.swift @@ -30,6 +30,7 @@ final class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate { } } + var statusBarViewModel = StatusBarViewModel() var utilityAreaModel = UtilityAreaViewModel() var searchState: SearchState? var quickOpenViewModel: QuickOpenViewModel? diff --git a/CodeEdit/Features/Editor/Views/EditorAreaFileView.swift b/CodeEdit/Features/Editor/Views/EditorAreaFileView.swift index 4746c6b825..18dad183f4 100644 --- a/CodeEdit/Features/Editor/Views/EditorAreaFileView.swift +++ b/CodeEdit/Features/Editor/Views/EditorAreaFileView.swift @@ -13,7 +13,6 @@ import SwiftUI struct EditorAreaFileView: View { @EnvironmentObject private var editorManager: EditorManager - @EnvironmentObject private var editor: Editor @Environment(\.edgeInsets) diff --git a/CodeEdit/Features/Editor/Views/ImageFileView.swift b/CodeEdit/Features/Editor/Views/ImageFileView.swift index 044f4ed8da..3f9a160df5 100644 --- a/CodeEdit/Features/Editor/Views/ImageFileView.swift +++ b/CodeEdit/Features/Editor/Views/ImageFileView.swift @@ -41,6 +41,7 @@ struct ImageFileView: View { maxWidth: min(pixelWidth, proxy.size.width, nsImage.size.width), maxHeight: min(pixelHeight, proxy.size.height, nsImage.size.height) ) + } .frame(width: proxy.size.width, height: proxy.size.height) } diff --git a/CodeEdit/Features/Editor/Views/NonTextFileView.swift b/CodeEdit/Features/Editor/Views/NonTextFileView.swift index cb5c776bcb..f067313f58 100644 --- a/CodeEdit/Features/Editor/Views/NonTextFileView.swift +++ b/CodeEdit/Features/Editor/Views/NonTextFileView.swift @@ -17,26 +17,38 @@ struct NonTextFileView: View { /// The file document you wish to open. let fileDocument: CodeFileDocument + @EnvironmentObject private var editorManager: EditorManager + @EnvironmentObject private var statusBarViewModel: StatusBarViewModel + var body: some View { - if let fileURL = fileDocument.fileURL { + Group { + if let fileURL = fileDocument.fileURL { - switch fileDocument.utType { - case .some(.image): - ImageFileView(fileURL) + switch fileDocument.utType { + case .some(.image): + ImageFileView(fileURL) + .modifier(UpdateStatusBarInfo(withURL: fileURL)) - case .some(.pdf): - PDFFileView(fileURL) + case .some(.pdf): + PDFFileView(fileURL) + .modifier(UpdateStatusBarInfo(withURL: fileURL)) - default: - AnyFileView(fileURL) - } + default: + AnyFileView(fileURL) + .modifier(UpdateStatusBarInfo(withURL: fileURL)) + } - } else { - ZStack { - Text("Cannot retrieve URL to the file you opened.") + } else { + ZStack { + Text("Cannot retrieve URL to the file you opened.") + } } } + .onDisappear { + statusBarViewModel.dimensions = nil + statusBarViewModel.fileSize = nil + } } } diff --git a/CodeEdit/Features/StatusBar/Models/CursorLocation.swift b/CodeEdit/Features/StatusBar/Models/CursorLocation.swift deleted file mode 100644 index a3f7a764f1..0000000000 --- a/CodeEdit/Features/StatusBar/Models/CursorLocation.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// CursorLocation.swift -// CodeEditModules/StatusBar -// -// Created by Lukas Pistrol on 11.05.22. -// - -import Foundation - -/// The location (line, column) of the cursor in the editor view -/// -/// - Note: Not yet implemented -struct CursorLocation { - /// The current line the cursor is located at. - var line: Int - /// The current column the cursor is located at. - var column: Int -} diff --git a/CodeEdit/Features/StatusBar/Models/ImageDimensions.swift b/CodeEdit/Features/StatusBar/Models/ImageDimensions.swift new file mode 100644 index 0000000000..7d652824bf --- /dev/null +++ b/CodeEdit/Features/StatusBar/Models/ImageDimensions.swift @@ -0,0 +1,14 @@ +// +// ImageDimensions.swift +// CodeEdit +// +// Created by Paul Ebose on 2024/5/13. +// + +import Foundation + +/// Helper struct used to store the (width x height) of the currently opened image. +struct ImageDimensions { + var width: Int + var height: Int +} diff --git a/CodeEdit/Features/StatusBar/ViewModels/StatusBarViewModel.swift b/CodeEdit/Features/StatusBar/ViewModels/StatusBarViewModel.swift new file mode 100644 index 0000000000..c7f00ae929 --- /dev/null +++ b/CodeEdit/Features/StatusBar/ViewModels/StatusBarViewModel.swift @@ -0,0 +1,27 @@ +// +// StatusBarViewModel.swift +// CodeEdit +// +// Created by Paul Ebose on 2024/5/12. +// + +import SwiftUI + +final class StatusBarViewModel: ObservableObject { + + /// The file size of the currently opened file. + @Published var fileSize: Int? + + /// The dimensions (width x height) of the currently opened image. + @Published var dimensions: ImageDimensions? + + /// Indicates whether the breakpoint is enabled or not. + @Published var isBreakpointEnabled = true + + /// The font style of items shown in the status bar. + private(set) var statusBarFont = Font.system(size: 11, weight: .medium) + + /// The color of the text shown in the status bar. + private(set) var foregroundStyle = Color.secondary + +} diff --git a/CodeEdit/Features/StatusBar/ViewModifiers/UpdateStatusBarInfo.swift b/CodeEdit/Features/StatusBar/ViewModifiers/UpdateStatusBarInfo.swift new file mode 100644 index 0000000000..e5385074d7 --- /dev/null +++ b/CodeEdit/Features/StatusBar/ViewModifiers/UpdateStatusBarInfo.swift @@ -0,0 +1,63 @@ +// +// UpdateStatusBarInfo.swift +// CodeEdit +// +// Created by Paul Ebose on 2024/5/12. +// + +import SwiftUI + +/// Updates ``StatusBarFileInfoView``'s `fileSize` and `dimensions`. +/// ```swift +/// FileView +/// .modifier(UpdateStatusBarInfo(withURL)) +/// ``` +struct UpdateStatusBarInfo: ViewModifier { + + /// The URL of the file to compute information from. + let withURL: URL + + @EnvironmentObject private var editorManager: EditorManager + @EnvironmentObject private var statusBarViewModel: StatusBarViewModel + + /// This is returned by ``UpdateStatusBarInfo`` `.computeStatusBarInfo`. + private struct ComputedStatusBarInfo { + let fileSize: Int + let dimensions: ImageDimensions? + } + + /// Compute information that can be used to update properties in ``StatusBarFileInfoView``. + /// - Parameter url: URL of the file to compute information from. + /// - Returns: The file size and its image dimensions (if any). + private func computeStatusBarInfo(url: URL) -> ComputedStatusBarInfo? { + guard let resourceValues = try? url.resourceValues(forKeys: [.contentTypeKey, .fileSizeKey]), + let contentType = resourceValues.contentType, + let fileSize = resourceValues.fileSize + else { + return nil + } + + if contentType.conforms(to: .image), let imageReps = NSImage(contentsOf: url)?.representations.first { + let dimensions = ImageDimensions(width: imageReps.pixelsWide, height: imageReps.pixelsHigh) + return ComputedStatusBarInfo(fileSize: fileSize, dimensions: dimensions) + } else { // non-image file + return ComputedStatusBarInfo(fileSize: fileSize, dimensions: nil) + } + } + + func body(content: Content) -> some View { + content + .onAppear { + let statusBarInfo = computeStatusBarInfo(url: withURL) + statusBarViewModel.fileSize = statusBarInfo?.fileSize + statusBarViewModel.dimensions = statusBarInfo?.dimensions + } + .onChange(of: editorManager.activeEditor.selectedTab) { newTab in + guard let newTab else { return } + let statusBarInfo = computeStatusBarInfo(url: newTab.file.url) + statusBarViewModel.fileSize = statusBarInfo?.fileSize + statusBarViewModel.dimensions = statusBarInfo?.dimensions + } + } + +} diff --git a/CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarBreakpointButton.swift b/CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarBreakpointButton.swift index c331b6ddf8..db376a5b34 100644 --- a/CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarBreakpointButton.swift +++ b/CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarBreakpointButton.swift @@ -1,6 +1,6 @@ // // StatusBarBreakpointButton.swift -// CodeEditModules/StatusBar +// CodeEdit // // Created by Stef Kors on 14/04/2022. // @@ -9,13 +9,13 @@ import SwiftUI import CodeEditSymbols struct StatusBarBreakpointButton: View { - @EnvironmentObject private var model: UtilityAreaViewModel + @EnvironmentObject private var statusBarViewModel: StatusBarViewModel var body: some View { Button { - model.isBreakpointEnabled.toggle() + statusBarViewModel.isBreakpointEnabled.toggle() } label: { - if model.isBreakpointEnabled { + if statusBarViewModel.isBreakpointEnabled { Image.breakpointFill .foregroundColor(.accentColor) } else { diff --git a/CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarCursorLocationLabel.swift b/CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarCursorPositionLabel.swift similarity index 92% rename from CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarCursorLocationLabel.swift rename to CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarCursorPositionLabel.swift index af4ee347e7..df4cf52280 100644 --- a/CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarCursorLocationLabel.swift +++ b/CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarCursorPositionLabel.swift @@ -1,6 +1,6 @@ // -// StatusBarCursorLocationLabel.swift -// CodeEditModules/StatusBar +// StatusBarCursorPositionLabel.swift +// CodeEdit // // Created by Lukas Pistrol on 22.03.22. // @@ -8,13 +8,14 @@ import SwiftUI import CodeEditSourceEditor -struct StatusBarCursorLocationLabel: View { +struct StatusBarCursorPositionLabel: View { @Environment(\.controlActiveState) private var controlActive @Environment(\.modifierKeys) private var modifierKeys - @EnvironmentObject private var model: UtilityAreaViewModel + @EnvironmentObject private var statusBarViewModel: StatusBarViewModel + @EnvironmentObject private var utilityAreaViewModel: UtilityAreaViewModel @EnvironmentObject private var editorManager: EditorManager @State private var tab: EditorInstance? @@ -87,7 +88,7 @@ struct StatusBarCursorLocationLabel: View { EmptyView() } } - .font(model.toolbarFont) + .font(statusBarViewModel.statusBarFont) .foregroundColor(foregroundColor) .fixedSize() .lineLimit(1) diff --git a/CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarFileInfoView.swift b/CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarFileInfoView.swift new file mode 100644 index 0000000000..58d6896d64 --- /dev/null +++ b/CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarFileInfoView.swift @@ -0,0 +1,39 @@ +// +// StatusBarFileInfoView.swift +// CodeEdit +// +// Created by Paul Ebose on 2024/5/12. +// + +import SwiftUI + +/// Shows media information about the currently opened file. +/// +/// This currently shows the file size and image dimensions, if available. +struct StatusBarFileInfoView: View { + + @EnvironmentObject private var statusBarViewModel: StatusBarViewModel + + private let dimensionsNumberStyle = IntegerFormatStyle(locale: Locale(identifier: "en_US")).grouping(.never) + + var body: some View { + + HStack(spacing: 15) { + + if let dimensions = statusBarViewModel.dimensions { + let width = dimensionsNumberStyle.format(dimensions.width) + let height = dimensionsNumberStyle.format(dimensions.height) + + Text("\(width) × \(height)") + } + + if let fileSize = statusBarViewModel.fileSize { + Text(fileSize.formatted(.byteCount(style: .memory))) + } + + } + .font(statusBarViewModel.statusBarFont) + .foregroundStyle(statusBarViewModel.foregroundStyle) + } + +} diff --git a/CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarToggleUtilityAreaButton.swift b/CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarToggleUtilityAreaButton.swift index f88d89a13b..16d525d814 100644 --- a/CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarToggleUtilityAreaButton.swift +++ b/CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarToggleUtilityAreaButton.swift @@ -1,6 +1,6 @@ // // StatusBarToggleUtilityAreaButton.swift -// CodeEditModules/StatusBar +// CodeEdit // // Created by Lukas Pistrol on 22.03.22. // @@ -11,17 +11,17 @@ internal struct StatusBarToggleUtilityAreaButton: View { @Environment(\.controlActiveState) var controlActiveState - @EnvironmentObject private var model: UtilityAreaViewModel + @EnvironmentObject private var utilityAreaViewModel: UtilityAreaViewModel internal var body: some View { Button { - model.togglePanel() + utilityAreaViewModel.togglePanel() } label: { Image(systemName: "square.bottomthird.inset.filled") } .buttonStyle(.icon) .keyboardShortcut("Y", modifiers: [.command, .shift]) - .help(model.isCollapsed ? "Show the Utility area" : "Hide the Utility area") + .help(utilityAreaViewModel.isCollapsed ? "Show the Utility area" : "Hide the Utility area") .onHover { isHovering($0) } .onChange(of: controlActiveState) { newValue in if newValue == .key { @@ -29,7 +29,7 @@ internal struct StatusBarToggleUtilityAreaButton: View { name: "Toggle Utility Area", title: "Toggle Utility Area", id: "open.drawer", - command: CommandClosureWrapper.init(closure: model.togglePanel) + command: CommandClosureWrapper.init(closure: utilityAreaViewModel.togglePanel) ) } } @@ -38,7 +38,7 @@ internal struct StatusBarToggleUtilityAreaButton: View { name: "Toggle Utility Area", title: "Toggle Utility Area", id: "open.drawer", - command: CommandClosureWrapper.init(closure: model.togglePanel) + command: CommandClosureWrapper.init(closure: utilityAreaViewModel.togglePanel) ) } } diff --git a/CodeEdit/Features/StatusBar/Views/StatusBarView.swift b/CodeEdit/Features/StatusBar/Views/StatusBarView.swift index db703e1ad3..a40f4d9532 100644 --- a/CodeEdit/Features/StatusBar/Views/StatusBarView.swift +++ b/CodeEdit/Features/StatusBar/Views/StatusBarView.swift @@ -1,6 +1,6 @@ // // StatusBarView.swift -// CodeEditModules/StatusBar +// CodeEdit // // Created by Lukas Pistrol on 19.03.22. // @@ -11,7 +11,9 @@ import SwiftUI /// /// A View that lives on the bottom of the window and offers information /// about compilation errors/warnings, git, cursor position in text, -/// indentation width (in spaces), text encoding and linebreak +/// indentation width (in spaces), text encoding and linebreak. +/// +/// Also information about the file size and dimensions, if available. /// /// Additionally it offers a togglable/resizable drawer which can /// host a terminal or additional debug information @@ -20,8 +22,6 @@ struct StatusBarView: View { @Environment(\.controlActiveState) private var controlActive - @EnvironmentObject private var model: UtilityAreaViewModel - static let height = 28.0 @Environment(\.colorScheme) @@ -37,8 +37,9 @@ struct StatusBarView: View { // StatusBarBreakpointButton() // StatusBarDivider() Spacer() + StatusBarFileInfoView() HStack(alignment: .center, spacing: 10) { - StatusBarCursorLocationLabel() + StatusBarCursorPositionLabel() } StatusBarDivider() StatusBarToggleUtilityAreaButton() diff --git a/CodeEdit/Features/UtilityArea/DebugUtility/UtilityAreaDebugView.swift b/CodeEdit/Features/UtilityArea/DebugUtility/UtilityAreaDebugView.swift index eeb92b3552..e81659baef 100644 --- a/CodeEdit/Features/UtilityArea/DebugUtility/UtilityAreaDebugView.swift +++ b/CodeEdit/Features/UtilityArea/DebugUtility/UtilityAreaDebugView.swift @@ -8,12 +8,12 @@ import SwiftUI struct UtilityAreaDebugView: View { - @EnvironmentObject private var model: UtilityAreaViewModel + @EnvironmentObject private var utilityAreaViewModel: UtilityAreaViewModel @State var tabSelection = 0 var body: some View { - UtilityAreaTabView(model: model.tabViewModel) { _ in + UtilityAreaTabView(model: utilityAreaViewModel.tabViewModel) { _ in Text("Nothing to debug") .font(.system(size: 16)) .foregroundColor(.secondary) diff --git a/CodeEdit/Features/UtilityArea/OutputUtility/UtilityAreaOutputView.swift b/CodeEdit/Features/UtilityArea/OutputUtility/UtilityAreaOutputView.swift index c1786e024f..5c76724374 100644 --- a/CodeEdit/Features/UtilityArea/OutputUtility/UtilityAreaOutputView.swift +++ b/CodeEdit/Features/UtilityArea/OutputUtility/UtilityAreaOutputView.swift @@ -1,5 +1,5 @@ // -// UtilityAreaDebugView.swift +// UtilityAreaOutputView.swift // CodeEdit // // Created by Austin Condiff on 5/25/23. @@ -9,7 +9,7 @@ import SwiftUI import LogStream struct UtilityAreaOutputView: View { - @EnvironmentObject private var model: UtilityAreaViewModel + @EnvironmentObject private var utilityAreaViewModel: UtilityAreaViewModel @ObservedObject var extensionManager = ExtensionManager.shared @@ -26,7 +26,7 @@ struct UtilityAreaOutputView: View { } var body: some View { - UtilityAreaTabView(model: model.tabViewModel) { _ in + UtilityAreaTabView(model: utilityAreaViewModel.tabViewModel) { _ in Group { if selectedOutputSource == nil { Text("No output") @@ -77,7 +77,7 @@ struct UtilityAreaOutputView: View { .labelsHidden() .controlSize(.small) Spacer() - FilterTextField(title: "Filter", text: $filterText) + UtilityAreaFilterTextField(title: "Filter", text: $filterText) .frame(maxWidth: 175) Button { output = [] diff --git a/CodeEdit/Features/UtilityArea/TerminalUtility/UtilityAreaTerminalView.swift b/CodeEdit/Features/UtilityArea/TerminalUtility/UtilityAreaTerminalView.swift index 815d1a16f2..867c8d43fd 100644 --- a/CodeEdit/Features/UtilityArea/TerminalUtility/UtilityAreaTerminalView.swift +++ b/CodeEdit/Features/UtilityArea/TerminalUtility/UtilityAreaTerminalView.swift @@ -1,5 +1,5 @@ // -// DebuggerAreaTerminal.swift +// UtilityAreaTerminal.swift // CodeEdit // // Created by Austin Condiff on 5/25/23. @@ -42,7 +42,7 @@ struct UtilityAreaTerminalView: View { @EnvironmentObject private var workspace: WorkspaceDocument - @EnvironmentObject private var model: UtilityAreaViewModel + @EnvironmentObject private var utilityAreaViewModel: UtilityAreaViewModel @State private var sidebarIsCollapsed = false @@ -55,7 +55,7 @@ struct UtilityAreaTerminalView: View { private func initializeTerminals() { let id = UUID() - model.terminals = [ + utilityAreaViewModel.terminals = [ UtilityAreaTerminal( id: id, url: workspace.workspaceFileManager?.folderUrl ?? URL(filePath: "/"), @@ -64,13 +64,13 @@ struct UtilityAreaTerminalView: View { ) ] - model.selectedTerminals = [id] + utilityAreaViewModel.selectedTerminals = [id] } private func addTerminal(shell: String? = nil) { let id = UUID() - model.terminals.append( + utilityAreaViewModel.terminals.append( UtilityAreaTerminal( id: id, url: URL(filePath: "\(id)"), @@ -79,17 +79,17 @@ struct UtilityAreaTerminalView: View { ) ) - model.selectedTerminals = [id] + utilityAreaViewModel.selectedTerminals = [id] } private func getTerminal(_ id: UUID) -> UtilityAreaTerminal? { - return model.terminals.first(where: { $0.id == id }) ?? nil + return utilityAreaViewModel.terminals.first(where: { $0.id == id }) ?? nil } private func updateTerminal(_ id: UUID, title: String? = nil) { - let terminalIndex = model.terminals.firstIndex(where: { $0.id == id }) + let terminalIndex = utilityAreaViewModel.terminals.firstIndex(where: { $0.id == id }) if terminalIndex != nil { - updateTerminalByReference(of: &model.terminals[terminalIndex!], title: title) + updateTerminalByReference(of: &utilityAreaViewModel.terminals[terminalIndex!], title: title) } } @@ -121,16 +121,16 @@ struct UtilityAreaTerminalView: View { } func moveItems(from source: IndexSet, to destination: Int) { - model.terminals.move(fromOffsets: source, toOffset: destination) + utilityAreaViewModel.terminals.move(fromOffsets: source, toOffset: destination) } var body: some View { - UtilityAreaTabView(model: model.tabViewModel) { tabState in + UtilityAreaTabView(model: utilityAreaViewModel.tabViewModel) { tabState in ZStack { - if model.selectedTerminals.isEmpty { + if utilityAreaViewModel.selectedTerminals.isEmpty { CEContentUnavailableView("No Selection") } - ForEach(model.terminals) { terminal in + ForEach(utilityAreaViewModel.terminals) { terminal in TerminalEmulatorView( url: terminal.url!, shellType: terminal.shell, @@ -144,14 +144,17 @@ struct UtilityAreaTerminalView: View { .padding(.top, 10) .padding(.horizontal, 10) .contentShape(Rectangle()) - .disabled(terminal.id != model.selectedTerminals.first) - .opacity(terminal.id == model.selectedTerminals.first ? 1 : 0) + .disabled(terminal.id != utilityAreaViewModel.selectedTerminals.first) + .opacity(terminal.id == utilityAreaViewModel.selectedTerminals.first ? 1 : 0) } } .paneToolbar { PaneToolbarSection { - UtilityAreaTerminalPicker(selectedIDs: $model.selectedTerminals, terminals: model.terminals) - .opacity(tabState.leadingSidebarIsCollapsed ? 1 : 0) + UtilityAreaTerminalPicker( + selectedIDs: $utilityAreaViewModel.selectedTerminals, + terminals: utilityAreaViewModel.terminals + ) + .opacity(tabState.leadingSidebarIsCollapsed ? 1 : 0) } Spacer() PaneToolbarSection { @@ -168,7 +171,7 @@ struct UtilityAreaTerminalView: View { } } .background { - if model.selectedTerminals.isEmpty { + if utilityAreaViewModel.selectedTerminals.isEmpty { EffectView(.contentBackground) } else if useThemeBackground { Color(nsColor: backgroundColor) @@ -181,27 +184,27 @@ struct UtilityAreaTerminalView: View { } } .colorScheme( - model.selectedTerminals.isEmpty + utilityAreaViewModel.selectedTerminals.isEmpty ? colorScheme : matchAppearance && darkAppearance ? themeModel.selectedDarkTheme?.appearance == .dark ? .dark : .light : themeModel.selectedTheme?.appearance == .dark ? .dark : .light ) } leadingSidebar: { _ in - List(selection: $model.selectedTerminals) { - ForEach(model.terminals, id: \.self.id) { terminal in + List(selection: $utilityAreaViewModel.selectedTerminals) { + ForEach(utilityAreaViewModel.terminals, id: \.self.id) { terminal in UtilityAreaTerminalTab( terminal: terminal, - removeTerminals: model.removeTerminals, - isSelected: model.selectedTerminals.contains(terminal.id), - selectedIDs: model.selectedTerminals + removeTerminals: utilityAreaViewModel.removeTerminals, + isSelected: utilityAreaViewModel.selectedTerminals.contains(terminal.id), + selectedIDs: utilityAreaViewModel.selectedTerminals ) .tag(terminal.id) .listRowSeparator(.hidden) } .onMove(perform: moveItems) } - .focusedObject(model) + .focusedObject(utilityAreaViewModel) .listStyle(.automatic) .accentColor(.secondary) .contextMenu { @@ -221,7 +224,7 @@ struct UtilityAreaTerminalView: View { } } } - .onChange(of: model.terminals) { newValue in + .onChange(of: utilityAreaViewModel.terminals) { newValue in if newValue.isEmpty { addTerminal() } @@ -234,12 +237,12 @@ struct UtilityAreaTerminalView: View { Image(systemName: "plus") } Button { - model.removeTerminals(model.selectedTerminals) + utilityAreaViewModel.removeTerminals(utilityAreaViewModel.selectedTerminals) } label: { Image(systemName: "minus") } - .disabled(model.terminals.count <= 1) - .opacity(model.terminals.count <= 1 ? 0.5 : 1) + .disabled(utilityAreaViewModel.terminals.count <= 1) + .opacity(utilityAreaViewModel.terminals.count <= 1 ? 0.5 : 1) } Spacer() } diff --git a/CodeEdit/Features/UtilityArea/Toolbar/StatusBarMaximizeButton.swift b/CodeEdit/Features/UtilityArea/Toolbar/StatusBarMaximizeButton.swift deleted file mode 100644 index ac87eeb894..0000000000 --- a/CodeEdit/Features/UtilityArea/Toolbar/StatusBarMaximizeButton.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// StatusBarMaximizeButton.swift -// CodeEditModules/StatusBar -// -// Created by Stef Kors on 12/04/2022. -// - -import SwiftUI - -struct StatusBarMaximizeButton: View { - @EnvironmentObject private var model: UtilityAreaViewModel - - var body: some View { - Button { - model.isMaximized.toggle() - } label: { - Image(systemName: "arrowtriangle.up.square") - .foregroundColor(model.isMaximized ? .accentColor : .secondary) - } - .buttonStyle(.plain) - } -} diff --git a/CodeEdit/Features/UtilityArea/Toolbar/StatusBarClearButton.swift b/CodeEdit/Features/UtilityArea/Toolbar/UtilityAreaClearButton.swift similarity index 64% rename from CodeEdit/Features/UtilityArea/Toolbar/StatusBarClearButton.swift rename to CodeEdit/Features/UtilityArea/Toolbar/UtilityAreaClearButton.swift index 74e174d24f..9becd5015f 100644 --- a/CodeEdit/Features/UtilityArea/Toolbar/StatusBarClearButton.swift +++ b/CodeEdit/Features/UtilityArea/Toolbar/UtilityAreaClearButton.swift @@ -1,15 +1,13 @@ // -// StatusBarClearButton.swift -// CodeEditModules/StatusBar +// UtilityAreaClearButton.swift +// CodeEdit // // Created by Stef Kors on 12/04/2022. // import SwiftUI -struct StatusBarClearButton: View { - @EnvironmentObject private var model: UtilityAreaViewModel - +struct UtilityAreaClearButton: View { var body: some View { Button { // Clear terminal diff --git a/CodeEdit/Features/UtilityArea/Toolbar/FilterTextField.swift b/CodeEdit/Features/UtilityArea/Toolbar/UtilityAreaFilterTextField.swift similarity index 93% rename from CodeEdit/Features/UtilityArea/Toolbar/FilterTextField.swift rename to CodeEdit/Features/UtilityArea/Toolbar/UtilityAreaFilterTextField.swift index 20de5db6f8..523055b7b0 100644 --- a/CodeEdit/Features/UtilityArea/Toolbar/FilterTextField.swift +++ b/CodeEdit/Features/UtilityArea/Toolbar/UtilityAreaFilterTextField.swift @@ -1,13 +1,13 @@ // -// FilterTextField.swift -// CodeEditModules/StatusBar +// UtilityAreaFilterTextField.swift +// CodeEdit // // Created by Stef Kors on 12/04/2022. // import SwiftUI -struct FilterTextField: View { +struct UtilityAreaFilterTextField: View { let title: String @Binding var text: String diff --git a/CodeEdit/Features/UtilityArea/Toolbar/UtilityAreaMaximizeButton.swift b/CodeEdit/Features/UtilityArea/Toolbar/UtilityAreaMaximizeButton.swift new file mode 100644 index 0000000000..bb63d2521b --- /dev/null +++ b/CodeEdit/Features/UtilityArea/Toolbar/UtilityAreaMaximizeButton.swift @@ -0,0 +1,22 @@ +// +// UtilityAreaMaximizeButton.swift +// CodeEdit +// +// Created by Stef Kors on 12/04/2022. +// + +import SwiftUI + +struct UtilityAreaMaximizeButton: View { + @EnvironmentObject private var utilityAreaViewModel: UtilityAreaViewModel + + var body: some View { + Button { + utilityAreaViewModel.isMaximized.toggle() + } label: { + Image(systemName: "arrowtriangle.up.square") + .foregroundColor(utilityAreaViewModel.isMaximized ? .accentColor : .secondary) + } + .buttonStyle(.plain) + } +} diff --git a/CodeEdit/Features/UtilityArea/Toolbar/StatusBarSplitTerminalButton.swift b/CodeEdit/Features/UtilityArea/Toolbar/UtilityAreaSplitTerminalButton.swift similarity index 62% rename from CodeEdit/Features/UtilityArea/Toolbar/StatusBarSplitTerminalButton.swift rename to CodeEdit/Features/UtilityArea/Toolbar/UtilityAreaSplitTerminalButton.swift index 71e1288410..9b93382a18 100644 --- a/CodeEdit/Features/UtilityArea/Toolbar/StatusBarSplitTerminalButton.swift +++ b/CodeEdit/Features/UtilityArea/Toolbar/UtilityAreaSplitTerminalButton.swift @@ -1,15 +1,13 @@ // -// StatusBarSplitTerminalButton.swift -// CodeEditModules/StatusBar +// UtilityAreaSplitTerminalButton.swift +// CodeEdit // // Created by Stef Kors on 14/04/2022. // import SwiftUI -struct StatusBarSplitTerminalButton: View { - @EnvironmentObject private var model: UtilityAreaViewModel - +struct UtilityAreaSplitTerminalButton: View { var body: some View { Button { // todo diff --git a/CodeEdit/Features/UtilityArea/ViewModels/UtilityAreaViewModel.swift b/CodeEdit/Features/UtilityArea/ViewModels/UtilityAreaViewModel.swift index 542def1310..671ccf3278 100644 --- a/CodeEdit/Features/UtilityArea/ViewModels/UtilityAreaViewModel.swift +++ b/CodeEdit/Features/UtilityArea/ViewModels/UtilityAreaViewModel.swift @@ -9,11 +9,8 @@ import SwiftUI /// # UtilityAreaViewModel /// -/// A model class to host and manage data for the ``StatusBarView`` -/// +/// A model class to host and manage data for the Utility area. class UtilityAreaViewModel: ObservableObject { - /// Returns the current location of the cursor in an editing view - @Published var cursorLocation: CursorLocation = .init(line: 1, column: 1) // Implementation needed!! @Published var terminals: [UtilityAreaTerminal] = [] @@ -28,24 +25,12 @@ class UtilityAreaViewModel: ObservableObject { /// The current height of the drawer. Zero if hidden @Published var currentHeight: Double = 0 - /// Indicates whether the drawer is being resized or not - @Published var isDragging: Bool = false - - /// Indicates whether the breakpoint is enabled or not - @Published var isBreakpointEnabled: Bool = true - - /// Search value to filter in drawer - @Published var searchText: String = "" - - /// The tab bar items for the DebugAreaView + /// The tab bar items for the UtilityAreaView @Published var tabItems: [UtilityAreaTab] = UtilityAreaTab.allCases /// The tab bar view model for UtilityAreaTabView @Published var tabViewModel = UtilityAreaTabViewModel() - /// Returns the font for status bar items to use - private(set) var toolbarFont: Font = .system(size: 11, weight: .medium) - func removeTerminals(_ ids: Set) { terminals.removeAll(where: { terminal in ids.contains(terminal.id) diff --git a/CodeEdit/Features/UtilityArea/Views/UtilityAreaView.swift b/CodeEdit/Features/UtilityArea/Views/UtilityAreaView.swift index fc611b03ac..bd897f902a 100644 --- a/CodeEdit/Features/UtilityArea/Views/UtilityAreaView.swift +++ b/CodeEdit/Features/UtilityArea/Views/UtilityAreaView.swift @@ -1,6 +1,6 @@ // // UtilityAreaView.swift -// CodeEditModules/StatusBar +// CodeEdit // // Created by Lukas Pistrol on 22.03.22. // @@ -17,7 +17,7 @@ struct UtilityAreaView: View { @Environment(\.colorScheme) private var colorScheme - @EnvironmentObject private var model: UtilityAreaViewModel + @EnvironmentObject private var utilityAreaViewModel: UtilityAreaViewModel @StateObject private var themeModel: ThemeModel = .shared @@ -34,7 +34,7 @@ struct UtilityAreaView: View { } .safeAreaInset(edge: .leading, spacing: 0) { HStack(spacing: 0) { - AreaTabBar(items: $model.tabItems, selection: $selection, position: .side) + AreaTabBar(items: $utilityAreaViewModel.tabItems, selection: $selection, position: .side) Divider() .overlay(Color(nsColor: colorScheme == .dark ? .black : .clear)) } @@ -44,15 +44,15 @@ struct UtilityAreaView: View { Divider() HStack(spacing: 0) { Button { - model.isMaximized.toggle() + utilityAreaViewModel.isMaximized.toggle() } label: { Image(systemName: "arrowtriangle.up.square") } - .buttonStyle(.icon(isActive: model.isMaximized, size: 24)) + .buttonStyle(.icon(isActive: utilityAreaViewModel.isMaximized, size: 24)) } } .colorScheme( - model.selectedTerminals.isEmpty + utilityAreaViewModel.selectedTerminals.isEmpty ? colorScheme : matchAppearance && darkAppearance ? themeModel.selectedDarkTheme?.appearance == .dark ? .dark : .light diff --git a/CodeEdit/WorkspaceView.swift b/CodeEdit/WorkspaceView.swift index 94f4db792b..b2649faccb 100644 --- a/CodeEdit/WorkspaceView.swift +++ b/CodeEdit/WorkspaceView.swift @@ -21,7 +21,7 @@ struct WorkspaceView: View { @EnvironmentObject private var workspace: WorkspaceDocument @EnvironmentObject private var editorManager: EditorManager - @EnvironmentObject private var utilityAreaModel: UtilityAreaViewModel + @EnvironmentObject private var utilityAreaViewModel: UtilityAreaViewModel @StateObject private var themeModel: ThemeModel = .shared @@ -43,7 +43,7 @@ struct WorkspaceView: View { focus: $focusedEditor ) .collapsable() - .collapsed($utilityAreaModel.isMaximized) + .collapsed($utilityAreaViewModel.isMaximized) .frame(minHeight: 170 + 29 + 29) .frame(maxWidth: .infinity, maxHeight: .infinity) .holdingPriority(.init(1)) @@ -52,7 +52,7 @@ struct WorkspaceView: View { } UtilityAreaView() .collapsable() - .collapsed($utilityAreaModel.isCollapsed) + .collapsed($utilityAreaViewModel.isCollapsed) .frame(idealHeight: 260) .frame(minHeight: 100) } diff --git a/Documentation.docc/App Window/StatusBarView.md b/Documentation.docc/App Window/StatusBarView.md index 2582bd2e14..c786a4afad 100644 --- a/Documentation.docc/App Window/StatusBarView.md +++ b/Documentation.docc/App Window/StatusBarView.md @@ -4,24 +4,22 @@ ### Model +- ``ImageDimensions`` + +### View Model + - ``StatusBarViewModel`` -- ``StatusBarTabType`` -- ``CursorLocation`` + +### View Modifiers + +- ``UpdateStatusBarInfo`` ### Items -- ``StatusBarMenuLabel`` +- ``StatusBarMenuStyle`` - ``StatusBarBreakpointButton`` - ``StatusBarIndentSelector`` - ``StatusBarEncodingSelector`` - ``StatusBarLineEndSelector`` -- ``StatusBarToggleDrawerButton`` -- ``StatusBarCursorLocationLabel`` - -### Drawer - -- ``UtilityAreaView`` -- ``StatusBarSplitTerminalButton`` -- ``StatusBarMaximizeButton`` -- ``StatusBarClearButton`` -- ``FilterTextField`` +- ``StatusBarToggleUtilityAreaButton`` +- ``StatusBarCursorPositionLabel`` diff --git a/Documentation.docc/App Window/UtilityAreaView.md b/Documentation.docc/App Window/UtilityAreaView.md new file mode 100644 index 0000000000..50e5e93988 --- /dev/null +++ b/Documentation.docc/App Window/UtilityAreaView.md @@ -0,0 +1,27 @@ +# ``CodeEdit/UtilityAreaView`` + +## Topics + +### Model + +- ``UtilityAreaTab`` + +### View Model + +- ``UtilityAreaViewModel`` +- ``UtilityAreaTabViewModel`` + +### Utility + +- ``UtilityAreaTerminal`` +- ``UtilityAreaTerminalTab`` +- ``UtilityAreaDebugView`` +- ``UtilityAreaOutputView`` + +### Toolbar + +- ``UtilityAreaView`` +- ``UtilityAreaSplitTerminalButton`` +- ``UtilityAreaMaximizeButton`` +- ``UtilityAreaClearButton`` +- ``UtilityAreaFilterTextField``