ref: b355c72152380f66c87553ca51ef3d9020c5d40c
parent: d9121a953e12ee3c3699ddd533d69f57e2f3a74c
author: phil9 <telephil9@gmail.com>
date: Tue Dec 27 14:49:34 EST 2022
new input dialog
--- a/a.h
+++ b/a.h
@@ -6,6 +6,7 @@
#include <thread.h>
#include <plumb.h>
#include <bio.h>
+#include <ctype.h>
typedef struct Dirview Dirview;
typedef struct Dirpanel Dirpanel;
@@ -151,6 +152,7 @@
int message(int, const char*, Mousectl*, Keyboardctl*);
void errormessage(char*, Mousectl*, Keyboardctl*);
+int input(char*, char*, int, Mousectl*, Keyboardctl*);
int mkdir(char*, char*);
int rm(char*, Dir);
@@ -184,6 +186,7 @@
Ncols
};
extern Image* cols[Ncols];
+extern Image* tick;
extern Mousectl* mc;
extern Keyboardctl* kc;
extern int mode;
--- /dev/null
+++ b/input.c
@@ -1,0 +1,173 @@
+#include "a.h"
+
+enum{
+ Border = 1,
+ Padding = 8,
+};
+
+static
+int
+max(int a, int b)
+{
+ return a>b ? a : b;
+}
+
+static void
+button(Image *b, Rectangle br, char *label, int focus)
+{
+ Point p;
+ int dx;
+
+ dx = (Dx(br) - stringwidth(font, label)) / 2;
+ border(b, br, 2, focus ? cols[Ctitle] : cols[Csel], ZP);
+ p = addpt(br.min, Pt(dx, 0.25*font->height));
+ p = stringn(b, p, cols[Ctitle], ZP, font, label, 1);
+ string(b, p, cols[Cfg], ZP, font, label+1);
+}
+
+static void
+entry(Image *b, Rectangle r, char *text, int focus)
+{
+ Point p;
+
+ border(b, r, 2, focus ? cols[Ctitle] : cols[Csel], ZP);
+ p = addpt(r.min, Pt(Padding, Padding/2));
+ p = string(b, p, cols[Cfg], ZP, font, text);
+ if(focus)
+ draw(b, rectaddpt(tick->r, p), tick, nil, ZP);
+}
+
+int
+input(char *ask, char *buf, int nbuf, Mousectl *mctl, Keyboardctl *kctl)
+{
+ Alt alts[3];
+ Rectangle r, er, br, brn, sc;
+ Point o, p;
+ Image *b, *save, *bg, *fg, *hi;
+ int rc, done, len, h, w, ew, eh, bw, bh, mw, dy, focus;
+ Mouse m;
+ Rune k;
+
+ alts[0].op = CHANRCV;
+ alts[0].c = mctl->c;
+ alts[0].v = &m;
+ alts[1].op = CHANRCV;
+ alts[1].c = kctl->c;
+ alts[1].v = &k;
+ alts[2].op = CHANEND;
+ alts[2].c = nil;
+ alts[2].v = nil;
+ while(nbrecv(kctl->c, nil)==1)
+ ;
+ rc = -1;
+ len = strlen(buf);
+ bg = cols[Cdialog];
+ fg = cols[Cfg];
+ hi = cols[Ctitle];
+ focus = 0;
+ done = 0;
+ save = nil;
+ bw = 2*stringwidth(font, "Cancel");
+ bh = 1.5*font->height;
+ mw = stringwidth(font, ask);
+ w = Border+Padding+3*mw+Padding+Border;
+ ew = w - 2*(Border+Padding);
+ eh = Padding+font->height;
+ h = Border+Padding+2*font->height+Padding+eh+Padding+bh+Padding+Border;
+ b = screen;
+ sc = b->clipr;
+ replclipr(b, 0, b->r);
+ while(!done){
+ o = addpt(screen->r.min, Pt((Dx(screen->r)-w)/2, (Dy(screen->r)-h)/2));
+ r = Rect(o.x, o.y, o.x+w, o.y+h);
+ if(save==nil){
+ save = allocimage(display, r, b->chan, 0, DNofill);
+ if(save==nil)
+ break;
+ draw(save, r, b, nil, r.min);
+ }
+ draw(b, r, bg, nil, ZP);
+ border(b, r, Border, cols[Csel], ZP);
+ p = addpt(o, Pt(0, 2));
+ line(b, p, Pt(r.max.x, p.y), 0, 0, 2, hi, ZP);
+ p = addpt(o, Pt(Border+Padding, Border+Padding+0.5*font->height));
+ string(b, p, fg, ZP, font, ask);
+ p.y += Padding+1.5*font->height;
+ dy = Border+Padding+1.5*font->height+Padding;
+ er = rectaddpt(Rect(0, 0, ew, eh), addpt(o, Pt(Border+Padding, dy)));
+ entry(b, er, buf, focus == 0);
+ dy += eh+0.5*font->height+Padding;
+ br = rectaddpt(Rect(0, 0, bw, bh), addpt(o, Pt(Border+Padding, dy)));
+ button(b, br, "Ok", focus == 1);
+ brn = rectaddpt(br, Pt(bw+Padding, 0));
+ button(b, brn, "Cancel", focus == 2);
+ flushimage(display, 1);
+ if(b!=screen || !eqrect(screen->clipr, sc)){
+ freeimage(save);
+ save = nil;
+ }
+ b = screen;
+ sc = b->clipr;
+ replclipr(b, 0, b->r);
+ switch(alt(alts)){
+ default:
+ continue;
+ break;
+ case 1:
+ if(k == '\t'){
+ focus = (focus + 1) % 3;
+ }else if(focus != 0 && (k == 'o' || k == 'O')){
+ done = 1;
+ rc = len;
+ }else if(k == '\n'){
+ done = 1;
+ if(focus == 0 || focus == 1)
+ rc = len;
+ else
+ rc = -1;
+ }else if(focus != 0 && (k == 'c' || k == 'C')){
+ done = 1;
+ rc = -1;
+ }else if(k == Kesc){
+ done = 1;
+ rc = -1;
+ }else{
+ if(isprint(k)){
+ if(len >= nbuf){
+ done = 1;
+ rc = -1;
+ }else
+ buf[len++] = k;
+ }else if(k == Knack){
+ len = 0;
+ }else if(k == Kbs){
+ if(len > 0)
+ buf[--len] = '\0';
+ }
+ buf[len] = 0;
+ }
+ break;
+ case 0:
+ if(m.buttons&4){
+ if(ptinrect(m.xy, br)){
+ done = 1;
+ rc = len;
+ }else if(ptinrect(m.xy, brn)){
+ done = 1;
+ rc = -1;
+ }
+ }
+ break;
+ }
+ if(save){
+ draw(b, save->r, save, nil, save->r.min);
+ freeimage(save);
+ save = nil;
+ }
+
+ }
+ replclipr(b, 0, sc);
+ flushimage(display, 1);
+ return rc;
+}
+
--- a/main.c
+++ b/main.c
@@ -1,6 +1,7 @@
#include "a.h"
Image *cols[Ncols];
+Image *tick;
Mousectl *mc;
Keyboardctl *kc;
int mode;
@@ -23,6 +24,20 @@
}
void
+tickinit(void)
+{
+ enum { Tickw = 3 };
+
+ tick = allocimage(display, Rect(0, 0, Tickw, font->height), screen->chan, 0, DWhite);
+ if(tick == nil)
+ sysfatal("allocimage: %r");
+ draw(tick, tick->r, cols[Cbg], nil, ZP);
+ draw(tick, Rect(Tickw/2, 0, Tickw/2+1, font->height), cols[Cfg], nil, ZP);
+ draw(tick, Rect(0, 0, Tickw, Tickw), cols[Cfg], nil, ZP);
+ draw(tick, Rect(0, font->height-Tickw, Tickw, font->height), cols[Cfg], nil, ZP);
+}
+
+void
redraw(void)
{
draw(screen, screen->r, cols[Cbg], nil, ZP);
@@ -144,6 +159,7 @@
text = mktext();
abar = mkactionbar();
colsinit();
+ tickinit();
resize();
setmode(Mdir);
alts[Emouse].c = mc->c;
--- a/mkfile
+++ b/mkfile
@@ -14,6 +14,7 @@
viewercmd.$O \
text.$O \
message.$O \
+ input.$O \
glob.$O \
fops.$O \
utils.$O