mothra: first attempt on text selection
This commit is contained in:
parent
9a06f93b71
commit
f34ef5a8d4
|
@ -17,21 +17,11 @@ static int plldepth;
|
||||||
static Image *pl_white, *pl_light, *pl_dark, *pl_black, *pl_hilit;
|
static Image *pl_white, *pl_light, *pl_dark, *pl_black, *pl_hilit;
|
||||||
int pl_drawinit(int ldepth){
|
int pl_drawinit(int ldepth){
|
||||||
plldepth=ldepth;
|
plldepth=ldepth;
|
||||||
/*
|
|
||||||
pl_white=allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xFFFFFFFF);
|
|
||||||
pl_light=allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xAAAAAAFF);
|
|
||||||
pl_dark =allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x555555FF);
|
|
||||||
pl_black=allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x000000FF);
|
|
||||||
pl_hilit=allocimage(display, Rect(0,0,1,1), CHAN1(CAlpha,8), 1, 0x80);
|
|
||||||
*/
|
|
||||||
|
|
||||||
pl_white=allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xFFFFFFFF);
|
pl_white=allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xFFFFFFFF);
|
||||||
pl_light=allocimagemix(display, DPalebluegreen, DWhite);
|
pl_light=allocimagemix(display, DPalebluegreen, DWhite);
|
||||||
pl_dark =allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
|
pl_dark =allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
|
||||||
pl_black=allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x000000FF);
|
pl_black=allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x000000FF);
|
||||||
pl_hilit=allocimage(display, Rect(0,0,1,1), CHAN1(CAlpha,8), 1, 0x80);
|
pl_hilit=allocimage(display, Rect(0,0,1,1), CHAN1(CAlpha,8), 1, 0x80);
|
||||||
|
|
||||||
|
|
||||||
if(pl_white==0 || pl_light==0 || pl_black==0 || pl_dark==0) return 0;
|
if(pl_white==0 || pl_light==0 || pl_black==0 || pl_dark==0) return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,6 +166,8 @@ Rtext *plrtpanel(Rtext **, int, int, Panel *, void *);
|
||||||
void plrtfree(Rtext *);
|
void plrtfree(Rtext *);
|
||||||
int plgetpostextview(Panel *);
|
int plgetpostextview(Panel *);
|
||||||
void plsetpostextview(Panel *, int);
|
void plsetpostextview(Panel *, int);
|
||||||
|
char *plsnarftext(Panel *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Idols
|
* Idols
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -10,44 +10,91 @@
|
||||||
#include <event.h>
|
#include <event.h>
|
||||||
#include <panel.h>
|
#include <panel.h>
|
||||||
#include "pldefs.h"
|
#include "pldefs.h"
|
||||||
|
#include "rtext.h"
|
||||||
|
|
||||||
typedef struct Textview Textview;
|
typedef struct Textview Textview;
|
||||||
struct Textview{
|
struct Textview{
|
||||||
void (*hit)(Panel *, int, Rtext *); /* call back to user on hit */
|
void (*hit)(Panel *, int, Rtext *); /* call back to user on hit */
|
||||||
Rtext *text; /* text */
|
Rtext *text; /* text */
|
||||||
int yoffs; /* offset of top of screen */
|
int yoffs; /* offset of top of screen */
|
||||||
Rtext *hitword; /* text to hilite */
|
Rtext *hitword; /* text to hilite */
|
||||||
Image *hitsave; /* for restoring hilit text */
|
Rtext *hitfirst; /* first word in range select */
|
||||||
|
Image *hitsave; /* for restoring hilit text */
|
||||||
int twid; /* text width */
|
int twid; /* text width */
|
||||||
int thgt; /* text height */
|
int thgt; /* text height */
|
||||||
Point minsize; /* smallest acceptible window size */
|
Point minsize; /* smallest acceptible window size */
|
||||||
int buttons;
|
int buttons;
|
||||||
|
char *snarf;
|
||||||
|
char *esnarf;
|
||||||
};
|
};
|
||||||
void pl_hiliteword(Panel *p, Rtext *w, int on){
|
|
||||||
|
/*
|
||||||
|
* Highlight a range of words from s to e.
|
||||||
|
*/
|
||||||
|
void pl_hilitewords(Panel *p, Rtext *s, Rtext *e, int on)
|
||||||
|
{
|
||||||
Point ul, size;
|
Point ul, size;
|
||||||
Rectangle r;
|
Rectangle r;
|
||||||
Textview *tp;
|
Textview *tp;
|
||||||
if(w==0 || (w->b==0 && w->p!=0)) return;
|
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;
|
tp=p->data;
|
||||||
ul=p->r.min;
|
ul=p->r.min;
|
||||||
size=subpt(p->r.max, p->r.min);
|
size=subpt(p->r.max, p->r.min);
|
||||||
pl_interior(UP, &ul, &size);
|
pl_interior(UP, &ul, &size);
|
||||||
ul.y-=tp->yoffs;
|
ul.y-=tp->yoffs;
|
||||||
r=rectaddpt(w->r, ul);
|
r=rectaddpt(r, ul);
|
||||||
if(rectclip(&r, p->r)){
|
if(rectclip(&r, p->r)==0)
|
||||||
if(on){
|
return;
|
||||||
if(tp->hitsave) freeimage(tp->hitsave);
|
|
||||||
tp->hitsave = allocimage(display, r, screen->chan, 0, DNofill);
|
if(on){
|
||||||
if(tp->hitsave) draw(tp->hitsave, r, p->b, 0, r.min);
|
if(tp->hitsave) freeimage(tp->hitsave);
|
||||||
pl_highlight(p->b, r);
|
tp->hitsave = allocimage(display, r, screen->chan, 0, DNofill);
|
||||||
}else{
|
if(tp->hitsave) draw(tp->hitsave, r, p->b, 0, r.min);
|
||||||
if(tp->hitsave){
|
if(t==e){
|
||||||
draw(p->b, r, tp->hitsave, 0, r.min);
|
for(t=s; t!=e; t=t->next){
|
||||||
freeimage(tp->hitsave);
|
if(t->p!=0) continue;
|
||||||
tp->hitsave = 0;
|
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){
|
void pl_stuffbitmap(Panel *p, Image *b){
|
||||||
p->b=b;
|
p->b=b;
|
||||||
for(p=p->child;p;p=p->next)
|
for(p=p->child;p;p=p->next)
|
||||||
|
@ -69,7 +116,7 @@ void pl_drawnon(Rtext *rp, Image *b){
|
||||||
void pl_fixtextview(Panel *p, Textview *tp, Rectangle r){
|
void pl_fixtextview(Panel *p, Textview *tp, Rectangle r){
|
||||||
Panel *sb;
|
Panel *sb;
|
||||||
int lo, hi;
|
int lo, hi;
|
||||||
pl_hiliteword(p, tp->hitword, 1);
|
pl_hilitewords(p, tp->hitword, tp->hitfirst, 1);
|
||||||
lo=tp->yoffs;
|
lo=tp->yoffs;
|
||||||
hi=lo+r.max.y-r.min.y; /* wrong? */
|
hi=lo+r.max.y-r.min.y; /* wrong? */
|
||||||
sb=p->yscroller;
|
sb=p->yscroller;
|
||||||
|
@ -106,45 +153,52 @@ void pl_passon(Rtext *t, Mouse *m){
|
||||||
if(t && t->b==0 && t->p!=0) plmouse(t->p, m);
|
if(t && t->b==0 && t->p!=0) plmouse(t->p, m);
|
||||||
}
|
}
|
||||||
int pl_hittextview(Panel *p, Mouse *m){
|
int pl_hittextview(Panel *p, Mouse *m){
|
||||||
Rtext *oldhitword;
|
Rtext *oldhitword, *oldhitfirst;
|
||||||
int hitme;
|
int hitme, oldstate;
|
||||||
Point ul, size;
|
Point ul, size;
|
||||||
Textview *tp;
|
Textview *tp;
|
||||||
tp=p->data;
|
|
||||||
oldhitword=tp->hitword;
|
|
||||||
hitme=0;
|
|
||||||
|
|
||||||
pl_passon(oldhitword, m);
|
tp=p->data;
|
||||||
|
|
||||||
|
hitme=0;
|
||||||
|
oldstate=p->state;
|
||||||
|
oldhitword=tp->hitword;
|
||||||
|
oldhitfirst=tp->hitfirst;
|
||||||
|
if(oldhitword==oldhitfirst)
|
||||||
|
pl_passon(oldhitword, m);
|
||||||
if(m->buttons&OUT)
|
if(m->buttons&OUT)
|
||||||
p->state=UP;
|
p->state=UP;
|
||||||
else if(m->buttons&7){
|
else if(m->buttons&7){
|
||||||
tp->buttons=m->buttons;
|
tp->buttons=m->buttons;
|
||||||
p->state=DOWN;
|
p->state=DOWN;
|
||||||
if(oldhitword==0
|
|
||||||
|| oldhitword->b!=0
|
ul=p->r.min;
|
||||||
|| oldhitword->p==0
|
size=subpt(p->r.max, p->r.min);
|
||||||
|| (oldhitword->p->flags&REMOUSE)==0){
|
pl_interior(p->state, &ul, &size);
|
||||||
ul=p->r.min;
|
tp->hitword=pl_rthit(tp->text, tp->yoffs, m->xy, ul);
|
||||||
size=subpt(p->r.max, p->r.min);
|
if(tp->hitword==0)
|
||||||
pl_interior(p->state, &ul, &size);
|
if(oldhitword!=0 && oldstate==DOWN)
|
||||||
tp->hitword=pl_rthit(tp->text, tp->yoffs, m->xy, ul);
|
tp->hitword=oldhitword;
|
||||||
if(tp->hitword!=0 && tp->hitword->hot==0) tp->hitword=0;
|
else
|
||||||
}
|
tp->hitfirst=0;
|
||||||
|
if(tp->hitword!=0 && oldstate!=DOWN)
|
||||||
|
tp->hitfirst=tp->hitword;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if(p->state==DOWN) hitme=1;
|
if(p->state==DOWN) hitme=1;
|
||||||
p->state=UP;
|
p->state=UP;
|
||||||
}
|
}
|
||||||
if(tp->hitword!=oldhitword){
|
if(tp->hitfirst!=oldhitfirst || tp->hitword!=oldhitword){
|
||||||
pl_hiliteword(p, oldhitword, 0);
|
pl_hilitewords(p, oldhitword, oldhitfirst, 0);
|
||||||
pl_hiliteword(p, tp->hitword, 1);
|
pl_hilitewords(p, tp->hitword, tp->hitfirst, 1);
|
||||||
pl_passon(tp->hitword, m);
|
if(tp->hitword==tp->hitfirst)
|
||||||
|
pl_passon(tp->hitword, m);
|
||||||
}
|
}
|
||||||
if(hitme && tp->hit && tp->hitword){
|
if(hitme && tp->hit && tp->hitword!=0 && tp->hitword==tp->hitfirst){
|
||||||
pl_hiliteword(p, tp->hitword, 0);
|
pl_hilitewords(p, tp->hitword, tp->hitfirst, 0);
|
||||||
if(tp->hitword->b!=0 || tp->hitword->p==0)
|
tp->hit(p, tp->buttons, tp->hitword);
|
||||||
tp->hit(p, tp->buttons, tp->hitword);
|
|
||||||
tp->hitword=0;
|
tp->hitword=0;
|
||||||
|
tp->hitfirst=0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -176,7 +230,7 @@ void pl_scrolltextview(Panel *p, int dir, int buttons, int num, int den){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(yoffs!=tp->yoffs){
|
if(yoffs!=tp->yoffs){
|
||||||
pl_hiliteword(p, tp->hitword, 0);
|
pl_hilitewords(p, tp->hitword, tp->hitfirst, 0);
|
||||||
r=pl_outline(p->b, p->r, p->state);
|
r=pl_outline(p->b, p->r, p->state);
|
||||||
pl_rtredraw(p->b, r, tp->text, yoffs, tp->yoffs);
|
pl_rtredraw(p->b, r, tp->text, yoffs, tp->yoffs);
|
||||||
p->scr.pos.y=tp->yoffs=yoffs;
|
p->scr.pos.y=tp->yoffs=yoffs;
|
||||||
|
@ -227,7 +281,9 @@ void plinittextview(Panel *v, int flags, Point minsize, Rtext *t, void (*hit)(Pa
|
||||||
tp->minsize=minsize;
|
tp->minsize=minsize;
|
||||||
tp->text=t;
|
tp->text=t;
|
||||||
tp->yoffs=0;
|
tp->yoffs=0;
|
||||||
|
tp->hitfirst=0;
|
||||||
tp->hitword=0;
|
tp->hitword=0;
|
||||||
|
tp->esnarf=tp->snarf=0;
|
||||||
v->scroll=pl_scrolltextview;
|
v->scroll=pl_scrolltextview;
|
||||||
tp->twid=-1;
|
tp->twid=-1;
|
||||||
v->scr.pos=Pt(0,0);
|
v->scr.pos=Pt(0,0);
|
||||||
|
@ -246,3 +302,47 @@ void plsetpostextview(Panel *p, int yoffs){
|
||||||
((Textview *)p->data)->yoffs=yoffs;
|
((Textview *)p->data)->yoffs=yoffs;
|
||||||
pldraw(p, p->b);
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ void killpix(Www *w);
|
||||||
char *buttons[]={
|
char *buttons[]={
|
||||||
"alt display",
|
"alt display",
|
||||||
"moth mode",
|
"moth mode",
|
||||||
"snarf url",
|
"snarf",
|
||||||
"paste",
|
"paste",
|
||||||
"save hit",
|
"save hit",
|
||||||
"hit list",
|
"hit list",
|
||||||
|
@ -1015,9 +1015,14 @@ void killpix(Www *w){
|
||||||
}
|
}
|
||||||
|
|
||||||
void snarf(Panel *p){
|
void snarf(Panel *p){
|
||||||
|
char *s;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if((fd=open("/dev/snarf", OWRITE|OTRUNC))>=0){
|
if((fd=open("/dev/snarf", OWRITE|OTRUNC))>=0){
|
||||||
fprint(fd, "%s", urlstr(selection));
|
s = plsnarftext(text);
|
||||||
|
if(s==0)
|
||||||
|
s = urlstr(selection);
|
||||||
|
fprint(fd, "%s", s);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue