[qwaq] Add Group and clean up lots of mess

Things are finally doing something again, and getting closer to having a
moveable window.
This commit is contained in:
Bill Currie 2020-03-05 15:44:53 +09:00
parent 1bf56b28ac
commit c377b324a1
15 changed files with 287 additions and 117 deletions

View file

@ -23,8 +23,8 @@ SUFFIXES=.o .r
sed -i -e '1s@:@: $(QFCC_DEP)@' $(DEPDIR)/$*.Tqo
$(am__mv) $(DEPDIR)/$*.Tqo $(DEPDIR)/$*.Qo
qwaq_dat_src= \
$e
qwaq_app_dat_src= \
qwaq-app.r qwaq-group.r qwaq-screen.r qwaq-window.r qwaq-view.r
qwaq_curses_libs=
qwaq_curses_SOURCES=main.c qwaq-curses.c
@ -59,7 +59,7 @@ qwaq_x11_DEPENDENCIES= $(qwaq_x11_libs) $(QWAQ_DEPS)
r_depfiles_remade=
qwaq_app_dat_SOURCES=qwaq-app.r qwaq-screen.r qwaq-window.r qwaq-view.r
qwaq_app_dat_SOURCES=$(qwaq_app_dat_src)
qwaq_app_obj=$(qwaq_app_dat_SOURCES:.r=.o)
qwaq_app_dep=$(addprefix ./$(DEPDIR)/,$(qwaq_app_obj:.o=.Qo))
qwaq-app.dat$(EXEEXT): $(qwaq_app_obj) $(QFCC_DEP)

View file

@ -26,6 +26,7 @@ typedef enum {
qe_message = 0xfe00,
qe_focused = qe_key | qe_command,
qe_positional = qe_mouse,
} qwaq_event_mask;
typedef enum {

View file

@ -39,17 +39,19 @@ arp_end (void)
screen = [[Screen screen] retain];
[screen setBackground: COLOR_PAIR (1)];
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;
[screen printf:"%d %d %d %d\n", r.xpos, r.ypos, r.xlen, r.ylen];
[screen printf:"%d %d %d %d\n",
r.offset.x, r.offset.y, r.extent.width, r.extent.height];
r.offset.x = r.extent.width / 4;
r.offset.y = r.extent.height / 4;
r.extent.width /= 2;
r.extent.height /= 2;
[screen printf:"%d %d %d %d\n",
r.offset.x, r.offset.y, r.extent.width, r.extent.height];
[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);
//wprintf (w.window, "%d %d %d %d\n", r.offset.x, r.offset.y, r.extent.width, r.ylen);
[screen redraw];
return self;
}
@ -128,3 +130,5 @@ void move_panel (panel_t panel, int x, int y) = #0;
window_t panel_window (panel_t panel) = #0;
void update_panels (void) = #0;
void doupdate (void) = #0;
int curs_set (int visibility) = #0;
int move (int x, int y) = #0;

View file

@ -73,6 +73,8 @@ typedef enum qwaq_commands_e {
qwaq_cmd_init_pair,
qwaq_cmd_wbkgd,
qwaq_cmd_scrollok,
qwaq_cmd_move,
qwaq_cmd_curs_set,
} qwaq_commands;
#define RING_BUFFER(type, size) \
@ -539,6 +541,23 @@ cmd_scrollok (qwaq_resources_t *res)
scrollok (window->win, flag);
}
static void
cmd_move (qwaq_resources_t *res)
{
int x = RB_PEEK_DATA (res->command_queue, 2);
int y = RB_PEEK_DATA (res->command_queue, 3);
move (y, x);
}
static void
cmd_curs_set (qwaq_resources_t *res)
{
int visibility = RB_PEEK_DATA (res->command_queue, 2);
curs_set (visibility);
}
static void
process_commands (qwaq_resources_t *res)
{
@ -604,6 +623,12 @@ process_commands (qwaq_resources_t *res)
case qwaq_cmd_scrollok:
cmd_scrollok (res);
break;
case qwaq_cmd_move:
cmd_move (res);
break;
case qwaq_cmd_curs_set:
cmd_curs_set (res);
break;
}
RB_DROP_DATA (res->command_queue, RB_PEEK_DATA (res->command_queue, 1));
}
@ -1106,6 +1131,29 @@ bi_acs_char (progs_t *pr)
}
}
static void
bi_move (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int x = P_INT (pr, 0);
int y = P_INT (pr, 1);
int command[] = { qwaq_cmd_move, 0, x, y, };
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
}
static void
bi_curs_set (progs_t *pr)
{
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
int visibility = P_INT (pr, 0);
int command[] = { qwaq_cmd_curs_set, 0, visibility, };
command[1] = CMD_SIZE(command);
qwaq_submit_command (res, command);
}
static void
bi_initialize (progs_t *pr)
{
@ -1168,6 +1216,8 @@ static builtin_t builtins[] = {
{"wbkgd", bi_wbkgd, -1},
{"scrollok", bi_scrollok, -1},
{"acs_char", bi_acs_char, -1},
{"move", bi_move, -1},
{"curs_set", bi_curs_set, -1},
{0}
};

View file

@ -98,6 +98,8 @@ typedef struct panel_s *panel_t;
@extern void scrollok (window_t win, int flag);
@extern int acs_char (int acs);
@extern int curs_set (int visibility);
@extern int move (int x, int y);
#endif
#endif//__qwaq_curses_h

View file

@ -4,7 +4,8 @@
@protocol Draw
-draw;
-redraw;
-setParent: parent;
-setOwner: owner;
-(struct window_s*) getWindow;
@end
#endif

17
ruamoko/qwaq/qwaq-group.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef __qwaq_group_h
#define __qwaq_group_h
#include "qwaq-view.h"
@class Array;
@interface Group : View
{
Array *views;
int focused;
}
-insert: (View *) view;
-remove: (View *) view;
@end
#endif//__qwaq_group_h

60
ruamoko/qwaq/qwaq-group.r Normal file
View file

@ -0,0 +1,60 @@
#include <Array.h>
#include "event.h"
#include "qwaq-group.h"
@implementation Group
-init
{
if (!(self = [super init])) {
return nil;
}
views = [[Array array] retain];
return self;
}
-(void)dealloc
{
[views release];
}
-insert: (View *) view
{
[views insertObject: view atIndex: 0];
return self;
}
-remove: (View *) view
{
int index = [views indexOfObject: view];
if (index != NotFound) {
if (focused == index) {
focused = -1;
} else if (focused > index) {
focused--;
}
[views removeObjectAtIndex: index];
}
return self;
}
-draw
{
[views makeObjectsPerformSelector: @selector(draw)];
return self;
}
-handleEvent: (qwaq_event_t *) event
{
[super handleEvent: event];
if (event.what & qe_focused) {
if (focused >= 0) {
[[views objectAtIndex:focused] handleEvent: event];
}
} else if (event.what & qe_positional) {
} else {
// broadcast
[views makeObjectsPerformSelector: @selector(draw) withObject: event];
}
return self;
}
@end

View file

@ -1,18 +1,21 @@
#ifndef __qwaq_rect_h
#define __qwaq_rect_h
typedef struct Rect_s {
int xpos;
int ypos;
int xlen;
int ylen;
} Rect;
typedef struct {
int x;
int y;
} Point;
typedef struct {
int width;
int height;
} Extent;
typedef struct Rect_s {
Point offset;
Extent extent;
} Rect;
@extern Rect makeRect (int xpos, int ypos, int xlen, int ylen);
//XXX will not work if point or rect point to a local variabl
@extern int rectContainsPoint (Rect *rect, Point *point);

View file

@ -1,28 +1,18 @@
#ifndef __qwaq_screen_h
#define __qwaq_screen_h
#include <Object.h>
#include "qwaq-draw.h"
#include "qwaq-rect.h"
@class View;
@class Array;
#include "qwaq-view.h"
@interface Screen: Object <HandleMouseEvent, Draw>
@interface Screen: View
{
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;
-handleEvent: (qwaq_event_t *) event;
-setBackground: (int) ch;
-printf: (string) fmt, ...;
-addch: (int) ch atX: (int) x Y: (int) y;
@end
#endif//__qwaq_screen_h

View file

@ -13,40 +13,12 @@
if (!(self = [super init])) {
return nil;
}
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;
}
-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)]) {
// want "top" objects to respond first
[event_handlers insertObject: obj atIndex: 0];
}
return self;
}
-setBackground: (int) ch
{
wbkgd (window, ch);
@ -58,33 +30,12 @@
if (event.what & qe_mouse) {
[self printf:"%04x %2d %2d %d %08x\r", event.what, event.mouse.x, event.mouse.y, event.mouse.click, event.mouse.buttons];
[self redraw];
Point p = { event.mouse.x, event.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;
//}
}
} 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;
}
return self;
}
-draw
{
[views makeObjectsPerformSelector: @selector (draw)];
update_panels ();
doupdate ();
return self;
@ -115,7 +66,7 @@
return &rect;
}
-setParent: parent
-setOwner: owner
{
return self;
}

View file

@ -7,16 +7,56 @@
#include "qwaq-draw.h"
#include "qwaq-rect.h"
@interface View: Object <Draw>
@class Group;
enum {
ofCanFocus =0x0001,
ofFirstClick =0x0002,
ofDontDraw =0x0004,
ofPreProcess =0x0008,
ofPostProcess =0x0010,
ofMakeFirst =0x0020,
ofTileable =0x0040,
ofCentered =0x0080,
ofCallHasObject =0x8000,
};
enum {
sfDrawn =0x0001,
sfDisabled =0x0002,
sfInFocus =0x0004,
sfModal =0x0008,
sfLocked =0x0010,
};
@interface View: Object
{
@public
Rect rect;
union {
Rect rect;
struct {
int xpos;
int ypos;
int xlen;
int ylen;
};
};
Rect absRect;
Point point; // can't be local :(
id parent;
Group *owner;
struct window_s *window;
int state;
int options;
int cursorState;
Point cursor;
}
-initWithRect: (Rect) rect;
- (void) dealloc;
-(struct window_s *) getWindow;
-setOwner: (Group *) owner;
-(struct Rect_s *)getRect;
-draw;
-redraw;
@end
#endif//__qwaq_view_h

View file

@ -1,18 +1,21 @@
#include "qwaq-curses.h"
#include "qwaq-view.h"
#include "qwaq-group.h"
Rect
makeRect (int xpos, int ypos, int xlen, int ylen)
{
Rect rect = {xpos, ypos, xlen, ylen};
Rect rect = {{xpos, ypos}, {xlen, ylen}};
return rect;
}
int
rectContainsPoint (Rect *rect, Point *point)
{
return ((point.x >= rect.xpos && point.x < rect.xpos + rect.xlen)
&& (point.y >= rect.ypos && point.y < rect.ypos + rect.ylen));
return ((point.x >= rect.offset.x
&& point.x < rect.offset.x + rect.extent.width)
&& (point.y >= rect.offset.y
&& point.y < rect.offset.y + rect.extent.height));
}
@implementation View
@ -24,24 +27,83 @@ rectContainsPoint (Rect *rect, Point *point)
}
self.rect = rect;
self.absRect = rect;
self.window = nil;
return self;
}
- (void) dealloc
{
if (owner) {
[owner remove:self];
}
[super dealloc];
}
static void
updateScreenCursor (View *view)
{
while ((view.state & sfInFocus) && view.owner) {
View *owner = (View *) view.owner;
if (view.cursor.x >= 0 && view.cursor.x < view.xlen
&& view.cursor.y >= 0 && view.cursor.y < view.ylen) {
owner.cursor.x = view.cursor.x + view.xpos;
owner.cursor.y = view.cursor.y + view.ypos;
owner.cursorState = view.cursorState;
} else {
owner.cursorState = 0;
}
view = owner;
}
if (view.state & sfInFocus) {
if (view.cursor.x >= 0 && view.cursor.x < view.xlen
&& view.cursor.y >= 0 && view.cursor.y < view.ylen) {
curs_set (view.cursorState);
move(view.cursor.x, view.cursor.y);
} else {
curs_set (0);
}
}
}
-draw
{
state |= sfDrawn;
updateScreenCursor (self);
return self;
}
-setParent: parent
-hide
{
self.parent = parent;
if (state & sfDrawn) {
state &= ~sfDrawn;
updateScreenCursor (self);
}
return self;
}
-redraw
{
return [parent redraw];
if ((state & sfDrawn) && !(options & ofDontDraw)) {
[self draw];
[owner redraw];
}
return self;
}
-setOwner: (Group *) owner
{
self.owner = owner;
window = [owner getWindow];
return self;
}
-(window_t) getWindow
{
return window;
}
- (Rect *) getRect
{
return &rect;
}
@end

View file

@ -3,16 +3,15 @@
#include "Object.h"
@class View;
@class Array;
#include "qwaq-draw.h"
#include "qwaq-rect.h"
#include "qwaq-view.h"
#include "qwaq-group.h"
@interface Window: Object <Draw, HandleFocusedEvent, HandleMouseEvent>
@interface Window: Group
{
Rect rect;
id parent;
Point point; // FIXME can't be local :(
Array *views;
View *focusedView;

View file

@ -19,14 +19,14 @@
}
views = [[Array array] retain];
self.rect = rect;
window = create_window (rect.xpos, rect.ypos, rect.xlen, rect.ylen);
window = create_window (xpos, ypos, xlen, ylen);
panel = create_panel (window);
return self;
}
-handleEvent: (qwaq_event_t *) event
{
switch (event.what) {
/* switch (event.what) {
case qe_mouse:
mvwprintf(window, 0, 3, "%2d %2d %08x",
event.mouse.x, event.mouse.y, event.mouse.buttons);
@ -54,17 +54,17 @@
break;
case qe_none:
break;
}
}*/
return self;
}
-addView: (View *) view
{
[views addObject: view];
/* [views addObject: view];
view.absRect.xpos = view.rect.xpos + rect.xpos;
view.absRect.ypos = view.rect.ypos + rect.ypos;
view.window = window;
[view setParent: self];
[view setOwner: self];*/
return self;
}
@ -74,16 +74,6 @@
return self;
}
-takeFocus
{
return self;
}
-loseFocus
{
return self;
}
-draw
{
int x = 0, y = 0;
@ -94,9 +84,9 @@
} else {
mvwaddch (window, x, y, '.');
}
if (++x >= rect.xlen) {
if (++x >= xlen) {
x = 0;
if (++y >= rect.ylen) {
if (++y >= ylen) {
break;
}
}
@ -110,14 +100,14 @@
return &rect;
}
-setParent: parent
-setOwner: owner
{
self.parent = parent;
self.owner = owner;
return self;
}
-redraw
{
return [parent redraw];
return [owner redraw];
}
@end