[qwaq] Make the event system more informative

Doesn't have timestamps at this stage, but otherwise it reflects the
event system I had in my old text UI which was heavily based on
TurboVision. TV is pretty good (after looking at things a bit closer I
found it wasn't as deep as I thought), and better yet, Borland released
it to the public domain 23 years ago! (wish I'd known that).

Anyway, this commit gets something happening on the screen, even though
the current hierarchy is still a mess.
This commit is contained in:
Bill Currie 2020-03-04 22:09:40 +09:00
parent 815ae02121
commit f3236410d0
6 changed files with 135 additions and 29 deletions

View file

@ -2,11 +2,31 @@
#define __qwaq_event_h #define __qwaq_event_h
typedef enum { typedef enum {
qe_none, qe_mousedown = 0x0001,
qe_key, qe_mouseup = 0x0002,
qe_mouse, qe_mouseclick= 0x0004,
qe_command, // application level command qe_mousemove = 0x0008,
} qwaq_etype; qe_mouseauto = 0x0010,
} qwaq_mouse_event;
typedef enum {
qe_keydown = 0x0020,
} qwaq_key_event;
typedef enum {
qe_command = 0x0200, // application level command
qe_broadcast = 0x0400,
} qwaq_message_event;
typedef enum {
qe_none = 0x0000,
qe_mouse = 0x001f,
qe_key = 0x0020,
qe_system = 0x01c0,
qe_message = 0xfe00,
qe_focused = qe_key | qe_command,
} qwaq_event_mask;
typedef enum { typedef enum {
qc_valid, qc_valid,
@ -17,6 +37,7 @@ typedef enum {
typedef struct qwaq_mevent_s { typedef struct qwaq_mevent_s {
int x, y; int x, y;
int buttons; int buttons;
int click;
} qwaq_mevent_t; } qwaq_mevent_t;
typedef struct qwaq_message_s { typedef struct qwaq_message_s {
@ -24,7 +45,7 @@ typedef struct qwaq_message_s {
} qwaq_message_t; } qwaq_message_t;
typedef struct qwaq_event_s { typedef struct qwaq_event_s {
qwaq_etype event_type; int what;
union { union {
int key; int key;
qwaq_mevent_t mouse; qwaq_mevent_t mouse;

View file

@ -1,3 +1,4 @@
int fence;
#include <AutoreleasePool.h> #include <AutoreleasePool.h>
#include "color.h" #include "color.h"
@ -47,8 +48,9 @@ arp_end (void)
[screen printf:"%d\n", acs_char(ACS_HLINE)]; [screen printf:"%d\n", acs_char(ACS_HLINE)];
[screen addch: acs_char(ACS_HLINE) atX:4 Y:4]; [screen addch: acs_char(ACS_HLINE) atX:4 Y:4];
Window *w; Window *w;
[screen add: w=[[Window windowWithRect: r] setBackground: COLOR_PAIR (2)]]; //[screen add: w=[[Window windowWithRect: r] setBackground: COLOR_PAIR (2)]];
//wprintf (w.window, "%d %d %d %d\n", r.xpos, r.ypos, r.xlen, r.ylen); //wprintf (w.window, "%d %d %d %d\n", r.xpos, r.ypos, r.xlen, r.ylen);
[screen redraw];
return self; return self;
} }
@ -59,7 +61,7 @@ arp_end (void)
arp_start (); arp_start ();
get_event (&event); get_event (&event);
if (event.event_type != qe_none) { if (event.what != qe_none) {
[self handleEvent: &event]; [self handleEvent: &event];
} }
@ -71,11 +73,11 @@ arp_end (void)
-handleEvent: (qwaq_event_t *) event -handleEvent: (qwaq_event_t *) event
{ {
[screen handleEvent: event]; [screen handleEvent: event];
if (event.event_type == qe_key && event.key == '\x18') { if (event.what == qe_key && event.key == '\x18') {
event.event_type = qe_command; event.what = qe_command;
event.message.command = qc_exit; event.message.command = qc_exit;
} }
if (event.event_type == qe_command if (event.what == qe_command
&& (event.message.command == qc_exit && (event.message.command == qc_exit
|| event.message.command == qc_error)) { || event.message.command == qc_error)) {
endState = event.message.command; endState = event.message.command;
@ -86,6 +88,9 @@ arp_end (void)
int main (int argc, string *argv) int main (int argc, string *argv)
{ {
fence = 0;
//while (!fence) {}
id app = [[QwaqApplication app] retain]; id app = [[QwaqApplication app] retain];
[app run]; [app run];

View file

@ -142,6 +142,11 @@ typedef enum qwaq_commands_e {
rb->buffer[(rb->tail + ahead) % RB_buffer_size (rb)]; \ rb->buffer[(rb->tail + ahead) % RB_buffer_size (rb)]; \
}) })
#define RB_POKE_DATA(ring_buffer, ahead, data) \
({ __auto_type rb = &(ring_buffer); \
rb->buffer[(rb->tail + ahead) % RB_buffer_size (rb)] = (data); \
})
typedef struct window_s { typedef struct window_s {
WINDOW *win; WINDOW *win;
} window_t; } window_t;
@ -607,6 +612,16 @@ process_commands (qwaq_resources_t *res)
static void static void
add_event (qwaq_resources_t *res, qwaq_event_t *event) add_event (qwaq_resources_t *res, qwaq_event_t *event)
{ {
// lock
// {
// merge motion events
unsigned last = RB_DATA_AVAILABLE (res->event_queue);
if (event->what == qe_mousemove && last > 1
&& RB_PEEK_DATA(res->event_queue, last - 1).what == qe_mousemove) {
RB_POKE_DATA(res->event_queue, last - 1, *event);
return; // unlock
}
// }
if (RB_SPACE_AVAILABLE (res->event_queue) >= 1) { if (RB_SPACE_AVAILABLE (res->event_queue) >= 1) {
RB_WRITE_DATA (res->event_queue, event, 1); RB_WRITE_DATA (res->event_queue, event, 1);
} }
@ -624,14 +639,69 @@ get_event (qwaq_resources_t *res, qwaq_event_t *event)
return 0; return 0;
} }
#define M_MOVE REPORT_MOUSE_POSITION
#define M_PRESS ( BUTTON1_PRESSED \
| BUTTON2_PRESSED \
| BUTTON3_PRESSED \
| BUTTON4_PRESSED \
| BUTTON5_PRESSED)
#define M_RELEASE ( BUTTON1_RELEASED \
| BUTTON2_RELEASED \
| BUTTON3_RELEASED \
| BUTTON4_RELEASED \
| BUTTON5_RELEASED)
#define M_CLICK ( BUTTON1_CLICKED \
| BUTTON2_CLICKED \
| BUTTON3_CLICKED \
| BUTTON4_CLICKED \
| BUTTON5_CLICKED)
#define M_DCLICK ( BUTTON1_DOUBLE_CLICKED \
| BUTTON2_DOUBLE_CLICKED \
| BUTTON3_DOUBLE_CLICKED \
| BUTTON4_DOUBLE_CLICKED \
| BUTTON5_DOUBLE_CLICKED)
#define M_TCLICK ( BUTTON1_TRIPLE_CLICKED \
| BUTTON2_TRIPLE_CLICKED \
| BUTTON3_TRIPLE_CLICKED \
| BUTTON4_TRIPLE_CLICKED \
| BUTTON5_TRIPLE_CLICKED)
static void static void
mouse_event (qwaq_resources_t *res, MEVENT *mevent) mouse_event (qwaq_resources_t *res, const MEVENT *mevent)
{ {
int mask = mevent->bstate;
qwaq_event_t event = {}; qwaq_event_t event = {};
event.event_type = qe_mouse;
event.mouse.x = mevent->x; event.mouse.x = mevent->x;
event.mouse.y = mevent->y; event.mouse.y = mevent->y;
event.mouse.buttons = mevent->bstate; event.mouse.buttons = mevent->bstate;
if (mask & M_MOVE) {
event.what = qe_mousemove;
mask &= ~M_MOVE;
}
if (mask & M_PRESS) {
event.what = qe_mousedown;
mask &= ~M_PRESS;
}
if (mask & M_RELEASE) {
event.what = qe_mouseup;
mask &= ~M_RELEASE;
}
if (mask & M_CLICK) {
event.what = qe_mouseclick;
mask &= ~M_CLICK;
event.mouse.click = 1;
}
if (mask & M_DCLICK) {
event.what = qe_mouseclick;
mask &= ~M_DCLICK;
event.mouse.click = 2;
}
if (mask & M_TCLICK) {
event.what = qe_mouseclick;
mask &= ~M_TCLICK;
event.mouse.click = 3;
}
add_event (res, &event); add_event (res, &event);
} }
@ -639,7 +709,7 @@ static void
key_event (qwaq_resources_t *res, int key) key_event (qwaq_resources_t *res, int key)
{ {
qwaq_event_t event = {}; qwaq_event_t event = {};
event.event_type = qe_key; event.what = qe_keydown;
event.key = key; event.key = key;
add_event (res, &event); add_event (res, &event);
} }

View file

@ -8,7 +8,7 @@
@class View; @class View;
@class Array; @class Array;
@interface Screen: Object <HandleEvent, Draw> @interface Screen: Object <HandleMouseEvent, Draw>
{ {
Rect rect; Rect rect;
Array *views; Array *views;

View file

@ -55,16 +55,9 @@
-handleEvent: (qwaq_event_t *) event -handleEvent: (qwaq_event_t *) event
{ {
switch (event.event_type) { if (event.what & qe_mouse) {
case qe_none: [self printf:"%04x %2d %2d %d %08x\r", event.what, event.mouse.x, event.mouse.y, event.mouse.click, event.mouse.buttons];
break; [self redraw];
case qe_key:
case qe_command:
[focused_handlers
makeObjectsPerformSelector: @selector(handleEvent:)
withObject: (id) event];
break;
case qe_mouse:
Point p = { event.mouse.x, event.mouse.y }; Point p = { event.mouse.x, event.mouse.y };
for (int i = [mouse_handler_rects count]; i-->0; ) { for (int i = [mouse_handler_rects count]; i-->0; ) {
//if (rectContainsPoint((Rect*)mouse_handler_rects._objs[i], &p)) { //if (rectContainsPoint((Rect*)mouse_handler_rects._objs[i], &p)) {
@ -72,6 +65,18 @@
// break; // break;
//} //}
} }
} else if (event.what & qe_focused) {
[focused_handlers
makeObjectsPerformSelector: @selector(handleEvent:)
withObject: (id) event];
}
switch (event.what) {
case qe_none:
break;
case qe_key:
case qe_command:
break;
case qe_mouse:
break; break;
} }
return self; return self;
@ -87,8 +92,8 @@
-redraw -redraw
{ {
[self error:"hmm"];
update_panels (); update_panels ();
wrefresh(window);
doupdate (); doupdate ();
return self; return self;
} }
@ -105,6 +110,11 @@
return self; return self;
} }
- (Rect *) getRect
{
return &rect;
}
-setParent: parent -setParent: parent
{ {
return self; return self;

View file

@ -26,7 +26,7 @@
-handleEvent: (qwaq_event_t *) event -handleEvent: (qwaq_event_t *) event
{ {
switch (event.event_type) { switch (event.what) {
case qe_mouse: case qe_mouse:
mvwprintf(window, 0, 3, "%2d %2d %08x", mvwprintf(window, 0, 3, "%2d %2d %08x",
event.mouse.x, event.mouse.y, event.mouse.buttons); event.mouse.x, event.mouse.y, event.mouse.buttons);
@ -46,7 +46,7 @@
if (focusedView) { if (focusedView) {
[focusedView handleEvent: event]; [focusedView handleEvent: event];
for (int i = [views count]; for (int i = [views count];
event.event_type != qe_none && i--> 0; ) { event.what != qe_none && i--> 0; ) {
View *v = [views objectAtIndex: i]; View *v = [views objectAtIndex: i];
[v handleEvent: event]; [v handleEvent: event];
} }