Lugaru's Epsilon
Programmer's
Editor

Context:
Epsilon User's Manual and Reference
   Primitives and EEL Subroutines
      . . .
      Control Primitives
         Control Flow
         Character Types
         Examining Strings
         . . .
         Help Subroutines
      Input Primitives
         Keys
         The Mouse
            Mouse Cursors
            Mouse Subroutines
            The Scroll Bar
            Mouse Panning
         Window Events
         Completion
         . . .
      Defining Language Modes
         Language-specific Subroutines

Previous   Up    Next
Keys  Primitives and EEL Subroutines   Mouse Cursors


Epsilon User's Manual and Reference > Primitives and EEL Subroutines > Input Primitives >

The Mouse

When a mouse event occurs, such as a button press or a mouse movement, Epsilon enqueues the information in the same data structure it uses for keyboard events. A call to wait_for_key( ) retrieves the next item from the queue--either a keystroke or a mouse event. Normally an EEL program calls the getkey( ) subroutine instead of wait_for_key( ). See Keys.

user short catch_mouse;

The catch_mouse primitive controls whether Epsilon will queue up any mouse events. Setting it to zero causes Epsilon to ignore the mouse. A nonzero value makes Epsilon queue up mouse events. If your system has no mouse, setting catch_mouse has no effect.

user short mouse_mask;
user short mouse_x, mouse_y;
user short mouse_screen;
user int double_click_time;

You can control which mouse events Epsilon dequeues, and which it ignores, by using the mouse_mask primitive. The following values, defined in codes.h, control this:

#define MASK_MOVE       0x01
#define MASK_LEFT_DN    0x02
#define MASK_LEFT_UP    0x04
#define MASK_RIGHT_DN   0x08
#define MASK_RIGHT_UP   0x10
#define MASK_CENTER_DN  0x20
#define MASK_CENTER_UP  0x40
#define MASK_ALL        0x7f
#define MASK_BUTTONS    (MASK_ALL - MASK_MOVE)
#define MASK_DN         // ... see eel.h
#define MASK_UP         // ... see eel.h

For example, the following EEL code would cause Epsilon to pay attention to the left mouse button and mouse movement, but ignore everything else:

mouse_mask = MASK_MOVE | MASK_LEFT_DN | MASK_LEFT_UP;

When Epsilon dequeues a mouse event with wait_for_key( ), it sets the values of mouse_x and mouse_y to the screen coordinates associated with that mouse event. Setting them moves the mouse cursor. The upper left corner has coordinate (0, 0).

When dequeuing a mouse event, wait_for_key( ) returns one of the following "keys" (defined in codes.h):

MOUSE_LEFT_DN     MOUSE_LEFT_UP     MOUSE_DBL_LEFT
MOUSE_CENTER_DN   MOUSE_CENTER_UP   MOUSE_DBL_CENTER
MOUSE_RIGHT_DN    MOUSE_RIGHT_UP    MOUSE_DBL_RIGHT
MOUSE_MOVE

Dequeuing a mouse event also sets the mouse_screen variable to indicate which screen its coordinates refer to. Screen coordinates are relative to the specified screen. Ordinary Epsilon windows are on the main screen, screen 0. When Epsilon creates a dialog box containing Epsilon windows, each Epsilon window receives its own screen number. For example, if you type Ctrl-X Ctrl-F ?, Epsilon displays a dialog box with two screens, usually numbered 1 and 2. If you click on the ninth line of the second screen, Epsilon returns the key MOUSE_LEFT_DN, sets mouse_y to 8 (counting from zero), and sets mouse_screen to 2.

The double_click_time primitive specifies how long a delay to allow for double-clicks (in hundredths of a second). If two consecutive MOUSE_LEFT_DN events occur within the allotted time, then Epsilon enqueues a MOUSE_DBL_LEFT event in place of the second MOUSE_LEFT_DN event. The corresponding thing happens for right clicks and center clicks as well. Epsilon for Windows ignores this variable and uses standard Windows settings to determine double-clicks.

#define IS_WIN_KEY(k)       // ... omitted
#define IS_MOUSE_KEY(k)     // ... omitted
#define IS_TRUE_KEY(k)      // ... omitted
#define IS_EXT_ASCII_KEY(k) // ... omitted
#define IS_WIN_PASSIVE_KEY(k) // ... omitted
#define IS_MOUSE_LEFT(k)    // ... omitted
#define IS_MOUSE_RIGHT(k)   // ... omitted
#define IS_MOUSE_CENTER(k)  // ... omitted
#define IS_MOUSE_SINGLE(k)  // ... omitted
#define IS_MOUSE_DOUBLE(k)  // ... omitted
#define IS_MOUSE_DOWN(k)    // ... omitted
#define IS_MOUSE_UP(k)      // ... omitted

The IS_MOUSE_KEY() macro returns a nonzero value if the given key code indicates a mouse event. The IS_TRUE_KEY() macro returns a nonzero value if the given key code indicates a keyboard key. The IS_EXT_ASCII_KEY() macro returns a nonzero value if the given key code represents a character that can appear in a buffer (rather than a function key or cursor key). The IS_WIN_KEY() macro returns a nonzero value if the given key code indicates a window event like a menu selection, pressing a button on a dialog, or getting the focus, while IS_WIN_PASSIVE_KEY() returns nonzero if the given key represents an incidental event: losing or gaining focus, losing the selection, or the mouse entering or leaving Epsilon's window.

The IS_MOUSE_LEFT(), IS_MOUSE_RIGHT(), and IS_MOUSE_CENTER() macros return nonzero if a particular key code represents either a single or a double click of the indicated button. The IS_MOUSE_SINGLE() and IS_MOUSE_DOUBLE() macros return nonzero if the given key code represents a single-click or double-click, respectively, of any mouse button. The IS_MOUSE_DOWN() macro returns nonzero if the key code represents the pressing of any mouse button (either a single-click or a double-click). Finally, the IS_MOUSE_UP() macro tells if a particular key code represents the release of any mouse button.

user short mouse_pixel_x, mouse_pixel_y;
int y_pixels_per_char()
int x_pixels_per_char()
clip_mouse()  /* mouse.e subr. */

On most systems, Epsilon can provide the mouse position with finer resolution than simply which character it is on. The mouse_pixel_x and mouse_pixel_y variables contain the mouse position in the most accurate form Epsilon provides. Setting the pixel variables moves the mouse cursor and resets the mouse_x and mouse_y variables to match. Similarly, setting mouse_x or mouse_y resets the corresponding pixel variable.

EEL subroutines should not assume any particular scaling between the screen character coordinates provided by mouse_x and mouse_y and these "pixel" variables. The scaling varies with the screen display mode or selected font. As with the character coordinates, the upper left corner has pixel coordinate (0, 0). The y_pixels_per_char( ) and x_pixels_per_char( ) primitives report the current scaling between pixels and characters. For example, mouse_x usually equals the quantity mouse_pixel_x / x_pixels_per_char(), rounded down to an integer.

The mouse_x variable can range from -1 to screen_cols, while the valid screen columns range from 0 to (screen_cols - 1). Epsilon uses the additional values to indicate that the user has tried to move the mouse cursor off the screen, in environments which can detect this (currently, no supported environments can). The mouse_pixel_x variable, on the other hand, ranges from 0 to screen_cols * x_pixels_per_char(). The highest and lowest values of mouse_pixel_x correspond to the highest and lowest values of mouse_x, while other values obey the relation outlined in the previous paragraph. The mouse_y and mouse_pixel_y variables work in the same way.

The clip_mouse( ) subroutine alters the mouse_x and mouse_y variables so that they refer to a valid screen column, if they currently range off the screen.

user short mouse_shift;
short shift_pressed()
#define KB_ALT_DN     0x08    // Some Alt key
#define KB_CTRL_DN    0x04    // Some Ctrl key
#define KB_LSHIFT_DN  0x02    // Left shift key
#define KB_RSHIFT_DN  0x01    // Right shift key
#define KB_SHIFT_DN   (KB_LSHIFT_DN | KB_RSHIFT_DN)
                              // Either shift key
int was_key_shifted()

When Epsilon dequeues a mouse event with wait_for_key( ), it also sets the mouse_shift variable to indicate which shift keys were depressed at the time the mouse event was enqueued. The shift_pressed( ) primitive returns the same codes, but indicates which shift keys are depressed at the moment you call it.

The was_key_shifted( ) subroutine tells if the user held down Shift when pressing the current key. Some keys produce the same key code with or without shift.

Unlike the shift_pressed( ) primitive, which reports on the current state of the Shift key, this one works with keyboard macros by returning the state of the Shift key at the time the key was originally pressed. A subroutine must call was_key_shifted( ) at the time the macro is recorded for the Shift state to be recorded in the macro. Macros defined by a command file can use an E- prefix to indicate this.

short mouse_buttons()
int mouse_pressed()
get_movement_or_release()  /* menu.e */

The mouse_buttons( ) primitive returns the number of buttons on the mouse. A value of zero means that Epsilon could not find a mouse on the system.

The mouse_pressed( ) primitive returns a nonzero value if and only if some button on the mouse has gone down but has not yet gone up. The subroutine get_movement_or_release( ) uses this function. It delays until the mouse moves or all its buttons have been released.



Previous   Up    Next
Keys  Primitives and EEL Subroutines   Mouse Cursors


Lugaru Copyright (C) 1984, 2020 by Lugaru Software Ltd. All rights reserved.