ref: 7455a7027cde79e0304bade55b6616983e2e8e1a
parent: bb63f08a8acc62f17975b108c918f4ff20c1f2c0
author: sirjofri <[email protected]>
date: Fri Sep 6 12:46:29 EDT 2024
adds ask function (plus test)
--- /dev/null
+++ b/ask.c
@@ -1,0 +1,139 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <memdraw.h>
+#include <event.h>
+#include <keyboard.h>
+#include "blie.h"
+
+static int asklineheight = 50;
+static int numberasks = 0;
+static int width = 200;
+
+static void
+dodraw(Image *img, Rectangle r, Ask *asks)
+{
+ int i;
+ Point p;
+ Rectangle box;
+
+ replclipr(img, 0, r);
+ draw(img, r, display->white, nil, ZP);
+ border(img, r, 1, display->black, ZP);
+
+ box.min = ZP;
+ box.max.x = width - 2*5;
+ box.max.y = font->height + 4;
+
+ p = r.min;
+ p.x += 5; /* margin left */
+
+ for (i = 0; i < numberasks; i++) {
+ p.y = r.min.y + i * asklineheight;
+ p.y += 8;
+ string(img, p, display->black, ZP, font, asks[i].label);
+ p.y += font->height + 2;
+ border(img, rectaddpt(box, p), 1, display->black, ZP);
+ p.y += 2;
+ p.x += 3;
+ string(img, p, display->black, ZP, font, asks[i].value);
+ p.x -= 3;
+ }
+
+ replclipr(img, 0, img->r);
+}
+
+static int
+handleclick(Ask *asks, Rectangle r, Mouse m)
+{
+ int i;
+ int y;
+ Mouse fm;
+
+ y = m.xy.y - r.min.y;
+ i = y / asklineheight;
+
+ if (i >= numberasks)
+ return 0;
+
+ fm.xy = r.min;
+ fm.xy.y += i * asklineheight;
+
+ return eenter(asks[i].label, asks[i].value, asks[i].nval, &m);
+}
+
+static int
+handlekeys(int kbdc)
+{
+ /* return values: 1: quit abort, 2: quit success, 0: NOP */
+ switch (kbdc) {
+ case 'q':
+ case Kdel:
+ case Kesc:
+ return 1;
+ case '\n':
+ return 2;
+ }
+ return 0;
+}
+
+int
+ask(Ask *asks, Mouse m)
+{
+ Image *img, *blit;
+ Rectangle r;
+ int height;
+ int e;
+ Event ev;
+ Point nbl;
+ Ask *a;
+ int ret;
+
+ asklineheight = 2*font->height + 15;
+
+ numberasks = 0;
+ for (a = asks; a->label; a++)
+ numberasks++;
+
+ height = numberasks * asklineheight + 5;
+ r.min = m.xy;
+ r.max = r.min;
+ r.max.x += width;
+ r.max.y += height;
+
+ if (screen->r.max.x <= r.max.x) {
+ r.max.x = screen->r.max.x;
+ r.min.x = r.max.x - width;
+ }
+ if (screen->r.max.y <= r.max.y) {
+ r.max.y = screen->r.max.y;
+ r.min.y = r.max.y - height;
+ }
+
+ nbl = r.min;
+
+ blit = allocimage(display, r, screen->chan, 0, DNofill);
+ draw(blit, blit->r, screen, nil, nbl);
+
+ for (;;) {
+ dodraw(screen, r, asks);
+Nodraw:
+ switch (event(&ev)) {
+ case Ekeyboard:
+ if (ret = handlekeys(ev.kbdc))
+ goto Out;
+ goto Nodraw;
+ case Emouse:
+ if (ev.mouse.buttons) {
+ if (handleclick(asks, r, ev.mouse))
+ break;
+ }
+ goto Nodraw;
+ }
+ }
+Out:
+ draw(screen, blit->r, blit, nil, nbl);
+ freeimage(blit);
+
+ return --ret;
+}
--- a/blie.h
+++ b/blie.h
@@ -18,6 +18,15 @@
/* could be extracted to libdraw */
int eentercolor(char*, ulong*, Mouse*);
+/* could be extracted to separate library */
+typedef struct Ask Ask;
+struct Ask {
+ char *label;
+ char *value;
+ int nval;
+};
+int ask(Ask*, Mouse);
+
struct Layer {
char *name;
char *label;
--- a/mkfile
+++ b/mkfile
@@ -10,6 +10,7 @@
eentercolor.$O\
db.$O\
util.$O\
+ ask.$O\
p9image.$O\
efilter.$O\
--- a/test/mkfile
+++ b/test/mkfile
@@ -2,7 +2,10 @@
TEST=\
tdb\
+ task\
</sys/src/cmd/mktest
6.tdb: tdb.6 ../db.6
+
+6.task: task.6 ../ask.6
--- /dev/null
+++ b/test/task.c
@@ -1,0 +1,62 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <memdraw.h>
+#include <event.h>
+#include "../blie.h"
+
+void
+eresized(int)
+{
+ draw(screen, screen->r, display->white, nil, ZP);
+}
+
+void
+main(int, char**)
+{
+ Event ev;
+ Ask asks[3];
+ char answer1[11];
+ char answer2[11];
+
+ asks[0].label = "question A";
+ asks[0].value = answer1;
+ asks[0].nval = 10;
+ asks[1].label = "question B";
+ asks[1].value = answer2;
+ asks[1].nval = 10;
+ asks[2].label = nil;
+ asks[2].value = nil;
+
+ snprint(answer1, sizeof answer1, "answer");
+ snprint(answer2, sizeof answer2, "%f", 50.54);
+
+ if (!initdraw(nil, nil, "asktest"))
+ sysfatal("%r");
+
+ eresized(0);
+ einit(Emouse|Ekeyboard);
+
+ for (;;) {
+ switch (event(&ev)) {
+ case Emouse:
+ if (ev.mouse.buttons & 1) {
+ if (!ask(asks, ev.mouse)) {
+ fprint(2, " abort:\n");
+ fprint(2, "0: %s: %s\n", asks[0].label, asks[0].value);
+ fprint(2, "1: %s: %s\n", asks[1].label, asks[1].value);
+ break;
+ }
+ fprint(2, " accept:\n");
+ fprint(2, "0: %s: %s\n", asks[0].label, asks[0].value);
+ fprint(2, "1: %s: %s\n", asks[1].label, asks[1].value);
+ }
+ break;
+ case Ekeyboard:
+ if (ev.kbdc == 'q')
+ exits(nil);
+ break;
+ }
+ }
+ exits(nil);
+}