What's the proper time for view initialization?

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

What's the proper time for view initialization?

Jeff M.
This is really a two question post:

First, I'm having a bit of trouble figuring out exactly when the right
time to do something is. I'm going to be initializing some view data,
which happens to be dependent on the view having been "created"
(meaning the handle, and everything else - like size - of the window
are valid and can be shown at any time). Hence, I can't put this code
in the initialize method.

I see overrides like hookWindowCreate, but I really am not sure what
this does. I see this calls and onAboutToCreate method, and I've tried
putting my init code in both, but doing this causes a recursive loop
that always blows the stack. So, either I'm doing something wrong, or
this is definitely the wrong place to put that code.

If I put the code in another (public) function, I can call it after
I've shown the view for the first time and everything works perfectly.
I'd like this code to be private, because it should never happen more
than once, I just don't know the method to override, sadly.

And second, I need to resize the window before it is shown as well
(again, only the first time). This is because the window size is
actually incorrect. If someone overrides defaultExtent, and gives
^##(640 @ 480) as the default, then this isn't really the size of the
client viewport (border and title bar haven't been taken into account).
In Win32/C++, I would need to do the following before the window is
actually shown:

// the window has already been created, and we're going to resize it
int style = GetWindowLong(hwnd, GWL_STYLE);
int exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);

// the desired viewport size
RECT size = { 0, 0, width - 1, height - 1 };

// resize the rectangle to encompass the title bar
AdjustWindowRectEx(&size, style, false, exstyle);

// TODO: resize window with new size rectangle

This code is easy enough to port over, once I know where to put it
exactly. It should happen after creation (of course, I need the
handle), but before my first problem (the private code initialization).

Bah, while I'm already posting, I might as well ask another question:
how can I set a breakpoint? I love the debugger, and am using it easily
from the Workspace, but if I've overridden an event method, I'd like to
be able to break inside when it's triggered (like when I click a button
and get inside the button code). It isn't immediately obvious how to do
this, and I haven't found anything in the documentation showing me how,
but I'm sure it's there.

Any suggestions? Thanks!

Jeff M.


Reply | Threaded
Open this post in threaded view
|

Re: What's the proper time for view initialization?

Ian Bartholomew-21
Jeff,

> First, I'm having a bit of trouble figuring out exactly when the right
> time to do something is. I'm going to be initializing some view data,
> which happens to be dependent on the view having been "created"
> (meaning the handle, and everything else - like size - of the window
> are valid and can be shown at any time). Hence, I can't put this code
> in the initialize method.

If you look in the Presenter class you will find methods that are called
(using Dolphins event mechanism) at certain times in the process of opening
a view.  Included in those are...

#onViewCreated
#onViewAvailable
#onViewOpened

The method comments give an indication of the state of the view at the time
the method is called so choose the appropriate one.  I tend to use
#onViewOpened because everything (Model, View and Presenter) is available
and the View is just about to become visible.  The #onViewAvailable method
is probably better for some situations though.

To use it you just override it in your new Shell subclass.  For example, say
you have added a Shell subclass called MyShell.  To resize the View [1] you
would add a method

MyShell>>onViewAvailable
 super onViewAvailable.
 self view extent: 400 @ 400

Try to remember the supersend.  It's not important in this case but if you
override #onViewOpened method then it is, and if you forget (which you will)
then your views don't work as they should.

[1] You can also specify a ShellView's size when you create it in the
ViewComposer - see the #preferredExtent aspect


> Bah, while I'm already posting, I might as well ask another question:
> how can I set a breakpoint? I love the debugger, and am using it easily
> from the Workspace, but if I've overridden an event method, I'd like to
> be able to break inside when it's triggered (like when I click a button
> and get inside the button code). It isn't immediately obvious how to do
> this, and I haven't found anything in the documentation showing me how,
> but I'm sure it's there.

The Walkback and Debugger are opened every time an incorrect expression is
encountered so to insert a breakpoint you just insert some code that will
fail.

self aSelectorThatDoesNotExist.

for example.  However, most people use

self halt

to bring up the debugger.   OK, so you will now be saying "there should be
some way of inserting a breakpoint without having to edit code" :-)   It's a
fair comment, and some Smalltalk implementations have addressed it, but I
don't consider it a real disadvantage - you get a lot of flexibility this
way.  Conditional breakpoints can be so much more, um, conditional ...

(anArgument = 10 and: [
    self hadSecondCupOfTea and: [
        date today isNotFriday]]) ifTrue: [self halt]

The only danger is putting breakpoints in some of the methods that are
involved with lower level windows and event handling.  As Smalltalk
programming works by modifying a running image putting a breakpoint is a
method that is involved in displaying the Debugger, for instance, would
cause problems!

--
Ian

Use the Reply-To address to contact me (limited validity).
Mail sent to the From address is ignored.


Reply | Threaded
Open this post in threaded view
|

Re: What's the proper time for view initialization?

Chris Uppal-3
In reply to this post by Jeff M.
Jeff

> int style = GetWindowLong(hwnd, GWL_STYLE);
> int exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);

Just a small meta-point:

While it is certainly possible to program at the level of the raw Win-32 API in
Dolphin, and indeed it is sometimes necessary to do so, you should usually be
able to do normal windowy things without dropping to that level.  By "normal" I
mean the kinds of GUI elements that you see in the IDE.

So, unless you /want/ to work at that level (in which case, btw, ST-MT[*] might
suit you better) it's generally worth looking around to see how Dolphin's MVP
framework expresses the concepts you are looking for.

In this particular case, as Ian has already mentioned, you can set the
#preferredExtent -- which itself is part of a moderately sophisticated
mechanism through which which Views and LayoutManagers negotiate component
sizes.

    -- chris

[*] ST-MT is a different Smalltalk implementation.  It follows a different
philosophy wrt. the Win32 API -- the approach seems to be to make it as
convenient as possible to use it "raw", but not to abstract away from it;
whereas the Dolphin approach is more about using the Win32 stuff to /implement/
a properly-designed GUI framework.)


Reply | Threaded
Open this post in threaded view
|

Re: What's the proper time for view initialization?

Eric Taylor
In reply to this post by Jeff M.
Jeff,

Have you by any chance purchased a copy of Ted Bracht's book The Dolphin
Companion?  He has a great insert at the back of the book that explains,
in table format, the sequence of events when Dolphin opens a window.  It
has been an indispensable reference for us here.  

The book is dated to version 4 of Dolphin, but that hasn't hindered its
usefulness in any appreciable way.

Cheers,

Eric

> -----Original Message-----
> From: Jeff M. [mailto:[hidden email]]
> Posted At: Friday, June 09, 2006 8:21 PM
> Posted To: comp.lang.smalltalk.dolphin
> Conversation: What's the proper time for view initialization?
> Subject: What's the proper time for view initialization?
>
> This is really a two question post:
>
> First, I'm having a bit of trouble figuring out exactly when the right
> time to do something is. I'm going to be initializing some view data,
> which happens to be dependent on the view having been "created"
> (meaning the handle, and everything else - like size - of the window
> are valid and can be shown at any time). Hence, I can't put this code
> in the initialize method.
>
> I see overrides like hookWindowCreate, but I really am not sure what
> this does. I see this calls and onAboutToCreate method, and I've tried
> putting my init code in both, but doing this causes a recursive loop
> that always blows the stack. So, either I'm doing something wrong, or
> this is definitely the wrong place to put that code.
>
> If I put the code in another (public) function, I can call it after
> I've shown the view for the first time and everything works perfectly.
> I'd like this code to be private, because it should never happen more
> than once, I just don't know the method to override, sadly.
>
> And second, I need to resize the window before it is shown as well
> (again, only the first time). This is because the window size is
> actually incorrect. If someone overrides defaultExtent, and gives
> ^##(640 @ 480) as the default, then this isn't really the size of the
> client viewport (border and title bar haven't been taken into
account).

> In Win32/C++, I would need to do the following before the window is
> actually shown:
>
> // the window has already been created, and we're going to resize it
> int style = GetWindowLong(hwnd, GWL_STYLE);
> int exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
>
> // the desired viewport size
> RECT size = { 0, 0, width - 1, height - 1 };
>
> // resize the rectangle to encompass the title bar
> AdjustWindowRectEx(&size, style, false, exstyle);
>
> // TODO: resize window with new size rectangle
>
> This code is easy enough to port over, once I know where to put it
> exactly. It should happen after creation (of course, I need the
> handle), but before my first problem (the private code
initialization).
>
> Bah, while I'm already posting, I might as well ask another question:
> how can I set a breakpoint? I love the debugger, and am using it
easily
> from the Workspace, but if I've overridden an event method, I'd like
to
> be able to break inside when it's triggered (like when I click a
button
> and get inside the button code). It isn't immediately obvious how to
do
> this, and I haven't found anything in the documentation showing me
how,
> but I'm sure it's there.
>
> Any suggestions? Thanks!
>
> Jeff M.


Reply | Threaded
Open this post in threaded view
|

Re: What's the proper time for view initialization?

Jeff M.
I wasn't aware of this book. Thank you, I'll have to check it out.

Jeff M.