[comp.sys.amiga] S/W Installation methodology

kim@uts.amdahl.com (Kim DeVaughn) (12/20/88)

[ "All sweet things have one thing in common ... a tendency to make you sick." ]
[                                    --Soolin                                  ]

Posted for a co-worker ...

On S/W installation methodology, Mike Robinson writes:
 
As  I  read  the   discussion  about  complicated  software  installation
procedures and how  to simplify them, I  would love to say  "Write a REXX
program to do it." That's how it's done in the VM/CMS world, where nearly
every vendor's installation sequence boils down to "Unload the first file
from this tape and run it."
 
In order for this sort of thing to happen in the Amiga community, we must
be able to PRESUME that Rexx will be available on the computer.  For this
to be  true, Commodore must license  REXX and supply it  with every Amiga
sold -- i.e. with AmigaDos 1.4.
 
I strongly believe that  this should be done. (And I  won't be any richer
because of it.)
 
/mr/


-- 
UUCP:  kim@amdahl.amdahl.com
  or:  {sun,decwrl,hplabs,pyramid,uunet,oliveb,ames}!amdahl!kim
DDD:   408-746-8462
USPS:  Amdahl Corp.  M/S 249,  1250 E. Arques Av,  Sunnyvale, CA 94086
BIX:   kdevaughn     GEnie:   K.DEVAUGHN     CIS:   76535,25

peter@sugar.uu.net (Peter da Silva) (12/20/88)

In article <e2f5Q6cTQG1010Yogos@amdahl.uts.amdahl.com>, kim@uts.amdahl.com (Kim DeVaughn) writes:
> As  I  read  the   discussion  about  complicated  software  installation
> procedures and how  to simplify them, I  would love to say  "Write a REXX
> program to do it." That's how it's done in the VM/CMS world, where nearly
> every vendor's installation sequence boils down to "Unload the first file
> from this tape and run it."

Why do you need REXX to do this? Just because REXX is the preferred batch
language on VM/CMS, doesn't mean it's the preferred batch language on the
Amiga. There's the existing "Execute" program.

Besides, we're not talking about how to get a program run. You can always
just write an install program. The discussion centers on just what that
program should *do*.

Me, I think that you should just copy the files to the hard disk and run the
program. Let the program ask you questions to finish the installation if it
hasn't been done the first time you run it.
-- 
Peter "Have you hugged your wolf today" da Silva  `-_-'  peter@sugar.uu.net

andy@cbmvax.UUCP (Andy Finkel) (12/21/88)

In article <e2f5Q6cTQG1010Yogos@amdahl.uts.amdahl.com> kim@uts.amdahl.com (Kim DeVaughn) writes:
>procedures and how  to simplify them, I  would love to say  "Write a REXX
>program to do it." That's how it's done in the VM/CMS world, where nearly
>every vendor's installation sequence boils down to "Unload the first file
>from this tape and run it."
> 
>In order for this sort of thing to happen in the Amiga community, we must
>be able to PRESUME that Rexx will be available on the computer.  For this
>to be  true, Commodore must license  REXX and supply it  with every Amiga
>sold -- i.e. with AmigaDos 1.4.

Not quite.  A specific language isn't the problem or the issue here.
At the moment, a vendor could write an installation program
in a compiled language (ie C or M2), a shell script, even
AmigaBasic.  The availability of Arexx doesn't have much to do
with the problem at hand.

The problem, of course, being how can a vendor best write an
installation procedure that addresses the *already* customized
installations that his/her potential customers are using ?

A language has nothing to say about this problem.  Even when we
start talking about languages designed to install programs, we're
not talking about complete solutions.

For instance, I keep my C: directory completely standard.  (It helps
in updates)  I keep other executables in Tools: or Bin:   How
can an installation program take account of this particular
preference, not to mention all the other strange configurations
other people may have ?  :-)

I do sysadmin on the Sun network here.  When I get a software
update, or a new program, I prefer getting shell scripts for
installation.  Not to run, though, since its really unlikely
that the configuration the person designing the script had matches
my current configuration.  No, I read through the script a couple
times until I figure out what its trying to do and where it
wants to put everything, then I turn on the script facility
(like hardcopy on the Amiga, for use if something goes
horribly wrong ) and do it all by hand.  It generally comes out better
that way.

(All right, I admit if a script is really customizable, ie through a Makefile,
I sometimes use it.  Never blindly, though :-))

> 
>I strongly believe that  this should be done. (And I  won't be any richer
>because of it.)
>UUCP:  kim@amdahl.amdahl.com

Entirely separate question.  While this may be a good answer to a question
(and personally, I think Arexx would be a nice thing to have) its
not the answer to the current question.

Anyway, we've made a couple attempts in a couple of our products
for installation procedures (in the 2090 hard disk software,
it was a script, in the Bridge card software it was a program).
I know we don't have a finally answer.

There are at least 2 problems...installing software in the right places
on a particular system configuration, and referencing all resources
that come with the program in a configuration independent manner.

		andy
-- 
andy finkel		{uunet|rutgers|amiga}!cbmvax!andy
Commodore-Amiga, Inc.

"Possibly this is a new usage of the word 'compatible' with which
 I was previously unfamiliar"

Any expressed opinions are mine; but feel free to share.
I disclaim all responsibilities, all shapes, all sizes, all colors.

papa@pollux.usc.edu (Marco Papa) (12/21/88)

In article <5540@cbmvax.UUCP> andy@cbmvax.UUCP (Andy Finkel) writes:
>Anyway, we've made a couple attempts in a couple of our products
>for installation procedures (in the 2090 hard disk software,
>it was a script, in the Bridge card software it was a program).
>I know we don't have a finally answer.

The installation disk for the A2090 is what I used as a basis of the A-Talk 
III Installation Disk [I even used the same icons]. It uses XICON and it
was very instructive for me [I didn't even use all the features that it 
uses]. I think it is a good start for anybody that wants to build an HD 
Installation disk for any tool. Not "the final answer", but so far it is the
best installation disk I have seen.

-- Marco Papa 'Doc'
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
uucp:...!pollux!papa       BIX:papa       ARPAnet:pollux!papa@oberon.usc.edu
 "There's Alpha, Beta, Gamma and Diga!" -- Leo Schwab [quoting Rick Unland]
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

lphillips@lpami.wimsey.bc.ca (Larry Phillips) (12/21/88)

In <3128@sugar.uu.net>, peter@sugar.uu.net (Peter da Silva) writes:
>> As  I  read  the   discussion  about  complicated  software  installation
>> procedures and how  to simplify them, I  would love to say  "Write a REXX
>> program to do it." That's how it's done in the VM/CMS world, where nearly
>> every vendor's installation sequence boils down to "Unload the first file
>> from this tape and run it."
> 
> Why do you need REXX to do this? Just because REXX is the preferred batch
> language on VM/CMS, doesn't mean it's the preferred batch language on the
> Amiga. There's the existing "Execute" program.

	Well, why not? Ever try to manipulate any file data with an 'Execute'
script? Ever try to parse user input with an 'Execute' script? If scripts are
going to be anything more than the simplest sort of thing, a more powerful
script language is needed. ARexx is here now with that power. Nothing else
comes close.
 
> Besides, we're not talking about how to get a program run. You can always
> just write an install program. The discussion centers on just what that
> program should *do*.

	Right.

> Me, I think that you should just copy the files to the hard disk and run the
> program. Let the program ask you questions to finish the installation if it
> hasn't been done the first time you run it.

	I agree. It seems that everyone wants the WB to somehw magically handle
everything, but without overhead. Some things are best known by the author of
the software.

--
"Intelligent CPU?  I thought you said Intel CPU!" 
        -Anonymous IBM designer-
+----------------------------------------------------------------------+ 
|   //   Larry Phillips                                                |
| \X/    lphillips@lpami.wimsey.bc.ca or uunet!van-bc!lpami!lphillips  |
|        COMPUSERVE: 76703,4322                                        |
+----------------------------------------------------------------------+

pds@quintus.uucp (Peter Schachte) (12/22/88)

In article <3128@sugar.uu.net> peter@sugar.uu.net (Peter da Silva) writes:
[about software installation]
>The discussion centers on just what that [installation] program should *do*.
>
>Me, I think that you should just copy the files to the hard disk and run the
>program. Let the program ask you questions to finish the installation if it
>hasn't been done the first time you run it.

This sounds like a good principle, but you still haven't said what
installation should *do*.

RECAP:
Matt Dillon and I independantly sugggested a (blessed by Commodore) script
file that is executed from your startup-sequence.  Someone else (sorry,
I forget who) suggested a directory all of whose files would be
executed from your startup-sequence.  I kind of like the second better,
because installation and deinstallation are easier, but it requires
some new standard software, which the first approach doesn't.  

NEW PROPOSAL:
Implement a global *persistent* ASSIGN, SETENV, and MOUNT (any others?)
in addition to the current ephemeral versions.  So when an application
installs itself, all it has to do is make the ASSIGNs, SETENVs, and
MOUNTs it needs, using the persistent versions.

One way to do this would be with a command PERSISTENT that takes an
ASSIGN, SETENV, or MOUNT command on the command line, executes the
command, and then puts the line in a S:PERSISTENT-STARTUP script (which
is executed from your startup-sequence).  Of course, it first removes
the line it should replace, if there is one.  This should be trivial to
implement, aside from the issue of trying to Execute() BCPL programs.
-Peter Schachte
pds@quintus.uucp
..!sun!quintus!pds

peter@sugar.uu.net (Peter da Silva) (12/24/88)

In article <896@quintus.UUCP>, pds@quintus.uucp (Peter Schachte) writes:
> This sounds like a good principle, but you still haven't said what
> installation should *do*.

It should put the names of the various files and directories in a file in
s: (if text). The name of this file should be chosen to avoid conflicts, but
it should be otherwise unrestricted. I would suggest '*.configuration', where
* is the name of the program. Then it should tell the user what it's done so
they can copy it to a more appropriate place (like, df0:s) if s: is in a RAM
disk.

If the file does not exist, the installation should be run again.
-- 
Peter "Have you hugged your wolf today" da Silva  `-_-'  peter@sugar.uu.net

peter@sugar.uu.net (Peter da Silva) (12/24/88)

In article <2048@van-bc.UUCP>, lphillips@lpami.wimsey.bc.ca (Larry Phillips) writes:
> 	Well, why not? Ever try to manipulate any file data with an 'Execute'
> script? Ever try to parse user input with an 'Execute' script? If scripts are
> going to be anything more than the simplest sort of thing, a more powerful
> script language is needed. ARexx is here now with that power. Nothing else
> comes close.

Well, any of the compiled languages can do a decent job of software
installation. And Execute can be enhanced with the various PD versions of
UNIX utilities, just as the UNIX shell is. If you need an interpreter, there's
one that comes with every Amiga... AmigaBasic. Then there are things like
Forth, XLISP, Little Smalltalk, and so on. And how about MicroEmacs, another
interpreter shipped with every box...?

Not to knock REXX, but saying "nothing else comes close" is a bit excessive.
-- 
Peter "Have you hugged your wolf today" da Silva  `-_-'  peter@sugar.uu.net

lphillips@lpami.wimsey.bc.ca (Larry Phillips) (12/25/88)

In <3147@sugar.uu.net>, peter@sugar.uu.net (Peter da Silva) writes:
> Well, any of the compiled languages can do a decent job of software
> installation. And Execute can be enhanced with the various PD versions of
> UNIX utilities, just as the UNIX shell is. If you need an interpreter, there's
> one that comes with every Amiga... AmigaBasic. Then there are things like
> Forth, XLISP, Little Smalltalk, and so on. And how about MicroEmacs, another
> interpreter shipped with every box...?

	Yes, compiled languages can indeed do a good job of software installation,
until there is an exception somewhere, on someone's machine. Perhaps a name
conflict or a non-standard setup for what may be perfectly valid reasons. An
interpreted language allows far more people to make changes to suit their own
environment.

	Unix-like utilities are fine, but take up space on the disk the software
comes on, or must be provided on the WB or extras disk. Of course in order for
them to be used in this way, they must truly be PD, and not just freely
distributable, or the author's permission must be obtained. That's a lot of
authors to contact and the answer may not always be an unqualified yes.

	Amigabasic is a joke. Ever try running it on an '020? I hope Bill Gates is
thoroughly ashamed to be associated with it.

	The others you mention are large programs, taking up space on the software
distribution disk. What is really needed is the equivalent of the native
interpreted 'execute', only with more power.
 
> Not to knock REXX, but saying "nothing else comes close" is a bit excessive.

	I stand by what I said about nothing else coming close, given the
alternatives available today.

-larry

--
"Intelligent CPU?  I thought you said Intel CPU!" 
        -Anonymous IBM designer-
+----------------------------------------------------------------------+ 
|   //   Larry Phillips                                                |
| \X/    lphillips@lpami.wimsey.bc.ca or uunet!van-bc!lpami!lphillips  |
|        COMPUSERVE: 76703,4322                                        |
+----------------------------------------------------------------------+

jdow@gryphon.COM (J. Dow) (12/26/88)

In article <2064@van-bc.UUCP> lphillips@lpami.wimsey.bc.ca (Larry Phillips) writes:
>In <3147@sugar.uu.net>, peter@sugar.uu.net (Peter da Silva) writes:
>
>	Amigabasic is a joke. Ever try running it on an '020? I hope Bill Gates is
>thoroughly ashamed to be associated with it.
>
Er - what is your problem running AmigaBasic with an 020? It runs here and at
Jerry's house with the one line patch Carolyn mentioned on bix... Go to offset
$0000F384 in the load file for AmigaBASIC. Original has $20327900. Change that
to $20327800 and run.

On another paw - though - AmigaBASIC is perhaps a bit <cough> improvable for
other reasons...

-- 
Sometimes a bird in the hand leaves a sticky deposit.
Perhaps it were best it remain there in the bush with the other one.

{@_@}
	jdow@bix (where else?)		Sometimes the dragon wins. Sometimes
	jdow@gryphon.CTS.COM		the knight. Does the fair maiden ever
	{backbone}!gryphon!jdow		win? Surely both the knight and dragon
					stink. Maybe the maiden should suicide?
					Better yet - she should get an Amiga and
					quit playing with dragons and knights.

peter@sugar.uu.net (Peter da Silva) (12/27/88)

In article <2064@van-bc.UUCP>, lphillips@lpami.wimsey.bc.ca (Larry Phillips) writes:
> 	Unix-like utilities are fine, but take up space on the disk the software
> comes on, or must be provided on the WB or extras disk. Of course in order for
> them to be used in this way, they must truly be PD, and not just freely
> distributable, or the author's permission must be obtained. That's a lot of
> authors to contact and the answer may not always be an unqualified yes.

All of which applies to REXX as well. Besides, there is a large pool of
completely PD software designed to run in VERY small environments, the
Software Tools Virtual Operating System tape. Yes, it's all in RATFOR, but
converting it to 'C' could be done by a competant set of editor macros.

I said:
> > Not to knock REXX, but saying "nothing else comes close" is a bit excessive.

> 	I stand by what I said about nothing else coming close, given the
> alternatives available today.

And since REXX has the same disadvantages as the alternatives, I stand by
what I said. REXX is great, but for the job we're talking about it's not a
whole lot better than the alternatives.
-- 
Peter "Have you hugged your wolf today" da Silva  `-_-'  peter@sugar.uu.net

lphillips@lpami.wimsey.bc.ca (Larry Phillips) (12/28/88)

In <10009@gryphon.COM>, jdow@gryphon.COM (J. Dow) writes:
> Er - what is your problem running AmigaBasic with an 020? It runs here and at
> Jerry's house with the one line patch Carolyn mentioned on bix... Go to offset
> $0000F384 in the load file for AmigaBASIC. Original has $20327900. Change that
> to $20327800 and run.

	Well, I guess that will solve the 'not running on the 020' problem. Thanks
for the tip. I'll pass it on to the part of the world that doesn't frequent
Bix. :-)
 
> On another paw - though - AmigaBASIC is perhaps a bit <cough> improvable for
> other reasons...

	How very er... tactful of you. :-)

Have a great New Year!

-larry

--
"Intelligent CPU?  I thought you said Intel CPU!" 
        -Anonymous IBM designer-
+----------------------------------------------------------------------+ 
|   //   Larry Phillips                                                |
| \X/    lphillips@lpami.wimsey.bc.ca or uunet!van-bc!lpami!lphillips  |
|        COMPUSERVE: 76703,4322                                        |
+----------------------------------------------------------------------+

kim@uts.amdahl.com (Kim DeVaughn) (01/05/89)

[ ... ]

I'm posting the following for Mike Robinson, WRT s/w installation:
 
/kim
 
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
 
  Here is a clarification that you might wish to post to the net for me.
   
  - - - -
   
  Let me clarify and expand upon my previous append:
   
   
  Software  that  requires  a   complicated  install  procedure  should  be
  accompanied by a program that carries out that procedure.  It should make
  assumptions that  are true for  most "vanilla" installations.   But since
  not  all installations  are "vanilla,"  as Andy  Finkel pointed  out, the
  install procedure should be some sort  of a script, which can be modified
  at will by those who need to do so, or simply printed off and followed by
  hand, again by those who need to do so.
   
   
  This  is  a  logical  application  for REXX,  because  it  is  much  more
  expressive than EXECUTE and Because It Is There.
                              ======= == == =====
   
   
  REXX has made  an enormous impact on the VM/CMS  community.  But I hasten
  to point out that this impact would  not have occurred if REXX had been a
  separately licensed program product.  It  is bundled with every operating
  system, so every user has it.  That is a critical element in its success;
  otherwise, its power would be wasted.
   
   
  Simple corollary?  (You knew  it was  coming.)  Hypercard.  Nice program.
  Clever idea.  Some would say innovative.   Maybe so.  But what we CAN say
  about  it right  now is  that it  WILL have  an impact  on the  Macintosh
  community, no matter how good or bad  it is.  Two reasons: it has Apple's
  official sanction, and BECAUSE IT IS THERE.  Since application developers
  know that the software has been bundled with Release X.X of the Macintosh
  system, they will  begin to write programs that  install themselves using
  Hypercard scripts,  and they will  begin to write programs  that actually
  incorporate Hypercard as part of  their functionality.  Leverage, my dear
  Watson.  Leverage!!
   
   
  No, no.   Hypercard is  not REXX,  and REXX is  not Hypercard.   But they
  share    a   common    trait:   they    are   an    externally-developed,
  generally-available  piece  of  software   that  amplifies  the  existing
  functionality of  other tools  that are  able to  coexist with  them, and
  which reduces  the cost of  developing programs that use  their features.
  And for one of the products at  least, a large part of its impact BECAUSE
  IT IS THERE!
   
   
  We're hobbling  along with  Amiga BASIC and  EXECUTE scripts  because C-A
  officially supports  and supplies  them.  Meanwhile, Macintosh  users are
  using  MacPaint  and  MacDraw  and  Hypercard  because  Apple  officially
  supports and supplies them.  There is another corollary here...
   
   
  I am NOT  criticizing Commodore-Amiga or comparing  the Amiga unfavorably
  with the Macintosh.  This is a constructive suggestion for something that
  I believe would make the Amiga a  better computer than it already is, and
  do so at a minimum cost.  Thank you for your time and attention.
   
  /mr/
   
   
------------------------  Mike further writes  ---------------------------
   
   
  In hope of not overtaxing your offer to post to the network, consider one
  more short one:
   
  ----------
   
  I want to see programs and subroutines coming out on Fish disks to help
  me write Amiga programs more easily.  For example, think about how much
  work you have to go through to create menus and dialog boxes in
  Intuition.  I come not to bury Caesar, but there are better ways to
  approach this than to code all those data structures by hand.  Just
  *look* at the "SpeechToy" program on the Lattice compiler disks! All
  necessary, yes, but what a mess! How many times did the author recompile
  that thing, "diddling" with it until it finally looked right?
   
   
  How about a program that will allow you to construct a menu, or a dialog
  box, or a control panel... interactively? Take a look at this month's DR.
  DOBB'S for inspiration.  You design the control panel the way you want
  it, and presto! Out comes "C" source code, or even an object file, to do
  what you want.  It could save days.
   
   
  (If an interactive program is too ambitious, then a simpler design which
  uses a flat file prepared with a text editor would a good alternative.)
   
   
  Instead of coding all those menu statements by hand, how about this?
   
    MAKEMENU(WINDOW,"\001Project\002About...\002Quit\001File\002Open")
   
  This subroutine would read the string, and build standard control blocks
  in memory at runtime.  Otherwise they would be a black box.
   
   
  You get the idea.  Arguably, these convenience tools would not do
  anything that you could not do by hand, nor everything that you might
  want to do.  But that is the case with any compiler, and we do not
  question the usefulness of those.  They would give us a head start in
  writing "most" "typical" applications, and that is enough.

  /mr/

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

-- 
UUCP:  kim@amdahl.amdahl.com
  or:  {sun,decwrl,hplabs,pyramid,uunet,oliveb,ames}!amdahl!kim
DDD:   408-746-8462
USPS:  Amdahl Corp.  M/S 249,  1250 E. Arques Av,  Sunnyvale, CA 94086
BIX:   kdevaughn     GEnie:   K.DEVAUGHN     CIS:   76535,25

shf@well.UUCP (Stuart H. Ferguson) (01/06/89)

+-- Mike Robinson writes:
|   I want to see programs and subroutines coming out on Fish disks to help
|   me write Amiga programs more easily.  For example, think about how much
|   work you have to go through to create menus and dialog boxes in
|   Intuition.  I come not to bury Caesar, but there are better ways to
|   approach this than to code all those data structures by hand.

Agreed.  I gave up on trying to hard-code Intuition structures long ago.

|   How about a program that will allow you to construct a menu, or a dialog
|   box, or a control panel... interactively?

There are some.  PowerWindowsII is the only one I've tried.  I don't use it
for two reasons:  1)  It's horribly under-documented.  The "manual" is a
tiny stapled together pamphlet like one you might get with your new toaster,
and the program clearly has features that are not even mentioned.  2)  There's
a bug which makes gadget hitboxes slightly smaller than their surrounding
borders so that the gadget has annoying little gaps when highlighted.  I do
use it for converting brushes to Images, however.

|   (If an interactive program is too ambitious, then a simpler design which
|   uses a flat file prepared with a text editor would a good alternative.)

This is what I did for designing all the Requesters in Modeler 3D.  I wrote
a simple "compiler" that takes a description of a requester layout and
generates code.  It also lets you preview the result in a little window.
Although interactive methods are nice, there are some advantages to the 
"flat file" method.  The "compiler" program can be called from a makefile,
so that the Requester description file becomes just like another source file
in your program.  Also, the description file contains almost no numbers,
so that the positions and sizes of things are computed relative to each other.
This means that if I ask for a gadget to be centered, I know it will be
exactly centered, rather than centered as well as I could guess using my
eye.  And, if I change other parts of the Requester, that gadget will *stay*
centered, even if it changes absolute position.

There's a version of my requester generater on some Fish disk (shame on me,
I can't remember the number -- 130-something?) with some examples.  I have
a newer version which supports a full "C"-style pre-processor (which the
old one sorely needs).  The new one has the added advantage that I can
create macros for commonly used structures -- something that few 
interactive construction sets will let you do.

|   Instead of coding all those menu statements by hand, how about this?
|    
|     MAKEMENU(WINDOW,"\001Project\002About...\002Quit\001File\002Open")
|    
|   This subroutine would read the string, and build standard control blocks
|   in memory at runtime.  Otherwise they would be a black box.

I did something like this for the menus in Modeler as well.  The structures
constructed by the programmer are more complex than the above, but not much,
and the menus are constructed at run-time.  I needed this for Modeler since
it can have multiple copies of the same class of window, and each needs its
own copy of the menu structure so that the checkmark items can be different
for each window.  Another advantage to the run-time construction is that
the menus can adapt to different sized fonts, screen resolutions, etc.

I'm currently stripping that section out of the Modeler code and packaging
it up as a general tool.  Once I can work out the tricker details I ignored
before, I'll send it to Fred and perhaps the "sources" group.

|   You get the idea.  Arguably, these convenience tools would not do
|   anything that you could not do by hand, nor everything that you might
|   want to do.  But that is the case with any compiler, and we do not
|   question the usefulness of those.  They would give us a head start in
|   writing "most" "typical" applications, and that is enough.

Yes, tools are a wonderful thing.  You almost never have "too many" tools.
-- 
		Stuart Ferguson		(shf@well.UUCP)
		Action by HAVOC

peter@sugar.uu.net (Peter da Silva) (01/06/89)

Here's a quick-and-dirty menu routine, taken from Browser. I use it like so:

	open_id = add_menu("Browser", "Open", 0, 0);
	close_id = add_menu("Browser", "Close", 0, 0);
	quit_id = add_menu("Browser", "Quit", 0, 0);

You can't delete menu items, or do any number of related manipulations. But
for simple jobs it's easy as 3.14159...

echo x - menu.c
sed 's/^X//' > menu.c << '//END'
X/* easy menus: Copyright 1987 Peter da Silva, all rights reserved.
X *
X *	Permission is granted to use this in any application, so long as
X *	this notice is retained in the source. Permission is granted to
X *	modify the code as you like, so long as this notice (between the
X *	first line beginning "easy menus" and the end of this paragraph,
X *	inclusive) is retained intact.
X *
X * Usage:
X *
X *	#include "menu.h"
X *
X *	struct MenuPtr menudata;
X *	struct MenuPtr *menuptr = &menudata;
X *
X *	init_menus(menuptr);	/ * Just zero menu pointer out * /
X *
X *	for(each menu item) {
X *		add_menu(menuptr, menu, item, subitem, flags);
X *	}
X *
X *  Flags:
X *    SUBITEM_NOCHECK	-- subitem does not require a checkmark.
X *    SUBITEM_SELECTOR	-- subitem is a 1 of n selector, use mutual-exclude.
X *    SUBITEM_TOGGLE	-- subitem is a toggled flag.
X *    SUBITEM_SELECTED	-- defaults to checked.
X *
X *
X *	SetMenuStrip(yourwindow, menuptr->MenuBar);
X *
X *	...
X *
X *	ClearMenuStrip(yourwindow);
X *
X *	trash_menus(menuptr);
X *
X * Notes:
X *
X *	if you don't want any subitems, use zero for the subitem value.
X *
X *	subitem is always initialised as a CHECKIT item with all the other
X *	subitems mutually excluded.
X *
X *	it is intended that the menu be set up with all action items in
X *	the first level of the menu, and all toggles in the second level...
X *	this is a piece of blatant authoritarianism on my part. I've seen
X *	too many menus with no rhyme or reason. Look at AmigaTerm (the term
X *	program that comes with the Amiga modem) some time. Baud rate has
X *	an item all by itself, but word size is hidden off in a menu with
X *	things like bell sound.
X *
X *	the appearance of the menus produced by this is (in my humble
X *	opinion) good. I took some care making text centered in menu boxes,
X *	for example.
X */
X#include <exec/memory.h>
X#include <intuition/intuition.h>
X#include "menu.h"
X#include "fonts.h"
X
X/*
Xstruct MenuPtr {
X	struct Menu *MenuBar;
X	struct Remember *MenuMemory;
X};
X*/
X
Xchar *AllocRemember();
X
Xstatic struct Menu *new_menu();
Xstatic struct MenuItem *new_item(), *new_subitem();
X
X#define TOMENUNUM(i,j,k) (SHIFTMENU(i)|SHIFTITEM(j)|SHIFTSUB(k))
X#define TextLen(s) (strlen(s)*FONTWIDTH)
X
Xtrash_menus(menuptr)
Xstruct MenuPtr *menuptr;
X{
X	FreeRemember(&menuptr->MenuMemory, 1);
X	menuptr->MenuMemory = 0;
X	menuptr->MenuBar = 0;
X}
X
Xinit_menus(menuptr)
Xstruct MenuPtr *menuptr;
X{
X	menuptr->MenuMemory = 0;
X	menuptr->MenuBar = 0;
X}
X
Xint add_menu(menuptr, menuname, itemname, subitemname, flags)
Xstruct MenuPtr *menuptr;
Xchar *menuname, *itemname, *subitemname;
Xlong flags;
X{
X	int i, j, k;
X	struct Menu *menu;
X	struct MenuItem *item;
X	struct MenuItem *subitem;
X
X	if(menuptr->MenuBar) {
X		for(i = 0, menu = menuptr->MenuBar;
X		    menu;
X			menu = menu->NextMenu, i++
X		   )
X			if(strcmp(menuname, menu->MenuName)==0)
X				break;
X		if(!menu)
X			menu = new_menu(menuptr, menuname);
X		if(!menu)
X			return MENUNULL;
X	} else {
X		i = 0;
X		menu = new_menu(menuptr, menuname);
X		if(!menu)
X			return MENUNULL;
X	}
X	for(j = 0, item = menu->FirstItem;
X		item;
X		item = item->NextItem, j++
X	   ) {
X		struct IntuiText *text;
X		text = (struct IntuiText *)item->ItemFill;
X		if(strcmp(itemname, text->IText) == 0)
X			break;
X	}
X	if(subitemname) {
X		if(!item)
X			item = new_item(menuptr, menu, itemname);
X		if(!item)
X			return MENUNULL;
X		for(k = 0, subitem = item->SubItem;
X			subitem;
X			subitem = subitem->NextItem, k++
X		   ) {
X			struct IntuiText *text;
X			text = (struct IntuiText *)subitem->ItemFill;
X			if(strcmp(subitemname, text->IText) == 0)
X				break;
X		}
X		if(!subitem)
X			subitem = new_subitem(menuptr, item, subitemname, flags);
X		if(!subitem)
X			return MENUNULL;
X		return TOMENUNUM(i, j, k);
X	} else {
X		if(!item)
X			item = new_item(menuptr, menu, itemname);
X		if(!item)
X			return MENUNULL;
X		return TOMENUNUM(i, j, NOSUB);
X	}
X}
X
Xstatic struct Menu *
Xnew_menu(menuptr, name)
Xstruct MenuPtr *menuptr;
Xchar *name;
X{
X	struct Menu *menu;
X
X	menu = (struct Menu *)AllocRemember(
X		&menuptr->MenuMemory,
X		sizeof(struct Menu),
X		MEMF_PUBLIC);
X	if(!menu)
X		return 0;
X	menu->NextMenu = NULL;
X	menu->LeftEdge = 0;
X	menu->TopEdge = 0;
X	menu->Width = TextLen(name)+FONTWIDTH;
X	menu->Height = 0;
X	menu->Flags = MENUENABLED;
X	menu->MenuName = name;
X	menu->FirstItem = 0;
X	if(menuptr->MenuBar) {
X		struct Menu *ptr, *prev;
X		for(ptr = menuptr->MenuBar; ptr; ptr=ptr->NextMenu) {
X			menu->LeftEdge += ptr->Width;
X			prev = ptr;
X		}
X		prev->NextMenu = menu;
X	} else {
X		menuptr->MenuBar = menu;
X	}
X
X	return menu;
X}
X
Xstatic struct item *
Xnew_item(menuptr, menu, name)
Xstruct MenuPtr *menuptr;
Xchar *name;
Xstruct Menu *menu;
X{
X	struct MenuItem *item;
X	struct IntuiText *text;
X
X	item = (struct MenuItem *)AllocRemember(
X		&menuptr->MenuMemory,
X		sizeof(struct MenuItem),
X		MEMF_PUBLIC);
X	if(!item)
X		return 0;
X	text = (struct IntuiText *)AllocRemember(
X		&menuptr->MenuMemory,
X		sizeof(struct IntuiText),
X		MEMF_PUBLIC);
X	if(!text)
X		return 0;
X
X	text->FrontPen = AUTOFRONTPEN;
X	text->BackPen = AUTOBACKPEN;
X	text->DrawMode = JAM2;
X	text->LeftEdge = 1;
X	text->TopEdge = 1;
X	text->ITextFont = NULL;
X	text->IText = name;
X	text->NextText = NULL;
X
X	item->NextItem = NULL;
X	item->LeftEdge = 0;
X	item->TopEdge = 0;
X	item->Width = IntuiTextLength(text)+2;
X	if(item->Width <= menu->Width)
X		item->Width = menu->Width+1;
X	item->Height = FONTHEIGHT+1;
X	item->Flags = ITEMTEXT|HIGHCOMP|ITEMENABLED;
X	item->MutualExclude = 0;
X	item->ItemFill = text;
X	item->SelectFill = NULL;
X	item->Command = 0;
X	item->SubItem = NULL;
X	item->NextSelect = NULL;
X
X	if(menu->FirstItem) {
X		struct MenuItem *ptr, *prev;
X		for(ptr = menu->FirstItem; ptr; ptr=ptr->NextItem) {
X			if(item->Width > ptr->Width) {
X				if(ptr->SubItem)
X					nudge(ptr->SubItem, item->Width-ptr->Width);
X				ptr->Width = item->Width;
X			} else if(ptr->Width>item->Width)
X				item->Width = ptr->Width;
X			prev = ptr;
X		}
X		item->TopEdge = prev->TopEdge + prev->Height;
X		prev->NextItem = item;
X	} else {
X		menu->FirstItem = item;
X	}
X
X	return item;
X}
X
Xstatic nudge(item, delta)
Xstruct MenuItem *item;
Xint delta;
X{
X	while(item) {
X		item->LeftEdge += delta;
X		item = item->NextItem;
X	}
X}
X
Xstatic struct item *
Xnew_subitem(menuptr, item, name, flags)
Xstruct MenuPtr *menuptr;
Xchar *name;
Xstruct MenuItem *item;
Xlong flags;
X{
X	struct MenuItem *subitem;
X	struct IntuiText *text;
X
X	subitem = (struct MenuItem *)AllocRemember(
X		&menuptr->MenuMemory,
X		sizeof(struct MenuItem),
X		MEMF_PUBLIC);
X	if(!subitem)
X		return 0;
X	text = (struct IntuiText *)AllocRemember(
X		&menuptr->MenuMemory,
X		sizeof(struct IntuiText),
X		MEMF_PUBLIC);
X	if(!text)
X		return 0;
X
X	text->FrontPen = AUTOFRONTPEN;
X	text->BackPen = AUTOBACKPEN;
X	text->DrawMode = JAM2;
X	text->LeftEdge = CHECKWIDTH+1;
X	text->TopEdge = 1;
X	text->ITextFont = NULL;
X	text->IText = name;
X	text->NextText = NULL;
X
X	subitem->NextItem = NULL;
X	subitem->LeftEdge = item->Width;
X	subitem->TopEdge = 0;
X	subitem->Width = IntuiTextLength(text)+2;
X	if(flags != SUBITEM_NOCHECK) subitem->Width += CHECKWIDTH;
X	subitem->Height = FONTHEIGHT+1;
X	subitem->Flags = ITEMTEXT|ITEMENABLED|HIGHCOMP;
X	subitem->MutualExclude = 0;
X	if(flags != SUBITEM_NOCHECK) {
X		subitem->Flags |= CHECKIT;
X		if(flags & SUBITEM_TOGGLE) subitem->Flags |= MENUTOGGLE;
X		if(flags & SUBITEM_SELECTED) subitem->Flags |= CHECKED;
X	}
X	subitem->ItemFill = text;
X	subitem->SelectFill = NULL;
X	subitem->Command = 0;
X	subitem->SubItem = NULL;
X	subitem->NextSelect = NULL;
X
X	if(item->SubItem) {
X		struct MenuItem *ptr, *prev;
X		int i;
X		for(i=0, ptr = item->SubItem; ptr; i++, ptr=ptr->NextItem) {
X			if(subitem->Width > ptr->Width)
X				ptr->Width = subitem->Width;
X			else if(ptr->Width>subitem->Width)
X				subitem->Width = ptr->Width;
X			prev = ptr;
X		}
X		subitem->TopEdge = prev->TopEdge + prev->Height;
X		if(flags & SUBITEM_SELECTOR)
X			subitem->MutualExclude = ~(1<<i);
X		prev->NextItem = subitem;
X	} else {
X		item->SubItem = subitem;
X		if(flags & SUBITEM_SELECTOR)
X			subitem->MutualExclude = ~1;
X	}
X
X	return subitem;
X}
//END
echo x - fonts.h
sed 's/^X//' > fonts.h << '//END'
X#ifndef FONTS_H
X#define FONTS_H
X#ifndef GRAPHICS_GFXBASE_H
X#include <graphics/gfxbase.h>
X#endif
X#ifndef GRAPHICS_TEXT_H
X#include <graphics/text.h>
X#endif
X
Xextern struct GfxBase *GfxBase;
X
X#define FONTWIDTH (GfxBase->DefaultFont->tf_XSize)
X#define FONTHEIGHT (GfxBase->DefaultFont->tf_YSize)
X#define FONTBASELINE (GfxBase->DefaultFont->tf_Baseline)
X#endif
//END
echo x - menu.h
sed 's/^X//' > menu.h << '//END'
Xstruct MenuPtr {
X	struct Menu *MenuBar;
X	struct Remember *MenuMemory;
X	int next_id;
X};
X
X/* flags */
X#define SUBITEM_NOCHECK 	0x0 	/* subitem does not require a checkmark. */
X#define SUBITEM_SELECTOR	0x10	/* subitem is a 1 of n selector */
X#define SUBITEM_TOGGLE  	0x20	/* subitem is a toggled flag. */
X#define SUBITEM_SELECTED	0x01	/* defaults to checked. */
//END
-- 
Peter "Have you hugged your wolf today" da Silva  `-_-'  Hackercorp.
...texbell!sugar!peter, or peter@sugar.uu.net      'U`

karl@sugar.uu.net (Karl Lehenbauer) (01/07/89)

In article <10235@well.UUCP>, shf@well.UUCP (Stuart H. Ferguson) writes:
> There are some.  PowerWindowsII is the only one I've tried.  I don't use it
> for two reasons:  1)  It's horribly under-documented.  The "manual" is a
> tiny stapled together pamphlet like one you might get with your new toaster,
> and the program clearly has features that are not even mentioned.  ...

I have been using Power Windows II but it's a frustating go.  It will guru
if there are too many files in the directory.  Certain structures are
impossible to set up.  The user interface is smelly, and as Stuart said, the
manual stinks. 

On the other hand, it beats figuring it out by hand, makes prototyping easier, 
etc, and is sort of the direction we want to be heading in that we need tools
to automate prototyping and development of Intuition structures.
-- 
-- uunet!sugar!karl  | "We've been following your progress with considerable 
-- karl@sugar.uu.net |  interest, not to say contempt."  -- Zaphod Beeblebrox IV
-- Usenet BBS (713) 438-5018

mrr@amanpt1.zone1.com (Mark Rinfret) (01/11/89)

In article <3231@sugar.uu.net>, karl@sugar.uu.net (Karl Lehenbauer) writes:
> In article <10235@well.UUCP>, shf@well.UUCP (Stuart H. Ferguson) writes:
> > There are some.  PowerWindowsII is the only one I've tried.  I don't use it
> > for two reasons:  1)  It's horribly under-documented.  The "manual" is a
> > tiny stapled together pamphlet like one you might get with your new toaster,
> > and the program clearly has features that are not even mentioned.  ...
> 
> I have been using Power Windows II but it's a frustating go.  It will guru
> if there are too many files in the directory.  Certain structures are
> impossible to set up.  The user interface is smelly, and as Stuart said, the
> manual stinks. 
> 

I use PowerWindows 2.5b and have been, for the most part, quite satisfied with
it.  If you are using a purchased copy and have the original disk, just mail
it to Inovatronics for a FREE update.  I have gotten three such upgrades.
Inovatronics also has a BBS which is fairly active and Martin Murray (PW author)
routinely participates, having answered all of my questions and suggestions
promptly and courteously. My chief complaint with PowerWindows is that it
forces its own naming conventions on you.  There are several lower-level
structures, such as IntuiTexts, which I would like to name myself, rather
than "discovering" what PW named them.  I (and many others) have recommended
a change in this area, but it won't be coming soon.  If someone is looking for
a product idea, this is a good place to jump in.

Mark

-- 
< Mark R. Rinfret,  mrr@amanpt1.ZONE1.COM | ...rayssd!galaxia!amanpt1!mrr    >
< HyperView Systems Corp.               Home: 401-846-7639                   >
< 28 Jacome Way                         Work: 401-849-9390 x301              >
< Middletown, RI 02840                  Hypermedia R Us!                     >