From info-admin@newcastle.ac.uk  Mon Aug  3 10:10:06 1992
Received: from dfunms.rus.uni-stuttgart.de by helpdesk.rus.uni-stuttgart.de (5.52/BelWue-1.0SG(subsidiary))
	(for zrzm0111) id AA20429; Mon, 3 Aug 92 10:10:06 MST
Received: from mail.Germany.EU.net by dfunms.rus.uni-stuttgart.de with SMTP id AA29250
  (5.65c/DFUE-M1.0 for <joerg.scheurich@rus.uni-stuttgart.de>); Mon, 3 Aug 1992 10:07:46 +0200
Message-Id: <9208030808.AA04558@mail.Germany.EU.net>
Received: from ben.uknet.ac.uk 
	by mail.Germany.EU.net with SMTP (5.65+/UNIDO-2.1.0.b)
	via EUnet for rus.uni-stuttgart.de
	id AA04558; Mon, 3 Aug 92 10:08:08 +0200
Received: from eros.uknet.ac.uk by ben.uknet.ac.uk via UKIP with SMTP (PP) 
          id <g.08572-0@ben.uknet.ac.uk>; Mon, 3 Aug 1992 09:06:51 +0100
Received: from newcastle.ac.uk by eros.uknet.ac.uk via JANET with NIFTP (PP) 
          id <3079-1@eros.uknet.ac.uk>; Mon, 3 Aug 1992 09:06:42 +0100
Date: Mon, 3 Aug 1992 08:55:54 +0100
Original-Received: 
Pp-Warning: Illegal Received field on preceding line
From: The Newcastle Info-Server <info-admin@newcastle.ac.uk>
To: joerg.scheurich@rus.uni-stuttgart.de
Subject: Re: Request: sources; Topic: archimedes wimpapp2
Sender: info-admin@newcastle.ac.uk
Status: RO

Path: newcastle.ac.uk!uknet!mcsun!uunet!comp.vuw.ac.nz!waikato.ac.nz!aukuni.ac.nz!cs18.cs.aukuni.ac.nz!jwil1
>From: jwil1@cs.aukuni.ac.nz (TMOTA)
Newsgroups: comp.sources.acorn
Subject: Source (Arc, BASIC): Wimp example program
Message-ID: <1992Jul15.220305.1513@cs.aukuni.ac.nz>
Date: 15 Jul 92 22:03:05 GMT
Sender: jwil1@cs.aukuni.ac.nz (TMOTA)
Organization: Computer Science Dept. University of Auckland
Lines: 330
Approved: cba@acorn.co.nz

Submitted-by: Jason Williams <jwil1@cs.aukuni.ac.nz>

A while ago I gave a talk at the local Acorn club about writing WIMP
applications. The following is a very brief handout for the talk,
along with the example program I wrote.

(Note: The example program needs an application directory with !Sprites,
!Run, and Templates files... The binary of this application will be posted
on comp.binaries.acorn: This message is intended as read-only material!)

--->8---

This program is Freeware. Do what you like with it, so long as you don't
make any profit out of it.

This is a small application written as a sort of tutorial on WIMP
programming in BASIC. I have tried to keep it simple while getting
as far as the basic necessities for your average application.
I hope it will help you to learn the basics of WIMP programming.


Application directories
=======================

Application directory: Always a directory with a '!' as the first
character of its name. Open this up by holding down shift while
double-clicking the application icon.

Inside, there are usually the following files:
!Boot     A file that is run when the application is first "seen" by the
	  filer. Usually an Obey file.
!Run      A file that is run when the user double-clicks (runs) the
	  application. Usually an Obey file.
!Help     A file/application that is run when the user selects the 'help'
	  option from the filer menu. Usually a text file.
!Sprites  A Sprite file containing the sprites needed for the application.
	  Usually two mode-12 sprites, a 34x17 one (!appname), and a
	  smaller one (19x9) called sm!appname.
	  (Under RISC OS 3.xx, there are 2 additional files, !Sprites22,
	  which should contain sprites defined in mode 20 (34x34), and
	  !Sprites23, which should contain a 34x34 black and white sprite
	  defined in mode 23. These files are optional but recommended)
!RunImage The main program to be run when the application is run.
	  This will be run by the !Run file. (see below)
Templates A file defining the size and shape of the windows used by the
	  application. This can be edited with !FormEd, and is the
	  easiest way to create your window layouts. You can also edit the
	  window layouts for your other applications by editing their
	  Template files - but remember to keep a copy of the original    
	  templates just in case!

Obey Files
==========
These are files containing operating system '*' commands (much like a
BBC's EXEC text files, but the commands are not echoed to the screen
when the file is run). They can be edited (as text files)  by dragging
them to !Edit. Typical things to find in application Obey files are:
<Obey$Dir>
				  This expands to the application
				  directory's full pathname 
				  when the Obey file is run.
IconSprites <Obey$Dir>.!Sprites   Tell the WIMP to load the sprite file
				  !Sprites into the icon- sprite area.
				  (i.e. load your app's icons into memory)
WimpSlot -min 64k -max 128k       This tells the Wimp that you need a
				  minimum of 64 kilobytes, and a maximum
				  of 128 kilobytes of memory before you
				  can be run.
Run <Obey$Dir>.!RunImage          Run the program called !Runimage in
				  the same directory as the Obey file.

The BASIC !RunImage
===================
This is the actual application. The next page has an example application
!RunImage program in  BASIC, showing the basics that you need to get
started.


WIMP POLL result blocks
=======================
When we poll the WIMP, it returns events to us under the following
categories (and more):

0    Null (Nothing has happened - these are only received if the machine
     is idling)

1    A window needs redrawing (Only received if you have
     non-auto-redraw windows - this can be set in the Tempate editor)

2    A window needs (re)opening. (A window is being opened/moved/resized)

3    A window needs closing (the user has clicked it's close box)

6    Mouse button press/release

9    A menu item has been chosen (Can only happen after you have popped
     up a menu!)

17  A message from another task has arrived
18  A message from another task has arrived. An acknowledging message is
    expected if you are interested in the operation they request.

For our simple application, we are only interested in a few of the event
types returned. When we receive the event, the WIMP fills in extra
useful information about the event into the  block we give it. The
useful block contents for the various events we are interested in are as 
follows:

For OpenWindow and CloseWindow (result = 2, 3) events,
  block!0 = the window handle.
If we don't want to check anything before allowing the window to be
resized/closed/etc, then all we need to do is pass the block back to the
WIMP (more or less saying "that's OK by me: go ahead  and open/close the
window), then we just call Wimp_OpenWindow or Wimp_CloseWindow. (Note
that if we don't do this, people will be unable to even MOVE or close
our windows!)

For Mouse events (result = 6), we get the following information:
  block!0   =  mouse x
  block!4   =  mouse y
  block!8   =  new button state
  block!12 =  window handle mouse is in
  block!16 =  icon handle mouse is in
We usually check the button state for Select or Menu clicks. In the
example program, a Menu click  calls the code to pop up our menu, while
a Select/Adjust click makes us ask the WIMP to open  our main window.
The x,y positions are used only by the menu creation code to position
the  menu in the correct place.

For menu events (result = 9), the block contains a list (terminated by
a value of -1) of menu items and  subitems that were selected.
Each number represents one menu, with the first item being number 0,
the second number 1, etc. Thus for our simple menu the choices returned
would either be 0  (Info, for which we take no action), or 1 (quit, for
which we set our "quit%" variable so that after  processing this event,
our main event loop will stop).
If a submenu is involved, then the first value (block%!0) is the main
menu item from which the submenu "hangs", and the second value 
(block%!4) would be the item number within the submenu.

Message events (result = 17 or 18) allow many fancy inter-application
communications: Our only  interest now is the message number 0
(block%!16 = 0), which is the "quit" message, sent by the  task manager
if the user selects "quit" from the menu popped up over the
application's name in  the task manager window. This is a very important
thing to include, as it is very simple, but  allows you to quit your
application during development, even if it doesn't yet supply a menu!

---

More information on these things can be found in back-issues of RISC
USER, Archive, BBC Acorn User,  or from me if you ask really nicely!
(The Programmers Reference Guide may also be of some help ;-)

Sorry about the brevity of this description, but this was originally
written as a handout for talk I gave at the local Acorn club...

However, I have written the !RunImage program as simply as I can, to make
it as clear and a easy to understand as possible.

Jason Williams.

--->8---

REM > !Example.!RunImage <
REM Example WIMP application
REM Jason Williams '91

DIM block% 512, menu% 256          :REM Data block to hold WIMP info

REM === Initialise the window manager ===
$block%="TASK"
SYS "Wimp_Initialise", 200, !block%, "ExampleApp" TO ,taskID%

PROCbarIcon                        :REM Put our icon on the icon bar
PROCloadTemplates                  :REM Load window templates

quit% = FALSE
mask% = 1

REPEAT                             :REM Main polling loop
  SYS "Wimp_Poll", mask%, block% TO pollResult%

  CASE pollResult% OF
    WHEN 1:                         REM A window needs redrawing
      REM none of our windows need this

    WHEN 2:                         REM A window needs (re)opening
      SYS "Wimp_OpenWindow",,block%

    WHEN 3:                         REM A window needs to be closed
      SYS "Wimp_CloseWindow",,block%

    WHEN 6:                         REM A mouse button click
      PROCbuttonClick

    WHEN 9:                         REM A menu item has been chosen
      PROCmenuChoice

    WHEN 17,18:                     REM A WIMP message has arrived
      IF block%!16 = 0 THEN quit%=TRUE
  ENDCASE
UNTIL quit%

REM === Tell WIMP we are quitting ===
SYS "Wimp_CloseDown",taskID%
END



DEF PROCbarIcon                      :REM Create iconbar icon
  block%!0  = -1                     :REM Icon on right side of iconbar
  block%!4  = 0                      :REM      min x position
  block%!8  = 0                      :REM      min y position
  block%!12 = 68                     :REM      max x (for standard icon size)
  block%!16 = 68                     :REM      max y (")
  block%!20 = &17003002              :REM Icon flags (colour, type, etc.)
  $(block%+24) = "!Example"          :REM Icon sprite name

  SYS "Wimp_CreateIcon",,block% TO barIcon%
ENDPROC



DEF PROCloadTemplates                :REM Load window templates
  DIM templates% 1024

  currentptr% = templates%
  bufferend%  = templates% + 1024

  SYS "Wimp_OpenTemplate",,"<Obey$Dir>.Templates"

    SYS "Wimp_LoadTemplate",,block%, currentptr%, bufferend%, -1, "info", 0
	TO ,,currentptr%
    SYS "Wimp_CreateWindow",,block% TO infoHandle%

    SYS "Wimp_LoadTemplate",,block%, currentptr%, bufferend%, -1, "window", 0
	TO ,,currentptr%
    SYS "Wimp_CreateWindow",,block% TO windowHandle%

  SYS "Wimp_CloseTemplate"
ENDPROC



DEF PROCbuttonClick                  :REM Mouse click
  window% = block%!12
  icon%   = block%!16
  button% = block%!8

  CASE window% OF
    WHEN -2:                          REM Click on iconbar icon
      IF button% = 2 THEN
	PROCcreateMenu               :REM Menu: Pop up the menu
      ELSE
	block%!0 = windowHandle%     :REM Select/Adjust: Open window
	SYS "Wimp_GetWindowState",,block%
	SYS "Wimp_OpenWindow",,block%
      ENDIF

    WHEN windowHandle%:               REM Click in main window
      CASE icon% OF
	WHEN 0:
	  VDU 7                      :REM Beep!

	WHEN 1:
	  VDU 7                      :REM Beep! Beep!
	  TIME = 0:REPEAT UNTIL TIME > 25
	  VDU 7

	WHEN 2:
	  VDU 7                      :REM Beep! Beep! Beep!
	  TIME = 0:REPEAT UNTIL TIME > 25
	  VDU 7
	  TIME = 0:REPEAT UNTIL TIME > 25
	  VDU 7
      ENDCASE
  ENDCASE
ENDPROC



DEF PROCcreateMenu                   :REM Create icon-bar menu
  xpos% = block%!0                   :REM Mouse x,y positions
  ypos% = block%!4

  $menu%   = "Example"               :REM Title (up to 11 chars long)
  menu%!12 = &00070207               :REM Standard colours
  menu%!16 = 128                     :REM Menu width
  menu%!20 = 40                      :REM Standard item height
  menu%!24 = 0                       :REM Standard inter-item gap

  ptr%   = menu% + 28                :REM Menu item base pointer
  ptr%!0 = 0                         :REM Flag word 1
  ptr%!4 = infoHandle%               :REM info window hangs off here
  ptr%!8 = &07000021                 :REM Standard flag word 2
  $(ptr%+12) = "Info"                :REM Item text (Up to 11 chars)

  ptr%  += 24                        :REM Advance menu item base pointer
  ptr%!0 = &80                       :REM Flag word 1 (End of list)
  ptr%!4 = -1                        :REM NO submenu/subwindow
  ptr%!8 = &07000021                 :REM Standard flag word 2
  $(ptr%+12) = "Quit"                :REM Item text (Up to 11 chars)

  numitems% = 2                      :REM 2 menu items (info, quit)
  ypos% = 96+(numitems%*40)

  xpos% -= 64                        :REM Menu pops up centred on pointer

  SYS "Wimp_CreateMenu",,menu%, xpos%, ypos%
ENDPROC



DEF PROCmenuChoice                   :REM Choice made from the menu
  mainitem% = block%!0

  CASE mainitem% OF
    WHEN 0:                           REM Info
      REM Do nothing in this case

    WHEN 1:                           REM Quit
      quit% = TRUE
  ENDCASE
ENDPROC

-- 
_________________  "I'd like to answer this question in two ways:
  /____ _ _/_ __       First in my normal voice, and then
 // / //_//_ /_/       in a silly, high-pitched whine." (Monty Python)

