shithub: riscv

Download patch

ref: bd998b2a78e32af7a2a8cf39ee8c11bbb3cd12ca
parent: f34ef5a8d43bdf2728cefb12707be8ea4f2052bb
author: cinap_lenrek <[email protected]>
date: Sat Sep 22 15:54:33 EDT 2012

mothra: text selection 2nd attempt

--- a/sys/src/cmd/mothra/forms.c
+++ b/sys/src/cmd/mothra/forms.c
@@ -395,7 +395,7 @@
 		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){
--- a/sys/src/cmd/mothra/libpanel/panel.h
+++ b/sys/src/cmd/mothra/libpanel/panel.h
@@ -9,7 +9,7 @@
 	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 @@
 #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 *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 *);
--- a/sys/src/cmd/mothra/libpanel/rtext.c
+++ b/sys/src/cmd/mothra/libpanel/rtext.c
@@ -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 *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 @@
 		&& 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,7 +179,7 @@
 			}
 			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),
@@ -186,10 +186,13 @@
 						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 @@
 	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;
@@ -249,4 +252,48 @@
 		if(ptinrect(p, r)) return t;
 	}
 	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;
 }
--- a/sys/src/cmd/mothra/libpanel/textview.c
+++ b/sys/src/cmd/mothra/libpanel/textview.c
@@ -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 @@
 	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_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 @@
 	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 @@
 	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 @@
 		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 @@
 		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 @@
 	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 @@
 	((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;
 }
--- a/sys/src/cmd/mothra/mothra.c
+++ b/sys/src/cmd/mothra/mothra.c
@@ -989,7 +989,7 @@
 			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;
--- a/sys/src/cmd/mothra/rdhtml.c
+++ b/sys/src/cmd/mothra/rdhtml.c
@@ -144,7 +144,7 @@
 		}
 	}
 	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;