I'm designing a simple GUI. I have Widgets, which have children and one parent. Each Widget is a Composite object, with a vector of WidgetComposite objects. One of those WidgetComposites is a PaintingBehaviour, but the Widget doesn't know it as such.
To display my window, I use a Visitor, called the ScreenVisitor. When the Visitor is called, this is what happens :
The first widget, the WidgetScene, iterates on each of its Widgets and calls the "accept(Visitor* v)" method. Then, each widget accepts the visitor, then iterates on its children.
For instance, this is a list of the objects (in the order it's going to happen) the visitor will have to accept.
root
child1
child2
child3
child4
child5
child6
child7
Now, my problem is simple : I want each Widget to be painted on its parent. How would you proceed ? I've tried with a tree, but I always have the same problem : when I have to go up in the hierarchy (for instance, after having displayed child3, when I have to display child4) I don't know how to get the right parent.
I'm coding in C++ but this problem is not language specific.
Do you have any ideas ? Thanks in advance !
The question is not very clear to me. If you just need to get them to be painted in the correct order. Parent before children, that would be quite easy:
accept(Visitor v)
paint() //paint parent first
v.visit()
foreach child
child.accept(v) //then paint children
If you need the parent (why?), you could change the accept method to (optionally) take a parent node.
accept(Visitor v,Element parent = null)
paint()
v.visit()
parent.foo()
foreach child
child.accept(v,this)
All right, since I could not find anything else, I tried this solution :
The visitor create a tree of "DisplayNodes" objects, who are basically a class made essentially of pointers. Here are the attributes of the class :
class DisplayNode
{
private:
Widget* myWidget;
PaintingBehaviour* myPB;
DisplayNode* myParent;
vector <DisplayNode*>myChildren;
};
Every DisplayNode is stocked in a vector in my visitor.
Then, for each PaintingBehaviour, I test the parent of the Widget connected, and check if one of my Node's "myWidget" is this parent. So I can find back where is everything. After that, it's quite easy, a simple paint method in DisplayNode with recursive calls to the children, called with the first DisplayNode of the scene...
Since it's a bit heavy, I create the tree of DisplayNode only once (though I do it again if PaintingBehaviour or widgets are added / removed). If the tree already exists, I go directly to the recursive painting.
It's a bit twisted (and probably not quite optimized), I'll admit, but it works ! But if anybody has a better solution, I'll be more than happy to hear it.
Related
I have a custom tree model with many items. It has more than 1000000 items at the first level below the top level. When I expand this level in a QTreeView it calls model.hasChildren() for each of these items even though the items are not visible (you would need to scroll down, down, down... to make them visible). The trouble is that my function hasChildren() takes some time especially when called million times (takes about 10 secs - in PySide/PyQt). My questions are:
1) I understand that hasChildren() is called for visible items because it must know whether the item should be expandable (if it has children) or not. But why it is called for invisible items (I mean those which are not inside the visible range and become visible only after scrolling down)? In my view it should be called only when the item is about to become visible. Am I missing somethig?
2) How to work around this issue?
You likely need to override fetchMore/canFetchMore per pyqt docs. Basically when you expand the root, fetchMore() will be called, you will only return a subset of data items; when the user scrolls, the view will ask the root if it can fetch more; if it answers yes, fetchMore() will get called and your model can return more items. This should cause hasChildren() to be called only on the tree items fetched.
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.
Is their anyway of keeping one tile at a constant position in a wrap panel and having all the added items (currently implementing through a listbox, so listboxitems) wrap around this item.
For example, having the blue tile constant regardless of how many items, with every other tile wrapping around it.
For example:
and:
*Edit #1
I've been looking into custom panels. Maybe i could add a field that if true, would allow for the absolute positioning of an element? Still need to understand how exactly the wrappanel wraps its elements.
*Edit #2
Just realized that idea wont work either. since the attribute of whether the item should have an absolute position would depend on the item itself and so it would require another container, like a "WrapPanelItem" of some sort to define that. Ugh lol
Edit #3
I can maybe set the "Tag" attribute of the children and have a custom Wrappanel check this attribute of the child. If it equals a certain value, it wont adjust its position? But then how do i set the initial position?
Edit #4
No luck with the previous idea.
Edit #5
So i'm attempting to make the custom panel again, but i have a few questions. When items are placed in a grid, how does the arrange method place the item in the item's desired position. I've looked and couldn't find such a property, so how then does the method know where to put the item?
Solved this by making a custom version of the "VariableSizedWrapGrid" provided in Kinnara's branch of the WP7ToolKit. (https://github.com/Kinnara/WPToolkit). It didnt work initially, as it wasn't checking if the entire block fit and instead than just the first unit of the block. If anyone is running into this problem PM me and il send you my updated control :)
O, and instead of trying to wrap around one element, i overlapped the element and had the elements wrapping in the background using the VariableSizedWrapGrid. This implementation was ALOT easier than what i was trying to do.
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
What is good GUI pattern for showing that a child is inheriting a value from its parent. In other words, if the user sets some value in the Parent, how would we indicate in the child that the value was set from the parent?
Parent
| Value : Foo
|
|----Child
Value : Foo => inheriting value from parent.
A lot depends on how interactive you'd like the different levels to be. More interactive (ability to change/override/etc), means making them stronger - less interactive (just for research purposes) - make them weaker.
If you're talking about displaying them all in a tree, then I'd actually leave the child with the same value and a label indicating "parent":
parent_div : width = 250
|
|-- child_div : Width = 250 ('parent_div')
If you're not showing them in a tree, then I'd display the value in some non-interactive way (I'm a fan of using a light grey, indented and italicized (i know that seems like overkill, but it's worth it)) - and then have a tooltip or mouseover that indicates where the original came from.
In either case, let me stress, it's INCREDIBLY valuable to have a direct link somewhere that gets you to the point where the value was set to begin with. It's so annoying to have to try to manually navigate there.
For an example I quite like, let me point at the Trace Styles tool in IE8 - tells me EXACTLY where the style came from (and lets me edit all the way up the chain) - Convenient!
IE 8 SS http://img101.imageshack.us/img101/3172/captureri.png
Leave it at book or regular weight, and make values modified in the child bold weight.