|
@@ -9,10 +9,17 @@ TYPE
|
|
|
|
|
|
DrawHandler* = PROCEDURE (W: Widget; x, y: INTEGER);
|
|
DrawHandler* = PROCEDURE (W: Widget; x, y: INTEGER);
|
|
MouseDownHandler* = PROCEDURE (W: Widget; x, y, btn: INTEGER);
|
|
MouseDownHandler* = PROCEDURE (W: Widget; x, y, btn: INTEGER);
|
|
|
|
+ MouseUpHandler* = PROCEDURE (W: Widget; x, y, btn: INTEGER);
|
|
|
|
+ ClickHandler* = PROCEDURE (W: Widget);
|
|
|
|
+
|
|
|
|
+ Message* = POINTER TO MsgDesc;
|
|
|
|
+ MsgDesc* = RECORD END;
|
|
|
|
+ Handler* = PROCEDURE (W: Widget; VAR msg: Message);
|
|
|
|
|
|
Widget* = POINTER TO WidgetDesc;
|
|
Widget* = POINTER TO WidgetDesc;
|
|
WidgetDesc* = RECORD
|
|
WidgetDesc* = RECORD
|
|
x*, y*, w*, h*: INTEGER;
|
|
x*, y*, w*, h*: INTEGER;
|
|
|
|
+ tag*: INTEGER;
|
|
body*: Widget;
|
|
body*: Widget;
|
|
text*: Caption;
|
|
text*: Caption;
|
|
bmp*: G.Bitmap;
|
|
bmp*: G.Bitmap;
|
|
@@ -20,12 +27,17 @@ TYPE
|
|
prev*, next*: Widget;
|
|
prev*, next*: Widget;
|
|
draw*: DrawHandler;
|
|
draw*: DrawHandler;
|
|
(* Event Handlers *)
|
|
(* Event Handlers *)
|
|
- onMouseDown*: MouseDownHandler
|
|
|
|
|
|
+ onMouseDown*: MouseDownHandler;
|
|
|
|
+ onMouseUp*: MouseUpHandler;
|
|
|
|
+ onClick*: ClickHandler;
|
|
|
|
+ (* Message Handler *)
|
|
|
|
+ handle*: Handler
|
|
END;
|
|
END;
|
|
|
|
|
|
Window* = POINTER TO WindowDesc;
|
|
Window* = POINTER TO WindowDesc;
|
|
WindowDesc* = RECORD(WidgetDesc)
|
|
WindowDesc* = RECORD(WidgetDesc)
|
|
- win*: G.Window
|
|
|
|
|
|
+ win*: G.Window;
|
|
|
|
+ curMouseDownWidget*: Widget (* Widget under mouse down event is saved here *)
|
|
END;
|
|
END;
|
|
|
|
|
|
VAR
|
|
VAR
|
|
@@ -45,11 +57,24 @@ BEGIN
|
|
W.onMouseDown := handler
|
|
W.onMouseDown := handler
|
|
END SetOnMouseDown;
|
|
END SetOnMouseDown;
|
|
|
|
|
|
|
|
+PROCEDURE SetOnMouseUp*(W: Widget; handler: MouseUpHandler);
|
|
|
|
+BEGIN
|
|
|
|
+ W.onMouseUp := handler
|
|
|
|
+END SetOnMouseUp;
|
|
|
|
+
|
|
|
|
+PROCEDURE SetOnClick*(W: Widget; handler: ClickHandler);
|
|
|
|
+BEGIN
|
|
|
|
+ W.onClick := handler;
|
|
|
|
+END SetOnClick;
|
|
|
|
+
|
|
PROCEDURE InitWidget*(w: Widget);
|
|
PROCEDURE InitWidget*(w: Widget);
|
|
BEGIN
|
|
BEGIN
|
|
w.x := 0; w.y := 0; w.w := 24; w.h := 24;
|
|
w.x := 0; w.y := 0; w.w := 24; w.h := 24;
|
|
|
|
+ w.tag := 0;
|
|
w.draw := NIL;
|
|
w.draw := NIL;
|
|
w.onMouseDown := NIL;
|
|
w.onMouseDown := NIL;
|
|
|
|
+ w.onMouseUp := NIL;
|
|
|
|
+ w.onClick := NIL;
|
|
|
|
|
|
(* Замок *)
|
|
(* Замок *)
|
|
NEW(w.body); w.body.prev := w.body; w.body.next := w.body
|
|
NEW(w.body); w.body.prev := w.body; w.body.next := w.body
|
|
@@ -114,6 +139,7 @@ BEGIN
|
|
'Window', newWindowSettings);
|
|
'Window', newWindowSettings);
|
|
win.x := 0; win.y := 0;
|
|
win.x := 0; win.y := 0;
|
|
win.w := win.win.w; win.h := win.win.h;
|
|
win.w := win.win.w; win.h := win.win.h;
|
|
|
|
+ win.curMouseDownWidget := NIL;
|
|
win.draw := DrawWindow
|
|
win.draw := DrawWindow
|
|
END InitWindow;
|
|
END InitWindow;
|
|
|
|
|
|
@@ -147,6 +173,20 @@ BEGIN
|
|
END
|
|
END
|
|
END TriggerOnMouseDown;
|
|
END TriggerOnMouseDown;
|
|
|
|
|
|
|
|
+PROCEDURE TriggerOnMouseUp*(W: Widget; x, y, btn: INTEGER);
|
|
|
|
+BEGIN
|
|
|
|
+ IF (W # NIL) & (W.onMouseUp # NIL) THEN
|
|
|
|
+ W.onMouseUp(W, x, y, btn)
|
|
|
|
+ END
|
|
|
|
+END TriggerOnMouseUp;
|
|
|
|
+
|
|
|
|
+PROCEDURE TriggerOnClick*(W: Widget);
|
|
|
|
+BEGIN
|
|
|
|
+ IF (W # NIL) & (W.onClick # NIL) THEN
|
|
|
|
+ W.onClick(W)
|
|
|
|
+ END
|
|
|
|
+END TriggerOnClick;
|
|
|
|
+
|
|
PROCEDURE FindWidgetUnderMouse*(W: Widget; VAR x, y: INTEGER): Widget;
|
|
PROCEDURE FindWidgetUnderMouse*(W: Widget; VAR x, y: INTEGER): Widget;
|
|
VAR p: Widget;
|
|
VAR p: Widget;
|
|
BEGIN
|
|
BEGIN
|
|
@@ -158,24 +198,55 @@ BEGIN
|
|
(p.y <= y) & (y < p.y + p.h))
|
|
(p.y <= y) & (y < p.y + p.h))
|
|
DO p := p.prev
|
|
DO p := p.prev
|
|
END;
|
|
END;
|
|
- IF p = W.body THEN p := W END
|
|
|
|
- ELSE p := NIL
|
|
|
|
|
|
+ IF p = W.body THEN p := W
|
|
|
|
+ ELSE DEC(x, p.x); DEC(y, p.y);
|
|
|
|
+ p := FindWidgetUnderMouse(p, x, y)
|
|
|
|
+ END
|
|
|
|
+ ELSE p := W
|
|
END
|
|
END
|
|
RETURN p END FindWidgetUnderMouse;
|
|
RETURN p END FindWidgetUnderMouse;
|
|
|
|
|
|
|
|
+(** Input: (x; y) relative to window.
|
|
|
|
+ Output: (x; y) relative to widget. *)
|
|
|
|
+PROCEDURE WindowToWidgetXY*(W: Widget; VAR x, y: INTEGER);
|
|
|
|
+BEGIN
|
|
|
|
+ WHILE (W # NIL) & ~(W IS Window) DO
|
|
|
|
+ DEC(x, W.x); DEC(y, W.y);
|
|
|
|
+ W := W.parent
|
|
|
|
+ END
|
|
|
|
+END WindowToWidgetXY;
|
|
|
|
+
|
|
PROCEDURE HandleMouseDownEvent*(e: G.Event);
|
|
PROCEDURE HandleMouseDownEvent*(e: G.Event);
|
|
VAR W: Widget;
|
|
VAR W: Widget;
|
|
x, y: INTEGER;
|
|
x, y: INTEGER;
|
|
BEGIN
|
|
BEGIN
|
|
x := e.x; y := e.y;
|
|
x := e.x; y := e.y;
|
|
W := FindWidgetUnderMouse(globalWin, x, y);
|
|
W := FindWidgetUnderMouse(globalWin, x, y);
|
|
|
|
+ IF W # NIL THEN
|
|
|
|
+ globalWin.curMouseDownWidget := W (* Save for future mouse up event *)
|
|
|
|
+ END;
|
|
TriggerOnMouseDown(W, x, y, e.button)
|
|
TriggerOnMouseDown(W, x, y, e.button)
|
|
END HandleMouseDownEvent;
|
|
END HandleMouseDownEvent;
|
|
|
|
|
|
|
|
+PROCEDURE HandleMouseUpEvent*(e: G.Event);
|
|
|
|
+VAR W: Widget;
|
|
|
|
+ x, y: INTEGER;
|
|
|
|
+BEGIN
|
|
|
|
+ x := e.x; y := e.y;
|
|
|
|
+ W := globalWin.curMouseDownWidget;
|
|
|
|
+ WindowToWidgetXY(W, x, y);
|
|
|
|
+ TriggerOnMouseUp(W, x, y, e.button);
|
|
|
|
+ IF (x >= 0) & (y >= 0) & (W.w > x) & (W.h > y) THEN
|
|
|
|
+ TriggerOnClick(W)
|
|
|
|
+ END
|
|
|
|
+END HandleMouseUpEvent;
|
|
|
|
+
|
|
PROCEDURE HandleEvent(e: G.Event);
|
|
PROCEDURE HandleEvent(e: G.Event);
|
|
BEGIN
|
|
BEGIN
|
|
IF e.type = G.mouseDown THEN
|
|
IF e.type = G.mouseDown THEN
|
|
HandleMouseDownEvent(e)
|
|
HandleMouseDownEvent(e)
|
|
|
|
+ ELSIF e.type = G.mouseUp THEN
|
|
|
|
+ HandleMouseUpEvent(e)
|
|
ELSIF e.type = G.keyDown THEN
|
|
ELSIF e.type = G.keyDown THEN
|
|
IF e.key = G.kEsc THEN exitRunLoop := TRUE END;
|
|
IF e.key = G.kEsc THEN exitRunLoop := TRUE END;
|
|
INC(ZZZ)
|
|
INC(ZZZ)
|