[litwindow-users] Re: Accessing Items
Status: Alpha
Brought to you by:
hajokirchhoff
From: Hajo K. <mai...@ha...> - 2005-04-18 09:44:26
|
yrs90 wrote: > Are there any provisions for allowing user code to access the RapidUI lookup > mechanism? That is not neccessary, because your code passes all the objects to RapidUI in the first place, so you already have access to the objects directly. > If I want to create a general event handler for all lists, it > would be nice to retrieve the Items property for the list that generated the > event. You can do that. Its extremely easy. wxListCtrl *m_ctrl; aggregate ag(*m_ctrl); accessor the_items=ag["Items"]; The common denomiator between RapidUI and your code are the accessors. They are the basis for everything! Just as RapidUI uses accessors to access your data, so can you. The above is equivalent to saying m_ctrl->Items, only that there is no C++ property Items of course. And in addition to that, Items exists only in the Lit Window Library enhanced version of wxListCtrl. But "Items" is available to C++ through the data adapters. aggregate ag(*m_ctrl) builds a new aggregate adapter from the list control. ag["Items"] returns an accessor to the "Items" property of the aggregate if there is one or throws an exception if there is no such property. Have a look at the aggregate documentation for other useful functions, such as iterators, find etc... So with accessor the_items=ag["Items"]; you now have an accessor for the items property for the list that generated the event. You can now, for example, container the_items_container=the_items.get_container(); get a container adapter, which is valid if "Items" is indeed a container, and iterate over all elements or insert and delete elements in the container. Note that this is not a copy of the container but a direct reference to the original container you passed to the Items property. > Eventually I guess the rules mechanism will be sufficient. But for now I > have to insert or delete manually. Right now I am referencing the > underlying data directly in a fixed manner. Example: Let this be the underlying data: vector<MyStruct> my_data; You pass the vector to your control with this rule: RULE("MyList.Items", make_expr<accessor>("my_data")) If you modify my_data in any way you must call NotifyChanged(my_data) to trigger rule evaluation and update the control. Now instead of directly referencing my_data in your handler, if you follow the aggregate approach above: void MyHandler::OnSomething(wxEvent &evt) { wxListCtrl *the_list=wxDynamicCast(evt.GetWindow(), wxListCtrl); aggregate ag(*the_list); // get an aggregate accessor ac(ag["Items"]); // get an accessor for "Items" container c(ac.get_container()); // get a container for "Items" // this ASSERT will evaluate to true in your case because // the container you obtained in this manner references the // same underlying object as make_container(my_data) wxASSERT(c.is_alias(make_container(my_data))); } make_aggregate... makes the transition between plain C++ runtime and aggregates/RapidUI properties. The reverse is also possible. accessor ac(ag["Items"]); typed_accessor<vector<MyData> > direct_ac=dynamic_cast_accessor<vector<MyData> >; Now you are casting the accessor back to the real thing, a pointer to vector<MyData>. typed_accessors are access objects you can use when the type is known at compile time. Use them to access the underlying object directly like in the following example: vector<MyData> *my_ptr=direct_ac.get_ptr(); Now you have a typed, C++ pointer to the data. NOTE: get_ptr() can return 0! Not all typed_accessors can return a pointer. If the accessor points to a property that is not a member, but a get/set method pair, there is no object for which a pointer could be returned. So get_ptr() returns 0. But you can use typed_accessor::get and typed_accessor::set to still access the underlying object. Hope this helped. Hajo |