From 371274ad242a322fd440b2317077c19ac3919e11 Mon Sep 17 00:00:00 2001 From: DaSol Kim Date: Mon, 4 Sep 2023 16:09:37 +0900 Subject: [PATCH 1/2] refactor: refactoring the main view. --- Box42.xcodeproj/project.pbxproj | 4 + .../Main/BoxBaseContainerViewController.swift | 657 +++++++++++++++--- Box42/QuickSlot/View/QuickSlotGroupView.swift | 2 +- .../42Box icon 1.png | Bin 0 -> 624 bytes .../42Box icon 2.png | Bin 0 -> 624 bytes .../bookmark-default.imageset/42Box icon.png | Bin 0 -> 624 bytes .../bookmark-default.imageset/Contents.json | 23 + Box42/View/BoxContentsViewGroup.swift | 137 ++-- 8 files changed, 663 insertions(+), 160 deletions(-) create mode 100644 Box42/Resources/Assets.xcassets/Icons/bookmark-default.imageset/42Box icon 1.png create mode 100644 Box42/Resources/Assets.xcassets/Icons/bookmark-default.imageset/42Box icon 2.png create mode 100644 Box42/Resources/Assets.xcassets/Icons/bookmark-default.imageset/42Box icon.png create mode 100644 Box42/Resources/Assets.xcassets/Icons/bookmark-default.imageset/Contents.json diff --git a/Box42.xcodeproj/project.pbxproj b/Box42.xcodeproj/project.pbxproj index a5f301d..3a787bd 100644 --- a/Box42.xcodeproj/project.pbxproj +++ b/Box42.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 7ECC67EA2AA5B74600265D54 /* BookmarkEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECC67E92AA5B74600265D54 /* BookmarkEditorView.swift */; }; DE018BB32A5099F900FF0AA3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE018BB22A5099F900FF0AA3 /* AppDelegate.swift */; }; DE018BB82A5099F900FF0AA3 /* Box42.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DE018BB62A5099F900FF0AA3 /* Box42.xcdatamodeld */; }; DE018BDD2A509AEB00FF0AA3 /* EventMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE018BDC2A509AEB00FF0AA3 /* EventMonitor.swift */; }; @@ -133,6 +134,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 7ECC67E92AA5B74600265D54 /* BookmarkEditorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BookmarkEditorView.swift; path = ../../../42box4/Box42/View/BookmarkEditorView.swift; sourceTree = ""; }; DE018BAF2A5099F900FF0AA3 /* Box42.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Box42.app; sourceTree = BUILT_PRODUCTS_DIR; }; DE018BB22A5099F900FF0AA3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; DE018BB72A5099F900FF0AA3 /* Box42.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Box42.xcdatamodel; sourceTree = ""; }; @@ -445,6 +447,7 @@ DE4408202A9297EE0091937A /* View */ = { isa = PBXGroup; children = ( + 7ECC67E92AA5B74600265D54 /* BookmarkEditorView.swift */, DE1F1A1A2A8B50C500A88DD8 /* BoxContentsViewGroup.swift */, DE24E6372A8FE10300E29F5D /* BoxBaseSplitView.swift */, ); @@ -876,6 +879,7 @@ DE0A917B2A8F0CA800D1D6F1 /* AppleScripts+ShowMessage.swift in Sources */, DE018BB82A5099F900FF0AA3 /* Box42.xcdatamodeld in Sources */, DEF0761B2AA33671005700E5 /* DeleteUserMeScript.swift in Sources */, + 7ECC67EA2AA5B74600265D54 /* BookmarkEditorView.swift in Sources */, DE62BE672A9BA92E00D97E06 /* QuickSlotButtonViewItem.swift in Sources */, DEF076302AA3CF8A005700E5 /* QuickSlotItemLabel.swift in Sources */, DE874F542A591F1400FC3B77 /* PreferencesView.swift in Sources */, diff --git a/Box42/Main/BoxBaseContainerViewController.swift b/Box42/Main/BoxBaseContainerViewController.swift index b2cc181..861a902 100644 --- a/Box42/Main/BoxBaseContainerViewController.swift +++ b/Box42/Main/BoxBaseContainerViewController.swift @@ -8,16 +8,31 @@ import Cocoa import SnapKit +let bookMarkList = [ + ("home", "https://42box.kr/"), + ("23Coaltheme", "https://42box.github.io/front-end/"), + ("Box 42", "https://42box.github.io/front-end/#/box"), + ("Intra 42", "https://intra.42.fr"), + ("Jiphyeonjeon", "https://42library.kr"), + ("42STAT", "https://stat.42seoul.kr/home"), + ("24Hane", "https://24hoursarenotenough.42seoul.kr"), + ("80kCoding", "https://80000coding.oopy.io"), + ("where42", "https://www.where42.kr"), + ("cabi", "https://cabi.42seoul.io/"), + ("42gg", "https://42gg.kr/"), + ("textart", "https://textart.sh/"), +] + class BoxBaseContainerViewController: NSViewController { // MARK: - LeftContainer - var splitView: BoxBaseSplitView = BoxBaseSplitView() +// var splitView: BoxBaseSplitView = BoxBaseSplitView() var contentGroup: BoxContentsViewGroup = BoxContentsViewGroup() var toolbarGroupVC: ToolbarViewController = ToolbarViewController() var quickSlotGroupVC: QuickSlotViewController = QuickSlotViewController() var functionGroupVC: BoxFunctionViewController = BoxFunctionViewController() let windowViewGroupVC: WindowButtonViewController = WindowButtonViewController() - var leftContainer: MovableContainerView = MovableContainerView() - var buttonGroupVC: ButtonGroupViewController = ButtonGroupViewController() +// var leftContainer: MovableContainerView = MovableContainerView() +// var buttonGroupVC: ButtonGroupViewController = ButtonGroupViewController() // MARK: - QuickSlot var preferenceVC: PreferencesViewController = PreferencesViewController() @@ -28,129 +43,296 @@ class BoxBaseContainerViewController: NSViewController { var quickSlotManagerVC: QuickSlotManagerViewController = QuickSlotManagerViewController() var quickSlotButtonCollectionVC: QuickSlotButtonCollectionViewController = QuickSlotButtonCollectionViewController() + private let splitView: NSSplitView = { + let splitView = NSSplitView() + splitView.isVertical = true + splitView.dividerStyle = .thick + return splitView + }() + + private let leftView: NSView = { + let view = NSView() + view.frame.size.width = 302 - 12 + view.frame.size.height = 1200 + return view + }() + + private let bookMarkView: NSView = { + let view = NSView() + return view + }() + + let tableView: NSTableView = { + let tableView = NSTableView() + tableView.autoresizingMask = [.width, .height] + tableView.headerView = nil + return tableView + }() + + var buttonTitleArray = bookMarkList.map { $0.0 } + var urlArray = bookMarkList.map { $0.1 } + var selectedRow: Int? + var selectedButton: DraggableButton? override func loadView() { self.view = NSView() - 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 + self.view.wantsLayer=true self.view.layer?.backgroundColor = NSColor(hex: "#E7E7E7").cgColor + self.view.snp.makeConstraints { make in + make.width.equalTo(BoxSizeManager.shared.size.width) + make.height.equalTo(BoxSizeManager.shared.size.height) + } - NotificationCenter.default.addObserver(self, selector: #selector(handleButtonTapped), name: .collectionButtonTapped, object: nil) - - NotificationCenter.default.addObserver(self, selector: #selector(headerTappedQuickSlotManagerHandle), name: .collectionHeaderTapped, object: nil) - } - - func BoxButtonViewGroupInit() -> BoxButtonViewGroup { + splitView.addArrangedSubview(leftView) + splitView.addArrangedSubview(contentGroup) + self.view.addSubview(splitView) - let buttonGroup = BoxButtonViewGroup { sender in - self.clickBtn(sender: sender) - } - - return buttonGroup - } - - 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") - } - } + splitView.snp.makeConstraints { make in + make.edges.equalToSuperview().inset(10) } - } - - private func leftContainerInit() { - 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(quickSlotGroupVC.view) - leftContainer.addSubview(functionGroupVC.view) - - leftContainerAutolayout() - } - - private func leftContainerAutolayout() { + + leftView.addSubview(windowViewGroupVC.view) + leftView.addSubview(bookMarkView) + leftView.addSubview(toolbarGroupVC.view) + leftView.addSubview(quickSlotGroupVC.view) + leftView.addSubview(functionGroupVC.view) + windowViewGroupVC.view.snp.makeConstraints { make in - make.top.equalTo(leftContainer) - make.left.equalTo(leftContainer).offset(3) + make.top.equalTo(leftView) + make.left.equalTo(leftView).offset(3) make.width.equalTo(77) make.height.equalTo(21) } - toolbarGroupVC.view.snp.makeConstraints { make in make.top.equalTo(windowViewGroupVC.view.snp.bottom).offset(31) - make.right.equalTo(leftContainer) - make.left.equalTo(leftContainer) + make.right.equalTo(leftView) + make.left.equalTo(leftView) make.height.equalTo(44 + 14 + 24) } - - buttonGroupVC.view.snp.makeConstraints { make in + bookMarkView.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.leading.trailing.equalToSuperview() make.bottom.equalTo(quickSlotGroupVC.view.snp.top).offset(-Constants.UI.groupAutolayout) } + quickSlotGroupVC.view.snp.makeConstraints { make in + make.bottom.equalTo(functionGroupVC.view.snp.top).offset(-27) + make.right.equalTo(leftView).offset(-Constants.UI.groupAutolayout) + make.left.equalTo(leftView) + make.height.equalTo(178) + } + functionGroupVC.view.snp.makeConstraints { make in + make.right.equalTo(leftView).offset(-Constants.UI.groupAutolayout) + make.left.bottom.equalTo(leftView) + } - quickSlotGroupVC.view.snp.makeConstraints { make in - make.bottom.equalTo(functionGroupVC.view.snp.top).offset(-27) - make.right.equalTo(leftContainer).offset(-Constants.UI.groupAutolayout) - make.left.equalTo(leftContainer) - make.height.equalTo(178) - } + splitView.delegate = self - functionGroupVC.view.snp.makeConstraints { make in - make.right.equalTo(leftContainer).offset(-Constants.UI.groupAutolayout) - make.left.bottom.equalTo(leftContainer) + let stackView = NSStackView() + stackView.orientation = .horizontal + stackView.spacing = 6 + stackView.alignment = .centerY + + let imageView = NSImageView() + imageView.image = NSImage(named: NSImage.Name("bookmark")) + + let label = NSTextField(labelWithString: "북마크") + label.textColor = NSColor.black + label.font = NSFont.boldSystemFont(ofSize: 16) + + let buttonImage = NSImage(named: NSImage.Name("add"))! + buttonImage.size = NSSize(width: 24, height: 24) + let button = NSButton(image: buttonImage, target: self, action: #selector(addBookMarkButtonClicked(_:))) + button.setButtonType(.momentaryChange) + button.bezelStyle = .texturedRounded + button.isBordered = false + button.wantsLayer = true + button.layer?.backgroundColor = NSColor(hex: "#E7E7E7").cgColor + let spacerView = NSView() + spacerView.snp.makeConstraints { make in + make.width.equalTo(173) + } + + stackView.addArrangedSubview(imageView) + stackView.addArrangedSubview(label) + stackView.addArrangedSubview(spacerView) + stackView.addArrangedSubview(button) + + tableView.wantsLayer = true + tableView.backgroundColor = NSColor(hex: "#E7E7E7") + tableView.focusRingType = .none + tableView.headerView = nil + tableView.autoresizingMask = [.width, .height] + tableView.selectionHighlightStyle = .none + tableView.intercellSpacing = NSSize(width: 0, height: 0) + tableView.setDraggingSourceOperationMask(.move, forLocal: true) + + let column = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("column1")) + column.title = "" + // column.width = 100 + column.resizingMask = .autoresizingMask + + tableView.addTableColumn(column) + + + let scrollView = NSScrollView() + scrollView.hasVerticalScroller = true + scrollView.documentView = tableView + + bookMarkView.addSubview(stackView) + bookMarkView.addSubview(scrollView) + // bookMarkView.addSubview(tableView) + + stackView.snp.makeConstraints { make in + make.top.equalToSuperview().offset(18) + make.leading.trailing.equalToSuperview().offset(0) + make.height.equalTo(24) } + + // tableView.snp.makeConstraints { make in + // make.top.equalTo(stackView.snp.bottom).offset(0) + // make.leading.equalToSuperview() + // } + + scrollView.snp.makeConstraints { make in + make.top.equalTo(stackView.snp.bottom).offset(0) + make.leading.trailing.equalToSuperview().offset(0) + make.bottom.equalToSuperview() + } + + tableView.dataSource = self + tableView.delegate = self + tableView.registerForDraggedTypes([NSPasteboard.PasteboardType.string]) } - func viewInit() { - self.boxViewSizeInit() + @objc func addBookMarkButtonClicked(_ sender: NSButton) { + splitView.removeArrangedSubview(contentGroup) + contentGroup.removeFromSuperview() - splitView.addArrangedSubview(leftContainer) - splitView.addArrangedSubview(contentGroup) - self.view.addSubview(splitView) + let newView = BookmarkEditorView(bookMarkList: bookMarkList) + newView.wantsLayer = true + newView.layer?.backgroundColor = NSColor.black.cgColor + newView.layer?.cornerRadius = 20 + newView.frame.size = contentGroup.frame.size - splitView.snp.makeConstraints { make in - 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) + contentGroup.addSubview(newView) + newView.snp.makeConstraints { make in + make.edges.equalToSuperview() } + + splitView.addArrangedSubview(contentGroup) } - func boxViewSizeInit() { - self.view.frame.size.width = BoxSizeManager.shared.size.width - self.view.frame.size.height = BoxSizeManager.shared.size.height + override func viewDidLoad() { +// self.view.wantsLayer = true +// +//// self.view.layer?.backgroundColor = NSColor(hex: "#FF9548").cgColor +// self.view.layer?.backgroundColor = NSColor(hex: "#E7E7E7").cgColor + + NotificationCenter.default.addObserver(self, selector: #selector(handleButtonTapped), name: .collectionButtonTapped, object: nil) + + NotificationCenter.default.addObserver(self, selector: #selector(headerTappedQuickSlotManagerHandle), name: .collectionHeaderTapped, object: nil) } + +// func BoxButtonViewGroupInit() -> BoxButtonViewGroup { +// +// let buttonGroup = BoxButtonViewGroup { sender in +// self.clickBtn(sender: sender) +// } +// +// return buttonGroup +// } + +// 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") +// } +// } +// } +// } +// +// private func leftContainerInit() { +// 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(quickSlotGroupVC.view) +// leftContainer.addSubview(functionGroupVC.view) +// +// leftContainerAutolayout() +// } +// +// private func leftContainerAutolayout() { +// 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(windowViewGroupVC.view.snp.bottom).offset(31) +// make.right.equalTo(leftContainer) +// make.left.equalTo(leftContainer) +// make.height.equalTo(44 + 14 + 24) +// } +// +// 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(quickSlotGroupVC.view.snp.top).offset(-Constants.UI.groupAutolayout) +// } +// +// quickSlotGroupVC.view.snp.makeConstraints { make in +// make.bottom.equalTo(functionGroupVC.view.snp.top).offset(-27) +// make.right.equalTo(leftContainer).offset(-Constants.UI.groupAutolayout) +// make.left.equalTo(leftContainer) +// make.height.equalTo(178) +// } +// +// functionGroupVC.view.snp.makeConstraints { make in +// make.right.equalTo(leftContainer).offset(-Constants.UI.groupAutolayout) +// make.left.bottom.equalTo(leftContainer) +// } +// } +// +// func viewInit() { +// self.boxViewSizeInit() +// +// splitView.addArrangedSubview(leftContainer) +// splitView.addArrangedSubview(contentGroup) +// self.view.addSubview(splitView) +// +// splitView.snp.makeConstraints { make in +// 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) +// } +// } +// +// func boxViewSizeInit() { +// self.view.frame.size.width = BoxSizeManager.shared.size.width +// self.view.frame.size.height = BoxSizeManager.shared.size.height +// } } extension BoxBaseContainerViewController: NSSplitViewDelegate { @@ -161,10 +343,10 @@ extension BoxBaseContainerViewController: NSSplitViewDelegate { } return proposedMinimumPosition } - + func splitView(_ splitView: NSSplitView, constrainMaxCoordinate proposedMaximumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat { if dividerIndex == 0 { - return CGFloat(312).pointsToPixels() + return CGFloat(302).pointsToPixels() } return proposedMaximumPosition } @@ -172,21 +354,284 @@ extension BoxBaseContainerViewController: NSSplitViewDelegate { func splitView(_ splitView: NSSplitView, resizeSubviewsWithOldSize oldSize: NSSize) { let dividerThickness = splitView.dividerThickness let newWidth = splitView.frame.width - dividerThickness - - let leftWidth = leftContainer.frame.width + + let leftWidth = leftView.frame.width let contentWidth = newWidth - leftWidth - - leftContainer.frame = NSRect(x: 0, y: 0, width: leftWidth, height: splitView.bounds.height) + + leftView.frame = NSRect(x: 0, y: 0, width: leftWidth, height: splitView.bounds.height) contentGroup.frame = NSRect(x: leftWidth + dividerThickness, y: 0, width: contentWidth, height: splitView.bounds.height) } } -extension BoxBaseContainerViewController: BoxFunctionViewControllerDelegate { - func didTapBoxButton() { - clickBtn(sender: "box") +extension BoxBaseContainerViewController: NSTableViewDelegate { + func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? { + let pasteboardItem = NSPasteboardItem() + pasteboardItem.setString(String(row), forType: .string) + return pasteboardItem + } + + func sendUpdatedDataToServer() { + let urlList = zip(buttonTitleArray, urlArray).map { ["name": $0.0, "url": $0.1] } + let jsonData = try? JSONSerialization.data(withJSONObject: ["urlList": urlList]) + + var request = URLRequest(url: URL(string:"https://api.42box.kr/user-service/users/me/url-list")!) + request.httpMethod = "POST" + request.httpBody = jsonData + + URLSession.shared.dataTask(with:request) { (data, response, error) in + if error != nil{ + print(error!.localizedDescription) + } + else{ + print("Data posted successfully") + } + }.resume() + } + +} + +class ButtonTableCellView: NSTableCellView { + var button: NSButton! + var deleteButton: NSButton! + var rowIndex: Int! + + override func viewWillDraw() { + super.viewWillDraw() + self.frame.size.width = 268.0 + self.frame = NSRect(x: self.frame.origin.x - 3, y: self.frame.origin.y, + width: self.frame.size.width, height: self.frame.size.height) + } +} + + +extension BoxBaseContainerViewController: NSTableViewDataSource { + func numberOfRows(in tableView: NSTableView) -> Int { + return buttonTitleArray.count + } + + func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { + let cellView = ButtonTableCellView() + cellView.rowIndex = row + + let button = DraggableButton(frame: NSRect(x: 0, y: 0, width: 300, height: 44)) + button.tag = row + button.bezelStyle = .inline + button.isBordered = false + button.title = "" + button.registerForDraggedTypes([NSPasteboard.PasteboardType.string]) + button.target = self + button.action = #selector(buttonClicked(_:)) + button.delegate = self + + let label = NSTextField(frame: NSRect(x: 26 + 21 + 8, y: 25 / 2, width: button.bounds.width, height: button.bounds.height)) + + label.stringValue = buttonTitleArray[row] + label.backgroundColor = .clear + label.isBordered = false + label.isEditable = false + + let attributes : [NSAttributedString.Key : Any] = + [ + NSAttributedString.Key.font : NSFont.systemFont(ofSize:18.0, weight: .light), + NSAttributedString.Key.foregroundColor : NSColor.black, + ] + let attributedStringTitle = NSAttributedString(string: label.stringValue , attributes: + attributes) + label.attributedStringValue=attributedStringTitle + button.addSubview(label) + + + // let image = NSImage(named: NSImage.Name("bookmark-default")) + // image?.size = NSSize(width: 21, height: 21) + // button.image = image + // button.imagePosition = .imageLeading + // button.image?.alignmentRect = NSRect(x: 0, y: 0, width: 21, height: 21) + + let imageView = NSImageView(frame: NSRect(x: 26, y: 25 / 2, width: 21, height: 21)) + imageView.image = NSImage(named: NSImage.Name("bookmark-default")) + imageView.imageScaling = .scaleProportionallyUpOrDown + imageView.imageAlignment = .alignCenter + button.addSubview(imageView) + + + + cellView.addSubview(button) + + button.snp.makeConstraints { make in + make.top.equalToSuperview().offset(2) + make.leading.equalToSuperview() + make.trailing.equalToSuperview() + // make.width.equalTo(268) + make.width.lessThanOrEqualTo(268) + make.height.equalTo(44) + } + + tableView.rowHeight = 50 + + if row == selectedRow { + button.wantsLayer = true + button.layer?.cornerRadius = 12 + button.layer?.backgroundColor = NSColor.white.cgColor + } else { + button.wantsLayer = true + button.layer?.cornerRadius = 12 + button.layer?.backgroundColor = NSColor.clear.cgColor + } + + return cellView + } + + @objc func buttonClicked(_ sender: DraggableButton) { + selectedButton?.layer?.backgroundColor = NSColor.clear.cgColor + + // Update the reference to the currently selected button and change its background color. + selectedButton = sender + sender.layer?.backgroundColor = NSColor.white.cgColor + + if sender.tag < urlArray.count { + if let url = URL(string:urlArray[sender.tag]) { + print(url) + contentGroup.webView.load(URLRequest(url: url)) + } + } + } + + 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 = buttonTitleArray[from] + buttonTitleArray.remove(at: from) + buttonTitleArray.insert(item, at: to) + tableView.reloadData() + + for (_, subview) in tableView.subviews.enumerated() { + guard let cellView = subview as? CustomTableCellView else { + continue + } + + cellView.button.title = buttonTitleArray[cellView.rowIndex] + } + + return true + } +} + +class DraggableButton: NSButton, NSDraggingSource { + weak var delegate: BoxBaseContainerViewController? + var mouseDownEvent: NSEvent? + + func draggingSession(_ session: NSDraggingSession, sourceOperationMaskFor context: NSDraggingContext) -> NSDragOperation { + return .move + } + + override func mouseUp(with event: NSEvent) { + print("mouseUp") + if let down = self.mouseDownEvent { + if event.locationInWindow == down.locationInWindow { + self.target?.perform(self.action, with: self) + } + + super.mouseUp(with:event) + self.mouseDownEvent = nil + } + } + + override func mouseDown(with event: NSEvent) { + print("mouseDown") + self.mouseDownEvent = event + if event.clickCount > 1 { + self.target?.perform(self.action, with: self) + } + } + + override func mouseDragged(with event: NSEvent) { + guard let down = self.mouseDownEvent else { return } + + let distance = hypot( + down.locationInWindow.x - event.locationInWindow.x, + down.locationInWindow.y - event.locationInWindow.y) + + if distance > 3 { // Adjust this as needed + let pasteboardItem = NSPasteboardItem() + pasteboardItem.setString("\(self.tag)", forType: .string) + + let draggingItem = NSDraggingItem(pasteboardWriter: pasteboardItem) + + // Create a snapshot of the button + let snapshot = self.snapshot() + + // Set the dragging frame and contents + draggingItem.setDraggingFrame(self.bounds, contents:snapshot) + + beginDraggingSession(with: [draggingItem], event:self.mouseDownEvent!, source:self) + + self.mouseDownEvent = nil + } + } + + func snapshot() -> NSImage? { + guard let bitmapRep = bitmapImageRepForCachingDisplay(in: bounds) else { return nil } + cacheDisplay(in: bounds, to: bitmapRep) + let image = NSImage(size: bounds.size) + image.addRepresentation(bitmapRep) + return image + } + + override func viewDidMoveToWindow() { + super.viewDidMoveToWindow() + + let trackingArea = NSTrackingArea( + rect: bounds, + options: [.mouseEnteredAndExited, .activeAlways], + owner: self, + userInfo: nil + ) + + addTrackingArea(trackingArea) + } + + override func mouseEntered(with event: NSEvent) { + super.mouseEntered(with: event) + + if self != delegate?.selectedButton { + wantsLayer = true + layer?.frame.size = CGSize(width: 268.0, height: 44.0) + layer?.cornerRadius = 12 + layer?.backgroundColor = NSColor(red: 0.848, green: 0.848, blue: 0.848, alpha: 1).cgColor + } + } + + override func mouseExited(with event: NSEvent) { + super.mouseExited(with: event) + + if self != delegate?.selectedButton { + wantsLayer = true + layer?.frame.size = CGSize(width: 268.0, height: 44.0) + layer?.cornerRadius = 12 + layer?.backgroundColor = NSColor.clear.cgColor + } } } + + +//extension BoxBaseContainerViewController: BoxFunctionViewControllerDelegate { +// func didTapBoxButton() { +// clickBtn(sender: "box") +// } +//} + extension BoxBaseContainerViewController { @objc func handleButtonTapped(notification: NSNotification) { if let button = notification.object as? NSButton { diff --git a/Box42/QuickSlot/View/QuickSlotGroupView.swift b/Box42/QuickSlot/View/QuickSlotGroupView.swift index e436c86..d6238eb 100644 --- a/Box42/QuickSlot/View/QuickSlotGroupView.swift +++ b/Box42/QuickSlot/View/QuickSlotGroupView.swift @@ -11,7 +11,7 @@ import SnapKit class QuickSlotGroupView: NSView { lazy var divider: NSBox = Divider(completion: { [weak self] in self?.dividerAction?() }) - lazy var headerView: QuickSlotHeaderView = QuickSlotHeaderView(image: NSImage(imageLiteralResourceName: "star"), completion: { [weak self] in self?.headerAction?() }) + lazy var headerView: QuickSlotHeaderView = QuickSlotHeaderView(image: NSImage(imageLiteralResourceName: "Star"), completion: { [weak self] in self?.headerAction?() }) lazy var buttonCollectionView: QuickSlotButtonCollectionViewController = QuickSlotButtonCollectionViewController() var dividerAction: (() -> Void)? diff --git a/Box42/Resources/Assets.xcassets/Icons/bookmark-default.imageset/42Box icon 1.png b/Box42/Resources/Assets.xcassets/Icons/bookmark-default.imageset/42Box icon 1.png new file mode 100644 index 0000000000000000000000000000000000000000..b5c6cf7ee2883d97a1c1166059c89836606cfe09 GIT binary patch literal 624 zcmV-$0+0QPP)xXjNlR2;IhHp2JHsz2F*=Cn1C_@6NC-u26O|ufw93LK(U=Vj==c;q^DM{ zU(%PjvHhzc2!bF8f*?H8810M(qemnCg?e<~V{4>XmyEnRZK3f+1XSAB&v*)^TuNJ%f-mp*!t7Ck(WVgAE$J68A zW!Vx~>+!XOOJu#rr|@sPJ7&<09Pokol^#4_W*hNsJ-&yC&)$f!3)h8ADZlwUqhqAc z%}ARa;(f%|yMCYfAMu?$=M0h({&qs2yOFj7(>Nr0ryl=}l<-ZaKId@C)aL^!;V%;V zOf8Iz^=paqmorHTzaoBTcOz}q6MNuo7(aGw8dPMe*1o61Kh-IZCsgB~Gu8QO@ePSn zUFsso4oy3qy)JTI+g5~!cjJ6}J}z?XkX;kTjvBidvQPe_Yy0Ecb3bFA=~%Y3ytKMd zIN8|LiiEEf312G`zE&iBt;E6~DVwtk9Pd$-wU+-Z#Y_f37pQwO&;q(Zt;s|W=zxXjNlR2;IhHp2JHsz2F*=Cn1C_@6NC-u26O|ufw93LK(U=Vj==c;q^DM{ zU(%PjvHhzc2!bF8f*?H8810M(qemnCg?e<~V{4>XmyEnRZK3f+1XSAB&v*)^TuNJ%f-mp*!t7Ck(WVgAE$J68A zW!Vx~>+!XOOJu#rr|@sPJ7&<09Pokol^#4_W*hNsJ-&yC&)$f!3)h8ADZlwUqhqAc z%}ARa;(f%|yMCYfAMu?$=M0h({&qs2yOFj7(>Nr0ryl=}l<-ZaKId@C)aL^!;V%;V zOf8Iz^=paqmorHTzaoBTcOz}q6MNuo7(aGw8dPMe*1o61Kh-IZCsgB~Gu8QO@ePSn zUFsso4oy3qy)JTI+g5~!cjJ6}J}z?XkX;kTjvBidvQPe_Yy0Ecb3bFA=~%Y3ytKMd zIN8|LiiEEf312G`zE&iBt;E6~DVwtk9Pd$-wU+-Z#Y_f37pQwO&;q(Zt;s|W=zxXjNlR2;IhHp2JHsz2F*=Cn1C_@6NC-u26O|ufw93LK(U=Vj==c;q^DM{ zU(%PjvHhzc2!bF8f*?H8810M(qemnCg?e<~V{4>XmyEnRZK3f+1XSAB&v*)^TuNJ%f-mp*!t7Ck(WVgAE$J68A zW!Vx~>+!XOOJu#rr|@sPJ7&<09Pokol^#4_W*hNsJ-&yC&)$f!3)h8ADZlwUqhqAc z%}ARa;(f%|yMCYfAMu?$=M0h({&qs2yOFj7(>Nr0ryl=}l<-ZaKId@C)aL^!;V%;V zOf8Iz^=paqmorHTzaoBTcOz}q6MNuo7(aGw8dPMe*1o61Kh-IZCsgB~Gu8QO@ePSn zUFsso4oy3qy)JTI+g5~!cjJ6}J}z?XkX;kTjvBidvQPe_Yy0Ecb3bFA=~%Y3ytKMd zIN8|LiiEEf312G`zE&iBt;E6~DVwtk9Pd$-wU+-Z#Y_f37pQwO&;q(Zt;s|W=z WKWebView? { + + if navigationAction.targetFrame == nil { + if let url = navigationAction.request.url { + if navigationAction.navigationType == .linkActivated { + webView.load(URLRequest(url: url)) + return nil + } + } + } + return nil + } + + func webView(_ webView: WKWebView, runOpenPanelWith parameters: WKOpenPanelParameters, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping ([URL]?) -> Void) { + let openPanel = NSOpenPanel() + openPanel.canChooseFiles = true + openPanel.allowsMultipleSelection = parameters.allowsMultipleSelection + openPanel.level = .popUpMenu -// let webConfiguration = WKWebViewConfiguration() -// webView = WKWebView(frame: .zero, configuration: webConfiguration) -// -// webView.uiDelegate = self -// WebViewManager.shared.hostingWebView = webView -// self.addSubview(webView) -// webView.snp.makeConstraints { make in -// make.edges.equalTo(self) -// } -// -// if let url = URL(string: "https://www.42box.kr") { -// let request = URLRequest(url: url) -// webView.load(request) -// } -// -// NotificationCenter.default.addObserver(self, selector: -// #selector(goBack), name: -// Notification.Name("goBack"), object:nil) -// -// NotificationCenter.default.addObserver(self, selector: -// #selector(goForward), name: -// Notification.Name("goForward"), object:nil) -// -// NotificationCenter.default.addObserver(self, selector: -// #selector(reload), name: -// Notification.Name("reload"), object:nil) + openPanel.begin { (result) in + if result == .OK { + completionHandler(openPanel.urls) + } else { + completionHandler(nil) + } + } } -// -// deinit { -// // view controller가 해제될 때 observer도 제거합니다. -// NotificationCenter.default.removeObserver(self) -// } -// -// @objc func goBack() { -// if webView.canGoBack { -// webView.goBack() -// } -// } -// -// @objc func goForward() { -// if webView.canGoForward { -// webView.goForward() -// } -// } -// -// @objc func reload() { -// webView.reload() -// } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") From cc85bd7b6891163ea9374c27e635100a440ad9c9 Mon Sep 17 00:00:00 2001 From: DaSol Kim Date: Mon, 4 Sep 2023 17:07:04 +0900 Subject: [PATCH 2/2] fix: issue xcode issue --- Box42.xcodeproj/project.pbxproj | 12 +- .../xcshareddata/swiftpm/Package.resolved | 24 ++-- Box42/{ => Main}/BoxWindowController.swift | 0 Box42/{ => Main}/UI/HoverButton.swift | 0 .../{ => Main}/UI/MovableContainerView.swift | 0 Box42/Main/View/BookmarkEditorView.swift | 104 ++++++++++++++++++ Box42/{ => Main}/View/BoxBaseSplitView.swift | 0 .../View/BoxContentsViewGroup.swift | 0 8 files changed, 121 insertions(+), 19 deletions(-) rename Box42/{ => Main}/BoxWindowController.swift (100%) rename Box42/{ => Main}/UI/HoverButton.swift (100%) rename Box42/{ => Main}/UI/MovableContainerView.swift (100%) create mode 100644 Box42/Main/View/BookmarkEditorView.swift rename Box42/{ => Main}/View/BoxBaseSplitView.swift (100%) rename Box42/{ => Main}/View/BoxContentsViewGroup.swift (100%) diff --git a/Box42.xcodeproj/project.pbxproj b/Box42.xcodeproj/project.pbxproj index 3a787bd..77df456 100644 --- a/Box42.xcodeproj/project.pbxproj +++ b/Box42.xcodeproj/project.pbxproj @@ -7,7 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - 7ECC67EA2AA5B74600265D54 /* BookmarkEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECC67E92AA5B74600265D54 /* BookmarkEditorView.swift */; }; + 7E9B46922AA5C564009EB900 /* BookmarkEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E9B46912AA5C564009EB900 /* BookmarkEditorView.swift */; }; DE018BB32A5099F900FF0AA3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE018BB22A5099F900FF0AA3 /* AppDelegate.swift */; }; DE018BB82A5099F900FF0AA3 /* Box42.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DE018BB62A5099F900FF0AA3 /* Box42.xcdatamodeld */; }; DE018BDD2A509AEB00FF0AA3 /* EventMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE018BDC2A509AEB00FF0AA3 /* EventMonitor.swift */; }; @@ -134,7 +134,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 7ECC67E92AA5B74600265D54 /* BookmarkEditorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BookmarkEditorView.swift; path = ../../../42box4/Box42/View/BookmarkEditorView.swift; sourceTree = ""; }; + 7E9B46912AA5C564009EB900 /* BookmarkEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkEditorView.swift; sourceTree = ""; }; DE018BAF2A5099F900FF0AA3 /* Box42.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Box42.app; sourceTree = BUILT_PRODUCTS_DIR; }; DE018BB22A5099F900FF0AA3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; DE018BB72A5099F900FF0AA3 /* Box42.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Box42.xcdatamodel; sourceTree = ""; }; @@ -165,7 +165,7 @@ 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 = Main/BoxBaseContainerViewController.swift; sourceTree = ""; }; + DE1F1A192A8B50C500A88DD8 /* BoxBaseContainerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 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 = ""; }; DE1F1A282A8B50E200A88DD8 /* BoxSizeManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoxSizeManager.swift; sourceTree = ""; }; @@ -408,7 +408,7 @@ DE1F1A192A8B50C500A88DD8 /* BoxBaseContainerViewController.swift */, DEB862E92A853F7F00278FCD /* BoxWindowController.swift */, ); - name = Main; + path = Main; sourceTree = ""; }; DE3FF36F2A978A6E009C88EF /* View */ = { @@ -447,7 +447,7 @@ DE4408202A9297EE0091937A /* View */ = { isa = PBXGroup; children = ( - 7ECC67E92AA5B74600265D54 /* BookmarkEditorView.swift */, + 7E9B46912AA5C564009EB900 /* BookmarkEditorView.swift */, DE1F1A1A2A8B50C500A88DD8 /* BoxContentsViewGroup.swift */, DE24E6372A8FE10300E29F5D /* BoxBaseSplitView.swift */, ); @@ -879,7 +879,6 @@ DE0A917B2A8F0CA800D1D6F1 /* AppleScripts+ShowMessage.swift in Sources */, DE018BB82A5099F900FF0AA3 /* Box42.xcdatamodeld in Sources */, DEF0761B2AA33671005700E5 /* DeleteUserMeScript.swift in Sources */, - 7ECC67EA2AA5B74600265D54 /* BookmarkEditorView.swift in Sources */, DE62BE672A9BA92E00D97E06 /* QuickSlotButtonViewItem.swift in Sources */, DEF076302AA3CF8A005700E5 /* QuickSlotItemLabel.swift in Sources */, DE874F542A591F1400FC3B77 /* PreferencesView.swift in Sources */, @@ -929,6 +928,7 @@ DE018BB32A5099F900FF0AA3 /* AppDelegate.swift in Sources */, DE78860C2A9C770300FE21DD /* ScriptsViewModel.swift in Sources */, DE0A91632A8E6A5400D1D6F1 /* Constants.swift in Sources */, + 7E9B46922AA5C564009EB900 /* BookmarkEditorView.swift in Sources */, DE7886172A9CCB3B00FE21DD /* UserProfile.swift in Sources */, DE0A91902A8F88CA00D1D6F1 /* DisplayURLInToolbar.swift in Sources */, DE77BBCD2A9E0568006CC98B /* ExecuteScripts.swift in Sources */, diff --git a/Box42.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Box42.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 19d4e8c..009c162 100644 --- a/Box42.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Box42.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,16 +1,14 @@ { - "object": { - "pins": [ - { - "package": "SnapKit", - "repositoryURL": "https://github.com/SnapKit/SnapKit.git", - "state": { - "branch": null, - "revision": "f222cbdf325885926566172f6f5f06af95473158", - "version": "5.6.0" - } + "pins" : [ + { + "identity" : "snapkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SnapKit/SnapKit.git", + "state" : { + "revision" : "f222cbdf325885926566172f6f5f06af95473158", + "version" : "5.6.0" } - ] - }, - "version": 1 + } + ], + "version" : 2 } diff --git a/Box42/BoxWindowController.swift b/Box42/Main/BoxWindowController.swift similarity index 100% rename from Box42/BoxWindowController.swift rename to Box42/Main/BoxWindowController.swift diff --git a/Box42/UI/HoverButton.swift b/Box42/Main/UI/HoverButton.swift similarity index 100% rename from Box42/UI/HoverButton.swift rename to Box42/Main/UI/HoverButton.swift diff --git a/Box42/UI/MovableContainerView.swift b/Box42/Main/UI/MovableContainerView.swift similarity index 100% rename from Box42/UI/MovableContainerView.swift rename to Box42/Main/UI/MovableContainerView.swift diff --git a/Box42/Main/View/BookmarkEditorView.swift b/Box42/Main/View/BookmarkEditorView.swift new file mode 100644 index 0000000..fc0088f --- /dev/null +++ b/Box42/Main/View/BookmarkEditorView.swift @@ -0,0 +1,104 @@ +// +// BookmarkEditorView.swift +// Box42 +// +// Created by Dasol on 2023/09/04. +// + +import Cocoa + +class BookmarkRowView: NSView { + let nameField = NSTextField() + let urlField = NSTextField() + + init(bookmark: (String, String)) { + super.init(frame: .zero) + + nameField.stringValue = bookmark.0 + urlField.stringValue = bookmark.1 + + addSubview(nameField) + addSubview(urlField) + + nameField.snp.makeConstraints { make in + make.top.bottom.equalToSuperview() + make.leading.equalToSuperview() + make.width.equalToSuperview().multipliedBy(0.5) + } + + urlField.snp.makeConstraints { make in + make.top.bottom.trailing.equalToSuperview() + make.leading.equalTo(nameField.snp.trailing) + } + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +class BookmarkEditorView : NSView { + + var bookMarkList : [(String,String)] + var changeButton=NSButton(title:"Change",target:nil,action:nil) + var closeButton=NSButton(title:"Close",target:nil,action:nil) + + init(bookMarkList : [(String,String)]){ + + self.bookMarkList=bookMarkList + + super.init(frame:.zero) + + for (index, bookmark) in bookMarkList.enumerated(){ + let row=BookmarkRowView(bookmark: bookmark) + self.addSubview(row) + + row.snp.makeConstraints { make in + if index == 0 { + // First row should be at the top of the editor. + make.top.equalToSuperview() + } else { + // Other rows should be below the previous one. + make.top.equalTo(self.subviews[index - 1].snp.bottom) + } + + // All rows have the same height and span the entire width of the editor. + make.height.equalTo(44) // Or any other height you want. + make.left.right.equalToSuperview() + } + } + + self.addSubview(changeButton) + + changeButton.snp.makeConstraints {make in + if let lastSubview=self.subviews.last{ + // Place it under last subview + make.top.equalTo(lastSubview.snp.bottom).offset(10) + }else{ + make.top.equalToSuperview() + } + + make.centerX.equalToSuperview() + } + + self.addSubview(closeButton) + closeButton.target = self + closeButton.action = #selector(closeButtonClicked(_:)) + closeButton.snp.makeConstraints{maker in + maker.centerX.equalToSuperview() + maker.top.equalTo(changeButton.snp.bottom).offset(10) + maker.bottom.equalToSuperview().offset(-10) + } + } + + required init?(coder aDecoder:NSCoder){ + fatalError("init(coder:) has not been implemented") + } + + @objc func closeButtonClicked(_ sender:NSButton) { + removeFromSuperview() + } +} + + + diff --git a/Box42/View/BoxBaseSplitView.swift b/Box42/Main/View/BoxBaseSplitView.swift similarity index 100% rename from Box42/View/BoxBaseSplitView.swift rename to Box42/Main/View/BoxBaseSplitView.swift diff --git a/Box42/View/BoxContentsViewGroup.swift b/Box42/Main/View/BoxContentsViewGroup.swift similarity index 100% rename from Box42/View/BoxContentsViewGroup.swift rename to Box42/Main/View/BoxContentsViewGroup.swift