Skip to content

Conversation

@wogus3602
Copy link

2023-02-09.3.06.19.mov

@wogus3602 wogus3602 changed the title Added MultiSelect #8 Added MultiSelect Feb 8, 2023
@wogus3602 wogus3602 changed the title #8 Added MultiSelect Added MultiSelect Feb 8, 2023
@ZofiaBernadetta
Copy link
Collaborator

Hi @wogus3602 👋

Thanks for the taking the time to work on this! I was playing around with the example app and I noticed a couple of issues.

  • The first time I click on a row, the row is highlighted and then immediately goes back to normal. The first selection is not being registered.
  • Multiple selection does not work with drag and drop.

You can see both the issues on the screen recording:

Screen.Recording.2023-02-13.at.21.11.08.mov

@RCCoop
Copy link
Contributor

RCCoop commented Feb 14, 2023

@ZofiaBernadetta , the multi-select not working with drag & drop is something I can work on, since it's my code that ignored the possibility of multiple dragged items. Maybe once @wogus3602 is done with everything else on this PR, I can take that responsibility last :-)

@brendand
Copy link

@RCCoop did you ever add support for multi-select drag & drop?

@RCCoop
Copy link
Contributor

RCCoop commented Sep 25, 2023

@brendand , I haven't, sorry. I've been working on other projects lately that don't use OutlineView, so I haven't had time to look at it.

) {
// Returns -1 if row is not found.
let index = outlineView.row(forItem: selectedItem)
let index = outlineView.row(forItem: selectedItems)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the updated code is correct for multiple selected items. I grabbed your code for an app I'm working on and besides renaming it selectRows my current code is:
func selectRows(
for items: [OutlineViewItem],
in outlineView: NSOutlineView
) {
// Returns -1 if row is not found.
let indices = items.compactMap { outlineView.row(forItem: $0) == -1 ? nil : outlineView.row(forItem: $0) }
outlineView.selectRowIndexes(IndexSet(indices), byExtendingSelection: false)
}

if selectedItem?.id != newSelection?.id {
selectedItem = newSelection
selectionChanged(selectedItem?.value)
let selectedRowIndexes = outlineView.selectedRowIndexes

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To get selectionChanged(xxx) to be called when I chose a new outline row I had to comment out some of your code. The first check for isEmpty shouldn't be needed because selectionChanged(emptySet) still needs to be called if you unselect every row. Also returning early because selectedItems and newSelection counts are same caused single selecting new items to not call selectionChanged(xxx) too. Also wasn't sure why the if selectedItems.allSatisfy call was there too?
Current code I'm using:
func outlineViewSelectionDidChange(_ notification: Notification) {
let outlineView = notification.object as! NSOutlineView
let selectedRowIndexes = outlineView.selectedRowIndexes

#warning("Check with original author why commented out code was needed")
//if !selectedRowIndexes.isEmpty {
let newSelections = selectedRowIndexes.compactMap {
outlineView.item(atRow: $0).map(typedItem)
}

// if selectedItems.count == newSelections.count {
// return
// }

        //if selectedItems.allSatisfy({ newSelections.contains($0) }) {
            selectedItems = newSelections
            selectionChanged(Set(selectedItems.map(\.value)))
        //}
    //}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants