brendand / mbtablegrid

An NSControl subclass which provides a spreadsheet-style table grid
9 stars 3 forks source link

Auto-complete cell content #41

Closed brendand closed 9 years ago

brendand commented 9 years ago

Add a feature to enable auto-complete on specified cells. The datasource could provide a list of relevant values to be entered into the cell given the current value entered into the cell. The auto-complete values would be displayed in a popup menu.

screen shot 2015-03-05 at 11 04 04 am

Dejal commented 9 years ago

I've implemented the data source stuff for this, but need to figure out how to display the auto-complete menu. A couple of options:

  1. Display a popover, and keep the keyboard focus on the table grid.
  2. Use NSComboBoxCell instead of NSTextFieldCell for cells that support auto-completion.

I don't have any strong preference.

Dejal commented 9 years ago

I was thinking overnight that another option could be to display a view below (or above, if the selection is near the bottom of the table grid) listing the auto-completions. That seems to be what Numbers does. Seems less tidy than using a popover or combo cell, but would at least be reasonable within the scope of the table grid control.

Using a combo box cell could be self-contained, since the controller would implement the combo list data source.

If a popover is best, since a control presenting a view controller like that feels like a bad design, it might be best to leave it up to the host controller: have a delegate method like

- (void)tableGrid:(MBTableGrid *)aTableGrid
    presentCompletionsForEditString:(NSString *)editString
    column:(NSUInteger)columnIndex row:(NSUInteger)rowIndex position:(NSPoint)position;

and the controller can implement as it likes, e.g. presenting a popover from the specified position, using the edit string and column/row values to populate it.

Would also need a delegate method to tell the controller to dismiss the popover when the edit ends, e.g.

- (void)dismissCompletionsForTableGrid:(MBTableGrid *)aTableGrid;

And would need a MBTableGrid method (not a data source or delegate one) to tell the table grid of a popover selection so it can update the editor, e.g.

- (void)updateEditorWithCompletion:(NSString *)editString;

Thoughts? I won't do any more on this issue until we decide on an approach.

brendand commented 9 years ago

It would seem to me that using the NSComboBoxCell would be a simpler approach and less work for the developer of the controller class. There should be no arrow control next to it in that case as there's no arrow in Numbers. Also, in my Numbers tests, if the cell was near the bottom of the window, it still put the completion menu below. I didn't see it being displayed on top of the cell.

brendand commented 9 years ago

It seems that Numbers uses a custom view for that:

numbers-autocomplete

Dejal commented 9 years ago

Yeah, Numbers looked like a custom view, from its behavior. I could do a custom view too, added as a subview of the table grid control, but using a combo box cell is probably better and simpler, since it leverages AppKit functionality.

brendand commented 9 years ago

Agreed

brendand commented 9 years ago

My only concern is if there will be a performance impact between using an NSTextCell and an NSComboBoxCell. Hopefully not.

Dejal commented 9 years ago

NSComboBoxCell is a subclass of NSTextFieldCell, so I doubt there would be much of a penalty. The extra functionality would presumably only kick in when actually editing.

brendand commented 9 years ago

Alright then. Make it so.

Dejal commented 9 years ago

I'm not having much luck using NSComboBoxCell. The main issue is that there isn't any way to pop up the list programmatically, as we'd want. It's designed to only pop up by the user clicking on the button. Interestingly, the button doesn't show (which we're fine with), but that makes it impossible to display the list.

So maybe I should add a subview with a table view instead? Or would you prefer the popover approach? A table view could be handled internally, so all the host controller would need to provide are the strings to display. (NSComboBox embeds its list in a custom window to allow it to go outside the bounds of the control, but I think we can make it fit within the table grid view bounds, and so avoid that extra complication.)

Of course, another approach could be to use the accessory button: if clicked, show a popup menu (context menu) with the suggested completions. Not the same as in Numbers, but might achieve what your users want.

Or if you don't mind having the combo box popup icon, and having the user manually display its list, I could keep working on the combo box approach.

brendand commented 9 years ago

Oh that's a bummer. What about just showing an NSMenu at the location of the cell when you start to type?

brendand commented 9 years ago

Found this: https://github.com/MindPreview/RSAutocomplete

brendand commented 9 years ago

Or this: http://stackoverflow.com/questions/19250827/how-to-trigger-complete-method-for-a-nstextfieldcell-in-order-to-display-the-a

Dejal commented 9 years ago

Thanks for those suggestions; I guess I wasn't thinking at the right level. This is now done, with very little code.

brendand commented 9 years ago

:+1: That's awesome!