NSOutlineView grouping via bindings - cocoa

This is sort of a best practice question, since I can think of a few ways that would work.
I want to implement an outline view. Let's suppose I want to implement the one in OmniFocus (my aim is very similar):
(I refer to the outline view in the main pane of that screenshot, not to the sidebar.)
So my data type is a task. Any task can have subtasks. Each task has one or zero parent tasks. Classic data model for displaying in an outline view, right?
BUT! I would like to offer the user the ability to group these tasks visually by a property of their choice. They could group them by milestone, or by assigned user, or by component… there'll be a bunch of these. And this grouping should appear in the outline view, at the top level of the hierarchy, just like the "Inbox", "Home" and "Work" items in this OmniFocus screenshot.
So it's fairly obvious that to display the grouping, I should use the built in NSOutlineView methods for drawing a group cell: the outlineView:isGroupItem: delegate method. The problem is, this setup is assuming that each item in the outline view is represented by an item in whatever data model I've connected it to: so both my tasks and my group headers have to be represented in the data model.
Therefore, just binding to the Core Data table that represents my tasks is a no-no. I could forego bindings all together and just go back to the old style data source methods, but then I lose a bunch of useful stuff. So is there a middle ground?
I could, for example, create another class TaskTemporaryGroup. I give that class an ivar NSSet that is subtasks, the same key path as could be used on a task to get its children. Then I can bind my set of TaskTemporaryGroup objects to a tree controller, and it'll arrange the whole tree regardless of the fact that the top level items are a different class to those lower down. I'd have to take care when implementing drag and drop, to make sure that the grouping rows can't be arbitrarily dragged about, but it might work.
The other point of contention is that I would like clicking on the table headers to sort the rows within each group, but not to sort the top level groups. I assume NSTreeController applies the sort descriptors to each level of the hierarchy? I could have my TaskTemporaryGroup class return the same thing (i.e. its desired sorting order, that I've calculated separately) for any of the key paths that I want to be able to sort the rest of the cells on, so that to the framework it would look like they stayed in the same order no matter what property they were sorted by. Is this a good way to go or is it a hack?
So, to summarize:
How do people suggest I implement this kind of hierarchy, where the top level is a special case and all subsequent levels are the same kind of object?
Is the way I described, with a class to represent the top level objects that happens to respond to the same key paths as the child objects, a good way to go?
Does anyone have any tips about how to make sorting work well in this scenario?
Or will trying to use bindings for this task cause me a world of hurt?
Thanks,
Amy

Related

How to deal with recycling lists

I'm building a UI test suite for an iOS app using XCUITest api. The app uses recycle lists and I need to access specific cells of those lists during my tests as shown in the code below:
let cells: XCUIElementQuery = app.descendants(matching: XCUIElement.ElementType.any).matching(identifier: "cells_accessibility_id")
let cell: XCUIElement = cells.element(boundBy: index)
cell.tap()
My problem is that since this is a recycle list, as soon it scrolls by any reason during the test (like animations), cells are unloaded, "cells" won't return all items and then "index" won't get the right cell from the list or becomes out of bounds.
Is there another way that I can retrieve the whole list regardless of element visibility? Or do I have to change my tests/try another approach?
You can not rely on the indices of reusable cells as you pointed out, however there is usually a way to eliminate the dependency on having to test cells at certain indices. The solution will depend on what you want to test, but here are some possible alternative strategies:
If your table cells are always the same, you could give them each a hard-coded identifier based on their contents.
If your table cells have dynamic content in them, you could use stub test data for each test to make it so that there is only one cell on screen (the one which is relevant to the test).
If you can identify the cell you want by the views contained within the cell, you can search each cell for the relevant views before selecting it, instead of relying on its index.

Coordinating highlighting between two tables

The challenge is this: 2 coordinated tables, 1 with an overview that is laid out on a grid, the other contains detailed information about the cells in the first table. (This overview is used for other information as well, which has been removed from the minimal example below.) Mousing over either one will highlight both. Clicking on the overview table will hide or show the rows of the data view.
The problem is that the data is being defined by a JSON data object and the order of that object is very important. It's important that the data is mapped to the overview without reordering either. There may be cells not represented in the data view that are in the overview and nothing bad should happen.
http://fiddle.jshell.net/g8z5h/14/
The problem is using select all lets d3 define the order things will be taken. I need to coordinate the mapping myself. I'm hoping there's an elegant solution to this that doesn't involve writing separate mouseover and mouse click functions.
You can use a key function to tie the selection to your data:
http://bost.ocks.org/mike/selection/#key
http://bost.ocks.org/mike/constancy/#key-functions

How to create expandable listview in blackberry

i search a lot but no single link found for Expandable listview in Blackberry, i know how to create Expandable list in android ,if someone having idea about Blackberry Expandable listview than please help me.
The standard way to create List on BB is to use the ListField class. This class is extremely efficient but has a couple of drawbacks
All the rows have to be the same height
All the rows have to contiguous on the display
This makes it difficult to use this class to replicate the Android ExpandingListView.
To replicate this look on a BlackBerry device, I suggest a series of VerticalFieldManagers (VFMs). Use one for the whole list, and add to this another for each expandable item. If the item is expanded, add child list entries to the associated VFM, when not expanded, delete the child entries.
This approach will work OK up to a point - adding and removing Fields can slow down the BB device significantly if there are significant number of Fields on display. So if you have, say 20 items in the list, then it will be fine. If you have 2000, it will slow the device down significantly when you expand and contract the list (add and remove the child list items).
You can improve this performance, by making your list items (parent and child) as efficient as possible. I recommend reviewing the code that is used for the ListStyleButtonField that you will find here: http://supportforums.blackberry.com/t5/Java-Development/Implement-advanced-buttons-fields-and-managers/ta-p/488276
Update
Just wanted to clarify why ListField does not work directly, and a possible work around.
The problem with ListField is each row has a specific height. To display the child elements you really need to expand the height of the parent item to include the children, which you can't do. So you can't just update the called back paint method (called drawListRow(..) in a ListField) to achieve this look. And the other problem, is that one list item on a ListField is focused as a single entity where as I assume you would want to select the children individually.
Instead, when expanding you can add additional rows, effectively inserting the children items in the list to be drawn. You will have to add these rows with a flag, so that your drawListRow(..) method knows to paint these as children. Reverse on deletion. Note that the children items have to be the same height as everything else.
Having attempted both, I have found the VFM approach easier to manage. I would only consider the ListField approach where the list was large enough to impact performance. And when it is that large, who is going to scroll through that number of entries on their BB? If you are getting to that number, then a paging mechanism would seem more user friendly.
if you mean BlackBerry Java SDK, then take a look at TreeField class.
UPDATE:
In this case the ListField would be the most suitable choice. Implement ListFieldCallback according to your needs and attach it to the ListField instance. When user clicks on an "expandable" list item, then just process this event in ListFieldCallback and repaint your list instance. Here is the tutorial on working with ListField classes.

Looking for a specific control (sketch included)

I am looking for a control many of us probably know, but I don't know it's name and don't have a real screenshot by hand, just this sketch:
In the left box one can select an operation or whatever, which then is moved to the right side. With the up/down arrows on the right, one can move this operation (or whatever kind of meaning the entry has) up or down in the order of execution.
How is this kind of control called? Or is it normally build by developers out of single controls? Is this control available in JavaFX 2? If not, I don't need exactly this control, but a control with the following features:
User can select multiple operations (duplicates allowed) out of all available operations
The user can arrange their order of execution
Thanks for any hint :-)
You need to use multiple controls to build up your interface. Use two ListViews with a MultipleSelectionModel for each (or at least the left one) and add a couple of buttons, that copy selected items from one list to the other and another couple of buttons which modify the position of selected items in the right list view by modifying the view's underlying item list.
listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

Sorting/Grouping data in WP7 based on user input using LongListSelector

I’m working on an inventory display app (master/details) for Windows Phone 7 where the user has the ability to change the sorting. The source of the data is XML from the web, and depending on the sort chosen, the results are either a flat list (sorted by name, model number, etc.) or grouped by the selected attributes (color, size, etc.). I'll pre-determine whether the sort returns flat vs. group and it won't be user selectable.
I’m displaying the results in a WP7 pivot control and want/need the different sorts to appear in the same PivotItem (putting the sorts in different PivotItems isn’t really an option). The source for the list is an Observable Collection (actually at this point it’s a CollectionViewSource, but I’m not wedded to either). I’m using the MVVM Light framework.
I’ve played with LongListSelector from the Silverlight Toolkit and it looks like it does what I want. I've read a number of posts (starting with WP7 ListBox Grouping) and actually have it working for the flat list (no sort applied, just default as it is from the source). Now I’m trying to figure out the right way to use it.
My questions:
Is it possible to re-structure the way the data is displayed (flat/sorted vs. grouped) without having to build/maintain multiple observable collections of the same info (one for each sort variant)?
If not, is the best method to save a local copy of the data locally on the phone and work from there? I expect I'd take a hit on complexity but pick up savings on perf/responsiveness.
To display the various results in the same PivotItem, should I create user controls with the appropriate formatting and swap them in to the pivot based on the chosen sort, or can I do it via dynamic ItemSource & ItemTemplate changes?
Is Observable Collection/CollectionViewSource the way to go here?
It’s entirely possible (even likely) the answers are staring me in the face, but I’m new to this stuff and I’ve hit data overload. I could really use some guidance.
Thanks,
Rich
Is it possible to re-structure the way the data is displayed (flat/sorted vs. grouped) without having to build/maintain multiple observable collections of the same info (one for each sort variant)?
I think what you could try is using LINQ to query your given collection, and use that query as the source for your LLS. I'm not sure on how the performance would be, but you can give it a try. Alternatively, IIRC the various *ViewSource collections have ways of changing the view of your data, so you can check those out.

Resources