Should keyedValue: also be implemented in AspectBuffer?

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

Should keyedValue: also be implemented in AspectBuffer?

Christopher J. Demers
I am trying to do MVP right this time. ;)  I am trying to let go of all my
previous dialog based development experience and let the spirit of MVP guide
me into UI bliss.

Should keyedValue: be implemented in AspectBuffer?  I am developing a dialog
whose model is something like a database record.  The fields are like a
dictionary.  I have created a presenter for each field, and I believe I want
to use keyedValue: to get a ValueKeyedAdaptor.  When I use this method on
the Dictionary it works fine except that changes are not buffered, they are
applied directly.  I think I need to send this message to model which is an
AspectBuffer so that the changes will be buffered.  Should this method be
implemented there?  Am I on the right track?  If not can someone help me
onto the right track? ;)

Thanks,

Chris


Reply | Threaded
Open this post in threaded view
|

Re: Should keyedValue: also be implemented in AspectBuffer?

Frank Sergeant
"Christopher J. Demers" <[hidden email]> wrote in
message news:95po6c$iaqv7$[hidden email]...
> Should keyedValue: be implemented in AspectBuffer?  I am developing a
dialog
> whose model is something like a database record.  The fields are like a
> dictionary.  I have created a presenter for each field, and I believe I
want
> to use keyedValue: to get a ValueKeyedAdaptor.  When I use this method on
> the Dictionary it works fine except that changes are not buffered, they
are
> applied directly.  I think I need to send this message to model which is
an
> AspectBuffer so that the changes will be buffered.  Should this method be
> implemented there?  Am I on the right track?  If not can someone help me
> onto the right track? ;)

The approach I take is to have a model which answers up to #at: and #at:put:
to supply and set its attributes.  Then, in #model: for the presenter, I do
something like the following.  (My model has a record which knows its field
names).

 -----------------------------------

model: aModel
"Setup the submodels for each of the subpresenters. The ValueKeyedAdaptor
for, e.g., an 'address' field causes the message at: 'address' or at:
'address' put: <somevalue> to be sent to the BusinessObject which is the
presenter's model. What happens if aModel is a ValueKeyedAdaptor for a
subform? Try taking its _value_ when calling #model:. Only set up submodels
where the presenter's name matches a field of the form's business object.  "

| fieldNames fieldPresenters |

super model: aModel value.

fieldNames := aModel record fieldNames.

fieldPresenters := subPresenters select: [:each | fieldNames includes: (self
nameOf: each) ].

fieldPresenters do:

    [ :each | each model: (ValueKeyedAdaptor

    subject: self model value

    key: (self nameOf: each)) ].

 -----------------------------------

I hope this helps.



-- Frank

[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Should keyedValue: also be implemented in AspectBuffer?

Christopher J. Demers
Thanks for the suggestion.  However changes are still not buffered with this
way.  As I understand it, with AspectBuffers changes are made to a copy of
the actual model.  If the OK button on a Dialog is selected the changes are
applied via the aspects collection.  If the Cancel button is selected the
changes are not applied.  This seems to work with ValueAspectAdaptors but
there does not seem to be a provision for ValueKeyedAdaptors to work in this
way with AspectBuffers.

I think I am going to try adding DNU support to my record class, so I can
use the existing aspectValue: message.

Thanks for the info,

Chris

Frank Sergeant <[hidden email]> wrote in message
news:GR_f6.728$[hidden email]...
>
> The approach I take is to have a model which answers up to #at: and
#at:put:
> to supply and set its attributes.  Then, in #model: for the presenter, I
do
> something like the following.  (My model has a record which knows its
field

> names).
>
>  -----------------------------------
>
> model: aModel
> "Setup the submodels for each of the subpresenters. The ValueKeyedAdaptor
> for, e.g., an 'address' field causes the message at: 'address' or at:
> 'address' put: <somevalue> to be sent to the BusinessObject which is the
> presenter's model. What happens if aModel is a ValueKeyedAdaptor for a
> subform? Try taking its _value_ when calling #model:. Only set up
submodels
> where the presenter's name matches a field of the form's business object.
"
>
> | fieldNames fieldPresenters |
>
> super model: aModel value.
>
> fieldNames := aModel record fieldNames.
>
> fieldPresenters := subPresenters select: [:each | fieldNames includes:
(self

> nameOf: each) ].
>
> fieldPresenters do:
>
>     [ :each | each model: (ValueKeyedAdaptor
>
>     subject: self model value
>
>     key: (self nameOf: each)) ].
>
>  -----------------------------------
>
> I hope this helps.
>
> -- Frank
>
> [hidden email]
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Should keyedValue: also be implemented in AspectBuffer?

Frank Sergeant
"Christopher J. Demers" <[hidden email]> wrote in
message news:95q1iq$i5rlh$[hidden email]...
> Thanks for the suggestion.  However changes are still not buffered with
this
> way.  As I understand it, with AspectBuffers changes are made to a copy of
> the actual model.  If the OK button on a Dialog is selected the changes
are
> applied via the aspects collection.  If the Cancel button is selected the
> changes are not applied.  This seems to work with ValueAspectAdaptors but
> there does not seem to be a provision for ValueKeyedAdaptors to work in
this
> way with AspectBuffers.

Oops, I left some information out from my previous post.  (And, may well
still be leaving something out.)

> I think I am going to try adding DNU support to my record class, so I can
> use the existing aspectValue: message.

That shouldn't be necessary.  Following is an example #model: from one of my
subclasses of Dialog.  The superclass (Dialog) takes care of creating the
buffered model.  For this to work, I added two methods to AspectBuffer
(#keyedApply and #keyedAspectValue: ) then override #apply in the Dialog
subclass to have it send #keyedApply to the model instead of #apply.

 ------------------------
model: aSubjectModel

"Set the model of the receiver to be a buffer onto of aSubjectModel."

| aspectBuffer |

super model: aSubjectModel.

" ** now wire up the sub models automatically ** "

aspectBuffer := self model.

subPresenters do: [:each |

aspectBuffer value at: (self nameOf: each) asSymbol ifPresent: [:what |

    each model: (aspectBuffer keyedAspectValue: (self nameOf: each)
asSymbol)]].


 ------------------------

AspectBuffer>>keyedApply
"Apply the aspects held by the receiver in the model copy back to the
original model"

aspects do: [:each |

    self subject perform: each putSelector with: each key with: each value ]

 ------------------------
AspectBuffer>>keyedAspectValue: aKey

"Answer a ValueAspectAdapter for anAspectSymbol of our copied model. If a
request for this aspect has already been registered then the same adapter
model is answered. Otherwise a new one is created and registered in our
aspects dictionary. This is the same as #aspectValue: except that the aspect
symbol is a key rather than an attribute."

^aspects at: aKey ifAbsentPut: [

    ValueKeyedAdaptor subject: subjectCopy "aspect:" key: aKey]

 ------------------------


-- Frank
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Should keyedValue: also be implemented in AspectBuffer?

Christopher J. Demers
Thanks, this is exactly what I was after.  I thought I might have to do
something like this.  I just wanted to make sure I was working the way MVP
wants me to work.  I wonder if OA might consider adding something like this
to the base system?  It looks like Dolphin has the beginnings of what we
need but stops just short of the full implementation (at least for Dialogs).

I have followed your example and it works, thank you!  I am thinking of a
slight variation on your approach:  I could create a method called applyTo:
in ValueKeyedAdaptor and ValueAspectAdaptor, that would do "its perform
thing".  Then I would edit AspectBuffer<<apply so that it just sends
applyTo: and passes subject.  I think it would make things more seamless
regarding ValueKeyedAdaptors or ValueKeyedAdaptors, in fact they could even
be mixed (not likely needed, but who knows).  I may not actually do this
since I don't really want to make these kinds of system changes.  However OA
might consider doing something like this as a future enhancement to better
support keyed collections in MVP Dialogs.

Chris

Frank Sergeant <[hidden email]> wrote in message
news:X13g6.759$[hidden email]...

> Oops, I left some information out from my previous post.  (And, may well
> still be leaving something out.)
>
> > I think I am going to try adding DNU support to my record class, so I
can
> > use the existing aspectValue: message.
>
> That shouldn't be necessary.  Following is an example #model: from one of
my

> subclasses of Dialog.  The superclass (Dialog) takes care of creating the
> buffered model.  For this to work, I added two methods to AspectBuffer
> (#keyedApply and #keyedAspectValue: ) then override #apply in the Dialog
> subclass to have it send #keyedApply to the model instead of #apply.
>
>  ------------------------
> model: aSubjectModel
>
> "Set the model of the receiver to be a buffer onto of aSubjectModel."
>
> | aspectBuffer |
>
> super model: aSubjectModel.
>
> " ** now wire up the sub models automatically ** "
>
> aspectBuffer := self model.
>
> subPresenters do: [:each |
>
> aspectBuffer value at: (self nameOf: each) asSymbol ifPresent: [:what |
>
>     each model: (aspectBuffer keyedAspectValue: (self nameOf: each)
> asSymbol)]].
>
>
>  ------------------------
>
> AspectBuffer>>keyedApply
> "Apply the aspects held by the receiver in the model copy back to the
> original model"
>
> aspects do: [:each |
>
>     self subject perform: each putSelector with: each key with: each
value ]
>
>  ------------------------
> AspectBuffer>>keyedAspectValue: aKey
>
> "Answer a ValueAspectAdapter for anAspectSymbol of our copied model. If a
> request for this aspect has already been registered then the same adapter
> model is answered. Otherwise a new one is created and registered in our
> aspects dictionary. This is the same as #aspectValue: except that the
aspect

> symbol is a key rather than an attribute."
>
> ^aspects at: aKey ifAbsentPut: [
>
>     ValueKeyedAdaptor subject: subjectCopy "aspect:" key: aKey]
>
>  ------------------------
>
>
> -- Frank
> [hidden email]
>


Reply | Threaded
Open this post in threaded view
|

Re: Should keyedValue: also be implemented in AspectBuffer?

Frank Sergeant
"Christopher J. Demers" <[hidden email]> wrote in
message news:95t2nv$ibbqe$[hidden email]...
> Thanks, this is exactly what I was after.
 ...
> I have followed your example and it works, thank you!

I am delighted to have provided something useful!

> I just wanted to make sure I was working the way MVP
> wants me to work.  I wonder if OA might consider adding something like
this
> to the base system?  It looks like Dolphin has the beginnings of what we
> need but stops just short of the full implementation (at least for
Dialogs).

Things have been going increasingly smoothly for me in Dolphin as I have
gotten more familiar with it.  It required a heavy investment in start-up
effort for me to do so, especially regarding building (and connecting) GUIs.
This was *after* I thought I knew Smalltalk and thought I understood the
equivalent GUI building in both VisualWorks and Visual Age.  The first point
(thinking I knew Smalltalk) could be explained by noting that I have
continued to learn a great deal about using the built-in Smalltalk
environment to answer questions, but it doesn't fully explain the 2nd and
3rd points (re "getting it" in VW and VA).  It could be that I had a blind
spot causing me trouble but that others fall into the Dolphin way without
effort.

The above paragraph is rather a disclaimer to my suggestion that maybe
Dolphin's GUI approach could be improved further.  We are used to the stupid
newbie coming in and suggesing all sorts of wild "improvements" before he
has a clue.  However, I hope I am no longer he.

I think the most needed thing is not so much a change to Dolphin, but
improved and additional documentation and examples.  Various posters have
been very helpful in providing examples and answering questions.  I am
looking forward to one or more Dolphin books.  If it had the number of books
that VW has, giving examples and explanations, Dolphin would be far easier
to "get into".  Well, we really have enough now so that Dolphin *can* be
learned, it just takes some digging, but more would be even better.

I need to look into it more, but I am somewhat unhappy that the dialog and
non-dialog windows are so segregated.  I believe OA have offered reasons for
this but all I got out of it was "Microsoft suggests it so it's got to be
good" (unfair, incorrect summary for rhetorical purposes).  What I want
instead (I think) is a simple boolean to say whether the window is modal or
not.  I do not see how the difference of model (sometimes you want a
buffered model and sometimes not, sometimes you want to wait for an answer
and sometimes not) justifies this separation.  Of course, I could be
overlooking important factors, so I want to look into it further before
committing myself.

Also, the various window creation methods seem needlessly complex (or maybe
I just just need a thorough explanation).

I think Dolphin is so very good that there is nothing stopping us from
having it be perfect.  My role, of course, is to point out possible
problems, or conveniences available in other environments, and then see them
appear magically.  With the base OA work plus Ian's ViewComposer additions,
we have much of the convenience of the very expensive but very good
WindowBuilderPro.  Things are so good that I am not sure what to ask for
next!  (Well, abstracting the GUI from its Windows implementation, without
losing any speed, thus paving the way for a port to Linux, is something you
could put on your "to do" list for when you didn't have anything better to
do.)


-- Frank
[hidden email]
I did not have sex with that woman


Reply | Threaded
Open this post in threaded view
|

Re: Should keyedValue: also be implemented in AspectBuffer?

Christopher J. Demers
Frank Sergeant <[hidden email]> wrote in message
news:rfFg6.947$[hidden email]...
>
> Things have been going increasingly smoothly for me in Dolphin as I have
> gotten more familiar with it.  It required a heavy investment in start-up
> effort for me to do so, especially regarding building (and connecting)
GUIs.
> This was *after* I thought I knew Smalltalk and thought I understood the
> equivalent GUI building in both VisualWorks and Visual Age.  The first
point

Yep, me too on this front.  My big problem at first was that I knew just
enough to be dangerous with Dolphin GUI's.  I knew how to refer to views via
viewNamed: so I thought I had no need for sub-presenters.  I just threw my
data in the views, and grabbed it back when I was done.  It worked, and I
had to make some GUI's, so I just did them that way.  Sometimes it is hard
to stop and learn the "right" way once you get going one way.

Now I understand the reason for all the sub-presenters.  However I still did
not want to type all the presenter support code manually.  I wrote a class
to do that for me.  It walks the view and gets all named sub-views that need
presenters.  Then it adds the instance variables to the class, and generates
a createComponents method for the class using a view class to presenter
class mapping dictionary.  If I can get the code polished a bit more, and
there is interest I might make it available as a free goodie.

> I think the most needed thing is not so much a change to Dolphin, but
> improved and additional documentation and examples.  Various posters have
> been very helpful in providing examples and answering questions.  I am
> looking forward to one or more Dolphin books.  If it had the number of
books

Definitely!  I would love to see a comprehensive Dolphin book as well as
improved documentation.

>
> I need to look into it more, but I am somewhat unhappy that the dialog and
> non-dialog windows are so segregated.  I believe OA have offered reasons
for

I think OA made some changes in this area in version 4.0.  I know because it
broke my code. ;)  I used to use Dialog<<show to open my dialogs in 3.0 and
it worked because it effectively just sent Dialog<<showModal.  In version 4
they removed Dialog<<show and it now uses Presenter<<show which will open a
non-modal dialog.  This may not be totally what you are after, but it might
be part of it.

I have had cases where I made a view in the wrong part of the hierarchy, and
needed to move it.  I found that I could move the presenter class, and then
mutate the view as needed (after I patched the mutate code so it does not
loose sub-view names).

>
> I think Dolphin is so very good that there is nothing stopping us from
> having it be perfect.  My role, of course, is to point out possible

Cheers to a perfect Dolphin, or as close to it as mortals dare tread!

Chris


Reply | Threaded
Open this post in threaded view
|

Re: Should keyedValue: also be implemented in AspectBuffer?

Andy Bower
In reply to this post by Frank Sergeant
Frank,

> I need to look into it more, but I am somewhat unhappy that the dialog and
> non-dialog windows are so segregated.  I believe OA have offered reasons
for
> this but all I got out of it was "Microsoft suggests it so it's got to be
> good" (unfair, incorrect summary for rhetorical purposes).  What I want
> instead (I think) is a simple boolean to say whether the window is modal
or
> not.  I do not see how the difference of model (sometimes you want a
> buffered model and sometimes not, sometimes you want to wait for an answer
> and sometimes not) justifies this separation.  Of course, I could be
> overlooking important factors, so I want to look into it further before
> committing myself.

FWIW, I agree with you. There shouldn't really be a need, on the presenter
side, to distinuguish between a dialog and a shell. A dialog does usually
need to buffer changes to its model and the #accept code has to go somewhere
so that's whay we created the Dialog subclass of Shell. It's possible that
this could be dispensed with but what impact this would have on existing
code, I don't know.

We would still need to keep the idea of a DialogView separately from a
ShellView, however. This is a Windows issue since the OS treats "real"
dialogs quite differentlly from top level windows. We don't really want to
get into the business of not using a real dialg and simulating the modal
behaviour since this doesn't fit with the "spirit" of Dolphin.

Best Regards,

Andy Bower
Dolphin Support
http://www.object-arts.com

---
Visit the Dolphin Smalltalk WikiWeb
http://www.object-arts.com/wiki/html/Dolphin/FrontPage.htm
---


Reply | Threaded
Open this post in threaded view
|

Re: Should keyedValue: also be implemented in AspectBuffer?

Frank Sergeant
"Andy Bower" <[hidden email]> wrote in message
news:960dtj$i9fpg$[hidden email]...
[re segregating Dialog and Shell windows]
> FWIW, I agree with you. There shouldn't really be a need, on the presenter
> side, to distinuguish between a dialog and a shell.
 ...
> It's possible that this could be dispensed with but what impact this would
have on existing
> code, I don't know.

Right, thanks, and I see your point about existing code.  No particular rush
on my part, just something to consider and possibly aim for eventually.

> We would still need to keep the idea of a DialogView separately from a
> ShellView, however.

Ok, that doesn't seem like a problem to me.

> This is a Windows issue since the OS treats "real"
> dialogs quite differentlly from top level windows. We don't really want to
> get into the business of not using a real dialg and simulating the modal
> behaviour since this doesn't fit with the "spirit" of Dolphin.

I accept that.  <wink>

By the way, Borland seems to think there is big money in Linux.  I just got
an ad for Kylix listing the big version ("server" development version, or
some such) for around $2000 (USD) and the little version ("desktop"
development version, or some such) for around $1000 (USD), but offering
several hundred dollars off if I buy right away.  Well, I think they are
making a mistake.  Linux is the home (one of the homes) of *free* software.
One of us is going to be surprised, and I think it is going to be Borland,
but I've been wrong before.

If Borland is right, maybe you should raise the priority of a Linux port of
Dolphin.  If I am right, there is hardly any point to doing the port just
for Steve and me.


-- Frank
[hidden email]