mothra: text selection 2nd attempt
This commit is contained in:
parent
f34ef5a8d4
commit
bd998b2a78
|
@ -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){
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue