ref: 6d347772d007e854bfcbdaecbb38abd7ef56ac6f
parent: 9c7d5576c074bd7b9d0fe8a249df31da2df31c9e
author: sirjofri <sirjofri@sirjofri.de>
date: Mon May 13 16:16:09 EDT 2024
first working ui, still with issues
--- a/mkfile
+++ b/mkfile
@@ -98,5 +98,7 @@
</sys/src/cmd/mkmany
+# LDFLAGS=$LDFLAGS -p
+
auxiliary/hatgen.$O: auxiliary/hatgen.c
$CC $CFLAGS -o $target auxiliary/hatgen.c
--- a/plan9.c
+++ b/plan9.c
@@ -12,6 +12,8 @@
#error Plan 9 should not be COMBINED
#endif
+//#define DIRECTDRAW
+
struct frontend {
Image *image;
midend *me;
@@ -19,14 +21,13 @@
Image **colors;
int ncolors;
Point ZP;
- int topbarh;
Controlset *cs;
Channel *c;
int showframe;
- Rectangle rect;
+ int timeractive;
};
-frontend *fe;
+frontend *fe = nil;
void
frontend_default_colour(frontend *fe, float *output)
@@ -49,10 +50,12 @@
void
deactivate_timer(frontend *fe)
{
+ fe->timeractive = 0;
}
void activate_timer(frontend *fe)
{
+ fe->timeractive = 1;
}
void fatal(const char *fmt, ...)
@@ -86,10 +89,18 @@
exits(nil);
}
+char *showcmd = "c_game show";
+#define ugf chanprint(fe->cs->ctl, showcmd);
+
static void p9_draw_text(void *handle, int x, int y, int fonttype, int fontsize, int align, int color, const char *text)
{
frontend *fe = (frontend*)handle;
+#ifdef DIRECTDRAW
+ string(screen, addpt(Pt(x, y), fe->ZP), fe->colors[color], ZP, font, text);
+#else
string(fe->image, Pt(x, y), fe->colors[color], ZP, font, text);
+ ugf;
+#endif
}
static void
@@ -96,7 +107,12 @@
p9_draw_rect(void *handle, int x, int y, int w, int h, int color)
{
frontend *fe = (frontend*)handle;
+#ifdef DIRECTDRAW
+ draw(screen, rectaddpt(Rect(x, y, x+w, y+h), fe->ZP), fe->colors[color], nil, ZP);
+#else
draw(fe->image, Rect(x, y, x+w, y+h), fe->colors[color], nil, ZP);
+ ugf;
+#endif
}
static void
@@ -103,7 +119,12 @@
p9_draw_line(void *handle, int x1, int y1, int x2, int y2, int color)
{
frontend *fe = (frontend*)handle;
+#ifdef DIRECTDRAW
+ line(screen, addpt(Pt(x1, y1), fe->ZP), addpt(Pt(x2, y2), fe->ZP), Endsquare, Endsquare, 1, fe->colors[color], ZP);
+#else
line(fe->image, Pt(x1, y1), Pt(x2, y2), Endsquare, Endsquare, 1, fe->colors[color], ZP);
+ ugf;
+#endif
}
static void
@@ -110,7 +131,12 @@
p9_draw_thick_line(void *handle, float thickness, float x1, float y1, float x2, float y2, int color)
{
frontend *fe = (frontend*)handle;
+#ifdef DIRECTDRAW
+ line(screen, addpt(Pt(x1, y1), fe->ZP), addpt(Pt(x2, y2), fe->ZP), Endsquare, Endsquare, thickness, fe->colors[color], ZP);
+#else
line(fe->image, Pt(x1, y1), Pt(x2, y2), Endsquare, Endsquare, thickness, fe->colors[color], ZP);
+ ugf;
+#endif
}
static void
@@ -121,14 +147,27 @@
points = malloc(npoints * sizeof(Point));
for (int i = 0; i < npoints; i++) {
+#ifdef DIRECTDRAW
+ points[i].x = coords[i*2+0] + fe->ZP.x;
+ points[i].y = coords[i*2+1] + fe->ZP.y;
+#else
points[i].x = coords[i*2+0];
points[i].y = coords[i*2+1];
+#endif
}
+#ifdef DIRECTDRAW
if (fillcolor > 0)
+ fillpoly(screen, points, npoints, 0, fe->colors[fillcolor], ZP);
+ if (outlinecolor > 0)
+ poly(screen, points, npoints, Endsquare, Endsquare, 1, fe->colors[outlinecolor], ZP);
+#else
+ if (fillcolor > 0)
fillpoly(fe->image, points, npoints, 0, fe->colors[fillcolor], ZP);
if (outlinecolor > 0)
poly(fe->image, points, npoints, Endsquare, Endsquare, 1, fe->colors[outlinecolor], ZP);
+ ugf;
+#endif
free(points);
}
@@ -137,14 +176,23 @@
p9_draw_circle(void *handle, int cx, int cy, int radius, int fillcolor, int outlinecolor)
{
frontend *fe = (frontend*)handle;
+#ifdef DIRECTDRAW
+ Point c = addpt(Pt(cx, cy), fe->ZP);
+ fillellipse(screen, c, radius, radius, fe->colors[fillcolor], ZP);
+ ellipse(screen, c, radius, radius, 0, fe->colors[outlinecolor], ZP);
+#else
Point c = Pt(cx, cy);
fillellipse(fe->image, c, radius, radius, fe->colors[fillcolor], ZP);
ellipse(fe->image, c, radius, radius, 0, fe->colors[outlinecolor], ZP);
+ ugf;
+#endif
}
static void
p9_draw_update(void *handle, int x, int y, int w, int h)
{
+ frontend *fe = (frontend*)handle;
+ chanprint(fe->cs->ctl, showcmd);
}
static void
@@ -165,8 +213,6 @@
static void
p9_end_draw(void *handle)
{
- frontend* fe = (frontend*)handle;
- chanprint(fe->cs->ctl, "c_game image frame");
}
static void
@@ -175,10 +221,6 @@
frontend *fe = (frontend*)handle;
chanprint(fe->cs->ctl, "l_status value %q", text);
-
- return;
- draw(fe->image, Rect(fe->ZP.x+10, fe->image->r.max.y-20, fe->image->r.max.x, fe->image->r.max.y), fe->background, nil, ZP);
- string(fe->image, Pt(fe->ZP.x+10, fe->image->r.max.y-20), display->black, ZP, font, text);
}
static blitter*
@@ -254,7 +296,6 @@
Point p;
menu = createrow(cs, "rowmain");
- chanprint(cs->ctl, "rowmain border 1");
stackmain = createstack(cs, "stackmain");
chanprint(cs->ctl, "stackmain border 1");
@@ -265,12 +306,14 @@
chanprint(cs->ctl, "b_game border 1");
chanprint(cs->ctl, "b_game align center");
chanprint(cs->ctl, "b_game text game");
- chanprint(cs->ctl, "b_game image i_white");
- chanprint(cs->ctl, "b_game light i_black");
- chanprint(cs->ctl, "b_game size %d %d 100 %d", p.x, p.y, p.y);
+ chanprint(cs->ctl, "b_game size %d %d 500 %d", p.x, p.y, p.y);
c_game = createbox(cs, "c_game");
- chanprint(cs->ctl, "c_game image frame");
chanprint(cs->ctl, "c_game border 1");
+#ifdef DIRECTDRAW
+ chanprint(cs->ctl, "c_game image background");
+#else
+ chanprint(cs->ctl, "c_game image frame");
+#endif
controlwire(c_game, "event", c);
controlwire(b_game, "event", c);
@@ -277,8 +320,8 @@
b_settings = createtextbutton(cs, "b_settings");
p = stringsize(font, "settings");
chanprint(cs->ctl, "b_settings text settings");
- chanprint(cs->ctl, "b_settings border 1");
- chanprint(cs->ctl, "b_settings size %d %d 100 %d", p.x, p.y, p.y);
+ chanprint(cs->ctl, "b_settings align center");
+ chanprint(cs->ctl, "b_settings size %d %d 500 %d", p.x, p.y, p.y);
c_settings = createcolumn(cs, "c_settings");
controlwire(c_settings, "event", c);
controlwire(b_settings, "event", c);
@@ -294,8 +337,26 @@
}
void
-initfe(frontend *fe, Channel *c)
+timerthread(void *v)
{
+ Channel *c;
+ long totaltime;
+ long newtime;
+
+ c = v;
+ totaltime = times(nil);
+
+ for (;;) {
+ sleep(100); /* minimum tick time */
+ newtime = times(nil);
+ chanprint(c, "tick: %ld\n", newtime - totaltime);
+ totaltime = newtime;
+ }
+}
+
+void
+initfe(frontend *fe)
+{
float *colors;
int ncolors;
int r, g, b;
@@ -302,10 +363,7 @@
int col;
float bgcol[3];
- fe->topbarh = 20;
fe->image = allocimage(display, screen->r, screen->chan, 0, 0);
- fe->ZP = screen->r.min;
- fe->ZP.y += fe->topbarh;
frontend_default_colour(fe, bgcol);
fe->background = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, rgb2col(bgcol[0]*255., bgcol[1]*255., bgcol[2]*255.));
@@ -320,24 +378,44 @@
}
free(colors);
- fe->cs = newcontrolset(fe->image, nil, nil, nil);
- fe->cs->clicktotype = 1;
- fe->c = c;
+ fe->cs = newcontrolset(screen, nil, nil, nil);
+ fe->c = chancreate(sizeof(char*), 0);
ctldeletequits = 1;
namectlimage(fe->image, "frame");
namectlimage(display->black, "i_black");
namectlimage(display->white, "i_white");
+ namectlimage(fe->background, "background");
initui(fe->cs, fe->c);
+
+ // needs different timer option - atnotify(2) / alarm(2) ?
+ //threadcreate(timerthread, fe->c, 4096);
}
-void
-resize(void)
+int windowset = 0;
+
+Point
+resize(int *resizenop)
{
- int x, y;
- x = screen->r.max.x - screen->r.min.x;
- y = screen->r.max.y - screen->r.min.y;
+ int x, y, fd;
+ x = Dx(screen->r);
+ y = Dy(screen->r) - 2*font->height;
midend_size(fe->me, &x, &y, 1, 1.);
+
+ // to test
+ if (0 && !windowset) {
+ fd = open("/dev/wctl", OWRITE);
+ if (fd >= 0) {
+ fprint(fd, "resize -dx %d -dy %d\n", x+2, y + 2*font->height);
+ close(fd);
+ windowset = 1;
+ }
+ } else
+ windowset = 0;
+
+ /* do not resize if we're waiting for the window resize */
+ *resizenop = windowset;
+ return Pt(x, y);
}
void
@@ -344,7 +422,9 @@
resizecontrolset(Controlset *cs)
{
Rectangle rmenu, rarea, sarea;
+ int resizenop;
Control *ctl;
+ Point newsize;
if (getwindow(display, Refnone) < 0) {
sysfatal("resize failed: %r");
@@ -351,23 +431,27 @@
}
rmenu = screen->r;
- rmenu.max.y = rmenu.min.y + 16;
+ rmenu.max.y = rmenu.min.y + font->height;
rarea = screen->r;
- rarea.min.y = rmenu.min.y + 16;
- rarea.max.y = rarea.max.y - 16;
+ rarea.min.y = rmenu.min.y + font->height;
+ rarea.max.y = rarea.max.y - font->height;
sarea = screen->r;
- sarea.min.y = sarea.max.y - 16;
+ sarea.min.y = sarea.max.y - font->height;
if (fe->image) {
freeimage(fe->image);
fe->image = nil;
}
- fe->image = allocimage(display, screen->r, screen->chan, 0, 0);
- fe->rect = rarea;
+ newsize = resize(&resizenop);
+ fe->image = allocimage(display, Rect(0, 0, newsize.x, newsize.y), screen->chan, 0, 0);
+ if (0 && resizenop)
+ return;
draw(screen, screen->r, fe->background, nil, ZP);
- resize();
- midend_redraw(fe->me);
+#ifndef DIRECTDRAW
+ midend_force_redraw(fe->me);
+#endif
+
chanprint(cs->ctl, "rowmain rect %R\nrowmain show", rmenu);
chanprint(cs->ctl, "c_game rect %R\nc_settings rect %R", rarea, rarea);
chanprint(cs->ctl, "stackmain rect %R\nstackmain show", rarea);
@@ -374,6 +458,11 @@
chanprint(cs->ctl, "stackmain reveal %d", fe->showframe);
chanprint(cs->ctl, "l_status rect %R\nl_status show", sarea);
+#ifdef DIRECTDRAW
+ if (fe->showframe == 0)
+ midend_force_redraw(fe->me);
+#endif
+
ctl = controlcalled("c_game");
fe->ZP = ctl->rect.min;
}
@@ -461,6 +550,8 @@
void
showframe(int frame)
{
+ if (frame == 0)
+ midend_force_redraw(fe->me);
fe->showframe = frame;
chanprint(fe->cs->ctl, "stackmain reveal %d", frame);
}
@@ -480,9 +571,18 @@
}
void
+tick(float delta)
+{
+ if (fe->timeractive) {
+ midend_timer(fe->me, delta);
+ }
+}
+
+void
threadmain(int argc, char **argv)
{
- int x, y, n;
+ int x, y, n, r;
+ int lastmouse;
long l;
char *s, *args[6];
int doprintoptions = 0;
@@ -528,8 +628,7 @@
initcontrols();
- c = chancreate(sizeof(char*), 0);
- initfe(fe, c);
+ initfe(fe);
midend_new_game(fe->me);
resizecontrolset(fe->cs);
@@ -545,27 +644,41 @@
x = atoi(args[2]+1) - fe->ZP.x; /* ignore '[' */
y = atoi(args[3]) - fe->ZP.y;
n = atoi(args[4]);
- if (n&1)
- midend_process_key(fe->me, x, y, LEFT_BUTTON);
- if (n&2)
- midend_process_key(fe->me, x, y, MIDDLE_BUTTON);
- if (n&4)
- midend_process_key(fe->me, x, y, RIGHT_BUTTON);
+ r = -1;
+ if ( (lastmouse&1) && !(n&1))
+ r = midend_process_key(fe->me, x, y, LEFT_RELEASE);
+ if (!(lastmouse&1) && (n&1))
+ r = midend_process_key(fe->me, x, y, LEFT_BUTTON);
+ if ( (lastmouse&2) && !(n&2))
+ r = midend_process_key(fe->me, x, y, MIDDLE_RELEASE);
+ if (!(lastmouse&2) && (n&2))
+ r = midend_process_key(fe->me, x, y, MIDDLE_BUTTON);
+ if ( (lastmouse&4) && !(n&4))
+ r = midend_process_key(fe->me, x, y, RIGHT_RELEASE);
+ if (!(lastmouse&4) && (n&2))
+ r = midend_process_key(fe->me, x, y, RIGHT_BUTTON);
+ if (r >= 0) {
+ chanprint(fe->cs->ctl, showcmd);
+ }
+ lastmouse = n;
} else
if (strcmp(args[1], "key") == 0) {
l = strtol(args[2], nil, 0);
if (keyev(l))
break;
- } else
- print("c_game event: %s\n", args[1]);
+ }
} else
if (strcmp(args[0], "b_game:") == 0) {
- print("b_game pressed\n");
showframe(0);
+ chanprint(fe->cs->ctl, "b_game value 0");
} else
if (strcmp(args[0], "b_settings:") == 0) {
- print("b_settings pressed\n");
showframe(1);
+ chanprint(fe->cs->ctl, "b_settings value 0");
+ } else
+ if (strcmp(args[0], "tick:") == 0) {
+ l = strtol(args[1], nil, 0);
+ tick(l / 1000.);
} else
print("event from %s: %s\n", args[0], args[1]);
}