[clean-list] ObjectIO test of Identifiers etc

alanh@dcs.kcl.ac.uk alanh@dcs.kcl.ac.uk
Fri, 20 Jun 2003 22:00:55 +0100 (BST)


If anyone cares to ofer advice, it will be welcome.
Below is my first attempt to write a Clean program with ObjectIO
which actually does something.  What it actually does is not what
any good program should do.

This is an experiment with one window, one button control, and
two menus.  It was compiled and run with Clean 2.0.2 and ObjectIO 1.2.3
under Microsoft Windows XP.

The button works.

The first menu is Unable when started, as intended.

The second menu contains two elements:
 - element 1 quits the program.  It works.
 - element 2 should toggle whether menu 1 is Able or Unable.
   When it is clicked, the whole window ceases to work.
   The entire menu bar disappears.  
   The cursor turns into an hourglass.
   A DOS window appears (although the program was not configured
   with one), with a message to press any key to stop the program.
   If this is minimised, a message appears on the main program's
   window saying that it is not responding.

What have I done wrong?

Alan Hutchinson
Dept. of Computer Science
King's College London

-----------------------------
module wmitest

import StdEnv, StdIO


Start :: *World -> *World

Start w0  =  startIO SDI Void initialise [] w1
where
  (menu01Id, w1)        =  openId w0
  
  initialise pst 
    # (error, pst)      =  openWindow Void mainwindow pst
    | error <> NoError  =  abort "Couldn't open the main window."
    # (error, pst)      =  openMenu Void menu01 pst
    | error <> NoError  =  abort "Couldn't open Menu 01."
    # (error, pst)      =  openMenu Void menu02 pst
    | error <> NoError  =  abort "Couldn't open Menu 02."
    | otherwise         =  pst

  mainwindow    =  Window 
                     "Window - Menu - Identifier test" 
                     maincontrols
                     [(WindowClose (noLS closeProcess))
                     ]
                     
  maincontrols  =  ButtonControl
                     "Quit" 
                     [ControlFunction (noLS closeProcess)]
  
  menu01        =  Menu
                     "Menu 01" 
                     (MenuItem 
                       "Quit 01" 
                       [MenuFunction (noLS closeProcess)]) 
                     [MenuId menu01Id
                     ,MenuSelectState Unable]
  
  menu02        =  Menu
                     "Menu 02" 
                     (MenuItem 
                        "Quit 02" 
                        [MenuFunction (noLS closeProcess)
                        ,MenuShortKey 'q'  
//                      really means 'q' but is displayed as 'Ctrl+Q' !
                        ]
                      :+:
                      MenuItem
                        "toggle Menu 01"
                        [MenuFunction (noLS (toggleMenu menu01Id))]
                     ) 
                     []
  
  toggleMenu :: Id (PSt .l)  ->  PSt .l
  toggleMenu id pst
  | isNothing maybeMstate =  abort "A menu's Id doesn't refer to a menu."
  | not tf                =  abort "Can't get a menu's select state."
  | selectState == Able   =  {pst & io = disableMenuElements [id] io2}
  | otherwise             =  {pst & io =  enableMenuElements [id] io2}
  where
    (maybeMstate, io2)    =  getMenu id pst.io
    (Just mState)         =  maybeMstate
    (tf, selectState)     =  getMenuElementSelectState id mState