How to create a hidden view?

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

How to create a hidden view?

Jurko Gospodnetic
Hi all.

  Could someone please tell me if there is a standard way to create a hidden
window (view) in Dolphin?

  I'm writing unit tests for a part of my GUI and would like them to create
and
test the views they need but not really show any of them on the screen.
However, I found no standard way to create a view without showing it on the
screen.

  These are some of the things I noticed so far:

- The View class creates windows using SW_SHOW windows showStyle
specified in the private View>>defaultShowStyle method and used in
View>>show.

- All the Presenter methods for creating it's view rely on the private
Presenter>>createView: method which directly tries to show the views at two
places - once for the surrogate parent ShellView and once afterwards for
it's
own view. So Presenter's view creation seems linked hard to that view being
displayed immediately - ugly. Also I don't really see why the surrogate
parent
view should be displayed before the child view is. Doesn't that leave a
running
risk of something flickering? Ah well, cest la vie...

- Shell class overrules the private Shell>>createView: method so it doesn't
show it's view automatically, but does call it's Shell>>view: method which
triggers the #viewOpened event even though the view has not yet been
displayed on the screen.

- If a non-shell Presenter's view is shown directly without providing it's
parent
presenter then a surrogate Shell presenter is provided for it in
Presenter>>createView:. However, in that case two #viewOpened events are
triggered for the surrogate parent Shell. Once when that parent view itself
is
created and connected to it's Presenter (see Shell>>view:) and once after
it's
subpresenter is added (see Presenter>>createView:). Seems smelly and
even more so if you have to duplicate this strange behavior trying to do
some
roundabout fix to this conundrum without wrecking up existing code. Many
questions pop to mind while reading through this code: Whose duty should it
be to trigger #viewOpened? Why do two separate classes do it? When
should it be triggered? What exactly does that event mean? That a view has
been created or that it has been displayed on the screen? Should
#viewOpened get triggered for subviews? Who should trigger it? The parent
view, the presenter creating the parent view or the subview's presenter?

  If anyone has any ideas, knows a standard solution to this problem or
simply
knows that all this View creation and displaying code is going to be redone
in
some future Dolphin release please let me know otherwise I'm gonna have to
live with those irritating little windows popping up during unit testing :-)
or and
implement my own extension to Dolphin classes and live with the fear of
Dolphin classes having their private methods changed in some future release
:-(.

  Thanks,
    Jurko


Reply | Threaded
Open this post in threaded view
|

Re: How to create a hidden view?

Bill Schwab-2
>   Could someone please tell me if there is a standard way to create a
hidden
> window (view) in Dolphin?
>
>   I'm writing unit tests for a part of my GUI and would like them to
create
> and
> test the views they need but not really show any of them on the screen.

Look at WinAsyncSocket.  However, I would encourage you to let your views
show themselves as part of your tests.  Not only does it make for a good
stress test, it can reveal drawing problems that you would not otherwise
notice.

Have a good one,

Bill

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


Reply | Threaded
Open this post in threaded view
|

Re: How to create a hidden view?

Randy Coulman-2
In reply to this post by Jurko Gospodnetic
Jurko Gospodnetiæ wrote:

>   Hi all.
>
>   Could someone please tell me if there is a standard way to create a hidden
> window (view) in Dolphin?
>
>   I'm writing unit tests for a part of my GUI and would like them to create
> and
> test the views they need but not really show any of them on the screen.
> However, I found no standard way to create a view without showing it on the
> screen.
>

See this article:
http://groups.google.com/groups?selm=uwuww2wro.fsf%40online.no

I haven't looked at the code or tried the approach myself, but I keep
meaning to.  It might help you.

Randy
--
Randy Coulman
NOTE: Reply-to: address is spam-guarded.  Reassemble the following to
reply directly:
rcoulman at charter dot net


Reply | Threaded
Open this post in threaded view
|

Re: How to create a hidden view?

Bill Dargel
In reply to this post by Jurko Gospodnetic
Jurko Gospodnetiæ wrote:
>   I'm writing unit tests for a part of my GUI and would like them to create
> and
> test the views they need but not really show any of them on the screen.
> However, I found no standard way to create a view without showing it on the
> screen.

Check out the various create* methods in Presenter class in the instance
creation category. If you use these rather than the various show*
methods the view doesn't actually show on the display, as #showShell is
not called.

Is this what you're looking for?

I've used create* in a quite a few of my unit tests, though I've found
that there're some things that require the showShell in order to
function, so I still have windows sometimes appearing briefly on the
display as unit tests are running.
 
-------------------------------------------
Bill Dargel            [hidden email]
Shoshana Technologies
100 West Joy Road, Ann Arbor, MI 48105  USA


Reply | Threaded
Open this post in threaded view
|

Re: How to create a hidden view?

Jurko Gospodnetic
In reply to this post by Bill Schwab-2
Hi Bill.

 Thanks for your prompt reply.

  I looked over the class you pointed me to and it helped me to finally
grasp
(I think :-)) how Dolphin creates it's windows. Using that knowledge I
created my windows with, hopefully, only minimal use of private methods
and the same side-effects (such as events and layout validation) as normal
window creation. For more information about that see my other reply.

> [...snipped...]
> However, I would encourage you to let your views
> show themselves as part of your tests.  Not only does it make for a
> good stress test, it can reveal drawing problems that you would not
> otherwise notice.

  As for the unit tests, I'd rather not have the views shown during testing.
If I need to stress test view drawing or test that a view can be shown
at all I'll put that in a separate test. And I don't get to check visually
whether a view is drawn correctly during unit tests as it pops up and
closes too fast anyway.

  Many thanks,
    Jurko

P.S.
  Sorry for not posting directly under your reply but my news reader
(OE) seems to be messing with me again.


Reply | Threaded
Open this post in threaded view
|

Re: How to create a hidden view?

Jurko Gospodnetic
In reply to this post by Bill Dargel
Hi Bill.

> I've used create* in a quite a few of my unit tests, though I've
> found that there're some things that require the showShell in
> order to function, so I still have windows sometimes appearing
> briefly on the display as unit tests are running.


  Thanks for the advice. I'd be very interested if you could tell me
exactly which things didn't work without the showShell method
being called. I'd like to check that my solution supports those
same things. For the solution itself see my other post.

  Thanks,
    Jurko


Reply | Threaded
Open this post in threaded view
|

Re: How to create a hidden view?

Jurko Gospodnetic
In reply to this post by Jurko Gospodnetic
Hi all.

  Thanks to all who responded!

  I managed to create my windows with, hopefully, only minimal use of
Dolphin's private methods and same side-effects (such as events and
layout validation) as normal window creation.

  Here's a code snippet that creates a hidden view. It's layed out in the
following pattern:
  1. create and set up views
  2. create presenters with their default models
  3. connect the views to the presenters.
Names of my classes have been changed so they wouldn't cloud the
issue:


[...begin code...]
"Create and connect all the needed views."
parentShellView := ShellView new create.
parentShellView
    layoutManager: GridLayout new;
    caption: 'MyView testing shell'.
myView := MyPresenter
    loadViewResource: MyPresenter defaultView
    inContext: parentShellView.
parentShellView validateLayout.
myView show.

"Create presenters with their default models."
myPresenter := MyPresenter new.
myPresenter view: myView.


"Create and connect the parent shell presenter. Connecting the
shell view and it's presenter triggers all the necessary events."
parentShellPresenter := Shell new.
parentShellPresenter add: myPresenter.
parentShellPresenter view: parentShellView.
[...end code...]

  The only private methods used are View>>create and
Presenter class>>loadViewResource:inContext:. Also no events
(for example #viewOpened) are triggered by hand as is done in
Presenter>>createView: from which I 'borrowed' much of the code
and ideas. One thing I do dislike about this code is that I found no
clean way to avoid calling parentShellView's validateLayout method
by hand.

  I created the surrounding Shell for two reasons. One is that it
allows me to normally show the window if needed, and the other is
that connecting the surrounding ShellView to it's Shell presenter
triggers all the events that are usually triggered when a view is
opened so I don't need to trigger any by hand.

  If I'm getting it correctly the #viewOpened event should be
triggered when a view (actually it's topView) is hooked up to a
Shell presenter. The view does not need to be visible at that time.
However, that same event is triggered from two other places
(through onViewOpened methods) in the standard Dolphin image:
  - Presenter class>>create:in:on: which, as I see it, is supposed
     to be used for creating subviews in already open and
     connected views.
  - Presenter>>createView: which seems to call it on the view it
     creates if it supplied it with a surrogate parent ShellView, but
     that code is needed only because it doesn't connect the
     parent ShellView to a Shell presenter at all. I was too hasty
     interpreting this method in my original post so a few mistakes
     slipped by but hopefully this corrects them.

  If anyone sees any other problems with this code, or sees any
way to clean it up, please let me know.

  I'd sure like to see Dolphin's public View/Presenter interface
tweaked a bit. My guess is that it could use a clean public way
for creating hidden views, as well as some tweaking related to
when certain events like #viewOpened are triggered. The way it's
implemented at the moment had me going around in circles not
knowing whether my code acts exactly the way 'standard view
showing' code does or if I forgot to trigger something by hand.

  Best regards,
    Jurko


Reply | Threaded
Open this post in threaded view
|

Re: How to create a hidden view?

Blair McGlashan
"Jurko Gospodnetiæ" <[hidden email]> wrote in message
news:bhstu0$hke$[hidden email]...

>   Hi all.
>
>   Thanks to all who responded!
>
>   I managed to create my windows with, hopefully, only minimal use of
> Dolphin's private methods and same side-effects (such as events and
> layout validation) as normal window creation.
>
>   Here's a code snippet that creates a hidden view. It's layed out in the
> following pattern:
>   1. create and set up views
>   2. create presenters with their default models
>   3. connect the views to the presenters.
> Names of my classes have been changed so they wouldn't cloud the
> issue:
> ....

I would have thought you could achieve what you want without any use of
private methods and much more succinctly by making use of the various public
creation methods in the <presenter factory> protocol on the class side
methods of Presenter. For example:

    shell := Shell create.
    myPresenter := MyPresenter createIn: shell.

The key to opening a window without it being shown is simply to supply your
own shell. If you don't then the framework helpfully opens one for you, but
it only really does this to make it easier to play and test out workspace
code. Consequently it deliberately shows that shell to avoid hidden windows
going astray.

You'll need a little extra code if you want to set the layout manager, but
presumably if you aren't interested in the visual result that is immaterial,
especially since the layout is lazily determined when the view is actually
painted.

I would say that this already amounts to a clean and simple way to create
hidden views. Whether it is truly a good idea to test GUIs like this is
another matter. As in the case of the layout managers, quite a lot of code
coverage will be lost, and frankly I very much doubt that the underlying
Microsoft Windows controls behave in the same way when hidden. Actually
there are some very obvious examples of where they do not, such as the
ListView control in virtual mode.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: How to create a hidden view?

Jurko Gospodnetic
Hi Blair.

  Thank you for responding. Your answer's been a great eye-opener! :-)))

> I would have thought you could achieve what you want without any use
> of private methods and much more succinctly by making use of the
> various public creation methods in the <presenter factory> protocol on
> the class side methods of Presenter.

  Actually I did play around with it first but originally didn't manage to
get it
working the way I wanted, but for the life of me I don't remember what
was the problem. The only difference I see now between this view opening
and a regular one (when the Shell used is my own class with MyPresenter as
a regular subpresenter) is that the Shell presenter and MyPresenter are
getting their #viewOpened events triggered in reverse order, but I guess I
can live with that for now.

> The key to opening a window without it being shown is simply to supply
> your own shell.  If you don't then the framework helpfully opens one for
you,
> but it only really does this to make it easier to play and test out
workspace
> code. Consequently it deliberately shows that shell to avoid hidden
windows
> going astray.

  Ok, got that one. If I look at it that way then it actually is a good
thing.

> I would say that this already amounts to a clean and simple way to create
> hidden views.

  I agree. It's much cleaner than that hand-crafted solution. Thanks for
pointing it out for me.

> Whether it is truly a good idea to test GUIs like this is
> another matter. As in the case of the layout managers, quite a lot of
> code coverage will be lost, and frankly I very much doubt that the
> underlying Microsoft Windows controls behave in the same way when
> hidden. Actually there are some very obvious examples of where they
> do not, such as the ListView control in virtual mode.

  *nod* Thanks for the tip, didn't realize those differences existed. Unit
testing views just got me thinking about creating hidden views. It doesn't
really matter if the screen blinks during testing even though it can be
annoying when it blinks 30 times but really only one of the tests needs it
shown on screen. :-) But I guess that whole construct falls apart if
views don't work the same hidden and visible.

  Thanks again.

  Best regards,
    Jurko