diff --git a/Box42.xcodeproj/project.pbxproj b/Box42.xcodeproj/project.pbxproj index 309678c..6ef337a 100644 --- a/Box42.xcodeproj/project.pbxproj +++ b/Box42.xcodeproj/project.pbxproj @@ -60,28 +60,34 @@ DE4408082A9240300091937A /* BoxFunctionButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4408072A9240300091937A /* BoxFunctionButtonView.swift */; }; DE44080C2A924B520091937A /* BoxFunctionViewGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE44080B2A924B520091937A /* BoxFunctionViewGroup.swift */; }; DE4408152A92750D0091937A /* keyDown+BoxBaseContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4408142A92750D0091937A /* keyDown+BoxBaseContainerViewController.swift */; }; - DE44081D2A928F760091937A /* TopDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE44081C2A928F760091937A /* TopDivider.swift */; }; + DE44081D2A928F760091937A /* Divider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE44081C2A928F760091937A /* Divider.swift */; }; + DE62BE5A2A9BA31700D97E06 /* QuickSlotButtonCollectionViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = DE62BE582A9BA31700D97E06 /* QuickSlotButtonCollectionViewController.xib */; }; + DE62BE672A9BA92E00D97E06 /* QuickSlotButtonViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE7F9D432A9B7A4700F8ACAE /* QuickSlotButtonViewItem.swift */; }; + DE6332E42A9BB8F800DCFAF6 /* QuickSlotButtonCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE62BE312A9B869900D97E06 /* QuickSlotButtonCollectionViewController.swift */; }; + DE6332E82A9BBEF800DCFAF6 /* NotifConst.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE6332E72A9BBEF800DCFAF6 /* NotifConst.swift */; }; + DE6332F22A9BCA2C00DCFAF6 /* QuickSlotScriptsLogicController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE6332F12A9BCA2C00DCFAF6 /* QuickSlotScriptsLogicController.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 */; }; + DE7F9D462A9B7A4700F8ACAE /* QuickSlotButtonViewItem.xib in Resources */ = {isa = PBXBuildFile; fileRef = DE7F9D442A9B7A4700F8ACAE /* QuickSlotButtonViewItem.xib */; }; DE874F4E2A591DEA00FC3B77 /* Hotkey.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE874F4D2A591DEA00FC3B77 /* Hotkey.swift */; }; DE874F542A591F1400FC3B77 /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE874F532A591F1400FC3B77 /* PreferencesView.swift */; }; DE874F572A591F2500FC3B77 /* Icon.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE874F562A591F2500FC3B77 /* Icon.swift */; }; DE874F5F2A5935CC00FC3B77 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE874F5E2A5935CC00FC3B77 /* String.swift */; }; DE97CA692A9A6364001073DE /* PixelConversion+CGFloat.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE97CA682A9A6364001073DE /* PixelConversion+CGFloat.swift */; }; + DE97CA792A9A6F6A001073DE /* QuickSlotHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE97CA782A9A6F6A001073DE /* QuickSlotHeaderView.swift */; }; + DE97CA7C2A9A7199001073DE /* QuickSlotGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE97CA7B2A9A7199001073DE /* QuickSlotGroupView.swift */; }; + DE97CA7F2A9A73A9001073DE /* QuickSlotUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE97CA7E2A9A73A9001073DE /* QuickSlotUI.swift */; }; + DE97CA862A9A7404001073DE /* QuickSlotViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE97CA6E2A9A6EFC001073DE /* QuickSlotViewModel.swift */; }; + DE97CA872A9A7407001073DE /* QuickSlotButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE97CA712A9A6F0D001073DE /* QuickSlotButtonModel.swift */; }; DE98E83B2A98DB6000F8744A /* RotateImage+NSImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE98E83A2A98DB6000F8744A /* RotateImage+NSImage.swift */; }; DE98E8432A98DDFD00F8744A /* QuickSlotViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE98E8422A98DDFD00F8744A /* QuickSlotViewController.swift */; }; - DE98E8472A98DE6D00F8744A /* QuickSlotHorizontalStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE98E8462A98DE6D00F8744A /* QuickSlotHorizontalStackView.swift */; }; - DE98E84B2A98E03800F8744A /* QuickSlotItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE98E84A2A98E03800F8744A /* QuickSlotItem.swift */; }; - DE98E8502A98E06300F8744A /* QuickSlotViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE98E84F2A98E06300F8744A /* QuickSlotViewModel.swift */; }; DE98E8552A98EA7900F8744A /* WindowButtonUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE98E8542A98EA7900F8744A /* WindowButtonUI.swift */; }; DE9DA8142A97F20E001C0D3B /* ButtonGroupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE9DA8132A97F20E001C0D3B /* ButtonGroupViewController.swift */; }; DEB862D42A85124500278FCD /* cleanCache.sh in Resources */ = {isa = PBXBuildFile; fileRef = DEB862D32A85124500278FCD /* cleanCache.sh */; }; DEB862D92A852C4500278FCD /* brewInGoinfre.sh in Resources */ = {isa = PBXBuildFile; fileRef = DEB862D82A852C4500278FCD /* brewInGoinfre.sh */; }; DEB862DC2A85347400278FCD /* Scripts.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEB862DB2A85347400278FCD /* Scripts.swift */; }; DEB862EB2A853F7F00278FCD /* BoxWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEB862E92A853F7F00278FCD /* BoxWindowController.swift */; }; - DEE0FA822A99FC1000085A65 /* QuickSlotCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEE0FA812A99FC1000085A65 /* QuickSlotCollectionView.swift */; }; - DEE0FA8B2A9A0BD500085A65 /* QuickSlotCollectionViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEE0FA842A99FD1100085A65 /* QuickSlotCollectionViewItem.swift */; }; DEE0FA962A9A554F00085A65 /* FunctionButtonUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEE0FA952A9A554F00085A65 /* FunctionButtonUI.swift */; }; DEF749322A85657600D987C8 /* NSScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEF749312A85657600D987C8 /* NSScreen.swift */; }; /* End PBXBuildFile section */ @@ -142,28 +148,34 @@ 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+BoxBaseContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "keyDown+BoxBaseContainerViewController.swift"; path = "Main/keyDown+BoxBaseContainerViewController.swift"; sourceTree = ""; }; - DE44081C2A928F760091937A /* TopDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopDivider.swift; sourceTree = ""; }; + DE44081C2A928F760091937A /* Divider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Divider.swift; sourceTree = ""; }; + DE62BE312A9B869900D97E06 /* QuickSlotButtonCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotButtonCollectionViewController.swift; sourceTree = ""; }; + DE62BE582A9BA31700D97E06 /* QuickSlotButtonCollectionViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = QuickSlotButtonCollectionViewController.xib; sourceTree = ""; }; + DE6332E72A9BBEF800DCFAF6 /* NotifConst.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotifConst.swift; sourceTree = ""; }; + DE6332F12A9BCA2C00DCFAF6 /* QuickSlotScriptsLogicController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotScriptsLogicController.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 = ""; }; + DE7F9D432A9B7A4700F8ACAE /* QuickSlotButtonViewItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotButtonViewItem.swift; sourceTree = ""; }; + DE7F9D442A9B7A4700F8ACAE /* QuickSlotButtonViewItem.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = QuickSlotButtonViewItem.xib; sourceTree = ""; }; DE874F4D2A591DEA00FC3B77 /* Hotkey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Hotkey.swift; sourceTree = ""; }; DE874F532A591F1400FC3B77 /* PreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesView.swift; sourceTree = ""; }; DE874F562A591F2500FC3B77 /* Icon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Icon.swift; sourceTree = ""; }; DE874F5E2A5935CC00FC3B77 /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = ""; }; DE97CA682A9A6364001073DE /* PixelConversion+CGFloat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PixelConversion+CGFloat.swift"; sourceTree = ""; }; + DE97CA6E2A9A6EFC001073DE /* QuickSlotViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotViewModel.swift; sourceTree = ""; }; + DE97CA712A9A6F0D001073DE /* QuickSlotButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotButtonModel.swift; sourceTree = ""; }; + DE97CA782A9A6F6A001073DE /* QuickSlotHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotHeaderView.swift; sourceTree = ""; }; + DE97CA7B2A9A7199001073DE /* QuickSlotGroupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotGroupView.swift; sourceTree = ""; }; + DE97CA7E2A9A73A9001073DE /* QuickSlotUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotUI.swift; sourceTree = ""; }; DE98E83A2A98DB6000F8744A /* RotateImage+NSImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RotateImage+NSImage.swift"; sourceTree = ""; }; DE98E8422A98DDFD00F8744A /* QuickSlotViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotViewController.swift; sourceTree = ""; }; - DE98E8462A98DE6D00F8744A /* QuickSlotHorizontalStackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotHorizontalStackView.swift; sourceTree = ""; }; - DE98E84A2A98E03800F8744A /* QuickSlotItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotItem.swift; sourceTree = ""; }; - DE98E84F2A98E06300F8744A /* QuickSlotViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotViewModel.swift; sourceTree = ""; }; DE98E8542A98EA7900F8744A /* WindowButtonUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowButtonUI.swift; sourceTree = ""; }; DE9DA8132A97F20E001C0D3B /* ButtonGroupViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroupViewController.swift; sourceTree = ""; }; DEB862D32A85124500278FCD /* cleanCache.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = cleanCache.sh; sourceTree = ""; }; DEB862D82A852C4500278FCD /* brewInGoinfre.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = brewInGoinfre.sh; sourceTree = ""; }; DEB862DB2A85347400278FCD /* Scripts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Scripts.swift; path = Box42/Scripts/Scripts.swift; sourceTree = SOURCE_ROOT; }; DEB862E92A853F7F00278FCD /* BoxWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxWindowController.swift; sourceTree = ""; }; - DEE0FA812A99FC1000085A65 /* QuickSlotCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotCollectionView.swift; sourceTree = ""; }; - DEE0FA842A99FD1100085A65 /* QuickSlotCollectionViewItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotCollectionViewItem.swift; sourceTree = ""; }; DEE0FA952A9A554F00085A65 /* FunctionButtonUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FunctionButtonUI.swift; sourceTree = ""; }; DEF7492E2A85603700D987C8 /* nodeInstall.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = nodeInstall.sh; sourceTree = ""; }; DEF749312A85657600D987C8 /* NSScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSScreen.swift; sourceTree = ""; }; @@ -350,7 +362,6 @@ DE4407FC2A923E920091937A /* View */ = { isa = PBXGroup; children = ( - DE44081C2A928F760091937A /* TopDivider.swift */, DE4407FD2A923EA90091937A /* PreferenceButtonView.swift */, DE4408012A923EB60091937A /* PinButtonView.swift */, DE4408042A923EC00091937A /* QuitButtonView.swift */, @@ -369,16 +380,36 @@ path = View; sourceTree = ""; }; + DE62BE632A9BA8CC00D97E06 /* ButtonCollectionView */ = { + isa = PBXGroup; + children = ( + DE62BE312A9B869900D97E06 /* QuickSlotButtonCollectionViewController.swift */, + DE62BE582A9BA31700D97E06 /* QuickSlotButtonCollectionViewController.xib */, + DE7F9D482A9B7A4E00F8ACAE /* Vertical Item */, + ); + path = ButtonCollectionView; + sourceTree = ""; + }; DE77BA542A82636500713683 /* Shared */ = { isa = PBXGroup; children = ( DE1F1A282A8B50E200A88DD8 /* BoxSizeManager.swift */, DE77BA552A82637900713683 /* StateManager.swift */, DE0A91622A8E6A5400D1D6F1 /* Constants.swift */, + DE6332E72A9BBEF800DCFAF6 /* NotifConst.swift */, ); path = Shared; sourceTree = ""; }; + DE7F9D482A9B7A4E00F8ACAE /* Vertical Item */ = { + isa = PBXGroup; + children = ( + DE7F9D432A9B7A4700F8ACAE /* QuickSlotButtonViewItem.swift */, + DE7F9D442A9B7A4700F8ACAE /* QuickSlotButtonViewItem.xib */, + ); + path = "Vertical Item"; + sourceTree = ""; + }; DE874F512A591EC600FC3B77 /* Preferences */ = { isa = PBXGroup; children = ( @@ -405,8 +436,10 @@ DE98E8412A98DDEB00F8744A /* View */ = { isa = PBXGroup; children = ( - DE98E8462A98DE6D00F8744A /* QuickSlotHorizontalStackView.swift */, - DEE0FA812A99FC1000085A65 /* QuickSlotCollectionView.swift */, + DE44081C2A928F760091937A /* Divider.swift */, + DE97CA782A9A6F6A001073DE /* QuickSlotHeaderView.swift */, + DE97CA7B2A9A7199001073DE /* QuickSlotGroupView.swift */, + DE62BE632A9BA8CC00D97E06 /* ButtonCollectionView */, ); path = View; sourceTree = ""; @@ -414,8 +447,8 @@ DE98E8492A98E02400F8744A /* Model */ = { isa = PBXGroup; children = ( - DEE0FA842A99FD1100085A65 /* QuickSlotCollectionViewItem.swift */, - DE98E84A2A98E03800F8744A /* QuickSlotItem.swift */, + DE97CA712A9A6F0D001073DE /* QuickSlotButtonModel.swift */, + DE97CA7E2A9A73A9001073DE /* QuickSlotUI.swift */, ); path = Model; sourceTree = ""; @@ -423,7 +456,7 @@ DE98E84E2A98E04F00F8744A /* ViewModel */ = { isa = PBXGroup; children = ( - DE98E84F2A98E06300F8744A /* QuickSlotViewModel.swift */, + DE97CA6E2A9A6EFC001073DE /* QuickSlotViewModel.swift */, ); path = ViewModel; sourceTree = ""; @@ -481,6 +514,7 @@ isa = PBXGroup; children = ( DE98E8422A98DDFD00F8744A /* QuickSlotViewController.swift */, + DE6332F12A9BCA2C00DCFAF6 /* QuickSlotScriptsLogicController.swift */, ); path = Controller; sourceTree = ""; @@ -575,7 +609,9 @@ DE1F1A152A8B506600A88DD8 /* exportMacOSInfo.sh in Resources */, DE1F1A162A8B506600A88DD8 /* keyMapping.sh in Resources */, DEB862D42A85124500278FCD /* cleanCache.sh in Resources */, + DE7F9D462A9B7A4700F8ACAE /* QuickSlotButtonViewItem.xib in Resources */, DEB862D92A852C4500278FCD /* brewInGoinfre.sh in Resources */, + DE62BE5A2A9BA31700D97E06 /* QuickSlotButtonCollectionViewController.xib in Resources */, DE018BE02A509B0600FF0AA3 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -591,6 +627,7 @@ DE0A91A72A8FC66600D1D6F1 /* SideBarLeading.swift in Sources */, DE0A917B2A8F0CA800D1D6F1 /* AppleScripts+ShowMessage.swift in Sources */, DE018BB82A5099F900FF0AA3 /* Box42.xcdatamodeld in Sources */, + DE62BE672A9BA92E00D97E06 /* QuickSlotButtonViewItem.swift in Sources */, DE874F542A591F1400FC3B77 /* PreferencesView.swift in Sources */, DE98E83B2A98DB6000F8744A /* RotateImage+NSImage.swift in Sources */, DE0A91982A8F977F00D1D6F1 /* ToolbarViewController.swift in Sources */, @@ -598,37 +635,41 @@ DE4408082A9240300091937A /* BoxFunctionButtonView.swift in Sources */, DE3FF3742A978AB8009C88EF /* WindowMaximizeButton.swift in Sources */, DE3FF3A32A97D2A6009C88EF /* DisplayURLTextfield.swift in Sources */, + DE97CA872A9A7407001073DE /* QuickSlotButtonModel.swift in Sources */, DE77BA562A82637900713683 /* StateManager.swift in Sources */, DE1F1A1C2A8B50C500A88DD8 /* BoxBaseContainerViewController.swift in Sources */, DEE0FA962A9A554F00085A65 /* FunctionButtonUI.swift in Sources */, DE018BE72A509B1E00FF0AA3 /* WebViewController.swift in Sources */, DE98E8552A98EA7900F8744A /* WindowButtonUI.swift in Sources */, DE4407FA2A923E860091937A /* BoxFunctionViewController.swift in Sources */, - DE98E8472A98DE6D00F8744A /* QuickSlotHorizontalStackView.swift in Sources */, DE4407FE2A923EA90091937A /* PreferenceButtonView.swift in Sources */, + DE6332E82A9BBEF800DCFAF6 /* NotifConst.swift in Sources */, DEF749322A85657600D987C8 /* NSScreen.swift in Sources */, DE018BF02A509B2F00FF0AA3 /* MenubarViewController.swift in Sources */, + DE6332E42A9BB8F800DCFAF6 /* QuickSlotButtonCollectionViewController.swift in Sources */, DE77BA512A82580400713683 /* MenubarViewModel.swift in Sources */, DE44080C2A924B520091937A /* BoxFunctionViewGroup.swift in Sources */, + DE97CA7C2A9A7199001073DE /* QuickSlotGroupView.swift in Sources */, DE018BE42A509B1700FF0AA3 /* CPU.swift in Sources */, DE874F5F2A5935CC00FC3B77 /* String.swift in Sources */, - DEE0FA822A99FC1000085A65 /* QuickSlotCollectionView.swift in Sources */, DE0A91862A8F889F00D1D6F1 /* RefreshPageViaToolbar.swift in Sources */, DE874F4E2A591DEA00FC3B77 /* Hotkey.swift in Sources */, DE0A91832A8F889000D1D6F1 /* GoHomePageViaToolbar().swift in Sources */, + DE6332F22A9BCA2C00DCFAF6 /* QuickSlotScriptsLogicController.swift in Sources */, DE018BB32A5099F900FF0AA3 /* AppDelegate.swift in Sources */, DE0A91632A8E6A5400D1D6F1 /* Constants.swift in Sources */, DE0A91902A8F88CA00D1D6F1 /* DisplayURLInToolbar.swift in Sources */, - DEE0FA8B2A9A0BD500085A65 /* QuickSlotCollectionViewItem.swift in Sources */, DE018BF32A509B3300FF0AA3 /* MenubarModel.swift in Sources */, - DE98E8502A98E06300F8744A /* QuickSlotViewModel.swift in Sources */, DE7A257A2A6D8CA20043225A /* PreferencesViewController.swift in Sources */, DE24E63B2A8FE93900E29F5D /* NSImage.swift in Sources */, + DE97CA792A9A6F6A001073DE /* QuickSlotHeaderView.swift in Sources */, DE0A916D2A8E7DD700D1D6F1 /* HoverButton.swift in Sources */, + DE97CA862A9A7404001073DE /* QuickSlotViewModel.swift in Sources */, DE3FF3762A978AB8009C88EF /* WindowCloseButton.swift in Sources */, DE3FF3772A978AB8009C88EF /* WindowMinimizeButton.swift in Sources */, DE4408022A923EB60091937A /* PinButtonView.swift in Sources */, DE0A91672A8E6CA700D1D6F1 /* WebViewManager.swift in Sources */, + DE97CA7F2A9A73A9001073DE /* QuickSlotUI.swift in Sources */, DE4408152A92750D0091937A /* keyDown+BoxBaseContainerViewController.swift in Sources */, DE018BED2A509B2600FF0AA3 /* URLModel.swift in Sources */, DE97CA692A9A6364001073DE /* PixelConversion+CGFloat.swift in Sources */, @@ -646,8 +687,7 @@ DE1F1A362A8BDDDF00A88DD8 /* StorageConfig.swift in Sources */, DE2AD3292A824EEB00002D51 /* Accessibility.swift in Sources */, DE24E6382A8FE10400E29F5D /* BoxBaseSplitView.swift in Sources */, - DE44081D2A928F760091937A /* TopDivider.swift in Sources */, - DE98E84B2A98E03800F8744A /* QuickSlotItem.swift in Sources */, + DE44081D2A928F760091937A /* Divider.swift in Sources */, DE98E8432A98DDFD00F8744A /* QuickSlotViewController.swift in Sources */, DE874F572A591F2500FC3B77 /* Icon.swift in Sources */, DE1F1A2E2A8BCC9800A88DD8 /* Storage.swift in Sources */, diff --git a/Box42/BoxWindowController.swift b/Box42/BoxWindowController.swift index fe74981..8acc892 100644 --- a/Box42/BoxWindowController.swift +++ b/Box42/BoxWindowController.swift @@ -18,16 +18,12 @@ class BoxWindowController: NSWindowController, NSWindowDelegate { windowInstance.title = "Box" windowInstance.titlebarAppearsTransparent = true windowInstance.titleVisibility = .hidden - windowInstance.isReleasedWhenClosed = false windowInstance.isMovableByWindowBackground = true + windowInstance.isReleasedWhenClosed = false windowInstance.standardWindowButton(.closeButton)?.isHidden = true windowInstance.standardWindowButton(.miniaturizeButton)?.isHidden = true windowInstance.standardWindowButton(.zoomButton)?.isHidden = true - if let zoomButton = windowInstance.standardWindowButton(.zoomButton) { - zoomButton.isHidden = true - } - let boxViewController = BoxBaseContainerViewController(nibName: nil, bundle: nil) windowInstance.contentViewController = boxViewController } diff --git a/Box42/FunctionButton/Model/FunctionButtonUI.swift b/Box42/FunctionButton/Model/FunctionButtonUI.swift index e5c9522..096fa6b 100644 --- a/Box42/FunctionButton/Model/FunctionButtonUI.swift +++ b/Box42/FunctionButton/Model/FunctionButtonUI.swift @@ -7,17 +7,17 @@ import AppKit -struct FunctionButtonUI { - struct size { +enum FunctionButtonUI { + enum size { static let font: CGFloat = 14 static let pinWidth: CGFloat = 89 static let pinHeight: CGFloat = 27 } - struct animation { + enum animation { } - struct color { + enum color { static let pinText = NSColor(hex: "#696969") } } diff --git a/Box42/FunctionButton/View/BoxFunctionViewGroup.swift b/Box42/FunctionButton/View/BoxFunctionViewGroup.swift index a0e9d49..2e961a0 100644 --- a/Box42/FunctionButton/View/BoxFunctionViewGroup.swift +++ b/Box42/FunctionButton/View/BoxFunctionViewGroup.swift @@ -10,10 +10,9 @@ 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 icon"), completion: { self.pinAction?() }) + lazy var pinButton: PinButtonView = PinButtonView(image: NSImage(imageLiteralResourceName: "pin-box"), 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)? @@ -38,17 +37,11 @@ class BoxFunctionViewGroup: NSView { 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() - } - pinButton.snp.makeConstraints { make in - make.top.equalTo(divider).offset(10) + make.top.equalToSuperview() make.bottom.equalToSuperview() make.left.equalToSuperview() make.width.equalTo(FunctionButtonUI.size.pinWidth) diff --git a/Box42/Main/BoxBaseContainerViewController.swift b/Box42/Main/BoxBaseContainerViewController.swift index 011e26c..de5f5c0 100644 --- a/Box42/Main/BoxBaseContainerViewController.swift +++ b/Box42/Main/BoxBaseContainerViewController.swift @@ -12,7 +12,7 @@ class BoxBaseContainerViewController: NSViewController { var splitView: BoxBaseSplitView = BoxBaseSplitView() var contentGroup: BoxContentsViewGroup = BoxContentsViewGroup() var toolbarGroupVC: ToolbarViewController = ToolbarViewController() - // var quickSlotGroupVC: QuickSlotViewController = QuickSlotViewController() + var quickSlotGroupVC: QuickSlotViewController = QuickSlotViewController() var functionGroupVC: BoxFunctionViewController = BoxFunctionViewController() let windowViewGroupVC: WindowButtonViewController = WindowButtonViewController() var leftContainer: MovableContainerView = MovableContainerView() @@ -76,7 +76,7 @@ class BoxBaseContainerViewController: NSViewController { leftContainer.addSubview(windowViewGroupVC.view) leftContainer.addSubview(buttonGroupVC.view) leftContainer.addSubview(toolbarGroupVC.view) -// leftContainer.addSubview(quickSlotGroupVC.view) + leftContainer.addSubview(quickSlotGroupVC.view) leftContainer.addSubview(functionGroupVC.view) leftContainerAutolayout() @@ -101,15 +101,15 @@ class BoxBaseContainerViewController: NSViewController { make.top.equalTo(toolbarGroupVC.view.snp.bottom).offset(Constants.UI.groupAutolayout) make.right.equalTo(leftContainer).offset(-Constants.UI.groupAutolayout) make.left.equalTo(leftContainer) - make.bottom.equalTo(functionGroupVC.view.snp.top).offset(-Constants.UI.groupAutolayout) + make.bottom.equalTo(quickSlotGroupVC.view.snp.top).offset(-Constants.UI.groupAutolayout) } -// quickSlotGroupVC.view.snp.makeConstraints { make in -// make.bottom.equalTo(functionGroupVC.view.snp.top).offset(-27) -// make.right.equalTo(leftContainer).offset(-Constants.UI.groupAutolayout) -// make.left.equalTo(leftContainer) -// make.height.equalTo(178) -// } + quickSlotGroupVC.view.snp.makeConstraints { make in + make.bottom.equalTo(functionGroupVC.view.snp.top).offset(-27) + make.right.equalTo(leftContainer).offset(-Constants.UI.groupAutolayout) + make.left.equalTo(leftContainer) + make.height.equalTo(178) + } functionGroupVC.view.snp.makeConstraints { make in make.right.equalTo(leftContainer).offset(-Constants.UI.groupAutolayout) diff --git a/Box42/Menubar/MenubarViewController.swift b/Box42/Menubar/MenubarViewController.swift index e9b361c..c62e462 100644 --- a/Box42/Menubar/MenubarViewController.swift +++ b/Box42/Menubar/MenubarViewController.swift @@ -122,7 +122,7 @@ extension MenubarViewController: MenubarViewControllerDelegate { } window.level = .floating } - boxWindowController?.showWindow(sender) + boxWindowController?.showWindow(sender) } } } diff --git a/Box42/Menubar/MenubarViewModel.swift b/Box42/Menubar/MenubarViewModel.swift index b1daf88..9946f07 100644 --- a/Box42/Menubar/MenubarViewModel.swift +++ b/Box42/Menubar/MenubarViewModel.swift @@ -32,6 +32,7 @@ class StatusBarViewModel { case "lee": for i in (1...5) {statusBar.frames.append(NSImage(imageLiteralResourceName: "lee_\(i)"))} case "box": for i in (1...4) {statusBar.frames.append(NSImage(imageLiteralResourceName: "42box_\(i)"))} case "fox": for i in (1...4) {statusBar.frames.append(NSImage(imageLiteralResourceName: "fox_page\(i)"))} + case "sitting_fox": for i in (0...3) {statusBar.frames.append(NSImage(imageLiteralResourceName: "sitting_fox\(i)"))} case "box_oc": for i in (1...2) {statusBar.frames.append(NSImage(imageLiteralResourceName: "42box_oc\(i)"))} default : for i in (1...11) {statusBar.frames.append(NSImage(imageLiteralResourceName: "42flip_0\(i)"))} } diff --git a/Box42/Preferences/PreferencesViewController.swift b/Box42/Preferences/PreferencesViewController.swift index 6604203..5a6c36d 100644 --- a/Box42/Preferences/PreferencesViewController.swift +++ b/Box42/Preferences/PreferencesViewController.swift @@ -141,7 +141,6 @@ class PreferencesViewController: NSViewController { print("Error: \(error)") } } - } } diff --git a/Box42/QuickSlot/Controller/QuickSlotScriptsLogicController.swift b/Box42/QuickSlot/Controller/QuickSlotScriptsLogicController.swift new file mode 100644 index 0000000..1038e76 --- /dev/null +++ b/Box42/QuickSlot/Controller/QuickSlotScriptsLogicController.swift @@ -0,0 +1,57 @@ +// +// QuickSlotScriptsLogicController.swift +// Box42 +// +// Created by Chanhee Kim on 8/28/23. +// + +import AppKit + +class ScriptsLogicController { + + static let shared = ScriptsLogicController() + + private init() { + NotificationCenter.default.addObserver(self, selector: #selector(handleButtonTapped), name: NSNotification.Name(NotifConst.object.collectionButtonTapped), object: nil) + } + + @objc func handleButtonTapped(notification: NSNotification) { + if let button = notification.object as? NSButton { + let buttonTitle = button.title // 메인 스레드에서 타이틀을 캡쳐 + print("Button with title \(buttonTitle) was tapped") + + DispatchQueue.global(qos: .background).async { [weak self] in + if buttonTitle == "clean" { + self?.executeCleanScript() + } + } + } + } + + private func executeCleanScript() { + if let scriptPath = Bundle.main.path(forResource: "cleanCache", ofType: "sh") { + let task = Process() + task.launchPath = "/bin/sh" + task.arguments = [scriptPath] + + let outputPipe = Pipe() + task.standardOutput = outputPipe + task.standardError = outputPipe + + task.launch() + task.waitUntilExit() + + let outputData = outputPipe.fileHandleForReading.readDataToEndOfFile() + let output = String(data: outputData, encoding: .utf8) ?? "" + + DispatchQueue.main.async { + print("Output: \(output)") + } + } else { + DispatchQueue.main.async { + print("Script not found") + } + } + } + +} diff --git a/Box42/QuickSlot/Controller/QuickSlotViewController.swift b/Box42/QuickSlot/Controller/QuickSlotViewController.swift new file mode 100644 index 0000000..177b5f9 --- /dev/null +++ b/Box42/QuickSlot/Controller/QuickSlotViewController.swift @@ -0,0 +1,32 @@ +// +// QuickSlotViewController.swift +// Box42 +// +// Created by Chanhee Kim on 8/25/23. +// + +import AppKit + +class QuickSlotViewController: NSViewController { + var viewModel: QuickSlotViewModel! + var buttonCollectionView: QuickSlotButtonCollectionViewController! + + override func loadView() { + let quickSlotViewGroup = QuickSlotGroupView() + quickSlotViewGroup.headerAction = headerAction + + NotificationCenter.default.addObserver(self, selector: #selector(handleButtonTapped), name: NSNotification.Name(NotifConst.object.collectionButtonTapped), object: nil) + + self.view = quickSlotViewGroup + } + + func headerAction() { + print("quick slot header") + } + + @objc func handleButtonTapped(notification: NSNotification) { + if let button = notification.object as? NSButton { + print("Button with title \(button.title) was tapped") + } + } +} diff --git a/Box42/QuickSlot/Model/QuickSlotButtonModel.swift b/Box42/QuickSlot/Model/QuickSlotButtonModel.swift new file mode 100644 index 0000000..8049fc7 --- /dev/null +++ b/Box42/QuickSlot/Model/QuickSlotButtonModel.swift @@ -0,0 +1,19 @@ +// +// QuickSlotButtonModel.swift +// Box42 +// +// Created by Chanhee Kim on 8/27/23. +// + +import Foundation + +// Model +struct QuickSlotButtonModel { + let id: UUID + var title: String + + init(title: String = "Default") { + self.id = UUID() + self.title = title + } +} diff --git a/Box42/QuickSlot/Model/QuickSlotUI.swift b/Box42/QuickSlot/Model/QuickSlotUI.swift new file mode 100644 index 0000000..c61c2cf --- /dev/null +++ b/Box42/QuickSlot/Model/QuickSlotUI.swift @@ -0,0 +1,24 @@ +// +// QuickSlotUI.swift +// Box42 +// +// Created by Chanhee Kim on 8/27/23. +// + +import AppKit + +enum QuickSlotUI { + enum size { + static let font: CGFloat = CGFloat(16).pointsToPixels() + static let headerHeight: CGFloat = 35 + static let button: CGFloat = 59 + static let lineSpacing: CGFloat = 12 + } + + enum animation { + } + + enum color { +// static let pinText = NSColor(hex: "#696969") + } +} diff --git a/Box42/QuickSlot/View/ButtonCollectionView/QuickSlotButtonCollectionViewController.swift b/Box42/QuickSlot/View/ButtonCollectionView/QuickSlotButtonCollectionViewController.swift new file mode 100644 index 0000000..edfaf7f --- /dev/null +++ b/Box42/QuickSlot/View/ButtonCollectionView/QuickSlotButtonCollectionViewController.swift @@ -0,0 +1,110 @@ +// +// QuickSlotButtonCollectionViewController.swift +// Box42 +// +// Created by Chanhee Kim on 8/27/23. +// + +import Cocoa +import Combine + +class QuickSlotButtonCollectionViewController: NSViewController { + @IBOutlet weak var quickSlotButtonCollectionView: NSCollectionView! + var viewModel: QuickSlotViewModel = QuickSlotViewModel() + var cancellables: Set = [] + + override func viewDidLoad() { + super.viewDidLoad() + initializeCombine() + + quickSlotButtonCollectionView.delegate = self + quickSlotButtonCollectionView.dataSource = self + + quickSlotButtonCollectionView.register(NSNib(nibNamed: NSNib.Name("QuickSlotButtonViewItem"), bundle: nil), forItemWithIdentifier: NSUserInterfaceItemIdentifier(rawValue: "QuickSlotButtonViewItem")) + + initializeView() + } + + override func viewDidLayout() { + super.viewDidLayout() + constraintsView() + } + + override func awakeFromNib() { + super.awakeFromNib() + } + + init() { + super.init(nibName: "QuickSlotButtonCollectionViewController", bundle: nil) + } + + func initializeCombine() { + viewModel.$buttons + .sink { [weak self] _ in + self?.quickSlotButtonCollectionView.reloadData() + } + .store(in: &cancellables) + } + + func initializeView() { + // MARK: - Setup FlowLayout View + let flowLayout: NSCollectionViewFlowLayout = NSCollectionViewFlowLayout() + flowLayout.itemSize = CGSize(width: QuickSlotUI.size.button, height: QuickSlotUI.size.button) + flowLayout.scrollDirection = .horizontal + flowLayout.minimumLineSpacing = QuickSlotUI.size.lineSpacing + flowLayout.sectionInset = NSEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) + quickSlotButtonCollectionView.collectionViewLayout = flowLayout + + // MARK: - Setup Collection View + quickSlotButtonCollectionView.wantsLayer = true + quickSlotButtonCollectionView.layer?.borderWidth = 0 + quickSlotButtonCollectionView.layer?.borderColor = NSColor.clear.cgColor + quickSlotButtonCollectionView.backgroundColors = [NSColor.clear] + + if let scrollView = quickSlotButtonCollectionView.enclosingScrollView { +// scrollView.hasVerticalScroller = false +// scrollView.hasHorizontalScroller = false + scrollView.backgroundColor = NSColor.clear + scrollView.drawsBackground = false + } + } + + func constraintsView() { + quickSlotButtonCollectionView.frame = self.view.bounds + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } +} + +extension QuickSlotButtonCollectionViewController: NSCollectionViewDelegate, NSCollectionViewDataSource { + + func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int { + return viewModel.buttons.count + } + + func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem { + let item = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "QuickSlotButtonViewItem"), for: indexPath) + + if let customItem = item as? QuickSlotButtonViewItem { + let buttonModel = viewModel.buttons[indexPath.item] + let btn = NSButton() +// btn.title = "\(indexPath)" + btn.title = buttonModel.title + btn.action = #selector(collectionButtonTapped) + btn.target = self + btn.wantsLayer = true + btn.layer?.backgroundColor = NSColor.red.cgColor + customItem.view.addSubview(btn) + btn.frame = CGRect(x: 0, y: 0, width: QuickSlotUI.size.button, height: QuickSlotUI.size.button) + } + return item + } +} + +extension QuickSlotButtonCollectionViewController { + @objc func collectionButtonTapped(_ sender: NSButton) { + NotificationCenter.default.post(name: NSNotification.Name(NotifConst.object.collectionButtonTapped), object: sender) + } +} diff --git a/Box42/QuickSlot/View/ButtonCollectionView/QuickSlotButtonCollectionViewController.xib b/Box42/QuickSlot/View/ButtonCollectionView/QuickSlotButtonCollectionViewController.xib new file mode 100644 index 0000000..0fda14b --- /dev/null +++ b/Box42/QuickSlot/View/ButtonCollectionView/QuickSlotButtonCollectionViewController.xib @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Box42/QuickSlot/View/ButtonCollectionView/Vertical Item/QuickSlotButtonViewItem.swift b/Box42/QuickSlot/View/ButtonCollectionView/Vertical Item/QuickSlotButtonViewItem.swift new file mode 100644 index 0000000..b3cc217 --- /dev/null +++ b/Box42/QuickSlot/View/ButtonCollectionView/Vertical Item/QuickSlotButtonViewItem.swift @@ -0,0 +1,14 @@ +// +// QuickSlotButtonViewItem.swift +// Box42 +// +// Created by Chanhee Kim on 8/27/23. +// + +import Cocoa + +class QuickSlotButtonViewItem: NSCollectionViewItem { + override func viewDidLoad() { + super.viewDidLoad() + } +} diff --git a/Box42/QuickSlot/View/ButtonCollectionView/Vertical Item/QuickSlotButtonViewItem.xib b/Box42/QuickSlot/View/ButtonCollectionView/Vertical Item/QuickSlotButtonViewItem.xib new file mode 100644 index 0000000..346e9c3 --- /dev/null +++ b/Box42/QuickSlot/View/ButtonCollectionView/Vertical Item/QuickSlotButtonViewItem.xib @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Box42/FunctionButton/View/TopDivider.swift b/Box42/QuickSlot/View/Divider.swift similarity index 90% rename from Box42/FunctionButton/View/TopDivider.swift rename to Box42/QuickSlot/View/Divider.swift index 81a39de..a3dfdb0 100644 --- a/Box42/FunctionButton/View/TopDivider.swift +++ b/Box42/QuickSlot/View/Divider.swift @@ -1,5 +1,5 @@ // -// TopDivider.swift +// Divider.swift // Box42 // // Created by Chanhee Kim on 8/21/23. @@ -7,7 +7,7 @@ import AppKit -class TopDivider: NSBox { +class Divider: NSBox { private var callback: (() -> Void)? diff --git a/Box42/QuickSlot/View/QuickSlotGroupView.swift b/Box42/QuickSlot/View/QuickSlotGroupView.swift new file mode 100644 index 0000000..228c26b --- /dev/null +++ b/Box42/QuickSlot/View/QuickSlotGroupView.swift @@ -0,0 +1,56 @@ +// +// QuickSlotGroupView.swift +// Box42 +// +// Created by Chanhee Kim on 8/27/23. +// + +import AppKit +import SnapKit + +class QuickSlotGroupView: NSView { + + lazy var divider: NSBox = Divider(completion: { [weak self] in self?.dividerAction?() }) + lazy var headerView: QuickSlotHeaderView = QuickSlotHeaderView(image: NSImage(imageLiteralResourceName: "star"), completion: { [weak self] in self?.headerAction?() }) + lazy var buttonCollectionView: QuickSlotButtonCollectionViewController = QuickSlotButtonCollectionViewController() + + var dividerAction: (() -> Void)? + var headerAction: (() -> 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(divider) + self.addSubview(headerView) + self.addSubview(buttonCollectionView.view) + + } + + private func setupConstraints() { + divider.snp.makeConstraints { make in + make.top.equalToSuperview() + make.left.right.equalToSuperview() + } + + headerView.snp.makeConstraints { make in + make.top.equalToSuperview() + make.left.right.equalToSuperview() + make.height.equalTo(QuickSlotUI.size.headerHeight) + } + + buttonCollectionView.view.snp.makeConstraints { make in + make.top.equalTo(headerView.snp.bottom).offset(14) + make.left.right.bottom.equalToSuperview() + } + } +} diff --git a/Box42/QuickSlot/View/QuickSlotHeaderView.swift b/Box42/QuickSlot/View/QuickSlotHeaderView.swift new file mode 100644 index 0000000..443ed69 --- /dev/null +++ b/Box42/QuickSlot/View/QuickSlotHeaderView.swift @@ -0,0 +1,55 @@ +// +// QuickSlotHeaderView.swift +// Box42 +// +// Created by Chanhee Kim on 8/27/23. +// + +import AppKit +import SnapKit + +class QuickSlotHeaderView: NSView { + + private var callback: (() -> Void)? + private var QuickSlotHeaderButton: NSButton! + private var QuickSlotHeaderLabel: NSTextField! + + init(image: NSImage, completion: @escaping () -> Void) { + super.init(frame: .zero) + + QuickSlotHeaderButton = NSButton(image: image, target: self, action: #selector(pin)) + QuickSlotHeaderButton.isBordered = false + QuickSlotHeaderButton.wantsLayer = true + QuickSlotHeaderButton.layer?.backgroundColor = NSColor.clear.cgColor + + self.addSubview(QuickSlotHeaderButton) + + QuickSlotHeaderLabel = NSTextField(labelWithString: "Quick Slot") + QuickSlotHeaderLabel.font = NSFont(name: "Inter", size: QuickSlotUI.size.font) + QuickSlotHeaderLabel.textColor = NSColor(hex: "#696969") + QuickSlotHeaderLabel.backgroundColor = NSColor.clear + QuickSlotHeaderLabel.isBordered = false + + self.addSubview(QuickSlotHeaderLabel) + + QuickSlotHeaderButton.snp.makeConstraints { make in + make.left.equalToSuperview() + make.top.equalToSuperview().offset(13) + } + + QuickSlotHeaderLabel.snp.makeConstraints { make in + make.left.equalTo(QuickSlotHeaderButton.snp.right).offset(4) + make.bottom.equalTo(QuickSlotHeaderButton.snp.bottom) + } + + self.callback = completion + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func pin() { + callback?() + } +} diff --git a/Box42/QuickSlot/ViewModel/QuickSlotViewModel.swift b/Box42/QuickSlot/ViewModel/QuickSlotViewModel.swift new file mode 100644 index 0000000..fe3e1da --- /dev/null +++ b/Box42/QuickSlot/ViewModel/QuickSlotViewModel.swift @@ -0,0 +1,35 @@ +// +// QuickSlotViewModel.swift +// Box42 +// +// Created by Chanhee Kim on 8/27/23. +// + +import AppKit +import Combine + +class QuickSlotViewModel { + @Published var buttons: [QuickSlotButtonModel] = [] + + init() { + let button1 = QuickSlotButtonModel(title: "clean") + let button2 = QuickSlotButtonModel(title: "icons") + let button3 = QuickSlotButtonModel(title: "scripts") + + buttons = [button1, button2, button3] + } + + func addButton(_ button: QuickSlotButtonModel) { + buttons.append(button) + } + + func removeButton(id: UUID) { + buttons.removeAll { $0.id == id } + } + + func updateButton(id: UUID, newTitle: String) { + if let index = buttons.firstIndex(where: { $0.id == id }) { + buttons[index].title = newTitle + } + } +} diff --git a/Box42/Resources/AppDelegate.swift b/Box42/Resources/AppDelegate.swift index 9bde3d6..65fb651 100644 --- a/Box42/Resources/AppDelegate.swift +++ b/Box42/Resources/AppDelegate.swift @@ -9,125 +9,127 @@ import Cocoa @main class AppDelegate: NSObject, NSApplicationDelegate { - var menubarController = MenubarViewController() + var menubarController = MenubarViewController() lazy var storage = Storage() - - func applicationWillFinishLaunching(_ notification: Notification) { - menubarController.menubarViewControllerInit() - } - - func applicationDidFinishLaunching(_ aNotification: Notification) { - menubarController.menubarViewControllerStart() -// alertAccessibility() -// hotkey() - -// storage.storageTimerEvent() + + func applicationWillFinishLaunching(_ notification: Notification) { + menubarController.menubarViewControllerInit() } - - func applicationWillTerminate(_ aNotification: Notification) { - // Insert code here to tear down your application - } - - func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { - return true - } - - // MARK: - Core Data stack - - lazy var persistentContainer: NSPersistentContainer = { - /* - The persistent container for the application. This implementation - creates and returns a container, having loaded the store for the - application to it. This property is optional since there are legitimate - error conditions that could cause the creation of the store to fail. - */ - let container = NSPersistentContainer(name: "Box42") - container.loadPersistentStores(completionHandler: { (storeDescription, error) in - if let error = error { - // Replace this implementation with code to handle the error appropriately. - // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. - - /* - Typical reasons for an error here include: - * The parent directory does not exist, cannot be created, or disallows writing. - * The persistent store is not accessible, due to permissions or data protection when the device is locked. - * The device is out of space. - * The store could not be migrated to the current model version. - Check the error message to determine what the actual problem was. - */ - fatalError("Unresolved error \(error)") - } - }) - return container - }() - - // MARK: - Core Data Saving and Undo support - - @IBAction func saveAction(_ sender: AnyObject?) { - // Performs the save action for the application, which is to send the save: message to the application's managed object context. Any encountered errors are presented to the user. - let context = persistentContainer.viewContext - - if !context.commitEditing() { - NSLog("\(NSStringFromClass(type(of: self))) unable to commit editing before saving") - } - if context.hasChanges { - do { - try context.save() - } catch { - // Customize this code block to include application-specific recovery steps. - let nserror = error as NSError - NSApplication.shared.presentError(nserror) - } - } - } - - func windowWillReturnUndoManager(window: NSWindow) -> UndoManager? { - // Returns the NSUndoManager for the application. In this case, the manager returned is that of the managed object context for the application. - return persistentContainer.viewContext.undoManager - } - - func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply { - // Save changes in the application's managed object context before the application terminates. - let context = persistentContainer.viewContext - - if !context.commitEditing() { - NSLog("\(NSStringFromClass(type(of: self))) unable to commit editing to terminate") - return .terminateCancel - } - - if !context.hasChanges { - return .terminateNow - } - - do { - try context.save() - } catch { - let nserror = error as NSError - - // Customize this code block to include application-specific recovery steps. - let result = sender.presentError(nserror) - if (result) { - return .terminateCancel - } - - let question = NSLocalizedString("Could not save changes while quitting. Quit anyway?", comment: "Quit without saves error question message") - let info = NSLocalizedString("Quitting now will lose any changes you have made since the last successful save", comment: "Quit without saves error question info"); - let quitButton = NSLocalizedString("Quit anyway", comment: "Quit anyway button title") - let cancelButton = NSLocalizedString("Cancel", comment: "Cancel button title") - let alert = NSAlert() - alert.messageText = question - alert.informativeText = info - alert.addButton(withTitle: quitButton) - alert.addButton(withTitle: cancelButton) - - let answer = alert.runModal() - if answer == .alertSecondButtonReturn { - return .terminateCancel - } - } - // If we got here, it is time to quit. - return .terminateNow - } - + + func applicationDidFinishLaunching(_ aNotification: Notification) { + menubarController.menubarViewControllerStart() + // alertAccessibility() + // hotkey() + + // storage.storageTimerEvent() + _ = ScriptsLogicController.shared + + } + + func applicationWillTerminate(_ aNotification: Notification) { + // Insert code here to tear down your application + } + + func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } + + // MARK: - Core Data stack + + lazy var persistentContainer: NSPersistentContainer = { + /* + The persistent container for the application. This implementation + creates and returns a container, having loaded the store for the + application to it. This property is optional since there are legitimate + error conditions that could cause the creation of the store to fail. + */ + let container = NSPersistentContainer(name: "Box42") + container.loadPersistentStores(completionHandler: { (storeDescription, error) in + if let error = error { + // Replace this implementation with code to handle the error appropriately. + // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + + /* + Typical reasons for an error here include: + * The parent directory does not exist, cannot be created, or disallows writing. + * The persistent store is not accessible, due to permissions or data protection when the device is locked. + * The device is out of space. + * The store could not be migrated to the current model version. + Check the error message to determine what the actual problem was. + */ + fatalError("Unresolved error \(error)") + } + }) + return container + }() + + // MARK: - Core Data Saving and Undo support + + @IBAction func saveAction(_ sender: AnyObject?) { + // Performs the save action for the application, which is to send the save: message to the application's managed object context. Any encountered errors are presented to the user. + let context = persistentContainer.viewContext + + if !context.commitEditing() { + NSLog("\(NSStringFromClass(type(of: self))) unable to commit editing before saving") + } + if context.hasChanges { + do { + try context.save() + } catch { + // Customize this code block to include application-specific recovery steps. + let nserror = error as NSError + NSApplication.shared.presentError(nserror) + } + } + } + + func windowWillReturnUndoManager(window: NSWindow) -> UndoManager? { + // Returns the NSUndoManager for the application. In this case, the manager returned is that of the managed object context for the application. + return persistentContainer.viewContext.undoManager + } + + func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply { + // Save changes in the application's managed object context before the application terminates. + let context = persistentContainer.viewContext + + if !context.commitEditing() { + NSLog("\(NSStringFromClass(type(of: self))) unable to commit editing to terminate") + return .terminateCancel + } + + if !context.hasChanges { + return .terminateNow + } + + do { + try context.save() + } catch { + let nserror = error as NSError + + // Customize this code block to include application-specific recovery steps. + let result = sender.presentError(nserror) + if (result) { + return .terminateCancel + } + + let question = NSLocalizedString("Could not save changes while quitting. Quit anyway?", comment: "Quit without saves error question message") + let info = NSLocalizedString("Quitting now will lose any changes you have made since the last successful save", comment: "Quit without saves error question info"); + let quitButton = NSLocalizedString("Quit anyway", comment: "Quit anyway button title") + let cancelButton = NSLocalizedString("Cancel", comment: "Cancel button title") + let alert = NSAlert() + alert.messageText = question + alert.informativeText = info + alert.addButton(withTitle: quitButton) + alert.addButton(withTitle: cancelButton) + + let answer = alert.runModal() + if answer == .alertSecondButtonReturn { + return .terminateCancel + } + } + // If we got here, it is time to quit. + return .terminateNow + } + } diff --git a/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/Contents.json b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox0.imageset/Contents.json b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox0.imageset/Contents.json new file mode 100644 index 0000000..44e39c0 --- /dev/null +++ b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox0.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "sitting_fox0.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox0.imageset/sitting_fox0.png b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox0.imageset/sitting_fox0.png new file mode 100644 index 0000000..61410e0 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox0.imageset/sitting_fox0.png differ diff --git a/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox1.imageset/Contents.json b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox1.imageset/Contents.json new file mode 100644 index 0000000..1dfc5aa --- /dev/null +++ b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "sitting_fox1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox1.imageset/sitting_fox1.png b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox1.imageset/sitting_fox1.png new file mode 100644 index 0000000..4ea17f8 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox1.imageset/sitting_fox1.png differ diff --git a/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox2.imageset/Contents.json b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox2.imageset/Contents.json new file mode 100644 index 0000000..dd0f044 --- /dev/null +++ b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "sitting_fox2.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox2.imageset/sitting_fox2.png b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox2.imageset/sitting_fox2.png new file mode 100644 index 0000000..050be9b Binary files /dev/null and b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox2.imageset/sitting_fox2.png differ diff --git a/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox3.imageset/Contents.json b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox3.imageset/Contents.json new file mode 100644 index 0000000..a64ac22 --- /dev/null +++ b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox3.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "sitting_fox3.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox3.imageset/sitting_fox3.png b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox3.imageset/sitting_fox3.png new file mode 100644 index 0000000..4ea17f8 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/42pack_icon/sitting_fox/sitting_fox3.imageset/sitting_fox3.png differ diff --git a/Box42/Resources/Assets.xcassets/uibuttons/Bookmark.imageset/Bookmark icon.png b/Box42/Resources/Assets.xcassets/uibuttons/Bookmark.imageset/Bookmark icon.png new file mode 100644 index 0000000..fa00ba0 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/uibuttons/Bookmark.imageset/Bookmark icon.png differ diff --git a/Box42/Resources/Assets.xcassets/uibuttons/Bookmark.imageset/Contents.json b/Box42/Resources/Assets.xcassets/uibuttons/Bookmark.imageset/Contents.json new file mode 100644 index 0000000..f843e5b --- /dev/null +++ b/Box42/Resources/Assets.xcassets/uibuttons/Bookmark.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Bookmark icon.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/uibuttons/Pin icon.png b/Box42/Resources/Assets.xcassets/uibuttons/Pin icon.png deleted file mode 100644 index f9bd8d6..0000000 Binary files a/Box42/Resources/Assets.xcassets/uibuttons/Pin icon.png and /dev/null differ diff --git a/Box42/Resources/Assets.xcassets/uibuttons/Star.imageset/Contents.json b/Box42/Resources/Assets.xcassets/uibuttons/Star.imageset/Contents.json new file mode 100644 index 0000000..bad711e --- /dev/null +++ b/Box42/Resources/Assets.xcassets/uibuttons/Star.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Star 3.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/uibuttons/Star.imageset/Star 3.png b/Box42/Resources/Assets.xcassets/uibuttons/Star.imageset/Star 3.png new file mode 100644 index 0000000..dcfda9c Binary files /dev/null and b/Box42/Resources/Assets.xcassets/uibuttons/Star.imageset/Star 3.png differ diff --git a/Box42/Resources/Assets.xcassets/uibuttons/Pin icon-1.imageset/Contents.json b/Box42/Resources/Assets.xcassets/uibuttons/pin-box-ver.imageset/Contents.json similarity index 100% rename from Box42/Resources/Assets.xcassets/uibuttons/Pin icon-1.imageset/Contents.json rename to Box42/Resources/Assets.xcassets/uibuttons/pin-box-ver.imageset/Contents.json diff --git a/Box42/Resources/Assets.xcassets/uibuttons/Pin icon-1.imageset/Pin icon.png b/Box42/Resources/Assets.xcassets/uibuttons/pin-box-ver.imageset/Pin icon.png similarity index 100% rename from Box42/Resources/Assets.xcassets/uibuttons/Pin icon-1.imageset/Pin icon.png rename to Box42/Resources/Assets.xcassets/uibuttons/pin-box-ver.imageset/Pin icon.png diff --git a/Box42/Resources/Assets.xcassets/uibuttons/Pin icon.imageset/Contents.json b/Box42/Resources/Assets.xcassets/uibuttons/pin-box.imageset/Contents.json similarity index 100% rename from Box42/Resources/Assets.xcassets/uibuttons/Pin icon.imageset/Contents.json rename to Box42/Resources/Assets.xcassets/uibuttons/pin-box.imageset/Contents.json diff --git a/Box42/Resources/Assets.xcassets/uibuttons/Pin icon.imageset/Pin icon_45.png b/Box42/Resources/Assets.xcassets/uibuttons/pin-box.imageset/Pin icon_45.png similarity index 100% rename from Box42/Resources/Assets.xcassets/uibuttons/Pin icon.imageset/Pin icon_45.png rename to Box42/Resources/Assets.xcassets/uibuttons/pin-box.imageset/Pin icon_45.png diff --git a/Box42/Shared/Constants.swift b/Box42/Shared/Constants.swift index 5e6347d..e0af4fc 100644 --- a/Box42/Shared/Constants.swift +++ b/Box42/Shared/Constants.swift @@ -5,14 +5,14 @@ // Created by Chanhee Kim on 8/17/23. // -struct Constants { - struct url { +enum Constants { + enum url { static let initialName = "home" // static let initialPage = "https://42box.kr" static let initialPage = "https://profile.intra.42.fr/" } - struct UI { + enum UI { static let groupAutolayout = 16 static let topWindow = 64 - 16 static let leadingWindow = 14 diff --git a/Box42/Shared/NotifConst.swift b/Box42/Shared/NotifConst.swift new file mode 100644 index 0000000..fb42e6a --- /dev/null +++ b/Box42/Shared/NotifConst.swift @@ -0,0 +1,16 @@ +// +// ConstantsNotificationCenter.swift +// Box42 +// +// Created by Chanhee Kim on 8/28/23. +// + +enum NotifConst { // NotificationCenter Constants + enum object { + static let collectionButtonTapped = "collectionButtonTapped" + } + + enum userInfo { + + } +} diff --git a/Box42/WebView/URL/URLModel.swift b/Box42/WebView/URL/URLModel.swift index 205a202..a7a0ff6 100644 --- a/Box42/WebView/URL/URLModel.swift +++ b/Box42/WebView/URL/URLModel.swift @@ -21,14 +21,49 @@ struct URLModel { } } +struct UserDataA: Codable { + var uuid: String + var nickname: String + var theme: Int + var icon: String + var urlList: [_URLModel] + var profileImage: String +} + +struct _URLModel: Codable { + var name: String + var url: String +} + struct URLModels { var info: [URLModel] - + let strData = """ + { + \"uuid\":\"8a8b9d71-3c10-4cbc-8b3a-ae1b5c215f40\", + \"nickname\":\"sechung\", + \"theme\":0, + \"icon\":\"fox\", + \"urlList\":[ + {\"name\":\"home\",\"url\":\"https://42box.kr/\"}, + {\"name\":\"23Coaltheme\",\"url\":\"https://42box.github.io/front-end/\"}, + {\"name\":\"loopback\",\"url\":\"http://127.0.0.1:3000/\"}, + {\"name\":\"Box42\",\"url\":\"https://42box.github.io/front-end/#/box\"}, + {\"name\":\"Intra 42\",\"url\":\"https://intra.42.fr\"}, + {\"name\":\"Jiphyeonjeon\",\"url\":\"https://42library.kr\"}, + {\"name\":\"42STAT\",\"url\":\"https://stat.42seoul.kr/home\"}, + {\"name\":\"24Hane\",\"url\":\"https://24hoursarenotenough.42seoul.kr\"}, + {\"name\":\"80kCoding\",\"url\":\"https://80000coding.oopy.io\"}, + {\"name\":\"where42\",\"url\":\"https://www.where42.kr\"}, + {\"name\":\"cabi\",\"url\":\"https://cabi.42seoul.io/\"}, + {\"name\":\"42gg\",\"url\":\"https://42gg.kr/\"} + ], + \"profileImage\":\"dummy-images.png\" + } + """ // Network logic api call 날려서 받아올 것. let URLstring: [nameUrl] = [ ("home", "https://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"), ("Jiphyeonjeon", "https://42library.kr"), @@ -40,4 +75,33 @@ struct URLModels { ("42gg", "https://42gg.kr/"), ("textart", "https://textart.sh/"), ] + + +// let a = URLModel(name: "name", url: "url") +// var m = URLModels(info: [a]) +// var strData = m.strData +// var dicData : Dictionary = [String: String]() +// do { +// dicData = try JSONSerialization.jsonObject(with: Data(strData.utf8), options: []) as! Dictionary +// } catch { +// print(error.localizedDescription) +// } +// print(dicData["home"]) +// print(dicData) +// +// +// let jsonData = Data(strData.utf8) +// do { +// let userData = try JSONDecoder().decode(UserDataA.self, from: jsonData) +// for urlModel in userData.urlList { +// print(urlModel.name, urlModel.url) +// } +// +// +// if let homeURLModel = userData.urlList.first(where: { $0.name == "home" }) { +// print(homeURLModel.url) +// } +// } catch { +// print(error.localizedDescription) +// } } diff --git a/Box42/WindowButton/Model/WindowButtonUI.swift b/Box42/WindowButton/Model/WindowButtonUI.swift index a9e3bdc..66252be 100644 --- a/Box42/WindowButton/Model/WindowButtonUI.swift +++ b/Box42/WindowButton/Model/WindowButtonUI.swift @@ -7,18 +7,18 @@ import AppKit -struct WindowButtonUI { - struct size { +enum WindowButtonUI { + enum size { static let diameter = 15 static let cornerRadius = CGFloat(diameter / 2) static let offset = 8 } - struct animation { + enum animation { static let duration = TimeInterval(0.2) } - struct color { + enum color { static let maximize = NSColor(hex: "#76DF7A").cgColor static let minimize = NSColor(hex: "#FFCE51").cgColor static let close = NSColor(hex: "#F36161").cgColor