From 0eca2eafb39ba2cd286a8947916c3c76d0787b43 Mon Sep 17 00:00:00 2001 From: chanhihi Date: Thu, 24 Aug 2023 21:56:06 +0900 Subject: [PATCH 01/15] =?UTF-8?q?fix:=20WebView=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=99=84=EC=84=B1=EC=8B=9C=20layer=EA=B0=80=20=EC=82=AC?= =?UTF-8?q?=EB=9D=BC=EC=A7=80=EB=8D=98=20=ED=98=84=EC=83=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Box42/Extensions/NSColor.swift | 30 ++++++++++++++++++++++++++++++ Box42/Main/BoxViewController.swift | 16 ++-------------- 2 files changed, 32 insertions(+), 14 deletions(-) create mode 100644 Box42/Extensions/NSColor.swift diff --git a/Box42/Extensions/NSColor.swift b/Box42/Extensions/NSColor.swift new file mode 100644 index 0000000..8360c15 --- /dev/null +++ b/Box42/Extensions/NSColor.swift @@ -0,0 +1,30 @@ +// +// NSColor.swift +// Box42 +// +// Created by Chanhee Kim on 8/24/23. +// + +import AppKit + +extension NSColor { + convenience init(hex: String) { + let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) + var int: UInt64 = 0 + + Scanner(string: hex).scanHexInt64(&int) + let a, r, g, b: UInt64 + switch hex.count { + case 3: // RGB (12-bit) + (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) + case 6: // RGB (24-bit) + (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) + case 8: // ARGB (32-bit) + (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) + default: + (a, r, g, b) = (255, 0, 0, 0) + } + + self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(a) / 255) + } +} diff --git a/Box42/Main/BoxViewController.swift b/Box42/Main/BoxViewController.swift index 551ba31..5a3db90 100644 --- a/Box42/Main/BoxViewController.swift +++ b/Box42/Main/BoxViewController.swift @@ -24,19 +24,7 @@ class BoxViewController: NSViewController { 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) + self.view.layer?.backgroundColor = NSColor(hex: "#FF9548").cgColor } @objc func boundsDidChange(notification: NSNotification) { @@ -52,7 +40,7 @@ class BoxViewController: NSViewController { @objc func pin(_ sender: NSSwitch) { - StateManager.shared.setToggleIsPin() + StateManager.shared.togglePin() print(sender.state) } From 472ddfc60e12f587110dfe857729bcbe7ca9b3c0 Mon Sep 17 00:00:00 2001 From: chanhihi Date: Thu, 24 Aug 2023 22:35:18 +0900 Subject: [PATCH 02/15] =?UTF-8?q?refactor:=20=EA=B5=AC=EC=A1=B0=EB=A5=BC?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=ED=95=A9=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{NSColor.swift => HexValue+NSColor.swift} | 0 .../BoxBaseContainerViewController.swift | 50 +++++++++++++------ Box42/Main/BoxViewController.swift | 50 ------------------- ...Down+BoxBaseContainerViewController.swift} | 2 +- Box42/Menubar/MenubarViewController.swift | 14 +++--- Box42/{Box => }/View/BoxBaseSplitView.swift | 0 Box42/{Box => }/View/BoxButtonViewGroup.swift | 0 .../{Box => }/View/BoxContentsViewGroup.swift | 1 - Box42/Window/BoxWindowController.swift | 6 +-- 9 files changed, 45 insertions(+), 78 deletions(-) rename Box42/Extensions/{NSColor.swift => HexValue+NSColor.swift} (100%) rename Box42/{Box => Main}/BoxBaseContainerViewController.swift (78%) delete mode 100644 Box42/Main/BoxViewController.swift rename Box42/Main/{keyDown+BoxViewController.swift => keyDown+BoxBaseContainerViewController.swift} (95%) rename Box42/{Box => }/View/BoxBaseSplitView.swift (100%) rename Box42/{Box => }/View/BoxButtonViewGroup.swift (100%) rename Box42/{Box => }/View/BoxContentsViewGroup.swift (97%) diff --git a/Box42/Extensions/NSColor.swift b/Box42/Extensions/HexValue+NSColor.swift similarity index 100% rename from Box42/Extensions/NSColor.swift rename to Box42/Extensions/HexValue+NSColor.swift diff --git a/Box42/Box/BoxBaseContainerViewController.swift b/Box42/Main/BoxBaseContainerViewController.swift similarity index 78% rename from Box42/Box/BoxBaseContainerViewController.swift rename to Box42/Main/BoxBaseContainerViewController.swift index 836ca15..e07a11e 100644 --- a/Box42/Box/BoxBaseContainerViewController.swift +++ b/Box42/Main/BoxBaseContainerViewController.swift @@ -16,21 +16,24 @@ class BoxBaseContainerViewController: NSViewController { let windowViewGroup: WindowButtonViewController = WindowButtonViewController() var buttonGroup: BoxButtonViewGroup! var leftContainer: MovableContainerView! - + weak var menubarVCDelegate: MenubarViewControllerDelegate? // extension + override func loadView() { self.view = NSView() -// self.view.wantsLayer = true -// self.view.layer?.backgroundColor = NSColor.red.cgColor self.view.addSubview(splitView) splitView.delegate = self buttonGroup = BoxButtonViewGroupInit() - leftContainerInit() viewInit() } + override func viewDidLoad() { + self.view.wantsLayer = true + self.view.layer?.backgroundColor = NSColor(hex: "#FF9548").cgColor + } + func BoxButtonViewGroupInit() -> BoxButtonViewGroup { let buttonGroup = BoxButtonViewGroup { sender in @@ -40,19 +43,28 @@ class BoxBaseContainerViewController: NSViewController { return buttonGroup } - func clickBtn(sender: NSButton) { - guard let clickCount = NSApp.currentEvent?.clickCount else { return } - if clickCount == 2 { - WebViewManager.shared.list[sender.title]!.reload() - print("Dobule Click") - } else if clickCount > 2 { - if let currentURL = WebViewManager.shared.hostingWebView?.url { - NSWorkspace.shared.open(currentURL) + func clickBtn(sender: Any?) { + if let button = sender as? NSButton { + guard let clickCount = NSApp.currentEvent?.clickCount else { return } + if clickCount == 2 { + WebViewManager.shared.list[button.title]!.reload() + print("Dobule Click") + } else if clickCount > 2 { + if let currentURL = WebViewManager.shared.hostingWebView?.url { + NSWorkspace.shared.open(currentURL) + } + print("Triple Click") + } else if clickCount < 2 { + contentGroup.removeAllSubviews() + contentGroup.showWebviews(button) + } + } else { + if let str = sender as? String { + if str == "box" { + contentGroup.removeAllSubviews() + print("box inside") + } } - print("Triple Click") - } else if clickCount < 2 { - contentGroup.removeAllSubviews() - contentGroup.showWebviews(sender) } } @@ -140,3 +152,9 @@ extension BoxBaseContainerViewController: NSSplitViewDelegate { contentGroup.frame = NSRect(x: leftWidth + dividerThickness, y: 0, width: contentWidth, height: splitView.bounds.height) } } + +extension BoxBaseContainerViewController: BoxFunctionViewControllerDelegate { + func didTapBoxButton() { + clickBtn(sender: "box") // 여기에 적절한 sender (NSButton) 전달) + } +} diff --git a/Box42/Main/BoxViewController.swift b/Box42/Main/BoxViewController.swift deleted file mode 100644 index 5a3db90..0000000 --- a/Box42/Main/BoxViewController.swift +++ /dev/null @@ -1,50 +0,0 @@ -// -// BoxViewController.swift -// Box42 -// -// Created by Chan on 2023/03/16. -// - -import AppKit -import WebKit - -class BoxViewController: NSViewController { - var boxView: BoxBaseContainerViewController = BoxBaseContainerViewController() - var gradientLayer: CAGradientLayer! - let preferencesVC = PreferencesViewController() - weak var menubarVCDelegate: MenubarViewControllerDelegate? - - override func loadView() { - self.view = boxView.view - } - - override func viewDidLoad() { - super.viewDidLoad() - - menubarVCDelegate = (NSApplication.shared.delegate as? AppDelegate)?.menubarController - - self.view.wantsLayer = true - self.view.layer?.backgroundColor = NSColor(hex: "#FF9548").cgColor - } - - @objc func boundsDidChange(notification: NSNotification) { - if let window = notification.object as? NSWindow { - gradientLayer.frame = window.contentView!.bounds - } - } - - @objc - func doubleClickBtn(sender: NSButton) { - WebViewManager.shared.list[sender.title]!.reload() - } - - @objc - func pin(_ sender: NSSwitch) { - StateManager.shared.togglePin() - print(sender.state) - } - - func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { - print(message.name) - } -} diff --git a/Box42/Main/keyDown+BoxViewController.swift b/Box42/Main/keyDown+BoxBaseContainerViewController.swift similarity index 95% rename from Box42/Main/keyDown+BoxViewController.swift rename to Box42/Main/keyDown+BoxBaseContainerViewController.swift index 63b89e2..f16fcfc 100644 --- a/Box42/Main/keyDown+BoxViewController.swift +++ b/Box42/Main/keyDown+BoxBaseContainerViewController.swift @@ -7,7 +7,7 @@ import AppKit -extension BoxViewController { +extension BoxBaseContainerViewController { override func keyDown(with event: NSEvent) { print(event.keyCode) if event.keyCode == 1 { diff --git a/Box42/Menubar/MenubarViewController.swift b/Box42/Menubar/MenubarViewController.swift index 2cb1a3f..7a8a719 100644 --- a/Box42/Menubar/MenubarViewController.swift +++ b/Box42/Menubar/MenubarViewController.swift @@ -8,7 +8,7 @@ import Foundation import AppKit -class MenubarViewController: NSWorkspace { +class MenubarViewController: NSViewController { var popover = NSPopover() var statusBarVM = StatusBarViewModel() lazy var eventMonitor: EventMonitor = self.setupEventMonitor() @@ -56,14 +56,14 @@ class MenubarViewController: NSWorkspace { } func popoverCoentViewInit() { - let boxViewController = BoxViewController(nibName: nil, bundle: nil) + let boxViewController = BoxBaseContainerViewController(nibName: nil, bundle: nil) popover.contentViewController = boxViewController } func setupEventMonitor() -> EventMonitor { return EventMonitor(mask: [.leftMouseDown, .rightMouseDown, .otherMouseDown]) { [weak self] event in if let strongSelf = self, strongSelf.popover.isShown { - if StateManager.shared.getIsPin() == false && event?.buttonNumber != 2 { + if StateManager.shared.pin == false && event?.buttonNumber != 2 { strongSelf.closePopover(sender: event) } } else if let strongSelf = self, !strongSelf.popover.isShown { @@ -99,8 +99,8 @@ class MenubarViewController: NSWorkspace { extension MenubarViewController: MenubarViewControllerDelegate { func toggleWindow(sender: Any?) { - StateManager.shared.setToggleIsShowWindow() - if StateManager.shared.getIsShowWindow() == false { + StateManager.shared.toggleShowWindow() + if StateManager.shared.showWindow == false { if let window = boxWindowController?.window { if window.isVisible { window.orderOut(sender) @@ -113,12 +113,12 @@ extension MenubarViewController: MenubarViewControllerDelegate { } if let button = statusBarVM.statusBar.statusItem.button, let window = boxWindowController?.window { - if StateManager.shared.getIsShowFirstWindow() == false { + if StateManager.shared.showFirstWindow == false { let buttonFrame = button.window?.convertToScreen(button.frame) ?? NSZeroRect 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() + StateManager.shared.toggleShowFirstWindow() } window.level = .floating } diff --git a/Box42/Box/View/BoxBaseSplitView.swift b/Box42/View/BoxBaseSplitView.swift similarity index 100% rename from Box42/Box/View/BoxBaseSplitView.swift rename to Box42/View/BoxBaseSplitView.swift diff --git a/Box42/Box/View/BoxButtonViewGroup.swift b/Box42/View/BoxButtonViewGroup.swift similarity index 100% rename from Box42/Box/View/BoxButtonViewGroup.swift rename to Box42/View/BoxButtonViewGroup.swift diff --git a/Box42/Box/View/BoxContentsViewGroup.swift b/Box42/View/BoxContentsViewGroup.swift similarity index 97% rename from Box42/Box/View/BoxContentsViewGroup.swift rename to Box42/View/BoxContentsViewGroup.swift index 596a5d1..1eb1ee5 100644 --- a/Box42/Box/View/BoxContentsViewGroup.swift +++ b/Box42/View/BoxContentsViewGroup.swift @@ -69,7 +69,6 @@ class BoxContentsViewGroup: NSView { } currentWebview.viewDidMoveToSuperview() - currentWebview.becomeFirstResponder() } } diff --git a/Box42/Window/BoxWindowController.swift b/Box42/Window/BoxWindowController.swift index 063dd96..38165ca 100644 --- a/Box42/Window/BoxWindowController.swift +++ b/Box42/Window/BoxWindowController.swift @@ -21,14 +21,14 @@ class BoxWindowController: NSWindowController, NSToolbarDelegate, NSWindowDelega windowInstance.backgroundColor = .clear windowInstance.isMovableByWindowBackground = true - let boxViewController = BoxViewController(nibName: nil, bundle: nil) + let boxViewController = BoxBaseContainerViewController(nibName: nil, bundle: nil) windowInstance.contentViewController = boxViewController super.init(window: windowInstance) windowInstance.delegate = self -// setupToolbar() + setupToolbar() } required init?(coder: NSCoder) { @@ -39,7 +39,7 @@ class BoxWindowController: NSWindowController, NSToolbarDelegate, NSWindowDelega extension BoxWindowController { func windowShouldClose(_ sender: NSWindow) -> Bool { // NSApplication.shared.terminate(self) - StateManager.shared.setToggleIsShowWindow() + StateManager.shared.toggleShowWindow() return true } } From 621bedff08699377f0a9405d468d123b6f0d949b Mon Sep 17 00:00:00 2001 From: chanhihi Date: Thu, 24 Aug 2023 22:36:31 +0900 Subject: [PATCH 03/15] =?UTF-8?q?fix:=20=EC=9E=98=EB=AA=BB=EB=90=9C=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EB=A7=B5=ED=95=91=EC=9D=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=ED=95=A9=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FunctionButton/BoxFunctionViewController.swift | 7 +++++++ Box42/Toolbar/View/BoxToolbarViewGroup.swift | 13 ++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Box42/FunctionButton/BoxFunctionViewController.swift b/Box42/FunctionButton/BoxFunctionViewController.swift index a2a482e..42e3396 100644 --- a/Box42/FunctionButton/BoxFunctionViewController.swift +++ b/Box42/FunctionButton/BoxFunctionViewController.swift @@ -36,7 +36,14 @@ class BoxFunctionViewController: NSViewController { NSApplication.shared.terminate(self) } + weak var delegate: BoxFunctionViewControllerDelegate? + func box() { print("box") + delegate?.didTapBoxButton() } } + +protocol BoxFunctionViewControllerDelegate: AnyObject { + func didTapBoxButton() +} diff --git a/Box42/Toolbar/View/BoxToolbarViewGroup.swift b/Box42/Toolbar/View/BoxToolbarViewGroup.swift index 3d63053..6495f30 100644 --- a/Box42/Toolbar/View/BoxToolbarViewGroup.swift +++ b/Box42/Toolbar/View/BoxToolbarViewGroup.swift @@ -10,11 +10,11 @@ import SnapKit class BoxToolbarViewGroup: NSView { var displayURL = DisplayURLInToolbar() - lazy var sidebarLeading: SideBarLeading = SideBarLeading(image: NSImage(imageLiteralResourceName: "sidebar.leading"), completion: { self.goBack?() }) - lazy var goBackButton: GoBackInToolbar = GoBackInToolbar(image: NSImage(imageLiteralResourceName: "arrow.left"), completion: { self.goFoward?()} ) - lazy var goForwardButton: GoForwardInToolbar = GoForwardInToolbar(image: NSImage(imageLiteralResourceName: "arrow.right"), completion: { self.reloadPage?() }) - lazy var reloadPageButton: ReloadPageViaToolbar = ReloadPageViaToolbar(image: NSImage(imageLiteralResourceName: "arrow.clockwise"), completion: { self.goToHome?() }) - lazy var goHomePageViaButton: GoHomePageViaToolbar = GoHomePageViaToolbar(image: NSImage(imageLiteralResourceName: "figure.skating"), completion: { self.sidebar?() }) + lazy var sidebarLeading: SideBarLeading = SideBarLeading(image: NSImage(imageLiteralResourceName: "sidebar.leading"), completion: { self.sidebar?() }) + lazy var goBackButton: GoBackInToolbar = GoBackInToolbar(image: NSImage(imageLiteralResourceName: "arrow.left"), completion: { self.goBack?() }) + lazy var goForwardButton: GoForwardInToolbar = GoForwardInToolbar(image: NSImage(imageLiteralResourceName: "arrow.right"), completion: { self.goFoward?()} ) + lazy var reloadPageButton: ReloadPageViaToolbar = ReloadPageViaToolbar(image: NSImage(imageLiteralResourceName: "arrow.clockwise"), completion: { self.reloadPage?() }) + lazy var goHomePageViaButton: GoHomePageViaToolbar = GoHomePageViaToolbar(image: NSImage(imageLiteralResourceName: "figure.skating"), completion: { self.goToHome?() }) var goBack: (() -> Void)? var goFoward: (() -> Void)? @@ -50,7 +50,7 @@ class BoxToolbarViewGroup: NSView { } sidebarLeading.snp.makeConstraints { make in - make.top.equalTo(displayURL).offset(10) + make.top.equalTo(displayURL.snp.bottom).offset(10) make.bottom.equalToSuperview() make.left.equalToSuperview() make.width.equalTo(goBackButton) @@ -79,6 +79,5 @@ class BoxToolbarViewGroup: NSView { make.left.equalTo(reloadPageButton.snp.right).offset(10) make.right.equalToSuperview() } - } } From 606b27b9ce97743b0a3c1537600ecebaa4229d35 Mon Sep 17 00:00:00 2001 From: chanhihi Date: Thu, 24 Aug 2023 22:36:52 +0900 Subject: [PATCH 04/15] =?UTF-8?q?build:=20=F0=9F=9B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Box42.xcodeproj/project.pbxproj | 57 ++++++++++++++++++++---------- Box42/Resources/Box42.entitlements | 6 +++- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/Box42.xcodeproj/project.pbxproj b/Box42.xcodeproj/project.pbxproj index 54be299..0d9fb62 100644 --- a/Box42.xcodeproj/project.pbxproj +++ b/Box42.xcodeproj/project.pbxproj @@ -38,7 +38,6 @@ 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 */; }; - 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 */; }; @@ -47,13 +46,19 @@ 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 */; }; + DE3FF3672A978A37009C88EF /* HexValue+NSColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE3FF3662A978A37009C88EF /* HexValue+NSColor.swift */; }; + DE3FF36B2A978A57009C88EF /* WindowButtonViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE3FF3692A978A57009C88EF /* WindowButtonViewController.swift */; }; + DE3FF3742A978AB8009C88EF /* WindowMaximizeButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE3FF3702A978AB8009C88EF /* WindowMaximizeButton.swift */; }; + DE3FF3752A978AB8009C88EF /* WindowViewGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE3FF3712A978AB8009C88EF /* WindowViewGroup.swift */; }; + DE3FF3762A978AB8009C88EF /* WindowCloseButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE3FF3722A978AB8009C88EF /* WindowCloseButton.swift */; }; + DE3FF3772A978AB8009C88EF /* WindowMinimizeButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE3FF3732A978AB8009C88EF /* WindowMinimizeButton.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 */; }; + DE4408152A92750D0091937A /* keyDown+BoxBaseContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4408142A92750D0091937A /* keyDown+BoxBaseContainerViewController.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 */; }; @@ -100,10 +105,9 @@ 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 = ""; }; + DE1F1A192A8B50C500A88DD8 /* BoxBaseContainerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BoxBaseContainerViewController.swift; path = Main/BoxBaseContainerViewController.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 = ""; }; @@ -112,13 +116,19 @@ 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 = ""; }; + DE3FF3662A978A37009C88EF /* HexValue+NSColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "HexValue+NSColor.swift"; sourceTree = ""; }; + DE3FF3692A978A57009C88EF /* WindowButtonViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowButtonViewController.swift; sourceTree = ""; }; + DE3FF3702A978AB8009C88EF /* WindowMaximizeButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowMaximizeButton.swift; sourceTree = ""; }; + DE3FF3712A978AB8009C88EF /* WindowViewGroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowViewGroup.swift; sourceTree = ""; }; + DE3FF3722A978AB8009C88EF /* WindowCloseButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowCloseButton.swift; sourceTree = ""; }; + DE3FF3732A978AB8009C88EF /* WindowMinimizeButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowMinimizeButton.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 = ""; }; + 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 = ""; }; DE77BA502A82580400713683 /* MenubarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenubarViewModel.swift; sourceTree = ""; }; DE77BA552A82637900713683 /* StateManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateManager.swift; sourceTree = ""; }; @@ -167,19 +177,17 @@ DE018BB12A5099F900FF0AA3 /* Box42 */ = { isa = PBXGroup; children = ( - DE0A916B2A8E7DC700D1D6F1 /* UI */, - DE1F1A202A8B50CA00A88DD8 /* Main */, + DE77BA542A82636500713683 /* Shared */, DEF749302A85655E00D987C8 /* Extensions */, + DE1F1A202A8B50CA00A88DD8 /* Main */, DEB862E82A853F6800278FCD /* Window */, DEB862D22A8511D600278FCD /* Scripts */, - DE77BA542A82636500713683 /* Shared */, DE874F512A591EC600FC3B77 /* Preferences */, DE018C0C2A509BDF00FF0AA3 /* Resources */, DE018C062A509B9000FF0AA3 /* System */, DE018C082A509BB500FF0AA3 /* WebView */, DE0A917D2A8F864300D1D6F1 /* Toolbar */, DE4407F82A923E5B0091937A /* FunctionButton */, - DE1F1A182A8B50BB00A88DD8 /* Box */, DE018C0E2A509C0C00FF0AA3 /* Menubar */, ); path = Box42; @@ -279,22 +287,26 @@ name = Frameworks; sourceTree = ""; }; - DE1F1A182A8B50BB00A88DD8 /* Box */ = { + DE1F1A202A8B50CA00A88DD8 /* Main */ = { isa = PBXGroup; children = ( + DE0A916B2A8E7DC700D1D6F1 /* UI */, DE4408202A9297EE0091937A /* View */, DE1F1A192A8B50C500A88DD8 /* BoxBaseContainerViewController.swift */, + DE4408142A92750D0091937A /* keyDown+BoxBaseContainerViewController.swift */, ); - name = Box; + name = Main; sourceTree = ""; }; - DE1F1A202A8B50CA00A88DD8 /* Main */ = { + DE3FF36F2A978A6E009C88EF /* View */ = { isa = PBXGroup; children = ( - DE1F1A232A8B50D500A88DD8 /* BoxViewController.swift */, - DE4408142A92750D0091937A /* keyDown+BoxViewController.swift */, + DE3FF3722A978AB8009C88EF /* WindowCloseButton.swift */, + DE3FF3702A978AB8009C88EF /* WindowMaximizeButton.swift */, + DE3FF3732A978AB8009C88EF /* WindowMinimizeButton.swift */, + DE3FF3712A978AB8009C88EF /* WindowViewGroup.swift */, ); - name = Main; + path = View; sourceTree = ""; }; DE4407F82A923E5B0091937A /* FunctionButton */ = { @@ -326,8 +338,7 @@ DE1F1A1A2A8B50C500A88DD8 /* BoxContentsViewGroup.swift */, DE24E6372A8FE10300E29F5D /* BoxBaseSplitView.swift */, ); - name = View; - path = Box/View; + path = View; sourceTree = ""; }; DE77BA542A82636500713683 /* Shared */ = { @@ -377,6 +388,8 @@ DEB862E82A853F6800278FCD /* Window */ = { isa = PBXGroup; children = ( + DE3FF36F2A978A6E009C88EF /* View */, + DE3FF3692A978A57009C88EF /* WindowButtonViewController.swift */, DEB862E92A853F7F00278FCD /* BoxWindowController.swift */, ); path = Window; @@ -385,6 +398,7 @@ DEF749302A85655E00D987C8 /* Extensions */ = { isa = PBXGroup; children = ( + DE3FF3662A978A37009C88EF /* HexValue+NSColor.swift */, DE874F5E2A5935CC00FC3B77 /* String.swift */, DEF749312A85657600D987C8 /* NSScreen.swift */, DE1F1A302A8BD68F00A88DD8 /* Double.swift */, @@ -473,13 +487,14 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + DE3FF3752A978AB8009C88EF /* WindowViewGroup.swift in Sources */, 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 */, + DE3FF3742A978AB8009C88EF /* WindowMaximizeButton.swift in Sources */, DE77BA562A82637900713683 /* StateManager.swift in Sources */, DE1F1A1C2A8B50C500A88DD8 /* BoxBaseContainerViewController.swift in Sources */, DE018BE72A509B1E00FF0AA3 /* WebViewController.swift in Sources */, @@ -501,9 +516,11 @@ DE7A257A2A6D8CA20043225A /* PreferencesViewController.swift in Sources */, DE24E63B2A8FE93900E29F5D /* NSImage.swift in Sources */, DE0A916D2A8E7DD700D1D6F1 /* HoverButton.swift in Sources */, + DE3FF3762A978AB8009C88EF /* WindowCloseButton.swift in Sources */, + DE3FF3772A978AB8009C88EF /* WindowMinimizeButton.swift in Sources */, DE4408022A923EB60091937A /* PinButtonView.swift in Sources */, DE0A91672A8E6CA700D1D6F1 /* WebViewManager.swift in Sources */, - DE4408152A92750D0091937A /* keyDown+BoxViewController.swift in Sources */, + DE4408152A92750D0091937A /* keyDown+BoxBaseContainerViewController.swift in Sources */, DE018BED2A509B2600FF0AA3 /* URLModel.swift in Sources */, DE4408052A923EC00091937A /* QuitButtonView.swift in Sources */, DE0A918A2A8F88A900D1D6F1 /* GoForwardInToolbar.swift in Sources */, @@ -511,6 +528,7 @@ DEB862EB2A853F7F00278FCD /* BoxWindowController.swift in Sources */, DE0A918D2A8F88BC00D1D6F1 /* GoBackInToolbar.swift in Sources */, DE018BDD2A509AEB00FF0AA3 /* EventMonitor.swift in Sources */, + DE3FF3672A978A37009C88EF /* HexValue+NSColor.swift in Sources */, DE1F1A292A8B50E200A88DD8 /* BoxSizeManager.swift in Sources */, DEB862DC2A85347400278FCD /* Scripts.swift in Sources */, DE1F1A1D2A8B50C500A88DD8 /* BoxContentsViewGroup.swift in Sources */, @@ -522,6 +540,7 @@ DE874F572A591F2500FC3B77 /* Icon.swift in Sources */, DE1F1A2E2A8BCC9800A88DD8 /* Storage.swift in Sources */, DE0A91782A8F014F00D1D6F1 /* WebView.swift in Sources */, + DE3FF36B2A978A57009C88EF /* WindowButtonViewController.swift in Sources */, DE1F1A312A8BD68F00A88DD8 /* Double.swift in Sources */, DE0A917F2A8F865400D1D6F1 /* BoxToolbarViewGroup.swift in Sources */, DE018BEA2A509B2100FF0AA3 /* WebViewModel.swift in Sources */, diff --git a/Box42/Resources/Box42.entitlements b/Box42/Resources/Box42.entitlements index aa078cb..1b4b0b0 100644 --- a/Box42/Resources/Box42.entitlements +++ b/Box42/Resources/Box42.entitlements @@ -6,7 +6,11 @@ com.apple.security.automation.apple-events - com.apple.security.files.user-selected.read-only + com.apple.security.device.camera + + com.apple.security.files.downloads.read-write + + com.apple.security.files.user-selected.read-write com.apple.security.network.client From 2043bb03558a5c41d84d4a12855cb290e846f73a Mon Sep 17 00:00:00 2001 From: chanhihi Date: Fri, 25 Aug 2023 06:13:51 +0900 Subject: [PATCH 05/15] =?UTF-8?q?feat:=20UI=EB=A5=BC=20=EC=9C=84=ED=95=9C?= =?UTF-8?q?=20Asset=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../42pack_icon/fox/Contents.json | 6 + .../fox/fox_page0.imageset/Contents.json | 20 ++ .../fox/fox_page0.imageset/fox0.png | Bin 0 -> 3944 bytes .../fox/fox_page1.imageset/Contents.json | 20 ++ .../fox/fox_page1.imageset/fox1.png | Bin 0 -> 3950 bytes .../fox/fox_page2.imageset/Contents.json | 20 ++ .../fox/fox_page2.imageset/fox2.png | Bin 0 -> 3946 bytes .../fox/fox_page3.imageset/Contents.json | 20 ++ .../fox/fox_page3.imageset/fox3.png | Bin 0 -> 3990 bytes .../fox/fox_page4.imageset/Contents.json | 20 ++ .../fox/fox_page4.imageset/fox4.png | Bin 0 -> 3900 bytes .../Contents.json | 0 .../arrow.left@2x.png | Bin .../Assets.xcassets/uibuttons/Contents.json | 6 + .../Assets.xcassets/uibuttons/Ellipse 1.png | Bin 0 -> 570 bytes .../arrow-left.imageset/Contents.json | 21 ++ .../arrow-left.imageset/arrow-left.png | Bin 0 -> 402 bytes .../arrow-right.imageset/Contents.json | 21 ++ .../arrow-right.imageset/arrow-right.png | Bin 0 -> 399 bytes .../uibuttons/circle.imageset/Contents.json | 21 ++ .../uibuttons/circle.imageset/Ellipse 1.png | Bin 0 -> 570 bytes .../rotate-right.imageset/Contents.json | 21 ++ .../rotate-right.imageset/rotate-right.png | Bin 0 -> 639 bytes .../toggle-off.imageset/Contents.json | 21 ++ .../toggle-off.imageset/toggle-off.png | Bin 0 -> 676 bytes .../toggle-on.imageset/Contents.json | 21 ++ .../toggle-on.imageset/toggle-on.png | Bin 0 -> 672 bytes Box42/View/BoxButtonViewGroup.swift | 309 ------------------ Box42/Window/BoxWindowController.swift | 136 -------- Box42/Window/View/WindowCloseButton.swift | 31 -- Box42/Window/View/WindowMaximizeButton.swift | 31 -- Box42/Window/View/WindowMinimizeButton.swift | 31 -- Box42/Window/View/WindowViewGroup.swift | 56 ---- Box42/Window/WindowButtonViewController.swift | 36 -- 34 files changed, 238 insertions(+), 630 deletions(-) create mode 100644 Box42/Resources/Assets.xcassets/42pack_icon/fox/Contents.json create mode 100644 Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page0.imageset/Contents.json create mode 100644 Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page0.imageset/fox0.png create mode 100644 Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page1.imageset/Contents.json create mode 100644 Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page1.imageset/fox1.png create mode 100644 Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page2.imageset/Contents.json create mode 100644 Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page2.imageset/fox2.png create mode 100644 Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page3.imageset/Contents.json create mode 100644 Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page3.imageset/fox3.png create mode 100644 Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page4.imageset/Contents.json create mode 100644 Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page4.imageset/fox4.png rename Box42/Resources/Assets.xcassets/Icons/{arrow.left.imageset => _arrow.left.imageset}/Contents.json (100%) rename Box42/Resources/Assets.xcassets/Icons/{arrow.left.imageset => _arrow.left.imageset}/arrow.left@2x.png (100%) create mode 100644 Box42/Resources/Assets.xcassets/uibuttons/Contents.json create mode 100644 Box42/Resources/Assets.xcassets/uibuttons/Ellipse 1.png create mode 100644 Box42/Resources/Assets.xcassets/uibuttons/arrow-left.imageset/Contents.json create mode 100644 Box42/Resources/Assets.xcassets/uibuttons/arrow-left.imageset/arrow-left.png create mode 100644 Box42/Resources/Assets.xcassets/uibuttons/arrow-right.imageset/Contents.json create mode 100644 Box42/Resources/Assets.xcassets/uibuttons/arrow-right.imageset/arrow-right.png create mode 100644 Box42/Resources/Assets.xcassets/uibuttons/circle.imageset/Contents.json create mode 100644 Box42/Resources/Assets.xcassets/uibuttons/circle.imageset/Ellipse 1.png create mode 100644 Box42/Resources/Assets.xcassets/uibuttons/rotate-right.imageset/Contents.json create mode 100644 Box42/Resources/Assets.xcassets/uibuttons/rotate-right.imageset/rotate-right.png create mode 100644 Box42/Resources/Assets.xcassets/uibuttons/toggle-off.imageset/Contents.json create mode 100644 Box42/Resources/Assets.xcassets/uibuttons/toggle-off.imageset/toggle-off.png create mode 100644 Box42/Resources/Assets.xcassets/uibuttons/toggle-on.imageset/Contents.json create mode 100644 Box42/Resources/Assets.xcassets/uibuttons/toggle-on.imageset/toggle-on.png delete mode 100644 Box42/View/BoxButtonViewGroup.swift delete mode 100644 Box42/Window/BoxWindowController.swift delete mode 100644 Box42/Window/View/WindowCloseButton.swift delete mode 100644 Box42/Window/View/WindowMaximizeButton.swift delete mode 100644 Box42/Window/View/WindowMinimizeButton.swift delete mode 100644 Box42/Window/View/WindowViewGroup.swift delete mode 100644 Box42/Window/WindowButtonViewController.swift diff --git a/Box42/Resources/Assets.xcassets/42pack_icon/fox/Contents.json b/Box42/Resources/Assets.xcassets/42pack_icon/fox/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Box42/Resources/Assets.xcassets/42pack_icon/fox/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page0.imageset/Contents.json b/Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page0.imageset/Contents.json new file mode 100644 index 0000000..64bcd2c --- /dev/null +++ b/Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page0.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "mac", + "scale" : "1x" + }, + { + "filename" : "fox0.png", + "idiom" : "mac", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page0.imageset/fox0.png b/Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page0.imageset/fox0.png new file mode 100644 index 0000000000000000000000000000000000000000..0892874e263d4aece136bfac2d934cdb392569c4 GIT binary patch literal 3944 zcmV-u50~(XP)-hJ00004XF*Lt006O% z3;baP000U%X+uL$b5ch_AW20-HZeIiHZ3wPF#rHaiJg{rR8!d&htIt?y-<=6ij>f6 zXi@@54ZTQ_E-Enz5K6$103tR-RB%L5k){YTDBysjLy@r}iiH7DvFijGMAUI`6dRUF zWUU$Bym{}eS9UO(Z2>7`&z9wUXbV-Il#&6`Y8GKGQ04S2&F6MJnWNa;Ck|;8QE#r9r;7G||@X{|> z%+C|c55>;RS}qbKr-&IQTvLXPlM{>K&(BTgi^a?^4mXV>;xX8n8Ce|RasXz}{8imI52H3ZN4bfe_i~WlJ|C&UW9+{8AKoW!}eExnGFE2re(F+`iE_46#!l9 z0Z_aBhs|Iw0E)7{bq;-T9=d#9QpDmcXDh4R++0fmpKB>E=%LdZt9g$j;($`3&Zthxi`{{&gM}5&R^+h%b~yM9Zd3AWW9ETgVfL z1(`yIK=_}U_z%PWq}jQaiQ4!P(3V&Nr6C$XejWfQDiI(Fdt@un?|lo#M+5oIi_w{w zo%_#%{(V=tO#a9gB!7-$M?^BX5>d|Vn*3S!?g~$*UQipUPL&zMmg;!4Do9IA%up=Rh? z=qPj=x&RGBx1dpI68aT-2O}^EromdU5o`ssU{5#*j)WJ%$?!5bA1;Eoz?EiTr=n?cd`V|I)p<|3Oju?MT93~aB0<#&j8`F+Cg&D?-VWzQItUA^l>xvD zRIYI4MQ`g1<+DyrL=EogS06Xii({| zv`U^zjmmKqDIK93(F5q|^fLNk`gQs{RV`IdRle#b)i%{Ds;|}NsClUI)k@Ub)kf6b zsWa4l)YH_rsduU0(?DsMX@qO!YV6TCtMPOWZH~(v?wpc2hv(eZgf-1HBQ#fN?$aF5 zoYvCT^3%%Fs?s{6^;Da#?V+8jy+iwi_M{F~$4y6|vqR^k&SQoO!;_KDsATjprgSxR z{dFa}^}2()GkV5)QF?`X?Rxk03HmJkB>f%wz4}uIItC#I1qQ7Kw+-=zEW;GTU55RJ zuZ@h2VvIHzbs0S}Rx=JT&Npr~zH34@aW`3J(qMAU6l2OVO*7qXdf5y%vo}jIt1%lg zhs_<#1?IcWhb_<+P8LFo28$a^64R5J!)#@aTGB0pEekEXET35!SjAgyv+B3{Xl-wu zZrx~o$A)4PXj5p@WAm%6nJw40#`fA=@?77!tLJvleQsxN$G6*KchjC~A7a13zSsVP zgQJ7Uq0M2^(ZDg$vDWbhi^d9LZDyT!LOXdmt#&%*^w!zIS?qk+`4<X~g?%56 z2@eae34a)26HyS+zks@6$%2*zuOhu7%OdYYnM6sVdZQJi6QY}=U&naIl*dS8tzuWk zUW(I*6U24LW8oFzvR(TOpM zEs5_rp_~TJ^wNN(wM(bCZ0;`Z6P^ce2XB(^$}i_nB)KM)Cp}7bP2Qe7nc|*Ok@8f) z7E}wKr~0SXrM^xJP1~RLDLp2=Jp-4Km~m7{5vB?IGPN`FGKaIwvx>8%%bb_(Ts9>N z5;bK**^9Ef#WdN^)PTf9vR*Qp{o-l7 zTcBI8wqSIn=gRt3(5j`YdRObOE?Pal#&6AmwS={4Ykw%TE-Wv6xh`g1Pmxy9nxe7w ze(PI{6^cd0H#WFzsN0CzDA+i-Y3`<~O&?2mB^OJrODjs>Z{}{k_?699m0x|@lC)*8 z%%N=0R?Jr6*6Z8cw;d=~F3&F?+a9vLa|dHb$&Qyhm+ZVyVOLSNi?B>BD~Ee(8aT1AWbo&CM;EEoH56tE6@EV8X%6-*|u1-NtOIZ>P7H z9s-9XhaP{M`0e$>L5F*fu#U8SXZT%h2eqT56Y5;vIn|ZYCGC#u9zGg)w718lr{jCe z@An_mJyvsE<#^c%!il02pHAkVoIaIx>gnm^(__6$dheWxJ#(!uyl?Pq(Ao3ne9xWf z_v}A;-u3*k3(gmgUSwVDy5w-FbHIL};|Kd6ItCpEJBJ*Hx-UCj?irppeBz4xmD5+f zub#UWaP88_{E^}7QP*$YNVp-r$-DXJR{E{yw{vdK+*xxMeYfPE(!GlNn)e%iH2tw% z>L5Kn>ODH}V8MesW8ASPKV|>)e!S=*`C-L`&P4Mg+egPHeJ3wJUif(YN!F8@r^P=j z|6Kdbc>FRj6+1QlT=e|YubW?}zu5oM?q%0Dy!50Qvv` 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%0Dy!50Qvv` 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%0Dy!50Qvv` z0D$NK0Cg|`0P0`>06Lfe02gqax=}m;000SaNLh0L01FZT01FZU(%pXi0000RbVXQn zQ*UN;cVTj607GSLb9r+hQ*?D?X>TA@Z*OeDr{R1600eePL_t(&f$f=ZXq9yo$3Mrl zW|5VYe;5^&)Qd>M7v(4+sjwn3%LHk?=|z$gvLc&AD zuwueyHVgPw((w4WR9%b^HnSPPdSDUIEU9Ze9jg|?gl_@%0OtV@120MXYaD&63c`d} z0xtyZj{|KJaa)H8cL7U-_PxMzNxz$!X#zzylZ2UF1snn{49Ok^wn`ctAJ?jbJmICl zE?`QLd>zmZ^p4kgHnTcl2XH{rbE)+OgqHwaj3x~5CGZL!(0-IOl-6iDFthuC4&WHD zTGFlrV>Sb`B{hzc1%z+K&uvW!JzwC&_XCH4firQo&8!)CHuyOVd=9LU^hr$r?ZABC z5@4mIjskf=xE?2QP68hUoC3bZSN&^Xx1?MJe8z;C-3Yu7oE>UD3~ZLPHRxlKWM)qQ z8}XewNF3o{&`d@dfX7nDV-H1-5KZwKy<>2n--15anaDsa%O19%`}OdQd? z44_j|!Puzsa4zsXPP#UhM!X>reV->qJHCa_$0uoF30tLhV*Y&BOFEHn97T9UV0I_4 z7`OwtGH4zOK2w74Fu`d_*qmVq*as|=)DI;H=V4|wz#QOa;2Yp)eC3Dm;4l>rDD!~J z@vE&4zb4AvAz2~3`Z>G`TrEjs5{^P#1!ZPa@vXQ8xVLhDGetgXF9bfWh;SUtY(8FP zt;kGiIt<_ueh@ExKTA#6%q|7i;7>zy(|VX8a=;&WO4@`+?EX}Q&1^BS4VaOMi`iiS z_z2JU_XGPRorVNKD-J;wvoR|VGk}0zpcB|6>1b4^N`ux~pf#0y)j2u{^sER!f|rzGG)dZ$T6t-^58{6dU0WntBI(V@F&PnF0DOp-iN64kNqQ}{ z;$*gKfJWdRyo@~nY{)e6_%CCU@I=QX;fan(!V?{T0~cWU$u0V9RR91007*qoM6N<$ Ef}%1};{X5v literal 0 HcmV?d00001 diff --git a/Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page3.imageset/Contents.json b/Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page3.imageset/Contents.json new file mode 100644 index 0000000..533abef --- /dev/null +++ b/Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page3.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "mac", + "scale" : "1x" + }, + { + "filename" : "fox3.png", + "idiom" : "mac", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page3.imageset/fox3.png b/Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page3.imageset/fox3.png new file mode 100644 index 0000000000000000000000000000000000000000..e15e2be4392683ec49db67a521070da37c90cc06 GIT binary patch literal 3990 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%0Dy!50Qvv` z0D$NK0Cg|`0P0`>06Lfe02gqax=}m;000SaNLh0L01FZT01FZU(%pXi0000RbVXQn zQ*UN;cVTj607GSLb9r+hQ*?D?X>TA@Z*OeDr{R1600g2*L_t(&f$iFV$lX;P2k_Tt z=3pj_da{>bH5jz`G$wfJ?DJi=kq@2d_U*&`P`?H z_W8lH566GrPk`!BurUK8iQuR0N9#hCPM9 z;Ro25WXtqS?FK^ySJfiifVbjsyl5U=zrweZe792zJH`QmtLkuU#9Gvte1FHqNp9`N zyzVhf@Riz89#`xPw&UC++a|PaD%ekORb7J1@xlptzm;VDgd9`Btl+9T7oW%LJK+5j z&Q5ZF2V9`4R^b!akmT;Fsx076tt6`IINXd^;20c+z1XdJ<|Uf*8bpjf`d23T__ziQ zHL_|+&%U*|A7>=lwGh$$JA6J?;2}-Oj^5u>I70K(FTojDgA;K=kLSM*T#(--IdN=t z!;Gvt20zCud$w)H$CBJP$1|mE;1fw6o^4-9q*YZ%;N>_Q7ij?r`|o)0t|S}Bo?!T# z_u=HeroZ6)BtM(k>Augy@J_rNk0e<)+c!yQSyhYiYEAUIAwza1S-#*2_RX_g+trl= zT@T^INq#gi{!)BWJC%>%lq5UoAeQbOog?u9d>Stu81lU&7gp6#+B>)sci_<^f1c+Y ztFZ~g7H?;7?w?>;&xVVzxYz#}-jw7XI!+#{YK6Ab=iwy#j`vm^tNDN#Jb@qLs|WMu zRdu=+46T@B*e^AIa|&M2*S;NRCiyE<%$BO^E}S`!p^xK&B)1RYSd?UMRc*ip_U+mz z4Ehk-LcA@>Zl)x-s+MZ8^^3=N?6M?Z8p5?6-{^gv>l*Awzo;K;&hs&*C-@HSeH|CK zVBPHTtGW;y4)V;w7U53q1npu9f~)Gy_~`@`|HL)gRrih#Oxmiw!;do^!FOxH$+HCy z;-n-`(!G~{gBB4zn{W@-%!Htw39hOWutmEIpJ~j9DyZqgluxe z{w1j`I4{Y=T?#%8cNv~lJyY0gpXkrw%U!?2n{ZZVgp*^pmdP!}rMR|h!Q1ef&Il*N z9{gMLDOcf}c(7~1n{oPx?x(R{EA+ibt94JBN%b3FTBT(xwrThIlUnV3^Hc(l5!cew zxI!z<{I+lGQQGle)B9Ye<=Eq3hbHhAEt^`bE$F{yuc2N%K0EIe0*~8pPG8f!a^han z{uUgK)%c87YC0JHfXkCyH!u69Ab1t-?Q7bF)OK;6@zZ>pN2WQSYXiBw-}ylmwrOU-Z6yKgoM1;Ch|5 zbNxB*rX+7)5Z@F_JZrTY)Qw60Ga=Wf@b!V__a(W0Y_3D)KLD!gGJJ8M`Q&kbv^!)3 wLsi{w|0>AX&hStZTzJ1$+rBo*1LJc153sif`|}XN$N&HU07*qoM6N<$f)O3B(f|Me literal 0 HcmV?d00001 diff --git a/Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page4.imageset/Contents.json b/Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page4.imageset/Contents.json new file mode 100644 index 0000000..018fb9c --- /dev/null +++ b/Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page4.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "mac", + "scale" : "1x" + }, + { + "filename" : "fox4.png", + "idiom" : "mac", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page4.imageset/fox4.png b/Box42/Resources/Assets.xcassets/42pack_icon/fox/fox_page4.imageset/fox4.png new file mode 100644 index 0000000000000000000000000000000000000000..352f1859245446e16b7a96567c9f14601342b0e1 GIT binary patch literal 3900 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%0Dy!50Qvv` z0D$NK0Cg|`0P0`>06Lfe02gqax=}m;000SaNLh0L01FZT01FZU(%pXi0000RbVXQn zQ*UN;cVTj607GSLb9r+hQ*?D?X>TA@Z*OeDr{R1600c-$L_t(&f$i9R$ev{x2Jqjx znNAdQq>`kd8;MFRKPV;fgD5SHQ2!Xx9}Yt#0;vURnrw-f2!5a_6@}>_i2PVl34T_T zSgs5)oth}>KU!G}Os8}2;UCxiY|q|3&%3>QpZDF<+5s2O{an|1ANP4&U*~yUmBjxO zYPaBB9J>YY>ewxKTu@c>a2Ph?703vj9cRIdunK>|l}X+l3GX-xuByH9J)DoHapJBn zcpp5Dqr0kAxFpHntEy%)wZ~QPfp`)JcU8eHxGc##{i1u%RW&ckL|3=zc`NQQ75q8e zi@p1*|Ah;atnRbx7k&zs;2ymGzb1G&uCb+Hcp0Bb@jgTG)op6YC_#xW?ogD>N*BpU|u&!*t2It-uCdjHVQsh9DyBy0NY`lsf1 zaQQZ<*I^Bg$HI;mUc{M6o*U|uCVFJ5tLnq}JkG&qv0#Yl&v7??f{oqA^Fu7d9@=Qu zkataLpXkc3u{6oLq5k!>R@M9@8wUvJ?SlQIu!U_^70$wWI0FYv;pk*MgSGgiHVdYU zbmcwVh!w-8Gp&b~;c(oa}m_gwV zP4s{8Tl@jf;w5|phv4HlvipBT_wKvcbCw*RE`kmC3ho>hl4ydLYg1t|-q3c*g#*Z^ zT3b5{8*yuruTN!E+S>Vztz+I~Y)k0dS_kd5{XUKay$!dtP<48e*M=Dv_QgZmI^0n_ zfeY~iEmX`k`Um5tB;OcjSY26xm8LgUC$tg0U(0cytg1h1GiGPvJ)D%}@j;E1L{%-u zPjTFKl5W5U@F>2SdF~t`onH&I(fuw~Ci(Xu<9@+~+i;Q1B6TFedYjk$6Sy(SkGCSM zx(#0)k(eIR_uI>_pVtzWH?`R|f#2cwBO!v+C*gwe|+aeoyc&Mt2v~|#n!G*W9k$nUYZ!7<9>I;#6DX7PAfRaa@@ZYKB@ zzBpB?I9<%9;O}c2;7qV8$+A)S)5B~EK23}52hM=zt|UuG<59zG-*_y>r?q3`F<7dF zkja?9KeZ!gKfadamXZ22mv>rIY-Fcu7w*sDLw)sECHeM9eVFS@ysCO0AMO5bz}ZRe z>)QTo%k*}2l5SOqpc5t~O$*Uvd9!J5miT42qq3ys%A_P)N2Pz;H1S^QCAliZHBpsxLXay!6qyw-5?Eq4Nbg zTLQF1L?YcxRSVU5fDdqbu}e zk?KwQgXfNL4gANdO!_C2w$arCr_!z;USsyMzB_=)iv20G!5=1L-6X0Q!@%L}QHQd; zx%0rNxK6#ra3(8qII~5yBRu-SD~2~oVmL1~bwquWXRyV*n$4OKUBe!ARLh9^J8cV_ zlu@lB`U1N!>8T^S$4}N{4c_^aP)*KY*CZ*^NjCiq_F2&A6YLYysO4s_c%ac3_K54~&LccEgfL+QK51Sv1 zvf@i=)UQiY*n<_oa#U(A?q+c7c}q;H^?f~s`lzm8hgGu(G0p;n|6-0|r_~&8<$2)Y zSN7z?J(O8q^ZB^$^e^HndYRmgla;)4%-S#HHq5d#zLfspxx1Ub#YH!f?nuOq-Tff0 z@4id>$2ZG11_NAyzaYih0Glty;R7*>Qy_C*<`cW)Vdq@F0o@9yaCqH&!vFvP07*qo IM6N<$g4*~61ONa4 literal 0 HcmV?d00001 diff --git a/Box42/Resources/Assets.xcassets/uibuttons/arrow-left.imageset/Contents.json b/Box42/Resources/Assets.xcassets/uibuttons/arrow-left.imageset/Contents.json new file mode 100644 index 0000000..aad174b --- /dev/null +++ b/Box42/Resources/Assets.xcassets/uibuttons/arrow-left.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "arrow-left.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/uibuttons/arrow-left.imageset/arrow-left.png b/Box42/Resources/Assets.xcassets/uibuttons/arrow-left.imageset/arrow-left.png new file mode 100644 index 0000000000000000000000000000000000000000..8a82ffc2390bdb2737dd3fc35e089d5bbdd449f9 GIT binary patch literal 402 zcmV;D0d4+?P)V3*SD_gu5H_vNs=_=h%@Z~htD{CE^XiU<#H!SoXC=4c!ApuImAj}B770YaY+s_ z{sv~k=j0e80hI8o|D*%( zJnt1n(d4@)1*)nF_@SDx2&N>gYoVi=okBbcIgdg%xb-_zsAnv}?K}*_f`C~3jiO7e zTF8(kR+kc}5}S%SM2XGiG@69bh6YK(cuR>QVRbHqAYpy5HJ0GjI(2z6VOjeZgTh*S&a((~f8T9L;-GvE{J7kU*${gRQJVEKOLC9kZIcJXkUF-5y z4z!6lR><+$#6>=HVanjP+5c>AOUo*U+uOqV>iV)dIj`CZy!^fIaqS1rbD#UZADJm+ zAjl9Tl*Z)XbSQ-3iPsG72ANJJ7Kc?XhD-{si!>NFgeaZalX2eJm95~#-S69@vf8AD-8nfEIiTudgq4)8jVXIIvO%*K6Dgh zTKTYXr-NTbg4P6Sxfz@uE$nJcK@S^uHKbH5&^oZ(dREl*9p`xYL$Ve5;*aihso0?E q8o^Mzu)LYuR;dW&&Ge^x7~b8ur7(A?b|*0W7(8A5T-G@yGywn}#g_U2 literal 0 HcmV?d00001 diff --git a/Box42/Resources/Assets.xcassets/uibuttons/circle.imageset/Contents.json b/Box42/Resources/Assets.xcassets/uibuttons/circle.imageset/Contents.json new file mode 100644 index 0000000..0b17967 --- /dev/null +++ b/Box42/Resources/Assets.xcassets/uibuttons/circle.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Ellipse 1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/uibuttons/circle.imageset/Ellipse 1.png b/Box42/Resources/Assets.xcassets/uibuttons/circle.imageset/Ellipse 1.png new file mode 100644 index 0000000000000000000000000000000000000000..f0350280d9a6a51f1d3b6ba468968a8b81b776b9 GIT binary patch literal 570 zcmV-A0>%A_P)N2Pz;H1S^QCAliZHBpsxLXay!6qyw-5?Eq4Nbg zTLQF1L?YcxRSVU5fDdqbu}e zk?KwQgXfNL4gANdO!_C2w$arCr_!z;USsyMzB_=)iv20G!5=1L-6X0Q!@%L}QHQd; zx%0rNxK6#ra3(8qII~5yBRu-SD~2~oVmL1~bwquWXRyV*n$4OKUBe!ARLh9^J8cV_ zlu@lB`U1N!>8T^S$4}N{4c_^aP)*KY*CZ*^NjCiq_F2&A6YLYysO4s_c%ac3_K54~&LccEgfL+QK51Sv1 zvf@i=)UQiY*n<_oa#U(A?q+c7c}q;H^?f~s`lzm8hgGu(G0p;n|6-0|r_~&8<$2)Y zSN7z?J(O8q^ZB^$^e^HndYRmgla;)4%-S#HHq5d#zLfspxx1Ub#YH!f?nuOq-Tff0 z@4id>$2ZG11_NAyzaYih0Glty;R7*>Qy_C*<`cW)Vdq@F0o@9yaCqH&!vFvP07*qo IM6N<$g4*~61ONa4 literal 0 HcmV?d00001 diff --git a/Box42/Resources/Assets.xcassets/uibuttons/rotate-right.imageset/Contents.json b/Box42/Resources/Assets.xcassets/uibuttons/rotate-right.imageset/Contents.json new file mode 100644 index 0000000..c2f10ea --- /dev/null +++ b/Box42/Resources/Assets.xcassets/uibuttons/rotate-right.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "rotate-right.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/uibuttons/rotate-right.imageset/rotate-right.png b/Box42/Resources/Assets.xcassets/uibuttons/rotate-right.imageset/rotate-right.png new file mode 100644 index 0000000000000000000000000000000000000000..662594e860f6f4f8086797f7a5dac1cba4a4139c GIT binary patch literal 639 zcmV-_0)YLAP)`z-sxzmdbaqW0~xUNJu27Y=?jKam;Atj zzTjIDv!E}uWIR<_`ra-{Ojqm*znt0)9T9Fx%oSnYx$CTx>*NQAp&hfO|I)X0^7+$a zzBp#hfk(KGy^?9jOSq)Y%VQYzoHcCgoc|TOtRf<%KCtw+ zT;~07_LszzjCUvBv!*YX6+^w18~laJ?ns9xIH$+zz#Dem_p|Nwnb*4_->$PE!M~ zARK5F@Qr;{=^Np(gJE(agfo|a>dYDSf)hCu}K zH7Mamiv09Y=*}-|pC)a{J`}8dFbqK7(`J%z=e_7F&>e-UE&q&QPlBoenU*cg&Jq++ z3bkZEO3{0TM{FGsTHe@uG9rT=68Y?xZF1}YPYf;f_@7w@d*e;|GkBzn16#Pm`;6fc zTL(B@!q5Bk?m$pP2l^&D&^NXY+CNLX7S?Cws$%?)T-7#Lc zcm()TXu2jU5Kd4ktga-qvN-J(|TlRi&sV_zU}zBKO;9&~z@_BBr2-bSeh1T4xb zM2c!vE);lmuC=fwQ7z+9M}hvJRluuq7X>#{aW}zbCAh5ZP`$|8eYOGGtaRd#@uKz} z9m5GMAf;nqlE4vxd{2b%fI~JJY5Rz&4Cf;sG5IPBk$axyI+b;e}Gqh5RdlFEd z6&MaQ3;4orRQkg3*um4eW2PWjyRC&v3v#OEUdv;R-lh=Mpd*U*lhqwNH?t^Qhk%)@ z5^*eGb{XZl_QTr$oiTE5YB}I?1k9q7i07@a6`pI#xyK)4v`>bz1G$zhsyl^7o~DE> zzLPDD-U|X~I{=~Om3=2Ca)cpadf&Dwu*R7%Lc8#XUXF0*efrZ7qb>v3A|7t@5Mt1F z0GvxU0&dfL05>58&^IZ7zG*vv=v~Ai+NR3@o)8bW2}sPpkNLs8BBs#SDK+iI-RywsL!7!j?EbYr$h4&!-IAu>tAJu>_e1#Kp>#3LM%|O z$_)ixovSTuNtDZYWGK)dGz)lD?yTVEEAD1EuLRqg4b_XTsaS+Si~P-l6;o5GF_B0l2EZ>*&l1;1dIJ~$0000 Void)? - var lastAddedButton: NSView? - var loginInfo: NSView? - - let tableView: NSTableView = { - let tableView = NSTableView() - tableView.autoresizingMask = [.width, .height] - tableView.headerView = nil - - let column = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("column1")) - column.title = "" - column.width = tableView.frame.size.width - column.resizingMask = .autoresizingMask - - tableView.addTableColumn(column) - - return tableView - }() - - let scrollView: NSScrollView = { - let scrollView = NSScrollView() - scrollView.borderType = .bezelBorder - return scrollView - }() - - private var isDeleteButtonsVisible: Bool = false - let toggleDeleteButton: NSButton = { - let button = NSButton(title: "-", target: nil, action: nil) - button.bezelStyle = .rounded - return button - }() - - @objc func toggleDeleteButtons() { - print("toggleDeleteButtons") - isDeleteButtonsVisible.toggle() - - let numberOfRows = tableView.numberOfRows - for row in 0.. Void) { - print("init") - self.clickAction = clickAction - super.init(frame: BoxSizeManager.shared.buttonGroupSizeNSRect) - // setupButtons() - - for item in boxVM.webViewURL.URLstring { - buttonArray.append(item.name) - } - - scrollView.documentView = tableView - super.addSubview(scrollView) - scrollView.snp.makeConstraints { make in - make.edges.equalToSuperview() - } - - tableView.dataSource = self - tableView.delegate = self - tableView.registerForDraggedTypes([NSPasteboard.PasteboardType.string]) - - super.addSubview(toggleDeleteButton) - toggleDeleteButton.target = self - toggleDeleteButton.action = #selector(toggleDeleteButtons) - toggleDeleteButton.snp.makeConstraints { make in - make.centerX.equalToSuperview() - make.bottom.equalToSuperview().offset(0) - } - - super.addSubview(addButton) - addButton.target = self - addButton.action = #selector(addCell) - addButton.snp.makeConstraints { make in - make.centerX.equalToSuperview() - make.bottom.equalTo(toggleDeleteButton.snp.top).offset(-10) - - } - } - - @objc func addCell() { - buttonArray.append("New Cell") // 'New Cell'은 신규 셀의 이름입니다. 필요에 따라 변경하십시오. - tableView.reloadData() - } - - 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 - } -} - -//NSTableViewDelegate -extension BoxButtonViewGroup: NSTableViewDataSource, NSTableViewDelegate { - func numberOfRows(in tableView: NSTableView) -> Int { - return buttonArray.count - } - - func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { - let cellView = CustomTableCellView() - cellView.layer?.backgroundColor = NSColor.red.cgColor - cellView.rowIndex = row - - let button = NSButton(title: buttonArray[row], target: self, action: #selector(buttonClicked(_:))) - button.tag = row - cellView.addSubview(button) - - let fontSize: CGFloat = 16.0 - button.font = NSFont.systemFont(ofSize: fontSize) - button.setButtonType(.momentaryLight) - button.bezelStyle = .shadowlessSquare - - button.wantsLayer = true - button.layer?.borderWidth = 0 - button.layer?.cornerRadius = 10 - button.layer?.backgroundColor = NSColor.orange.cgColor - - button.snp.makeConstraints { make in - make.width.equalTo(100) - make.height.equalTo(50) - make.top.bottom.equalToSuperview().inset(5) - } - - let deleteButton = NSButton(title: "삭제", target: self, action: #selector(deleteButtonClicked(_:))) - deleteButton.tag = row - deleteButton.bezelStyle = .shadowlessSquare - deleteButton.wantsLayer = true - deleteButton.layer?.borderWidth = 0 - deleteButton.layer?.cornerRadius = 10 - deleteButton.layer?.backgroundColor = NSColor.red.cgColor - - cellView.addSubview(deleteButton) - deleteButton.snp.makeConstraints { make in - make.trailing.equalToSuperview().offset(-5) - make.top.bottom.equalToSuperview().inset(5) - } - cellView.deleteButton = deleteButton - cellView.deleteButton.isHidden = !isDeleteButtonsVisible - - return cellView - } - - - @objc func deleteButtonClicked(_ sender: NSButton) { - let row = sender.tag - print("Delete button clicked in row: \(row)") - - // 데이터 목록에서 항목 제거 - buttonArray.remove(at: row) - tableView.reloadData() - // 테이블 뷰에서 행 제거 및 셀 인덱스 업데이트 - tableView.removeRows(at: IndexSet(integer: row), withAnimation: .effectFade) - for (_, subview) in tableView.subviews.enumerated() { - guard let cellView = subview as? CustomTableCellView else { - continue - } - - cellView.rowIndex = tableView.row(for: cellView) - cellView.button.tag = cellView.rowIndex - cellView.deleteButton.tag = cellView.rowIndex - - cellView.button.title = buttonArray[cellView.rowIndex] - } - } - - - func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat { - return 40.0 - } - - @objc func buttonClicked(_ sender: NSButton) { - let row = sender.tag - print("Button clicked in row: \(row)") - } - - // Drag and Drop methods - func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? { - let pasteboardItem = NSPasteboardItem() - pasteboardItem.setString(String(row), forType: .string) - return pasteboardItem - } - - func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation { - if dropOperation == .above { - return .move - } else { - return [] - } - } - - func tableView(_ aTableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool { - guard let str = info.draggingPasteboard.string(forType: .string), let from = Int(str) else { - return false - } - - let to = (from < row) ? row - 1 : row - let item = buttonArray[from] - buttonArray.remove(at: from) - buttonArray.insert(item, at: to) - tableView.reloadData() - - for (_, subview) in tableView.subviews.enumerated() { - guard let cellView = subview as? CustomTableCellView else { - continue - } - - cellView.button.title = buttonArray[cellView.rowIndex] - } - - return true - } -} diff --git a/Box42/Window/BoxWindowController.swift b/Box42/Window/BoxWindowController.swift deleted file mode 100644 index 38165ca..0000000 --- a/Box42/Window/BoxWindowController.swift +++ /dev/null @@ -1,136 +0,0 @@ -// -// BoxWindowController.swift -// Box42 -// -// Created by Chanhee Kim on 8/11/23. -// - -import Cocoa - -class BoxWindowController: NSWindowController, NSToolbarDelegate, NSWindowDelegate { - override init(window: NSWindow?) { - let contentRect = BoxSizeManager.shared.boxViewSizeNSRect - let styleMask: NSWindow.StyleMask = [.resizable, .closable, .miniaturizable, .fullSizeContentView] - let windowInstance = NSWindow(contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false) - - windowInstance.titlebarAppearsTransparent = true - windowInstance.titleVisibility = .hidden - windowInstance.title = "Box" - windowInstance.isReleasedWhenClosed = false - windowInstance.isOpaque = false - windowInstance.backgroundColor = .clear - windowInstance.isMovableByWindowBackground = true - - let boxViewController = BoxBaseContainerViewController(nibName: nil, bundle: nil) - windowInstance.contentViewController = boxViewController - - 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.toggleShowWindow() - 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 - } - } - - @objc func toggleSidebar() { - print("sidebar") - } - - @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") -} diff --git a/Box42/Window/View/WindowCloseButton.swift b/Box42/Window/View/WindowCloseButton.swift deleted file mode 100644 index 0e9a747..0000000 --- a/Box42/Window/View/WindowCloseButton.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// WindowCloseButton.swift -// Box42 -// -// Created by Chanhee Kim on 8/23/23. -// - -import AppKit - -class WindowCloseButton: NSButton { - - private var callback: (() -> Void)? - - init(image: NSImage, completion: @escaping () -> Void) { - super.init(frame: .zero) - - self.title = "X" // 기본적인 X 모양으로 표시. 이미지나 다른 디자인을 원하시면 변경하실 수 있습니다. - self.bezelStyle = .texturedRounded - self.target = self - self.action = #selector(closeAction) - self.callback = completion - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - @objc func closeAction() { - callback?() - } -} diff --git a/Box42/Window/View/WindowMaximizeButton.swift b/Box42/Window/View/WindowMaximizeButton.swift deleted file mode 100644 index dde3691..0000000 --- a/Box42/Window/View/WindowMaximizeButton.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// WindowMaximizeButton.swift -// Box42 -// -// Created by Chanhee Kim on 8/23/23. -// - -import AppKit - -class WindowMaximizeButton: NSButton { - - private var callback: (() -> Void)? - - init(image: NSImage, completion: @escaping () -> Void) { - super.init(frame: .zero) - - self.title = "□" // 기본적인 □ 모양으로 표시. 변경 가능. - self.bezelStyle = .texturedRounded - self.target = self - self.action = #selector(maximizeAction) - self.callback = completion - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - @objc func maximizeAction() { - callback?() - } -} diff --git a/Box42/Window/View/WindowMinimizeButton.swift b/Box42/Window/View/WindowMinimizeButton.swift deleted file mode 100644 index e940fb5..0000000 --- a/Box42/Window/View/WindowMinimizeButton.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// WindowMinimizeButton.swift -// Box42 -// -// Created by Chanhee Kim on 8/23/23. -// - -import AppKit - -class WindowMinimizeButton: NSButton { - - private var callback: (() -> Void)? - - init(image: NSImage, completion: @escaping () -> Void) { - super.init(frame: .zero) - - self.title = "_" // 기본적인 _ 모양으로 표시. 변경 가능. - self.bezelStyle = .texturedRounded - self.target = self - self.action = #selector(minimizeAction) - self.callback = completion - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - @objc func minimizeAction() { - callback?() - } -} diff --git a/Box42/Window/View/WindowViewGroup.swift b/Box42/Window/View/WindowViewGroup.swift deleted file mode 100644 index f96abec..0000000 --- a/Box42/Window/View/WindowViewGroup.swift +++ /dev/null @@ -1,56 +0,0 @@ -// -// WindowViewGroup.swift -// Box42 -// -// Created by Chanhee Kim on 8/23/23. -// - -import AppKit -import SnapKit - -class WindowViewGroup: NSView { - lazy var windowClose: WindowCloseButton = WindowCloseButton(image: NSImage(imageLiteralResourceName: "sidebar.leading"), completion: { self.close?() }) - lazy var windowMinimize: WindowMinimizeButton = WindowMinimizeButton(image: NSImage(imageLiteralResourceName: "arrow.left"), completion: { self.minimize?()} ) - lazy var windowMaximize: WindowMaximizeButton = WindowMaximizeButton(image: NSImage(imageLiteralResourceName: "arrow.right"), completion: { self.maximize?() }) - - var close: (() -> Void)? - var minimize: (() -> Void)? - var maximize: (() -> 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(windowClose) - self.addSubview(windowMinimize) - self.addSubview(windowMaximize) - } - - private func setupConstraints() { - - windowClose.snp.makeConstraints { make in - make.top.left.bottom.equalToSuperview() - make.width.equalTo(windowMinimize) - } - - windowMinimize.snp.makeConstraints { make in - make.top.bottom.equalTo(windowClose) - make.left.equalTo(windowClose.snp.right).offset(10) - make.width.equalTo(windowMaximize) - } - - windowMaximize.snp.makeConstraints { make in - make.top.right.bottom.equalToSuperview() - make.left.equalTo(windowMinimize.snp.right).offset(10) - } - } -} diff --git a/Box42/Window/WindowButtonViewController.swift b/Box42/Window/WindowButtonViewController.swift deleted file mode 100644 index 511ef8c..0000000 --- a/Box42/Window/WindowButtonViewController.swift +++ /dev/null @@ -1,36 +0,0 @@ -// -// WindowButtonViewController.swift -// Box42 -// -// Created by Chanhee Kim on 8/23/23. -// - -import Cocoa - -class WindowButtonViewController: NSViewController { - override func loadView() { - let windowViewGroup = WindowViewGroup() - - windowViewGroup.close = windowClose - windowViewGroup.minimize = windowMin - windowViewGroup.maximize = windowMax - - self.view = windowViewGroup - } - - override func viewDidLoad() { - super.viewDidLoad() - } - - func windowClose() { - print("close") - } - - func windowMin() { - print("min") - } - - func windowMax() { - print("max") - } -} From ae3d2099e97a11bf2f556c23430a3a217e54c228 Mon Sep 17 00:00:00 2001 From: chanhihi Date: Fri, 25 Aug 2023 06:14:31 +0900 Subject: [PATCH 06/15] =?UTF-8?q?chore:=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EB=B6=80=EB=B6=84=20=EC=82=AD=EC=A0=9C=20=EB=B0=8F?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Box42.xcodeproj/project.pbxproj | 30 ++++++++++++++---- .../Assets.xcassets/uibuttons/Ellipse 1.png | Bin 570 -> 0 bytes 2 files changed, 23 insertions(+), 7 deletions(-) delete mode 100644 Box42/Resources/Assets.xcassets/uibuttons/Ellipse 1.png diff --git a/Box42.xcodeproj/project.pbxproj b/Box42.xcodeproj/project.pbxproj index 0d9fb62..337d15f 100644 --- a/Box42.xcodeproj/project.pbxproj +++ b/Box42.xcodeproj/project.pbxproj @@ -52,6 +52,7 @@ DE3FF3752A978AB8009C88EF /* WindowViewGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE3FF3712A978AB8009C88EF /* WindowViewGroup.swift */; }; DE3FF3762A978AB8009C88EF /* WindowCloseButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE3FF3722A978AB8009C88EF /* WindowCloseButton.swift */; }; DE3FF3772A978AB8009C88EF /* WindowMinimizeButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE3FF3732A978AB8009C88EF /* WindowMinimizeButton.swift */; }; + DE3FF3A32A97D2A6009C88EF /* DisplayURLTextfield.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE3FF3A22A97D2A6009C88EF /* DisplayURLTextfield.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 */; }; @@ -67,6 +68,7 @@ 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 */; }; + 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 */; }; @@ -122,6 +124,7 @@ DE3FF3712A978AB8009C88EF /* WindowViewGroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowViewGroup.swift; sourceTree = ""; }; DE3FF3722A978AB8009C88EF /* WindowCloseButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowCloseButton.swift; sourceTree = ""; }; DE3FF3732A978AB8009C88EF /* WindowMinimizeButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowMinimizeButton.swift; sourceTree = ""; }; + DE3FF3A22A97D2A6009C88EF /* DisplayURLTextfield.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayURLTextfield.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 = ""; }; @@ -137,6 +140,7 @@ 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 = ""; }; + 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; }; @@ -179,16 +183,17 @@ children = ( DE77BA542A82636500713683 /* Shared */, DEF749302A85655E00D987C8 /* Extensions */, + DE018C0E2A509C0C00FF0AA3 /* Menubar */, + DE9DA8122A97F1E2001C0D3B /* ButtonGroup */, DE1F1A202A8B50CA00A88DD8 /* Main */, - DEB862E82A853F6800278FCD /* Window */, DEB862D22A8511D600278FCD /* Scripts */, DE874F512A591EC600FC3B77 /* Preferences */, DE018C0C2A509BDF00FF0AA3 /* Resources */, DE018C062A509B9000FF0AA3 /* System */, DE018C082A509BB500FF0AA3 /* WebView */, + DEB862E82A853F6800278FCD /* WindowButton */, DE0A917D2A8F864300D1D6F1 /* Toolbar */, DE4407F82A923E5B0091937A /* FunctionButton */, - DE018C0E2A509C0C00FF0AA3 /* Menubar */, ); path = Box42; sourceTree = ""; @@ -271,6 +276,7 @@ children = ( DE0A91A62A8FC66600D1D6F1 /* SideBarLeading.swift */, DE0A91822A8F889000D1D6F1 /* GoHomePageViaToolbar().swift */, + DE3FF3A22A97D2A6009C88EF /* DisplayURLTextfield.swift */, DE0A918F2A8F88CA00D1D6F1 /* DisplayURLInToolbar.swift */, DE0A918C2A8F88BC00D1D6F1 /* GoBackInToolbar.swift */, DE0A91892A8F88A900D1D6F1 /* GoForwardInToolbar.swift */, @@ -294,6 +300,7 @@ DE4408202A9297EE0091937A /* View */, DE1F1A192A8B50C500A88DD8 /* BoxBaseContainerViewController.swift */, DE4408142A92750D0091937A /* keyDown+BoxBaseContainerViewController.swift */, + DEB862E92A853F7F00278FCD /* BoxWindowController.swift */, ); name = Main; sourceTree = ""; @@ -302,8 +309,8 @@ isa = PBXGroup; children = ( DE3FF3722A978AB8009C88EF /* WindowCloseButton.swift */, - DE3FF3702A978AB8009C88EF /* WindowMaximizeButton.swift */, DE3FF3732A978AB8009C88EF /* WindowMinimizeButton.swift */, + DE3FF3702A978AB8009C88EF /* WindowMaximizeButton.swift */, DE3FF3712A978AB8009C88EF /* WindowViewGroup.swift */, ); path = View; @@ -334,7 +341,6 @@ DE4408202A9297EE0091937A /* View */ = { isa = PBXGroup; children = ( - DE1F1A1B2A8B50C500A88DD8 /* BoxButtonViewGroup.swift */, DE1F1A1A2A8B50C500A88DD8 /* BoxContentsViewGroup.swift */, DE24E6372A8FE10300E29F5D /* BoxBaseSplitView.swift */, ); @@ -363,6 +369,15 @@ path = Preferences; sourceTree = ""; }; + DE9DA8122A97F1E2001C0D3B /* ButtonGroup */ = { + isa = PBXGroup; + children = ( + DE1F1A1B2A8B50C500A88DD8 /* BoxButtonViewGroup.swift */, + DE9DA8132A97F20E001C0D3B /* ButtonGroupViewController.swift */, + ); + path = ButtonGroup; + sourceTree = ""; + }; DEB862D22A8511D600278FCD /* Scripts */ = { isa = PBXGroup; children = ( @@ -385,14 +400,13 @@ path = sh; sourceTree = ""; }; - DEB862E82A853F6800278FCD /* Window */ = { + DEB862E82A853F6800278FCD /* WindowButton */ = { isa = PBXGroup; children = ( DE3FF36F2A978A6E009C88EF /* View */, DE3FF3692A978A57009C88EF /* WindowButtonViewController.swift */, - DEB862E92A853F7F00278FCD /* BoxWindowController.swift */, ); - path = Window; + path = WindowButton; sourceTree = ""; }; DEF749302A85655E00D987C8 /* Extensions */ = { @@ -493,8 +507,10 @@ DE018BB82A5099F900FF0AA3 /* Box42.xcdatamodeld in Sources */, DE874F542A591F1400FC3B77 /* PreferencesView.swift in Sources */, DE0A91982A8F977F00D1D6F1 /* ToolbarViewController.swift in Sources */, + DE9DA8142A97F20E001C0D3B /* ButtonGroupViewController.swift in Sources */, DE4408082A9240300091937A /* BoxFunctionButtonView.swift in Sources */, DE3FF3742A978AB8009C88EF /* WindowMaximizeButton.swift in Sources */, + DE3FF3A32A97D2A6009C88EF /* DisplayURLTextfield.swift in Sources */, DE77BA562A82637900713683 /* StateManager.swift in Sources */, DE1F1A1C2A8B50C500A88DD8 /* BoxBaseContainerViewController.swift in Sources */, DE018BE72A509B1E00FF0AA3 /* WebViewController.swift in Sources */, diff --git a/Box42/Resources/Assets.xcassets/uibuttons/Ellipse 1.png b/Box42/Resources/Assets.xcassets/uibuttons/Ellipse 1.png deleted file mode 100644 index f0350280d9a6a51f1d3b6ba468968a8b81b776b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 570 zcmV-A0>%A_P)N2Pz;H1S^QCAliZHBpsxLXay!6qyw-5?Eq4Nbg zTLQF1L?YcxRSVU5fDdqbu}e zk?KwQgXfNL4gANdO!_C2w$arCr_!z;USsyMzB_=)iv20G!5=1L-6X0Q!@%L}QHQd; zx%0rNxK6#ra3(8qII~5yBRu-SD~2~oVmL1~bwquWXRyV*n$4OKUBe!ARLh9^J8cV_ zlu@lB`U1N!>8T^S$4}N{4c_^aP)*KY*CZ*^NjCiq_F2&A6YLYysO4s_c%ac3_K54~&LccEgfL+QK51Sv1 zvf@i=)UQiY*n<_oa#U(A?q+c7c}q;H^?f~s`lzm8hgGu(G0p;n|6-0|r_~&8<$2)Y zSN7z?J(O8q^ZB^$^e^HndYRmgla;)4%-S#HHq5d#zLfspxx1Ub#YH!f?nuOq-Tff0 z@4id>$2ZG11_NAyzaYih0Glty;R7*>Qy_C*<`cW)Vdq@F0o@9yaCqH&!vFvP07*qo IM6N<$g4*~61ONa4 From 74378482c249ae19e8610ec8176b8b1934c292c8 Mon Sep 17 00:00:00 2001 From: chanhihi Date: Fri, 25 Aug 2023 06:15:09 +0900 Subject: [PATCH 07/15] =?UTF-8?q?fix:=20window=20controller=EB=A1=9C=20?= =?UTF-8?q?=EC=A0=91=EC=86=8D=EC=8B=9C=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20=EC=82=AC=EC=9A=A9=EB=AA=BB=ED=95=98?= =?UTF-8?q?=EB=8D=98=20=EA=B2=83=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Box42/BoxWindowController.swift | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Box42/BoxWindowController.swift diff --git a/Box42/BoxWindowController.swift b/Box42/BoxWindowController.swift new file mode 100644 index 0000000..3a3babf --- /dev/null +++ b/Box42/BoxWindowController.swift @@ -0,0 +1,41 @@ +// +// BoxWindowController.swift +// Box42 +// +// Created by Chanhee Kim on 8/11/23. +// + +import Cocoa + +class BoxWindowController: NSWindowController, NSWindowDelegate { + override init(window: NSWindow?) { + let contentRect = BoxSizeManager.shared.boxViewSizeNSRect + let styleMask: NSWindow.StyleMask = [.resizable, .titled, .fullSizeContentView, .closable, .miniaturizable] + let windowInstance = NSWindow(contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false) + super.init(window: windowInstance) + windowInstance.delegate = self + + windowInstance.title = "Box" + windowInstance.titlebarAppearsTransparent = true + windowInstance.titleVisibility = .hidden + windowInstance.isReleasedWhenClosed = false + windowInstance.isMovableByWindowBackground = true + + let boxViewController = BoxBaseContainerViewController(nibName: nil, bundle: nil) + windowInstance.contentViewController = boxViewController + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +extension BoxWindowController { + func windowWillClose(_ notification: Notification) { + StateManager.shared.showWindow = false + } + + func windowWillMiniaturize(_ notification: Notification) { + StateManager.shared.showWindow = false + } +} From dce80e9847e335b87aa6ae07ce240f7d243ece27 Mon Sep 17 00:00:00 2001 From: chanhihi Date: Fri, 25 Aug 2023 06:16:52 +0900 Subject: [PATCH 08/15] =?UTF-8?q?refactor:=20=EA=B5=AC=EC=A1=B0=EB=A5=BC?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=ED=95=A9=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Box42/ButtonGroup/BoxButtonViewGroup.swift | 309 ++++++++++++++++++ .../ButtonGroupViewController.swift | 35 ++ 2 files changed, 344 insertions(+) create mode 100644 Box42/ButtonGroup/BoxButtonViewGroup.swift create mode 100644 Box42/ButtonGroup/ButtonGroupViewController.swift diff --git a/Box42/ButtonGroup/BoxButtonViewGroup.swift b/Box42/ButtonGroup/BoxButtonViewGroup.swift new file mode 100644 index 0000000..512d3c0 --- /dev/null +++ b/Box42/ButtonGroup/BoxButtonViewGroup.swift @@ -0,0 +1,309 @@ +// +// BoxButtonView.swift +// Box42 +// +// Created by Chanhee Kim on 8/11/23. +// + +import Cocoa +import SnapKit + +class CustomTableCellView: NSTableCellView { + var button: NSButton! + var deleteButton: NSButton! + var rowIndex: Int! +} + +class BoxButtonViewGroup: NSView { + var boxVM: WebViewModel = WebViewModel() + var pinSwitch : NSSwitch = NSSwitch() + var clickAction: ((NSButton) -> Void)? + var lastAddedButton: NSView? + var loginInfo: NSView? + + let tableView: NSTableView = { + let tableView = NSTableView() + tableView.autoresizingMask = [.width, .height] + tableView.headerView = nil + + let column = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("column1")) + column.title = "" + column.width = tableView.frame.size.width + column.resizingMask = .autoresizingMask + + tableView.addTableColumn(column) + + return tableView + }() + + let scrollView: NSScrollView = { + let scrollView = NSScrollView() + scrollView.borderType = .bezelBorder + return scrollView + }() + + private var isDeleteButtonsVisible: Bool = false + let toggleDeleteButton: NSButton = { + let button = NSButton(title: "-", target: nil, action: nil) + button.bezelStyle = .rounded + return button + }() + + @objc func toggleDeleteButtons() { + print("toggleDeleteButtons") + isDeleteButtonsVisible.toggle() + + let numberOfRows = tableView.numberOfRows + for row in 0.. Void) { + print("init") + self.clickAction = clickAction + super.init(frame: BoxSizeManager.shared.buttonGroupSizeNSRect) + // setupButtons() + + for item in boxVM.webViewURL.URLstring { + buttonArray.append(item.name) + } + + scrollView.documentView = tableView + super.addSubview(scrollView) + scrollView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + + tableView.dataSource = self + tableView.delegate = self + tableView.registerForDraggedTypes([NSPasteboard.PasteboardType.string]) + + super.addSubview(toggleDeleteButton) + toggleDeleteButton.target = self + toggleDeleteButton.action = #selector(toggleDeleteButtons) + toggleDeleteButton.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.bottom.equalToSuperview().offset(0) + } + + super.addSubview(addButton) + addButton.target = self + addButton.action = #selector(addCell) + addButton.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.bottom.equalTo(toggleDeleteButton.snp.top).offset(-10) + + } + } + + @objc func addCell() { + buttonArray.append("New Cell") // 'New Cell'은 신규 셀의 이름입니다. 필요에 따라 변경하십시오. + tableView.reloadData() + } + + 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 + } +} + +//NSTableViewDelegate +extension BoxButtonViewGroup: NSTableViewDataSource, NSTableViewDelegate { + func numberOfRows(in tableView: NSTableView) -> Int { + return buttonArray.count + } + + func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { + let cellView = CustomTableCellView() + cellView.layer?.backgroundColor = NSColor.red.cgColor + cellView.rowIndex = row + + let button = NSButton(title: buttonArray[row], target: self, action: #selector(buttonClicked(_:))) + button.tag = row + cellView.addSubview(button) + + let fontSize: CGFloat = 16.0 + button.font = NSFont.systemFont(ofSize: fontSize) + button.setButtonType(.momentaryLight) + button.bezelStyle = .shadowlessSquare + + button.wantsLayer = true + button.layer?.borderWidth = 0 + button.layer?.cornerRadius = 10 + button.layer?.backgroundColor = NSColor.orange.cgColor + + button.snp.makeConstraints { make in + make.width.equalTo(100) + make.height.equalTo(50) + make.top.bottom.equalToSuperview().inset(5) + } + + let deleteButton = NSButton(title: "삭제", target: self, action: #selector(deleteButtonClicked(_:))) + deleteButton.tag = row + deleteButton.bezelStyle = .shadowlessSquare + deleteButton.wantsLayer = true + deleteButton.layer?.borderWidth = 0 + deleteButton.layer?.cornerRadius = 10 + deleteButton.layer?.backgroundColor = NSColor.red.cgColor + + cellView.addSubview(deleteButton) + deleteButton.snp.makeConstraints { make in + make.trailing.equalToSuperview().offset(-5) + make.top.bottom.equalToSuperview().inset(5) + } + cellView.deleteButton = deleteButton + cellView.deleteButton.isHidden = !isDeleteButtonsVisible + + return cellView + } + + + @objc func deleteButtonClicked(_ sender: NSButton) { + let row = sender.tag + print("Delete button clicked in row: \(row)") + + // 데이터 목록에서 항목 제거 + buttonArray.remove(at: row) + tableView.reloadData() + // 테이블 뷰에서 행 제거 및 셀 인덱스 업데이트 + tableView.removeRows(at: IndexSet(integer: row), withAnimation: .effectFade) + for (_, subview) in tableView.subviews.enumerated() { + guard let cellView = subview as? CustomTableCellView else { + continue + } + + cellView.rowIndex = tableView.row(for: cellView) + cellView.button.tag = cellView.rowIndex + cellView.deleteButton.tag = cellView.rowIndex + + cellView.button.title = buttonArray[cellView.rowIndex] + } + } + + + func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat { + return 40.0 + } + + @objc func buttonClicked(_ sender: NSButton) { + let row = sender.tag + print("Button clicked in row: \(row)") + } + + // Drag and Drop methods + func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? { + let pasteboardItem = NSPasteboardItem() + pasteboardItem.setString(String(row), forType: .string) + return pasteboardItem + } + + func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation { + if dropOperation == .above { + return .move + } else { + return [] + } + } + + func tableView(_ aTableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool { + guard let str = info.draggingPasteboard.string(forType: .string), let from = Int(str) else { + return false + } + + let to = (from < row) ? row - 1 : row + let item = buttonArray[from] + buttonArray.remove(at: from) + buttonArray.insert(item, at: to) + tableView.reloadData() + + for (_, subview) in tableView.subviews.enumerated() { + guard let cellView = subview as? CustomTableCellView else { + continue + } + + cellView.button.title = buttonArray[cellView.rowIndex] + } + + return true + } +} diff --git a/Box42/ButtonGroup/ButtonGroupViewController.swift b/Box42/ButtonGroup/ButtonGroupViewController.swift new file mode 100644 index 0000000..2101feb --- /dev/null +++ b/Box42/ButtonGroup/ButtonGroupViewController.swift @@ -0,0 +1,35 @@ +// +// ButtonGroupViewController.swift +// Box42 +// +// Created by Chanhee Kim on 8/25/23. +// + +import Cocoa + +class ButtonGroupViewController: NSViewController { + override func loadView() { +// let ButtonViewGroup = BoxButtonViewGroup() + let ButtonViewGroup = NSView() + ButtonViewGroup.wantsLayer = true + ButtonViewGroup.layer?.backgroundColor = NSColor.black.cgColor + self.view = ButtonViewGroup + } + + override func viewDidLoad() { + super.viewDidLoad() + } + + func preference() { + print("preference") + } + + func pin() { + print("pin") + } + + func quit() { + print("quit") + NSApplication.shared.terminate(self) + } +} From cc0612467124c90bc93a976ed66ebcf6b1c7b615 Mon Sep 17 00:00:00 2001 From: chanhihi Date: Fri, 25 Aug 2023 06:17:37 +0900 Subject: [PATCH 09/15] =?UTF-8?q?fix:=20button=20=EB=B0=B0=EA=B2=BD=20?= =?UTF-8?q?=ED=88=AC=EB=AA=85=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Box42/FunctionButton/View/BoxFunctionButtonView.swift | 4 +++- Box42/FunctionButton/View/PinButtonView.swift | 4 +++- Box42/FunctionButton/View/PreferenceButtonView.swift | 4 +++- Box42/FunctionButton/View/QuitButtonView.swift | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Box42/FunctionButton/View/BoxFunctionButtonView.swift b/Box42/FunctionButton/View/BoxFunctionButtonView.swift index 01eb568..b0fd5fc 100644 --- a/Box42/FunctionButton/View/BoxFunctionButtonView.swift +++ b/Box42/FunctionButton/View/BoxFunctionButtonView.swift @@ -15,7 +15,9 @@ class BoxFunctionButtonView: NSButton { super.init(frame: .zero) self.image = image - self.bezelStyle = .texturedRounded + self.isBordered = false // 버튼의 테두리를 제거 + self.wantsLayer = true + self.layer?.backgroundColor = NSColor.clear.cgColor self.target = self self.action = #selector(BoxFunction) self.callback = completion diff --git a/Box42/FunctionButton/View/PinButtonView.swift b/Box42/FunctionButton/View/PinButtonView.swift index a91036b..f80e9d3 100644 --- a/Box42/FunctionButton/View/PinButtonView.swift +++ b/Box42/FunctionButton/View/PinButtonView.swift @@ -15,7 +15,9 @@ class PinButtonView: NSButton { super.init(frame: .zero) self.image = image - self.bezelStyle = .texturedRounded + self.isBordered = false // 버튼의 테두리를 제거 + self.wantsLayer = true + self.layer?.backgroundColor = NSColor.clear.cgColor self.target = self self.action = #selector(pin) self.callback = completion diff --git a/Box42/FunctionButton/View/PreferenceButtonView.swift b/Box42/FunctionButton/View/PreferenceButtonView.swift index ffc8102..7c7a324 100644 --- a/Box42/FunctionButton/View/PreferenceButtonView.swift +++ b/Box42/FunctionButton/View/PreferenceButtonView.swift @@ -14,7 +14,9 @@ class PreferenceButtonView: NSButton { init(image: NSImage, completion: @escaping () -> Void) { super.init(frame: .zero) self.image = image - self.bezelStyle = .texturedRounded + self.isBordered = false // 버튼의 테두리를 제거 + self.wantsLayer = true + self.layer?.backgroundColor = NSColor.clear.cgColor self.target = self self.action = #selector(preference) self.callback = completion diff --git a/Box42/FunctionButton/View/QuitButtonView.swift b/Box42/FunctionButton/View/QuitButtonView.swift index aaf9259..eec8ed7 100644 --- a/Box42/FunctionButton/View/QuitButtonView.swift +++ b/Box42/FunctionButton/View/QuitButtonView.swift @@ -15,7 +15,9 @@ class QuitButtonView: NSButton { super.init(frame: .zero) self.image = image - self.bezelStyle = .texturedRounded + self.isBordered = false // 버튼의 테두리를 제거 + self.wantsLayer = true + self.layer?.backgroundColor = NSColor.clear.cgColor self.target = self self.action = #selector(QuitButton) self.callback = completion From 1eedc044c0434b1ebe13bd4684da28330441022c Mon Sep 17 00:00:00 2001 From: chanhihi Date: Fri, 25 Aug 2023 06:18:06 +0900 Subject: [PATCH 10/15] =?UTF-8?q?feat:=20=EC=83=81=EB=8B=A8=20window=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=82=AC=EC=9A=A9=20=EC=8B=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=90=A0=20=EA=B2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WindowButton/View/WindowCloseButton.swift | 55 +++++++++++++++++ .../View/WindowMaximizeButton.swift | 55 +++++++++++++++++ .../View/WindowMinimizeButton.swift | 55 +++++++++++++++++ Box42/WindowButton/View/WindowViewGroup.swift | 61 +++++++++++++++++++ .../WindowButtonViewController.swift | 38 ++++++++++++ 5 files changed, 264 insertions(+) create mode 100644 Box42/WindowButton/View/WindowCloseButton.swift create mode 100644 Box42/WindowButton/View/WindowMaximizeButton.swift create mode 100644 Box42/WindowButton/View/WindowMinimizeButton.swift create mode 100644 Box42/WindowButton/View/WindowViewGroup.swift create mode 100644 Box42/WindowButton/WindowButtonViewController.swift diff --git a/Box42/WindowButton/View/WindowCloseButton.swift b/Box42/WindowButton/View/WindowCloseButton.swift new file mode 100644 index 0000000..84074b3 --- /dev/null +++ b/Box42/WindowButton/View/WindowCloseButton.swift @@ -0,0 +1,55 @@ +// +// WindowCloseButton.swift +// Box42 +// +// Created by Chanhee Kim on 8/23/23. +// + +import AppKit + +class WindowCloseButton: NSButton { + + private var callback: (() -> Void)? + + init(completion: @escaping () -> Void) { + super.init(frame: NSRect(x: 0, y: 0, width: 21, height: 21)) + + self.title = "" + self.isBordered = false + self.wantsLayer = true + self.layer?.cornerRadius = 21 / 2 + self.layer?.backgroundColor = NSColor.white.cgColor + self.target = self + self.action = #selector(closeAction) + self.callback = completion + + let trackingArea = NSTrackingArea(rect: self.bounds, options: [.mouseEnteredAndExited, .activeAlways], owner: self, userInfo: nil) + self.addTrackingArea(trackingArea) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func closeAction() { + callback?() + } + + override func mouseEntered(with event: NSEvent) { + super.mouseEntered(with: event) + + NSAnimationContext.runAnimationGroup({ (context) in + context.duration = 2 + self.layer?.backgroundColor = NSColor.red.cgColor + }, completionHandler: nil) + } + + override func mouseExited(with event: NSEvent) { + super.mouseExited(with: event) + + NSAnimationContext.runAnimationGroup({ (context) in + context.duration = 2 + self.layer?.backgroundColor = NSColor.white.cgColor + }, completionHandler: nil) + } +} diff --git a/Box42/WindowButton/View/WindowMaximizeButton.swift b/Box42/WindowButton/View/WindowMaximizeButton.swift new file mode 100644 index 0000000..5934059 --- /dev/null +++ b/Box42/WindowButton/View/WindowMaximizeButton.swift @@ -0,0 +1,55 @@ +// +// WindowMaximizeButton.swift +// Box42 +// +// Created by Chanhee Kim on 8/23/23. +// + +import AppKit + +class WindowMaximizeButton: NSButton { + + private var callback: (() -> Void)? + + init(completion: @escaping () -> Void) { + super.init(frame: NSRect(x: 0, y: 0, width: 21, height: 21)) + + self.title = "" + self.isBordered = false + self.wantsLayer = true + self.layer?.cornerRadius = 21 / 2 + self.layer?.backgroundColor = NSColor.white.cgColor + self.target = self + self.action = #selector(maximizeAction) + self.callback = completion + + let trackingArea = NSTrackingArea(rect: self.bounds, options: [.mouseEnteredAndExited, .activeAlways], owner: self, userInfo: nil) + self.addTrackingArea(trackingArea) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func maximizeAction() { + callback?() + } + + override func mouseEntered(with event: NSEvent) { + super.mouseEntered(with: event) + + NSAnimationContext.runAnimationGroup({ (context) in + context.duration = 2 + self.layer?.backgroundColor = NSColor.green.cgColor + }, completionHandler: nil) + } + + override func mouseExited(with event: NSEvent) { + super.mouseExited(with: event) + + NSAnimationContext.runAnimationGroup({ (context) in + context.duration = 2 + self.layer?.backgroundColor = NSColor.white.cgColor + }, completionHandler: nil) + } +} diff --git a/Box42/WindowButton/View/WindowMinimizeButton.swift b/Box42/WindowButton/View/WindowMinimizeButton.swift new file mode 100644 index 0000000..c628742 --- /dev/null +++ b/Box42/WindowButton/View/WindowMinimizeButton.swift @@ -0,0 +1,55 @@ +// +// WindowMinimizeButton.swift +// Box42 +// +// Created by Chanhee Kim on 8/23/23. +// + +import AppKit + +class WindowMinimizeButton: NSButton { + + private var callback: (() -> Void)? + + init(completion: @escaping () -> Void) { + super.init(frame: NSRect(x: 0, y: 0, width: 21, height: 21)) + + self.title = "" + self.isBordered = false + self.wantsLayer = true + self.layer?.cornerRadius = 21 / 2 + self.layer?.backgroundColor = NSColor.white.cgColor + self.target = self + self.action = #selector(minimizeAction) + self.callback = completion + + let trackingArea = NSTrackingArea(rect: self.bounds, options: [.mouseEnteredAndExited, .activeAlways], owner: self, userInfo: nil) + self.addTrackingArea(trackingArea) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func minimizeAction() { + callback?() + } + + override func mouseEntered(with event: NSEvent) { + super.mouseEntered(with: event) + + NSAnimationContext.runAnimationGroup({ (context) in + context.duration = 2 + self.layer?.backgroundColor = NSColor.yellow.cgColor + }, completionHandler: nil) + } + + override func mouseExited(with event: NSEvent) { + super.mouseExited(with: event) + + NSAnimationContext.runAnimationGroup({ (context) in + context.duration = 2 + self.layer?.backgroundColor = NSColor.white.cgColor + }, completionHandler: nil) + } +} diff --git a/Box42/WindowButton/View/WindowViewGroup.swift b/Box42/WindowButton/View/WindowViewGroup.swift new file mode 100644 index 0000000..9891bcc --- /dev/null +++ b/Box42/WindowButton/View/WindowViewGroup.swift @@ -0,0 +1,61 @@ +// +// WindowViewGroup.swift +// Box42 +// +// Created by Chanhee Kim on 8/23/23. +// + +import AppKit +import SnapKit + +class WindowViewGroup: NSView { + lazy var windowClose = WindowCloseButton(completion: { self.close?() }) + lazy var windowMinimize = WindowMinimizeButton(completion: { self.minimize?() }) + lazy var windowMaximize = WindowMaximizeButton(completion: { self.maximize?() }) + + var close: (() -> Void)? + var minimize: (() -> Void)? + var maximize: (() -> 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(windowClose) + self.addSubview(windowMinimize) + self.addSubview(windowMaximize) + } + + private func setupConstraints() { + + windowClose.snp.makeConstraints { make in + make.top.equalToSuperview() + make.left.equalToSuperview() + make.width.equalTo(21) + make.height.equalTo(21) + } + + windowMinimize.snp.makeConstraints { make in + make.top.bottom.equalTo(windowClose) + make.left.equalTo(windowClose.snp.right).offset(7) + make.width.equalTo(21) + make.height.equalTo(21) + } + + windowMaximize.snp.makeConstraints { make in + make.top.bottom.equalTo(windowClose) + make.left.equalTo(windowMinimize.snp.right).offset(7) + make.width.equalTo(21) + make.height.equalTo(21) + } + } +} diff --git a/Box42/WindowButton/WindowButtonViewController.swift b/Box42/WindowButton/WindowButtonViewController.swift new file mode 100644 index 0000000..10dd411 --- /dev/null +++ b/Box42/WindowButton/WindowButtonViewController.swift @@ -0,0 +1,38 @@ +// +// WindowButtonViewController.swift +// Box42 +// +// Created by Chanhee Kim on 8/23/23. +// + +import Cocoa + +class WindowButtonViewController: NSViewController { + override func loadView() { + let windowViewGroup = WindowViewGroup() + + windowViewGroup.close = windowClose + windowViewGroup.minimize = windowMin + windowViewGroup.maximize = windowMax + + self.view = windowViewGroup + } + + override func viewDidLoad() { + super.viewDidLoad() + } + + func windowClose() { + StateManager.shared.showWindow = false + self.view.window?.close() + } + + func windowMin() { + StateManager.shared.showWindow = false + self.view.window?.miniaturize(nil) + } + + func windowMax() { + self.view.window?.toggleFullScreen(nil) + } +} From a6825a24dd879e86c6822cdfd341dfa1de86479f Mon Sep 17 00:00:00 2001 From: chanhihi Date: Fri, 25 Aug 2023 06:20:31 +0900 Subject: [PATCH 11/15] =?UTF-8?q?refactor:=20code=20style=EC=9D=84=20?= =?UTF-8?q?=EA=B6=8C=EC=9E=A5=EB=90=98=EB=8A=94=20=EB=B0=A9=EC=8B=9D?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=ED=95=A9=EB=8B=88?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Box42/Extensions/NSScreen.swift | 10 +++- Box42/Menubar/MenubarViewController.swift | 7 +-- Box42/Scripts/Scripts.swift | 4 +- Box42/Shared/BoxSizeManager.swift | 8 +-- Box42/Shared/Constants.swift | 8 ++- Box42/Shared/StateManager.swift | 71 +++++++++++------------ Box42/System/CPU.swift | 2 +- Box42/WebView/WebView.swift | 5 +- 8 files changed, 59 insertions(+), 56 deletions(-) diff --git a/Box42/Extensions/NSScreen.swift b/Box42/Extensions/NSScreen.swift index 778e4fd..263a718 100644 --- a/Box42/Extensions/NSScreen.swift +++ b/Box42/Extensions/NSScreen.swift @@ -10,7 +10,13 @@ import Cocoa extension NSScreen { static let screenSize = NSScreen.main?.visibleFrame.size static let screenWidth = screenSize!.width - static let screenHeight = screenSize!.height + static let screenHeight = screenSize!.height - 60 static let halfOfScreen = (x: screenWidth / 2, y: screenHeight / 2) - static let customScreenSize = (x: CGFloat(900), y: screenHeight - 132) + static let contentsScreenSize = CGSize(width: CGFloat(768), height: screenHeight) + static let buttonGroupSize = CGSize(width: CGFloat(200), height: screenHeight) + static let customScreenSize = contentsScreenSize + buttonGroupSize +} + +func +(left: CGSize, right: CGSize) -> CGSize { + return CGSize(width: left.width + right.width, height: left.height) } diff --git a/Box42/Menubar/MenubarViewController.swift b/Box42/Menubar/MenubarViewController.swift index 7a8a719..2701716 100644 --- a/Box42/Menubar/MenubarViewController.swift +++ b/Box42/Menubar/MenubarViewController.swift @@ -21,7 +21,7 @@ class MenubarViewController: NSViewController { func menubarViewControllerStart() { self.menubarStartRunning() self.buttonActionInit() - self.popoverCoentViewInit() + self.popoverContentViewInit() self.startEventMonitoring() } @@ -42,7 +42,7 @@ class MenubarViewController: NSViewController { } func buttonInit() { - buttonImageChange("Cat") + buttonImageChange("Fox") statusBarVM.statusButtonAppear() } @@ -55,7 +55,7 @@ class MenubarViewController: NSViewController { statusBarVM.statusBar.statusItem.button?.target = self } - func popoverCoentViewInit() { + func popoverContentViewInit() { let boxViewController = BoxBaseContainerViewController(nibName: nil, bundle: nil) popover.contentViewController = boxViewController } @@ -125,7 +125,6 @@ extension MenubarViewController: MenubarViewControllerDelegate { boxWindowController?.showWindow(sender) } } - } protocol MenubarViewControllerDelegate: AnyObject { diff --git a/Box42/Scripts/Scripts.swift b/Box42/Scripts/Scripts.swift index 96323f7..2feac26 100644 --- a/Box42/Scripts/Scripts.swift +++ b/Box42/Scripts/Scripts.swift @@ -8,8 +8,8 @@ import Foundation struct Scripts { - var info: [(name: String, description: String)] = [("cleanCache", "cleaning cache"), ("brewInGoinfre", - "brew download in goinfre")] + var info: [(name: String, description: String)] = [("cleanCache", "cleaning cache"), + ("brewInGoinfre", "brew download in goinfre")] } struct Script { diff --git a/Box42/Shared/BoxSizeManager.swift b/Box42/Shared/BoxSizeManager.swift index acd32f4..1e80c2b 100644 --- a/Box42/Shared/BoxSizeManager.swift +++ b/Box42/Shared/BoxSizeManager.swift @@ -22,13 +22,13 @@ struct BoxSizeManager { 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)) + size = (NSScreen.customScreenSize.width, NSScreen.customScreenSize.height) + buttonGroupSize = (NSScreen.buttonGroupSize.width, NSScreen.buttonGroupSize.height) + toolbarGroupSize = (NSScreen.buttonGroupSize.width, 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) + windowButtonGroupSize = (NSScreen.buttonGroupSize.width, NSScreen.customScreenSize.height) } } diff --git a/Box42/Shared/Constants.swift b/Box42/Shared/Constants.swift index 322faa9..4484e4a 100644 --- a/Box42/Shared/Constants.swift +++ b/Box42/Shared/Constants.swift @@ -7,11 +7,13 @@ struct Constants { struct url { - static let InitialName = "home" - static let InitialPage = "https://42box.github.io/front-end/" + static let initialName = "home" + static let initialPage = "https://42box.github.io/front-end/" } struct UI { - static let GroupAutolayout = 12 + static let groupAutolayout = 16 + static let topWindow = 64 - 16 + static let leadingWindow = 14 } } diff --git a/Box42/Shared/StateManager.swift b/Box42/Shared/StateManager.swift index e73da57..e62b1e3 100644 --- a/Box42/Shared/StateManager.swift +++ b/Box42/Shared/StateManager.swift @@ -7,62 +7,59 @@ class StateManager { static let shared = StateManager() - - private var isPin: Bool! - 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 - } + private var _pin: Bool = false + private var _showCPUUsage: Bool = false + private var _showWindow: Bool = false + private var _showFirstWindow: Bool = false + private var _autoStorage: Bool = true - func getIsPin() -> Bool { - return isPin + var pin: Bool { + get { return _pin } + set { _pin = newValue } } - func setToggleIsPin() { - isPin.toggle() + func togglePin() { + _pin.toggle() } - func getIsShowCPUUsage() -> Bool { - return isShowCPUUsage + var showCPUUsage: Bool { + get { return _showCPUUsage } + set { _showCPUUsage = newValue } } - - func setToggleIsShowCPUUsage() { - isShowCPUUsage.toggle() + + func toggleShowCPUUsage() { + _showCPUUsage.toggle() } - func getIsShowWindow() -> Bool { - return isShowWindow + var showWindow: Bool { + get { return _showWindow } + set { _showWindow = newValue } } - func setToggleIsShowWindow() { - isShowWindow.toggle() + func toggleShowWindow() { + _showWindow.toggle() } - func getIsShowFirstWindow() -> Bool { - return isShowFirstWindow + var showFirstWindow: Bool { + get { return _showFirstWindow } + set { _showFirstWindow = newValue } } - - func setToggleIsShowFirstWindow() { - isShowFirstWindow.toggle() + + func toggleShowFirstWindow() { + _showFirstWindow.toggle() } - func getIsAutoStorage() -> Bool { - return isAutoStorage + var autoStorage: Bool { + get { return _autoStorage } + set { _autoStorage = newValue } } - func setOffIsAutoStorage() { - isAutoStorage = false + func setOffAutoStorage() { + _autoStorage = false } - func setOnIsAutoStorage() { - isAutoStorage = true + func setOnAutoStorage() { + _autoStorage = true } } diff --git a/Box42/System/CPU.swift b/Box42/System/CPU.swift index f7a8dbf..9f70003 100644 --- a/Box42/System/CPU.swift +++ b/Box42/System/CPU.swift @@ -52,7 +52,7 @@ class CPU { cpuTimer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true, block: { _ in self.usageCPU() statusBar.interval = 0.02 * (100 - max(0.0, min(99.0, self.usage.value))) / 6 - statusBar.statusItem.button?.title = StateManager.shared.getIsShowCPUUsage() ? self.usage.description : "" + statusBar.statusItem.button?.title = StateManager.shared.showCPUUsage ? self.usage.description : "" }) self.cpuTimer?.fire() return true diff --git a/Box42/WebView/WebView.swift b/Box42/WebView/WebView.swift index 0e909ad..e12930e 100644 --- a/Box42/WebView/WebView.swift +++ b/Box42/WebView/WebView.swift @@ -7,7 +7,7 @@ import WebKit -class WebView: WKWebView, WKScriptMessageHandler, WKUIDelegate, WKNavigationDelegate { +class WebView: WKWebView, WKScriptMessageHandler, WKUIDelegate { func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { print("userContentController") } @@ -25,14 +25,13 @@ class WebView: WKWebView, WKScriptMessageHandler, WKUIDelegate, WKNavigationDele super.init(frame: .zero, configuration: configuration) - contentController.add(self, name: "box") // Moved after super.init + contentController.add(self, name: "box") 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() } From 69453e60d952aae6ad34c8cab2fe181d122a468f Mon Sep 17 00:00:00 2001 From: chanhihi Date: Fri, 25 Aug 2023 06:20:59 +0900 Subject: [PATCH 12/15] =?UTF-8?q?feat:=20=ED=98=84=EC=9E=AC=20=EB=94=94?= =?UTF-8?q?=EC=9E=90=EC=9D=B8=EC=97=90=20=EB=A7=9E=EC=B6=B0=EC=84=9C=20?= =?UTF-8?q?=EC=9E=AC=EC=A1=B0=EB=A6=BD=20=ED=95=98=EC=98=80=EC=8A=B5?= =?UTF-8?q?=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Box42/Toolbar/View/BoxToolbarViewGroup.swift | 64 +++++++------- Box42/Toolbar/View/DisplayURLInToolbar.swift | 84 +++++++++++++++++-- Box42/Toolbar/View/DisplayURLTextfield.swift | 26 ++++++ Box42/Toolbar/View/GoBackInToolbar.swift | 6 +- Box42/Toolbar/View/GoForwardInToolbar.swift | 6 +- .../Toolbar/View/GoHomePageViaToolbar().swift | 4 +- .../Toolbar/View/RefreshPageViaToolbar.swift | 6 +- Box42/Toolbar/View/SideBarLeading.swift | 6 +- 8 files changed, 155 insertions(+), 47 deletions(-) create mode 100644 Box42/Toolbar/View/DisplayURLTextfield.swift diff --git a/Box42/Toolbar/View/BoxToolbarViewGroup.swift b/Box42/Toolbar/View/BoxToolbarViewGroup.swift index 6495f30..00628df 100644 --- a/Box42/Toolbar/View/BoxToolbarViewGroup.swift +++ b/Box42/Toolbar/View/BoxToolbarViewGroup.swift @@ -9,12 +9,12 @@ import AppKit import SnapKit class BoxToolbarViewGroup: NSView { - var displayURL = DisplayURLInToolbar() - lazy var sidebarLeading: SideBarLeading = SideBarLeading(image: NSImage(imageLiteralResourceName: "sidebar.leading"), completion: { self.sidebar?() }) - lazy var goBackButton: GoBackInToolbar = GoBackInToolbar(image: NSImage(imageLiteralResourceName: "arrow.left"), completion: { self.goBack?() }) - lazy var goForwardButton: GoForwardInToolbar = GoForwardInToolbar(image: NSImage(imageLiteralResourceName: "arrow.right"), completion: { self.goFoward?()} ) - lazy var reloadPageButton: ReloadPageViaToolbar = ReloadPageViaToolbar(image: NSImage(imageLiteralResourceName: "arrow.clockwise"), completion: { self.reloadPage?() }) - lazy var goHomePageViaButton: GoHomePageViaToolbar = GoHomePageViaToolbar(image: NSImage(imageLiteralResourceName: "figure.skating"), completion: { self.goToHome?() }) + var displayURL: DisplayURLInToolbar = DisplayURLInToolbar() + lazy var sidebarLeading: SideBarLeading = SideBarLeading(image: NSImage(imageLiteralResourceName: "toggle-off"), completion: { [weak self] in self?.sidebar?() }) + lazy var goBackButton: GoBackInToolbar = GoBackInToolbar(image: NSImage(imageLiteralResourceName: "arrow-left"), completion: { [weak self] in self?.goBack?() }) + lazy var goForwardButton: GoForwardInToolbar = GoForwardInToolbar(image: NSImage(imageLiteralResourceName: "arrow-right"), completion: { [weak self] in self?.goFoward?()} ) + lazy var reloadPageButton: ReloadPageViaToolbar = ReloadPageViaToolbar(image: NSImage(imageLiteralResourceName: "rotate-right"), completion: { [weak self] in self?.reloadPage?() }) + lazy var goHomePageViaButton: GoHomePageViaToolbar = GoHomePageViaToolbar(image: NSImage(imageLiteralResourceName: "figure.skating"), completion: { [weak self] in self?.goToHome?() }) var goBack: (() -> Void)? var goFoward: (() -> Void)? @@ -35,49 +35,47 @@ class BoxToolbarViewGroup: NSView { } private func setupViews() { - self.addSubview(displayURL) - self.addSubview(sidebarLeading) self.addSubview(goBackButton) self.addSubview(goForwardButton) self.addSubview(reloadPageButton) - self.addSubview(goHomePageViaButton) + self.addSubview(sidebarLeading) + self.addSubview(displayURL) +// self.addSubview(goHomePageViaButton) } private func setupConstraints() { - displayURL.snp.makeConstraints { make in - make.top.equalToSuperview() - make.left.right.equalToSuperview() - } - - sidebarLeading.snp.makeConstraints { make in - make.top.equalTo(displayURL.snp.bottom).offset(10) - make.bottom.equalToSuperview() - make.left.equalToSuperview() - make.width.equalTo(goBackButton) - } - goBackButton.snp.makeConstraints { make in - make.top.bottom.equalTo(sidebarLeading) - make.left.equalTo(sidebarLeading.snp.right).offset(10) - make.width.equalTo(goForwardButton) + make.top.equalToSuperview() + make.left.equalToSuperview().offset(2) + make.width.equalTo(24) + make.height.equalTo(24) } goForwardButton.snp.makeConstraints { make in - make.top.bottom.equalTo(sidebarLeading) - make.left.equalTo(goBackButton.snp.right).offset(10) - make.width.equalTo(reloadPageButton) + make.top.bottom.equalTo(goBackButton) + make.left.equalTo(goBackButton.snp.right).offset(14) + make.width.equalTo(24) + make.height.equalTo(24) } reloadPageButton.snp.makeConstraints { make in - make.top.bottom.equalTo(sidebarLeading) - make.left.equalTo(goForwardButton.snp.right).offset(10) - make.width.equalTo(goHomePageViaButton) + make.top.bottom.equalTo(goBackButton) + make.left.equalTo(goForwardButton.snp.right).offset(14) + make.width.equalTo(24) + make.height.equalTo(24) } - goHomePageViaButton.snp.makeConstraints { make in - make.top.bottom.equalTo(sidebarLeading) - make.left.equalTo(reloadPageButton.snp.right).offset(10) + sidebarLeading.snp.makeConstraints { make in + make.top.equalToSuperview() make.right.equalToSuperview() + make.width.equalTo(24) + make.height.equalTo(24) + } + + displayURL.snp.makeConstraints { make in + make.top.equalTo(goBackButton.snp.bottom).offset(14) + make.left.right.equalToSuperview() + make.height.equalTo(44) } } } diff --git a/Box42/Toolbar/View/DisplayURLInToolbar.swift b/Box42/Toolbar/View/DisplayURLInToolbar.swift index d8026dd..59ff65b 100644 --- a/Box42/Toolbar/View/DisplayURLInToolbar.swift +++ b/Box42/Toolbar/View/DisplayURLInToolbar.swift @@ -6,28 +6,94 @@ // import AppKit +import WebKit +import SnapKit -class DisplayURLInToolbar: NSTextField { +class DisplayURLInToolbar: NSView { + var URLTextfield: DisplayURLTextfield = DisplayURLTextfield() + var originalString: String = "" override init(frame frameRect: NSRect) { - super.init(frame: frameRect) + super.init(frame: .zero) + self.wantsLayer = true + self.layer?.backgroundColor = NSColor(hex: "#7FFFFFFF").cgColor + self.layer?.cornerRadius = 13 - self.isEditable = true - self.isBordered = false // 테두리를 제거합니다. - self.backgroundColor = NSColor.clear // 배경색을 투명하게 만듭니다. + WebViewManager.shared.hostingWebView?.navigationDelegate = self - if let url = WebViewManager.shared.hostingWebView?.url { - self.stringValue = url.absoluteString + self.addSubview(URLTextfield) + textfieldInit() + textfieldConstraints() + + updateURL() + } + + func textfieldInit() { + URLTextfield.font = NSFont.systemFont(ofSize: 15) + URLTextfield.maximumNumberOfLines = 1 + URLTextfield.lineBreakMode = .byTruncatingTail + URLTextfield.isEditable = true + URLTextfield.isBordered = false + URLTextfield.backgroundColor = NSColor.clear + URLTextfield.focusRingType = .none + URLTextfield.isAutomaticTextCompletionEnabled = false + URLTextfield.delegate = self + URLTextfield.onTextFieldRestore = { + self.URLTextfield.stringValue = self.originalString } } - + + func textfieldConstraints() { + URLTextfield.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.leading.equalToSuperview().offset(17) + make.trailing.equalToSuperview().offset(-17) + } + } + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } +} + +extension DisplayURLInToolbar: NSTextFieldDelegate { + func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool { + if commandSelector == #selector(insertNewline(_:)) { + var urlString = URLTextfield.stringValue + let validateURL = urlString.split(separator: "/").map({String($0)}) + if validateURL.count < 1 { + return false + } else if validateURL[0] != "https:" && validateURL[0] != "http:" { + urlString = "https://" + urlString + } + + if let url = URL(string: urlString) { + DispatchQueue.main.async { + print(url) + WebViewManager.shared.hostingWebView?.load(URLRequest(url: url)) + } + } + return true + } + return false + } +} +extension DisplayURLInToolbar: WKNavigationDelegate { func updateURL() { if let url = WebViewManager.shared.hostingWebView?.url { - self.stringValue = url.absoluteString + originalString = url.absoluteString + let showURLString: [String?] = originalString.split(separator: "/").map{String($0)} + if showURLString.count > 1 { + URLTextfield.stringValue = (showURLString[1] ?? "") + } } } } + +extension DisplayURLInToolbar { + func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { + print("Navigation finished") + updateURL() + } +} diff --git a/Box42/Toolbar/View/DisplayURLTextfield.swift b/Box42/Toolbar/View/DisplayURLTextfield.swift new file mode 100644 index 0000000..ea65859 --- /dev/null +++ b/Box42/Toolbar/View/DisplayURLTextfield.swift @@ -0,0 +1,26 @@ +// +// DisplayURLTextfield.swift +// Box42 +// +// Created by Chanhee Kim on 8/25/23. +// + +import AppKit + +class DisplayURLTextfield: NSTextField { + var onTextFieldRestore: (() -> Void)? + + override func mouseDown(with event: NSEvent) { + onTextFieldRestore?() + super.mouseDown(with: event) + } + + override func keyUp(with event: NSEvent) { + if event.keyCode == 53 { + print("url") + onTextFieldRestore?() + } else { + super.keyUp(with: event) + } + } +} diff --git a/Box42/Toolbar/View/GoBackInToolbar.swift b/Box42/Toolbar/View/GoBackInToolbar.swift index 6bb209f..9e3a8c3 100644 --- a/Box42/Toolbar/View/GoBackInToolbar.swift +++ b/Box42/Toolbar/View/GoBackInToolbar.swift @@ -15,10 +15,14 @@ class GoBackInToolbar: NSButton { super.init(frame: .zero) self.image = image - self.bezelStyle = .texturedRounded + self.isBordered = false // 버튼의 테두리를 제거 + self.wantsLayer = true + self.layer?.backgroundColor = NSColor.clear.cgColor self.target = self self.action = #selector(goBackWebView) self.callback = completion + self.wantsLayer = true + self.layer?.backgroundColor = .clear } required init?(coder: NSCoder) { diff --git a/Box42/Toolbar/View/GoForwardInToolbar.swift b/Box42/Toolbar/View/GoForwardInToolbar.swift index e5f04fb..5556d05 100644 --- a/Box42/Toolbar/View/GoForwardInToolbar.swift +++ b/Box42/Toolbar/View/GoForwardInToolbar.swift @@ -15,10 +15,14 @@ class GoForwardInToolbar: NSButton { super.init(frame: .zero) self.image = image - self.bezelStyle = .texturedRounded + self.isBordered = false // 버튼의 테두리를 제거 + self.wantsLayer = true + self.layer?.backgroundColor = NSColor.clear.cgColor self.target = self self.action = #selector(goForwardWebView) self.callback = completion + self.wantsLayer = true + self.layer?.backgroundColor = .clear } required init?(coder: NSCoder) { diff --git a/Box42/Toolbar/View/GoHomePageViaToolbar().swift b/Box42/Toolbar/View/GoHomePageViaToolbar().swift index 2728ff3..c647cc1 100644 --- a/Box42/Toolbar/View/GoHomePageViaToolbar().swift +++ b/Box42/Toolbar/View/GoHomePageViaToolbar().swift @@ -15,7 +15,9 @@ class GoHomePageViaToolbar: NSButton { super.init(frame: .zero) self.image = image - self.bezelStyle = .texturedRounded + self.isBordered = false // 버튼의 테두리를 제거 + self.wantsLayer = true + self.layer?.backgroundColor = NSColor.clear.cgColor self.target = self self.action = #selector(goToHomePageWebView) self.callback = completion diff --git a/Box42/Toolbar/View/RefreshPageViaToolbar.swift b/Box42/Toolbar/View/RefreshPageViaToolbar.swift index 8be72bc..8c4ef50 100644 --- a/Box42/Toolbar/View/RefreshPageViaToolbar.swift +++ b/Box42/Toolbar/View/RefreshPageViaToolbar.swift @@ -15,7 +15,11 @@ class ReloadPageViaToolbar: NSButton { super.init(frame: .zero) self.image = image - self.bezelStyle = .texturedRounded + self.isBordered = false // 버튼의 테두리를 제거 + self.wantsLayer = true + self.layer?.backgroundColor = NSColor.clear.cgColor + self.wantsLayer = true + self.layer?.backgroundColor = .clear self.target = self self.action = #selector(reloadWebView) self.callback = completion diff --git a/Box42/Toolbar/View/SideBarLeading.swift b/Box42/Toolbar/View/SideBarLeading.swift index 9849a05..24c2f1c 100644 --- a/Box42/Toolbar/View/SideBarLeading.swift +++ b/Box42/Toolbar/View/SideBarLeading.swift @@ -15,10 +15,14 @@ class SideBarLeading: NSButton { super.init(frame: .zero) self.image = image - self.bezelStyle = .texturedRounded + self.isBordered = false // 버튼의 테두리를 제거 + self.wantsLayer = true + self.layer?.backgroundColor = NSColor.clear.cgColor self.target = self self.action = #selector(sideBarLeading) self.callback = completion + self.wantsLayer = true + self.layer?.backgroundColor = .clear } required init?(coder: NSCoder) { From 8900553936901b70eef94c8f954d867d80020b0c Mon Sep 17 00:00:00 2001 From: chanhihi Date: Fri, 25 Aug 2023 06:21:22 +0900 Subject: [PATCH 13/15] =?UTF-8?q?refactor:=20code=20style=EC=9D=84=20?= =?UTF-8?q?=EA=B6=8C=EC=9E=A5=EB=90=98=EB=8A=94=20=EB=B0=A9=EC=8B=9D?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=ED=95=A9=EB=8B=88?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Box42/System/Storage.swift | 7 +++---- Box42/UI/MovableContainerView.swift | 2 +- Box42/WebView/WebViewModel.swift | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Box42/System/Storage.swift b/Box42/System/Storage.swift index 4024446..a728ffb 100644 --- a/Box42/System/Storage.swift +++ b/Box42/System/Storage.swift @@ -55,7 +55,7 @@ class Storage { func storageTimerEvent(){ storageTimer?.invalidate() - if StateManager.shared.getIsAutoStorage() == false { + if StateManager.shared.autoStorage == false { return } @@ -72,7 +72,7 @@ class Storage { if usagePercentage < self.config.threshold.rawValue { self.cleanSh() self.count += 1 - if self.count > 2 { + if self.count > 1 { // showMessageWithAppleScript("캐시 문제가 아닙니다. ncdu ~ 를 확인해주세요.", "재시작") { button in // print("timer") // dump(button) @@ -89,8 +89,7 @@ class Storage { // } // } // } - StateManager.shared.setOffIsAutoStorage() - // 여기서도 타이머를 중지시켜야 합니다. + StateManager.shared.setOffAutoStorage() self.storageTimer?.invalidate() } else { print("\(usedUsage.roundedToTwoDecimalPlaces) GB", "Storage used is less than 30%") diff --git a/Box42/UI/MovableContainerView.swift b/Box42/UI/MovableContainerView.swift index 69c4042..bd8dba6 100644 --- a/Box42/UI/MovableContainerView.swift +++ b/Box42/UI/MovableContainerView.swift @@ -9,7 +9,7 @@ import AppKit class MovableContainerView: NSView { init() { - super.init(frame: NSRect(x: 0, y: 0, width: 300, height: BoxSizeManager.shared.size.height)) + super.init(frame: .zero) } required init?(coder: NSCoder) { diff --git a/Box42/WebView/WebViewModel.swift b/Box42/WebView/WebViewModel.swift index 2e091a0..d9af17b 100644 --- a/Box42/WebView/WebViewModel.swift +++ b/Box42/WebView/WebViewModel.swift @@ -17,7 +17,7 @@ class WebViewModel: ObservableObject { private var cancellables = Set() init() { - self.webViewURL = URLModels(info: [URLModel(name: Constants.url.InitialName, url: Constants.url.InitialPage)]) + self.webViewURL = URLModels(info: [URLModel(name: Constants.url.initialName, url: Constants.url.initialPage)]) self.URLdict = URLMapping() $webViewURL.sink { (WVURL) in @@ -43,11 +43,11 @@ class WebViewModel: ObservableObject { } func readURL(_ index: Int) -> URL { - return URL(string: webViewURL.info[index].url) ?? URL(string: Constants.url.InitialPage)! + return URL(string: webViewURL.info[index].url) ?? URL(string: Constants.url.initialPage)! } func safeURL() -> URL { - return URL(string: webViewURL.info.first?.url ?? Constants.url.InitialPage)! + return URL(string: webViewURL.info.first?.url ?? Constants.url.initialPage)! } func requestURL(_ url: URL) -> URLRequest { From 8f700c2aa991a3de0cef8970a3ed435de063df44 Mon Sep 17 00:00:00 2001 From: chanhihi Date: Fri, 25 Aug 2023 06:21:37 +0900 Subject: [PATCH 14/15] =?UTF-8?q?feat:=20=EC=83=81=EB=8B=A8=EC=95=84?= =?UTF-8?q?=EC=9D=B4=EC=BD=98=EC=9D=84=20Fox=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=ED=95=A9=EB=8B=88=EB=8B=A4.=20=F0=9F=A6=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Box42/Menubar/MenubarViewModel.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Box42/Menubar/MenubarViewModel.swift b/Box42/Menubar/MenubarViewModel.swift index 7a7fb9e..5d23f10 100644 --- a/Box42/Menubar/MenubarViewModel.swift +++ b/Box42/Menubar/MenubarViewModel.swift @@ -31,6 +31,7 @@ class StatusBarViewModel { case "gam": for i in (1...5) {statusBar.frames.append(NSImage(imageLiteralResourceName: "gam_\(i)"))} 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 "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)"))} } From 246071b5523273f797eb56ca2b6208bb7bebac6c Mon Sep 17 00:00:00 2001 From: chanhihi Date: Fri, 25 Aug 2023 06:22:07 +0900 Subject: [PATCH 15/15] =?UTF-8?q?refactor:=20=EA=B5=AC=EC=A1=B0=EB=A5=BC?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=ED=95=A9=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Main/BoxBaseContainerViewController.swift | 61 ++++++++++--------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/Box42/Main/BoxBaseContainerViewController.swift b/Box42/Main/BoxBaseContainerViewController.swift index e07a11e..dcb6323 100644 --- a/Box42/Main/BoxBaseContainerViewController.swift +++ b/Box42/Main/BoxBaseContainerViewController.swift @@ -13,9 +13,9 @@ class BoxBaseContainerViewController: NSViewController { var contentGroup: BoxContentsViewGroup = BoxContentsViewGroup() var toolbarGroupVC: ToolbarViewController = ToolbarViewController() var functionGroupVC: BoxFunctionViewController = BoxFunctionViewController() - let windowViewGroup: WindowButtonViewController = WindowButtonViewController() - var buttonGroup: BoxButtonViewGroup! - var leftContainer: MovableContainerView! + let windowViewGroupVC: WindowButtonViewController = WindowButtonViewController() + var leftContainer: MovableContainerView = MovableContainerView() + var buttonGroupVC: ButtonGroupViewController = ButtonGroupViewController() weak var menubarVCDelegate: MenubarViewControllerDelegate? // extension override func loadView() { @@ -23,7 +23,7 @@ class BoxBaseContainerViewController: NSViewController { self.view.addSubview(splitView) splitView.delegate = self - buttonGroup = BoxButtonViewGroupInit() +// buttonGroup = BoxButtonViewGroupInit() leftContainerInit() viewInit() @@ -69,39 +69,44 @@ class BoxBaseContainerViewController: NSViewController { } private func leftContainerInit() { - leftContainer = MovableContainerView() - leftContainer.addSubview(buttonGroup) - leftContainer.addSubview(windowViewGroup.view) + leftContainer.frame.size.width = BoxSizeManager.shared.windowButtonGroupSize.width + leftContainer.frame.size.height = BoxSizeManager.shared.windowButtonGroupSize.height +// leftContainer.addSubview(windowViewGroupVC.view) + leftContainer.addSubview(buttonGroupVC.view) leftContainer.addSubview(toolbarGroupVC.view) leftContainer.addSubview(functionGroupVC.view) + leftContainerAutolayout() - leftContainer.frame.size.width = BoxSizeManager.shared.windowButtonGroupSize.width } private func leftContainerAutolayout() { - windowViewGroup.view.snp.makeConstraints { make in - make.top.equalTo(leftContainer).offset(Constants.UI.GroupAutolayout) - make.right.equalTo(leftContainer).offset(-Constants.UI.GroupAutolayout) - make.left.equalTo(leftContainer) - } +// windowViewGroupVC.view.snp.makeConstraints { make in +// make.top.equalTo(leftContainer) +// make.left.equalTo(leftContainer).offset(3) +// make.width.equalTo(77) +// make.height.equalTo(21) +// } toolbarGroupVC.view.snp.makeConstraints { make in - make.top.equalTo(windowViewGroup.view.snp.bottom).offset(Constants.UI.GroupAutolayout) - make.right.equalTo(leftContainer).offset(-Constants.UI.GroupAutolayout) - make.left.equalTo(leftContainer) - } - - buttonGroup.snp.makeConstraints { make in - make.top.equalTo(toolbarGroupVC.view.snp.bottom).offset(Constants.UI.GroupAutolayout) - make.right.equalTo(leftContainer).offset(-Constants.UI.GroupAutolayout) +// make.top.equalTo(windowViewGroupVC.view.snp.bottom).offset(31) + make.top.equalTo(leftContainer).offset(31) // wVGVC 없으면 + make.right.equalTo(leftContainer) make.left.equalTo(leftContainer) + make.height.equalTo(44 + 14 + 24) } 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.top.equalTo(buttonGroup.snp.bottom).offset(Constants.UI.groupAutolayout) + make.right.equalTo(leftContainer).offset(-Constants.UI.groupAutolayout) make.left.bottom.equalTo(leftContainer) } + + buttonGroupVC.view.snp.makeConstraints { make in + 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) + } } func viewInit() { @@ -112,10 +117,10 @@ class BoxBaseContainerViewController: NSViewController { 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) + make.top.equalToSuperview().offset(Constants.UI.groupAutolayout) + make.left.equalToSuperview().offset(Constants.UI.groupAutolayout) + make.right.equalToSuperview().offset(-Constants.UI.groupAutolayout) + make.bottom.equalToSuperview().offset(-Constants.UI.groupAutolayout) } } @@ -155,6 +160,6 @@ extension BoxBaseContainerViewController: NSSplitViewDelegate { extension BoxBaseContainerViewController: BoxFunctionViewControllerDelegate { func didTapBoxButton() { - clickBtn(sender: "box") // 여기에 적절한 sender (NSButton) 전달) + clickBtn(sender: "box") } }