Reference List Dialog Library -turn page- Reference List Window Library

Contents | Start

The Window Library

4. The Window Library
4.1
4.2
4.3
4.4
4.5
4.6
4.7
4.8
4.9
4.10
4.11
4.12
4.13
4.14
4.15
The Concept of the Virtual Screen
The Principles of Programming a Window Using EasyGem
Indicating the Dimensions of a Window
Graphics Windows
Set and Query the Dimension of a Window
The Sequence of Windows
The Query of the Mouse in a Window
Text Windows
Setting and Querying of Text Attributes
Inputs in Text Windows
User Windows
Rubber Band Commands for Graphics and User Windows
Blocks in Windows
Commands for the Default Menu
Apple Events
Reference List Window Library



Every owner of an Apple computer knows the advantages of the user friendly interface and handling, which are offered to the user through the windows environment and windowing. Unfortunately, windows are usually not exactly the easiest to program. The ambitious programmer has to fight through a jungle of operation system calls and queries - just to accomplish simple tasks. The root of the problem is that window commands of the Mac OS have little effect on their own. Only the complex interaction and coordinated collaboration of several commands makes the management of windows even possible. EasyGem now offers commands on a higher level, which are more likely to satisfy the requirements of application programs. Here is an overview over those procedures and functions of EasyGem that concern windowing.

Fully automatically managed text windows in any desired size.
Fully automatically managed graphics windows in any desired size.
Semiautomatically managed user windows on virtual screens.
Easy setting and querying of windows dimensions.
All Omikron Basic drawing commands can be rerouted to any window.
Commands for marking and managing of blocks.
Clipboard support (cut, copy, paste).
Commands to load and save documents.
Commands to print documents.

Individual blocks can be defined in each window.
Evaluating Apple events.



4.1 The Concept of the Virtual Screen

Let's stop for a moment and think about why windowing was even invented. The problem had been trying to display more information than could fit on any given screen. Larger screens or spreading the information among several screens might have been the answer, although an expensive one and one that cannot be expanded indefinitely. Therefore, virtual screens were invented. They are actually nothing more than reserved memory areas in which the information is managed similarly to the screen buffer of the real screen.
However, since one cannot see virtual screens, windows are needed, which allow the user at least a glimpse or view of a section of the underlying virtual screen. And that is exactly the concept of the Windows Library. Windows are considered to be an aid in displaying virtual screens. It might help to think of a rectangular hole (the window), which is being cut into a piece of black cardboard and then placed on a page in a book larger than the hole. Now it is impossible to read the entire page at once, but the remainder of the page can be read by moving the piece of cardboard with the hole in it. The computer contains many such pieces of cardboard, which can then be used to look at many different pages in a book.

The Window Library manages three different types of virtual screens for the different applications of this concept.

Types of Screens:
Graphics Information is saved in pixels.
Text Information is saved in characters.
User The data structure of user screens may be determined by the programmer him- or herself. The Window Library offers support only for the displaying of the screen and takes over the management of the border areas.



4.2 The Principle of Programming a Window Using EasyGem

Being able to program windows with EasyGem means mainly that you as the programmer have been relieved of many tedious tasks. Actually, your program does not need to do anything but wait and ask repeatedly what the user is doing on the screen at any given moment. Deciding, which activities of the user are important and what the user was actually doing, is being performed automatically by EasyGem. If something has occurred that is important to your program, EasyGem will report this event using
Easy_Mesag. Then your program has to evaluate the message and react correspondingly. However, in most instances it is possible to let EasyGem perform all necessary tasks automatically using Win_Domessages. The only exceptions are e.g., menu activities of the user, which have to be responded to by the program itself. This has already been described in the menu section.

A simple window without a menu would therefore appear as follows:

COMPILER "MIN_SIZE 1000000"
COMPILER "BAS_MEM 1000000"
COMPILER "Warnings off"

Easy_Init
Gwin_Open Win1,0,21,200,160,320,200,"Window 1"
REPEAT
 Easy_Mesag Entry,Buffer$
 Win_Domessages Buffer$
UNTIL FN Win_Closed(Win1)
Easy_Exit
END
This little program opens a window and then repeatedly calls the commands Easy_Mesag and Win_Domessages. The window and a mouse can be seen on the screen during this time. The program user may move the mouse and click on any location. As soon as the user performs an important activity, that is, as soon as the user clicks on one of the control elements of the window, Easy_Mesag reports the correspondingly coded message instead of the usual "nothing new... ". Consequently, the procedure Win_Domessages carries out the change at once.
As you can see, your program does not have to take care of anything by itself. The control of the mouse, e.g., whether a window, the slider bar, the scrolling arrows, or other control elements have been clicked on - EasyGem performs all of these tasks automatically.

Caution: A few of the commands of the Window Library might cause the operating system to issue a message of its own (e.g., Win_Open, Win_Reopen, Win_Setview, Win_Setborder, Win_Top, Win_Setsize, Win_Setwork, or Win_Full). Because of this, the commands Easy_Mesag and Win_Domessages have to be called in a loop at regular intervals, as shown in the above sample program.
The command
Easy_Mesag is probably already known to you from the menu programming description. Easy_Mesag will now be given a second variable so that you will obtain information about window activities as well. This second variable now only needs to be passed to Win_Domessages. The command to collect events is as follows:

Easy_Mesag R Entry[,R Buffer$]
Report messages of the operating system.

Entry is the variable already familiar to you from the menus. It is used to report if a menu item has been chosen. This variable is of less interest in connection with windows. Only Buffer$ is here of importance.
Easy_Mesag does not wait for any activity of the user but rather returns immediately and in cases of doubt reports "Nothing new on screen" to Win_Domessages.

Note: Those programmers who now would like to react to other mouse clicks in the window as well, need to apply a further expanded Easy_Mesag as described in Win_Mousepos.

Pro Tip: Incidentally, Buffer$ is exactly that 16 byte event string of the MacOS that is returned by 'WaitNextEvent'. This means that it is also possible to evaluate Buffer$ "manually," or what is even easier, simply just pass the string to the procedure Win_Domessages:

Win_Domessages Buffer$[,Closeaction]
Process messages of the operating system.

In that case, Buffer$ is the already mentioned string returned by Easy_Mesag. Closeaction contains the address of a function, which is called automatically whenever a window is being closed. This function can be defined by the programmer him- or herself. For example, this function could first carry out a security query before the window is being closed, but we will discuss this in more detail later on.

Attention: In contrast to older EasyGem versions, the address of a function rather than the label of a subprogram has to be passed in Closeaction.

Note: It is best to use the procedure Win_Closeaction discussed below to define a suitable action function. You can then also use Win_Domessages with one parameter. 



4.3 Indicating the Dimensions of a Window

Before delving any deeper into the subject matter at hand, we should first clearly define a few of the fundamental terms. This will prevent any possible confusion later on.

We differentiate between:
Outer dimension of the window (border area)
Inner dimension of the window (work area)
Total dimension of the virtual screen (virtual area)
Viewable sections of the virtual screen (view area)
These types of measures are usually indicated by four numbers: distance from left margin (X-position), distance from upper margin (Y-position), width (W) and height (H).

(See picture)



The sectional view is always displayed on the inside of the window. The width and height of the sectional view and the work area are thus always equal to one another. The X and Y positions, however, differ.
In order to organize the different window dimensions clearly, this manual refers to the coordinates as follows:

Border_X,Border_Y,Border_W,Border_H Outer window dimensions.
Work_X,Work_Y,Work_W,Work_H Inner window area.
Virt_X,Virt_Y,Virt_W,Virt_H Total dimension of virtual area.
View_X,View_Y,View_W,View_H Sectional view.

Please refer to the illustration for a detailed description of all terms.



4.4 Graphics Windows

Since graphics windows are quite similar to the Omikron Basic output windows you already know, but offer significantly more possibilities, we will start with the description of the graphics windows. The command to open a graphics window is as follows:

Gwin_Open R Win,Win_X,Win_Y,Win_W,Win_H
[,Virt_W,Virt_H],Name$
Gwin_Open R Win,Win_X,Win_Y,Win_W,Win_H,
Virt_W,Virt_H,Name$,Info$[,Kind]
Open graphics window.

Gwin_Open produces a window on the screen, which shows a section from a virtual graphics screen. To accomplish this, some memory in the application heap of your program will be reserved. If necessary, you have to use COMPILER "MIN_SIZE X" to ensure that the application heap will be sufficient in size. This memory area will then be used for the virtual graphics screen. Then you can use Gwin_Activate to reroute all Omikron Basic's printing and drawing commands to the virtual screen. The Window Library makes sure that the window will always feature the correct section of the virtual screen.
The significance of each particular parameter is as follows:

Win Win is the identification number of the new window. This number has to be indicated for every command which is supposed to reference the window. Therefore, it is also not permitted to reference a yet unopened window.
Win_X,
Win_Y
Position of the upper left corner of the window on the real screen, which makes it the outer or border dimension.
Win_W,
Win_H
Width and heights of the border dimension of the window. Here you have the option to indicate negative numbers as well. In that case, EasyGem takes the absolute value and interprets the numbers as the inner dimension (work area).
Virt_W,
Virt_H
Width and heights of the virtual screen. If Virt_W and Virt_H are omitted, then Virt_W=Work_W and Virt_H=Work_H is valid. The virtual screen can be of any size, as long as the application heap has enough memory to spare. If you should receive an error message with Gwin_Open, then the most common reason is that the available memory is insufficient.
Name$ The name of the window that will be displayed in the slider bar.
Info$ Another information line may be displayed below the window name, which is managed automatically by EasyGem. The content of this line is determined in Info$.
Kind In Kind, each one of the lower 12 bits represents one of the elements which are used to construct the border area. If Kind=0, only a thin frame surrounds the window. Each set bit adds another border element. In order to make it easier to know which bit represent which border element, each bit has a symbolic name. It is then possible to just add up all individual elements.
Use the bits 14 to 17 to set additional window properties:
. G_Name Display name of window.
G_Close The window has a close field.
G_Full The so-called full field is a field which can be used to maximize the size of the window.
G_Move The window is moveable.
G_Info The window has an information line.
G_Size The size of the window can be modified.
G_Uparrow Display scroll arrow pointing up.
G_Dnarrow Display scroll arrow pointing down.
G_Larrow Display scroll arrow pointing left.
G_Rarrow Display scroll arrow pointing right.
G_Vslide The vertical slider bar is displayed.
G_Hslide The horizontal slider bar is displayed.
G_Palette (Bit 14) The system color palette is assigned to the window. If your computer is set to display 256 colors or less, the color palette of the screen will be adjusted automatically as soon as the window becomes the frontmost window.
G_Hide (Bit 15) The window is invisible (hidden) but may be displayed using Win_Reopen.
G_Float
(Bit 16)
The window is opened as a so-called float window. This type of window is always in the front and has smaller edge elements. Float windows are especially suitable for building toolboxes, because all of the tools should be easily accessed when working in a document window.
Only the float windows of the currently active program are visible, all others are automatically removed from the screen.


The float property is supported starting with Mac OS 8.6. Older versions do also depict a float window, which, however, behaves like a regular document window.
G_Sidebar
(Bit 17)
The slider bar is located at the left. This bit is valid only for float windows.

Attention: If this bit is set, the name of the window is not displayed.
G_All All border elements, except the information line, are displayed.

In order to define a window with moving slider, name, and full field, it is necessary to indicate the following:
Kind=G_Name+G_Full+G_Move

Note: The scroll arrows and the slider bars can only be displayed together or not at all. As soon as a bit has been set, the other elements are displayed as well.

If Kind is omitted, all elements are displayed.
Exception: if
Info$ is omitted, that means, of course, that no information line is displayed either.


In order to move our elements to be output into the graphics window now, we need the following command:

Gwin_Activate Win   
Activate graphics window.

After Gwin_Activate has been called, all commands referencing the screen are rerouted to the virtual graphics screen using the number in Win. We would like to introduce two additional commands before we illustrate this on an example:

Gwin_Disactivate
Deactivate graphics window.

Gwin_Disactivate cancels the effect of Gwin_Activate, which means that all drawing commands once again reference the normal screen. Please note that you cannot output anything on the normal screen as long as a virtual screen remains active.

Important: Some EasyGem commands cancel the effect of Gwin_Activate, so that this procedure should always be called ahead of the actual output.

Our analogy of comparing windows with rectangular cut out sections in a black piece of cardboard is not quite accurate in all respects. When we are looking at the section of the book through our cardboard hole, we immediately see that part of the book that is currently not covered. But since we are not sitting in front of a smart book but instead in front of a stupid computer, the computer has to transfer the viewed section into the window every time a change to the virtual screen occurs. This process is called updating or redrawing and the corresponding EasyGem command is called:

Win_Redraw Win[,X,Y,W,H]
Update window contents.

Win_Redraw copies the visible section of the virtual screen to the real window, thus updating or redrawing the window content.
The coordinates
X,Y,W,H are the virtual screen coordinates of the visible section to be updated or redrawn. This section can also extend past the window. It is not common to indicate a section for redrawing because most of the time the entire screen has to be redrawn.
You might have noticed that this command is not called
Gwin_Redraw but only Win_Redraw. The reason for this is that Win_Redraw redraws all types of windows and not just graphics windows. We will adhere to this terminology in the future as well. All commands that can be applied to all types of windows will start with "Win".

The basic method of working with a graphics window is as follows:

1. Open graphics window using Gwin_Open.
2. Reroute output to this graphics window using
Gwin_Activate.
3. Carry out all screen outputs as usual, using either graphics commands or
PRINT.
4. Reroute output back to normal screen with
Gwin_Disactivate.
5. Redraw or update graphics window with
Win_Redraw.


Example:
COMPILER "MIN_SIZE 1000000"
COMPILER "BAS_MEM 1000000"
COMPILER "Warnings off"

Easy_Init:'Initialize EasyGem.
'Open graphics window.
T$="Graphics window":I$="Info"
Gwin_Open Win1,0,21,200,160,320,200,T$,I$
Gwin_Activate Win1:'Reroute output.
FOR R=10 TO 99 STEP 10
 CIRCLE 160,100,R:'Draw graphic.
NEXT R
Gwin_Disactivate:'Output to normal.
Win_Redraw Win1:'Redraw window.
REPEAT
 Easy_Mesag Entry,Buffer$
 Win_Domessages Buffer$
UNTIL FN Win_Closed(Win1)
Easy_Exit:'Unmount EasyGem.
END

In many cases it is desired to have a window disappear before the program is being closed. For that the following command applies:

Win_Close Win    
Close window.

However, one has to consider that it is really deleted afterwards. If the same window is supposed to be opened again at a later time, it is better to use the command Win_Hide:

Win_Hide Win    
Make window invisible.

Win_Hide is used to remove a window from the screen. In contrast to Win_Close the virtual screen remains in memory, and the window can become visible again at any time using the command:

Win_Reopen Win[,Win_X,Win_Y,Win_W,Win_H]
Reopen window.

Win_Reopen returns a window to the screen which was previously deleted with Win_Hide. The parameters Win_X,Win_Y,Win_W,Win_H correspond to those used with Gwin_Open. It is therefore possible to indicate the new dimensions of the window to be reopened at once.



4.5 Set and Query the Dimension of a Window

Because a window is really nothing more than a peephole to a screen that is not displayed itself, it is important to be able to adjust the size of that peephole. Usually, EasyGem carries out this task all by itself, for example, if the user clicks on the slider bar or sliding arrows. But in some cases it could be possible that you would like to adjust the peephole to view other sections of the virtual screen by e.g., pressing a key. Or you might want to move the window to the left side of the screen in order to be able to open another one, etc.
There are a whole string of commands for these types of tasks offered by EasyGem, which all start with "
Win," because they are valid for all types of windows:

Win_Setborder Win,Border_X,Border_Y,Border_W,Border_H
Win_Setwork Win,Work_X,Work_Y,Work_W,Work_H
Win_Setview Win,View_X,View_Y,View_W,View_H
Win_Setvirt Win,Virt_X,Virt_Y,Virt_W,Virt_H

All dimensions of the window can be set with the aid of these four procedures. The terms Border, Work, View, and Virt have already been explained. All four procedures are available in three different syntaxes, which are explained here using Win_Setborder as the model:

Win_Setborder Win,Border_X,Border_Y
Move only.
Win_Setborder Win,0,Border_W,Border_H
Size only.
Win_Setborder Win,Border_X,Border_Y,Border_W,Border_H
Set all dimensions.


Of course, there are also the corresponding procedures to query the current settings:


Win_Getborder Win,R Border_X,
R Border_Y,R Border_W,R Border_H
Win_Getwork Win,R Work_X,R Work_Y,R Work_W,R Work_H
Win_Getview Win,R View_X,R View_Y,R View_W,R View_H
Win_Getvirt Win,R Virt_X,R Virt_Y,R Virt_W,R Virt_H


The query procedure is also available in three syntaxes:


Win_Getborder Win,R Border_X,R Border_Y
Query position only.
Win_Getborder Win,0,R Border_W,R Border_H
Query size only.
Win_Getborder Win,R Border_X,R Border_Y,
R Border_W,R Border_H
Query all dimensions.

The query functions Win_Getborder and Win_Getwork function not only for windows but also for the desktop. In this case, one just passes minus one (-1) instead of the window number, that is, Win_Getborder -1,X,Y,W,H and Win_Getwork -1,X,Y,W,H, respectively.
The result will be that the entire screen including the menu line and/or the work area of the desktop - without menu line - will be returned.

Note: A window previously deleted with Win_Hide can certainly now no longer be queried.

Caution: When dimensioning text windows on the virtual screen using(View_X, View_Y, View_W, View_H, Virt_X, Virt_Y, Virt_W, Virt_H), letter sizes are used rather than screen points. A description of text windows is listed a few pages later.

The following program demonstrates the effect of
Win_Setborder:

COMPILER "MIN_SIZE 1000000"
COMPILER "BAS_MEM 1000000"
COMPILER "Warnings off"

Easy_Init
DIM Win(2):'To store the window number.
FOR I=0 TO 2:'Open window.
 Gwin_Open Win(I),0,21,-160,-100,160,100,"Window"+STR$(I)
NEXT I
Win_Getwork -1,X,Y,W,H:'Determine desktop size.
FOR I=2 TO 0 STEP -1:'Arrange windows one below the other.
 Win_Setborder Win(I),X,Y+(H\3)*I,W,H\3
NEXT I
REPEAT
 Easy_Mesag Entry,Buffer$
 Win_Domessages Buffer$
 W0=FN Win_Closed (Win(0))
 W1=FN Win_Closed (Win(1))
 W2=FN Win_Closed (Win(2))
UNTIL W0 AND W1 AND W2
'Wait until all windows have been closed.
Easy_Exit:'De-register EasyGem.
END

You can maximize a window with the previously discussed commands; the following command, however, facilitates this task:

Win_Full Win
Maximize window.

This command has the same effect as clicking on the full field (second field from the right in title bar). However, if the window is already maximized, Win_Full does not return the window size to its old value.

In addition to the size of a window, one would, of course, also like to adjust and query other attributes such as the texts in title and info line, the increments for scrolling, or the type of a window. Once again, EasyGem offers a series of procedures and functions that will accomplish those tasks. They are as follows:

Win_Name Win,Name$ 
Modify window name.
FN Win_Name$(Win)  
Query window name.

The name of the window will always be displayed in the header.

Win_Info Win,Info$ 
Change information line.
FN Win_Info$(Win)
Query information line.
 
Caution: If the window has been opened without information line, it is also impossible to add one subsequently.
 
Win_Infoheight(Win,H)
Sets height of information line.
FN Win_Infoheight(Win)
Queries the height of information line.

If you would like to set some output in the info line yourself or would like to place free controls into the info line, you usually have to adjust the height of the info line. Use the procedure Win_Infoheight to set the height for each window individually with H indicating the desired height.
It might be necessary in a few cases to rather place output in a real window on the screen than in a virtual window. What is important to remember here is that the info line is managed by EasyGem but is still associated with the window content. In order not to overwrite the info line in such cases, use the function
FN Win_Infoheight to ascertain the info line height and then use that value to add to the y-coordinates of your drawing commands as an offset.

Win_Setstep Win,Step_X,Step_Y   
Modify scrolling increment.

Clicking on the scroll arrows in the border area of windows causes the work area of a graphics and user window to scroll by 8 pixel, whereas the text window will scroll by 1 character. These default settings can be modified using Win_Setstep. The X and the Y direction have to be set independently.

Win_Getstep Win,R Step_X,R Step_Y 
Query scrolling increment.

This command returns the current scrolling increment setting for the window with the number Win in Step_X and Step_Y .

FN Win_Kind(Win)  
Determine structure of marginal area.

The return value contains the flags that have been passed in Kind when the window was opened. For example, to determine if a window contains a close field, one can write the following:

IF FN Win_Kind(Win) AND G_Close THEN ...

FN Win_Type(Win)           
Determine window type.

This function's result yields information whether the window with the number Win is closed or whether it is a text, graphics, user window, or a dialog box. The function value has then the following significance:

0 : The window is closed.
1 : It is a text window.
2 : It is a graphics window.
3 : It is a user window.
4 : It is a non-movable modal dialog box.
5 : It is a movable modal dialog box.
6 : It is a movable modeless dialog box.

FN Win_Closed(Win)       
Determine if window has been closed.

You can use this function to determine if a window is currently open or closed. The number of the window, whose status you want to query, is passed in Win. The function returns 0 if the window is open and -1 if the window is closed or has never been opened.

FN Win_Visible(Win)       
Determines if window is visible.

Remember, an open window does not mean that this window is also visible. For example, you can use Win_Hide to remove a window from the screen without closing it first. To really determine if an existing window is actually visible, use the function FN Win_Visible. The function returns -1 if the window is visible and 0 if the window is hidden.

FN Win_Collapsed(Win)       
Determine if window has been collapsed.

You can use this function to determine if a window is currently collapsed. The number of the window, whose status you want to query, is passed in Win. The function returns 0 if the window is open and -1 if the window has been collapsed.

Win_Setflags Win,Flags 
Change flags of window numbered in Win.
FN Win_Getflags(Win)  
Query flags of window numbered in Win.

These two commands serve to influence the behavior of the Window Library. Currently, the lowest 4 bits are assigned.

Bit 0: If sections of a user window have to be redrawn, EasyGem normally fills these areas with the background color. However, if your own redraw function also fills the entire area, any prior deletion is unnecessary. Setting the lowest bit with the command
Win_Setflags Win,FN Win_Getflags(Win) OR %1 can be used to suppress this deletion.

Bit 1: Has the same function as the bit 0 but applies only to the info line. Setting this bit makes only sense, of course, if you place your own output into the info line.

Bit 2: Clicking on the scroll arrows usually has the effect that the window content is shifted by moving the window section by the scroll width across the screen with only the generated invalid area being redrawn. If this bit is set, the entire window is redrawn when scrolling, which yields better scroll results (less jerking) when using graphics and user windows featuring quick redraw functions.

Bit 3: This suppresses the so-called smart scrolling (the window content follows the movements of the slider in the scroll bar). Smart scrolling is available only starting with Mac OS 8.5.

If you have used Win_Domessages before, then you are familiar with the possibility of defining your own action function, which is then called by EasyGem as soon as the user wants to close a window. The following procedures may also be used to define action functions for other events.

Win_Topaction Action
Defines action function for topping windows.
Win_Moveaction Action
Defines action function for moving windows.
Win_Sizeaction Action
Defines action function for resizing windows.
Win_Closeaction Action
Defines action function for closing windows.

You have to use Action to pass the respective address of one of the functions defined by you. EasyGem then calls this function as soon as the user has executed the corresponding operation. Your action function has to have one parameter:
Action=&FN My_Action()
DEF FN My_Action(Win)
...
END_FN
In Win,the window identification number is passed to your function. In the case of Win_Topaction and Win_Closeaction, you can still decide whether the window is really to be topped and/or closed by returning the function value -1 (execute function) or 0 (do not execute function).

The other action functions are not called until the operation has already been carried out. For example, you can use
Win_Sizeaction to simultaneously move controls that have been defined at the lower edge of the window, which means that they remain at the lower edge even after the window size has been changed. Another example for the utilization of action functions is illustrated by EasyPaint.BAS in the DEMO folder.

For pros: There are two additional functions for professionals and those of us who strive to become just that: These two additional functions return the 'WindowPtr' of the window with the number Win or, in the case of graphics windows, also the 'GWorldPtr'. We are dealing here with pointers to special structures, which are explained in "Inside Macintosh, Toolbox Essentials" and "Imaging with Quick Draw ", respectively. These pointers are needed if you want to apply Mac OS functions directly to EasyGem windows:

FN Win_Ptr(Win) 
Return the 'WindowPtr'.
FN Gwin_Ptr(Win)
Return the 'GWorldPtr'.
      


4.6 The Sequence of Windows

If more than one window is opened, it is only natural that a certain sequence or order is established among the different windows. One of the windows is always marked ( is displayed above all others), and is the only one to feature active control elements. This window will have visible slider bars; the moving bar contains a grid, and the close, full, and dimension fields contain all appropriate symbols. All other windows, however, do not have any control elements.
In order to bring one window to the foreground or to determine which window is currently in the foreground, EasyGem offers the procedure
Win_top and the function FN Win_Whichtop:

Win_Top Win
Bring window to the front/top.

This procedure places the window above all of the others, that is, no other window will overlap it. All fields and slider bars of the so activated window are now usable - in contrast to any perhaps underlying other, not active windows.

FN Win_Whichtop  
Determine the number of the active document window.
FN Win_Floattop
Determine the number of the active float window.

FN Win_Whichtop returns the number of the document window that is currently located in the foreground. In other words, the searched window is the one that overlaps all others. A result of zero indicates that no EasyGem window is currently active, which means that either no window has been opened at all, or another program has the active window.

Remember, starting with Mac OS 8.6 you can also define float windows. These are ignored by
FN Win_Whichtop, because it would otherwise be impossible to determine the uppermost document window. In order to find out, which float window is the uppermost one, use the function FN Win_Floattop. Both functions return the same result if no float windows are open.



4.7 The Query of the Mouse in a Window

The user might move the mouse, use the mouse button or a key on the keyboard - these are all events your program needs to know in order to be able to respond correctly. If several programs are running parallel, only the currently active program should receive reports about these events. If you were to use the BASIC command
MOUSEBUT and INKEY$ to query the mouse button and the keyboard, you would receive a report about each and every key being pressed, even if it was never intended for your program. Therefore, EasyGem features the expanded function of Easy_Mesag, which reports only the messages intended for your program:

Easy_Mesag R Entry,R Buffer$,R Mx,R My
[,R Mb[,R Modifier[,R Clicks]]]

Mx and My define the mouse position.
Mb represents the status of the mouse button.
Modifier is the status of the so-called modifier keys (Command, Shift, Control, Alternate, Caps Lock).
Clicks returns the number of mouse clicks (1=normal, 2=double-click, 3=tripple-click etc.).

Note when using a mouse with two or three buttons:
Program your multiple button mouse in such a way that the second mouse button works like [Cmd]+[Return] and the third like [Alt]+[Return]. Then you will receive values between 0 (no button pressed) and 7 (all three buttons pressed) in
Mb. Of course, you can also assign a double-click to the middle button and use the right mouse button as the second button or assign any other desired combination.

Only the procedure
Win_Mousepos is required to ascertain now in which window in which location of the virtual screen the user clicked with the mouse button. This is a rather important command, if the mouse is supposed to be usable within a window because Win_Mousepos returns the number of the window over which the mouse is currently located. At the same time, it converts the screen coordinates into virtual coordinates.

Win_Mousepos R Win[,Xin,Yin],R Xout,R Yout
Determine mouse position.

Win will return to you the number of the window over which the mouse is located. A zero indicates that it is not an EasyGem-window .
Xin and Yin can be omitted. Then you will receive the mouse position on the virtual screen that belongs to the window with the number Win in Xout and Yout.
However, it is also possible to pass any desired position on the real screen in
Xin and Yin, which then will be converted into the corresponding virtual coordinates and returned in Xout and Yout. If Win is the number of a text window, then the result will not be in pixel but in letter sizes.

Example:
COMPILER "MIN_SIZE 1000000"
COMPILER "BAS_MEM 1000000"
COMPILER "Warnings off"

Easy_Init
Gwin_Open Win1,0,21,-320,-200,320,200,"Window 1"
OUTLINE OFF
REPEAT
 Easy_Mesag Entry,Buffer$,Mx,My,Mb,Modifier
 Win_Domessages Buffer$
 IF Mb THEN
  Win_Mousepos Win,X,Y
  IF Win=Win1 THEN
   'With Shift-key: deletes points, otherwise sets them.
   IF Modifier SHR 8 AND 2
    THEN FILL COLOR =0
    ELSE FILL COLOR =1
   ENDIF
   Gwin_Activate Win1
   PBOX X,Y,5,5:'Draw point on virtual screen.
   Win_Redraw Win1,X,Y,5,5:'Redraws window.
  ENDIF
 ENDIF
UNTIL FN Win_Closed(Win1)
Easy_Exit
END




4.8 Text Windows

Of course, you can also output text in graphics windows. The disadvantage is that the information will be saved in pixel, which can result in a large memory consumption. It is also difficult to edit the text, since the information is processed as a picture and you are unaware of which character is located at which location. Easy Gem therefore makes special text windows available for the output of long texts (e.g., measuring results) or the editing of texts (text entry). These windows store the information not in pixel but in characters.
The maximum width of such a window can be 32766 characters. The number of lines is limited to 5000 for all text windows together through the default setting; however, this setting may be increased so that for all practical purposes, the size of your documents is only limited by the amount of available memory.
And this brings us to the first command for text windows:

Twin_Maxspace Lines  
Sets the maximum number of text lines for text window.

Using this command will allow you to reserve more lines for text windows. You indicate in Lines how many lines all text windows combined will require. Twin_Maxspace should be called directly after Easy_Init, because Twin_Maxspace redimensions a string field. Of course, an alternative would be to use the expanded command Easy_Init to receive more space for your text window.

Important: The content of the text window is stored in string fields. Therefore, you have to ensure that the string heap has a sufficient amount of BASIC memory by using COMPILER "BAS_MEM X." To estimate the approximate amount needed, just multiply the width of the text window with its height and then multiply the result with three. You will then have enough space for your text windows.

EasyGem manages virtual text windows for you with the following options:

Virtual text windows of any height and with a width of max. 32766 characters.
Each window may be assigned its own character set with all attributes.
Windows with their own input and output commands with many variations.
Output to virtual text window is immediately visible on the real screen.

Semiautomatic management of text blocks.
Support of the clipboard (Cut, Copy, Paste).
Commands to load and save text.
Commands to print text.


All text window commands start with
"Twin_" , which ensures a clear grouping right from the start.
Of course, in order to be able to work with text windows, one has to open such a window first. The following command achieves this task:


Twin_Open R Win,Win_X,Win_Y,Win_W,Win_H
[,Virt_W,Virt_H],Name$

Twin_Open R Win,Win_X,Win_Y,Win_W,
Win_H,Virt_W,Virt_H, Name$, Info$[,Kind]
 
Open text window.

Twin_Open has the same parameters as Gwin_Open, the only difference is that Virt_W and Virt_H are indicated in letters and not in picture pixel. We therefore will omit a repeated description here, but should you be unsure about the significance of this parameter, please read up about it under Gwin_Open.

Note: Text window commands can be applied only to windows that have been opened with the command Twin_Open.

Now that you know how to open a text window, you probably would like to display something in it as well. Use the following command for this task:

Twin_Print Win[[,Y,X],Txt$] 
Output text and start new line.
Twin_Print_ Win[,Y,X][,Txt$] 
Output text without starting new line.

Twin_Print is the counterpart to the BASIC command PRINT. Twin_Print Win will print nothing but an empty line. If Txt$ is indicated as well, the text will appear at the current cursor position. If Y and X are also given, then you can position the cursor before the text is displayed just like with the BASIC command PRINT @(Y,X) . The most important control sequences of the VT52 emulator are actually interpreted correctly. Applicable escape codes are: A, B, C, D, E, H, I, J, K, L, M, Y, d, l, o. Their significance is explained in the Omikron Basic Manual.
The command
Twin_Print triggers a line feed exactly the same as the BASIC command PRINT "TEXT". In order to deactivate the line feed, a semicolon is written in BASIC behind the text: PRINT "TEXT";
In order to deactivate the line feed with
Twin_Print, Twin_Print_ is used, that is, Twin_Print with an added underscore character.

Note: Twin_Print_ does not exist with a parameter, of course, since this command would only trigger a line feed, which would be suppressed by the underscore immediately; this command would therefore have no effect at all.

Example: 
COMPILER "MIN_SIZE 1000000"
COMPILER "BAS_MEM 1000000"
COMPILER "Warnings off"

Easy_Init
Twin_Open Win1,0,21,-240,-320,35,20,"Text window","Info"
FOR I=1 TO 10:'Output 10 lines of text.
 Twin_Print Win1,"This is the"+ STR$(I)+". line."
NEXT I
REPEAT
 Easy_Mesag 0,Buffer$:'The first parameter is 0, since we have no menu.
 Win_Domessages Buffer$
UNTIL FN Win_Closed(Win1)
Easy_Exit
END

What occurs often is that one would like to write the text to the virtual screen first and then redraw and update the entire window at once using Win_Redraw. This procedure will speed up output significantly if many text entries are being made in a row. The flickering of the screen during output will also be avoided. The following commands corresponding with Twin_Print are used for this task:

Twin_Iprint Win[[,Y,X],Txt$]
Output text virtually and start new line.
Twin_Iprint_ Win[,Y,X][,Txt$]
Output text virtually without starting new line.

Here, the "I" means "internal" and indicates that the operation is carried out only on the internal virtual screen.
Since there are additional commands for text windows, which are also available in an internal version, we will from here on out write these below the normal commands without giving any detailed explanations.

Use the following command if you wish to clear the entire virtual text screen:

Twin_Cls Win 
Clear text screen and immediately display result.
Twin_Icls Win 
Clear text screen.

The cursor is brought to the position (0,0) - just like when using the BASIC command CLS - and the virtual screen is being cleared.

Sometimes it is necessary to scroll the virtual text up or down, for example, because one does not require the information located at the beginning or end any longer, or because the space for the intended output is insufficient. Mind you, we are not talking about scrolling in the real window, but scrolling in the virtual text screen. Lines, which have been scrolled out, are therefore lost and not only invisible!

Twin_Scrollup Win[,N]
Scroll text window to the top and immediately display result.
Twin_Iscrollup Win[,N]
Scroll text window to the top.

Twin_Scrolldown Win[,N]
Scroll text window to the bottom and immediately display result.
Twin_Iscrolldown Win[,N]
Scroll text window to the bottom.

Twin_Scrollup pushes a virtual text screen up by N lines. The lower N lines are afterwards empty. The scrolled out text has been lost. Accordingly, Twin_Scrolldown moves all lines down. If N is omitted, the scrolling increment is one line.

Example:
COMPILER "MIN_SIZE 1000000"
COMPILER "BAS_MEM 1000000"
COMPILER "Warnings off"

Easy_Init
Twin_Open Win1,0,21,-240,-128,80,8,"Text window","Info"
T= TIMER
FOR I=1 TO 26:'Output letters A to Z.
 Twin_Print Win1,CHR$(64+I)*80
NEXT I

Win_Info Win1,"Normal Print:"+ STR$(( TIMER -T)/200)+" sec"
'The same once more internally.
Twin_Open Win2,40,61,-240,-128,80,8,"Text window","Info"
T= TIMER
FOR I=1 TO 26:'Output letters A to Z.
 Twin_Iprint Win2,CHR$(64+I)*80
NEXT I
Win_Redraw Win2
Win_Info Win2,"Internal Print:"+ STR$((TIMER -T)/200)+" sec"
REPEAT
 Easy_Mesag 0,Buffer$
 Win_Domessages Buffer$
UNTIL FN Win_Closed(Win1) OR FN Win_Closed(Win2)
Easy_Exit
END

A more direct option also exists in addition to the Print commands, which may be used to modify or query the content of a text window. For this operation, the indicated text is written to the virtual text window directly without evaluating the therein contained control characters (escape sequences, see above).

Twin_Setline Win,Y,Txt$
Set text window line.
FN Twin_Getline$(Win,Y)
Get text window line.
FN Twin_Getlen(Win,Y)
Determine length of text window line.

The content of the line Y of the window with the number Win is queried or modified, respectively.
These functions are quite useful if you would like to write new input functions or want to save or print the content of a window.
The function
FN Twin_Getlen does not return the widths of the virtual text screen but rather the actual length of the text in line Y. The result can therefore be also zero, namely if no text is located in the indicated line.

An often occurring task is having to insert some text into the continuous text of a window or having to remove a certain amount of characters from the text. Two EasyGem commands will take care of these tasks as well:

 
Twin_Insert Win,Y,X,Txt$
Insert text.
Twin_Iinsert Win,Y,X,Txt$
Insert text only virtually.
Twin_Delete Win,Y,X,N
Remove text.
Twin_Idelete Win,Y,X,N
Remove text only virtually.

These four procedures work in such a way as to wrap the following lines to prevent words being cut and separated right in the middle. Hyphenation only takes place in those locations where a fill character is located.
Txt$ contains the text to be inserted and N the amount of characters to be removed.

Caution: The internal commands are only functional on the virtual screen. In order to make the result visible, you subsequently have to update the real window using Win_Redraw.

We already mentioned that it is possible to modify the cursor position with Twin_Print_ , but sometimes it is nice to know where the cursor is currently located. The following two query functions take over that task:

FN Twin_Csrlin(Win)   
Determine current cursor line.
FN Twin_Pos(Win) 
Determine current cursor column.

These two functions are a pendant to the BASIC functions CSRLIN or POS, respectively, with the only difference that with FN Twin_Csrlin, counting starts at zero and not at one (1).



4.9 Setting and Querying of Text Attributes

With EasyGem it is possible to assign individual text attributes to each text window. For example, you therefore can work in a bold blue font in one window and with a normal yellow font on a black background in the other. Of course, all other attributes such as text size and text style may be modified as well. The following commands and functions may be used for these tasks:

Twin_Setfont Win,Font_No
Set the text font.
FN Twin_Getfont(Win)    
Return the set text font.

The identification number of the desired font has to be passed in Font_No (e.g., Monaco=4, Courier=22). Should you only know the name of the font and not its number, then you can use the function FN Get_Font_Number from the Extension Library in order to determine the proper identification number.  

Twin_Setsize Win,Font_Size    
Set text size.
FN Twin_Getsize(Win)    
Return the set text size.

The default is 13 points. Any other value may be used for Font_Size as well, of course.

An additional command to set text size included for reasons of compatibility to older EasyGem versions is:

Twin_Settextsize Win,Font_Size      
Change text size.

In this case, the values in Font_Size are interpreted as follows:
0 = 8 points, 1= 10 points, 2= 13 points, and all other numbers the same way as with
Twin_Setsize.

Twin_Setface Win,Font_Face
Set the text style.
FN Twin_Getface(Win)    
Return the set text style.

This may be used to modify or query the text style. Flags, as described in the Omikron Basic Manual under TEXT STYLE, have to passed in Font_Face.

Twin_Setbackcolor Win,Font_Backcolor    
Set the background color.
FN Twin_Getbackcolor(Win)       
Return the set background color.

Twin_Setforecolor Win,Font_Forecolor    
Set the text color.
FN Twin_Getforecolor(Win)             
Return the set text color.

These four commands may be used to set or query the background or foreground color. Just as in the BASIC command TEXT COLOR, the color is identified with an index.

It is often quite practical to know how many text lines or columns might fit into any given real window. In order to determine this, one has to first know the height and width of a character. EasyGem features two functions that will return the current values when called, which, as we know, depend on the just set text attributes.

FN Twin_Cellwidth(Win)           
Determine width of letters.
FN Twin_Cellheight(Win)         
Determine height of letters.

This means that these two functions can be used to determine the amount of needed space for one letter.




4.10 Inputs in Text Windows

Let's start first with the easiest input, the input of one single character. Omikron Basic features the command
INKEY$ to determine at any time whether a key has been pressed or not. A similar command exists in EasyGem as well:


Twin_Inkey Win    
Cause input of a character.

Initially, the command Twin_Inkey has no effect other than to cause EasyGem to watch out for the pressing of a key, which might occur while the window with the number Win is the active EasyGem window.
The procedure
Win_Domessages now manages not only all window events, but it also checks at regular intervals whether a key has been pressed. If that is the case, then the key code is remembered and assigned to the active window. But you still do not know which key has been pressed. In order to find out, the following function exists:

FN Twin_Inkey(Win)          
Query input of a character.

The function Twin_Inkey returns the result zero if no key has been pressed, otherwise a long integer number with information about the pressed key is returned. The ASCII code is in the byte with the lowest value, the second is always zero, the third contains the virtual code, and the byte with the highest value contains the modifier keys. The information is here coded the same way as with the BASIC command INKEY$.
Even though
FN Twin_Inkey may be queried as often as desired, it will return the same result until the command Twin_Inkey has been called again.

Example:
COMPILER "MIN_SIZE 1000000"
COMPILER "BAS_MEM 1000000"
COMPILER "Warnings off"

Easy_Init
N$="Twin_Inkey-Test":I$="End with Esc-key"
Twin_Open Win1,0,21,-240,-340,80,25,N$,I$
REPEAT
 Twin_Print_ Win1,"Please, press any key:"
 Twin_Inkey Win1:'Activates keyboard check.
 REPEAT
  Easy_Mesag 0,Buffer$
  Win_Domessages Buffer$
  IF FN Win_Closed(Win1) THEN Easy_Exit :END
 UNTIL FN Twin_Inkey(Win1):'Until a key has been pressed.
 A=FN Twin_Inkey(Win1):'Which key has been pressed?
 Twin_Print Win1:'Displays result.
 Twin_Print Win1,"The ASCII code is:"+STR$(A AND 255)
 Twin_Print Win1,"The virtual key code is:"+STR$(HIGH(A) AND 255)
 Twin_Print Win1,"The modifier keys are:"+STR$(A SHR 24)
 Twin_Print Win1
UNTIL FN Win_Closed(Win1) OR (A AND 255)=27
'Until window is closed or Esc-key has been pressed.
Easy_Exit
END
If you would like to cancel keyboard monitoring for a specific window prematurely - before a key has been pressed - use the following command:

Twin_Inkey_Clear Win          
Cancel input.

The command Twin_Inkey_Clear cancels the input inside a window prematurely and applies to a simple character input (Twin_Inkey) as well as to the command Twin_Input, which we will discuss next.

You are probably familiar with the
INPUT command from using BASIC. It can be used to input single characters as well as entire lines and it is still possible to edit any input (arrow keys, Backspace, insert, delete ... ) before the input becomes final with [Return].
Omikron Basic's command
INPUT USING accomplishes this task even more comfortably. Essential parameters may be defined ahead of time, e.g., the character string to be edited, the max. input length, the fill characters up to the max. input length, the cursor position within the input, which characters are even permitted, and which keys are to end input.
All of these options are also offered by EasyGem with this command:

Twin_Input Win[,Def$[,Usng$[,Length[,F_Char[,Posn]]]]  
Input of one line.
Twin_Input Win,Y,X,Def$,Usng$,Length,F_Char,Posn  
Input of one line with positioning.

Win is the number of the window in which the input is supposed to take place.
Def$ is the text that will be displayed in the input initially. If Def$ is not indicated, the initial input is empty.
Usng$ is a character string indicating which characters are permitted. The Omikron Basic Manual explains more about this under INPUT USING. If Usng$ is not indicated, all characters are permitted.
Length denotes the max. length of the input. If a max. length is not given, it is possible to insert input up to the last column of the virtual screen.
F_Char contains the ASCII code of the fill characters up to the max. input length. If F_Char is not recorded, then either 95 is assumed (underlining up to the max. length) or 0 (no fill character if no max. length has been denoted).
Posn serves to adjust the cursor position. If Posn is not indicated, the cursor position initially is located to the very left of the input line.

A blinking cursor and the default text or input mask, respectively, will first appear after
Twin_Input has been called. In order for EasyGem to monitor the keyboard and react to possible future inputs, it is necessary to call Easy_Mesag and Win_Domessages at regular intervals.

FN Twin_Input(Win)          
Test whether the input of one line has been concluded.

The function results in 0 if input has not been concluded yet and not 0 (unequal 0) if the input has already been concluded. The following applies:
-1 : Input is terminated because the left margin has been exceeded.
-2 : Input is terminated because the right margin has been exceeded.
>0: This function returns a value containing the cancel key same as in
FN Twin_Inkey.

The key that has triggered the end of input can still be determined later using
FN Twin_Inkey.

FN Twin_Input_Pos(Win)          
Return the X-position of the cursor within the input line.

This function returns the current cursor position within the input line.

FN Twin_Input$(Win)          
Return the entered string.

This may be applied to query which text in the window with the number Win was input at the very end.

Twin_Input_Fullbuff          

This procedure has no longer any significance and is only included for reasons of compatibility with older versions of EasyGem.

Example:
COMPILER "MIN_SIZE 1000000"
COMPILER "BAS_MEM 1000000"
COMPILER "Warnings off"

Easy_Init
Win_Closeaction &FN Closeaction()
Win_Getwork -1,X,Y,W,H:'Determine desktop size.
Twin_Open Win1,X,Y,W,H,80,25,"Text"
REPEAT
 Twin_Print Win1,"Please, indicate your name:"
 Twin_Input Win1,"Carrie Carefree","á%0",35,95,5
 REPEAT
  Easy_Mesag 0,Buffer$
  Win_Domessages Buffer$
 UNTIL FN Twin_Input(Win1) OR FN Win_Closed(Win1)
 IF FN Win_Closed(Win1)=0 THEN
  Twin_Print Win1
  A$=FN Twin_Input$(Win1)+" is a nice name."
  Twin_Print Win1,A$
 ENDIF
UNTIL FN Win_Closed(Win1)
Easy_Exit
END

DEF FN Closeaction(Win):LOCAL A$
 A$="[2][You really do not want to|give a name?][ Yes |I do]"
 FORM_ALERT(1,A$,R)
 RETURN R-2
END_FN

Sometimes it is necessary to edit the entire text of a window instead of just one line. The following EasyGem command applies this:

Twin_Fullinput Win[,Y,X[,Usng$[,F_Char]]]      
Edit the entire text.

The significance of the parameters is the same as for Twin_Input. The only difference lies in the fact that the entire text of a window is being edited. If, for example, the inserted text of the sample does not fit into the current line, the following text is automatically wrapped to the next line. With that EasyGem makes sure that words are not broken up. Line divisions thus occur only at the fill characters or at paragraphs. The following lines move up automatically even if pieces of text are deleted.
Paragraphs can be created with [Return]. In that case, a new line is opened, and the cursor is placed at the beginning of the new line.
This command therefore allows the easy programming of a simple text editor such as the one created in the sample program EasyPaint.BAS in the DEMO folder.



4.11 User Windows

So-called user windows allow you a maximum amount of leeway when determining the window content. But since EasyGem can no longer know what your user window now contains and how it is to be displayed, a user window is the programmer's responsibility. To facilitate these tasks, the command for opening a user window is equipped with one additional parameter, which has to be indicated with all variations and contain the address of a function, which you have to define yourself and which is called by EasyGem any time the window or parts of that window have to be redrawn. As you can see, even in the case of user windows EasyGem relieves you of the burden of monitoring the control elements.

Uwin_Open R Win,Win_X,Win_Y,Win_W,Win_H
[,Virt_W,Virt_H],Name$,Redraw
Uwin_Open R Win,Win_X,Win_Y,Win_W,
Win_H,Virt_W,Virt_H,Name$,Info$[,Kind],Redraw

Thus, the parameters are the same as for Gwin_Open. The only new item is Redraw, which has to contain the reference address to one of the functions defined by you. This function has to take 7 parameters and therefore has to have the following basic structure:
DEF FN My_Redraw(Win,X,Y,W,H,X_Offset,Y_Offset)

Win will contain the number of the window having to be redrawn.
X,Y,W,H denote the rectangular on the virtual screen which has to be updated.
X_Offset,Y_Offset contain an offset calculated by EasyGem, which takes into consideration all parameters such as position of the sliders, existence of an info line, etc., so that this offset need only be subtracted from your virtual coordinates in order to update the correct area in the real window. If your function was unable to redraw the indicated area, it should return the value -1 and otherwise 0.
Of course, all of this sounds very theoretical right now and therefore we want to try to illustrate the whole subject with an example. You will find the programs EasyFractal.BAS and EasyPaint.BAS in the DEMO folder, which are programs also demonstrating the handling of user windows.

The following example manages a virtual user screen with a pixel size of 2000x2000, containing only circles:

COMPILER "MIN_SIZE 1000000"
COMPILER "BAS_MEM 1000000"
COMPILER "Warnings off"

Easy_Init
T$="User window":I$=" Information"
Redraw=&FN Redraw_Circle(0,0,0,0,0,0,0)
Uwin_Open Win1,0,21,300,300,2000,2000,T$,I$,Redraw
Win_Setview Win1,850,0:'Make upper middle of Win1 visible.
REPEAT
 Easy_Mesag 0,Buffer$
 Win_Domessages Buffer$
UNTIL FN Win_Closed(Win1)
Easy_Exit
END

DEF FN Redraw_Circle(Win,X,Y,W,H,X_Offset,Y_Offset)
 LOCAL Xm=1000,Ym=1000,K#,T
 K#= SQR(.5)
 FOR R=0 TO 1000 STEP 20
  'Now we first have to find out if parts of this circle
  'can pass through the rectangular X,Y,W,H.
  T=R*K#:'Length of side of the square within the circle/2.
  'Area in enclosing square?
  IF ABS(Xm-X)<R OR ABS(Xm-X-W)<R OR ABS(Ym-Y)<R OR ABS(Ym-Y-H)<R
   THEN'Area outside of the square located within the circle.
    IF ABS(Xm-X)>T OR ABS(Xm-X-W)>T OR ABS(Ym-Y)>T OR ABS(Ym-Y-H)>T
     THEN CIRCLE Xm-X_Offset,Ym-Y_Offset,R
    ENDIF
  ENDIF
 NEXT R
 RETURN -1
END_FN

As you can see with this example, it is possible to manage a very large virtual screen (2000 x 2000 pixel) without any additional memory usage if user windows are being employed. A graphics window would have used 4 million bytes with 256 colors and even 16 million in case of a True Color resolution for the same example.
Of course, you can display any other object and even text in your user window besides circles. You just have to manage it all yourself, since EasyGem cannot know what is supposed to be in your window.
Please, also view the sample program EasyPaint.BAS in the DEMO folder. This program demonstrates how to handle user windows to define easy tool boxes for a paint program.

Note: Since no content and display defaults exist for user windows, EasyGem is also unable to support your programming with special procedures and functions as decidedly as during the programming of text or graphics windows. Thus, few special commands exist for user windows. Of course, you may use all commands starting with "Win" for user windows as well.

In a few instances it might be advantageous to output directly into a real window. The following command applies to that task:

Win_Activate Win    
Reroute output to real window.

The window is considered as a local graphics port. The point (0,0) is here located in the interior of the window in the upper left corner above the info line! If you should therefore desire to draw into a window directly, you have to add the height of the info line to the Y coordinates first in order to prevent the info line being typed or drawn over.



4.12 Rubber Band Commands for Graphics and User Windows

Graphics applications often require the display of flexible or elastic lines, rectangulars, circles, etc., which follow the mouse movement like a rubber band and allow the user to define basic geometrical shapes. EasyGem features a variety of procedures for these types of tasks, which will be discussed in the following paragraphs.

Elastic_Line Win,X1,Y1,R X2,R Y2,R Mb[,Action]
Display flexible line.
Elastic_Rect Win,X,Y,R W,R H,R Mb[,Action]
Display flexible rectangular.
Elastic_Roundrect Win,X,Y,R W,R H,R Mb[,Action]
Display flexible rectangular with rounded corners.
Elastic_Circle Win,X,Y,R Ra,R Mb[,Action]
Display flexible circle.
Elastic_Ellipse Win,X,Y,R Rx,R Ry,R Mb[,Action]
Display flexible ellipses.

All of these share the required passing of a window identification number as well as the passing of the start position (in virtual coordinates) within the first three parameters.
Elastic_Line returns in (X2,Y2) the end point of the rubber band line.
Elastic_Rect and Elastic_Roundrect return in W and H the width and height of the created rectangular.
Elastic_Circle returns in Ra the radius of the created circle.
Elastic_Ellipse returns in Rx and Ry both of the half axis of the rubber band ellipses.
As long as
MOUSEBUT=1,that is, as long as the mouse button has been pressed without any additional modifier keys (Cmd, Alt ...), EasyGem takes over the control over the mouse movements after an elastic command has been called. Once the mouse reaches the edge of the window, the window will be automatically scrolled further, so that the rubber band can stretch across the entire virtual window.
If the user releases the mouse button or presses an additional modifier key, the respective procedure returns and passes in
Mb the value of MOUSEBUT - which caused the cancellation - to your program.
Because several ways to cancel or terminate do exist, your program may react differently, e.g., in case of a normal cancellation it might draw the object, in case of canceling with the Cmd-key it might not.

Note: The currently selected type of rounded corner is applied to the drawing when using Elastic_Roundrect. The roundings can be adjusted with the command Set_Roundings from the Extension Library.

If needed you can also pass the address of an action function in
Action (&FN My_Action(,,)), which is going to be called by EasyGem at every mouse movement and which, for example, could display the current mouse position on the info line.
The action function has to take three parameters in which the window identification number and the mouse position on the virtual screen are passed; in case of text windows, of course, once again in letters instead of pixel.

Example:
DEF FN My_Action(Win,X,Y)

See also the program EasyPaint.BAS in the DEMO folder.




4.13 Blocks in Windows

Quite often a programmer would like to highlight or mark certain areas of a window, either to cut or copy the content of these highlighted areas or to process them in some other task. In order to facilitate and aid these types of tasks significantly, EasyGem features block functions, which carry out almost all work for you. The commands have a structure similar to those used to set and query the windows' dimensions, with the only difference that in cases of text windows, the position of the first and last letter have to be indicated:

Gwin_Setblock Win,X,Y
Modify only beginning of block.
Gwin_Setblock Win,0,W,H
Modify only block size.
Gwin_Setblock Win,X,Y,W,H
Modify beginning and size of block.

Twin_Setblock Win,X1,Y1
Modify only beginning of block.
Twin_Setblock Win,0,X2,Y2
Modify only end of block.
Twin_Setblock Win,X1,Y1,X2,Y2
Modify beginning and end of block.

Uwin_Setblock Win,X,Y
Modify only beginning of block.
Uwin_Setblock Win,0,W,H
Modify only block size.
Uwin_Setblock Win,X,Y,W,H
Modify beginning and size of block.

The coordinates of the block (X,Y,W,H or X1,Y1,X2,Y2), respectively, have to be indicated as virtual coordinates. The block becomes immediately visible in the real window as soon as the command has been executed. One can recognize a block in a text window by its inverted colors, while marked areas in graphics and user windows are surrounded by a thin, moving dotted line with the dots running continuously from the upper left to the bottom right.
Just indicate four zeros as the parameter if you would like to remove the marking again.

Of course, the option to query a defined block has to exist as well and would return its starting and ending points. The following query functions apply:

Gwin_Getblock Win,R X,R Y
Query only beginning of block.
Gwin_Getblock Win,0,R W,R H
Query only block size.
Gwin_Getblock Win,R X,R Y,R W,R H
Query beginning and size of block.

Twin_Getblock Win,R X1,R Y1
Query only beginning of block.
Twin_Getblock Win,0,R X2,R Y2
Query only end of block.
Twin_Getblock Win,R X1,R Y1,R X2,R Y2
Query beginning and end of block .

Uwin_Getblock Win,R X,R Y
Query only beginning of block
Uwin_Getblock Win,0,R W,R H
Query only size of block.
Uwin_Getblock Win,R X,R Y,R W,R H
Query beginning and size of block.

Note: Starting with Omikron Basic 6.17, negative values may also be indicated for W and H. In that case the block will be constructed starting from the point (X,Y) and leading to the left or the top, respectively.

Important: The parameters behind the block commands have to be indicated in letters for any text windows and in pixel for any graphics and user windows.

The block functions may be used to define and select any desired area of the virtual screen while the program is running. But one would also usually like to have the option to define a block with the mouse (pull up a block). Such a routine could be programmed easily by yourself using the functions listed above, but you can be relieved of this task by EasyGem, namely through the use of the following commands:

Gwin_Select Win,X,Y,R W,R H[,Action]
Select block in graphics window.

Twin_Select Win,X1,Y1,R X2,R Y2[,Action]
Select block in text window.

Uwin_Select Win,X,Y,R W,R H[,Action]
Select block in user window.

Pass the current mouse position on the virtual screen in (X,Y) or (X1,Y1), respectively, as the starting point of the block as soon as the mouse is located within the window and the user has pressed the mouse button. After the procedure has been called, EasyGem takes over the mouse movement control and continuously redraws an elastic rubber band rectangular from the starting point to the current mouse position. If the mouse should reach the edge of the window during this process, the window will be scrolled automatically, so that the block can stretch across the entire virtual screen. The procedure returns as soon as MOUSEBUT<>1, that is, when the mouse button has been released or if an additional modifier key (Cmd, Shift, Ctrl, Alt ...) has been pressed together with the depressed mouse button. (W,H) will return the width and height of the selected block or - in case of text windows - the position of the first letter behind the block in(X2,Y2).
If needed, you may use
Action to pass the address to an action function (&FN My_Action(,,)), which is going to be called by EasyGem any time the mouse is being moved and which will, for example, display the current mouse position in the info line if so desired.
The action function has to have three parameters in which the window identification number and the mouse position are passed to the virtual screen; in case of text windows, of course, once again in letters instead of pixel.
Example:
DEF FN My_Action(Win,X,Y)
See also the program EasyPaint.BAS in the DEMO folder.

Example:
COMPILER "MIN_SIZE 1000000"
COMPILER "BAS_MEM 1000000"
COMPILER "Warnings off"

Easy_Init:'Attach EasyGem.
'Open graphics window.
T$="Graphic window":I$="Select block"
Gwin_Open Win1,0,21,-320,-200,320,200,T$,I$
Gwin_Activate Win1:'Reroute output.
FOR R=10 TO 99 STEP 10
 CIRCLE 160,100,R:'Draw graphic.
NEXT R
Gwin_Disactivate:'Normal output.
Win_Redraw Win1:'Redraw window.
REPEAT
 Easy_Mesag Entry,Buffer$,Mx,My,Mb
 Win_Domessages Buffer$
 IF Mb AND CVI(Buffer$) THEN
  'The mouse button has been pressed and the event
  'has not yet been processed by Win_Domessages.
  Win_Mousepos Win,X,Y
  IF Win THEN Gwin_Select Win,X,Y,W,H:'Mount block.
 ENDIF
UNTIL FN Win_Closed(Win1)
Easy_Exit:'Unmount EasyGem.
END




4.14 Commands for the Default Menu

As we have mentioned at the end of the chapter about menu programming, each program should enable some elementary basic functions such as Open, Save, Print, or the support of the clipboard. Some parts of the sample menu such as 'Closing' or 'End' are probably rather easy to realize, others, however, require a significant amount of programming time and effort. This is the reason why EasyGem supports you in these tasks with special commands.

Gwin_Load R Win,Win_X,Win_Y,Win_W,Win_H
[,Virt_W,Virt_H],Name$,File$
Gwin_Load R Win,Win_X,Win_Y,Win_W,Win_H,
Virt_W,Virt_H,Name$,Info$ [,Kind],File$
Load graphics file.

Twin_Load R Win,Win_X,Win_Y,Win_W,Win_H
[,Virt_W,Virt_H],Name$,File$
Twin_Load R Win,Win_X,Win_Y,Win_W,Win_H,
Virt_W,Virt_H,Name$,Info$ [,Kind],File$
Load text file.

The syntax of these commands corresponds to the commands Gwin_Open or Twin_Open, respectively, but do have the additional parameter File$, in which a FileSpecificationRecord has to be passed. If the file has the correct format (PICT and/or TEXT), a virtually window will be opened automatically and the file will be loaded in said window (Virt_W=0,Virt_H=0). You may, of course, indicate the size of the virtual screen yourself using Virt_W and Virt_H.
TEXT files are stored in the string heap and PICT files in the application heap. You have to remember to ensure a sufficient amount of memory with the compiler control words COMPILER "BAS_MEM X" or COMPILER "MIN_SIZE X," respectively.
A corresponding command for user windows does not exist since EasyGem cannot know the format of your user window, and therefore EasyGem is unable to load the file as well.

Note: If your computer is set to 256 colors or less, a color table will be created automatically by EasyGem using Gwin_Load, which is optimized for the PICT image to be loaded. Other objects on the screen might experience a change in their own color because of this.

Of course, you not only want to load files, you would also like to save them. The following EasyGem commands apply:


Gwin_Save Win[,X,Y,W,H],File$
Save graphics window.
Twin_Save Win[,X1,Y1,X2,Y2],Format,File$
Save text window.
Uwin_Save Win[,X,Y,W,H],File$
Save user window

These commands allow you to save the content of a virtual window or - if X,Y,W,H and/or X1,Y1,X2,Y2 have been indicated - to save any section of the virtual window to a file. The coordinates in the case of Gwin_Save and Uwin_Save have to be indicated in pixel on the virtual screen and in case of Twin_Save in letters. Once again, a FileSpecificationRecord has to be passed in File$.
A file of the type
'PICT' is generated in the case of graphics and user windows, while the file type 'TEXT' is applied to text windows.
In the case of text windows, an additional flag has to be passed in
Format, which will determine whether the file is going to be saved in the Apple format (Format=0) or in the DOS format (Format=1).

Especially high demands are made on the art of programming when the writing of printing routines is required, since such a wide variety of concerns have to be considered. For example, often enough the window does not fit onto a paper page and one has to find the most suitable way to divide up the window and spread it across several pages. In order to relieve you of these bothersome tasks, we have integrated certain procedures into EasyGem, which are applicable to the printing out of any desired window:

Gwin_Hcopy Win[,X,Y,W,H]
Print graphics window.
Twin_Hcopy Win[,X1,Y1,X2,Y2]
Print text window.
Uwin_Hcopy Win[,X,Y,W,H]
Print user window.

You probably have noticed that these commands are very similar to the commands used for saving window content. If needed, it is possible once again to use X,Y,W,H and/or X1,Y1,X2,Y2 to define an area for printing.

You can easily program all other items in the file menu yourself as you can see in the sample program EasyPaint.BAS in the DEMO folder.


EasyGem also offers easy to use procedures for the edit menu, which will enable you to equip your programs with certain default features with little time and effort. If you call one of the following procedures, you should subsequently also call a
Win_Redraw (except when using copy commands), so that any changes on the virtual screen will be made visible on the real screen as well.

Gwin_Cut Win[,X,Y,W,H]
Cut graphics window.
Twin_Cut Win[,X1,Y1,X2,Y2],Format
Cut text window.

These commands enable the copying to the clipboard of a whole virtual window or of a section defined with X,Y,W,H or X1,Y1,X2,Y2, respectively, and the subsequent deleting of these from the virtual screen. Format has again the same meaning as with Twin_Save.
EasyGem does not have this command for user windows because it cannot know the file format in these windows, which would mean that marked areas could be copied but subsequently not deleted.

If you would like to copy a virtual window or a marked section of a virtual window to the clipboard but would rather not delete it afterwards, you best use the following commands:

Gwin_Copy Win[,X,Y,W,H]
Copy graphics window.
Twin_Copy Win[,X1,Y1,X2,Y2],Format
Copy text window.
Uwin_Copy Win[,X,Y,W,H]
Copy user window.

Since nothing has to be deleted after the copying process, this command is also available in a version for user windows.


Now that we have familiarized ourselves with the cut and copy commands, we reach the opposite, the inserting of picture or text blocks, respectively:

Gwin_Paste Win[,X,Y[,W,H]][,File$]
Paste picture into graphics window.
Gwin_Paste Win,X,Y,W,H,File$,Action
Paste picture into graphics window, with redraw function.
Twin_Paste Win[,X1,Y1][,File$]
Paste text into text window.

With X,Y or X1,Y1, respectively, you can determine where on the virtual screen the text or graphic is supposed to be inserted. A FileSpecificationRecord may also be passed in File$. In that case, text or graphics are not taken from the clipboard but rather from the specified file.
An additional option exists for graphics windows with which you can influence the size of the picture with
W,H. If you indicate the value zero for both W and H, then EasyGem will automatically generate a shadow frame of the same size as the original block to be inserted, which can be moved within the graphics window using the mouse. When contact with the window edge is being made, the window is automatically scrolled. Gwin_Paste will insert the block at the current mouse position automatically and return as soon as the mouse button is pressed. It is possible to prevent the insertion of the block by pressing a modifier key (Shift, Ctrl ...) together with the mouse button.
Gwin_Paste features an extra syntax with an additional parameter. You can pass the address of an action function (&FN My_Action(,,)) in Action, which then is continuously called by Gwin_Paste as long as the shadow is being moved across the screen with the mouse. This action function may be used, for example, to display the current mouse position in the info line.
The action function has to take three parameters in which the window identification number and the mouse position on the virtual screen are passed:
DEF FN My_Action(Win,X,Y)
See also the program EasyPaint.BAS in the DEMO folder.

If the only parameter indicated is the windows number, then EasyGem will insert the picture or text at the left upper corner of the virtual screen.
Due to the above mentioned reasons, this command is not available for user windows.

The last commands from this group serve to delete rectangular sections of graphics or text windows, respectively. They are as follows:
Gwin_Clear Win[,X,Y,W,H]
Clear graphics window.
Twin_Clear Win[,X1,Y1,X2,Y2]
Clear text window.

The syntax of these commands corresponds to the syntax of the commands Gwin_Cut or Twin_Cut, respectively, with the only difference that the content is not being copied to the clipboard before being deleted.
These commands are also not available for user windows.

At this point, we will forego a printed example since the use of these commands is illustrated in the program EasyPaint.BAS in the DEMO folder.



4.15 Apple-Events

A multitasking operating system such the Mac OS sometimes requires that the parallel running programs exchange information with one another. For example, if you drag a BASIC file on the Omikron Basic program icon, the Finder will report this activity to Omikron Basic, which in turn opens that file. This occurs through so-called "high level events". Apple events are a subgroup of these high level events. Each program should support at least four of the basic events. Since the interpretation and evaluation is rather complicated, EasyGem helps you to fulfill this minimum requirement. Let's once more consider the procedure
Easy_Mesag:

Easy_Mesag R Entry,R Buffer$,R Ev_Msk,
R Mx,R My,R Mb,R Modifier,R Clicks,R Kbrd

When a high level event is reported to your program initially, EasyGem will first check whether this event falls into the category of those four basic Apple events. If this should be the case, then any eventual parameters are extracted and routed to your program. The type of event is returned in the variable Entry and the parameters are added to Buffer$.
The following options exist:

Entry = CVIL("oapp") This Open-Application-Event has no parameter and is send by your program right after it starts. Afterwards, you can respond, e.g., with the opening of a new window so that the user may begin working right after the program starts.
Entry = CVIL("odoc") This is an Open-Document-Event. If you receive this message, it is expected that your program will open a document. A FileSpecificationRecord is added to Buffer$, which will specify the file to be opened. (Fsspec$=MID$(Buffer$,17)).
Entry = CVIL("pdoc") This Print-Document-Event means that your program is supposed to print the file whose FileSpecificationRecord you will receive starting at position 17 in Buffer$. You will receive such a message e.g., if a file of your program is selected and you click on "Print" in the Finder.
Entry = CVIL("quit") This event indicates that your program is supposed to be terminated because e.g., the user wants to turn off the computer. In this case, you just have to call your "end procedure."
Of course, still other high level events do exist but none of them are processed by EasyGem automatically. If you would like to delve deeper into the subject matter at hand, we recommend the detailed information about this subject in the book "Inside Macintosh, Interapplication Communication;" however, as we have stated before, the subject is rather complicated.

You might have noticed that the above listed procedure
Easy_Mesag has two parameters more than the version you are already familiar with concerning the query of the mouse in a window.
The final additional parameter is
Kbrd. This variable will return information about a pressed keyboard key. Its structure corresponds to the string described in the Omikron Basic Manual under INKEY$ (see also Twin_Inkey a few paragraphs above).
Now the variable
Ev_Msk is located behind Buffer$. This event mask may be used on the one hand to determine which events you would even like to receive, on the other hand, it is employed by EasyGem to report to you which events have actually taken place. For this purpose, each bit has an event assigned to it according to the following table:
Bit 1 Mouse button has been pressed.
Bit 2 Mouse button has been released.
Bit 3 Keyboard key has been pressed.
Bit 4 Keyboard key has been released.
Bit 5 Automatic key repeat.
Bit 6 Update window.
Bit 7 Floppy disk has been inserted.
Bit 8 Activate program (make it the foremost process).
Bit 10 High level event.
Bit 15 Operating system event.
Under normal circumstances you do want to know about all events. Then you have to set Ev_Msk=-1 first and each time before you call Easy_Mesag.

The sample programs EasyFractal.BAS and EasyPaint.BAS in the DEMO folder illustrate the use of the expanded
Easy_Mesag function and of the Apple events.

Reference List Dialog Library -turn page- Reference List Window Library

Contents | Start



© 1998-2000 Berkhan-Software
www.berkhan.com | Home