Dialogs and ListModels

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Dialogs and ListModels

Randy Coulman-2
I'm relatively new to Dolphin, so forgive me if this is a trivial
question.  I didn't find an answer in the searching I did.

I'm working on an application that has a dialog that contains two lists
of items.  The first list is a (sorted) list of "all items" and the
second is a list containing "included items".  The model class contains
these two lists as ListModels, and the dialogs use ListPresenters and
ListBoxes.  There are buttons to include or exclude items from the
"included items" list, and buttons to change the order of items in the
"included items" list.

I want the changes to the "included items" list to be buffered in the
same way that changes to simple values are.  When I cancel the dialog,
the buffered changes should be tossed.  When I OK the dialog, the
changes should be applied to the original list.

I've been messing with different ways of doing this and have been having
trouble getting it to work.

Has anyone done something like this before?  Is there a standard way of
handling this?

Thanks,
Randy
--
Randy Coulman
NOTE: Reply-to: address is spam-guarded.  Reassemble the following to
reply directly:
rvcoulman at acm dot org


Reply | Threaded
Open this post in threaded view
|

Re: Dialogs and ListModels

Christopher J. Demers
Randy Coulman <[hidden email]> wrote in message
news:ara3ft$gd2nj$[hidden email]...
...
> I want the changes to the "included items" list to be buffered in the
> same way that changes to simple values are.  When I cancel the dialog,
> the buffered changes should be tossed.  When I OK the dialog, the
> changes should be applied to the original list.

The easiest (not sure if it is the best) way to handle this would be to
override the copy method on your model.  Dialogs use an AspectBuffer to
buffer changes.  This makes a copy of your model and changes the copy as you
make chances in the UI.  When you accept the dialog these changes are copied
back to the original model.  The problem is that by default copy is a
shallowCopy.  That means only the model is copied and the instance variables
still point to the same objects.  If you implement a copy method that makes
a deeper copy of the relevant instance variable then I think the default
AspectBuffer will work for you.  Just make sure you use aspectValue: so that
the AspectBuffer will know to copy the list over when the dialog is
accepted.  There may be implications with this approach depending upon how
your list is intended to be referenced by other objects.  Make sure you
understand what is happening with the references.  You could also make your
own custom AspectBuffer subclass, but that may be overkill for this problem.

You could do something like this (warning untested code):
===============
YourModel<<copy

    | newObj |

    newObj := super copy.
    newObj yourList: self yourList copy.
    ^newObj.
===============

Chris


Reply | Threaded
Open this post in threaded view
|

Re: Dialogs and ListModels

Bill Schwab-2
> The easiest (not sure if it is the best) way to handle this would be to
> override the copy method on your model.  Dialogs use an AspectBuffer to
> buffer changes.  This makes a copy of your model and changes the copy as
you
> make chances in the UI.  When you accept the dialog these changes are
copied
> back to the original model.  The problem is that by default copy is a
> shallowCopy.  That means only the model is copied and the instance
variables
> still point to the same objects.  If you implement a copy method that
makes
> a deeper copy of the relevant instance variable then I think the default
> AspectBuffer will work for you.  Just make sure you use aspectValue: so
that
> the AspectBuffer will know to copy the list over when the dialog is
> accepted.

An alternative (again with tradeoffs) is to override the buffering in a
Dialog subclass and derive any problematic dialogs from it.  I've been doing
that for quite a while with no apparent problems.

Have a good one,

Bill

--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Dialogs and ListModels

Randy Coulman-2
In reply to this post by Christopher J. Demers
Christopher J. Demers wrote:

>
> The easiest (not sure if it is the best) way to handle this would be to
> override the copy method on your model.  Dialogs use an AspectBuffer to
> buffer changes.  This makes a copy of your model and changes the copy as you
> make chances in the UI.  When you accept the dialog these changes are copied
> back to the original model.  The problem is that by default copy is a
> shallowCopy.  That means only the model is copied and the instance variables
> still point to the same objects.  If you implement a copy method that makes
> a deeper copy of the relevant instance variable then I think the default
> AspectBuffer will work for you.  Just make sure you use aspectValue: so that
> the AspectBuffer will know to copy the list over when the dialog is
> accepted.  There may be implications with this approach depending upon how
> your list is intended to be referenced by other objects.  Make sure you
> understand what is happening with the references.  You could also make your
> own custom AspectBuffer subclass, but that may be overkill for this problem.
>

I've already done this part (using postCopy instead of copy as in your
example).  The problem with it is that using aspectValue: returns a
ValueAspectAdapter that doesn't understand the messages that the listbox
sends to a list model.  I worked around this by using aspectValue: to
tell the AspectBuffer about the aspect, but to use the actual ListModel
from subjectCopy as the model for the listbox.

I over-simplified my original description a bit.  My "dialog" is
actually a sub-view in a container view that has OK and Cancel buttons.
  I'm using AspectBuffer and aspectValue: exactly like Dialog does, but
my presenter is not actually a sub-class of Dialog.

The problems I'm seeing are:
1. When I hit the cancel button, the list doesn't get refreshed.  In a
real dialog, this wouldn't be an issue.  Now that it isn't late, and I'm
thinking more clearly, I'm remembering that ApsectBuffer>>revert has the
following line:

subjectCopy := self subject copy.

The old subjectCopy gets tossed, but my ListBox still has its ListModel
as its model.  I need to fix that.

2. AspectBuffer>>apply didn't seem to be actually copying its changes
back to the original.  Again, thinking about it now that it's not late
at night, I was actually seeing an indirect symptom of that.  I need to
investigate further.

Thanks for your help.  It made me think things through a little more,
and I may have a solution.  More tonight, when I get back to this stuff...

Randy
--
Randy Coulman
NOTE: Reply-to: address is spam-guarded.  Reassemble the following to
reply directly:
rvcoulman at acm dot org


Reply | Threaded
Open this post in threaded view
|

Re: Dialogs and ListModels

Randy Coulman-2
I wrote:
>
> The old subjectCopy gets tossed, but my ListBox still has its ListModel
> as its model.  I need to fix that.
>

This turned out to be the problem.  Now it works fine.

> 2. AspectBuffer>>apply didn't seem to be actually copying its changes
> back to the original.  Again, thinking about it now that it's not late
> at night, I was actually seeing an indirect symptom of that.  I need to
> investigate further.
>

As I suspected, this turned out to be a different problem.  I've now
refactored my code so that this problem won't happen again.

Thanks again, everybody, for the help.

Randy
--
Randy Coulman
NOTE: Reply-to: address is spam-guarded.  Reassemble the following to
reply directly:
rvcoulman at acm dot org