;
; menuDefs.sh
;
; Constant definitions and macros for dealing with menus
;
;  1994-1998 Straylight
;

;----- Licensing note -------------------------------------------------------
;
; This file is part of Straylight's Sapphire library.
;
; Sapphire is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2, or (at your option)
; any later version.
;
; Sapphire is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with Sapphire.  If not, write to the Free Software Foundation,
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

;----- Overview -------------------------------------------------------------
;
; Macros provided:
;
;   BITSPEC
;   SETBIT
;   NEWITEM
;   MENU
;   MENUI
;   TEAROFF
;   TEAROFFI
;   R12DATA
;   MAKEME
;   MHEIGHT
;   GLOBALM
;   ITEM
;   ITEWI
;   SHADE
;   ISHADE
;   SWITCH
;   RADIO
;   SPRITE
;   HALFSZ
;   SUBWARN
;   SUBMENU
;   NOWARN
;   RULEOFF
;   MENUEND

		[	:LNOT::DEF:menuDefs__dfn
		GBLL	menuDefs__dfn

;+		LIB	sapphire:^.bsh.menuDefs

;----- Constants for menus --------------------------------------------------
;
; In the descriptions of flags below, the data required in the packed menu
; definition is shown in the comments.  Insert items in the order of the
; bit precedences of the flags.
;
; Note -- a (*) following a description means the flag is only supported by
; tms (the tearoff system), and a (+) means that the flag is only supported
; by menu (the WIMP system).

; --- Flags for menu titles and items ---

mFlag_indirect	EQU	(1<<0)			;Data string is indirect
						;+0 == offset of text pointer
						;+4

mFlag_R12	EQU	(1<<16)			;Use R12 for writable data
						;+0

mFlag_noTrans	EQU	(1<<19)			;Don't translate messages
						;+0

; --- Menu title flags ---

mFlag_tearoff	EQU	(1<<1)			;Menu may be torn off (*)
						;+0

mFlag_makeMe	EQU	(1<<2)			;Menu recreated by client (+)
						;+0 == pointer to recreate fn
						;+4

mFlag_maxHeight	EQU	(1<<3)			;Menu has a max height (*)
						;+0 == max height in OS units
						;+4

mFlag_global	EQU	(1<<4)			;Menu is `global' (*)
						;+0

; --- Menu item flags ---

mFlag_shortCut	EQU	(1<<1)			;Item has a shortcut
						;+0 == shortcut key number
						;+4

mFlag_iShortCut	EQU	(1<<2)			;Item has indirected shortcut
						;+0 == offset of key number
						;+4

mFlag_shade	EQU	(1<<3)			;Item may be shaded
						;+0 == bitspec of shade bit
						;+4

mFlag_invShade	EQU	(1<<4)			;Item may be unshaded
						;+0 == bitspec of unshade bit
						;+4

mFlag_switch	EQU	(1<<5)			;Item is a switch (tickable)
						;+0 == bitspec of tick bit
						;+4

mFlag_radio	EQU	(1<<6)			;Item is a radio button
						;+0 == offset of grp selector
						;+4 == number of item in grp
						;+8

mFlag_sprite	EQU	(1<<7)			;Item contains a sprite (*)
						;For WIMP menus:
						;+0 == ptr to validation str
						;+4
						;For TMS menus:
						;+0 == offset of name pointer
						;+4 == sprite area (-1==res)
						;+8

mFlag_halfSize	EQU	(1<<8)			;Display sprite half sized
						;+0

mFlag_subWarn	EQU	(1<<9)			;Make event on opening sub
						;+0

mFlag_subMenu	EQU	(1<<10)			;Item has a submenu
						;+0 == pointer to submenu def
						;+4

mFlag_noWarn	EQU	(1<<17)			;Don't open sub when shaded
						;+0

mFlag_ruleOff	EQU	(1<<18)			;Rule off after the item
						;+0

mFlag_end	EQU	(1<<31)			;There are no more items
						;+0

; --- Event codes ---
;
; Event codes are returned in R0, with R1 being the item number within
; the packed menu definition, indexed from 0.
;
; Note: mEvent_deleted is only sent to the topmost menu title by the
; standard menu system, but is sent to the titles of all menus being closed
; by TMS.  If you are converting from one to the other, bear this in mind.

mEvent_select	EQU	0			;The user chose a menu item
						;R1 == item number
						;R2 == address of packed def

mEvent_subMenu	EQU	1			;A submenu is about to open
						;R1 == item number

mEvent_deleted	EQU	2			;A menu has just closed

mEvent_help	EQU	3			;Help is wanted for an item
						;R1 == item number
						;R2 == address of packed def

;----- Menu creation macros -------------------------------------------------

; --- Note to reader ---
;
; These macros make a lot of use of private constants and variables.  Try to
; avoid examining these too closely, because you'll probably get lost.

; --- Set up the variables ---

		GBLA	md__i
md__i		SETA	0
		GBLA	md__f
md__f		SETA	0

; --- Macro: BITSPEC ---
;
; Arguments:	offset == offset into workspace of target word
;		bit == bitmask with a 1 in the position of the bit
;
; Use:		Assembles a bit specification referencing the described bit.
;		The bit is described by a mask word rather than a bit
;		position, because it is expected that you will already have
;		set up constants for bit masks.

		MACRO
		BITSPEC	$offset,$bit

		LCLA	bn
bn		SETA	0
		LCLA	bv
bv		SETA	$bit
		[	bv = 0
		!	1,"Bit mask is 0 in BITSPEC"
		]

		WHILE	(bv :AND: 1)=0
bn		SETA	bn+1
bv		SETA	bv >> 1
		WEND

		DCD	($offset << 5) :OR: bn
		MEND

; --- Macro: SETBIT ---
;
; Arguments:	flag == which menu flag above to set
;
; Use:		Sets a bit within the current item or menu title's flags
;		word.  It ensures that items are inserted in the correct
;		order.

		MACRO
		SETBIT	$flag
		[	(md__f :AND: &ffff) >= $flag
		!	1,"Flags built in bad order in menuDefs"
		]
md__f		SETA	md__f :OR: $flag
		MEND

; --- Macro: NEWITEM ---
;
; Arguments:	--
;
; Use:		Starts a new menu item or menu title.  It also inserts a new
;		flags word in the current position.

		MACRO
$label		NEWITEM
		ALIGN
$label
md__F$md__i	EQU	md__f
md__f		SETA	0
md__i		SETA	md__i+1
		DCD	md__F$md__i
		MEND

; --- Macro: MENU ---
;
; Arguments:	title == the menu's title string/message tag
;
; Use:		Creates a nonindirected menu title and starts a new menu.

		MACRO
$label		MENU	$title
$label		NEWITEM
		[	:LEN:"$title">12
		!	1,"Menu title too long"
		]
		DCB	"$title",0
		ALIGN
		MEND

; --- Macro: MENUI ---
;
; Arguments:	title == offset to title pointer in client's workspace
;
; Use:		Creates an indirected menu title and starts a new menu.

		MACRO
$label		MENUI	$title
$label		NEWITEM
		SETBIT	mFlag_indirect
		DCD	$title
		MEND

; --- Macro: TEAROFF ---
;
; Arguments:	title == menu's title string/message tag
;
; Use:		Creates a nonindirected tearoff menu title and starts a new
;		menu.

		MACRO
$label		TEAROFF	$title
$label		NEWITEM
		DCB	"$title",0
		ALIGN
		SETBIT	mFlag_tearoff
		MEND

; --- Macro: TEARI ---
;
; Arguments:	title == offset to title pointer in client's workspace
;
; Use:		Creates an indirected tearoff menu title and starts a new
;		menu.

		MACRO
$label		TEARI	$title
$label		NEWITEM
		SETBIT	mFlag_indirect
		DCD	$title
		SETBIT	mFlag_tearoff
		MEND

; --- Macro: R12DATA ---
;
; Arguments:	--
;
; Use:		Sets the current menu item or menu title to use the client's
;		R12 pointer rather than its R10 pointer for workspace.

		MACRO
		R12DATA
		SETBIT	mFlag_R12
		MEND

; --- Macro: NOTRANS ---
;
; Arguments:	--
;
; Use:		Disables message translation of the current item or menu
;		title.  This is useful if you're building the item or title
;		text dynamically.

		MACRO
		NOTRANS
		SETBIT	mFlag_noTrans
		MEND

; --- Macro: MAKEME ---
;
; Arguments:	makeProc == pointer to procedure which will remake the menu
;
; Use:		Sets the current menu to require being remade from scratch
;		when being updated (e.g. after an item is selected).

		MACRO
		MAKEME	$makeProc
		SETBIT	mFlag_makeMe
		DCD	$makeProc
		MEND

; --- Macro: MHEIGHT ---
;
; Arguments:	height == maximum permitted height for menu in OS units
;
; Use:		Sets the menu's maximum allowable height.

		MACRO
		MHEIGHT	$height
		SETBIT	mFlag_maxHeight
		DCD	$height
		MEND

; --- Macro: GLOBALM ---
;
; Arguments:	--
;
; Use:		Sets the menu's maximum allowable height.

		MACRO
		GLOBALM
		SETBIT	mFlag_global
		MEND

; --- Macro: ITEM ---
;
; Arguments:	text == item's text string/message tag
;
; Use:		Creates a new nonindirected menu item.

		MACRO
$label		ITEM	$text
$label		NEWITEM
		DCB	"$text",0
		ALIGN
		MEND

; --- Macro: ITEMI ---
;
; Arguments:	text == offset of pointer to menu text
;
; Use:		Creates a new indirected menu item

		MACRO
$label		ITEMI	$text
$label		NEWITEM
		SETBIT	mFlag_indirect
		DCD	$text
		MEND

; --- Macro: SHADE ---
;
; Arguments:	$offset,$bit == bitspec of item's `shaded' bit
;
; Use:		Sets the current item to be shadable.

		MACRO
		SHADE	$offset,$bit
		SETBIT	mFlag_shade
		BITSPEC	$offset,$bit
		MEND

; --- Macro: ISHADE ---
;
; Arguments:	offset,$bit == bitspec of item's `unshaded' bit
;
; Use:		Sets the current item to be inverse shadable.

		MACRO
		ISHADE	$offset,$bit
		SETBIT	mFlag_invShade
		BITSPEC	$offset,$bit
		MEND

; --- Macro: SWITCH ---
;
; Arguments:	offset,$bit == bitspec of item's `ticked' bit
;
; Use:		Sets the current item to be tickable.

		MACRO
		SWITCH	$offset,$bit
		SETBIT	mFlag_switch
		BITSPEC	$offset,$bit
		MEND

; --- Macro: RADIO ---
;
; Arguments:	group == offset of this item's radio group selector
;		selector == value of selector to blob this item
;
; Use:		Marks this item as a radio item, so that it is blobbed (or
;		ticked under the WIMP menu system) when the selector in the
;		client's workspace matches the item's selector.

		MACRO
		RADIO	$group,$selector
		SETBIT	mFlag_radio
		DCD	$group,$selector
		MEND

; --- Macro: SPRITE ---
;
; Arguments:	sprite == EITHER address of validation string, OR offset of
;		  sprite name pointer (if area argument given)
;		area == (optional) sprite area, or -1 for resspr_area
;
; Use:		Adds a sprite to the menu item definition.

		MACRO
		SPRITE	$sprite,$area
		SETBIT	mFlag_sprite
		DCD	$sprite
		[ "$area"<>""
		DCD	$area
		]
		MEND

; --- Macro: HALFSZ ---
;
; Arguments:	--
;
; Use:		Sets the item to display its sprite at half size

		MACRO
		HALFSZ
		SETBIT	mFlag_halfSize
		MEND

; --- Macro: SUBWARN ---
;
; Arguments:	--
;
; Use:		Sets the item to generate submenu warnings when its submenu
;		arrow is pointed at.

		MACRO
		SUBWARN
		SETBIT	mFlag_subWarn
		MEND

; --- Macro: SUBMENU ---
;
; Arguments:	subMenu == pointer to packed definition of the submenu
;		handler == pointer to handler routine
;
; Use:		Attaches the given menu as a submenu of this item.

		MACRO
		SUBMENU	$subMenu,$handler
		SETBIT	mFlag_subMenu
		DCD	$subMenu,$handler
		MEND

; --- Macro: NOWARN ---
;
; Arguments:	--
;
; Use:		Prevents this item from returning submenu events if it is
;		shaded.

		MACRO
		NOWARN
		SETBIT	mFlag_noWarn
		MEND

; --- Macro: RULEOFF ---
;
; Arguments:	--
;
; Use:		Inserts a ruleoff after the current item, assuming there are
;		some more items after it.

		MACRO
		RULEOFF
		SETBIT	mFlag_ruleOff
		MEND

; --- Macro: MENUEND ---
;
; Arguments:	--
;
; Use:		Finishes off the current menu.

		MACRO
		MENUEND
md__F$md__i	EQU	md__f
md__f		SETA	0
md__i		SETA	md__i+1
		DCD	mFlag_end
		MEND

		]

;----- That's all, folks ----------------------------------------------------

		END
