Make progress on drag and drop. Reads feeds from pasteboard. This needs refactoring, though.
This commit is contained in:
parent
f29f690625
commit
089ffbd299
|
@ -26,6 +26,18 @@ extension Feed: PasteboardWriterOwner {
|
|||
static let feedUTIInternal = "com.ranchero.NetNewsWire-Evergreen.internal.feed"
|
||||
static let feedUTIInternalType = NSPasteboard.PasteboardType(rawValue: feedUTIInternal)
|
||||
|
||||
private struct Key {
|
||||
|
||||
static let url = "URL"
|
||||
static let homePageURL = "homePageURL"
|
||||
static let name = "name"
|
||||
|
||||
// Internal
|
||||
static let accountID = "accountID"
|
||||
static let feedID = "feedID"
|
||||
static let editedName = "editedName"
|
||||
}
|
||||
|
||||
init(feed: Feed) {
|
||||
|
||||
self.feed = feed
|
||||
|
@ -57,23 +69,20 @@ extension Feed: PasteboardWriterOwner {
|
|||
|
||||
return plist
|
||||
}
|
||||
|
||||
// MARK: - Dragged Feed
|
||||
|
||||
static func draggedFeeds(with pasteboard: NSPasteboard) -> Set<DraggedFeed>? {
|
||||
guard let items = pasteboard.pasteboardItems else {
|
||||
return nil
|
||||
}
|
||||
let feeds = items.compactMap { draggedFeed(with: $0) }
|
||||
return feeds.isEmpty ? nil : Set(feeds)
|
||||
}
|
||||
}
|
||||
|
||||
private extension FeedPasteboardWriter {
|
||||
|
||||
private struct Key {
|
||||
|
||||
static let url = "URL"
|
||||
static let homePageURL = "homePageURL"
|
||||
static let name = "name"
|
||||
|
||||
// Internal
|
||||
static let accountID = "accountID"
|
||||
static let feedID = "feedID"
|
||||
static let editedName = "editedName"
|
||||
static let unreadCount = "unreadCount"
|
||||
}
|
||||
|
||||
func exportDictionary() -> [String: String] {
|
||||
|
||||
var d = [String: String]()
|
||||
|
@ -100,11 +109,51 @@ private extension FeedPasteboardWriter {
|
|||
if let editedName = feed.editedName {
|
||||
d[Key.editedName] = editedName
|
||||
}
|
||||
if feed.unreadCount > 0 {
|
||||
d[Key.unreadCount] = feed.unreadCount
|
||||
if let accountID = feed.account?.accountID {
|
||||
d[Key.accountID] = accountID
|
||||
}
|
||||
|
||||
return d
|
||||
}
|
||||
|
||||
static func draggedFeed(with dictionary: [String: String]) -> DraggedFeed? {
|
||||
guard let url = dictionary[Key.url] else {
|
||||
return nil
|
||||
}
|
||||
let homePageURL = dictionary[Key.homePageURL]
|
||||
let name = dictionary[Key.name]
|
||||
let accountID = dictionary[Key.accountID]
|
||||
let feedID = dictionary[Key.feedID]
|
||||
let editedName = dictionary[Key.editedName]
|
||||
|
||||
return DraggedFeed(url: url, feedID: feedID, homePageURL: homePageURL, name: name, editedName: editedName, accountID: accountID)
|
||||
}
|
||||
|
||||
static func draggedFeed(with pasteboardItem: NSPasteboardItem) -> DraggedFeed? {
|
||||
|
||||
// TODO: This needs to handle strings and URLs also.
|
||||
var pasteboardType: NSPasteboard.PasteboardType?
|
||||
if pasteboardItem.types.contains(FeedPasteboardWriter.feedUTIInternalType) {
|
||||
pasteboardType = FeedPasteboardWriter.feedUTIInternalType
|
||||
}
|
||||
else if pasteboardItem.types.contains(FeedPasteboardWriter.feedUTIType) {
|
||||
pasteboardType = FeedPasteboardWriter.feedUTIType
|
||||
}
|
||||
guard let foundType = pasteboardType else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let feedDictionary = pasteboardItem.propertyList(forType: foundType) as! [String: String]
|
||||
return draggedFeed(with: feedDictionary)
|
||||
}
|
||||
}
|
||||
|
||||
struct DraggedFeed: Hashable {
|
||||
|
||||
let url: String
|
||||
let feedID: String?
|
||||
let homePageURL: String?
|
||||
let name: String?
|
||||
let editedName: String?
|
||||
let accountID: String?
|
||||
}
|
||||
|
|
|
@ -25,21 +25,21 @@ import Account
|
|||
|
||||
func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
|
||||
|
||||
return nodeForItem(item as AnyObject?).numberOfChildNodes
|
||||
return nodeForItem(item).numberOfChildNodes
|
||||
}
|
||||
|
||||
func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
|
||||
|
||||
return nodeForItem(item as AnyObject?).childNodes[index]
|
||||
return nodeForItem(item).childNodes[index]
|
||||
}
|
||||
|
||||
func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
|
||||
|
||||
return nodeForItem(item as AnyObject?).canHaveChildNodes
|
||||
return nodeForItem(item).canHaveChildNodes
|
||||
}
|
||||
|
||||
func outlineView(_ outlineView: NSOutlineView, pasteboardWriterForItem item: Any) -> NSPasteboardWriting? {
|
||||
let node = nodeForItem(item as AnyObject?)
|
||||
let node = nodeForItem(item)
|
||||
guard nodeRepresentsDraggableItem(node) else {
|
||||
return nil
|
||||
}
|
||||
|
@ -49,10 +49,29 @@ import Account
|
|||
// MARK: - Drag and Drop
|
||||
|
||||
func outlineView(_ outlineView: NSOutlineView, validateDrop info: NSDraggingInfo, proposedItem item: Any?, proposedChildIndex index: Int) -> NSDragOperation {
|
||||
let parentNode = nodeForItem(item)
|
||||
if parentNode == treeController.rootNode {
|
||||
return SidebarOutlineDataSource.dragOperationNone
|
||||
}
|
||||
|
||||
guard let draggedFeeds = FeedPasteboardWriter.draggedFeeds(with: info.draggingPasteboard()) else {
|
||||
return SidebarOutlineDataSource.dragOperationNone
|
||||
}
|
||||
|
||||
let draggingSourceOutlineView = info.draggingSource() as? NSOutlineView
|
||||
let isLocalDrop = draggingSourceOutlineView == outlineView
|
||||
|
||||
// // If NSOutlineViewDropOnItemIndex, retarget to parent of parent item, if possible.
|
||||
// if index == NSOutlineViewDropOnItemIndex && !parentNode.canHaveChildNodes {
|
||||
// guard let grandparentNode = parentNode.parent, grandparentNode.canHaveChildNodes else {
|
||||
// return SidebarOutlineDataSource.dragOperationNone
|
||||
// }
|
||||
// outlineView.setDropItem(grandparentNode, dropChildIndex: NSOutlineViewDropOnItemIndex)
|
||||
// return isLocalDrop ? .move : .copy
|
||||
// }
|
||||
|
||||
if isLocalDrop {
|
||||
return validateLocalDrop(info, proposedItem: item, proposedChildIndex: index)
|
||||
return validateLocalDrop(draggedFeeds, proposedItem: item, proposedChildIndex: index)
|
||||
}
|
||||
return SidebarOutlineDataSource.dragOperationNone
|
||||
}
|
||||
|
@ -66,8 +85,7 @@ import Account
|
|||
|
||||
private extension SidebarOutlineDataSource {
|
||||
|
||||
func nodeForItem(_ item: AnyObject?) -> Node {
|
||||
|
||||
func nodeForItem(_ item: Any?) -> Node {
|
||||
if item == nil {
|
||||
return treeController.rootNode
|
||||
}
|
||||
|
@ -82,10 +100,10 @@ private extension SidebarOutlineDataSource {
|
|||
return node.representedObject is Feed
|
||||
}
|
||||
|
||||
func validateLocalDrop(_ info: NSDraggingInfo, proposedItem item: Any?, proposedChildIndex index: Int) -> NSDragOperation {
|
||||
func validateLocalDrop(_ draggedFeeds: Set<DraggedFeed>, proposedItem item: Any?, proposedChildIndex index: Int) -> NSDragOperation {
|
||||
|
||||
// let parentNode = nodeForItem(item)
|
||||
|
||||
// let node = nodeForItem(item)
|
||||
return SidebarOutlineDataSource.dragOperationNone
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue