litwindow-users Mailing List for Lit Window Library
Status: Alpha
Brought to you by:
hajokirchhoff
You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(13) |
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
|
Feb
|
Mar
|
Apr
(62) |
May
(10) |
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2008 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(2) |
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
From: ecomVia G. S. <no-...@ec...> - 2008-12-12 19:17:03
|
Boost your sales & Start getting new buyers Sir / Madam, As we have been attracted to your site "The Lit Window Library", we are proud to bring you the option of unique kind of priceless online presentation for your company and your products, that will bring you new potential buyers of your products and multiple your sales. With ecomVia Global System you can: Represent your company Introduce the activities and production of your company in a very latest kind of online presentation, by providing all details and information. Allow potential buyers to get a complete outlook on your company by providing images from inside life, production, etc. Display all of your products Attract daily visitors and convert them to your new buyers. Just add the complete and detailed descriptions of all your products, add the detailed and inviting images and use the enhancements to stand out of products of other companies. Access up-to-date requests & offers Check out, what the others need. There’s a high possibility, that someone is looking for product, you are able to produce or supply. Obtaining a new order has never been easier – just few clicks away. Get contacted with inquiries from possible buyers Providing detailed information about your company and products supplemented with inviting images assures a high possibility of early contacting by new potential buyers. Find supplies & partners for your company Search in milions of suppliers and products and find what you are looking for. At slovak-products.com you are able to find anything you require for your production and even find new dealers and local distributors for your products. Ready yet to receive new orders? Go to http://www.ecomvia.info/registration to start now! Thanks and best regards, ecomVia Inc. SNP street 119, SK-90873 Velke Levare. Slovakia Tel.: +421-910-353111 |
From: ecomVia G. S. <no-...@ec...> - 2008-12-12 19:17:03
|
Boost your sales & Start getting new buyers Sir / Madam, As we have been attracted to your site "The Lit Window Library", we are proud to bring you the option of unique kind of priceless online presentation for your company and your products, that will bring you new potential buyers of your products and multiple your sales. With ecomVia Global System you can: Represent your company Introduce the activities and production of your company in a very latest kind of online presentation, by providing all details and information. Allow potential buyers to get a complete outlook on your company by providing images from inside life, production, etc. Display all of your products Attract daily visitors and convert them to your new buyers. Just add the complete and detailed descriptions of all your products, add the detailed and inviting images and use the enhancements to stand out of products of other companies. Access up-to-date requests & offers Check out, what the others need. There’s a high possibility, that someone is looking for product, you are able to produce or supply. Obtaining a new order has never been easier – just few clicks away. Get contacted with inquiries from possible buyers Providing detailed information about your company and products supplemented with inviting images assures a high possibility of early contacting by new potential buyers. Find supplies & partners for your company Search in milions of suppliers and products and find what you are looking for. At slovak-products.com you are able to find anything you require for your production and even find new dealers and local distributors for your products. Ready yet to receive new orders? Go to http://www.ecomvia.info/registration to start now! Thanks and best regards, ecomVia Inc. SNP street 119, SK-90873 Velke Levare. Slovakia Tel.: +421-910-353111 |
From: Hajo K. <mai...@ha...> - 2005-06-13 10:20:28
|
Hello all, as of June-10th, McAfee virus scanner incorrectly reports a 'Generic Backdoor' trojan horse for the Lit Window Library setup.exe, which was created with the Inno Setup installer (http://www.jrsoftware.org/isinfo.php). This happens with McAfee DAT files version 4511 and should be corrected with the next DAT version, 4512, hopefully out within the next few days. The Lit Window Library setup.exe is *NOT* infected. This is a false positive. For more information please read http://vil.mcafeesecurity.com/vil/content/v_103069.htm Best regards Hajo Kirchhoff -- -------------------------------------------- Lit Window Library - Speed up GUI coding 10x http://www.litwindow.com/library?src=ml wxVisualSetup - integrate wxWidgets into Visual Studio .NET http://www.litwindow.com/Products/products.html?src=ml BugLister - Defect Tracker http://www.litwindow.com/buglister?src=ml Tips & Tricks for wxWidgets & MS Visual Studio http://www.litwindow.com/Knowhow/knowhow.html?src=ml |
From: Hajo K. <mai...@ha...> - 2005-05-21 05:07:52
|
Hi, > As I was working on this, I noticed that there doesn't seem to be any check > that the iterator does not increment past the last element. In particular > advance() seems susceptible to overrunning the container in the basic case. that is correct. The current implementation follows the STL iterators closely and like them does not have any checks. Actually I am not sure if advance is really used at all or if it was just a failed attempt at starting with the bookmarks implementation. > In implementing the filter feature, I need to compare against the end > element in a few other locations too, but I don't see any way to access > end() or npos or whatever from within a container_iterator_imp_base subclass > or via access to the stl container's iterator. Am I missing something? No. If you need this you have to do it yourself. > While I was searching around looking for something within the iterator class > that would tell me if I was at the end, I stumbled across the boost > library's filtered iterator implementation. > (http://www.boost.org/libs/iterator/doc/filter_iterator.html) They appear to > address the boundary condition test by explicitly passing an end iterator. > I wonder if using it would be as simple as declaring the filtered iterator > as a litwindow container. If it follows the STL container conventions, yes. If it doesn't, you will have to override the make_container_iterator and container_iterator mechanism. BTW, I can *highly* recommend the boost library. I have all but finalized my decision to use boost with the Lit Window Library anyway. > filter to a rule in litwindow. Once I resign myself to creating a new > container/iterator implementation for each filtered view, I find that the > independence of the iterator from the container prevents me from passing the > end value to the iterator. A way around this are the container_converter::get_begin() / container_converter::get_const_begin methods. You have to override them anyway and can pass a pointer to the container to your iterator. STL iterators are fast but extremely simple. The IBM Open Class Library for example had a much more sophisticated concept. And iterators there always had a pointer back to the owning container. BTW, passing end() to the iterator will not be sufficient in your case, since end() may change over time. So you really need the pointer to the container itself and get 'end()' everytime you need it. > I appreciate the direction thus far. The instructions were very clear. If I > can solve the 'end' problem, I think I can give this a try. Otherwise, I > could embark on an exploration of boost library (which looks fairly > elegant), but I'm sure that will be time consuming too... If you have the time, explore it. It is well worth it. Start with shared_ptr<>, if you are not already using it. Best regards Hajo |
From: yrs90 <yr...@ya...> - 2005-05-20 07:08:47
|
> I have experimented this morning and I think your easiest route will be > implementing your own iterators. It looks much more complicated than it > actually is. Here is what you need to do: Well that was very nice. Thank you. As I was working on this, I noticed that there doesn't seem to be any check that the iterator does not increment past the last element. In particular advance() seems susceptible to overrunning the container in the basic case. In implementing the filter feature, I need to compare against the end element in a few other locations too, but I don't see any way to access end() or npos or whatever from within a container_iterator_imp_base subclass or via access to the stl container's iterator. Am I missing something? While I was searching around looking for something within the iterator class that would tell me if I was at the end, I stumbled across the boost library's filtered iterator implementation. (http://www.boost.org/libs/iterator/doc/filter_iterator.html) They appear to address the boundary condition test by explicitly passing an end iterator. I wonder if using it would be as simple as declaring the filtered iterator as a litwindow container. This actually highlights a conceptual problem I was having. I am defining a new container (a set<MyListElementDataClass*>) to go with the customized iterator. It seems clumsy, but I don't see any way to pass an adaptive filter to a rule in litwindow. Once I resign myself to creating a new container/iterator implementation for each filtered view, I find that the independence of the iterator from the container prevents me from passing the end value to the iterator. I appreciate the direction thus far. The instructions were very clear. If I can solve the 'end' problem, I think I can give this a try. Otherwise, I could embark on an exploration of boost library (which looks fairly elegant), but I'm sure that will be time consuming too... Regards, Joel --- [This E-mail scanned for viruses by Declude Virus] |
From: Hajo K. <mai...@ha...> - 2005-05-19 10:39:43
|
Hi, yrs90 wrote: > I am at the point where I need to the ability to filter a list. I considered I have experimented this morning and I think your easiest route will be implementing your own iterators. It looks much more complicated than it actually is. Here is what you need to do: First I'd, typedef your container so that it gets its own unique name. IMPLEMENT_CONTAINER_ADAPTER(MyContainer) instantiates the entire container adapter mechanism. A container is really nothing more than a container iterator factory providing access to begin() and end() and ++. Step 1: Write your own iterator adapter. Derive it from container_iterator_imp_base for non-const, from const_container_iterator_imp_base for const container access. You need to implement the following functions: virtual (const_)container_iterator_imp_base *clone() create a copy of self on the heap and return it virtual (const_)accessor get() const return an accessor pointing to the current location virtual void inc() advance the iterator one element virtual void advance(size_t off) advance the iterator 'off' elements Example: typedef map<wxString, obj*> MyContainer; class MyContainerIterator:public container_iterator_imp_base { MyContainer::iterator m_iterator; // the real iterator public: MyContainerIterator(const MyContainer::iterator &i) :m_iterator(i) { } container_iterator_imp_base *clone() const { return new MyContainerIterator(*this); } accessor get() const { return make_accessor(*m_iterator); } void inc() { ++m_iterator; } void advance(size_t off) { while (off--) inc(); } }; Step 2: You have to use template specialization to override the default iterator factory. Add template<> container_iterator_imp_base *container_converter<MyContainer>::get_begin(const schema_entry *se, const_prop_ptr member_ptr) const { return new MyContainerIterator(member(member_ptr).begin()); } in front (!) of the IMPLEMENT_CONTAINER_ADAPTER statement. It needs to go in front so the compiler sees the specialization before it instantiates the template. 'new MyContainerIterator...' creates a new MyContainerIterator object on the heap and returns a pointer to it. member(member_ptr) returns a reference to the container itself. member(member_ptr).begin() makes sense only if the container actually has a 'begin' method. The STL containers do, but if you where using a different container, you'd be calling a different method. container_converter is a class defined in dataadaptercontainerimp.h. It has four relevant functions: get_begin(), get_end(), get_const_begin() and get_const_end(). These functions return a pointer to a container_iterator_imp_base for non-const container and const_container_iterator_imp_base for const container. You need to override all these methods. Step 3: Add filtering. In Step 1 you defined MyContainerIterator::inc. Modify it so that it skips elements you want filtered out. You will also have to modify the container_converter::get_(const_)begin methods so they will return an iterator to the first element that matches the filter criteria instead of just the first element. > overriding iterators, but it looks pretty complicated. I considered > avoiding the problem by simply creating new underlying data, a new string > vector, to populate the filtered list, but I can't create a rule that allows > me to connect an item selected from the filtered list back to the original > list. For example the following rule won't work: > > RULE("xrcTextCtrl.Text", > make_expr<wxString>("m_FullData[xrcFilteredList.Current].Details")) But you could write your own property here. Assuming that m_FullData is part of a struct MyData, write a FullDataCurrent property with get/set methods that reflect m_FullData[xrcFilteredList.Current]. But its a cludge. > I am considering creating a Condition property in the lwListAdapterBase. The > idea is that an item is inserted in the list only if the Condition evaluates > true. > > Currently there isn't any rule syntax that would allow me to refer to the > current item such that I could evaluate a Boolean rule for each list item. > Also, I am not sure how to cause a rule to be reevaluated. Hm, intriguing. You are suggesting a property that is itself an expression or rule. So that I could pass an expression to the property and it would be evaluated when needed. I'll have to keep that in mind. This is possible and I like the idea. > Any suggestions on the easiest way to add this functionality? Try writing your own iterators. Its not very hard to do, it just looks this way since its still undocumented. Regards Hajo |
From: yrs90 <yr...@ya...> - 2005-05-19 04:30:02
|
I am at the point where I need to the ability to filter a list. I considered overriding iterators, but it looks pretty complicated. I considered avoiding the problem by simply creating new underlying data, a new string vector, to populate the filtered list, but I can't create a rule that allows me to connect an item selected from the filtered list back to the original list. For example the following rule won't work: RULE("xrcFullList.Items", make_expr<accessor>("m_FullData")) RULE("xrcFilteredList.Items", make_expr<accessor>("m_FilteredData")) RULE("xrcTextCtrl.Text", make_expr<wxString>("m_FullData[xrcFilteredList.Current].Details")) where m_FullData is map<wxString,ComplexDataType> and m_FilteredData is vector<wxString>. (I'm trying to avoid duplicating the entire data set.) I am considering creating a Condition property in the lwListAdapterBase. The idea is that an item is inserted in the list only if the Condition evaluates true. Currently there isn't any rule syntax that would allow me to refer to the current item such that I could evaluate a Boolean rule for each list item. Also, I am not sure how to cause a rule to be reevaluated. Alternatively, (but more restrictively) I could require that the Condition be a string value referring to a member of the aggregate currently being inserted. In that case I think I could reference the member via ag[GetCondition()]. Also, in this case I'm not sure yet how to invoke the aggregate member. Any suggestions on the easiest way to add this functionality? Thanks, Joel --- [This E-mail scanned for viruses by Declude Virus] |
From: yrs90 <yr...@ya...> - 2005-05-02 10:17:58
|
> Regarding your other post and 'SetLabel': I will introduce a new > property 'Text' or perhaps 'String' and will call SetValue instead. > Makes things more 'proper'. Label is indeed misleading. It turns out that SetLabel doesn't have the intended affect in a multiline wxTextCtrl anyway. Even with the correct wxTE_MULTILINE style set, the SetLabel doesn't translate the newlines into linefeed carriage returns. > What do you think would be better? Text or String? Value is already > taken and accepts an accessor. Double accepts double. So text could > accept a text. In a fit of not-very-creative-let's-get-it-to-work, I created a StrValue here locally. Either of your suggestions sounds acceptable, but I think "Text" is a little closer to the actual meaning. So that's my vote. Joel --- [This E-mail scanned for viruses by Declude Virus] |
From: Hajo K. <mai...@ha...> - 2005-05-02 05:59:25
|
yrs90 wrote: >>Use xrcTextCtrl.Label instead of .Value. > > > It works! I thought I looked for another property that accepted wxString. > In fact, I don't see Label defined anywhere except wxControl. I guess it > searches both co-objects, adapter and widget hierarchies. I'm very happy to > get this working. > > Thanks! > Great. Yes, both hierarchies are searched. The lit window text control 'inherits' from the textctrladapter and the textctrl itself. Regarding your other post and 'SetLabel': I will introduce a new property 'Text' or perhaps 'String' and will call SetValue instead. Makes things more 'proper'. Label is indeed misleading. What do you think would be better? Text or String? Value is already taken and accepts an accessor. Double accepts double. So text could accept a text. Suggestions? Hajo |
From: yrs90 <yr...@ya...> - 2005-05-01 10:43:48
|
> Use xrcTextCtrl.Label instead of .Value. It works! I thought I looked for another property that accepted wxString. In fact, I don't see Label defined anywhere except wxControl. I guess it searches both co-objects, adapter and widget hierarchies. I'm very happy to get this working. Thanks! --- [This E-mail scanned for viruses by Declude Virus] |
From: yrs90 <yr...@ya...> - 2005-05-01 09:16:53
|
> I will investigate that. Might be a typo or it might be that for > wxTextCtrl SetValue and SetLabel do the same thing. I found the following: http://groups-beta.google.com/group/comp.soft-sys.wxwindows/browse_thread/th read/c3e65abf426862e/06bfe1a5055f37a9 <quote> I believe the correct API calls for working with the contents of a TextCtrl are GetValue and SetValue. The fact that Get/SetLabel works on MSW is probably an artifact of how Windows itself implements the text controls. </quote> > > I'd like to assign a wxString to Value, but I'm having trouble > > figuring out > > how to convert a wxString to an accessor in a wxTextCtrl rule. I > > thought wrongly that perhaps the following rule would work. > > > > PROP_GetSet(wxString, Info) > > RULE("xrcTextCtrl.Value", > > make_accessor(make_expr<wxString>("xrcList.Current.Info"))) > > I'll investigate. Thanks. I don't have a solution yet. I've tried rules of a few different varieties: RULE("xrcTextCtrl.Value", make_const<accessor>(make_accessor(wxString("test string")))) RULE("xrcTextCtrl.Value", make_accessor(make_expr<wxString>("xrcList.Current.second.Info))) RULE("xrcTextCtrl.Value", make_accessor(make_const<wxString>(wxString("test string")))) wxString test="test string"; BEGIN_RULES() RULE("xrcTargetInfoMain.Value", make_const<accessor>(make_accessor<wxString>(test))) END_RULES() The last case works. The previous tries all fail. The first case compiles but gives me a runtime error. Oddly the crash is in strlen(). It looks like the wxString hasn't been created yet. Below is the simplified-for-readability backtrace. MSVCR80D!strlen+0x30 MSVCP80D!std::basic_string::assign+0x10 MSVCP80D!std::basic_string::basic_string MyApp!litwindow::converter<wxString>::to_string+0x5d [base_objects.cpp @ 36] MyApp!litwindow::converter<wxString>::to_string+0x4d [dataadapterimp.h @ 736] MyApp!litwindow::const_accessor::to_string MyApp!litwindow::wxTextCtrlAdapter::SetValue MyApp!litwindow::converter_with_getset<>::set_value MyApp!litwindow::typed_accessor<>::set MyApp!litwindow::value_assign_expr<>::do_assign MyApp!litwindow::rule_base::execute_immediate MyApp!litwindow::constraint_solver::execute_all_immediate MyApp!litwindow::RapidUI::Start Case 2 and 3, fail during compilation. It complains about 'value_type' not being a member of 'litwindow::accessor'. I am guessing this isn't interesting, but, if it is, I'll send the detailed errors. Case 4 works.... Well that's some progress. However, I still don't see how to dynamically lookup a wxString. make_expr<wxString> returns expr_primary<wxString> so it isn't suitable for changing into an accessor<wxString>. > > - - - > > > > On a different tact, I was puzzled by the following code snippet. > Actually the code does invalidate multiple values here. It is a bit > difficult to see, because the 'Value' is an accessor itself. > ... > RapidUI rules dependency has two flavors. Static dependency means that a > rule depends on an accessor and that never changes its location and type > in memory during the lifetime of the rule. The object pointed to by this > accessor may change, but not the accessor itself. > > Dynamic dependency otoh allows that the accessor itself changes. This explanation is quite interesting. So it follows that rules which pass an accessor are always dynamic because it assigns a replacement accessor each time the rule is updated? What do static dependency rules look like? (For a moment I thought make_expr<const_accessor> but that would just keep the object pointed at from being changed, right?) For the list assignment, the library takes care of invalidating the old accessor so the user need not be concerned. Are there times when the user is required to call NotifyChanged on a value before updating? Joel --- [This E-mail scanned for viruses by Declude Virus] |
From: Hajo K. <mai...@ha...> - 2005-05-01 06:56:37
|
Hi, > I'd like to assign a wxString to Value, but I'm having trouble figuring out > how to convert a wxString to an accessor in a wxTextCtrl rule. I thought > wrongly that perhaps the following rule would work. > > PROP_GetSet(wxString, Info) > RULE("xrcTextCtrl.Value", > make_accessor(make_expr<wxString>("xrcList.Current.Info"))) of course, now I remember :) Use xrcTextCtrl.Label instead of .Value. The Value property is indeed an accessor. I don't know if it is possible to pass an accessor using explicit rules. If it is, it should be make_expr<accessor>("xrcList.Current.Info") and make_expr should 'cast' the string to an accessor implicitly. Or something like this. Your expression above tried to make an accessor for the expression, which will not work. wxTextCtrl has three properties that can be used for the actual text: Value is of type accessor and automatically detects the correct type. Double is of type double. Label is of type string. So for double variables you'd use xrcTextCtrl.Double = m_myDouble for string you'd use xrcTextCtrl.Label = m_myString I choose label because it is inherited by all controls. The Value property comes in handy when you are using implicit rules where your data variable and text ctrl name are the same. RapidUI will create the rule automatically. Regards Hajo |
From: Hajo K. <mai...@ha...> - 2005-05-01 06:53:09
|
yrs90 wrote: > I get the impression that wxTextCtrl support is currently limited to use > with a double value. Why does wxTextCtrlBase::SetValue call > wxTextCtrl::SetLabel (rather than wxTextCtrl::SetValue) if the value isn't a > double? I will investigate that. Might be a typo or it might be that for wxTextCtrl SetValue and SetLabel do the same thing. wxTextCtrl should accept any data type. If its a double, it will switch to 'numbers only' mode automatically. Also it eliminates the need to convert your double from/to string, as is currently neccessary in the traditional programming world. But it should be possible to use a string. > I'd like to assign a wxString to Value, but I'm having trouble figuring out > how to convert a wxString to an accessor in a wxTextCtrl rule. I thought > wrongly that perhaps the following rule would work. > > PROP_GetSet(wxString, Info) > RULE("xrcTextCtrl.Value", > make_accessor(make_expr<wxString>("xrcList.Current.Info"))) I'll investigate. > - - - > > On a different tact, I was puzzled by the following code snippet. > > // mark current m_value as invalid > g_rapidUI->ValueChanged(GetWndAggregate()["Value"], false, false); > // assign new accessor > m_value=newValue; > // and send change notification for new accessor > g_rapidUI->ValueChanged(GetWndAggregate()["Value"], false); > > How/why does the first call to ValueChanged mark m_value as invalid? I had > thought the notification was only required after updating. I notice that it > won't be solved until the second call, but I thought deferred resolution was > just for use when invalidating multiple values. Actually the code does invalidate multiple values here. It is a bit difficult to see, because the 'Value' is an accessor itself. The first NotifyChanged tells the RapidUI mechanism that the accessor that up to then pointed to the value has changed. RapidUI marks all rules that depend on that accessor as 'dirty'. Every rule has a list of accessors it depends on. Next time they are evaluated, they will refresh their dependency list with new accessors. Without the first ValueChanged call the dependency-list for the rules would still contain the old accessor, which is no longer valid after m_value=newValue. RapidUI rules dependency has two flavors. Static dependency means that a rule depends on an accessor and that never changes its location and type in memory during the lifetime of the rule. The object pointed to by this accessor may change, but not the accessor itself. Dynamic dependency otoh allows that the accessor itself changes. Hajo |
From: Hajo K. <mai...@ha...> - 2005-04-29 14:19:10
|
Hi >> Take the following problem: You are writing a bug tracking application >> and are offering the user a 'priority' enumeration: low, medium, high, >> critical. You also want to let the user modify this list. >> >> The sort order here is implied by the semantics of the object, not by a >> view. > In your example, perhaps I don't understand the distinction you are making. > The priority is an attribute of the object by which the view can sort. It > might just as easily sort by another attribute like the date. Perhaps one > view has a priority sorted list while another shows a histogram of bugs by > priority for each day. But exactly how do you sort the view? Where is the sort order defined? Clicking on a column header of a list control should sort the bugs by ascending or descending priority. But all you have is a container of strings "low, medium, high, critical" and the alphabetical sort order is useless. It would be 'critical', 'high', 'low', 'medium'. So where would a generic list control get the true sort order from? I think this is a case where the sort order is a fixed property of the container, not of a view of the container. That is why I make a distinction between sort order imposed by a container and a sort order that depends on a view and can be different from user to user. I think we need both. >> So you think of every control as a view to the container? > > > I do. Am I redefining the term? No. I just wanted to make sure. > >> Where and how do you save the view attributes? > > > > In some cases the controls have provisions to save these attributes. When > they don't, I am not sure. Will sortable iterators (which I've started to > think are a good idea) help address this problem? They might, if they can encapsulate all the attributes that the controls need. >> Another idea: The lit window library could introduce a 'filter' object, >> which is basically a view. > > How would selective display be achieved without using a filter object? These > seem like a necessary feature. Could filter behavior be rules based too? Sure. Filter behaviour would just be another data type and could be set like every other object, too. > Actually I was wondering about filtering earlier too. I guess I need to > implement a new iterator for my container in order to achieve filtering, > right? I can't create a rule that accesses a container via function calls? Not at the moment. No. Creating your own iterator is the way to do this. Hajo |
From: yrs90 <yr...@ya...> - 2005-04-29 06:45:53
|
> Take the following problem: You are writing a bug tracking application > and are offering the user a 'priority' enumeration: low, medium, high, > critical. You also want to let the user modify this list. > > The sort order here is implied by the semantics of the object, not by a > view. Perhaps part of what leads to the ambiguity over where to sort is that the wx controls store a copy of the data. So, for example, the wxListCtrl can sort its contents independent of the source data. Perhaps container or iterator base ordering is more an issue in a lightweight control. My initial reaction is that imposing external source-data/iterator ordering on the control may either conflict with or reinvent the control management. Perhaps there are some rules that just apply to the control (on column click, sort by column) while other rules deal with the moving of data to and from the control (on delete key, delete element from container). In your example, perhaps I don't understand the distinction you are making. The priority is an attribute of the object by which the view can sort. It might just as easily sort by another attribute like the date. Perhaps one view has a priority sorted list while another shows a histogram of bugs by priority for each day. > I don't know yet, but why not. These iterators would not sort the > underlying objects in the container itself, of course. Rather they would > be a sorted vector of pointers to the objects. This is the same approach > that ADO(.NET) uses with ADO record sets. You load a recordset into > memory (-> container) and then get a cursor (-> iterator). The nice > thing is you can have more than one cursor and can specify a sort order > for each cursor. This sounds useful. > The lit window container abstraction will then of course be a lot > higher-level than the STL. And performance will not always be as good as > the STL. Perhaps the user could decide the cost by using a property 'Sorted' that would use the costlier sorted iterator rather than the native stl iterator. > > >>This high-level container might even contain more than one 'index'. > > > > > > I don't see why it is desirable to have more than one index to a given > > container element. Well, that is unless you mean to have the index not > only > > indicate the item, but also the particular sorting that was used. But > that > > seems unnecessary since element ordering is available from the view (or > > through a sortable iterator). > > What exactly is a view? > > Imagine a container and a program that has more than one list control > that is being connected to the container. How would you solve the > problem that each list control can have a different sort order? In the case of wxListCtrl, the sort criteria can be bound to the control. Now the next question is how sort criteria can be described by a rule. I am not sure. > So you think of every control as a view to the container? I do. Am I redefining the term? > Where and how do you save the view attributes? In some cases the controls have provisions to save these attributes. When they don't, I am not sure. Will sortable iterators (which I've started to think are a good idea) help address this problem? > Another idea: The lit window library could introduce a 'filter' object, > which is basically a view. This is an idea that pops up every now and > then. A filter would take an accessor (aggregate or container), modify > it in specific ways and represent this modification as an accessor > itself. You could bind your control to a filter and bind the filter to a > container. Filter would then essentially become a view. The control > could change the filter's sort order, perhaps there really could be a > filter expression so you could display only specific parts of containers. How would selective display be achieved without using a filter object? These seem like a necessary feature. Could filter behavior be rules based too? > Another example of where filters where handy would be the column > headers. Currently you have the 'columnheader' property. But you could > filter the aggregates, remove unwanted members from the aggregate and > change the names of the other members and the order through a filter. Those filter rules would require just about as much customization as the columnheader property. On the other hand, it would make it possible to dynamically alter the number of columns that were displayed. This sounds useful. Actually I was wondering about filtering earlier too. I guess I need to implement a new iterator for my container in order to achieve filtering, right? I can't create a rule that accesses a container via function calls? Regard, Joel --- [This E-mail scanned for viruses by Declude Virus] |
From: yrs90 <yr...@ya...> - 2005-04-29 04:21:26
|
I get the impression that wxTextCtrl support is currently limited to use with a double value. Why does wxTextCtrlBase::SetValue call wxTextCtrl::SetLabel (rather than wxTextCtrl::SetValue) if the value isn't a double? I found that not passing an accessor in a rule to a property when one was expected causes a crash in rule_base::execute_immediate(). Someday it would be good to generate a warning instead. This is probably a common error. The perpetrator follows. // note defined as PROP_GetSet(accessor, Value). RULE("xrcTextCtrl.Value", make_const<string>(string("test"))) // fails I'd like to assign a wxString to Value, but I'm having trouble figuring out how to convert a wxString to an accessor in a wxTextCtrl rule. I thought wrongly that perhaps the following rule would work. PROP_GetSet(wxString, Info) RULE("xrcTextCtrl.Value", make_accessor(make_expr<wxString>("xrcList.Current.Info"))) Since the only thing I know is an accessor is something declared as a container, I tried using a container. The error makes sense, but doesn't help me understand how to make an accessor. test.push_back(wxString("test1")); test.push_back(wxString("test2")); IMPLEMENT_ADAPTER_CONTAINER(vector<wxString>) RULE("xrcTextCtrl.Value", make_expr<accessor>("test")) This complains that error converter<vector<wxString>>::to_string method wasn't implemented. This makes some sense, because the SetValue code isn't looking for a container. I suppose I could make GetInfo() return an accessor (by calling make_accessor before returning), but then it's not so useful internally. - - - On a different tact, I was puzzled by the following code snippet. // mark current m_value as invalid g_rapidUI->ValueChanged(GetWndAggregate()["Value"], false, false); // assign new accessor m_value=newValue; // and send change notification for new accessor g_rapidUI->ValueChanged(GetWndAggregate()["Value"], false); How/why does the first call to ValueChanged mark m_value as invalid? I had thought the notification was only required after updating. I notice that it won't be solved until the second call, but I thought deferred resolution was just for use when invalidating multiple values. Regards, Joel --- [This E-mail scanned for viruses by Declude Virus] |
From: yrs90 <yr...@ya...> - 2005-04-29 00:43:18
|
Earlier I wrote: > Could you tell me where to find the data that the accessor is pointing to? I found it right in front of me in const_accessor.this_ptr. I looked at the memory this pointed to several times but I was expecting to see some string data rather than just pointers to wxString. It's obvious now, but I was confused... sorry. > Currently, though, I'm trying to figure out why, when using m_current as > originally designed, I can follow a particular click-sequence and watch > what starts out as an iterator pointing to correct contents translate into > corrupted data during the assignment to m_current. Not only that but > m_current's original contents coming into the assignment look suspect too. I figured this out too. I wonder if this was a danger I should have been sensitive to. (It vaguely sounds familiar.) Here's my explanation. A class that manages some allocated memory. class A { char *data; int size; public: A():data(0),size(0){} ~A(){delete[]data;} char *getdata() { return data; } void setdata(int sz, char* src) { if(data) delete [] data; data = new char[sz]; if(data) { memcpy(data,src,sz); size = sz; } } int getsize() {return size;} A &operator(const A& a) { setdata(a.getsize(), a.getdata()); } } And now a function from class typed_const_accessor: const Value get() const { Value v; get(v); return v; } Function get(v) will copy an instance of A into v using the operator=. No problem. On return from get(void) I seem to see another instance of A being created, but /data/ will have the same pointer value as v.data! Then v gets destroyed freeing the memory that /data/ references. Perhaps I needed a copy constructor? Anyway, I resolved by managing my data in a new object that I embed in A. Now it works! <sigh> Regards, Joel --- [This E-mail scanned for viruses by Declude Virus] |
From: yrs90 <yr...@ya...> - 2005-04-28 12:41:50
|
Oh, I didn't explain the failure mode for the m_current as pointer implementation. I have to paraphrase this because I don't have the stack trace at hand. When there was a rule defined using Current and data changed (I presume this involved something like NotifyChanged("m_List");) then I would see function calls related to find_scope that were sometimes seeking ...Current... and sometimes seeking the underlying data m_List. Anyway I stepped through watching iterations of find_scope until I got a heap failure. I rationalized this by thinking that recursing m_current and getting an m_List member must have triggered Current to be evaluated and so on. However, I didn't stay with it long to pinpoint the propagation mechanism. (Lots of loops...) Instead I did a combination of tracing and sitting on breakpoints until I confirmed I had localized the failure. Regards, Joel -----Original Message----- Sent: Thursday, April 28, 2005 4:46 AM To: lit...@li... Subject: RE: [litwindow-users] Re: m_current as a pointer > Can you post the relevant code? m_current declaration, and where you > call NotifyChanged and other relevant places. Let's see. This is a little hard to boil down. I presume (perhaps wrongly) that you prefer the narrative explanation over a diff. lwListAdapterBase header was changed so mutable accessor m_current; became mutable accessor *m_current; mutable accessor m_empty; m_current was initialized to &m_empty in lwListAdapterBase constructor. m_empty.destroy() is called in the lwListAdapterBase destructor. The biggest changes were to CalcCurrent where empty is assigned an empty object if not !is_valid and m_current either points to the the_item or m_empty accessor depending on whether the container index indicated an item was selected. void lwListAdapterBase::CalcCurrent(int containerIndex) const { if (m_items.is_valid() && m_items.is_container()) { // the const_accessor points to the end item which is invalid // but the type of the item is valid. container c=m_items.get_container(); container::iterator i=containerIndex>=0 ? m_items.get_container().at(containerIndex) : m_items.get_container().end(); accessor the_item=*i; prop_t type=the_item.get_type(); if (!m_empty.is_valid()) m_empty=create_object(type); if (i!=c.end()) m_current = &the_item; else { m_current = &m_empty; } g_rapidUI->ValueChanged(*m_current, true); } } Commands to destroy m_current were removed. All ValueChanged() calls in wxListObject were changed to reference *m_current rather than m_current. --- [This E-mail scanned for viruses by Declude Virus] |
From: yrs90 <yr...@ya...> - 2005-04-28 11:45:34
|
To answer this email I'm returning to the pointer implementation I tried. Maybe it will turn out to be a better solution. Currently, though, I'm trying to figure out why, when using m_current as originally designed, I can follow a particular click-sequence and watch what starts out as an iterator pointing to correct contents translate into corrupted data during the assignment to m_current. Not only that but m_current's original contents coming into the assignment look suspect too. Actually, my investigation is hampered because I can't find the data or a data pointer in the accessor data structure. Could you tell me where to find the data that the accessor is pointing to? I can find it in the iterator but lose it once it is dereferenced and becomes an accessor. To find the data in the iterator 'i' I can look in i.it.container_iterator.i._Tree._Ptr._Myval So on (or back?) to m_current as a pointer. I probably should have renamed the variable to avoid confusion... > Can you post the relevant code? m_current declaration, and where you > call NotifyChanged and other relevant places. Let's see. This is a little hard to boil down. I presume (perhaps wrongly) that you prefer the narrative explanation over a diff. lwListAdapterBase header was changed so mutable accessor m_current; became mutable accessor *m_current; mutable accessor m_empty; m_current was initialized to &m_empty in lwListAdapterBase constructor. m_empty.destroy() is called in the lwListAdapterBase destructor. The biggest changes were to CalcCurrent where empty is assigned an empty object if not !is_valid and m_current either points to the the_item or m_empty accessor depending on whether the container index indicated an item was selected. void lwListAdapterBase::CalcCurrent(int containerIndex) const { if (m_items.is_valid() && m_items.is_container()) { // the const_accessor points to the end item which is invalid // but the type of the item is valid. container c=m_items.get_container(); container::iterator i=containerIndex>=0 ? m_items.get_container().at(containerIndex) : m_items.get_container().end(); accessor the_item=*i; prop_t type=the_item.get_type(); if (!m_empty.is_valid()) m_empty=create_object(type); if (i!=c.end()) m_current = &the_item; else { m_current = &m_empty; } g_rapidUI->ValueChanged(*m_current, true); } } Commands to destroy m_current were removed. All ValueChanged() calls in wxListObject were changed to reference *m_current rather than m_current. > BTW, I don't know if you have stumbled across create, clone and > destroy yet as they are still undocumented. Together with a couple of > other methods they implement an object factory, giving you the ability > to create and clone objects dynamically by type, similar to the > wxWidgets runtime type system. > > Comes in useful when you want to write a generic insert method for > your control. > > Have a look at objectfactorytests.cpp for more information. I'll take a closer look. Thanks. Best regards, Joel --- [This E-mail scanned for viruses by Declude Virus] |
From: Hajo K. <mai...@ha...> - 2005-04-28 09:48:39
|
yrs90 wrote: >>I wonder if m_current as a pointer into the underlying data is >>causing a circular reference somewhere during change resolution. > > > I see now. When m_current is made a pointer that points into the underlying > data, the notification process does enter a death loop. Of course, the nice Can you post the relevant code? m_current declaration, and where you call NotifyChanged and other relevant places. > Aside: While looking through the code, I noticed that in dataadapterimp.h, > the function implementation for converter_abstract_base::destroy() throws an > exception claiming to be clone. Perhaps that body should belong to the > function converter_abstract_base::clone(), which is declared directly before > destroy()? No. Thats a cut&paste error. It should read "not_implemented("destroy (abstract class)". The clone body is at dataadapter.h, line 871. I'll correct and commit it. Thanks for finding. BTW, I don't know if you have stumbled across create, clone and destroy yet as they are still undocumented. Together with a couple of other methods they implement an object factory, giving you the ability to create and clone objects dynamically by type, similar to the wxWidgets runtime type system. Comes in useful when you want to write a generic insert method for your control. Have a look at objectfactorytests.cpp for more information. Regards Hajo |
From: yrs90 <yr...@ya...> - 2005-04-28 07:26:28
|
> I wonder if m_current as a pointer into the underlying data is > causing a circular reference somewhere during change resolution. I see now. When m_current is made a pointer that points into the underlying data, the notification process does enter a death loop. Of course, the nice thing about the originally implementation is precisely that it was an independent object being monitored for changes, just like any other object for which a rule is defined. I considered several different options: a) change my container to permit copying b) add a specializable assignment template like type_traits c) create m_current with a copy constructor version of create_object() d) figure out how to break the recursive loop when m_current points into a container. The first three options use m_current as defined originally. The last option changes m_current into a pointer to an accessor. a) change my container to permit copying I considered several ways to do this, but I can't see a way to accomplish this. Overriding the key alone isn't sufficient because it's still going to be a constant. I would like to override pair<>, but I don't know how to get map<> to use the pair<> derivative unless I reimplement map<> (not desirable). I can't just specialize pair<>::operator= (say, with a delete and recreate using the copy constructor) because it doesn't have an operator=() for me to override in pair<>. b) add a specializable assignment template like type_traits This doesn't get around the inability to copy a constant member. However, this would keep the framework general while still allowing the user to specialize the assignment so that, in my case, perhaps I only copy the value and not the key. This would require that I define my adapter as permitting copy. I presume this is okay, but I am concerned that somewhere in the framework it might copy data into the container rather. If it's only going to be used in m_current then a partial copy won't be problem. c) create m_current with a copy constructor version of create_object() This seems like a more complete work-around for the need to use the copy-constructor for constant member initialization. On the other hand, I don't know if it actually increases or decreases compatibility by moving the requirement from operator= to copy-constructor being defined. d) figure out how to break the recursive loop when m_current points into a container. This sounds like a great solution, but I don't understand the code well enough to pursue this yet. So what I actually pursued to completion was (b), just adding an assign<Type>::operator()(dst,src) that defaults to dst=src, but can be overridden to provide a partial copy of pair<>. Now however, I'm finding that when current is reassigned for a second time (by clicking different list entries) that I'm getting some type of memory violation. I must be overlooking something. This should have been a minimal change. Aside: While looking through the code, I noticed that in dataadapterimp.h, the function implementation for converter_abstract_base::destroy() throws an exception claiming to be clone. Perhaps that body should belong to the function converter_abstract_base::clone(), which is declared directly before destroy()? Regards, Joel --- [This E-mail scanned for viruses by Declude Virus] |
From: Hajo K. <mai...@ha...> - 2005-04-28 06:21:46
|
yrs90 wrote: >>Is the sort order an inherent attribute of the >>collection? Or is the sort order just a 'view' to the collection, >>imposed by the user.... So, should sorting be part of the container >>or not? > > > I had assumed that sort order should be part of the view rather than part of > the container. Multiple views of data are not uncommon. Multiple views > probably require that sort order be independent of the container. Take the following problem: You are writing a bug tracking application and are offering the user a 'priority' enumeration: low, medium, high, critical. You also want to let the user modify this list. The sort order here is implied by the semantics of the object, not by a view. >>Iterators otoh will be short-lived objects used to access and iterate >>the container. Their sort order can be changed without changing the >>actual sort order of the underlying container. > > > This is an interesting perspective. I had assumed that sorting would be > handled by the view itself rather than by an iterator. Is there a way to > provide sorted iterators efficiently? I don't know yet, but why not. These iterators would not sort the underlying objects in the container itself, of course. Rather they would be a sorted vector of pointers to the objects. This is the same approach that ADO(.NET) uses with ADO record sets. You load a recordset into memory (-> container) and then get a cursor (-> iterator). The nice thing is you can have more than one cursor and can specify a sort order for each cursor. The lit window container abstraction will then of course be a lot higher-level than the STL. And performance will not always be as good as the STL. >>This high-level container might even contain more than one 'index'. > > > I don't see why it is desirable to have more than one index to a given > container element. Well, that is unless you mean to have the index not only > indicate the item, but also the particular sorting that was used. But that > seems unnecessary since element ordering is available from the view (or > through a sortable iterator). What exactly is a view? Imagine a container and a program that has more than one list control that is being connected to the container. How would you solve the problem that each list control can have a different sort order? > Restricting to a single association between a control and a container is too > constraining for a general framework, I think. Although, so long as (a) > only one control could access a given container at any given time and (b) a > container could notify all bound controls when change had occurred, then I > think it would work for multiple controls bound to a single container too. I agree. >>Idea 1: >>Insertion / deletion is being handled by the container itself. >>Interested objects are being notified. > > The only troublesome part of this is that it takes a bit of work for a > control to gain access to its bound container. I expect the access > mechanism could hidden, which would make this the more versatile approach. > For one thing, a deletion from a view might be achieved by setting a > container element attribute to "hidden". So you think of every control as a view to the container? Where and how do you save the view attributes? Another idea: The lit window library could introduce a 'filter' object, which is basically a view. This is an idea that pops up every now and then. A filter would take an accessor (aggregate or container), modify it in specific ways and represent this modification as an accessor itself. You could bind your control to a filter and bind the filter to a container. Filter would then essentially become a view. The control could change the filter's sort order, perhaps there really could be a filter expression so you could display only specific parts of containers. Another example of where filters where handy would be the column headers. Currently you have the 'columnheader' property. But you could filter the aggregates, remove unwanted members from the aggregate and change the names of the other members and the order through a filter. Hajo |
From: yrs90 <yr...@ya...> - 2005-04-27 09:16:28
|
It turns out that the pair<> issue isn't a copy constructor or operator=. The problem is that map<A,B> creates pairs pair<const A, B>. The "const" is what breaks assignability and keeps copy from working. To overcome this I changed the list adapter implementation so that m_current is accessor*, a pointer. This eliminates the need to copy. I created an m_empty list-adapter member that m_current points to when there isn't an item selected. This seems to work. I can add to the list, delete selected items, etc. Now, however, I am running into problems with rules that reference Current. Since Current is a pair<> it is necessary to use ".second" in order to access the data. Frequently, the rule that includes Current can be seen to work correctly before an exception (for example it can put the selected item in the title bar), but an exception will be thrown whenever some state changes (insert, selection, etc). I think it has something to do with the structure walking process. When I was looking at this earlier, I think it was encountering null schema ?type?, but now I seem to be getting some type of heap allocation error. I wonder if m_current as a pointer into the underlying data is causing a circular reference somewhere during change resolution. I'll try to compose an explanation. First I'll try using a vector instead of a map and see if a RULE using Current behaves any differently. --- [This E-mail scanned for viruses by Declude Virus] |
From: Hajo K. <mai...@ha...> - 2005-04-26 12:22:19
|
yrs90 wrote: > I ran the unittests. I got the following output. The couple of exceptions > I looked at appear to be consistent with a successful test. They do. These are expected exceptions. Relevant is the line OK (41 tests). That indicates all unit tests are okay. Hajo > > unittest_md.exe > ......................................... > > > OK (41 tests) > > > <RETURN> to continue > > --------------- lw_err --------------- > lwbase_error exception is not a container > lwbase_error exception is not a container > lwbase_error exception invalid from_string<int> input. not a number. > lwbase_error exception type mismatch > lwbase_error exception no such property > lwbase_error exception converter<Fix1>::to_string method not implemented > lwbase_error exception value conflict > lwbase_error exception value conflict > lwbase_error exception Variable fixValue1 has type Fix1 but type int > expected. > lwbase_error exception Variable noSuchVariable not found > > > > --- > [This E-mail scanned for viruses by Declude Virus] > > > > ------------------------------------------------------- > SF email is sponsored by - The IT Product Guide > Read honest & candid reviews on hundreds of IT Products from real users. > Discover which products truly live up to the hype. Start reading now. > http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click |
From: Hajo K. <mai...@ha...> - 2005-04-26 07:41:51
|
Hi, > When I run, I get the assertion during startup: > std::runtime_error: from_accessor method not implemented > > The assertion appears to be correct. The from_accessor looks like it is not > implemented when <pair> is declared ...ADAPTER_NO_COPY. However, without > NO_COPY there will be problems because of operator=. Why doesn't it want to > play with the list? that is unfortunate. Hm. The problem here is that indeed the pair<> does not have a copy constructor or = operator. But the list code wants to access map elements by value. from_accessor does the same thing as from_string: it sets the value of an object pointed to by an accessor from a different accessor, whereas from_string would read the value from a string. I will have to think about how to solve this problem. This wasn't an issue with vector<>, because the elements of the vector could be copied and thus ...ADAPTER without NO_COPY could be used. I may have to introduce a type_traits class that encapsulates assignment, comparison and other operations. That way you can specialize the type_traits template when you know how to copy an object but there is no = operator or copy constructor available. In this case it would mean writing something like template<> void type_traits<pair<string, int> >::assign(pair<string, int> &to, const pair<string, int> &from) { to.first=from.first; to.second=from.second; } The entire = and copy constructor issue is causing many problems with the data adapter design. Here is where the problem actually stems from: When you define get/set properties you have to be able to copy elements. If it were all member variables I could simply pass a pointer to the object around. But I cannot pass a pointer to the result of a get_property call. So the data adapter mechanism tries to do both: use pointers when possible and use the copy scheme when get_/set_ property methods are used. Some objects don't have a copy constructor or = operator. The first distinction then is the one between ...ADAPTER and ...ADAPTER_NO_COPY. The ...ADAPTER_NO_COPY creates a data adapter with more limited functionality. from_accessor is not defined for example, because from_accessor tries to assign an object. Hmm. Difficult. Hajo |