PRAGMA init_bloc
(init_op => initialize)
Manager for simple, nonoverlapping windows for alpha-numeric console.
This application is the HOOD version of "Dining Philosophers - Ada95 edition" from Michael B. Feldman, The George Washington University, July 1995.
HOOD adaptation was performed by Pierre Dissaux, TNI, June 1998, with STOOD toolset.
SR4: This modules implements an abstract simple window manager. (cf.SR4/Display_windows:)
FR4: Open and initialize a window. (cf.FR4/Open&initialize_window:)
FR5: Write messages at a specified location on the window. (cf.FR5/Write_messages:)
Windows are passive unshared objects. There is no particular behaviour requirements.
Please refer to parent module description.
Window module is designed as a passive HOOD4 class.
It describes a window data structure and all relevant functional services.
Code generator will produce a package containing a tagged type.
SR4: type Window is a class which attributes describe first, last and current positions of the cursor on the screen.
Following operations are primitive operations of type Window:
FR4:
- Initialize: package init block is used to clear the screen.
- Open: instanciates a new window and initialize its attributes with passed values.
- Title: writes a title and optionnaly a separation line.
- Borders: draws top, right, left and bottom lines.
FR5:
- MoveCursor: sets current cursor position.
- Put#1: writes a character at current cursor position.
- Put#2: writes a string at current cursor location.
- New_Line: puts current cursor position at the beginning of next line.
- EraseToEndOfLine: erases from current location to the end of line.
None
None
A few changes in initial source code were done to best fit HOOD4 design rules:
- Window was declared as a HOOD4 class, so code generator produces a tagged type by default.
- Name of the parameter of type Window in all primitive operation declarations was set to "me".
First : coordinates of upper left corner;
Last : coordinates of lower right corner;
Current : current cursor position.
INHERITANCE NONE
ATTRIBUTES First : screen.Position, Last : screen.Position, Current : screen.Position
ENUMERATION NONE
type Window is private;
Pre: UpperLeft, Weight, and Width are defined
Post: returns a Window with the given upper-left corner, height, and width
open(
UpperLeft : in Screen.Position;
Height : in Screen.Height;
Width : in Screen.Width
) return Window;
WCET
Pre: me, Name, and Under are defined
Post: Name is displayed at the top of the window me, underlined with the character Under
title(
me : in out Window;
Name : in String;
Under : in Character
);
WCET
Pre: All parameters are defined
Post: Draw border around current writable area in window with characters specified.
Call this BEFORE Title.
borders(
me : in out Window;
Corner : in Character;
Down : in Character;
Across : in Character
);
WCET
Pre: me, and P are defined, and P lies within the area of me
Post: Cursor is moved to the specified position.
Coordinates are relative to the upper left corner of me, which is (1,1)
movecursor(me : in out Window; P : in Screen.Position);
WCET
Pre: me, and Ch are defined.
Post: Ch is displayed in the window at the next available position.
If end of column, go to the next row.
If end of window, go to the top of the window.
put#1(me : in out Window; Ch : in Character);
WCET
Pre: me, and S are defined.
Post: Ch is displayed in the window, "line-wrapped" if necessary
put#2(me : in out Window; S : in String);
WCET
Pre: me is defined.
Post: Cursor moves to beginning of next line of me;
line is not blanked until next character is written
new_line(me : in out Window);
WCET
OBJECT screen;
TYPES
Height; Position; Width;
CONSTANTS
NONE
OPERATION_SETS
NONE
OPERATIONS
MoveCursor; ClearScreen;
EXCEPTIONS
NONE
OBJECT standard;
TYPES
Character; String;
CONSTANTS
NONE
OPERATION_SETS
NONE
OPERATIONS
NONE
EXCEPTIONS
NONE
OBJECT text_io;
TYPES
NONE
CONSTANTS
NONE
OPERATION_SETS
NONE
OPERATIONS
Put; New_Line;
EXCEPTIONS
NONE
Used to erase partially the screen.
erasetoendofline(me : in out Window);
WCET
This HOOD operation will not be generated as an Ada procedure, but as package initialization block.
This result is obtained by setting pragma "init_bloc(initialize)" when generating Ada code.
initialize;
WCET
Instanciates a new Window named "Result"
Sets Result attributes (Current, First and Last)
Returns Result.
Result : Window;
begin
Result.Current := UpperLeft;
Result.First := UpperLeft;
Result.Last := (Row => UpperLeft.Row + Height - 1,
Column => UpperLeft.Column + Width - 1);
return Result;
Sets cursor at the beginning of first line.
Writes title string
If "Under" is blank then continue
else draw a separation line
Reduces writable area as required.
windows.put
windows.new_line
begin
-- Put name on top line
me.Current := me.First;
Put(me, Name);
New_Line(me);
-- Underline name if desired, and reduce the writable area
-- of the window by one line
if Under = ' ' then
-- no underlining
me.First.Row := me.First.Row + 1;
else
-- go across the row, underlining
for Count in me.First.Column..me.Last.Column loop
Put(me, Under);
end loop;
New_Line(me);
-- reduce writable area
me.First.Row := me.First.Row + 2;
end if;
Draws top line border.
Draws the two side lines.
Draws the bottom line of the border.
Make the Window smaller by one character on each side.
screen.MoveCursor
text_io.Put
begin
-- Put top line of border
Screen.MoveCursor(me.First);
Text_IO.Put(Corner);
for Count in me.First.Column+1 .. me.Last.Column-1 loop
Text_IO.Put(Across);
end loop;
Text_IO.Put(Corner);
-- Put the two side lines
for Count in me.First.Row+1 .. me.Last.Row-1 loop
Screen.MoveCursor((Row => Count,Column => me.First.Column));
Text_IO.Put(Down);
Screen.MoveCursor((Row => Count,Column => me.Last.Column));
Text_IO.Put(Down);
end loop;
-- Put the bottom line of the border
Screen.MoveCursor((Row => me.Last.Row,Column => me.First.Column));
Text_IO.Put(corner);
for Count in me.First.Column+1 .. me.Last.Column-1 loop
Text_IO.Put (Across);
end loop;
Text_IO.Put(Corner);
-- Make the Window smaller by one character on each side
me.First := (Row => me.First.Row+1,Column => me.First.Column+1);
me.Last := (Row => me.Last.Row-1,Column => me.Last.Column-1);
me.Current := me.First;
Cursor position passed as parameter is relative to window boundaries.
-- Relative to writable Window boundaries, of course
begin
me.Current.Row := me.First.Row + P.Row;
me.Current.Column := me.First.Column + P.Column;
If at end of current line then move to next line.
If at beginning of current line then erase the entire line.
Writes given character.
windows.erasetoendofline
screen.MoveCursor
text_io.Put
begin
-- If at end of current line, move to next line
if me.Current.Column > me.Last.Column then
if me.Current.Row = me.Last.Row then
me.Current.Row := me.First.Row;
else
me.Current.Row := me.Current.Row + 1;
end if;
me.Current.Column := me.First.Column;
end if;
-- If at First char, erase line
if me.Current.Column = me.First.Column then
EraseToEndOfLine(me);
end if;
Screen.MoveCursor(To => me.Current);
-- here is where we actually write the character!
Text_IO.Put(Ch);
me.Current.Column := me.Current.Column + 1;
Uses put#1 to write each character of the string.
begin
for Count in S'Range loop
Put(me, S (Count));
end loop;
If cursor is at beginning of a line then first erase this line.
If cursor is on last line then put it on first line.
Else put it on next line.
windows.erasetoendofline
begin
if me.Current.Column = 1 then
EraseToEndOfLine(me);
end if;
if me.Current.Row = me.Last.Row then
me.Current.Row := me.First.Row;
else
me.Current.Row := me.Current.Row + 1;
end if;
me.Current.Column := me.First.Column;
Puts blank characters from current cursor position to the end of current line.
Current cursor position remains unchanged.
screen.MoveCursor
text_io.Put
begin
Screen.MoveCursor (me.Current);
for Count in me.Current.Column .. me.Last.Column loop
Text_IO.Put (' ');
end loop;
Screen.MoveCursor (me.Current);
Clears the screen.
text_io.New_Line
screen.ClearScreen
begin
Text_IO.New_Line;
Screen.ClearScreen;
Text_IO.New_Line;