diff --git a/Box42.xcodeproj/project.pbxproj b/Box42.xcodeproj/project.pbxproj index 8235f4f..54be299 100644 --- a/Box42.xcodeproj/project.pbxproj +++ b/Box42.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - D676A64A2A8C5CEA00B5C319 /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = D676A6492A8C5CEA00B5C319 /* SnapKit */; }; DE018BB32A5099F900FF0AA3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE018BB22A5099F900FF0AA3 /* AppDelegate.swift */; }; DE018BB82A5099F900FF0AA3 /* Box42.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DE018BB62A5099F900FF0AA3 /* Box42.xcdatamodeld */; }; DE018BDD2A509AEB00FF0AA3 /* EventMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE018BDC2A509AEB00FF0AA3 /* EventMonitor.swift */; }; @@ -18,27 +17,44 @@ DE018BED2A509B2600FF0AA3 /* URLModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE018BEC2A509B2600FF0AA3 /* URLModel.swift */; }; DE018BF02A509B2F00FF0AA3 /* MenubarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE018BEF2A509B2F00FF0AA3 /* MenubarViewController.swift */; }; DE018BF32A509B3300FF0AA3 /* MenubarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE018BF22A509B3300FF0AA3 /* MenubarModel.swift */; }; - DE018BF62A509B3600FF0AA3 /* MenubarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE018BF52A509B3600FF0AA3 /* MenubarView.swift */; }; DE018C032A509B5D00FF0AA3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DE018C022A509B5D00FF0AA3 /* Main.storyboard */; }; DE0A915D2A8E348D00D1D6F1 /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = DE0A915C2A8E348D00D1D6F1 /* SnapKit */; }; DE0A91632A8E6A5400D1D6F1 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A91622A8E6A5400D1D6F1 /* Constants.swift */; }; - DE0A91672A8E6CA700D1D6F1 /* WebViewList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A91662A8E6CA700D1D6F1 /* WebViewList.swift */; }; + DE0A91672A8E6CA700D1D6F1 /* WebViewManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A91662A8E6CA700D1D6F1 /* WebViewManager.swift */; }; DE0A916D2A8E7DD700D1D6F1 /* HoverButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A916C2A8E7DD700D1D6F1 /* HoverButton.swift */; }; - DE0A91702A8E8BDE00D1D6F1 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A916F2A8E8BDE00D1D6F1 /* GradientView.swift */; }; + DE0A91782A8F014F00D1D6F1 /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A91772A8F014F00D1D6F1 /* WebView.swift */; }; + DE0A917B2A8F0CA800D1D6F1 /* AppleScripts+ShowMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A917A2A8F0CA800D1D6F1 /* AppleScripts+ShowMessage.swift */; }; + DE0A917F2A8F865400D1D6F1 /* BoxToolbarViewGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A917E2A8F865400D1D6F1 /* BoxToolbarViewGroup.swift */; }; + DE0A91832A8F889000D1D6F1 /* GoHomePageViaToolbar().swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A91822A8F889000D1D6F1 /* GoHomePageViaToolbar().swift */; }; + DE0A91862A8F889F00D1D6F1 /* RefreshPageViaToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A91852A8F889F00D1D6F1 /* RefreshPageViaToolbar.swift */; }; + DE0A918A2A8F88A900D1D6F1 /* GoForwardInToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A91892A8F88A900D1D6F1 /* GoForwardInToolbar.swift */; }; + DE0A918D2A8F88BC00D1D6F1 /* GoBackInToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A918C2A8F88BC00D1D6F1 /* GoBackInToolbar.swift */; }; + DE0A91902A8F88CA00D1D6F1 /* DisplayURLInToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A918F2A8F88CA00D1D6F1 /* DisplayURLInToolbar.swift */; }; + DE0A91982A8F977F00D1D6F1 /* ToolbarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A91972A8F977F00D1D6F1 /* ToolbarViewController.swift */; }; + DE0A91A72A8FC66600D1D6F1 /* SideBarLeading.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A91A62A8FC66600D1D6F1 /* SideBarLeading.swift */; }; DE1F1A142A8B506600A88DD8 /* importMacOSInfo.sh in Resources */ = {isa = PBXBuildFile; fileRef = DE1F1A112A8B506600A88DD8 /* importMacOSInfo.sh */; }; DE1F1A152A8B506600A88DD8 /* exportMacOSInfo.sh in Resources */ = {isa = PBXBuildFile; fileRef = DE1F1A122A8B506600A88DD8 /* exportMacOSInfo.sh */; }; DE1F1A162A8B506600A88DD8 /* keyMapping.sh in Resources */ = {isa = PBXBuildFile; fileRef = DE1F1A132A8B506600A88DD8 /* keyMapping.sh */; }; DE1F1A1C2A8B50C500A88DD8 /* BoxBaseContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE1F1A192A8B50C500A88DD8 /* BoxBaseContainerViewController.swift */; }; DE1F1A1D2A8B50C500A88DD8 /* BoxContentsViewGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE1F1A1A2A8B50C500A88DD8 /* BoxContentsViewGroup.swift */; }; DE1F1A1E2A8B50C500A88DD8 /* BoxButtonViewGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE1F1A1B2A8B50C500A88DD8 /* BoxButtonViewGroup.swift */; }; - DE1F1A242A8B50D500A88DD8 /* BoxButtonHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE1F1A212A8B50D500A88DD8 /* BoxButtonHandler.swift */; }; - DE1F1A252A8B50D500A88DD8 /* BoxViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE1F1A222A8B50D500A88DD8 /* BoxViewModel.swift */; }; DE1F1A262A8B50D500A88DD8 /* BoxViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE1F1A232A8B50D500A88DD8 /* BoxViewController.swift */; }; DE1F1A292A8B50E200A88DD8 /* BoxSizeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE1F1A282A8B50E200A88DD8 /* BoxSizeManager.swift */; }; DE1F1A2E2A8BCC9800A88DD8 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE1F1A2D2A8BCC9800A88DD8 /* Storage.swift */; }; DE1F1A312A8BD68F00A88DD8 /* Double.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE1F1A302A8BD68F00A88DD8 /* Double.swift */; }; DE1F1A362A8BDDDF00A88DD8 /* StorageConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE1F1A352A8BDDDF00A88DD8 /* StorageConfig.swift */; }; + DE24E6352A8FE02A00E29F5D /* MovableContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE24E6342A8FE02A00E29F5D /* MovableContainerView.swift */; }; + DE24E6382A8FE10400E29F5D /* BoxBaseSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE24E6372A8FE10300E29F5D /* BoxBaseSplitView.swift */; }; + DE24E63B2A8FE93900E29F5D /* NSImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE24E63A2A8FE93900E29F5D /* NSImage.swift */; }; DE2AD3292A824EEB00002D51 /* Accessibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE2AD3282A824EEB00002D51 /* Accessibility.swift */; }; + DE4407FA2A923E860091937A /* BoxFunctionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4407F92A923E860091937A /* BoxFunctionViewController.swift */; }; + DE4407FE2A923EA90091937A /* PreferenceButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4407FD2A923EA90091937A /* PreferenceButtonView.swift */; }; + DE4408022A923EB60091937A /* PinButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4408012A923EB60091937A /* PinButtonView.swift */; }; + DE4408052A923EC00091937A /* QuitButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4408042A923EC00091937A /* QuitButtonView.swift */; }; + DE4408082A9240300091937A /* BoxFunctionButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4408072A9240300091937A /* BoxFunctionButtonView.swift */; }; + DE44080C2A924B520091937A /* BoxFunctionViewGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE44080B2A924B520091937A /* BoxFunctionViewGroup.swift */; }; + DE4408152A92750D0091937A /* keyDown+BoxViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4408142A92750D0091937A /* keyDown+BoxViewController.swift */; }; + DE44081D2A928F760091937A /* TopDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE44081C2A928F760091937A /* TopDivider.swift */; }; DE77BA512A82580400713683 /* MenubarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE77BA502A82580400713683 /* MenubarViewModel.swift */; }; DE77BA562A82637900713683 /* StateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE77BA552A82637900713683 /* StateManager.swift */; }; DE7A257A2A6D8CA20043225A /* PreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE7A25792A6D8CA20043225A /* PreferencesViewController.swift */; }; @@ -66,27 +82,44 @@ DE018BEC2A509B2600FF0AA3 /* URLModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLModel.swift; sourceTree = ""; }; DE018BEF2A509B2F00FF0AA3 /* MenubarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenubarViewController.swift; sourceTree = ""; }; DE018BF22A509B3300FF0AA3 /* MenubarModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenubarModel.swift; sourceTree = ""; }; - DE018BF52A509B3600FF0AA3 /* MenubarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenubarView.swift; sourceTree = ""; }; DE018C022A509B5D00FF0AA3 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; DE018C192A509DBA00FF0AA3 /* Box42.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Box42.entitlements; sourceTree = ""; }; DE0A91622A8E6A5400D1D6F1 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; - DE0A91662A8E6CA700D1D6F1 /* WebViewList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewList.swift; sourceTree = ""; }; + DE0A91662A8E6CA700D1D6F1 /* WebViewManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewManager.swift; sourceTree = ""; }; DE0A916C2A8E7DD700D1D6F1 /* HoverButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HoverButton.swift; sourceTree = ""; }; - DE0A916F2A8E8BDE00D1D6F1 /* GradientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = ""; }; + DE0A91772A8F014F00D1D6F1 /* WebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebView.swift; sourceTree = ""; }; + DE0A917A2A8F0CA800D1D6F1 /* AppleScripts+ShowMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppleScripts+ShowMessage.swift"; sourceTree = ""; }; + DE0A917E2A8F865400D1D6F1 /* BoxToolbarViewGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxToolbarViewGroup.swift; sourceTree = ""; }; + DE0A91822A8F889000D1D6F1 /* GoHomePageViaToolbar().swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GoHomePageViaToolbar().swift"; sourceTree = ""; }; + DE0A91852A8F889F00D1D6F1 /* RefreshPageViaToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefreshPageViaToolbar.swift; sourceTree = ""; }; + DE0A91892A8F88A900D1D6F1 /* GoForwardInToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoForwardInToolbar.swift; sourceTree = ""; }; + DE0A918C2A8F88BC00D1D6F1 /* GoBackInToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoBackInToolbar.swift; sourceTree = ""; }; + DE0A918F2A8F88CA00D1D6F1 /* DisplayURLInToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayURLInToolbar.swift; sourceTree = ""; }; + DE0A91972A8F977F00D1D6F1 /* ToolbarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolbarViewController.swift; sourceTree = ""; }; + DE0A91A62A8FC66600D1D6F1 /* SideBarLeading.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SideBarLeading.swift; sourceTree = ""; }; DE1F1A112A8B506600A88DD8 /* importMacOSInfo.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = importMacOSInfo.sh; sourceTree = ""; }; DE1F1A122A8B506600A88DD8 /* exportMacOSInfo.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = exportMacOSInfo.sh; sourceTree = ""; }; DE1F1A132A8B506600A88DD8 /* keyMapping.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = keyMapping.sh; sourceTree = ""; }; DE1F1A192A8B50C500A88DD8 /* BoxBaseContainerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BoxBaseContainerViewController.swift; path = Box/BoxBaseContainerViewController.swift; sourceTree = ""; }; - DE1F1A1A2A8B50C500A88DD8 /* BoxContentsViewGroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BoxContentsViewGroup.swift; path = Box/BoxContentsViewGroup.swift; sourceTree = ""; }; - DE1F1A1B2A8B50C500A88DD8 /* BoxButtonViewGroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BoxButtonViewGroup.swift; path = Box/BoxButtonViewGroup.swift; sourceTree = ""; }; - DE1F1A212A8B50D500A88DD8 /* BoxButtonHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BoxButtonHandler.swift; path = Main/BoxButtonHandler.swift; sourceTree = ""; }; - DE1F1A222A8B50D500A88DD8 /* BoxViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BoxViewModel.swift; path = Main/BoxViewModel.swift; sourceTree = ""; }; + DE1F1A1A2A8B50C500A88DD8 /* BoxContentsViewGroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoxContentsViewGroup.swift; sourceTree = ""; }; + DE1F1A1B2A8B50C500A88DD8 /* BoxButtonViewGroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoxButtonViewGroup.swift; sourceTree = ""; }; DE1F1A232A8B50D500A88DD8 /* BoxViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BoxViewController.swift; path = Main/BoxViewController.swift; sourceTree = ""; }; DE1F1A282A8B50E200A88DD8 /* BoxSizeManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoxSizeManager.swift; sourceTree = ""; }; DE1F1A2D2A8BCC9800A88DD8 /* Storage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Storage.swift; sourceTree = ""; }; DE1F1A302A8BD68F00A88DD8 /* Double.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Double.swift; sourceTree = ""; }; DE1F1A352A8BDDDF00A88DD8 /* StorageConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorageConfig.swift; sourceTree = ""; }; + DE24E6342A8FE02A00E29F5D /* MovableContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MovableContainerView.swift; sourceTree = ""; }; + DE24E6372A8FE10300E29F5D /* BoxBaseSplitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxBaseSplitView.swift; sourceTree = ""; }; + DE24E63A2A8FE93900E29F5D /* NSImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSImage.swift; sourceTree = ""; }; DE2AD3282A824EEB00002D51 /* Accessibility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Accessibility.swift; sourceTree = ""; }; + DE4407F92A923E860091937A /* BoxFunctionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxFunctionViewController.swift; sourceTree = ""; }; + DE4407FD2A923EA90091937A /* PreferenceButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferenceButtonView.swift; sourceTree = ""; }; + DE4408012A923EB60091937A /* PinButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinButtonView.swift; sourceTree = ""; }; + DE4408042A923EC00091937A /* QuitButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuitButtonView.swift; sourceTree = ""; }; + DE4408072A9240300091937A /* BoxFunctionButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxFunctionButtonView.swift; sourceTree = ""; }; + DE44080B2A924B520091937A /* BoxFunctionViewGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxFunctionViewGroup.swift; sourceTree = ""; }; + DE4408142A92750D0091937A /* keyDown+BoxViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "keyDown+BoxViewController.swift"; path = "Main/keyDown+BoxViewController.swift"; sourceTree = ""; }; + DE44081C2A928F760091937A /* TopDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopDivider.swift; sourceTree = ""; }; DE77BA502A82580400713683 /* MenubarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenubarViewModel.swift; sourceTree = ""; }; DE77BA552A82637900713683 /* StateManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateManager.swift; sourceTree = ""; }; DE7A25792A6D8CA20043225A /* PreferencesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferencesViewController.swift; sourceTree = ""; }; @@ -144,6 +177,8 @@ DE018C0C2A509BDF00FF0AA3 /* Resources */, DE018C062A509B9000FF0AA3 /* System */, DE018C082A509BB500FF0AA3 /* WebView */, + DE0A917D2A8F864300D1D6F1 /* Toolbar */, + DE4407F82A923E5B0091937A /* FunctionButton */, DE1F1A182A8B50BB00A88DD8 /* Box */, DE018C0E2A509C0C00FF0AA3 /* Menubar */, ); @@ -165,9 +200,10 @@ isa = PBXGroup; children = ( DE018C0B2A509BC100FF0AA3 /* URL */, + DE0A91662A8E6CA700D1D6F1 /* WebViewManager.swift */, DE018BE92A509B2100FF0AA3 /* WebViewModel.swift */, DE018BE62A509B1E00FF0AA3 /* WebViewController.swift */, - DE0A91662A8E6CA700D1D6F1 /* WebViewList.swift */, + DE0A91772A8F014F00D1D6F1 /* WebView.swift */, ); path = WebView; sourceTree = ""; @@ -183,6 +219,7 @@ DE018C0C2A509BDF00FF0AA3 /* Resources */ = { isa = PBXGroup; children = ( + DEB862DE2A85348600278FCD /* sh */, DE018C192A509DBA00FF0AA3 /* Box42.entitlements */, DE018BB22A5099F900FF0AA3 /* AppDelegate.swift */, DE018BDF2A509B0600FF0AA3 /* Assets.xcassets */, @@ -198,7 +235,6 @@ children = ( DE018BEF2A509B2F00FF0AA3 /* MenubarViewController.swift */, DE018BF22A509B3300FF0AA3 /* MenubarModel.swift */, - DE018BF52A509B3600FF0AA3 /* MenubarView.swift */, DE77BA502A82580400713683 /* MenubarViewModel.swift */, ); path = Menubar; @@ -208,11 +244,34 @@ isa = PBXGroup; children = ( DE0A916C2A8E7DD700D1D6F1 /* HoverButton.swift */, - DE0A916F2A8E8BDE00D1D6F1 /* GradientView.swift */, + DE24E6342A8FE02A00E29F5D /* MovableContainerView.swift */, ); path = UI; sourceTree = ""; }; + DE0A917D2A8F864300D1D6F1 /* Toolbar */ = { + isa = PBXGroup; + children = ( + DE0A919E2A8FA15300D1D6F1 /* View */, + DE0A91972A8F977F00D1D6F1 /* ToolbarViewController.swift */, + ); + path = Toolbar; + sourceTree = ""; + }; + DE0A919E2A8FA15300D1D6F1 /* View */ = { + isa = PBXGroup; + children = ( + DE0A91A62A8FC66600D1D6F1 /* SideBarLeading.swift */, + DE0A91822A8F889000D1D6F1 /* GoHomePageViaToolbar().swift */, + DE0A918F2A8F88CA00D1D6F1 /* DisplayURLInToolbar.swift */, + DE0A918C2A8F88BC00D1D6F1 /* GoBackInToolbar.swift */, + DE0A91892A8F88A900D1D6F1 /* GoForwardInToolbar.swift */, + DE0A91852A8F889F00D1D6F1 /* RefreshPageViaToolbar.swift */, + DE0A917E2A8F865400D1D6F1 /* BoxToolbarViewGroup.swift */, + ); + path = View; + sourceTree = ""; + }; DE17AF722A834A1600325BF4 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -223,9 +282,8 @@ DE1F1A182A8B50BB00A88DD8 /* Box */ = { isa = PBXGroup; children = ( + DE4408202A9297EE0091937A /* View */, DE1F1A192A8B50C500A88DD8 /* BoxBaseContainerViewController.swift */, - DE1F1A1B2A8B50C500A88DD8 /* BoxButtonViewGroup.swift */, - DE1F1A1A2A8B50C500A88DD8 /* BoxContentsViewGroup.swift */, ); name = Box; sourceTree = ""; @@ -233,13 +291,45 @@ DE1F1A202A8B50CA00A88DD8 /* Main */ = { isa = PBXGroup; children = ( - DE1F1A212A8B50D500A88DD8 /* BoxButtonHandler.swift */, DE1F1A232A8B50D500A88DD8 /* BoxViewController.swift */, - DE1F1A222A8B50D500A88DD8 /* BoxViewModel.swift */, + DE4408142A92750D0091937A /* keyDown+BoxViewController.swift */, ); name = Main; sourceTree = ""; }; + DE4407F82A923E5B0091937A /* FunctionButton */ = { + isa = PBXGroup; + children = ( + DE4407FC2A923E920091937A /* View */, + DE4407F92A923E860091937A /* BoxFunctionViewController.swift */, + ); + path = FunctionButton; + sourceTree = ""; + }; + DE4407FC2A923E920091937A /* View */ = { + isa = PBXGroup; + children = ( + DE44081C2A928F760091937A /* TopDivider.swift */, + DE4407FD2A923EA90091937A /* PreferenceButtonView.swift */, + DE4408012A923EB60091937A /* PinButtonView.swift */, + DE4408042A923EC00091937A /* QuitButtonView.swift */, + DE4408072A9240300091937A /* BoxFunctionButtonView.swift */, + DE44080B2A924B520091937A /* BoxFunctionViewGroup.swift */, + ); + path = View; + sourceTree = ""; + }; + DE4408202A9297EE0091937A /* View */ = { + isa = PBXGroup; + children = ( + DE1F1A1B2A8B50C500A88DD8 /* BoxButtonViewGroup.swift */, + DE1F1A1A2A8B50C500A88DD8 /* BoxContentsViewGroup.swift */, + DE24E6372A8FE10300E29F5D /* BoxBaseSplitView.swift */, + ); + name = View; + path = Box/View; + sourceTree = ""; + }; DE77BA542A82636500713683 /* Shared */ = { isa = PBXGroup; children = ( @@ -265,8 +355,8 @@ DEB862D22A8511D600278FCD /* Scripts */ = { isa = PBXGroup; children = ( - DEB862DE2A85348600278FCD /* sh */, DEB862DB2A85347400278FCD /* Scripts.swift */, + DE0A917A2A8F0CA800D1D6F1 /* AppleScripts+ShowMessage.swift */, ); path = Scripts; sourceTree = ""; @@ -298,6 +388,7 @@ DE874F5E2A5935CC00FC3B77 /* String.swift */, DEF749312A85657600D987C8 /* NSScreen.swift */, DE1F1A302A8BD68F00A88DD8 /* Double.swift */, + DE24E63A2A8FE93900E29F5D /* NSImage.swift */, ); path = Extensions; sourceTree = ""; @@ -382,40 +473,57 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + DE0A91A72A8FC66600D1D6F1 /* SideBarLeading.swift in Sources */, + DE0A917B2A8F0CA800D1D6F1 /* AppleScripts+ShowMessage.swift in Sources */, DE1F1A262A8B50D500A88DD8 /* BoxViewController.swift in Sources */, DE018BB82A5099F900FF0AA3 /* Box42.xcdatamodeld in Sources */, DE874F542A591F1400FC3B77 /* PreferencesView.swift in Sources */, + DE0A91982A8F977F00D1D6F1 /* ToolbarViewController.swift in Sources */, + DE4408082A9240300091937A /* BoxFunctionButtonView.swift in Sources */, DE77BA562A82637900713683 /* StateManager.swift in Sources */, DE1F1A1C2A8B50C500A88DD8 /* BoxBaseContainerViewController.swift in Sources */, - DE018BF62A509B3600FF0AA3 /* MenubarView.swift in Sources */, DE018BE72A509B1E00FF0AA3 /* WebViewController.swift in Sources */, + DE4407FA2A923E860091937A /* BoxFunctionViewController.swift in Sources */, + DE4407FE2A923EA90091937A /* PreferenceButtonView.swift in Sources */, DEF749322A85657600D987C8 /* NSScreen.swift in Sources */, DE018BF02A509B2F00FF0AA3 /* MenubarViewController.swift in Sources */, DE77BA512A82580400713683 /* MenubarViewModel.swift in Sources */, + DE44080C2A924B520091937A /* BoxFunctionViewGroup.swift in Sources */, DE018BE42A509B1700FF0AA3 /* CPU.swift in Sources */, DE874F5F2A5935CC00FC3B77 /* String.swift in Sources */, + DE0A91862A8F889F00D1D6F1 /* RefreshPageViaToolbar.swift in Sources */, DE874F4E2A591DEA00FC3B77 /* Hotkey.swift in Sources */, - DE1F1A252A8B50D500A88DD8 /* BoxViewModel.swift in Sources */, + DE0A91832A8F889000D1D6F1 /* GoHomePageViaToolbar().swift in Sources */, DE018BB32A5099F900FF0AA3 /* AppDelegate.swift in Sources */, DE0A91632A8E6A5400D1D6F1 /* Constants.swift in Sources */, + DE0A91902A8F88CA00D1D6F1 /* DisplayURLInToolbar.swift in Sources */, DE018BF32A509B3300FF0AA3 /* MenubarModel.swift in Sources */, DE7A257A2A6D8CA20043225A /* PreferencesViewController.swift in Sources */, + DE24E63B2A8FE93900E29F5D /* NSImage.swift in Sources */, DE0A916D2A8E7DD700D1D6F1 /* HoverButton.swift in Sources */, - DE1F1A242A8B50D500A88DD8 /* BoxButtonHandler.swift in Sources */, - DE0A91672A8E6CA700D1D6F1 /* WebViewList.swift in Sources */, + DE4408022A923EB60091937A /* PinButtonView.swift in Sources */, + DE0A91672A8E6CA700D1D6F1 /* WebViewManager.swift in Sources */, + DE4408152A92750D0091937A /* keyDown+BoxViewController.swift in Sources */, DE018BED2A509B2600FF0AA3 /* URLModel.swift in Sources */, + DE4408052A923EC00091937A /* QuitButtonView.swift in Sources */, + DE0A918A2A8F88A900D1D6F1 /* GoForwardInToolbar.swift in Sources */, DE1F1A1E2A8B50C500A88DD8 /* BoxButtonViewGroup.swift in Sources */, DEB862EB2A853F7F00278FCD /* BoxWindowController.swift in Sources */, + DE0A918D2A8F88BC00D1D6F1 /* GoBackInToolbar.swift in Sources */, DE018BDD2A509AEB00FF0AA3 /* EventMonitor.swift in Sources */, DE1F1A292A8B50E200A88DD8 /* BoxSizeManager.swift in Sources */, DEB862DC2A85347400278FCD /* Scripts.swift in Sources */, DE1F1A1D2A8B50C500A88DD8 /* BoxContentsViewGroup.swift in Sources */, + DE24E6352A8FE02A00E29F5D /* MovableContainerView.swift in Sources */, DE1F1A362A8BDDDF00A88DD8 /* StorageConfig.swift in Sources */, DE2AD3292A824EEB00002D51 /* Accessibility.swift in Sources */, + DE24E6382A8FE10400E29F5D /* BoxBaseSplitView.swift in Sources */, + DE44081D2A928F760091937A /* TopDivider.swift in Sources */, DE874F572A591F2500FC3B77 /* Icon.swift in Sources */, DE1F1A2E2A8BCC9800A88DD8 /* Storage.swift in Sources */, - DE0A91702A8E8BDE00D1D6F1 /* GradientView.swift in Sources */, + DE0A91782A8F014F00D1D6F1 /* WebView.swift in Sources */, DE1F1A312A8BD68F00A88DD8 /* Double.swift in Sources */, + DE0A917F2A8F865400D1D6F1 /* BoxToolbarViewGroup.swift in Sources */, DE018BEA2A509B2100FF0AA3 /* WebViewModel.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Box42.xcodeproj/xcshareddata/xcschemes/Box42.xcscheme b/Box42.xcodeproj/xcshareddata/xcschemes/Box42.xcscheme new file mode 100644 index 0000000..d8294f7 --- /dev/null +++ b/Box42.xcodeproj/xcshareddata/xcschemes/Box42.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Box42/Box/BoxBaseContainerViewController.swift b/Box42/Box/BoxBaseContainerViewController.swift index dd38da3..538078f 100644 --- a/Box42/Box/BoxBaseContainerViewController.swift +++ b/Box42/Box/BoxBaseContainerViewController.swift @@ -6,114 +6,124 @@ // import Cocoa +import SnapKit class BoxBaseContainerViewController: NSViewController { - var buttonGroup : BoxButtonViewGroup! - var contentGroup : BoxContentsViewGroup! - + var splitView: BoxBaseSplitView! = BoxBaseSplitView() + var contentGroup: BoxContentsViewGroup! = BoxContentsViewGroup() + var toolbarGroup: BoxToolbarViewGroup! = BoxToolbarViewGroup() + var functionGroupVC: BoxFunctionViewController! = BoxFunctionViewController() + var buttonGroup: BoxButtonViewGroup! + var leftContainer: MovableContainerView! + override func loadView() { - self.view = NSView() // 뷰 컨트롤러의 뷰 설정 + self.view = NSView() + self.view.addSubview(splitView) + splitView.delegate = self + buttonGroup = BoxButtonViewGroupInit() - contentGroup = BoxContentsViewGroup() - panGestureInit() + + leftContainerInit() viewInit() } - + func BoxButtonViewGroupInit() -> BoxButtonViewGroup { let buttonGroup = BoxButtonViewGroup { sender in self.clickBtn(sender: sender) } - view.addSubview(buttonGroup) return buttonGroup } - + func clickBtn(sender: NSButton) { guard let clickCount = NSApp.currentEvent?.clickCount else { return } - if sender.title == "Preferences" { - contentGroup.removeAllSubviews() - contentGroup.showPreferences() - return - } if clickCount == 2 { - WebViewList.shared.list[sender.title]!.reload() + WebViewManager.shared.list[sender.title]!.reload() print("Dobule Click") } else if clickCount > 2 { -// let rqURL = URLRequest(url: boxVM.URLdict[sender.title]!) -// WebViewList.shared.list[sender.title]!.load(rqURL) + if let currentURL = WebViewManager.shared.hostingWebView?.url { + NSWorkspace.shared.open(currentURL) + } print("Triple Click") } else if clickCount < 2 { contentGroup.removeAllSubviews() contentGroup.showWebviews(sender) } } + + private func leftContainerInit() { + leftContainer = MovableContainerView() + leftContainer.addSubview(buttonGroup) + leftContainer.addSubview(toolbarGroup) + leftContainer.addSubview(functionGroupVC.view) + leftContainerAutolayout() + leftContainer.frame.size.width = BoxSizeManager.shared.windowButtonGroupSize.width + } - private func panGestureInit() { - let panRecognizer = NSPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:))) - self.view.addGestureRecognizer(panRecognizer) // 뷰 컨트롤러의 뷰에 제스처 추가 + private func leftContainerAutolayout() { + toolbarGroup.snp.makeConstraints { make in + make.top.equalTo(leftContainer).offset(Constants.UI.GroupAutolayout) + make.right.equalTo(leftContainer).offset(-Constants.UI.GroupAutolayout) + make.left.equalTo(leftContainer) + } + + buttonGroup.snp.makeConstraints { make in + make.top.equalTo(toolbarGroup.snp.bottom).offset(Constants.UI.GroupAutolayout) + make.right.equalTo(leftContainer).offset(-Constants.UI.GroupAutolayout) + make.left.equalTo(leftContainer) + } + + functionGroupVC.view.snp.makeConstraints { make in + make.top.equalTo(buttonGroup.snp.bottom).offset(Constants.UI.GroupAutolayout) + make.right.equalTo(leftContainer).offset(-Constants.UI.GroupAutolayout) + make.left.bottom.equalTo(leftContainer) + } } func viewInit() { self.boxViewSizeInit() - self.buttonBoxGroupInit() - self.contentsGroupInit() - // buttonGroup과 contentGroup을 self에 추가합니다. - view.addSubview(buttonGroup) - view.addSubview(contentGroup) - - // buttonGroup 오토레이아웃 설정 - buttonGroup.translatesAutoresizingMaskIntoConstraints = false - NSLayoutConstraint.activate([ - buttonGroup.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), - buttonGroup.topAnchor.constraint(equalTo: self.view.topAnchor), - buttonGroup.bottomAnchor.constraint(equalTo: self.view.bottomAnchor), - buttonGroup.widthAnchor.constraint(equalToConstant: BoxSizeManager.shared.buttonGroupSize.width) - ]) - - // contentGroup 오토레이아웃 설정 - contentGroup.translatesAutoresizingMaskIntoConstraints = false - NSLayoutConstraint.activate([ - contentGroup.leadingAnchor.constraint(equalTo: buttonGroup.trailingAnchor), - contentGroup.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), - contentGroup.topAnchor.constraint(equalTo: self.view.topAnchor), - contentGroup.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) - ]) + splitView.addArrangedSubview(leftContainer) + splitView.addArrangedSubview(contentGroup) + self.view.addSubview(splitView) + + splitView.snp.makeConstraints { make in + make.top.equalTo(self.view).offset(Constants.UI.GroupAutolayout) + make.left.equalTo(self.view).offset(Constants.UI.GroupAutolayout) + make.right.equalTo(self.view).offset(-Constants.UI.GroupAutolayout) + make.bottom.equalTo(self.view).offset(-Constants.UI.GroupAutolayout) + } } - + func boxViewSizeInit() { self.view.frame.size.width = BoxSizeManager.shared.size.width self.view.frame.size.height = BoxSizeManager.shared.size.height } - - func contentsGroupInit() { - self.contentGroup.frame.size.width = BoxSizeManager.shared.size.width - BoxSizeManager.shared.buttonGroupSize.width - self.contentGroup.frame.size.height = BoxSizeManager.shared.size.height - } - - func buttonBoxGroupInit() { - self.buttonGroup.frame.size.width = BoxSizeManager.shared.buttonGroupSize.width - self.buttonGroup.frame.size.height = BoxSizeManager.shared.buttonGroupSize.height - } } -extension BoxBaseContainerViewController { - // 추후 논의. 내부 panGesture로 View크기 증감 - @objc private func handlePanGesture(_ recognizer: NSPanGestureRecognizer) { - guard let view = recognizer.view else { return } - - // 사용자가 드래그한 변화량을 가져옵니다. - let translation = recognizer.translation(in: view) - - // 드래그로 인한 크기 변화를 계산합니다. - let newWidth = view.frame.width + translation.x - let newHeight = view.frame.height + translation.y - - // 크기를 적용합니다. - view.setFrameSize(NSSize(width: newWidth, height: newHeight)) +extension BoxBaseContainerViewController: NSSplitViewDelegate { + func splitView(_ splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat { - // 변화량을 리셋합니다. - recognizer.setTranslation(.zero, in: view) - - print(newWidth, newHeight) + if dividerIndex == 0 { + return 132 + } + return proposedMinimumPosition + } + + func splitView(_ splitView: NSSplitView, constrainMaxCoordinate proposedMaximumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat { + if dividerIndex == 0 { + return 200 + } + return proposedMaximumPosition + } + + func splitView(_ splitView: NSSplitView, resizeSubviewsWithOldSize oldSize: NSSize) { + let dividerThickness = splitView.dividerThickness + let newWidth = splitView.frame.width - dividerThickness + + let leftWidth = leftContainer.frame.width + let contentWidth = newWidth - leftWidth + + leftContainer.frame = NSRect(x: 0, y: 0, width: leftWidth, height: splitView.bounds.height) + contentGroup.frame = NSRect(x: leftWidth + dividerThickness, y: 0, width: contentWidth, height: splitView.bounds.height) } } diff --git a/Box42/Box/BoxButtonViewGroup.swift b/Box42/Box/BoxButtonViewGroup.swift deleted file mode 100644 index 0160c5b..0000000 --- a/Box42/Box/BoxButtonViewGroup.swift +++ /dev/null @@ -1,181 +0,0 @@ -// -// BoxButtonView.swift -// Box42 -// -// Created by Chanhee Kim on 8/11/23. -// - -import Cocoa -import SnapKit - -class BoxButtonViewGroup: NSView { - var boxVM: WebViewModel! = WebViewModel() - var divider : NSBox = NSBox() - var pinSwitch : NSSwitch = NSSwitch() - var clickAction: ((NSButton) -> Void)? - var lastAddedButton: NSView? - var loginInfo: NSView? - - init(clickAction: @escaping (NSButton) -> Void) { - self.clickAction = clickAction - super.init(frame: BoxSizeManager.shared.buttonGroupSizeNSRect) - setupButtons() - divide() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func draw(_ dirtyRect: NSRect) { - // 뷰의 커스텀 렌더링에 사용됨. - } - - private func setupButtons() { - for subview in self.subviews { - subview.removeFromSuperview() - } - - for (name, _) in boxVM.webViewURL.URLstring { - self.createButton(name) - } - createLoginInfo() - preferencesButton() - createQuitButton() - createPinButton() - } - - func createLoginInfo() { - - } - - @objc private func clickBtn(sender: NSButton) { - clickAction?(sender) - } - - private func createButton(_ title: String) { - let button: NSButton - - if title == "home" { - button = NSButton(title: "home", image: NSImage(imageLiteralResourceName: "42box_logo"), target: self, action: #selector(clickBtn(sender:))) - button.imagePosition = .imageOnly - button.isBordered = false - } else { - button = HoverButton() - button.title = title - - button.wantsLayer = true - button.contentTintColor = NSColor.black - button.layer?.borderColor = NSColor.black.cgColor - button.layer?.borderWidth = 1.0 - button.layer?.cornerRadius = 5.0 - button.layer?.opacity = 0.7 - } - super.addSubview(button) - - button.target = self - button.action = #selector(clickBtn(sender:)) - - let fontSize: CGFloat = 16.0 - button.font = NSFont.systemFont(ofSize: fontSize) - button.setButtonType(.momentaryLight) - button.translatesAutoresizingMaskIntoConstraints = false - - button.snp.makeConstraints { make in - make.centerX.equalToSuperview() - make.leading.equalToSuperview().offset(10) - make.trailing.equalToSuperview().offset(-10) - - if title == "home" { - make.height.equalTo(50) - } else { - make.height.equalTo(50) - } - - if let lastButton = lastAddedButton { - make.top.equalTo(lastButton.snp.bottom).offset(10) - } else { - make.top.equalToSuperview().offset(10) - } - } - - lastAddedButton = button - } - - func createQuitButton() { - let button = NSButton() - button.title = "Quit Box" - button.setButtonType(.momentaryLight) - - button.translatesAutoresizingMaskIntoConstraints = false - button.action = #selector(NSApplication.terminate(_:)) - button.isBordered = true - button.bezelStyle = .roundRect - button.showsBorderOnlyWhileMouseInside = true - - self.addSubview(button) - - button.snp.makeConstraints { make in - make.leading.equalToSuperview().offset(20) - make.trailing.equalToSuperview().offset(-20) - make.bottom.equalToSuperview() - } - - lastAddedButton = button // 이 부분 추가 - } - - func createPinButton() { - let button = NSButton() - button.title = "Pin Box" - button.setButtonType(.toggle) - button.contentTintColor = .orange - button.translatesAutoresizingMaskIntoConstraints = false - - button.target = self - button.action = #selector(clickBtn(sender:)) - - button.isBordered = true - button.bezelStyle = .roundRect - button.showsBorderOnlyWhileMouseInside = true - - self.addSubview(button) - - button.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 20).isActive = true - button.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -50).isActive = true - button.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20).isActive = true - } - - func preferencesButton() { - let button = NSButton() - button.title = "Preferences" - button.setButtonType(.momentaryLight) - - button.translatesAutoresizingMaskIntoConstraints = false - - button.target = self - button.action = #selector(clickBtn(sender:)) - - button.isBordered = true - button.bezelStyle = .roundRect - button.showsBorderOnlyWhileMouseInside = true - - self.addSubview(button) - - button.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 20).isActive = true - button.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -90).isActive = true - button.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20).isActive = true - } - - func divide() { - divider.boxType = .separator - divider.translatesAutoresizingMaskIntoConstraints = false - self.addSubview(divider) - NSLayoutConstraint.activate([ - divider.leadingAnchor.constraint(equalTo: self.leadingAnchor), - divider.trailingAnchor.constraint(equalTo: self.trailingAnchor), - divider.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -40), - divider.heightAnchor.constraint(equalToConstant: 1) - ]) - } - -} diff --git a/Box42/Box/View/BoxBaseSplitView.swift b/Box42/Box/View/BoxBaseSplitView.swift new file mode 100644 index 0000000..3def6e3 --- /dev/null +++ b/Box42/Box/View/BoxBaseSplitView.swift @@ -0,0 +1,20 @@ +// +// BoxBaseSplitView.swift +// Box42 +// +// Created by Chanhee Kim on 8/19/23. +// + +import AppKit + +class BoxBaseSplitView: NSSplitView { + init() { + super.init(frame: .zero) + self.isVertical = true + self.dividerStyle = .thick + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/Box42/Box/View/BoxButtonViewGroup.swift b/Box42/Box/View/BoxButtonViewGroup.swift new file mode 100644 index 0000000..44a2299 --- /dev/null +++ b/Box42/Box/View/BoxButtonViewGroup.swift @@ -0,0 +1,92 @@ +// +// BoxButtonView.swift +// Box42 +// +// Created by Chanhee Kim on 8/11/23. +// + +import Cocoa +import SnapKit + +class BoxButtonViewGroup: NSView { + var boxVM: WebViewModel! = WebViewModel() + var pinSwitch : NSSwitch = NSSwitch() + var clickAction: ((NSButton) -> Void)? + var lastAddedButton: NSView? + var loginInfo: NSView? + + init(clickAction: @escaping (NSButton) -> Void) { + self.clickAction = clickAction + super.init(frame: BoxSizeManager.shared.buttonGroupSizeNSRect) + setupButtons() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func draw(_ dirtyRect: NSRect) { + // 뷰의 커스텀 렌더링에 사용됨. + } + + private func setupButtons() { + for subview in self.subviews { + subview.removeFromSuperview() + } + + for (name, _) in boxVM.webViewURL.URLstring { + self.createButton(name) + } + } + @objc private func clickBtn(sender: NSButton) { + clickAction?(sender) + } + + private func createButton(_ title: String) { + let button: NSButton + + if title == "home" { + button = NSButton(title: "home", image: NSImage(imageLiteralResourceName: "42box_logo"), target: self, action: #selector(clickBtn(sender:))) + button.imagePosition = .imageOnly + button.isBordered = false + } else { + button = HoverButton() + button.title = title + + button.wantsLayer = true + button.contentTintColor = NSColor.black + button.layer?.borderColor = NSColor.black.cgColor + button.layer?.borderWidth = 1.0 + button.layer?.cornerRadius = 5.0 + button.layer?.opacity = 0.7 + } + super.addSubview(button) + + button.target = self + button.action = #selector(clickBtn(sender:)) + + let fontSize: CGFloat = 16.0 + button.font = NSFont.systemFont(ofSize: fontSize) + button.setButtonType(.momentaryLight) + button.translatesAutoresizingMaskIntoConstraints = false + + button.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.leading.equalToSuperview().offset(10) + make.trailing.equalToSuperview().offset(-10) + + if title == "home" { + make.height.equalTo(50) + } else { + make.height.equalTo(50) + } + + if let lastButton = lastAddedButton { + make.top.equalTo(lastButton.snp.bottom).offset(10) + } else { + make.top.equalToSuperview().offset(10) + } + } + lastAddedButton = button + } +} diff --git a/Box42/Box/BoxContentsViewGroup.swift b/Box42/Box/View/BoxContentsViewGroup.swift similarity index 62% rename from Box42/Box/BoxContentsViewGroup.swift rename to Box42/Box/View/BoxContentsViewGroup.swift index 78c9b96..215d0ce 100644 --- a/Box42/Box/BoxContentsViewGroup.swift +++ b/Box42/Box/View/BoxContentsViewGroup.swift @@ -5,22 +5,28 @@ // Created by Chanhee Kim on 8/13/23. // -import Cocoa import WebKit +import SnapKit class BoxContentsViewGroup: NSView { var webVC: WebViewController? - var webView: WKWebView! var preferencesVC = PreferencesViewController() init() { - let webVC = WebViewController(nibName: nil, bundle: nil) + webVC = WebViewController(nibName: nil, bundle: nil) super.init(frame: NSRect(x: 0, y: 0, width: BoxSizeManager.shared.size.width - BoxSizeManager.shared.buttonGroupSize.width, height: BoxSizeManager.shared.buttonGroupSize.height)) + self.frame.size.width = BoxSizeManager.shared.size.width - BoxSizeManager.shared.buttonGroupSize.width + self.frame.size.height = BoxSizeManager.shared.size.height + self.wantsLayer = true - webVC.view.frame = self.bounds - self.addSubview(webVC.view) + self.addSubview(webVC!.view) + + webVC?.view.translatesAutoresizingMaskIntoConstraints = false + webVC?.view.snp.makeConstraints { make in + make.edges.equalTo(self) + } } required init?(coder: NSCoder) { @@ -44,25 +50,26 @@ class BoxContentsViewGroup: NSView { } func showWebviews(_ sender: NSButton) { - guard let currentWebview = WebViewList.shared.list[sender.title] else { + guard let currentWebview = WebViewManager.shared.list[sender.title] else { print("No WebView found for title: \(sender.title)") return } + + WebViewManager.shared.hostingname = sender.title + WebViewManager.shared.hostingWebView = currentWebview - currentWebview.frame = self.bounds // WebView의 크기 및 위치 설정 self.addSubview(currentWebview) - // WebView 설정 - currentWebview.configuration.preferences.javaScriptCanOpenWindowsAutomatically = true - currentWebview.configuration.preferences.javaScriptEnabled = true + currentWebview.snp.makeConstraints { make in + make.edges.equalTo(self) + } - // WebView 내용 로드 확인 (옵셔널) if currentWebview.url == nil { print("WebView for \(sender.title) has no content loaded.") } currentWebview.viewDidMoveToSuperview() + currentWebview.becomeFirstResponder() } } - diff --git a/Box42/Extensions/NSImage.swift b/Box42/Extensions/NSImage.swift new file mode 100644 index 0000000..602020e --- /dev/null +++ b/Box42/Extensions/NSImage.swift @@ -0,0 +1,30 @@ +// +// NSImage.swift +// Box42 +// +// Created by Chanhee Kim on 8/19/23. +// + +import Cocoa + +extension NSImage { + func resized(to newSize: CGSize) -> NSImage? { + if let bitmapRepresentation = NSBitmapImageRep( + bitmapDataPlanes: nil, pixelsWide: Int(newSize.width), pixelsHigh: Int(newSize.height), + bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, + colorSpaceName: NSColorSpaceName.deviceRGB, bytesPerRow: 0, bitsPerPixel: 0) { + + bitmapRepresentation.size = newSize + NSGraphicsContext.saveGraphicsState() + NSGraphicsContext.current = NSGraphicsContext(bitmapImageRep: bitmapRepresentation) + self.draw(in: NSRect(x: 0, y: 0, width: newSize.width, height: newSize.height), from: .zero, operation: .copy, fraction: 1.0) + NSGraphicsContext.restoreGraphicsState() + + let resizedImage = NSImage(size: newSize) + resizedImage.addRepresentation(bitmapRepresentation) + return resizedImage + } + + return nil + } +} diff --git a/Box42/FunctionButton/BoxFunctionViewController.swift b/Box42/FunctionButton/BoxFunctionViewController.swift new file mode 100644 index 0000000..a2a482e --- /dev/null +++ b/Box42/FunctionButton/BoxFunctionViewController.swift @@ -0,0 +1,42 @@ +// +// FunctionButtonViewController.swift +// Box42 +// +// Created by Chanhee Kim on 8/20/23. +// + +import Cocoa + +class BoxFunctionViewController: NSViewController { + override func loadView() { + let functionViewGroup = BoxFunctionViewGroup() + + functionViewGroup.preferenceAction = preference + functionViewGroup.pinAction = pin + functionViewGroup.quitAction = quit + functionViewGroup.boxAction = box + + self.view = functionViewGroup + } + + override func viewDidLoad() { + super.viewDidLoad() + } + + func preference() { + print("preference") + } + + func pin() { + print("pin") + } + + func quit() { + print("quit") + NSApplication.shared.terminate(self) + } + + func box() { + print("box") + } +} diff --git a/Box42/FunctionButton/View/BoxFunctionButtonView.swift b/Box42/FunctionButton/View/BoxFunctionButtonView.swift new file mode 100644 index 0000000..01eb568 --- /dev/null +++ b/Box42/FunctionButton/View/BoxFunctionButtonView.swift @@ -0,0 +1,31 @@ +// +// BoxFunctionButtonView.swift +// Box42 +// +// Created by Chanhee Kim on 8/20/23. +// + +import AppKit + +class BoxFunctionButtonView: NSButton { + + private var callback: (() -> Void)? + + init(image: NSImage, completion: @escaping () -> Void) { + super.init(frame: .zero) + + self.image = image + self.bezelStyle = .texturedRounded + self.target = self + self.action = #selector(BoxFunction) + self.callback = completion + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func BoxFunction() { + callback?() + } +} diff --git a/Box42/FunctionButton/View/BoxFunctionViewGroup.swift b/Box42/FunctionButton/View/BoxFunctionViewGroup.swift new file mode 100644 index 0000000..9e5fa88 --- /dev/null +++ b/Box42/FunctionButton/View/BoxFunctionViewGroup.swift @@ -0,0 +1,75 @@ +// +// BoxFunctionViewGroup.swift +// Box42 +// +// Created by Chanhee Kim on 8/20/23. +// + +import AppKit +import SnapKit + +class BoxFunctionViewGroup: NSView { + lazy var preferenceButton: PreferenceButtonView! = PreferenceButtonView(image: NSImage(imageLiteralResourceName: "plus"), completion: { self.preferenceAction?() }) + lazy var pinButton: PinButtonView! = PinButtonView(image: NSImage(imageLiteralResourceName: "pin"), completion: { self.pinAction?() }) + lazy var quitButton: QuitButtonView! = QuitButtonView(image: NSImage(imageLiteralResourceName: "figure.snowboarding"), completion: { self.quitAction?() }) + lazy var boxButton: BoxFunctionButtonView! = BoxFunctionButtonView(image: NSImage(imageLiteralResourceName: "shippingbox"), completion: { self.boxAction?() }) + lazy var divider: NSBox! = TopDivider(completion: { self.dividerAction?() }) + + var preferenceAction: (() -> Void)? + var pinAction: (() -> Void)? + var quitAction: (() -> Void)? + var boxAction: (() -> Void)? + var dividerAction: (() -> Void)? + + override init(frame: NSRect) { + super.init(frame: frame) + setupViews() + setupConstraints() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + setupViews() + setupConstraints() + } + + private func setupViews() { + self.addSubview(preferenceButton) + self.addSubview(pinButton) + self.addSubview(quitButton) + self.addSubview(boxButton) + self.addSubview(divider) + } + + private func setupConstraints() { + divider.snp.makeConstraints { make in + make.top.equalToSuperview() + make.left.right.equalToSuperview() + } + + preferenceButton.snp.makeConstraints { make in + make.top.equalTo(divider).offset(10) + make.bottom.equalToSuperview() + make.left.equalToSuperview() + make.width.equalTo(pinButton) + } + + pinButton.snp.makeConstraints { make in + make.top.bottom.equalTo(preferenceButton) + make.left.equalTo(preferenceButton.snp.right).offset(10) + make.width.equalTo(quitButton) + } + + quitButton.snp.makeConstraints { make in + make.top.bottom.equalTo(preferenceButton) + make.left.equalTo(pinButton.snp.right).offset(10) + make.width.equalTo(boxButton) + } + + boxButton.snp.makeConstraints { make in + make.top.bottom.equalTo(preferenceButton) + make.left.equalTo(quitButton.snp.right).offset(10) + make.right.equalToSuperview() + } + } +} diff --git a/Box42/FunctionButton/View/PinButtonView.swift b/Box42/FunctionButton/View/PinButtonView.swift new file mode 100644 index 0000000..a91036b --- /dev/null +++ b/Box42/FunctionButton/View/PinButtonView.swift @@ -0,0 +1,31 @@ +// +// PinButtonView.swift +// Box42 +// +// Created by Chanhee Kim on 8/20/23. +// + +import AppKit + +class PinButtonView: NSButton { + + private var callback: (() -> Void)? + + init(image: NSImage, completion: @escaping () -> Void) { + super.init(frame: .zero) + + self.image = image + self.bezelStyle = .texturedRounded + self.target = self + self.action = #selector(pin) + self.callback = completion + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func pin() { + callback?() + } +} diff --git a/Box42/FunctionButton/View/PreferenceButtonView.swift b/Box42/FunctionButton/View/PreferenceButtonView.swift new file mode 100644 index 0000000..ffc8102 --- /dev/null +++ b/Box42/FunctionButton/View/PreferenceButtonView.swift @@ -0,0 +1,30 @@ +// +// PreferenceButtonView.swift +// Box42 +// +// Created by Chanhee Kim on 8/20/23. +// + +import AppKit + +class PreferenceButtonView: NSButton { + + private var callback: (() -> Void)? + + init(image: NSImage, completion: @escaping () -> Void) { + super.init(frame: .zero) + self.image = image + self.bezelStyle = .texturedRounded + self.target = self + self.action = #selector(preference) + self.callback = completion + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func preference() { + callback?() + } +} diff --git a/Box42/FunctionButton/View/QuitButtonView.swift b/Box42/FunctionButton/View/QuitButtonView.swift new file mode 100644 index 0000000..aaf9259 --- /dev/null +++ b/Box42/FunctionButton/View/QuitButtonView.swift @@ -0,0 +1,31 @@ +// +// QuitButtonView.swift +// Box42 +// +// Created by Chanhee Kim on 8/20/23. +// + +import AppKit + +class QuitButtonView: NSButton { + + private var callback: (() -> Void)? + + init(image: NSImage, completion: @escaping () -> Void) { + super.init(frame: .zero) + + self.image = image + self.bezelStyle = .texturedRounded + self.target = self + self.action = #selector(QuitButton) + self.callback = completion + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func QuitButton() { + callback?() + } +} diff --git a/Box42/FunctionButton/View/TopDivider.swift b/Box42/FunctionButton/View/TopDivider.swift new file mode 100644 index 0000000..81a39de --- /dev/null +++ b/Box42/FunctionButton/View/TopDivider.swift @@ -0,0 +1,28 @@ +// +// TopDivider.swift +// Box42 +// +// Created by Chanhee Kim on 8/21/23. +// + +import AppKit + +class TopDivider: NSBox { + + private var callback: (() -> Void)? + + init(completion: @escaping () -> Void) { + super.init(frame: .zero) + self.title = "" + self.boxType = .separator + self.callback = completion + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func preference() { + callback?() + } +} diff --git a/Box42/Main/BoxButtonHandler.swift b/Box42/Main/BoxButtonHandler.swift deleted file mode 100644 index 2c5440c..0000000 --- a/Box42/Main/BoxButtonHandler.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// BoxButtonHandler.swift -// Box42 -// -// Created by Chanhee Kim on 8/11/23. -// - -import Cocoa - -class BoxButtonHandler { - func clickBtn(sender: NSButton) {} -// guard let clickCount = NSApp.currentEvent?.clickCount else { return } -// if sender.title == "Preferences" { -//// boxView.contentGroup.subviews.removeAll() -//// boxView.contentGroup.addSubview(preferencesVC.view) -//// preferencesVC.viewDidAppear() -// return -// } -// if clickCount == 2 { -// WebViewList.shared.list[sender.title]!.reload() -// print("Dobule Click") -// } else if clickCount > 2 { -//// let rqURL = URLRequest(url: boxVM.URLdict[sender.title]!) -//// WebViewList.shared.list[sender.title]!.load(rqURL) -// print("Triple Click") -// } else if clickCount < 2 { -//// boxView.contentGroup.subviews.removeAll() -//// boxView.contentGroup.addSubview(WebViewList.shared.list[sender.title]!) -// WebViewList.shared.list[sender.title]!.configuration.preferences.javaScriptCanOpenWindowsAutomatically = true -// WebViewList.shared.list[sender.title]!.configuration.preferences.javaScriptEnabled = true -// WebViewList.shared.list[sender.title]?.viewDidMoveToSuperview() -// } -// } -} diff --git a/Box42/Main/BoxViewController.swift b/Box42/Main/BoxViewController.swift index 3b1ba65..a9692c8 100644 --- a/Box42/Main/BoxViewController.swift +++ b/Box42/Main/BoxViewController.swift @@ -5,15 +5,13 @@ // Created by Chan on 2023/03/16. // -import Cocoa import AppKit import WebKit class BoxViewController: NSViewController { var boxView: BoxBaseContainerViewController! = BoxBaseContainerViewController() - + var gradientLayer: CAGradientLayer! let preferencesVC = PreferencesViewController() - let buttonHandler = BoxButtonHandler() weak var menubarVCDelegate: MenubarViewControllerDelegate? @@ -23,14 +21,34 @@ class BoxViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() - + menubarVCDelegate = (NSApplication.shared.delegate as? AppDelegate)?.menubarController + + self.view.wantsLayer = true + setupGradientLayer() + + NotificationCenter.default.addObserver(self, selector: #selector(boundsDidChange), name: NSWindow.didResizeNotification, object: self.view.window) } + func setupGradientLayer() { + gradientLayer = CAGradientLayer() + gradientLayer.frame = self.view.bounds + let startingColor = NSColor(red: 1.0, green: 0.804, blue: 0.0, alpha: 0.9).cgColor + let endingColor = NSColor(red: 1.0, green: 0.447, blue: 0.0, alpha: 0.7).cgColor + gradientLayer.colors = [startingColor, endingColor] + self.view.layer?.addSublayer(gradientLayer) + } + + @objc func boundsDidChange(notification: NSNotification) { + if let window = notification.object as? NSWindow { + gradientLayer.frame = window.contentView!.bounds + } + } + @objc func doubleClickBtn(sender: NSButton) { - WebViewList.shared.list[sender.title]!.reload() + WebViewManager.shared.list[sender.title]!.reload() } @objc @@ -43,28 +61,3 @@ class BoxViewController: NSViewController { print(message.name) } } - -extension BoxViewController { - override func keyDown(with event: NSEvent) { - print(event.keyCode) - if event.keyCode == 1 { - StorageConfig.shared.setThreshold(.percentage50) - StorageConfig.shared.setPeriod(.period10s) - } - if event.keyCode == 2 { -// SdtorageConfig.shared.setThreshold(.percentage30) - DispatchQueue.main.async { - StorageConfig.shared.setThreshold(.percentage30) - } - StorageConfig.shared.setPeriod(.period1s) - } - - - if event.keyCode == 53 { // Escape 키의 keyCode는 53입니다. - print("escape") - menubarVCDelegate?.toggleWindow(sender: nil) - } else { - super.keyDown(with: event) // 기타 키를 처리하기 위해 상위 클래스에게 전달 - } - } -} diff --git a/Box42/Main/BoxViewModel.swift b/Box42/Main/BoxViewModel.swift deleted file mode 100644 index 3ae31fd..0000000 --- a/Box42/Main/BoxViewModel.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// URLViewModel.swift -// Box42 -// -// Created by Chanhee Kim on 8/9/23. -// - -import Foundation -import Combine - -// CRUD 4가지 형태의 데이터 가공 create, read, update, delete -class BoxViewModel: ObservableObject { - // Box View Model은 전체적인 View Model을 담당하게 될것. -} diff --git a/Box42/Main/keyDown+BoxViewController.swift b/Box42/Main/keyDown+BoxViewController.swift new file mode 100644 index 0000000..63b89e2 --- /dev/null +++ b/Box42/Main/keyDown+BoxViewController.swift @@ -0,0 +1,33 @@ +// +// keyDown+BoxViewController.swift +// Box42 +// +// Created by Chanhee Kim on 8/21/23. +// + +import AppKit + +extension BoxViewController { + override func keyDown(with event: NSEvent) { + print(event.keyCode) + if event.keyCode == 1 { + StorageConfig.shared.setThreshold(.percentage50) + StorageConfig.shared.setPeriod(.period10s) + } + if event.keyCode == 2 { + // SdtorageConfig.shared.setThreshold(.percentage30) + DispatchQueue.main.async { + StorageConfig.shared.setThreshold(.percentage30) + } + StorageConfig.shared.setPeriod(.period1s) + } + + + if event.keyCode == 53 { // Escape 키의 keyCode는 53입니다. + print("escape") + menubarVCDelegate?.toggleWindow(sender: nil) + } else { + super.keyDown(with: event) // 기타 키를 처리하기 위해 상위 클래스에게 전달 + } + } +} diff --git a/Box42/Menubar/MenubarView.swift b/Box42/Menubar/MenubarView.swift deleted file mode 100644 index 7a0e63a..0000000 --- a/Box42/Menubar/MenubarView.swift +++ /dev/null @@ -1,13 +0,0 @@ -// -// MenubarView.swift -// Box42 -// -// Created by Chan on 2023/03/16. -// - -import Foundation -import AppKit - -class MenuBarView { - -} diff --git a/Box42/Menubar/MenubarViewController.swift b/Box42/Menubar/MenubarViewController.swift index de28917..2cb1a3f 100644 --- a/Box42/Menubar/MenubarViewController.swift +++ b/Box42/Menubar/MenubarViewController.swift @@ -11,7 +11,6 @@ import AppKit class MenubarViewController: NSWorkspace { var popover = NSPopover() var statusBarVM = StatusBarViewModel() - let menuBarView = MenuBarView() lazy var eventMonitor: EventMonitor = self.setupEventMonitor() var boxWindowController: BoxWindowController? @@ -116,7 +115,7 @@ extension MenubarViewController: MenubarViewControllerDelegate { let window = boxWindowController?.window { if StateManager.shared.getIsShowFirstWindow() == false { let buttonFrame = button.window?.convertToScreen(button.frame) ?? NSZeroRect - let desiredPosition = NSPoint(x: buttonFrame.origin.x, y: buttonFrame.origin.y - window.frame.height) + let desiredPosition = NSPoint(x: buttonFrame.origin.x - (BoxSizeManager.shared.size.width / 2) - 10, y: buttonFrame.origin.y - window.frame.height) window.setFrameOrigin(desiredPosition) StateManager.shared.setToggleIsShowFirstWindow() diff --git a/Box42/Preferences/PreferencesViewController.swift b/Box42/Preferences/PreferencesViewController.swift index 786e21d..6604203 100644 --- a/Box42/Preferences/PreferencesViewController.swift +++ b/Box42/Preferences/PreferencesViewController.swift @@ -104,21 +104,21 @@ class PreferencesViewController: NSViewController { task.standardError = outputPipe - outputPipe.fileHandleForReading.readabilityHandler = { [weak self] fileHandle in - if #available(OSX 10.15.4, *) { - if let data = try? fileHandle.readToEnd(), let output = String(data: data, encoding: .utf8) { - DispatchQueue.main.async { - if let outputView = self?.outputView { - outputView.string += "\(output)" - } else { - print("outputView is nil") - } - } - } - } else { - // Fallback on earlier versions - } - } +// outputPipe.fileHandleForReading.readabilityHandler = { [weak self] fileHandle in +// if #available(OSX 10.15.4, *) { +// if let data = try? fileHandle.readToEnd(), let output = String(data: data, encoding: .utf8) { +// DispatchQueue.main.async { +// if let outputView = self?.outputView { +// outputView.string += "\(output)" +// } else { +// print("outputView is nil") +// } +// } +// } +// } else { +// // Fallback on earlier versions +// } +// } task.launch() diff --git a/Box42/Resources/Assets.xcassets/Icons/Contents.json b/Box42/Resources/Assets.xcassets/Icons/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Box42/Resources/Assets.xcassets/Icons/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/Icons/arrow.clockwise.imageset/Contents.json b/Box42/Resources/Assets.xcassets/Icons/arrow.clockwise.imageset/Contents.json new file mode 100644 index 0000000..e6da493 --- /dev/null +++ b/Box42/Resources/Assets.xcassets/Icons/arrow.clockwise.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "arrow.clockwise@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/Icons/arrow.clockwise.imageset/arrow.clockwise@2x.png b/Box42/Resources/Assets.xcassets/Icons/arrow.clockwise.imageset/arrow.clockwise@2x.png new file mode 100644 index 0000000..be10d0b Binary files /dev/null and b/Box42/Resources/Assets.xcassets/Icons/arrow.clockwise.imageset/arrow.clockwise@2x.png differ diff --git a/Box42/Resources/Assets.xcassets/Icons/arrow.left.imageset/Contents.json b/Box42/Resources/Assets.xcassets/Icons/arrow.left.imageset/Contents.json new file mode 100644 index 0000000..4b93ed1 --- /dev/null +++ b/Box42/Resources/Assets.xcassets/Icons/arrow.left.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "arrow.left@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/Icons/arrow.left.imageset/arrow.left@2x.png b/Box42/Resources/Assets.xcassets/Icons/arrow.left.imageset/arrow.left@2x.png new file mode 100644 index 0000000..dd616af Binary files /dev/null and b/Box42/Resources/Assets.xcassets/Icons/arrow.left.imageset/arrow.left@2x.png differ diff --git a/Box42/Resources/Assets.xcassets/Icons/arrow.right.imageset/Contents.json b/Box42/Resources/Assets.xcassets/Icons/arrow.right.imageset/Contents.json new file mode 100644 index 0000000..483e2db --- /dev/null +++ b/Box42/Resources/Assets.xcassets/Icons/arrow.right.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "arrow.right@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/Icons/arrow.right.imageset/arrow.right@2x.png b/Box42/Resources/Assets.xcassets/Icons/arrow.right.imageset/arrow.right@2x.png new file mode 100644 index 0000000..f3362b8 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/Icons/arrow.right.imageset/arrow.right@2x.png differ diff --git a/Box42/Resources/Assets.xcassets/Icons/doc.on.doc.imageset/Contents.json b/Box42/Resources/Assets.xcassets/Icons/doc.on.doc.imageset/Contents.json new file mode 100644 index 0000000..97e4fcf --- /dev/null +++ b/Box42/Resources/Assets.xcassets/Icons/doc.on.doc.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "doc.on.doc@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/Icons/doc.on.doc.imageset/doc.on.doc@2x.png b/Box42/Resources/Assets.xcassets/Icons/doc.on.doc.imageset/doc.on.doc@2x.png new file mode 100644 index 0000000..5a880b3 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/Icons/doc.on.doc.imageset/doc.on.doc@2x.png differ diff --git a/Box42/Resources/Assets.xcassets/Icons/ellipsis.imageset/Contents.json b/Box42/Resources/Assets.xcassets/Icons/ellipsis.imageset/Contents.json new file mode 100644 index 0000000..849e448 --- /dev/null +++ b/Box42/Resources/Assets.xcassets/Icons/ellipsis.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "ellipsis@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/Icons/ellipsis.imageset/ellipsis@2x.png b/Box42/Resources/Assets.xcassets/Icons/ellipsis.imageset/ellipsis@2x.png new file mode 100644 index 0000000..e027e56 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/Icons/ellipsis.imageset/ellipsis@2x.png differ diff --git a/Box42/Resources/Assets.xcassets/Icons/figure.skating.imageset/Contents.json b/Box42/Resources/Assets.xcassets/Icons/figure.skating.imageset/Contents.json new file mode 100644 index 0000000..99f8ebe --- /dev/null +++ b/Box42/Resources/Assets.xcassets/Icons/figure.skating.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "figure.skating@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/Icons/figure.skating.imageset/figure.skating@2x.png b/Box42/Resources/Assets.xcassets/Icons/figure.skating.imageset/figure.skating@2x.png new file mode 100644 index 0000000..1ddfa0f Binary files /dev/null and b/Box42/Resources/Assets.xcassets/Icons/figure.skating.imageset/figure.skating@2x.png differ diff --git a/Box42/Resources/Assets.xcassets/Icons/figure.snowboarding.imageset/Contents.json b/Box42/Resources/Assets.xcassets/Icons/figure.snowboarding.imageset/Contents.json new file mode 100644 index 0000000..f437f7e --- /dev/null +++ b/Box42/Resources/Assets.xcassets/Icons/figure.snowboarding.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "figure.snowboarding@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/Icons/figure.snowboarding.imageset/figure.snowboarding@2x.png b/Box42/Resources/Assets.xcassets/Icons/figure.snowboarding.imageset/figure.snowboarding@2x.png new file mode 100644 index 0000000..d797233 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/Icons/figure.snowboarding.imageset/figure.snowboarding@2x.png differ diff --git a/Box42/Resources/Assets.xcassets/Icons/figure.surfing.imageset/Contents.json b/Box42/Resources/Assets.xcassets/Icons/figure.surfing.imageset/Contents.json new file mode 100644 index 0000000..faa8a6b --- /dev/null +++ b/Box42/Resources/Assets.xcassets/Icons/figure.surfing.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "figure.surfing@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/Icons/figure.surfing.imageset/figure.surfing@2x.png b/Box42/Resources/Assets.xcassets/Icons/figure.surfing.imageset/figure.surfing@2x.png new file mode 100644 index 0000000..3e6b0e9 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/Icons/figure.surfing.imageset/figure.surfing@2x.png differ diff --git a/Box42/Resources/Assets.xcassets/Icons/minus.imageset/Contents.json b/Box42/Resources/Assets.xcassets/Icons/minus.imageset/Contents.json new file mode 100644 index 0000000..c437350 --- /dev/null +++ b/Box42/Resources/Assets.xcassets/Icons/minus.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "minus@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/Icons/minus.imageset/minus@2x.png b/Box42/Resources/Assets.xcassets/Icons/minus.imageset/minus@2x.png new file mode 100644 index 0000000..2a101f6 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/Icons/minus.imageset/minus@2x.png differ diff --git a/Box42/Resources/Assets.xcassets/Icons/pin.fill.imageset/Contents.json b/Box42/Resources/Assets.xcassets/Icons/pin.fill.imageset/Contents.json new file mode 100644 index 0000000..ff506bf --- /dev/null +++ b/Box42/Resources/Assets.xcassets/Icons/pin.fill.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "pin.fill@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/Icons/pin.fill.imageset/pin.fill@2x.png b/Box42/Resources/Assets.xcassets/Icons/pin.fill.imageset/pin.fill@2x.png new file mode 100644 index 0000000..164fbcf Binary files /dev/null and b/Box42/Resources/Assets.xcassets/Icons/pin.fill.imageset/pin.fill@2x.png differ diff --git a/Box42/Resources/Assets.xcassets/Icons/pin.imageset/Contents.json b/Box42/Resources/Assets.xcassets/Icons/pin.imageset/Contents.json new file mode 100644 index 0000000..832a223 --- /dev/null +++ b/Box42/Resources/Assets.xcassets/Icons/pin.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "pin@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/Icons/pin.imageset/pin@2x.png b/Box42/Resources/Assets.xcassets/Icons/pin.imageset/pin@2x.png new file mode 100644 index 0000000..28b65a3 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/Icons/pin.imageset/pin@2x.png differ diff --git a/Box42/Resources/Assets.xcassets/Icons/plus.imageset/Contents.json b/Box42/Resources/Assets.xcassets/Icons/plus.imageset/Contents.json new file mode 100644 index 0000000..ace344d --- /dev/null +++ b/Box42/Resources/Assets.xcassets/Icons/plus.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "plus@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/Icons/plus.imageset/plus@2x.png b/Box42/Resources/Assets.xcassets/Icons/plus.imageset/plus@2x.png new file mode 100644 index 0000000..3b9f621 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/Icons/plus.imageset/plus@2x.png differ diff --git a/Box42/Resources/Assets.xcassets/Icons/shippingbox.imageset/Contents.json b/Box42/Resources/Assets.xcassets/Icons/shippingbox.imageset/Contents.json new file mode 100644 index 0000000..e79e1f2 --- /dev/null +++ b/Box42/Resources/Assets.xcassets/Icons/shippingbox.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "shippingbox@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/Icons/shippingbox.imageset/shippingbox@2x.png b/Box42/Resources/Assets.xcassets/Icons/shippingbox.imageset/shippingbox@2x.png new file mode 100644 index 0000000..9a0a5b3 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/Icons/shippingbox.imageset/shippingbox@2x.png differ diff --git a/Box42/Resources/Assets.xcassets/Icons/sidebar.leading.imageset/Contents.json b/Box42/Resources/Assets.xcassets/Icons/sidebar.leading.imageset/Contents.json new file mode 100644 index 0000000..0ea6145 --- /dev/null +++ b/Box42/Resources/Assets.xcassets/Icons/sidebar.leading.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "sidebar.leading@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/Icons/sidebar.leading.imageset/sidebar.leading@2x.png b/Box42/Resources/Assets.xcassets/Icons/sidebar.leading.imageset/sidebar.leading@2x.png new file mode 100644 index 0000000..c5c2618 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/Icons/sidebar.leading.imageset/sidebar.leading@2x.png differ diff --git a/Box42/Resources/Info.plist b/Box42/Resources/Info.plist index b61be39..1520f65 100644 --- a/Box42/Resources/Info.plist +++ b/Box42/Resources/Info.plist @@ -2,6 +2,11 @@ + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable diff --git a/Box42/Resources/Main.storyboard b/Box42/Resources/Main.storyboard index 0fece80..f542723 100644 --- a/Box42/Resources/Main.storyboard +++ b/Box42/Resources/Main.storyboard @@ -78,24 +78,36 @@ - + + + + - + + + + + + + + + + - + - + @@ -106,7 +118,7 @@ - + @@ -132,19 +144,326 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Box42/Scripts/sh/brewInGoinfre.sh b/Box42/Resources/sh/brewInGoinfre.sh similarity index 100% rename from Box42/Scripts/sh/brewInGoinfre.sh rename to Box42/Resources/sh/brewInGoinfre.sh diff --git a/Box42/Scripts/sh/cleanCache.sh b/Box42/Resources/sh/cleanCache.sh similarity index 100% rename from Box42/Scripts/sh/cleanCache.sh rename to Box42/Resources/sh/cleanCache.sh diff --git a/Box42/Scripts/sh/exportMacOSInfo.sh b/Box42/Resources/sh/exportMacOSInfo.sh similarity index 100% rename from Box42/Scripts/sh/exportMacOSInfo.sh rename to Box42/Resources/sh/exportMacOSInfo.sh diff --git a/Box42/Scripts/sh/importMacOSInfo.sh b/Box42/Resources/sh/importMacOSInfo.sh similarity index 100% rename from Box42/Scripts/sh/importMacOSInfo.sh rename to Box42/Resources/sh/importMacOSInfo.sh diff --git a/Box42/Scripts/sh/keyMapping.sh b/Box42/Resources/sh/keyMapping.sh similarity index 100% rename from Box42/Scripts/sh/keyMapping.sh rename to Box42/Resources/sh/keyMapping.sh diff --git a/Box42/Scripts/sh/nodeInstall.sh b/Box42/Resources/sh/nodeInstall.sh similarity index 100% rename from Box42/Scripts/sh/nodeInstall.sh rename to Box42/Resources/sh/nodeInstall.sh diff --git a/Box42/Scripts/AppleScripts+ShowMessage.swift b/Box42/Scripts/AppleScripts+ShowMessage.swift new file mode 100644 index 0000000..3a7411b --- /dev/null +++ b/Box42/Scripts/AppleScripts+ShowMessage.swift @@ -0,0 +1,42 @@ +// +// AppleScripts+ShowMessage.swift +// Box42 +// +// Created by Chanhee Kim on 8/18/23. +// + +import Foundation +import AppKit + +func showMessageWithAppleScript(_ message: String) { + let appleScript = """ + display dialog "\(message)" buttons {"OK"} default button "OK" + """ + + var error: NSDictionary? + if let scriptObject = NSAppleScript(source: appleScript) { + scriptObject.executeAndReturnError(&error) + if let error = error { + print("AppleScript Error: \(error)") + } + } +} + +func showMessageWithAppleScript(_ message: String, _ button: String, completion: @escaping (String?) -> Void) { + let appleScript = """ + display dialog "\(message)" buttons {"\(button)", "취소"} default button "\(button)" + """ + + var error: NSDictionary? + if let scriptObject = NSAppleScript(source: appleScript) { + let output = scriptObject.executeAndReturnError(&error) + let buttonReturned = output.forKeyword(keyDirectObject) + print("output", output.description) +// completion(output.stringValue) + completion(buttonReturned?.stringValue) + if let error = error { + print("AppleScript Error: \(error)") + completion(nil) + } + } +} diff --git a/Box42/Shared/BoxSizeManager.swift b/Box42/Shared/BoxSizeManager.swift index ed665bf..acd32f4 100644 --- a/Box42/Shared/BoxSizeManager.swift +++ b/Box42/Shared/BoxSizeManager.swift @@ -13,18 +13,22 @@ struct BoxSizeManager { var halfSize: (width: CGFloat, height: CGFloat)! var size: (width: CGFloat, height: CGFloat)! var buttonGroupSize: (width: CGFloat, height: CGFloat)! + var toolbarGroupSize: (width: CGFloat, height: CGFloat)! var viewStack: [NSView?] var boxViewSizeNSRect: NSRect var boxViewSizeNSSize: NSSize var buttonGroupSizeNSRect: NSRect + var windowButtonGroupSize: (width: CGFloat, height: CGFloat)! init() { halfSize = (NSScreen.halfOfScreen.x, NSScreen.halfOfScreen.y) size = (NSScreen.customScreenSize.x, NSScreen.customScreenSize.y) buttonGroupSize = (CGFloat(132), NSScreen.customScreenSize.y) + toolbarGroupSize = (CGFloat(132), CGFloat(100)) viewStack = [NSView()] boxViewSizeNSRect = NSRect(x: 0, y: 0, width: size.width, height: size.height) boxViewSizeNSSize = NSSize(width: size.width, height: size.height) buttonGroupSizeNSRect = NSRect(x: 0, y: 0, width: buttonGroupSize.width, height: buttonGroupSize.height) + windowButtonGroupSize = (CGFloat(200), NSScreen.customScreenSize.y) } } diff --git a/Box42/Shared/Constants.swift b/Box42/Shared/Constants.swift index 3e4ff73..322faa9 100644 --- a/Box42/Shared/Constants.swift +++ b/Box42/Shared/Constants.swift @@ -10,4 +10,8 @@ struct Constants { static let InitialName = "home" static let InitialPage = "https://42box.github.io/front-end/" } + + struct UI { + static let GroupAutolayout = 12 + } } diff --git a/Box42/Shared/StateManager.swift b/Box42/Shared/StateManager.swift index 0e8ca1d..e73da57 100644 --- a/Box42/Shared/StateManager.swift +++ b/Box42/Shared/StateManager.swift @@ -12,12 +12,14 @@ class StateManager { private var isShowCPUUsage: Bool! private var isShowWindow: Bool! private var isShowFirstWindow: Bool! + private var isAutoStorage: Bool! private init() { isPin = false isShowCPUUsage = false isShowWindow = false isShowFirstWindow = false + isAutoStorage = true } func getIsPin() -> Bool { @@ -51,4 +53,16 @@ class StateManager { func setToggleIsShowFirstWindow() { isShowFirstWindow.toggle() } + + func getIsAutoStorage() -> Bool { + return isAutoStorage + } + + func setOffIsAutoStorage() { + isAutoStorage = false + } + + func setOnIsAutoStorage() { + isAutoStorage = true + } } diff --git a/Box42/System/Storage.swift b/Box42/System/Storage.swift index 8c55f25..4024446 100644 --- a/Box42/System/Storage.swift +++ b/Box42/System/Storage.swift @@ -54,6 +54,11 @@ class Storage { func storageTimerEvent(){ storageTimer?.invalidate() + + if StateManager.shared.getIsAutoStorage() == false { + return + } + storageTimer = Timer.scheduledTimer(withTimeInterval: config.period.rawValue, repeats: true, block: { [weak self] _ in guard let self = self else { return } @@ -63,11 +68,33 @@ class Storage { } if let usedUsage = self.usedUsage, let totalUsage = self.totalUsage, totalUsage != 0 { - let usagePercentage = usedUsage / totalUsage + let usagePercentage = (totalUsage - usedUsage) / totalUsage if usagePercentage < self.config.threshold.rawValue { self.cleanSh() self.count += 1 - print(self.count > 5 ? "캐시 문제가 아닙니다. ncdu ~ 를 확인해주세요." : "\(usedUsage.roundedToTwoDecimalPlaces) GB", "Storage used is less than 30%") + if self.count > 2 { +// showMessageWithAppleScript("캐시 문제가 아닙니다. ncdu ~ 를 확인해주세요.", "재시작") { button in +// print("timer") +// dump(button) +// if let button = button { +// switch button { +// case "재시작": +// StateManager.shared.setOnIsAutoStorage() +// print("재시작 버튼을 클릭했습니다.") +// case "취소": +// // 취소 관련 로직 실행 +// print("취소 버튼을 클릭했습니다.") +// default: +// break +// } +// } +// } + StateManager.shared.setOffIsAutoStorage() + // 여기서도 타이머를 중지시켜야 합니다. + self.storageTimer?.invalidate() + } else { + print("\(usedUsage.roundedToTwoDecimalPlaces) GB", "Storage used is less than 30%") + } } else { self.count = 0 } @@ -75,8 +102,10 @@ class Storage { print("Failed to get storage usage details") } }) + storageTimer?.fire() } + func cleanSh() { if let scriptPath = Bundle.main.path(forResource: "cleanCache", ofType: "sh") { diff --git a/Box42/System/StorageConfig.swift b/Box42/System/StorageConfig.swift index 1eec523..002581c 100644 --- a/Box42/System/StorageConfig.swift +++ b/Box42/System/StorageConfig.swift @@ -27,7 +27,7 @@ class StorageConfig: ObservableObject { @Published var threshold: StorageThreshold @Published var period: StoragePeriod - init(_ threshold: StorageThreshold = .percentage05, _ period: StoragePeriod = .period3s) { + init(_ threshold: StorageThreshold = .percentage30, _ period: StoragePeriod = .period3s) { self.threshold = threshold self.period = period } diff --git a/Box42/Toolbar/ToolbarViewController.swift b/Box42/Toolbar/ToolbarViewController.swift new file mode 100644 index 0000000..ea32aab --- /dev/null +++ b/Box42/Toolbar/ToolbarViewController.swift @@ -0,0 +1,57 @@ +// +// ToolbarViewController.swift +// Box42 +// +// Created by Chanhee Kim on 8/18/23. +// + +import Cocoa + +class ToolbarViewController: NSViewController { + var displayURL = DisplayURLInToolbar() + var goBackButton: GoBackInToolbar? + var goForwardButton: GoForwardInToolbar? + var reloadPageButton: ReloadPageViaToolbar? + var goHomePageViaButton: GoHomePageViaToolbar? + var sidebarLeading: SideBarLeading? + + override func loadView() { + displayURL = DisplayURLInToolbar() + sidebarLeading = SideBarLeading(image: NSImage(imageLiteralResourceName: "sidebar.leading"), completion: sidebar) + goBackButton = GoBackInToolbar(image: NSImage(imageLiteralResourceName: "arrow.left"), completion: goBack) + goForwardButton = GoForwardInToolbar(image: NSImage(imageLiteralResourceName: "arrow.right"), completion: goFoward) + reloadPageButton = ReloadPageViaToolbar(image: NSImage(imageLiteralResourceName: "arrow.clockwise"), completion: reloadPage) + goHomePageViaButton = GoHomePageViaToolbar(image: NSImage(imageLiteralResourceName: "figure.skating"), completion: goToHome) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + super.viewDidLoad() + // Do view setup here. + } + + func sidebar() { + print("sidebar") + } + + func goBack() { + WebViewManager.shared.hostingWebView?.goBack() + } + + func goFoward() { + WebViewManager.shared.hostingWebView?.goForward() + } + + func reloadPage() { + WebViewManager.shared.hostingWebView?.reload() + } + + func goToHome() { + if let item = WebViewManager.shared.hostingWebView?.backForwardList.backList.first { + WebViewManager.shared.hostingWebView?.go(to: item) + } + } +} diff --git a/Box42/Toolbar/View/BoxToolbarViewGroup.swift b/Box42/Toolbar/View/BoxToolbarViewGroup.swift new file mode 100644 index 0000000..ac17e8c --- /dev/null +++ b/Box42/Toolbar/View/BoxToolbarViewGroup.swift @@ -0,0 +1,31 @@ +// +// BoxToolbarViewGroup.swift +// Box42 +// +// Created by Chanhee Kim on 8/18/23. +// + +import AppKit +import SnapKit + +class BoxToolbarViewGroup: NSView { + var toolbarVC: ToolbarViewController? + + init() { +// toolbarVC = ToolbarViewController(nibName: nil, bundle: nil) + + super.init(frame: NSRect(x: 0, y: 0, width: BoxSizeManager.shared.size.width - BoxSizeManager.shared.toolbarGroupSize.width, height: BoxSizeManager.shared.toolbarGroupSize.height)) + + self.wantsLayer = true +// self.addSubview(toolbarVC!.view) + + toolbarVC?.view.translatesAutoresizingMaskIntoConstraints = false + toolbarVC?.view.snp.makeConstraints { make in + make.edges.equalTo(self) + } + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/Box42/Toolbar/View/DisplayURLInToolbar.swift b/Box42/Toolbar/View/DisplayURLInToolbar.swift new file mode 100644 index 0000000..d8026dd --- /dev/null +++ b/Box42/Toolbar/View/DisplayURLInToolbar.swift @@ -0,0 +1,33 @@ +// +// displayURLInToolbar.swift +// Box42 +// +// Created by Chanhee Kim on 8/18/23. +// + +import AppKit + +class DisplayURLInToolbar: NSTextField { + + override init(frame frameRect: NSRect) { + super.init(frame: frameRect) + + self.isEditable = true + self.isBordered = false // 테두리를 제거합니다. + self.backgroundColor = NSColor.clear // 배경색을 투명하게 만듭니다. + + if let url = WebViewManager.shared.hostingWebView?.url { + self.stringValue = url.absoluteString + } + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func updateURL() { + if let url = WebViewManager.shared.hostingWebView?.url { + self.stringValue = url.absoluteString + } + } +} diff --git a/Box42/Toolbar/View/GoBackInToolbar.swift b/Box42/Toolbar/View/GoBackInToolbar.swift new file mode 100644 index 0000000..6bb209f --- /dev/null +++ b/Box42/Toolbar/View/GoBackInToolbar.swift @@ -0,0 +1,31 @@ +// +// GoBackInToolbar.swift +// Box42 +// +// Created by Chanhee Kim on 8/18/23. +// + +import AppKit + +class GoBackInToolbar: NSButton { + + private var callback: (() -> Void)? + + init(image: NSImage, completion: @escaping () -> Void) { + super.init(frame: .zero) + + self.image = image + self.bezelStyle = .texturedRounded + self.target = self + self.action = #selector(goBackWebView) + self.callback = completion + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func goBackWebView() { + callback?() + } +} diff --git a/Box42/Toolbar/View/GoForwardInToolbar.swift b/Box42/Toolbar/View/GoForwardInToolbar.swift new file mode 100644 index 0000000..e5f04fb --- /dev/null +++ b/Box42/Toolbar/View/GoForwardInToolbar.swift @@ -0,0 +1,31 @@ +// +// GoForwardInToolbar.swift +// Box42 +// +// Created by Chanhee Kim on 8/18/23. +// + +import AppKit + +class GoForwardInToolbar: NSButton { + + private var callback: (() -> Void)? + + init(image: NSImage, completion: @escaping () -> Void) { + super.init(frame: .zero) + + self.image = image + self.bezelStyle = .texturedRounded + self.target = self + self.action = #selector(goForwardWebView) + self.callback = completion + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func goForwardWebView() { + callback?() + } +} diff --git a/Box42/Toolbar/View/GoHomePageViaToolbar().swift b/Box42/Toolbar/View/GoHomePageViaToolbar().swift new file mode 100644 index 0000000..2728ff3 --- /dev/null +++ b/Box42/Toolbar/View/GoHomePageViaToolbar().swift @@ -0,0 +1,31 @@ +// +// GoHomePageViaToolbar.swift +// Box42 +// +// Created by Chanhee Kim on 8/18/23. +// + +import AppKit + +class GoHomePageViaToolbar: NSButton { + + private var callback: (() -> Void)? + + init(image: NSImage, completion: @escaping () -> Void) { + super.init(frame: .zero) + + self.image = image + self.bezelStyle = .texturedRounded + self.target = self + self.action = #selector(goToHomePageWebView) + self.callback = completion + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func goToHomePageWebView() { + callback?() + } +} diff --git a/Box42/Toolbar/View/RefreshPageViaToolbar.swift b/Box42/Toolbar/View/RefreshPageViaToolbar.swift new file mode 100644 index 0000000..8be72bc --- /dev/null +++ b/Box42/Toolbar/View/RefreshPageViaToolbar.swift @@ -0,0 +1,31 @@ +// +// ReloadPageViaToolbar.swift +// Box42 +// +// Created by Chanhee Kim on 8/18/23. +// + +import AppKit + +class ReloadPageViaToolbar: NSButton { + + private var callback: (() -> Void)? + + init(image: NSImage, completion: @escaping () -> Void) { + super.init(frame: .zero) + + self.image = image + self.bezelStyle = .texturedRounded + self.target = self + self.action = #selector(reloadWebView) + self.callback = completion + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func reloadWebView() { + callback?() + } +} diff --git a/Box42/Toolbar/View/SideBarLeading.swift b/Box42/Toolbar/View/SideBarLeading.swift new file mode 100644 index 0000000..9849a05 --- /dev/null +++ b/Box42/Toolbar/View/SideBarLeading.swift @@ -0,0 +1,31 @@ +// +// SideBarLeading.swift +// Box42 +// +// Created by Chanhee Kim on 8/18/23. +// + +import AppKit + +class SideBarLeading: NSButton { + + private var callback: (() -> Void)? + + init(image: NSImage, completion: @escaping () -> Void) { + super.init(frame: .zero) + + self.image = image + self.bezelStyle = .texturedRounded + self.target = self + self.action = #selector(sideBarLeading) + self.callback = completion + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func sideBarLeading() { + callback?() + } +} diff --git a/Box42/UI/GradientView.swift b/Box42/UI/GradientView.swift deleted file mode 100644 index 7afd87e..0000000 --- a/Box42/UI/GradientView.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// GradientView.swift -// Box42 -// -// Created by Chanhee Kim on 8/18/23. -// - -import Cocoa - -//layer caching 기법. -//레이어 캐싱: 복잡한 그래픽 연산이 필요한 뷰의 경우 wantsLayer를 true로 설정하고 shouldRasterize 속성을 true로 설정하여 렌더링 결과를 캐시할 수 있습니다. 하지만 이를 과도하게 사용하면 메모리 사용량이 증가할 수 있으므로 주의가 필요합니다. -class GradientView: NSView { - override init(frame frameRect: NSRect) { - super.init(frame: frameRect) - self.setupLayerCaching() - } - - required init?(coder: NSCoder) { - super.init(coder: coder) - self.setupLayerCaching() - } - - private func setupLayerCaching() { - self.wantsLayer = true - self.layer?.shouldRasterize = true - self.layer?.rasterizationScale = self.window?.backingScaleFactor ?? 1.0 - } - - override func draw(_ dirtyRect: NSRect) { - super.draw(dirtyRect) - - let startingColor = NSColor(red: 1.0, green: 0.804, blue: 0.0, alpha: 0.9) - let endingColor = NSColor(red: 1.0, green: 0.447, blue: 0.0, alpha: 0.7) - let gradient = NSGradient(starting: startingColor, ending: endingColor) - gradient?.draw(in: self.bounds, angle: 90) - } -} diff --git a/Box42/UI/MovableContainerView.swift b/Box42/UI/MovableContainerView.swift new file mode 100644 index 0000000..69c4042 --- /dev/null +++ b/Box42/UI/MovableContainerView.swift @@ -0,0 +1,24 @@ +// +// MovableContainerView.swift +// Box42 +// +// Created by Chanhee Kim on 8/19/23. +// + +import AppKit + +class MovableContainerView: NSView { + init() { + super.init(frame: NSRect(x: 0, y: 0, width: 300, height: BoxSizeManager.shared.size.height)) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func mouseDown(with event: NSEvent) { + if let window = self.window { + window.performDrag(with: event) + } + } +} diff --git a/Box42/WebView/URL/URLModel.swift b/Box42/WebView/URL/URLModel.swift index d27e9e3..014f62c 100644 --- a/Box42/WebView/URL/URLModel.swift +++ b/Box42/WebView/URL/URLModel.swift @@ -26,7 +26,8 @@ struct URLModels { // Network logic api call 날려서 받아올 것. let URLstring: [nameUrl] = [ - ("home", "https://42box.github.io/front-end/"), + ("home", "http://42box.kr/"), + ("23Coaltheme", "https://42box.github.io/front-end/"), // ("home", "http://127.0.0.1:3000/"), ("Box 42", "https://42box.github.io/front-end/#/box"), ("Intra 42", "https://intra.42.fr"), diff --git a/Box42/WebView/WebView.swift b/Box42/WebView/WebView.swift new file mode 100644 index 0000000..0e909ad --- /dev/null +++ b/Box42/WebView/WebView.swift @@ -0,0 +1,42 @@ +// +// WebView.swift +// Box42 +// +// Created by Chanhee Kim on 8/18/23. +// + +import WebKit + +class WebView: WKWebView, WKScriptMessageHandler, WKUIDelegate, WKNavigationDelegate { + func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { + print("userContentController") + } + + + init() { + let preferences = WKPreferences() + preferences.javaScriptEnabled = true + preferences.javaScriptCanOpenWindowsAutomatically = true + + let contentController = WKUserContentController() + let configuration = WKWebViewConfiguration() + configuration.preferences = preferences + configuration.userContentController = contentController + + super.init(frame: .zero, configuration: configuration) + + contentController.add(self, name: "box") // Moved after super.init + + self.configuration.preferences.javaScriptCanOpenWindowsAutomatically = true + self.configuration.preferences.javaScriptEnabled = true + self.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs") + + self.uiDelegate = self + self.navigationDelegate = self + self.becomeFirstResponder() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/Box42/WebView/WebViewController.swift b/Box42/WebView/WebViewController.swift index 55991ed..e0d1f02 100644 --- a/Box42/WebView/WebViewController.swift +++ b/Box42/WebView/WebViewController.swift @@ -9,7 +9,7 @@ import Cocoa import WebKit import Combine -class WebViewController: NSViewController, WKScriptMessageHandler, WKUIDelegate, WKNavigationDelegate { +class WebViewController: NSViewController { var URLVM = WebViewModel() var webView: WKWebView! @@ -17,105 +17,59 @@ class WebViewController: NSViewController, WKScriptMessageHandler, WKUIDelegate, var cancellables: Set = [] override func loadView() { - self.webView = addWebView() + self.webView = WebView() self.view = webView - loadWebViewInit() webViewInit() + loadWebviewInit() // bindViewModel() } - func loadWebViewInit() { + func loadWebviewInit() { URLVM.setUpURLdict() - for (key, value) in URLVM.URLdict { - let wkWebView = addWebView() - WebViewList.shared.list[key] = wkWebView - DispatchQueue.main.async { - wkWebView.load(self.URLVM.requestURL(value)) - } - } + loadAllWebview() + } + + func loadWebView(_ name: String, _ url: URL) { + let wkWebView = WebView() + WebViewManager.shared.list[name] = wkWebView + DispatchQueue.main.async { + wkWebView.load(self.URLVM.requestURL(url)) + } } + func loadAllWebview() { + for (name, URL) in URLVM.URLdict { + loadWebView(name, URL) + } + } + func webViewInit() { + WebViewManager.shared.hostingWebView = self.webView DispatchQueue.main.async { self.webView.load(self.URLVM.requestURL(self.URLVM.safeURL())) } } func bindViewModel() { - // Whenever URLdict changes, it will call loadWebViewInit URLVM.$URLdict .sink { [weak self] _ in - self?.loadWebViewInit() + self?.loadAllWebview() } .store(in: &cancellables) } - func addWebView() -> WKWebView { - let preferences = WKPreferences() - preferences.javaScriptEnabled = true - preferences.javaScriptCanOpenWindowsAutomatically = true - - let contentController = WKUserContentController() - contentController.add(self, name: "box") - - let configuration = WKWebViewConfiguration() - configuration.preferences = preferences - configuration.userContentController = contentController - - let webView = WKWebView(frame: .zero, configuration: configuration) - - webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = true - webView.configuration.preferences.javaScriptEnabled = true - - webView.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs") - if #available(macOS 11.0, *) { - webView.configuration.defaultWebpagePreferences.allowsContentJavaScript = true - } - - webView.uiDelegate = self - webView.navigationDelegate = self - return webView - } - override func viewDidLoad() { super.viewDidLoad() } - + func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { print(message.name) } -} - -extension WebViewController { - override func keyDown(with event: NSEvent) { - print(event.keyCode) - - if (event.modifierFlags.contains(.command) && event.charactersIgnoringModifiers == "c") || - (event.modifierFlags.contains(.command) && event.charactersIgnoringModifiers == "ㅊ") { - // 복사 동작 처리 - webView.evaluateJavaScript("document.execCommand('copy')") { (_, error) in - if let error = error { - print("Copy error: \(error)") - } else { - print("Copy success") - } - } - } else if (event.modifierFlags.contains(.command) && event.charactersIgnoringModifiers == "v") || - (event.modifierFlags.contains(.command) && event.charactersIgnoringModifiers == "ㅍ") { - // 붙여넣기 동작 처리 - let pasteboard = NSPasteboard.general - if let pasteString = pasteboard.string(forType: .string) { - let escapedPasteString = pasteString.escapedForJavaScript - webView.evaluateJavaScript("document.execCommand('insertText', false, '\(escapedPasteString)')") { (_, error) in - if let error = error { - print("Paste error: \(error)") - } else { - print("Paste success") - } - } - } - } else { - super.keyDown(with: event) // 기본 키 이벤트 처리 + + func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { + if let url = navigationAction.request.url { + webView.load(URLRequest(url: url)) } + return nil } } diff --git a/Box42/WebView/WebViewList.swift b/Box42/WebView/WebViewManager.swift similarity index 63% rename from Box42/WebView/WebViewList.swift rename to Box42/WebView/WebViewManager.swift index e4535fc..bdf0fe1 100644 --- a/Box42/WebView/WebViewList.swift +++ b/Box42/WebView/WebViewManager.swift @@ -9,8 +9,11 @@ import WebKit typealias WebViewMapping = [String : WKWebView] -class WebViewList { - static let shared = WebViewList() +class WebViewManager { + static let shared = WebViewManager() + + var hostingname: String? + var hostingWebView: WKWebView? var list: WebViewMapping! diff --git a/Box42/Window/BoxWindowController.swift b/Box42/Window/BoxWindowController.swift index 964e402..dc69045 100644 --- a/Box42/Window/BoxWindowController.swift +++ b/Box42/Window/BoxWindowController.swift @@ -7,45 +7,132 @@ import Cocoa -class BoxWindowController: NSWindowController { - var windowInstance: NSWindow! - var gradientView: NSView! - +class BoxWindowController: NSWindowController, NSToolbarDelegate, NSWindowDelegate { + override init(window: NSWindow?) { let contentRect = BoxSizeManager.shared.boxViewSizeNSRect - let styleMask: NSWindow.StyleMask = [.titled, .closable, .resizable, .miniaturizable] - windowInstance = NSWindow(contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false) + let styleMask: NSWindow.StyleMask = [.resizable, .closable, .miniaturizable, .fullSizeContentView, .titled] + + let windowInstance = NSWindow(contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false) + + windowInstance.titlebarAppearsTransparent = true + windowInstance.titleVisibility = .hidden windowInstance.title = "Box" - windowInstance.styleMask.insert(.resizable) windowInstance.isReleasedWhenClosed = false windowInstance.isOpaque = false - - super.init(window: windowInstance) - gradientView = GradientView(frame: contentRect) - + windowInstance.backgroundColor = .clear + windowInstance.isMovableByWindowBackground = true + let boxViewController = BoxViewController(nibName: nil, bundle: nil) windowInstance.contentViewController = boxViewController - windowInstance.contentView?.addSubview(gradientView, positioned: .below, relativeTo: nil) - gradientView.translatesAutoresizingMaskIntoConstraints = false - gradientViewAutoLayout() + + super.init(window: windowInstance) + + windowInstance.delegate = self + + setupToolbar() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } +} + +extension BoxWindowController { + func windowShouldClose(_ sender: NSWindow) -> Bool { +// NSApplication.shared.terminate(self) + StateManager.shared.setToggleIsShowWindow() + return true + } +} + +// MARK: - Toolbar +extension BoxWindowController { + func setupToolbar() { + let toolbar = NSToolbar(identifier: "MainToolbar") + toolbar.delegate = self + toolbar.displayMode = .iconOnly + toolbar.sizeMode = .small + self.window?.toolbar = toolbar + } + + func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] { + return [.group] + } + + func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] { + return [.group, .flexibleSpace, .sidebar, .flexibleSpace, .goBack, .flexibleSpace, .goFoward, .flexibleSpace, .reloadPage, .flexibleSpace, .goToHome] + } + + func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? { + switch itemIdentifier { + case .group: + let groupItem = NSToolbarItemGroup(itemIdentifier: .group) + + let sidebarItem = NSToolbarItem(itemIdentifier: .sidebar) + sidebarItem.label = "Sidebar" + sidebarItem.image = NSImage(named: NSImage.Name("sidebar.leading")) + sidebarItem.action = #selector(toggleSidebar) + sidebarItem.minSize = NSSize(width: 40, height: 40) + sidebarItem.maxSize = NSSize(width: 40, height: 40) + + let goBack = NSToolbarItem(itemIdentifier: .goBack) + goBack.label = "left" + goBack.image = NSImage(named: NSImage.Name("arrow.left")) // 이미지 설정 + goBack.action = #selector(goBackAction) // 해당 action 설정 + + let goFoward = NSToolbarItem(itemIdentifier: .goFoward) + goFoward.label = "right" + goFoward.image = NSImage(named: NSImage.Name("arrow.right")) + goFoward.action = #selector(goFowardAction) + + let reloadPage = NSToolbarItem(itemIdentifier: .reloadPage) + reloadPage.label = "clockwise" + reloadPage.image = NSImage(named: NSImage.Name("arrow.clockwise")) + reloadPage.action = #selector(reloadPageAction) + + let goToHome = NSToolbarItem(itemIdentifier: .goToHome) + goToHome.label = "skating" + goToHome.image = NSImage(named: NSImage.Name("figure.skating")) + goToHome.action = #selector(goToHomeAction) + + groupItem.subitems = [sidebarItem, goBack, goFoward, reloadPage, goToHome] + + return groupItem + + default: + return nil + } + } - override func windowDidLoad() { - super.windowDidLoad() + @objc func toggleSidebar() { + print("sidebar") } - func gradientViewAutoLayout() { - if let contentView = windowInstance.contentView { - NSLayoutConstraint.activate([ - gradientView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), - gradientView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), - gradientView.topAnchor.constraint(equalTo: contentView.topAnchor), - gradientView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor) - ]) + @objc func goBackAction() { + WebViewManager.shared.hostingWebView?.goBack() + } + + @objc func goFowardAction() { + WebViewManager.shared.hostingWebView?.goForward() + } + + @objc func reloadPageAction() { + WebViewManager.shared.hostingWebView?.reload() + } + + @objc func goToHomeAction() { + if let item = WebViewManager.shared.hostingWebView?.backForwardList.backList.first { + WebViewManager.shared.hostingWebView?.go(to: item) } } } + +extension NSToolbarItem.Identifier { + static let sidebar = NSToolbarItem.Identifier(rawValue: "SidebarButton") + static let goBack = NSToolbarItem.Identifier(rawValue: "goBackButton") + static let goFoward = NSToolbarItem.Identifier(rawValue: "goFowardButton") + static let reloadPage = NSToolbarItem.Identifier(rawValue: "reloadPageButton") + static let goToHome = NSToolbarItem.Identifier(rawValue: "goToHomeButton") + static let group = NSToolbarItem.Identifier(rawValue: "ItemGroup") +}