[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.
This commit is contained in:
Bill Currie 2020-03-03 21:30:47 +09:00
parent 7976eec2ce
commit c58cf2c2d0
12 changed files with 180 additions and 11 deletions

View file

@ -37,11 +37,15 @@ typedef struct qwaq_event_s {
-handleEvent: (struct qwaq_event_s *) event;
@end
@protocol TakeFocus <HandleEvent>
@protocol HandleFocusedEvent <HandleEvent>
-takeFocus;
-loseFocus;
@end
@protocol HandleMouseEvent <HandleEvent>
-(struct Rect_s *)getRect;
@end
#endif
#endif//__qwaq_event_h

View file

@ -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;

View file

@ -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}
};

View file

@ -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

View file

@ -3,6 +3,8 @@
@protocol Draw
-draw;
-redraw;
-setParent: parent;
@end
#endif

View file

@ -1,7 +1,7 @@
#ifndef __qwaq_rect_h
#define __qwaq_rect_h
typedef struct {
typedef struct Rect_s {
int xpos;
int ypos;
int xlen;

View file

@ -10,16 +10,19 @@
@interface Screen: Object <HandleEvent, Draw>
{
@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

View file

@ -1,3 +1,4 @@
#include <Array.h>
#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

View file

@ -13,6 +13,7 @@
Rect rect;
Rect absRect;
Point point; // can't be local :(
id parent;
struct window_s *window;
}
-initWithRect: (Rect) rect;

View file

@ -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;

View file

@ -9,10 +9,10 @@
#include "qwaq-draw.h"
#include "qwaq-rect.h"
@interface Window: Object <Draw, TakeFocus>
@interface Window: Object <Draw, HandleFocusedEvent, HandleMouseEvent>
{
@public
Rect rect;
id parent;
Point point; // FIXME can't be local :(
Array *views;
View *focusedView;

View file

@ -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 &rect;
}
-setParent: parent
{
self.parent = parent;
return self;
}
-redraw
{
return [parent redraw];
}
@end