[comp.windows.open-look] XView Programming Style

awatkins@lager.UVic.CA (Andrew Watkins) (03/14/91)

Hi!

I am writing a reasonably large program using XView to create the user interface. With this
program I have a bunch of popup window (~7) and I'm adding more all the time. At present I
create all of my windows when the program starts up and set the visibility off for all the 
windows I'm not using. Is this bad form? Should I create my windows as they are needed and
destroy them when I'm done or does it really matter?

Thanks for your responses,

Andrew Watkins
University of Victoria,
Victoria, BC CANADA

andrew@resam.dk (Leif Andrew Rump) (03/15/91)

In <1991Mar13.193948.16328@sol.UVic.CA> awatkins@lager.UVic.CA (Andrew  Watkins) writes:

>Hi!

> I am writing a reasonably large program using XView to create the user
> interface. With this program I have a bunch of popup window (~7) and
> I'm adding more all the time. At present I create all of my windows
> when the program starts up and set the visibility off for all the 
> windows I'm not using. Is this bad form? Should I create my windows as
> they are needed and destroy them when I'm done or does it really matter?

~7 windows isn't that much and XView/OpenWindows isn't that speedy so I
would (& do) create all the windows from the beginning (I'm using
DevGuide, and that is how DevGuide does it!). This also make housekeeping
much more simple, because values & states like inactive may be changed
on hidden windows and you don't need to keep track on the values & state.


Leif Andrew


Leif Andrew Rump, AmbraSoft A/S, Stroedamvej 50, DK-2100 Copenhagen OE, Denmark
UUCP: andrew@ambra.dk, phone: +45 39 27 11 77                /
Currently at Scandinavian Airline Systems                =======/
UUCP: andrew@resam.dk, phone: +45 32 32 51 54                \
SAS, RESAM Project Office, CPHML-V, P.O.BOX 150, DK-2770 Kastrup, Denmark

NOTICE: 'Cause of SendMail ConFiGuRation FaultS weee may experiienc ProBleeems
wiiiiiiith our return add<zap> andrew@resam.dk whiccccch may BeCoMe sOmEthIng
like <wheee>w@cph<click> !%#@#
			      @$$%$%(&**&(^%$
					     $#%%^&)(&^T^%^%^^#
							       login:

mrd@ecs.soton.ac.uk (Mark Dobie) (03/18/91)

In <1991Mar13.193948.16328@sol.UVic.CA> awatkins@lager.UVic.CA (Andrew  Watkins) writes:

>Hi!

>I am writing a reasonably large program using XView to create the user
>interface. With this program I have a bunch of popup window (~7) and
>I'm adding more all the time. At present I create all of my windows
>when the program starts up and set the visibility off for all the
>windows I'm not using. Is this bad form? Should I create my windows as
>they are needed and destroy them when I'm done or does it really
>matter?

Good question. This is how I do it too, but when I told my friend the
Microsoft Windows/Presentation Manager programmer he nearly had a
heart attack. He went on about the memory and the system resources and
stuff. I reckon this way is neater because you can do things to the
windows when they are invisible. Besides, creating the windows does seem
to take a while sometimes.

				Mark.

lwake@runcible.West.Sun.COM (Larry Wake) (03/23/91)

In article <7207@ecs.soton.ac.uk> mrd@ecs.soton.ac.uk (Mark Dobie) writes:
>In <1991Mar13.193948.16328@sol.UVic.CA> awatkins@lager.UVic.CA
(Andrew Watkins) writes:
>>iI have a bunch of popup window (~7) and
>>I'm adding more all the time. At present I create all of my windows
>>when the program starts up and set the visibility off for all the
>>windows I'm not using. Is this bad form? Should I create my windows as
>>they are needed and destroy them when I'm done or does it really
>>matter?
>
>Good question. This is how I do it too, but when I told my friend the
>Microsoft Windows/Presentation Manager programmer he nearly had a
>heart attack. He went on about the memory and the system resources and
>stuff. I reckon this way is neater because you can do things to the
>windows when they are invisible. Besides, creating the windows does seem
>to take a while sometimes.

In the manual "XView Version 2 Reference Manual: Converting SunView
Applications," Appendix B ("Performance Hints") says:

    "As a rule, create resources such as pop-ups only at the time they are
     required."

If you think about it, this makes a lot of sense.  For example, in an
application I'm writing there are nine windows, including the main
window, with more possibly to come.  However, I figure the average user
will use four of those with any frequency; the other four they may never
use.

As Mark mentioned above, these windows will take time to create; they'll
also consume X server resources and application memory.  So, why create
them until they're first needed?  If I don't create them all at once,
the program starts that much faster, and the time taken to create
windows is distributed equitably throughout the total execution time of
the program.

I use DevGuide quite heavily; the code I write to replace the stub
routines looks something like this:

    #include "foowin_ui.h"

    int foo_window_created = FALSE;
    foowin_frame_objects *foowin_p;

    /*
     *  Representative of a function that needs window "foo" visible.
     */
    void
    func_that_frobs_the_foo_window()
    {
	show_foo_window();
	xv_set(foowin_p->bar_item, PANEL_VALUE, "Hi there!", NULL);
	xv_set(blah blah blah);
    }

    /*
     * How we pop up window "foo" -- makes sure it exists, first
     */
    void
    show_foo_window()
    {
	if (!foo_window_created) create_foo_window();

	[ Stuff to set up a window each time it pops up goes here]

	xv_set(foowin_p->frame, XV_SHOW, TRUE, NULL);
    }

    /*
     * How we create window "foo" -- the verbosely-named function is
     * auto-generated by DevGuide and lives in foowin_ui.c
     */
    void
    create_foo_window();
    {
	foowin_p = foowin_frame_objects_initialize(base_frame, NULL);

	[code to pick up stuff DevGuide misses goes here]

	foo_window_created = TRUE;
    }

You can still do stuff to windows while they're not showing if you
want; just put the "if (!created) create_it();" construct in any
function that wants to deal with that window.
--
Larry Wake, Sun Microsystems (larry.wake@west.sun.com)
"Father McGrath!  I thought you were dead!"  "I was!"

rick@pbi.com (Richard M. Goldstein) (03/26/91)

	In article <7207@ecs.soton.ac.uk> mrd@ecs.soton.ac.uk (Mark Dobie) writes:
	>In <1991Mar13.193948.16328@sol.UVic.CA> awatkins@lager.UVic.CA
	(Andrew Watkins) writes:
	>>iI have a bunch of popup window (~7) and
	>>I'm adding more all the time. At present I create all of my windows
	>>when the program starts up and set the visibility off for all the
	>>windows I'm not using. Is this bad form? Should I create my windows as
	>>they are needed and destroy them when I'm done or does it really
	>>matter?

a great topic! one that is certainly relevant.


	As Mark mentioned above, these windows will take time to create; they'll
	also consume X server resources and application memory.  So, why create
	them until they're first needed?  If I don't create them all at once,
	the program starts that much faster, and the time taken to create
	windows is distributed equitably throughout the total execution time of
	the program.

my applications have a bad case of this too, so i've been thinking on this.

    void
    show_foo_window()
    {
	if (!foo_window_created) create_foo_window();

	[ Stuff to set up a window each time it pops up goes here]

	xv_set(foowin_p->frame, XV_SHOW, TRUE, NULL);
    }

so far, i'm down with ya.....

	You can still do stuff to windows while they're not showing if you
	want; just put the "if (!created) create_it();" construct in any
	function that wants to deal with that window.
	--
	Larry Wake, Sun Microsystems (larry.wake@west.sun.com)


somehow, i still don't think most applications of any sophistication
would get all the way through their setup with this technique, they
would still end up creating everything between invocation and the
call to xv_main_loop().

a more sophisticated technique would be to create an "object" (i.e.
structure) that represents all of the controls on the popup and interact
with the popup through this object.  this way, at invocation you would
malloc() the structures and maintain a coherent "state" for the popup
by getting/putting values into the structure.

then, on down the road when the user selects this popup off the menu,
call to the devguide initializer and copy the contents of the corresponding
structure into the popup and then set XV_SHOW to true.

granted this takes more work, but it allows you to keep things coherent
while still postphoning the window creation until absolutly necessary.

I'd certainly like to hear if anyone has any better ideas.

rick

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                %
% Richard M. Goldstein                           %
%                                                %
% Perfect Byte, Inc.       Phone:  (402)554-1122 %
% 7121 Cass St.            Fax:    (402)554-1938 %
% Omaha, NE 68132          email:  rick@pbi.com  %
%                                                %
% "If I knew what I was doing,                   %
%       d'ya think I'd be in Omaha?"             %
%                                                %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

warsaw@nlm.nih.gov (Barry A. Warsaw) (03/28/91)

Of course, life can be so much easier if you use C++ :-).

Anyway, what I do is subclass all the GUIDE generated classes. One
reason is to shorten all those <Interface>_<basewin>_object class
names which I hate to type.  But another is to use OO style to keep
track of all my windows. I can bypass using tons of XV_KEY_DATA's
since the only one I really need is INSTANCE, which contains a pointer
to an object of my derived class and each derived class has data
members which point to 1. the base window, 2. their subwindows, and 3.
a list of all multiple instance subwindows.

So I have basically two types of windows. The first will only have a
single instance within my application.  This might be the introductory
window, or an "About..." type window.  The second type of window may
have many instances floating about at any one time.  For example, a
"file" window for an editor (editing multiple files at once).

On my base window object, I have public members which are pointers to
all single instance windows and if they pop up at start up time, I
call objects_initialize() (inherited from the GUIDE-generated base
class) in their constructor.  For windows with multiple instances, or
for single instance windows which pop up later at a user's
instruction, I usually have both a constructor and a "pop" method.
The constructor will not call objects_initialize(), but pop() will
check to see if the XView structures have been initialized and if not,
it will first call objects_initialize(), then pop up the window.
Seems to work very well for me since its easy to create multiple
instances of windows and I don't create all those window resources
until they're absolutely necessary.

Also, using C++ really cleans up the event handlers for windows since
the INSTANCE key for items will be a pointer to my derived class. The
event handler has just enough code to extract and cast the INSTANCE
key value to the object pointer and then call the appropriate member
function which implements the guts of the event's functionality.

Hope this makes some sense. Anyway, yes this is a plug for C++ :-).

-Barry

NAME:  Barry A. Warsaw         INET: warsaw@nlm.nih.gov
TELE:  (301) 496-1936          UUCP: uunet!nlm.nih.gov!warsaw

tom@elan.Elan.COM (Thomas Smith) (03/28/91)

[ regarding a discussion of whether to create popup windows at startup time
  or the first time that they are actually needed. ]

Originally (I think) awatkins@lager.UVic.CA (Andrew Watkins) writes:
> I have a bunch of popup window (~7) and
> I'm adding more all the time. At present I create all of my windows
> when the program starts up and set the visibility off for all the
> windows I'm not using.

This is one approach to creating popups (also known as dialog boxes,
depending on your favorite nomenclature).  It has the following advantages:
    + All application initialization appears in the code at the same place
    + Code updating state information in the dialog boxes can assume that
      the structures are present/allocated
However, you also may encounter the following problems:
    - Since allocation/initialization is done at the same time, there may
      be a significant delay in startup as perceived by the user (customer).
    - The worst-case scenario for resource usage (memory, cpu) becomes the
      normal case - in other words, if your application has dialogs that
      are not often used, you still pay the penalty of creating and managing
      them.

Then Larry Wake, Sun Microsystems (larry.wake@west.sun.com) adds:
> ...these windows will take time to create; they'll
> also consume X server resources and application memory.  So, why create
> them until they're first needed?  If I don't create them all at once,
> the program starts that much faster, and the time taken to create
> windows is distributed equitably throughout the total execution time of
> the program.

This is the other approach to popup window creation.  If your particular
application has many dialog boxes that are modestly sized, this is generally
a better approach to use.  For small applications it is probably not
an important decision, but as Andrew Watkins observes above, as an
application grows, its interface is usually growing as well.  What may
not be a significant performance hit today may annoy prospective customers
six months from now.

This is referred to as the "Piss-Off Factor of User Interface Design":
The approach that is least likely to piss-off the user is more likely
to sell your product.  (also known as "In the Valley, no one can hear
you scream.")

In addition to the potential saving of resources that are never needed,
you also have the option to free resources that are no longer used.
A popup window can be destroyed when it is undisplayed, if necessary.

rick@pbi.com (Richard M. Goldstein) has the following suggestion:
> somehow, i still don't think most applications of any sophistication
> would get all the way through their setup with this technique, they
> would still end up creating everything between invocation and the
> call to xv_main_loop().

Why do you say this?  A good design is one that is easily extended as
your product grows.  Both of the above approaches treat the N+1th dialog
the same as the Nth one.

> a more sophisticated technique would be to create an "object" (i.e.
> structure) that represents all of the controls on the popup and interact
> with the popup through this object.  this way, at invocation you would
> malloc() the structures and maintain a coherent "state" for the popup
> by getting/putting values into the structure.
> 
> then, on down the road when the user selects this popup off the menu,
> call to the devguide initializer and copy the contents of the corresponding
> structure into the popup and then set XV_SHOW to true.

This is actually independent of when the dialog (or managing structure)
is created.  It is more an issue of modularity.  There are two approaches
to maintaining a dialog box's display of an application's state.
  1) Pushing information:
     When a dialog box is created, initialize it with the current state
     (note that this applies regardless of the creation strategy used).
     As the application changes state, have it feed the appropriate new
     information to each (created) dialog box.
  2) Pulling information:
     When a dialog box is *displayed*, have it query the application layer for
     the current state and initialize itself.
     As the application changes state, have it trigger each
     *currently displayed* dialog box to update itself.

The second approach has several advantages:
  + It is more modular.  The code necessary to update each dialog box 
    is separated from the application layer itself.  Enhancements to the
    dialog box (new controls, extended features) thus have a limited impact
    on the application.
  + It is more efficient.  Because only displayed dialog boxes are updated,
    information is only passed around if the user can see it.
  + It is faster to implement.  The "update-me" code, which is typically
    as complicated as the "create-me" code, can be used both for initial
    displaying and for updating the state as it changes.

The moral of the story?  Some thoughtful design today can make your
product sell better in the market place tomorrow.

    Thomas Smith
    Elan Computer Group, Inc.
    (415) 964-2200
    tom@elan.com, ...!{ames, uunet, hplabs}!elan!tom

chuck@trantor.harris-atd.com (Chuck Musciano) (03/29/91)

In article <971@elan.Elan.COM>, tom@elan.Elan.COM (Thomas Smith) writes:
> [ several good arguments for delaying creation of dialog boxes ]

     I agree with Thomas Smith, and have always delayed dialog creation to
make tools start faster.  Using Guide, I always have the same harness to
being up a dialog box:

static	dialog_objects	*dialog = NULL;

Menu_item	edit_filters(item, op)

Menu_item	item;
Menu_generate	op;

{
	if (op == MENU_NOTIFY) {
	   xv_set(base_frame, FRAME_BUSY, TRUE, NULL);
	   if (dialog == NULL) {
	      dialog = dialog_objects_initialize(NULL, base_frame);
	      place_dialog(base_frame, dialog->sub_frame);
	      /* one time only initialization here */
	      }
	   if (xv_get(dialog->sub_frame, XV_SHOW) == FALSE) {
	      update_dialog_values();
	      }
	   xv_set(dialog->sub_frame, XV_SHOW, TRUE, NULL);
	   xv_set(contool_base->base, FRAME_BUSY, FALSE, NULL);
	   }
	return item;
}

     This works for all cases: the first time the user presses the button or
picks the menu entry, the routine creates the dialog using the Guide-
generated initialize routine and performs one-time-only tweaking of the
window.  It also calls my place_dialog() routine, which puts the dialog
in a logical place with respect to the base frame.  On subsequent calls,
the window is either simply redisplayed (if it is mapped but obscured) or
reinitialized and reopened (if it is not mapped).  The update_dialog_values()
is the same routine bound to the reset button, which every dialog should
have.  I also make the base frame go busy to clue the user that some time
is being taken to make things right.

     I like this approach because I get minimal startup time, nice handling
and placement of dialogs, and consistent behavior: when you press a button
or pick a menu item, that dialog will either be opened or moved to the
front of any obscuring windows.  Makes for a nice, orthogonal interface.

-- 

Chuck Musciano				ARPA  : chuck@trantor.harris-atd.com
Harris Corporation 			Usenet: ...!uunet!x102a!trantor!chuck
PO Box 37, MS 3A/1912			AT&T  : (407) 727-6131
Melbourne, FL 32902			FAX   : (407) 729-3363

A good newspaper is never good enough,
	but a lousy newspaper is a joy forever.		-- Garrison Keillor

monardo@cshl.org (Pat Monardo) (04/02/91)

In article <1552@west.West.Sun.COM> lwake@runcible.West.Sun.COM (Larry Wake) writes:
>In article <7207@ecs.soton.ac.uk> mrd@ecs.soton.ac.uk (Mark Dobie) writes:
>>In <1991Mar13.193948.16328@sol.UVic.CA> awatkins@lager.UVic.CA
>(Andrew Watkins) writes:
>>>iI have a bunch of popup window (~7) and
>>>I'm adding more all the time. At present I create all of my windows
>>>when the program starts up and set the visibility off for all the
>>>windows I'm not using. Is this bad form? Should I create my windows as
>>>they are needed and destroy them when I'm done or does it really
>>>matter?
>>
>
>In the manual "XView Version 2 Reference Manual: Converting SunView
>Applications," Appendix B ("Performance Hints") says:
>
>    "As a rule, create resources such as pop-ups only at the time they are
>     required."
>
>If you think about it, this makes a lot of sense.  For example, in an
>application I'm writing there are nine windows, including the main
>window, with more possibly to come.  However, I figure the average user
>will use four of those with any frequency; the other four they may never
>use.
>
these are canvases (i assume). i use a configurable canvas array
and i create and destroy canvases on demand.
but i create a few panels at startup time which are command frames.
the panels are a bit tedious to build, so building them once
seemed reasonable to me (but i guess reason may not always the best guide).
so the rule seems to me to a bit vague. some questions i have
are: What is a pop-up? Does the size of the application matter?

lwake@runcible.West.Sun.COM (Larry Wake) (04/02/91)

>In article <1552@west.West.Sun.COM> I wrote:
>>    "As a rule, create resources such as pop-ups only at the time they are
>>     required."
>>
>>If you think about it, this makes a lot of sense.  For example, in an
>>application I'm writing there are nine windows, including the main
>>window, with more possibly to come.  However, I figure the average user
>>will use four of those with any frequency; the other four they may never
>>use.
>>

And in article <1991Apr1.200322.12740@cshl.org> monardo@cshl.org
(Pat Monardo) replies:
>these are canvases (i assume).

Nope, panels.

>... the rule seems to me to a bit vague. some questions i have
>are: What is a pop-up?

In this context, I've been using it as "any window that's not the base
window" (this is how devGuide uses the term, too), but it could cover
menus and such as well.

>Does the size of the application matter?

That depends.  As someone before me said, "good programming practice
scales."  Or something like that.  I think it's always a good idea not
to commit resources until they're used, since it's possible they might
never be needed at all.  In the case of my application, I see the two
choices as being:

	Create main window
	Create eight pop-up windows, but don't show them
	enter main event loop
	    (handle events; update and show windows as needed)

versus

	Create main window
	enter main event loop
	    (handle events; create, update and show windows as needed)

To me, the latter style is very natural, easy to write, and doesn't use
up resources that may never be called on.  It also gets us to the main
event loop that much faster, making your application feel faster to the
user.  Unless you're keeping some kind of application-related state in
your pop-up window structures, I don't see much of a downside to doing
it this way.
--
Larry Wake, Sun Microsystems (larry.wake@west.sun.com)
"Father McGrath!  I thought you were dead!"  "I was!"

andrew@resam.dk (Leif Andrew Rump) (04/10/91)

The problem with not having created the popup windows when the base window
is created is that the programmer must keep track on the states (inactive/
changed labels/...) on all the buttons/text fields/... It is manageable
but I'm quite sure that a OOP (C++ (God forbid)) could solve the problem.
- but why should we keep track on something the window system is fully
capable of handling? OK, OpenWindows is currently implemented in C using
OOP techniques so even the smallest instance use the full scale structure
(I haven't checked this but that is what I have been told) so the memory
usage is rather heavy but keeping the information twice sure doesn't help!

I'm interested in knowing if anybody out there has a description form that
keeps tracks on: which buttons/text fields/... change state on what action
and do changes to all the windows created even though they may be hidden!

I'll rather sacrifice some memory & speed for easy programming!


Leif Andrew


Leif Andrew Rump, AmbraSoft A/S, Stroedamvej 50, DK-2100 Copenhagen OE, Denmark
UUCP: andrew@ambra.dk, phone: +45 39 27 11 77                /
Currently at Scandinavian Airline Systems                =======/
UUCP: andrew@resam.dk, phone: +45 32 32 51 54                \
SAS, RESAM Project Office, CPHML-V, P.O.BOX 150, DK-2770 Kastrup, Denmark

		If it's broke, fix it (The MS-DOS way)
	    If it aint broke, don't touch it (The Unix way)
	     If you can't fix it, fuck it (The U-boat way)