popup: refine the input panel
This commit is contained in:
132
popup_layout.c
132
popup_layout.c
@@ -1,6 +1,33 @@
|
||||
#include "dat.h"
|
||||
#include "fn.h"
|
||||
|
||||
enum {
|
||||
Asciitofull = 0xFEE0,
|
||||
};
|
||||
|
||||
static void
|
||||
fill(u32int *buf, int n, u32int color)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < n; i++)
|
||||
buf[i] = color;
|
||||
}
|
||||
|
||||
static void
|
||||
fillrect(u32int *buf, int w, int h, int x, int y, int rw, int rh,
|
||||
u32int color)
|
||||
{
|
||||
int x0, x1, y0, y1;
|
||||
|
||||
x0 = min(max(x, 0), w);
|
||||
x1 = min(max(x + max(rw, 0), 0), w);
|
||||
y0 = min(max(y, 0), h);
|
||||
y1 = min(max(y + max(rh, 0), 0), h);
|
||||
for(; y0 < y1; y0++)
|
||||
fill(buf + y0*w + x0, max(x1 - x0, 0), color);
|
||||
}
|
||||
|
||||
int
|
||||
pagemarker(char *buf, int nbuf, int first, int shown, int total)
|
||||
{
|
||||
@@ -13,6 +40,111 @@ pagemarker(char *buf, int nbuf, int first, int shown, int total)
|
||||
first + shown, total);
|
||||
}
|
||||
|
||||
void
|
||||
popuplayout(Drawcmd *dc, int screenw, Popup *p)
|
||||
{
|
||||
char buf[32];
|
||||
vlong width;
|
||||
Str mark;
|
||||
int i, maxw, nmark, npre, roww, y;
|
||||
|
||||
memset(p, 0, sizeof *p);
|
||||
p->prey = -1;
|
||||
p->sepy = -1;
|
||||
p->rowsy = -1;
|
||||
p->markx = -1;
|
||||
p->marky = -1;
|
||||
p->sely = -1;
|
||||
p->n = min(max(dc->nkouho, 0), Maxdisp);
|
||||
npre = dc->pre.n != 0;
|
||||
if(p->n == 0 && !npre)
|
||||
return;
|
||||
|
||||
maxw = npre ? textwidth(&dc->pre) : 0;
|
||||
roww = 0;
|
||||
for(i = 0; i < p->n; i++)
|
||||
roww = max(roww, textwidth(&dc->kouho[i]));
|
||||
if(p->n != 0)
|
||||
maxw = max(maxw, PopupNumw + roww);
|
||||
nmark = pagemarker(buf, sizeof buf, dc->first, p->n, dc->total);
|
||||
if(nmark != 0){
|
||||
sinit(&mark, buf, nmark);
|
||||
maxw = max(maxw, textwidth(&mark));
|
||||
}
|
||||
width = (vlong)maxw + 2*PopupPad;
|
||||
p->w = min(min(max(width, 1), Imgw), max(screenw, 0));
|
||||
|
||||
y = PopupPad;
|
||||
if(npre){
|
||||
p->prey = y;
|
||||
y += Fontsz;
|
||||
}
|
||||
if(npre && p->n != 0){
|
||||
p->sepy = y;
|
||||
y += PopupSep;
|
||||
}
|
||||
if(p->n != 0){
|
||||
p->rowsy = y;
|
||||
y += p->n*Fontsz;
|
||||
}
|
||||
if(nmark != 0){
|
||||
p->marky = y;
|
||||
y += Fontsz;
|
||||
}
|
||||
p->h = y + PopupPad;
|
||||
p->numx = PopupPad;
|
||||
p->textx = PopupPad + PopupNumw;
|
||||
p->textw = max(p->w - PopupPad - p->textx, 0);
|
||||
if(nmark != 0){
|
||||
p->markw = min(textwidth(&mark), max(p->w - 2*PopupPad, 0));
|
||||
p->markx = p->w - PopupPad - p->markw;
|
||||
}
|
||||
p->selx = PopupPad;
|
||||
p->selw = max(p->w - 2*PopupPad, 0);
|
||||
if(dc->sel >= 0 && dc->sel < p->n)
|
||||
p->sely = p->rowsy + dc->sel*Fontsz;
|
||||
}
|
||||
|
||||
void
|
||||
popupdraw(u32int *img, Drawcmd *dc, Popup *p)
|
||||
{
|
||||
char buf[32];
|
||||
Str mark, num;
|
||||
u32int color;
|
||||
int i, nmark, y;
|
||||
|
||||
if(img == nil || p->n < 0 || p->n > Maxdisp ||
|
||||
p->w <= 0 || p->w > Imgw ||
|
||||
p->h <= 0 || p->h > Imgh)
|
||||
return;
|
||||
fill(img, p->w*p->h, Colbg);
|
||||
if(p->prey >= 0)
|
||||
textdrawfit(img, p->w, p->h, PopupPad, p->prey,
|
||||
max(p->w - 2*PopupPad, 0), &dc->pre);
|
||||
if(p->sepy >= 0)
|
||||
fillrect(img, p->w, p->h, PopupPad, p->sepy,
|
||||
p->w - 2*PopupPad, PopupSep, Colsep);
|
||||
if(p->sely >= 0)
|
||||
fillrect(img, p->w, p->h, p->selx, p->sely,
|
||||
p->selw, Fontsz, Colsel);
|
||||
for(i = 0, y = p->rowsy; i < p->n; i++, y += Fontsz){
|
||||
color = i == dc->sel ? Colselfg : Colfg;
|
||||
sclear(&num);
|
||||
sputr(&num, '1' + i + Asciitofull);
|
||||
textdrawfitcolor(img, p->w, p->h, p->numx, y,
|
||||
min(PopupNumw,
|
||||
max(p->w - PopupPad - p->numx, 0)), color, &num);
|
||||
textdrawfitcolor(img, p->w, p->h, p->textx, y,
|
||||
p->textw, color, &dc->kouho[i]);
|
||||
}
|
||||
nmark = pagemarker(buf, sizeof buf, dc->first, p->n, dc->total);
|
||||
if(nmark != 0 && p->marky >= 0){
|
||||
sinit(&mark, buf, nmark);
|
||||
textdrawfit(img, p->w, p->h, p->markx, p->marky,
|
||||
p->markw, &mark);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
popupposition(Caret *caret, int pointerx, int pointery, int screenw,
|
||||
int screenh, int w, int h, int *x, int *y)
|
||||
|
||||
Reference in New Issue
Block a user