libdraw: added enter() and eenter() functions
This commit is contained in:
parent
01a7c491fc
commit
278d4f8477
7 changed files with 472 additions and 4 deletions
|
@ -64,3 +64,4 @@ extern Rectangle egetrect(int, Mouse*);
|
|||
extern void edrawgetrect(Rectangle, int);
|
||||
extern int ereadmouse(Mouse*);
|
||||
extern int eatomouse(Mouse*, char*, int);
|
||||
extern int eenter(char*, char*, int, Mouse*);
|
||||
|
|
|
@ -4,6 +4,7 @@ typedef struct Channel Channel;
|
|||
typedef struct Cursor Cursor;
|
||||
typedef struct Menu Menu;
|
||||
typedef struct Mousectl Mousectl;
|
||||
typedef struct Keyboardctl Keyboardctl;
|
||||
|
||||
struct Mouse
|
||||
{
|
||||
|
@ -44,3 +45,4 @@ extern void setcursor(Mousectl*, Cursor*);
|
|||
extern void drawgetrect(Rectangle, int);
|
||||
extern Rectangle getrect(int, Mousectl*);
|
||||
extern int menuhit(int, Mousectl*, Menu*, Screen*);
|
||||
extern int enter(char *, char *, int, Mousectl*, Keyboardctl*, Screen*);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.TH EVENT 2
|
||||
.SH NAME
|
||||
event, einit, estart, estartfn, etimer, eread, emouse, ekbd, ecanread, ecanmouse, ecankbd, ereadmouse, eatomouse, eresized, egetrect, edrawgetrect, emenuhit, emoveto, esetcursor, Event, Mouse, Menu \- graphics events
|
||||
event, einit, estart, estartfn, etimer, eread, emouse, ekbd, ecanread, ecanmouse, ecankbd, ereadmouse, eatomouse, eresized, egetrect, edrawgetrect, emenuhit, eenter, emoveto, esetcursor, Event, Mouse, Menu \- graphics events
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.PP
|
||||
|
@ -69,15 +69,16 @@ void edrawgetrect(Rectangle r, int up)
|
|||
.B
|
||||
int emenuhit(int but, Mouse *m, Menu *menu)
|
||||
.PP
|
||||
.PP
|
||||
.B
|
||||
int emoveto(Point p)
|
||||
.PP
|
||||
.PP
|
||||
.B
|
||||
int esetcursor(Cursor *c)
|
||||
.PP
|
||||
.B
|
||||
int eenter(char *ask, char *buf, int len, Mouse *m)
|
||||
.PP
|
||||
.B
|
||||
extern Mouse *mouse
|
||||
.PP
|
||||
.B
|
||||
|
@ -374,6 +375,35 @@ changes the cursor image to that described by the
|
|||
If
|
||||
.B c
|
||||
is nil, it restores the image to the default arrow.
|
||||
.PP
|
||||
.I Eenter
|
||||
provides a simple way of text input in graphical programs. It displays
|
||||
a box at the current position of the mouse cursor (passed in the
|
||||
.B Mouse *m
|
||||
argument) in wich text can be
|
||||
typed and edited.
|
||||
If the string argument
|
||||
.B ask
|
||||
is not
|
||||
.B nil,
|
||||
it is displayed as a static label before the input string.
|
||||
The
|
||||
.B buf
|
||||
parameter contains the null-terminated input string to be edited. The
|
||||
.B len
|
||||
argument specified the length of
|
||||
.B buf
|
||||
in bytes including the terminating null byte.
|
||||
If
|
||||
.B buf
|
||||
or
|
||||
.B len
|
||||
is zero, no text can be entered.
|
||||
On success,
|
||||
.I eenter
|
||||
returns the number of bytes in the edited string
|
||||
.B buf
|
||||
or -1 on error.
|
||||
.SH SOURCE
|
||||
.B /sys/src/libdraw
|
||||
.SH "SEE ALSO"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.TH MOUSE 2
|
||||
.SH NAME
|
||||
initmouse, readmouse, closemouse, moveto, getrect, drawgetrect, menuhit, setcursor \- mouse control
|
||||
initmouse, readmouse, closemouse, moveto, getrect, drawgetrect, menuhit, setcursor, enter \- mouse control
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.B
|
||||
|
@ -42,6 +42,11 @@ void drawgetrect(Rectangle r, int up)
|
|||
.PP
|
||||
.B
|
||||
int menuhit(int but, Mousectl *mc, Menu *menu, Screen *scr)
|
||||
.PP
|
||||
.B
|
||||
int enter(char *ask, char *buf, int len,
|
||||
.B
|
||||
Mousectl *mc, Keyboardctl *kc, Screen *scr)
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
These functions access and control a mouse in a multi-threaded environment.
|
||||
|
@ -239,6 +244,20 @@ behaves like
|
|||
creating backing store for the menu, writing the menu directly on the display, and
|
||||
restoring the display when the menu is removed.
|
||||
.PP
|
||||
.I Enter
|
||||
is a multithreded version of the
|
||||
.I eenter
|
||||
function described in
|
||||
.IR event(2).
|
||||
Like
|
||||
.I menuhit,
|
||||
it has a optional
|
||||
.B scr
|
||||
argument to create a window. Keyboard input is read from the channel in the
|
||||
.B Keyboardctl *kc
|
||||
argument (see
|
||||
.IR keyboard (2)).
|
||||
.PP
|
||||
.SH SOURCE
|
||||
.B /sys/src/libdraw
|
||||
.SH SEE ALSO
|
||||
|
|
195
sys/src/libdraw/eenter.c
Normal file
195
sys/src/libdraw/eenter.c
Normal file
|
@ -0,0 +1,195 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <event.h>
|
||||
#include <keyboard.h>
|
||||
|
||||
int
|
||||
eenter(char *ask, char *buf, int len, Mouse *m)
|
||||
{
|
||||
int done, down, tick, n, h, w, l, i;
|
||||
Image *b, *save, *backcol, *bordcol;
|
||||
Point p, o, t;
|
||||
Rectangle r;
|
||||
Event ev;
|
||||
Rune k;
|
||||
|
||||
o = screen->r.min;
|
||||
backcol = allocimagemix(display, DPurpleblue, DWhite);
|
||||
bordcol = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
|
||||
if(backcol == nil || bordcol == nil)
|
||||
return -1;
|
||||
|
||||
while(ecankbd())
|
||||
ekbd();
|
||||
|
||||
if(m) o = m->xy;
|
||||
|
||||
if(buf && len > 0)
|
||||
n = strlen(buf);
|
||||
else {
|
||||
buf = nil;
|
||||
len = 0;
|
||||
n = 0;
|
||||
}
|
||||
|
||||
k = -1;
|
||||
b = screen;
|
||||
tick = n;
|
||||
save = nil;
|
||||
done = down = 0;
|
||||
|
||||
p = stringsize(font, " ");
|
||||
h = p.y;
|
||||
w = p.x;
|
||||
|
||||
while(!done){
|
||||
p = stringsize(font, buf ? buf : "");
|
||||
if(ask && ask[0]){
|
||||
if(buf) p.x += w;
|
||||
p.x += stringwidth(font, ask);
|
||||
}
|
||||
r = rectaddpt(insetrect(Rpt(ZP, p), -4), o);
|
||||
p.x = 0;
|
||||
r = rectsubpt(r, p);
|
||||
|
||||
p = ZP;
|
||||
if(r.min.x < screen->r.min.x)
|
||||
p.x = screen->r.min.x - r.min.x;
|
||||
if(r.min.y < screen->r.min.y)
|
||||
p.y = screen->r.min.y - r.min.y;
|
||||
r = rectaddpt(r, p);
|
||||
p = ZP;
|
||||
if(r.max.x > screen->r.max.x)
|
||||
p.x = r.max.x - screen->r.max.x;
|
||||
if(r.max.y > screen->r.max.y)
|
||||
p.y = r.max.y - screen->r.max.y;
|
||||
r = rectsubpt(r, p);
|
||||
|
||||
r = insetrect(r, -2);
|
||||
if(save == nil){
|
||||
save = allocimage(display, r, b->chan, 0, DNofill);
|
||||
if(save == nil){
|
||||
n = -1;
|
||||
break;
|
||||
}
|
||||
draw(save, r, b, nil, r.min);
|
||||
}
|
||||
draw(b, r, backcol, nil, ZP);
|
||||
border(b, r, 2, bordcol, ZP);
|
||||
p = addpt(r.min, Pt(6, 6));
|
||||
if(ask && ask[0]){
|
||||
p = string(b, p, bordcol, ZP, font, ask);
|
||||
if(buf) p.x += w;
|
||||
}
|
||||
if(buf){
|
||||
t = p;
|
||||
p = stringn(b, p, display->black, ZP, font, buf, utfnlen(buf, tick));
|
||||
draw(b, Rect(p.x-1, p.y, p.x+2, p.y+3), display->black, nil, ZP);
|
||||
draw(b, Rect(p.x, p.y, p.x+1, p.y+h), display->black, nil, ZP);
|
||||
draw(b, Rect(p.x-1, p.y+h-3, p.x+2, p.y+h), display->black, nil, ZP);
|
||||
p = string(b, p, display->black, ZP, font, buf+tick);
|
||||
}
|
||||
flushimage(display, 1);
|
||||
|
||||
i = Ekeyboard;
|
||||
if(m != nil)
|
||||
i |= Emouse;
|
||||
switch(eread(i, &ev)){
|
||||
default:
|
||||
done = 1;
|
||||
n = -1;
|
||||
break;
|
||||
case Ekeyboard:
|
||||
k = ev.kbdc;
|
||||
if(buf == nil || k == Keof || k == '\n'){
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
if(k == Knack || k == Kesc){
|
||||
done = !n;
|
||||
buf[n = tick = 0] = 0;
|
||||
break;
|
||||
}
|
||||
if(k == Ksoh || k == Khome){
|
||||
tick = 0;
|
||||
continue;
|
||||
}
|
||||
if(k == Kenq || k == Kend){
|
||||
tick = n;
|
||||
continue;
|
||||
}
|
||||
if(k == Kright){
|
||||
if(tick < n)
|
||||
tick += chartorune(&k, buf+tick);
|
||||
continue;
|
||||
}
|
||||
if(k == Kleft){
|
||||
for(i = 0; i < n; i += l){
|
||||
l = chartorune(&k, buf+tick);
|
||||
if(i+l >= tick){
|
||||
tick = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(k == Kbs){
|
||||
if(tick <= 0)
|
||||
continue;
|
||||
for(i = 0; i < n; i += l){
|
||||
l = chartorune(&k, buf+i);
|
||||
if(i+l >= tick){
|
||||
memmove(buf+i, buf+i+l, n - (i+l));
|
||||
buf[n -= l] = 0;
|
||||
tick -= l;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(k < 0x20 || k == Kdel || (k & 0xFF00) == KF || (k & 0xFF00) == Spec)
|
||||
continue;
|
||||
if((len-n) <= (l = runelen(k)))
|
||||
continue;
|
||||
memmove(buf+tick+l, buf+tick, n - tick);
|
||||
runetochar(buf+tick, &k);
|
||||
buf[n += l] = 0;
|
||||
tick += l;
|
||||
break;
|
||||
case Emouse:
|
||||
*m = ev.mouse;
|
||||
if(!ptinrect(m->xy, r)){
|
||||
down = 0;
|
||||
continue;
|
||||
}
|
||||
if(m->buttons & 7){
|
||||
down = 1;
|
||||
if(buf && m->xy.x >= (t.x - w)){
|
||||
down = 0;
|
||||
for(i = 0; i < n; i += l){
|
||||
l = chartorune(&k, buf+i);
|
||||
t.x += stringnwidth(font, buf+i, 1);
|
||||
if(t.x > m->xy.x)
|
||||
break;
|
||||
}
|
||||
tick = i;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
done = down;
|
||||
break;
|
||||
}
|
||||
|
||||
draw(b, save->r, save, nil, save->r.min);
|
||||
freeimage(save);
|
||||
save = nil;
|
||||
}
|
||||
|
||||
freeimage(backcol);
|
||||
freeimage(bordcol);
|
||||
flushimage(display, 1);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
219
sys/src/libdraw/enter.c
Normal file
219
sys/src/libdraw/enter.c
Normal file
|
@ -0,0 +1,219 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <thread.h>
|
||||
#include <mouse.h>
|
||||
#include <keyboard.h>
|
||||
|
||||
int
|
||||
enter(char *ask, char *buf, int len, Mousectl *mc, Keyboardctl *kc, Screen *scr)
|
||||
{
|
||||
int done, down, tick, n, h, w, l, i;
|
||||
Image *b, *save, *backcol, *bordcol;
|
||||
Point p, o, t;
|
||||
Rectangle r;
|
||||
Alt a[3];
|
||||
Mouse m;
|
||||
Rune k;
|
||||
|
||||
o = screen->r.min;
|
||||
backcol = allocimagemix(display, DPurpleblue, DWhite);
|
||||
bordcol = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
|
||||
if(backcol == nil || bordcol == nil)
|
||||
return -1;
|
||||
|
||||
n = 0;
|
||||
if(kc){
|
||||
while(nbrecv(kc->c, nil) == 1)
|
||||
;
|
||||
a[n].op = CHANRCV;
|
||||
a[n].c = kc->c;
|
||||
a[n].v = &k;
|
||||
n++;
|
||||
}
|
||||
if(mc){
|
||||
o = mc->xy;
|
||||
a[n].op = CHANRCV;
|
||||
a[n].c = mc->c;
|
||||
a[n].v = &m;
|
||||
n++;
|
||||
}
|
||||
a[n].op = CHANEND;
|
||||
a[n].c = nil;
|
||||
a[n].v = nil;
|
||||
|
||||
if(buf && len > 0)
|
||||
n = strlen(buf);
|
||||
else {
|
||||
buf = nil;
|
||||
len = 0;
|
||||
n = 0;
|
||||
}
|
||||
|
||||
k = -1;
|
||||
b = nil;
|
||||
tick = n;
|
||||
save = nil;
|
||||
done = down = 0;
|
||||
|
||||
p = stringsize(font, " ");
|
||||
h = p.y;
|
||||
w = p.x;
|
||||
|
||||
while(!done){
|
||||
p = stringsize(font, buf ? buf : "");
|
||||
if(ask && ask[0]){
|
||||
if(buf) p.x += w;
|
||||
p.x += stringwidth(font, ask);
|
||||
}
|
||||
r = rectaddpt(insetrect(Rpt(ZP, p), -4), o);
|
||||
p.x = 0;
|
||||
r = rectsubpt(r, p);
|
||||
|
||||
p = ZP;
|
||||
if(r.min.x < screen->r.min.x)
|
||||
p.x = screen->r.min.x - r.min.x;
|
||||
if(r.min.y < screen->r.min.y)
|
||||
p.y = screen->r.min.y - r.min.y;
|
||||
r = rectaddpt(r, p);
|
||||
p = ZP;
|
||||
if(r.max.x > screen->r.max.x)
|
||||
p.x = r.max.x - screen->r.max.x;
|
||||
if(r.max.y > screen->r.max.y)
|
||||
p.y = r.max.y - screen->r.max.y;
|
||||
r = rectsubpt(r, p);
|
||||
|
||||
r = insetrect(r, -2);
|
||||
if(scr){
|
||||
if(b == nil)
|
||||
b = allocwindow(scr, r, Refbackup, DWhite);
|
||||
if(b == nil)
|
||||
scr = nil;
|
||||
}
|
||||
if(scr == nil && save == nil){
|
||||
if(b == nil)
|
||||
b = screen;
|
||||
save = allocimage(display, r, b->chan, 0, DNofill);
|
||||
if(save == nil){
|
||||
n = -1;
|
||||
break;
|
||||
}
|
||||
draw(save, r, b, nil, r.min);
|
||||
}
|
||||
draw(b, r, backcol, nil, ZP);
|
||||
border(b, r, 2, bordcol, ZP);
|
||||
p = addpt(r.min, Pt(6, 6));
|
||||
if(ask && ask[0]){
|
||||
p = string(b, p, bordcol, ZP, font, ask);
|
||||
if(buf) p.x += w;
|
||||
}
|
||||
if(buf){
|
||||
t = p;
|
||||
p = stringn(b, p, display->black, ZP, font, buf, utfnlen(buf, tick));
|
||||
draw(b, Rect(p.x-1, p.y, p.x+2, p.y+3), display->black, nil, ZP);
|
||||
draw(b, Rect(p.x, p.y, p.x+1, p.y+h), display->black, nil, ZP);
|
||||
draw(b, Rect(p.x-1, p.y+h-3, p.x+2, p.y+h), display->black, nil, ZP);
|
||||
p = string(b, p, display->black, ZP, font, buf+tick);
|
||||
}
|
||||
flushimage(display, 1);
|
||||
|
||||
switch(alt(a)){
|
||||
case -1:
|
||||
done = 1;
|
||||
n = -1;
|
||||
break;
|
||||
case 0:
|
||||
if(buf == nil || k == Keof || k == '\n'){
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
if(k == Knack || k == Kesc){
|
||||
done = !n;
|
||||
buf[n = tick = 0] = 0;
|
||||
break;
|
||||
}
|
||||
if(k == Ksoh || k == Khome){
|
||||
tick = 0;
|
||||
continue;
|
||||
}
|
||||
if(k == Kenq || k == Kend){
|
||||
tick = n;
|
||||
continue;
|
||||
}
|
||||
if(k == Kright){
|
||||
if(tick < n)
|
||||
tick += chartorune(&k, buf+tick);
|
||||
continue;
|
||||
}
|
||||
if(k == Kleft){
|
||||
for(i = 0; i < n; i += l){
|
||||
l = chartorune(&k, buf+tick);
|
||||
if(i+l >= tick){
|
||||
tick = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(k == Kbs){
|
||||
if(tick <= 0)
|
||||
continue;
|
||||
for(i = 0; i < n; i += l){
|
||||
l = chartorune(&k, buf+i);
|
||||
if(i+l >= tick){
|
||||
memmove(buf+i, buf+i+l, n - (i+l));
|
||||
buf[n -= l] = 0;
|
||||
tick -= l;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(k < 0x20 || k == Kdel || (k & 0xFF00) == KF || (k & 0xFF00) == Spec)
|
||||
continue;
|
||||
if((len-n) <= (l = runelen(k)))
|
||||
continue;
|
||||
memmove(buf+tick+l, buf+tick, n - tick);
|
||||
runetochar(buf+tick, &k);
|
||||
buf[n += l] = 0;
|
||||
tick += l;
|
||||
break;
|
||||
case 1:
|
||||
if(!ptinrect(m.xy, r)){
|
||||
down = 0;
|
||||
continue;
|
||||
}
|
||||
if(m.buttons & 7){
|
||||
down = 1;
|
||||
if(buf && m.xy.x >= (t.x - w)){
|
||||
down = 0;
|
||||
for(i = 0; i < n; i += l){
|
||||
l = chartorune(&k, buf+i);
|
||||
t.x += stringnwidth(font, buf+i, 1);
|
||||
if(t.x > m.xy.x)
|
||||
break;
|
||||
}
|
||||
tick = i;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
done = down;
|
||||
break;
|
||||
}
|
||||
|
||||
if(b != screen) {
|
||||
freeimage(b);
|
||||
b = nil;
|
||||
} else {
|
||||
draw(b, save->r, save, nil, save->r.min);
|
||||
freeimage(save);
|
||||
save = nil;
|
||||
}
|
||||
}
|
||||
|
||||
freeimage(backcol);
|
||||
freeimage(bordcol);
|
||||
flushimage(display, 1);
|
||||
|
||||
return n;
|
||||
}
|
|
@ -18,9 +18,11 @@ OFILES=\
|
|||
defont.$O\
|
||||
draw.$O\
|
||||
drawrepl.$O\
|
||||
eenter.$O\
|
||||
egetrect.$O\
|
||||
ellipse.$O\
|
||||
emenuhit.$O\
|
||||
enter.$O\
|
||||
event.$O\
|
||||
fmt.$O\
|
||||
font.$O\
|
||||
|
|
Loading…
Reference in a new issue