lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] wx-2.9.5-rc1 regression with conditional controls enablement


From: Vadim Zeitlin
Subject: Re: [lmi] wx-2.9.5-rc1 regression with conditional controls enablement
Date: Wed, 17 Jul 2013 21:13:01 +0200

On Wed, 17 Jul 2013 00:42:46 +0000 Greg Chicares <address@hidden> wrote:

GC> From this important point I conclude that use of Lineage() and lineage_,
GC> which are recursive, immunized parts of the code against the wx change
GC> above (r71886); and that direct, nonrecursive use of wxWindowList in
GC> 'mvc_controller.cpp' needs to be reevaluated in both places it occurs:
GC> 
GC> (1) in ConditionallyEnable(), as discussed in your later message; and also
GC> 
GC> (2) in EnsureOptimalFocus(). I see a regression there: on the "Solve" tab,
GC> every control is in a groupbox, and none can be reached with the Tab key.

 Yes, sorry, I should have realized that we had the same problem here too.

GC> I'll comment on the patch you sent in a later message

 Just to be clear: I'll be waiting for your comments before doing anything
else. As, in any case, this doesn't seem to be a problem with wxWidgets
itself (granted, this is a backwards incompatible change but it really
needed to happen, especially for wxGTK port, as it solved several problems
with controls inside the static boxes that simply couldn't be solved
otherwise so the benefits of breaking compatibility do outweigh the costs
here), we released 2.9.5 yesterday without waiting for the denouement of
this thread as I think that any workaround needs to be done in LMI itself.
The advantage of this is that it can be done at your own pace, and that you
should be able to upgrade to 2.9.5 (or to 3.0 if it's released by then)
once this happens.

GC> >  Ideal would be to replace a flat vector by a map of parent pages to the
GC> > (interesting) controls inside them, then we could iterate over this 
instead
GC> > of iterating over GetChildren().
GC> 
GC> At first I thought you were suggesting that iteration would be faster over a
GC> std::map than over a std::vector. Rereading this more carefully, though, I
GC> see the real point: sometimes we want to iterate over the current page only,
GC> and sometimes over all pages; but controls aren't added or removed, so we
GC> only need to generate a container of controls once

 Yes, exactly.

GC> This question calls to mind an investigation I abandoned years ago, but
GC> I'll mention it again in case it leads us to a better idea:
GC> 
GC> http://lists.nongnu.org/archive/html/lmi/2010-05/msg00015.html
GC> | Actually, at one time I experimented with the idea of writing
GC> | Input::DoHarmonize() in Prolog. The problem I though that might solve
GC> | is that there are many interdependencies among enablement conditions.
GC> | Using a logical inference engine to untangle them is more attractive
GC> | than spending time to write imperative-language statements in exactly
GC> | the right order. And we could even use this rejected boost library:
GC> |   http://www.cc.gatech.edu/~yannis/fc++/boostpaper/fcpp.html
GC> | to write Prolog in C++, as discussed here:
GC> |   http://www.cc.gatech.edu/~yannis/lc++/paper.pdf
GC> | But that would be a separate project.
GC> 
GC> That would work for lmi's MVC implementation in general. As quoted above,
GC> Input::DoHarmonize() takes care to express interrelated dependencies in
GC> a viable order. But in code like MvcController::ConditionallyEnable() we
GC> disregard interdependencies and impose all conditions afresh--each time
GC> any control's value changes, even though that change won't affect most
GC> of the other controls.
GC> 
GC> Without a radical change like importing a Prolog interpreter, we could
GC> still get some of the benefits. Form a vector C of all controls that have
GC> validators. Create a square boolean matrix M mapping C onto itself, and
GC> set M[i,j] true iff a change in C[i] could cause a change in C[j] (any
GC> sort of change, including enablement, limits, and so on). Naively, that
GC> captures only direct dependencies, which is insufficient; but by raising
GC> M to an adequate power (defining, I guess, multiplication to be logical
GC> OR), we'd fill in indirect dependencies. Then, when C[i] changes, we
GC> only need to consider C[k] for which C[i,k] is true when applying
GC> iterative functions like ConditionallyEnable(). And that should be much
GC> faster.

 If we can assume that the dependencies are simple, i.e. each control whose
state needs to be changed dynamically depends on the value of only a single
other control (be it a checkbox, radiobox or something else), then I think
we could avoid using EVT_UPDATE_UI entirely and just connect the handlers
to the checkboxes/radioboxes governing the state of the other controls to
enable them as needed.

[Aside: normally I'm the first one to advocate the use of EVT_UPDATE_UI as
 the code using it is simpler to write and more obviously correct, but in
 this case I think neither advantage really matters as all the code is
 generic and so wouldn't result in a usual tangle of hard to follow logic
 which inevitably arises in the code handling the events to enable
 dependent controls manually.]


 OTOH if the dependencies are more complex, then just maintaining the
matrix M manually would be already complicated. So I am not really sure I
see the benefit of the approach above: it seems like an overkill for the
simplest possible case but doesn't seem to really solve the problem for the
more complicated one.


 Regards,
VZ

reply via email to

[Prev in Thread] Current Thread [Next in Thread]