mothra: text selection 2nd attempt

This commit is contained in:
cinap_lenrek 2012-09-22 19:54:33 +02:00
parent f34ef5a8d4
commit bd998b2a78
6 changed files with 80 additions and 137 deletions

View file

@ -395,7 +395,7 @@ void mkfieldpanel(Rtext *t){
free(t->text);
t->text=0;
t->p=f->p;
t->hot=1;
t->flags|=PL_HOT;
}
}
void h_checkinput(Panel *p, int, int v){

View file

@ -9,7 +9,7 @@ struct Scroll{
Point pos, size;
};
struct Rtext{
int hot; /* responds to hits? */
int flags; /* responds to hits? text selection? */
void *user; /* user data */
int space; /* how much space before, if no break */
int indent; /* how much space before, after a break */
@ -96,6 +96,11 @@ struct Panel{
#define PRI_NORMAL 0 /* ordinary panels */
#define PRI_POPUP 1 /* popup menus */
#define PRI_SCROLLBAR 2 /* scroll bars */
/* Rtext.flags */
#define PL_HOT 1
#define PL_SEL 2
int plinit(int); /* initialization */
void plpack(Panel *, Rectangle); /* figure out where to put the Panel & children */
void plmove(Panel *, Point); /* move an already-packed panel to a new location */
@ -164,6 +169,9 @@ Rtext *plrtstr(Rtext **, int, int, Font *, char *, int, void *);
Rtext *plrtbitmap(Rtext **, int, int, Image *, int, void *);
Rtext *plrtpanel(Rtext **, int, int, Panel *, void *);
void plrtfree(Rtext *);
void plrtseltext(Rtext *, Rtext *, Rtext *);
char *plrtsnarftext(Rtext *);
int plgetpostextview(Panel *);
void plsetpostextview(Panel *, int);
char *plsnarftext(Panel *);

View file

@ -13,10 +13,10 @@
#define LEAD 4 /* extra space between lines */
#define BORD 2 /* extra border for images */
Rtext *pl_rtnew(Rtext **t, int space, int indent, Image *b, Panel *p, Font *f, char *s, int hot, void *user){
Rtext *pl_rtnew(Rtext **t, int space, int indent, Image *b, Panel *p, Font *f, char *s, int flags, void *user){
Rtext *new;
new=pl_emalloc(sizeof(Rtext));
new->hot=hot;
new->flags=flags;
new->user=user;
new->space=space;
new->indent=indent;
@ -37,11 +37,11 @@ Rtext *pl_rtnew(Rtext **t, int space, int indent, Image *b, Panel *p, Font *f, c
Rtext *plrtpanel(Rtext **t, int space, int indent, Panel *p, void *user){
return pl_rtnew(t, space, indent, 0, p, 0, 0, 1, user);
}
Rtext *plrtstr(Rtext **t, int space, int indent, Font *f, char *s, int hot, void *user){
return pl_rtnew(t, space, indent, 0, 0, f, s, hot, user);
Rtext *plrtstr(Rtext **t, int space, int indent, Font *f, char *s, int flags, void *user){
return pl_rtnew(t, space, indent, 0, 0, f, s, flags, user);
}
Rtext *plrtbitmap(Rtext **t, int space, int indent, Image *b, int hot, void *user){
return pl_rtnew(t, space, indent, b, 0, 0, 0, hot, user);
Rtext *plrtbitmap(Rtext **t, int space, int indent, Image *b, int flags, void *user){
return pl_rtnew(t, space, indent, b, 0, 0, 0, flags, user);
}
void plrtfree(Rtext *t){
Rtext *next;
@ -171,7 +171,7 @@ void pl_rtdraw(Image *b, Rectangle r, Rtext *t, int yoffs){
&& dr.min.y<r.max.y){
if(t->b){
draw(b, insetrect(dr, BORD), t->b, 0, t->b->r.min);
if(t->hot) border(b, dr, 1, display->black, ZP);
if(t->flags&PL_HOT) border(b, dr, 1, display->black, ZP);
}
else if(t->p){
plmove(t->p, subpt(dr.min, t->p->r.min));
@ -179,17 +179,20 @@ void pl_rtdraw(Image *b, Rectangle r, Rtext *t, int yoffs){
}
else{
string(b, dr.min, display->black, ZP, t->font, t->text);
if(t->hot){
if(t->flags&PL_HOT){
if(lp.y+1 != dr.max.y)
lp = Pt(dr.min.x, dr.max.y-1);
line(b, lp, Pt(dr.max.x, dr.max.y-1),
Endsquare, Endsquare, 0,
display->black, ZP);
lp = Pt(dr.max.x, dr.max.y-1);
continue;
goto Cont;
}
}
lp=ZP;
Cont:
if(t->flags&PL_SEL)
pl_highlight(b, dr);
}
}
replclipr(b, b->repl, cr);
@ -240,7 +243,7 @@ Rtext *pl_rthit(Rtext *t, int yoffs, Point p, Point ul){
for(;t!=0;t=t->next){
if(t->topy>p.y) return 0;
r = t->r;
if(t->hot && t->b == nil && t->p == nil){
if((t->flags&PL_HOT) != 0 && t->b == nil && t->p == nil){
if(lp.y == r.max.y && lp.x < r.min.x)
r.min.x=lp.x;
lp=r.max;
@ -250,3 +253,47 @@ Rtext *pl_rthit(Rtext *t, int yoffs, Point p, Point ul){
}
return 0;
}
void plrtseltext(Rtext *t, Rtext *s, Rtext *e){
while(t){
t->flags &= ~PL_SEL;
t = t->next;
}
if(s==0 || e==0)
return;
for(t=s; t!=0 && t!=e; t=t->next)
;
if(t==e){
for(t=s; t!=e; t=t->next)
t->flags |= PL_SEL;
}else{
for(t=e; t!=s; t=t->next)
t->flags |= PL_SEL;
}
t->flags |= PL_SEL;
}
char *plrtsnarftext(Rtext *w){
char *b, *p, *e;
int n;
p = e = 0;
for(; w; w = w->next){
if((w->flags&PL_SEL)==0 || w->b!=0 || w->p!=0 || w->text==0)
continue;
n = strlen(w->text)+4;
if((b = realloc(p, (e+n) - p)) == nil)
break;
e = (e - p) + b;
p = b;
if(w->space == 0)
e += sprint(e, "%s", w->text);
else if(w->space > 0)
e += sprint(e, " %s", w->text);
else if(PL_OP(w->space) == PL_TAB)
e += sprint(e, "\t%s", w->text);
if(w->nextline == w->next)
e += sprint(e, "\n");
}
return p;
}

View file

@ -10,7 +10,6 @@
#include <event.h>
#include <panel.h>
#include "pldefs.h"
#include "rtext.h"
typedef struct Textview Textview;
struct Textview{
@ -19,82 +18,12 @@ struct Textview{
int yoffs; /* offset of top of screen */
Rtext *hitword; /* text to hilite */
Rtext *hitfirst; /* first word in range select */
Image *hitsave; /* for restoring hilit text */
int twid; /* text width */
int thgt; /* text height */
Point minsize; /* smallest acceptible window size */
int buttons;
char *snarf;
char *esnarf;
};
/*
* Highlight a range of words from s to e.
*/
void pl_hilitewords(Panel *p, Rtext *s, Rtext *e, int on)
{
Point ul, size;
Rectangle r;
Textview *tp;
Rtext *t;
if(s==0 || e==0)
return;
for(t=s; t!=0 && t!=e; t=t->next)
;
if(t==e){
r=s->r;
for(t=s; t!=e; t=t->next)
combinerect(&r, t->r);
}else{
r=e->r;
for(t=e; t!=s; t=t->next)
combinerect(&r, t->r);
}
combinerect(&r, t->r);
tp=p->data;
ul=p->r.min;
size=subpt(p->r.max, p->r.min);
pl_interior(UP, &ul, &size);
ul.y-=tp->yoffs;
r=rectaddpt(r, ul);
if(rectclip(&r, p->r)==0)
return;
if(on){
if(tp->hitsave) freeimage(tp->hitsave);
tp->hitsave = allocimage(display, r, screen->chan, 0, DNofill);
if(tp->hitsave) draw(tp->hitsave, r, p->b, 0, r.min);
if(t==e){
for(t=s; t!=e; t=t->next){
if(t->p!=0) continue;
r=rectaddpt(t->r, ul);
if(rectclip(&r, p->r))
pl_highlight(p->b, r);
}
}else{
for(t=e; t!=s; t=t->next){
if(t->p!=0) continue;
r=rectaddpt(t->r, ul);
if(rectclip(&r, p->r))
pl_highlight(p->b, r);
}
}
if(t->p==0){
r=rectaddpt(t->r, ul);
if(rectclip(&r, p->r))
pl_highlight(p->b, r);
}
} else {
if(tp->hitsave){
draw(p->b, r, tp->hitsave, 0, r.min);
freeimage(tp->hitsave);
tp->hitsave = 0;
}
}
}
void pl_stuffbitmap(Panel *p, Image *b){
p->b=b;
for(p=p->child;p;p=p->next)
@ -116,7 +45,6 @@ void pl_drawnon(Rtext *rp, Image *b){
void pl_fixtextview(Panel *p, Textview *tp, Rectangle r){
Panel *sb;
int lo, hi;
pl_hilitewords(p, tp->hitword, tp->hitfirst, 1);
lo=tp->yoffs;
hi=lo+r.max.y-r.min.y; /* wrong? */
sb=p->yscroller;
@ -130,7 +58,7 @@ void pl_drawtextview(Panel *p){
tp=p->data;
b=allocimage(display, p->r, screen->chan, 0, DNofill);
if(b==0) b=p->b;
r=pl_outline(b, p->r, p->state);
r=pl_outline(b, p->r, UP);
twid=r.max.x-r.min.x;
if(twid!=tp->twid){
tp->twid=twid;
@ -169,9 +97,8 @@ int pl_hittextview(Panel *p, Mouse *m){
if(m->buttons&OUT)
p->state=UP;
else if(m->buttons&7){
tp->buttons=m->buttons;
p->state=DOWN;
tp->buttons=m->buttons;
ul=p->r.min;
size=subpt(p->r.max, p->r.min);
pl_interior(p->state, &ul, &size);
@ -189,13 +116,14 @@ int pl_hittextview(Panel *p, Mouse *m){
p->state=UP;
}
if(tp->hitfirst!=oldhitfirst || tp->hitword!=oldhitword){
pl_hilitewords(p, oldhitword, oldhitfirst, 0);
pl_hilitewords(p, tp->hitword, tp->hitfirst, 1);
plrtseltext(tp->text, tp->hitword, tp->hitfirst);
pl_drawtextview(p);
if(tp->hitword==tp->hitfirst)
pl_passon(tp->hitword, m);
}
if(hitme && tp->hit && tp->hitword!=0 && tp->hitword==tp->hitfirst){
pl_hilitewords(p, tp->hitword, tp->hitfirst, 0);
plrtseltext(tp->text, 0, 0);
pl_drawtextview(p);
tp->hit(p, tp->buttons, tp->hitword);
tp->hitword=0;
tp->hitfirst=0;
@ -230,7 +158,6 @@ void pl_scrolltextview(Panel *p, int dir, int buttons, int num, int den){
break;
}
if(yoffs!=tp->yoffs){
pl_hilitewords(p, tp->hitword, tp->hitfirst, 0);
r=pl_outline(p->b, p->r, p->state);
pl_rtredraw(p->b, r, tp->text, yoffs, tp->yoffs);
p->scr.pos.y=tp->yoffs=yoffs;
@ -283,7 +210,6 @@ void plinittextview(Panel *v, int flags, Point minsize, Rtext *t, void (*hit)(Pa
tp->yoffs=0;
tp->hitfirst=0;
tp->hitword=0;
tp->esnarf=tp->snarf=0;
v->scroll=pl_scrolltextview;
tp->twid=-1;
v->scr.pos=Pt(0,0);
@ -302,47 +228,9 @@ void plsetpostextview(Panel *p, int yoffs){
((Textview *)p->data)->yoffs=yoffs;
pldraw(p, p->b);
}
static void
snarfword(Textview *tp, Rtext *w){
char *b;
int n;
if(w->b!=0 || w->p!=0 || w->text==0)
return;
n = strlen(w->text)+4;
if((b = realloc(tp->snarf, (tp->esnarf+n) - tp->snarf)) == nil)
return;
tp->esnarf = (tp->esnarf - tp->snarf) + b;
tp->snarf = b;
if(w->space == 0)
tp->esnarf += sprint(tp->esnarf, "%s", w->text);
else if(w->space > 0)
tp->esnarf += sprint(tp->esnarf, " %s", w->text);
else if(PL_OP(w->space) == PL_TAB)
tp->esnarf += sprint(tp->esnarf, "\t%s", w->text);
if(w->nextline == w->next)
tp->esnarf += sprint(tp->esnarf, "\n");
}
char *plsnarftext(Panel *p){
Rtext *t, *s, *e;
Textview *tp;
tp=p->data;
free(tp->snarf);
tp->snarf=tp->esnarf=0;
s = tp->hitfirst;
e = tp->hitword;
if(s==0 || e==0)
return nil;
for(t=s; t!=0 && t!=e; t=t->next)
;
if(t==e){
for(t=s; t!=e; t=t->next)
snarfword(tp, t);
}else{
for(t=e; t!=s; t=t->next)
snarfword(tp, t);
}
snarfword(tp, t);
return tp->snarf;
char* plsnarftext(Panel *p){
static char *b = nil;
free(b);
b = plrtsnarftext(((Textview *)p->data)->text);
return b;
}

View file

@ -989,7 +989,7 @@ mothon(Www *w, int on)
t->next = nil;
ap=emalloc(sizeof(Action));
ap->link = strdup(a->link);
plrtstr(&t->next, 0, 0, t->font, strdup("->"), 1, ap);
plrtstr(&t->next, 0, 0, t->font, strdup("->"), PL_HOT, ap);
t->next->next = x;
} else {
t->next = x->next;

View file

@ -144,7 +144,7 @@ void pl_htmloutput(Hglob *g, int nsp, char *s, Field *field){
}
}
plrtstr(&g->dst->text, space, indent, f->font, strdup(s),
g->state->link[0] || g->state->image[0], ap);
(g->state->link[0] || g->state->image[0]) ? PL_HOT : 0, ap);
g->para=0;
g->linebrk=0;
g->dst->changed=1;