aboutsummaryrefslogtreecommitdiff
path: root/menulist.c
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2023-09-20 13:15:48 +0000
committerrodri <rgl@antares-labs.eu>2023-09-20 13:15:48 +0000
commit33de2d046acfc7ee42fb71b1804b091f671b098a (patch)
tree3c19b6a12cf861050701f004c5bad76877eac10e /menulist.c
parenta99916512365d68d130c7dfdb3f7ac5e2e0bbe8a (diff)
downloadbattleship-33de2d046acfc7ee42fb71b1804b091f671b098a.tar.gz
battleship-33de2d046acfc7ee42fb71b1804b091f671b098a.tar.bz2
battleship-33de2d046acfc7ee42fb71b1804b091f671b098a.zip
more work on the menulist of matches.
Diffstat (limited to 'menulist.c')
-rw-r--r--menulist.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/menulist.c b/menulist.c
new file mode 100644
index 0000000..8cd41a8
--- /dev/null
+++ b/menulist.c
@@ -0,0 +1,131 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <draw.h>
+#include <mouse.h>
+#include <cursor.h>
+#include <keyboard.h>
+#include <geometry.h>
+#include "dat.h"
+#include "fns.h"
+
+enum {
+ Menuborder = 2,
+ Vspace = 2,
+ Scrollwidth = 10,
+ Maxvisitems = 5,
+};
+static char none[] = "none";
+
+
+static void
+menulist_add(Menulist *ml, int id, char *title)
+{
+ Mentry e = {id, title};
+ int ew;
+
+ ml->entries = erealloc(ml->entries, ++ml->nentries * sizeof *ml->entries);
+ ml->entries[ml->nentries-1] = e;
+
+ if((ew = stringwidth(font, e.title)) > Dx(ml->r)){
+ ml->r.min.x = SCRW/2 - ew/2;
+ ml->r.max.x = ml->r.min.x + ew;
+ }
+ if(ml->nentries > 1)
+ ml->r.max.y += font->height+Vspace;
+}
+
+static void
+menulist_clear(Menulist *ml)
+{
+ int i, w;
+
+ if(ml->entries == nil)
+ return;
+
+ for(i = 0; i < ml->nentries; i++)
+ free(ml->entries[i].title);
+ free(ml->entries);
+ ml->entries = nil;
+ ml->nentries = 0;
+ ml->filling = 0;
+
+ w = max(stringwidth(font, ml->title), stringwidth(font, none));
+ ml->r.min.x = SCRW/2 - w/2;
+ ml->r.max = addpt(ml->r.min, Pt(w, font->height+Vspace));
+ ml->sr = ZR;
+ ml->high = -1;
+}
+
+static void
+menulist_update(Menulist *ml, Mousectl *mc)
+{
+ if(ptinrect(mc->xy, ml->r)){
+ /* item highlighting and selection */
+ }else if(ptinrect(mc->xy, ml->sr)){
+ /* scrolling */
+ }
+}
+
+static void
+menulist_draw(Menulist *ml, Image *dst)
+{
+ static Image *bc;
+ Rectangle tr, er; /* title and per-entry */
+ int i;
+
+ if(ml->filling)
+ return;
+
+ if(bc == nil)
+ bc = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
+
+ /* draw title */
+ tr.min = subpt(ml->r.min, Pt(0,Menuborder + font->height+Vspace));
+ tr.max = Pt(ml->r.max.x, ml->r.min.y - Menuborder);
+ draw(dst, tr, display->black, nil, ZP);
+ string(dst, tr.min, display->white, ZP, font, ml->title);
+
+ /* draw content */
+ border(dst, ml->r, -Menuborder, bc, ZP);
+ er.min = ml->r.min;
+ er.max = Pt(ml->r.max.x, er.min.y + font->height+Vspace);
+ for(i = 0; i < ml->nentries; i++){
+ draw(dst, er, display->white, nil, ZP);
+ string(dst, er.min, display->black, ZP, font, ml->entries[i].title);
+ er.min.y += font->height+Vspace;
+ er.max.y = er.min.y + font->height+Vspace;
+ }
+ if(i == 0){
+ draw(dst, er, display->white, nil, ZP);
+ string(dst, er.min, display->black, ZP, font, none);
+ }
+}
+
+Menulist *
+newmenulist(int topmargin, char *title)
+{
+ Menulist *ml;
+ int w;
+
+ ml = emalloc(sizeof *ml);
+ memset(ml, 0, sizeof *ml);
+ ml->title = estrdup(title);
+ w = max(stringwidth(font, title), stringwidth(font, none));
+ ml->r.min = Pt(SCRW/2 - w/2, topmargin);
+ ml->r.max = addpt(ml->r.min, Pt(w, font->height+Vspace));
+ ml->high = -1;
+ ml->add = menulist_add;
+ ml->clear = menulist_clear;
+ ml->update = menulist_update;
+ ml->draw = menulist_draw;
+ return ml;
+}
+
+void
+delmenulist(Menulist *ml)
+{
+ ml->clear(ml);
+ free(ml->title);
+ free(ml);
+}