% "intrface.tu" % % University of Toronto % CSC148s, 1996 % Solution to Assignment 2 % % This file defines the interface module used in the solution of Assingment 2. % The interface display has three components: % % 1) A status line at the top of the screen, % % 2) A representation of the maze in the middle of the screen, % % 3) and a button in the lower left corner. % % Routines are available for changing the text in the button and % the status line and for manipulating the maze display. unit module Interface export displayMessage, displayButton, inButton, displayInitialMaze, displayMazeElement, findMazeCoordinate, maxMazeHeight, maxMazeWidth, entranceColour, spaceColour, solidColour % Private constants. % NOTE: A limitation of this module is that it won't respond % to changes in the graphic screen's size. Calls to "setscreen" may % change "maxx" and "maxy" which are assumed to be constant by this % module. const squareSize := 10 % Dimensions of a maze element. const rowHeight := maxy div maxrow const colWidth := maxx div maxcol % Coordinates for message line. const msgX := 0 const msgY := maxy - rowHeight % Coordinates for Button. Allow space for 5 characters. const maxCharsInButton := 5 const buttonX := 0 const buttonY := 0 const buttonWidth := maxCharsInButton * colWidth const buttonHeight := rowHeight % Boundaries for maze. Insist on two pixels of space between % the maze and the button or the message line or the sides % of the screen. const bufferSpace := 2 const minXforMaze := bufferSpace const maxXforMaze := maxx - (bufferSpace*2) const minYforMaze := buttonHeight + bufferSpace const maxYforMaze := maxy - (buttonHeight + rowHeight + bufferSpace*2) % Public Constants const maxMazeWidth := (maxXforMaze - minXforMaze +1) div squareSize const maxMazeHeight := (maxYforMaze - minYforMaze +1) div squareSize % Maze colours const spaceColour := White const solidColour := Black const mazeBackColour := Blue const entranceColour := Green % Private variables % Actual maze coordinates. var mazeLowerLeftX, mazeLowerLeftY, mazeHeight, mazeWidth : int var mazeIsInitialized : boolean := false % displayMessage(message, textColour, backColour) % - displays a message on the status line with the text in % 'textColour' on a background of 'backColour'. The message is % truncated to fit on a single line. It is assumed that there % are no control characters in the string that could mess up the % display (e.g. a newline). procedure displayMessage (message : string, textColour, backColour : int) % Truncate message. var msgToDisplay : string := message (1 .. min (length (message), maxcol)) % Clear the line colourback (White) colour (Black) locatexy (msgX, msgY) put repeat (" ", maxcol) .. % Output the text. colourback (backColour) colour (textColour) locatexy (msgX, msgY) put msgToDisplay .. % Restore default text colours. colourback (White) colour (Black) end displayMessage % displayButton(text, textColour, backColour) % - display some text in the button with the text in % 'textColour' on a background of 'backColour'. The text % is truncated to fit in the button. It is assumed that there % are no control characters in the string that could mess up % the display. procedure displayButton (text : string, textColour, backColour : int) % Truncate text var msgToDisplay : string := text (1 .. min (length (text), maxCharsInButton)) % Draw box around button and fill with background colour. drawfillbox (buttonX, buttonY, buttonX + buttonWidth, buttonY + buttonHeight, backColour) % Output text in the button. locatexy (buttonX, buttonY) colourback (backColour) colour (textColour) put msgToDisplay .. % Restore default text colours colourback (White) colour (Black) end displayButton % displayMazeElement(mazeX, mazeY, colour) % - display the maze element (mazeX, mazeY) in colour 'colour'. procedure displayMazeElement (mazeX, mazeY : int, colour : int) assert 1 <= mazeX and mazeX <= mazeWidth and 1 <= mazeY and mazeY <= mazeHeight const llx := mazeLowerLeftX + (mazeX - 1) * squareSize const lly := mazeLowerLeftY + (mazeY - 1) * squareSize drawfillbox (llx + 1, lly + 1, llx + squareSize - 1, lly + squareSize - 1, colour) end displayMazeElement % displayInitialMaze(width, height, error) % - This procedure displays a grid of maze elements (all solid) % of size widthXheight. If width or height are not appropriate, nothing % is done and 'error' is set to true. procedure displayInitialMaze (width, height : int, var error : boolean) if width < 1 or height < 1 then error := true return end if % Calculate actual width and height of maze display. mazeHeight := height mazeWidth := width const displayWidth := squareSize * mazeWidth const displayHeight := squareSize * mazeHeight % Center the maze mazeLowerLeftX := (minXforMaze+maxXforMaze) div 2 - displayWidth div 2 mazeLowerLeftY := (minYforMaze+maxYforMaze) div 2 - displayHeight div 2 % Check boundaries for size const upperRightX := mazeLowerLeftX + displayWidth - 1 const upperRightY := mazeLowerLeftY + displayHeight - 1 if mazeLowerLeftX < minXforMaze or mazeLowerLeftY < minYforMaze or (mazeLowerLeftX + displayWidth - 1) > maxXforMaze or (mazeLowerLeftY + displayHeight - 1) > maxYforMaze then error := true return else error := false end if mazeIsInitialized := true % Everything is fine so display the maze. % - Draw background colour. % - Draw the elements (all solid). drawfillbox (mazeLowerLeftX, mazeLowerLeftY, mazeLowerLeftX + displayWidth, mazeLowerLeftY + displayHeight, mazeBackColour) for i : 1 .. width for j : 1 .. height displayMazeElement (i, j, solidColour) end for end for end displayInitialMaze % findMazeCoordinate(x, y, mazeX, mazeY) % - This procedure converts screen a coordinate (x,y) into a maze % coordinate (mazeX, mazeY). If the screen coordinate is not inside the % maze display, both mazeX and mazeY are set to zero. procedure findMazeCoordinate (x, y : int, var mazeX, mazeY : int) assert mazeIsInitialized const displayWidth := squareSize * mazeWidth const displayHeight := squareSize * mazeHeight if x < mazeLowerLeftX or y < mazeLowerLeftY or x >= (mazeLowerLeftX + displayWidth) or y >= (mazeLowerLeftY + displayHeight) then % Not in maze. mazeX := 0 mazeY := 0 return else const xOffset := x - mazeLowerLeftX const yOffset := y - mazeLowerLeftY mazeX := xOffset div squareSize + 1 mazeY := yOffset div squareSize + 1 assert mazeX <= mazeWidth assert mazeY <= mazeHeight assert mazeX > 0 assert mazeY > 0 end if end findMazeCoordinate % inButton(x, y) : boolean % - This function returns true if the screen coordinate (x,y) is % inside the button and false otherwise. function inButton (x, y : int) : boolean result x >= buttonX and x < (buttonX + buttonWidth) and y >= buttonY and y < (buttonY + buttonHeight) end inButton end Interface