From c58cf2c2d059a585c5e941418d2ea66b6f404986 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 3 Mar 2020 21:30:47 +0900 Subject: [PATCH] [qwaq] Fail at object oriented design 101 This is horrible, doesn't work, isn't really the direction I want to go (that became apparent while implementing Screen's handleEvent) and crashes anyway (Array and not-id...) *sigh* Still, this does have some good stuff in it, and it pushed qfcc along some more. --- ruamoko/qwaq/event.h | 6 +++- ruamoko/qwaq/qwaq-app.r | 12 +++++--- ruamoko/qwaq/qwaq-curses.c | 61 ++++++++++++++++++++++++++++++++++++ ruamoko/qwaq/qwaq-curses.h | 2 ++ ruamoko/qwaq/qwaq-draw.h | 2 ++ ruamoko/qwaq/qwaq-rect.h | 2 +- ruamoko/qwaq/qwaq-screen.h | 5 ++- ruamoko/qwaq/qwaq-screen.r | 63 +++++++++++++++++++++++++++++++++++++- ruamoko/qwaq/qwaq-view.h | 1 + ruamoko/qwaq/qwaq-view.r | 11 +++++++ ruamoko/qwaq/qwaq-window.h | 4 +-- ruamoko/qwaq/qwaq-window.r | 22 +++++++++++++ 12 files changed, 180 insertions(+), 11 deletions(-) diff --git a/ruamoko/qwaq/event.h b/ruamoko/qwaq/event.h index f494234a9..9eca5158e 100644 --- a/ruamoko/qwaq/event.h +++ b/ruamoko/qwaq/event.h @@ -37,11 +37,15 @@ typedef struct qwaq_event_s { -handleEvent: (struct qwaq_event_s *) event; @end -@protocol TakeFocus +@protocol HandleFocusedEvent -takeFocus; -loseFocus; @end +@protocol HandleMouseEvent +-(struct Rect_s *)getRect; +@end + #endif #endif//__qwaq_event_h diff --git a/ruamoko/qwaq/qwaq-app.r b/ruamoko/qwaq/qwaq-app.r index e100ae69e..ed6339faf 100644 --- a/ruamoko/qwaq/qwaq-app.r +++ b/ruamoko/qwaq/qwaq-app.r @@ -37,15 +37,15 @@ arp_end (void) init_pair (2, COLOR_WHITE, COLOR_BLACK); screen = [[Screen screen] retain]; [screen setBackground: COLOR_PAIR (1)]; - Rect r = screen.rect; - wprintf (screen.window, "%d %d %d %d\n", r.xpos, r.ypos, r.xlen, r.ylen); + Rect r = *[screen getRect]; + [screen printf:"%d %d %d %d\n", r.xpos, r.ypos, r.xlen, r.ylen]; r.xpos = r.xlen / 4; r.ypos = r.ylen / 4; r.xlen /= 2; r.ylen /= 2; - wprintf (screen.window, "%d %d %d %d\n", r.xpos, r.ypos, r.xlen, r.ylen); - wprintf (screen.window, "%d\n", acs_char(ACS_HLINE)); - mvwaddch(screen.window, 4, 4, acs_char(ACS_HLINE)); + [screen printf:"%d %d %d %d\n", r.xpos, r.ypos, r.xlen, r.ylen]; + [screen printf:"%d\n", acs_char(ACS_HLINE)]; + [screen addch: acs_char(ACS_HLINE) atX:4 Y:4]; Window *w; [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); @@ -102,6 +102,7 @@ window_t create_window (int xpos, int ypos, int xlen, int ylen) = #0; void destroy_window (window_t win) = #0; void mvwprintf (window_t win, int x, int y, string fmt, ...) = #0; void wprintf (window_t win, string fmt, ...) = #0; +void wvprintf (window_t win, string fmt, @va_list args) = #0; void wrefresh (window_t win) = #0; void mvwaddch (window_t win, int x, int y, int ch) = #0; int get_event (qwaq_event_t *event) = #0; @@ -109,6 +110,7 @@ int max_colors (void) = #0; int max_color_pairs (void) = #0; int init_pair (int pair, int f, int b) = #0; void wbkgd (window_t win, int ch) = #0; +void scrollok (window_t win, int flag) = #0; int acs_char (int acs) = #0; panel_t create_panel (window_t window) = #0; diff --git a/ruamoko/qwaq/qwaq-curses.c b/ruamoko/qwaq/qwaq-curses.c index f33e01a5a..c03a38542 100644 --- a/ruamoko/qwaq/qwaq-curses.c +++ b/ruamoko/qwaq/qwaq-curses.c @@ -72,6 +72,7 @@ typedef enum qwaq_commands_e { qwaq_cmd_wrefresh, qwaq_cmd_init_pair, qwaq_cmd_wbkgd, + qwaq_cmd_scrollok, } qwaq_commands; #define RING_BUFFER(type, size) \ @@ -523,6 +524,16 @@ cmd_wbkgd (qwaq_resources_t *res) wbkgd (window->win, ch); } +static void +cmd_scrollok (qwaq_resources_t *res) +{ + int window_id = RB_PEEK_DATA (res->command_queue, 2); + int flag = RB_PEEK_DATA (res->command_queue, 3); + + window_t *window = get_window (res, __FUNCTION__, window_id); + scrollok (window->win, flag); +} + static void process_commands (qwaq_resources_t *res) { @@ -585,6 +596,9 @@ process_commands (qwaq_resources_t *res) case qwaq_cmd_wbkgd: cmd_wbkgd (res); break; + case qwaq_cmd_scrollok: + cmd_scrollok (res); + break; } RB_DROP_DATA (res->command_queue, RB_PEEK_DATA (res->command_queue, 1)); } @@ -881,6 +895,37 @@ bi_wprintf (progs_t *pr) } } +static void +bi_wvprintf (progs_t *pr) +{ + qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq"); + int window_id = P_INT (pr, 0); + const char *fmt = P_GSTRING (pr, 1); + __auto_type args = (pr_va_list_t *) &P_POINTER (pr, 2); + pr_type_t *list_start = PR_GetPointer (pr, args->list); + pr_type_t **list = alloca (args->count); + + for (int i = 0; i < args->count; i++) { + list[i] = list_start + i * pr->pr_param_size; + } + + if (get_window (res, __FUNCTION__, window_id)) { + int string_id = acquire_string (res); + dstring_t *print_buffer = res->strings + string_id; + int command[] = { + qwaq_cmd_waddstr, 0, + window_id, string_id + }; + + command[1] = CMD_SIZE(command); + + dstring_clearstr (print_buffer); + PR_Sprintf (pr, print_buffer, "waddstr", fmt, args->count, list); + + qwaq_submit_command (res, command); + } +} + static void bi_mvwaddch (progs_t *pr) { @@ -963,6 +1008,20 @@ bi_wbkgd (progs_t *pr) } } +static void +bi_scrollok (progs_t *pr) +{ + qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq"); + int window_id = P_INT (pr, 0); + int flag = P_INT (pr, 1); + + if (get_window (res, __FUNCTION__, window_id)) { + int command[] = { qwaq_cmd_scrollok, 0, window_id, flag, }; + command[1] = CMD_SIZE(command); + qwaq_submit_command (res, command); + } +} + static const char qwaq_acs_char_map[] = "lmkjtuvwqxnos`afg~,+.-hi0pryz{|}"; static void bi_acs_char (progs_t *pr) @@ -1029,6 +1088,7 @@ static builtin_t builtins[] = { {"doupdate", bi_doupdate, -1}, {"mvwprintf", bi_mvwprintf, -1}, {"wprintf", bi_wprintf, -1}, + {"wvprintf", bi_wvprintf, -1}, {"mvwaddch", bi_mvwaddch, -1}, {"wrefresh", bi_wrefresh, -1}, {"get_event", bi_get_event, -1}, @@ -1036,6 +1096,7 @@ static builtin_t builtins[] = { {"max_color_pairs", bi_max_color_pairs, -1}, {"init_pair", bi_init_pair, -1}, {"wbkgd", bi_wbkgd, -1}, + {"scrollok", bi_scrollok, -1}, {"acs_char", bi_acs_char, -1}, {0} }; diff --git a/ruamoko/qwaq/qwaq-curses.h b/ruamoko/qwaq/qwaq-curses.h index bf5d24191..e9574e764 100644 --- a/ruamoko/qwaq/qwaq-curses.h +++ b/ruamoko/qwaq/qwaq-curses.h @@ -75,6 +75,7 @@ typedef struct panel_s *panel_t; @extern void destroy_window (window_t win); @extern void mvwprintf (window_t win, int x, int y, string fmt, ...); @extern void wprintf (window_t win, string fmt, ...); +@extern void wvprintf (window_t win, string fmt, @va_list args); @extern void wrefresh (window_t win); @extern void mvwaddch (window_t win, int x, int y, int ch); @@ -94,6 +95,7 @@ typedef struct panel_s *panel_t; @extern int max_color_pairs (void); @extern int init_pair (int pair, int f, int b); @extern void wbkgd (window_t win, int ch); +@extern void scrollok (window_t win, int flag); @extern int acs_char (int acs); #endif diff --git a/ruamoko/qwaq/qwaq-draw.h b/ruamoko/qwaq/qwaq-draw.h index 4abac3e55..7b614a29e 100644 --- a/ruamoko/qwaq/qwaq-draw.h +++ b/ruamoko/qwaq/qwaq-draw.h @@ -3,6 +3,8 @@ @protocol Draw -draw; +-redraw; +-setParent: parent; @end #endif diff --git a/ruamoko/qwaq/qwaq-rect.h b/ruamoko/qwaq/qwaq-rect.h index 0c26b5817..c679352fc 100644 --- a/ruamoko/qwaq/qwaq-rect.h +++ b/ruamoko/qwaq/qwaq-rect.h @@ -1,7 +1,7 @@ #ifndef __qwaq_rect_h #define __qwaq_rect_h -typedef struct { +typedef struct Rect_s { int xpos; int ypos; int xlen; diff --git a/ruamoko/qwaq/qwaq-screen.h b/ruamoko/qwaq/qwaq-screen.h index 5ded2ecaf..8c83abb6e 100644 --- a/ruamoko/qwaq/qwaq-screen.h +++ b/ruamoko/qwaq/qwaq-screen.h @@ -10,16 +10,19 @@ @interface Screen: Object { - @public Rect rect; Array *views; Array *event_handlers; + Array *focused_handlers; + Array *mouse_handlers; + Array *mouse_handler_rects; View *focusedView; struct window_s *window; } +(Screen *) screen; -add: obj; -setBackground: (int) ch; +-printf: (string) fmt, ...; @end #endif//__qwaq_screen_h diff --git a/ruamoko/qwaq/qwaq-screen.r b/ruamoko/qwaq/qwaq-screen.r index 770104c64..0c8573a83 100644 --- a/ruamoko/qwaq/qwaq-screen.r +++ b/ruamoko/qwaq/qwaq-screen.r @@ -1,3 +1,4 @@ +#include #include "qwaq-curses.h" #include "qwaq-screen.h" @@ -14,7 +15,11 @@ } views = [[Array array] retain]; event_handlers = [[Array array] retain]; + focused_handlers = [[Array array] retain]; + mouse_handlers = [[Array array] retain]; + mouse_handler_rects = [[Array array] retain]; window = stdscr; + scrollok (window, 1); rect = getwrect (window); return self; } @@ -22,10 +27,22 @@ -add: obj { if ([obj conformsToProtocol: @protocol (Draw)]) { + // "top" objects are drawn last [views addObject: obj]; + [obj setParent: self]; + } + if ([obj conformsToProtocol: @protocol (HandleFocusedEvent)]) { + // want "top" objects to respond first + [focused_handlers insertObject: obj atIndex: 0]; + } + if ([obj conformsToProtocol: @protocol (HandleMouseEvent)]) { + // "top" objects respond first, but the array is searched in reverse + [mouse_handlers addObject: obj]; + [mouse_handler_rects addObject: (id) [obj getRect]]; } if ([obj conformsToProtocol: @protocol (HandleEvent)]) { - [event_handlers addObject: obj]; + // want "top" objects to respond first + [event_handlers insertObject: obj atIndex: 0]; } return self; } @@ -38,6 +55,25 @@ -handleEvent: (qwaq_event_t *) event { + switch (event.event_type) { + case qe_none: + break; + case qe_key: + case qe_command: + [focused_handlers + makeObjectsPerformSelector: @selector(handleEvent:) + withObject: (id) event]; + break; + case qe_mouse: + Point p = { event.e.mouse.x, event.e.mouse.y }; + for (int i = [mouse_handler_rects count]; i-->0; ) { + //if (rectContainsPoint((Rect*)mouse_handler_rects._objs[i], &p)) { + // [mouse_handlers._objs[i] handleEvent: event]; + // break; + //} + } + break; + } return self; } @@ -49,4 +85,29 @@ return self; } +-redraw +{ + [self error:"hmm"]; + update_panels (); + doupdate (); + return self; +} + +-printf: (string) fmt, ... +{ + wvprintf (window, fmt, @args); + return self; +} + +-addch: (int) ch atX: (int) x Y: (int) y +{ + mvwaddch(window, x, y, ch); + return self; +} + +-setParent: parent +{ + return self; +} + @end diff --git a/ruamoko/qwaq/qwaq-view.h b/ruamoko/qwaq/qwaq-view.h index 817ec0ab7..e7c0db85e 100644 --- a/ruamoko/qwaq/qwaq-view.h +++ b/ruamoko/qwaq/qwaq-view.h @@ -13,6 +13,7 @@ Rect rect; Rect absRect; Point point; // can't be local :( + id parent; struct window_s *window; } -initWithRect: (Rect) rect; diff --git a/ruamoko/qwaq/qwaq-view.r b/ruamoko/qwaq/qwaq-view.r index 8cf37c53d..bc218630f 100644 --- a/ruamoko/qwaq/qwaq-view.r +++ b/ruamoko/qwaq/qwaq-view.r @@ -33,6 +33,17 @@ rectContainsPoint (Rect *rect, Point *point) return self; } +-setParent: parent +{ + self.parent = parent; + return self; +} + +-redraw +{ + return [parent redraw]; +} + @end Rect getwrect (window_t window) = #0; diff --git a/ruamoko/qwaq/qwaq-window.h b/ruamoko/qwaq/qwaq-window.h index ae45d7e72..19921301a 100644 --- a/ruamoko/qwaq/qwaq-window.h +++ b/ruamoko/qwaq/qwaq-window.h @@ -9,10 +9,10 @@ #include "qwaq-draw.h" #include "qwaq-rect.h" -@interface Window: Object +@interface Window: Object { - @public Rect rect; + id parent; Point point; // FIXME can't be local :( Array *views; View *focusedView; diff --git a/ruamoko/qwaq/qwaq-window.r b/ruamoko/qwaq/qwaq-window.r index 493a6ccff..7e201aa9a 100644 --- a/ruamoko/qwaq/qwaq-window.r +++ b/ruamoko/qwaq/qwaq-window.r @@ -17,6 +17,7 @@ if (!(self = [super init])) { return nil; } + views = [[Array array] retain]; self.rect = rect; window = create_window (rect.xpos, rect.ypos, rect.xlen, rect.ylen); panel = create_panel (window); @@ -27,6 +28,9 @@ { switch (event.event_type) { case qe_mouse: + mvwprintf(window, 0, 3, "%2d %2d %08x", + event.e.mouse.x, event.e.mouse.y, event.e.mouse.buttons); + [self redraw]; point.x = event.e.mouse.x; point.y = event.e.mouse.y; for (int i = [views count]; i--> 0; ) { @@ -60,6 +64,7 @@ view.absRect.xpos = view.rect.xpos + rect.xpos; view.absRect.ypos = view.rect.ypos + rect.ypos; view.window = window; + [view setParent: self]; return self; } @@ -96,6 +101,23 @@ } } } + [views makeObjectsPerformSelector: @selector (draw)]; return self; } + +-(Rect *) getRect +{ + return ▭ +} + +-setParent: parent +{ + self.parent = parent; + return self; +} + +-redraw +{ + return [parent redraw]; +} @end