home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.x
- Path: uunet!munnari.oz.au!mips!mips!msi!dcmartin
- From: mab@ecmwf.co.uk (Baudouin Raoult)
- Subject: v16i145: hyperwidget & manual browser, Part03/06
- Message-ID: <1992Mar6.204828.8719@msi.com>
- Originator: dcmartin@fascet
- Sender: dcmartin@msi.com (David C. Martin - Moderator)
- Organization: Molecular Simulations, Inc.
- References: <csx-16i143-hman@uunet.UU.NET>
- Date: Fri, 6 Mar 1992 20:48:28 GMT
- Approved: dcmartin@msi.com
-
- Submitted-by: mab@ecmwf.co.uk (Baudouin Raoult)
- Posting-number: Volume 16, Issue 145
- Archive-name: hman/part03
-
- #!/bin/sh
- # this is part 3 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file Hyper.c continued
- #
- CurArch=3
- if test ! -r s2_seq_.tmp
- then echo "Please unpack part 1 first!"
- exit 1; fi
- ( read Scheck
- if test "$Scheck" != $CurArch
- then echo "Please unpack part $Scheck next!"
- exit 1;
- else exit 0; fi
- ) < s2_seq_.tmp || exit 1
- echo "x - Continuing file Hyper.c"
- sed 's/^X//' << 'SHAR_EOF' >> Hyper.c
- X XFillRectangle(XtDisplay(w),XtWindow(w),
- X w->hyper.xor_gc,
- X w->hyper.grep_x,
- X w->hyper.grep_y,
- X w->hyper.grep_width,
- X w->hyper.grep_height);
- X
- X }
- X }
- X}
- X
- X/*------------------------------------------------------------------*/
- X/* SetValues : redraw only for font or color changes */
- X/*------------------------------------------------------------------*/
- X
- Xstatic Boolean SetValues (current, request, new)
- XHyperWidget current, request, new;
- X{
- X Boolean redraw = FALSE;
- X
- X#define HAS_CHANGED(a) (new->a != current->a)
- X
- X if(
- X HAS_CHANGED(core.background_pixel) ||
- X HAS_CHANGED(hyper.select_color) ||
- X HAS_CHANGED(hyper.highlight_color) ||
- X HAS_CHANGED(hyper.highlight_font) ||
- X HAS_CHANGED(hyper.normal_color) ||
- X HAS_CHANGED(hyper.normal_font)
- X )
- X {
- X
- X XtReleaseGC (new, new->hyper.normal_gc);
- X XtReleaseGC (new, new->hyper.highlight_gc);
- X XtReleaseGC (new, new->hyper.xor_gc);
- X XtReleaseGC (new, new->hyper.select_gc);
- X create_gcs(new);
- X
- X /* rebuild text */
- X/*
- X if(HAS_CHANGED(hyper.normal_font) ||
- X HAS_CHANGED(hyper.highlight_font))
- X */
- X create_new_text(new);
- X
- X redraw = TRUE;
- X }
- X
- X return (redraw);
- X
- X#undef HAS_CHANGED
- X
- X}
- X
- X/*------------------------------------------------------------------*/
- X/* Calculate the size of the widget */
- X/*------------------------------------------------------------------*/
- X
- Xstatic void calc_new_size (w)
- XHyperWidget w;
- X{
- X text_segment *s = w->hyper.first_seg;
- X int x = w->hyper.margin;
- X int y = 0;
- X int last_height = 0;
- X Boolean newline = TRUE;
- X Dimension maxWidth = w->hyper.margin;
- X Dimension maxHeight = w->hyper.margin;
- X XtGeometryResult result;
- X Dimension replyWidth = 0, replyHeight = 0;
- X
- X /* Get the size of the widget */
- X
- X while(s)
- X {
- X if(newline)
- X {
- X if(x>maxWidth) maxWidth=x;
- X x = w->hyper.margin;
- X y += s->height;
- X if(y>maxHeight) maxHeight=y;
- X
- X }
- X
- X s->x = x;
- X s->y = y - s->height;
- X
- X x += s->width;
- X
- X newline = (s->type == NEWLINE);
- X last_height = s->height;
- X
- X s = s->next;
- X }
- X
- X x+= w->hyper.margin;
- X y+= last_height;
- X
- X if(x>maxWidth ) maxWidth=x;
- X if(y>maxHeight) maxHeight=y;
- X
- X /*
- X Tell our parent we want a new size
- X */
- X
- X if(w->core.width != maxWidth || w->core.height != maxHeight)
- X {
- X result = XtMakeResizeRequest(w,maxWidth,maxHeight,
- X &replyWidth, &replyHeight) ;
- X
- X if (result == XtGeometryAlmost)
- X XtMakeResizeRequest (w, replyWidth, replyHeight,NULL, NULL);
- X
- X }
- X}
- X
- X/*-----------------------------------------------------------------------*/
- X/* Find the "visible" part of a widget as the intersection of all the */
- X/* windows of it's parents' windows */
- X/*-----------------------------------------------------------------------*/
- X
- Xstatic void find_visible_part(w,x,y,width,height)
- XWidget w;
- XPosition *x;
- XPosition *y;
- XDimension *width;
- XDimension *height;
- X{
- X Position root_x,root_y;
- X Widget p = w;
- X
- X *width = w->core.width;
- X *height = w->core.height;
- X XtTranslateCoords(w,0,0,&root_x,&root_y);
- X
- X *x = 0;
- X *y = 0;
- X
- X while(p = XtParent(p))
- X {
- X Position rx,ry;
- X Dimension w,h;
- X
- X /*
- X make all computations in the root's
- X coordinate system
- X */
- X
- X XtTranslateCoords(p,0,0,&rx,&ry);
- X
- X w = p->core.width;
- X h = p->core.height;
- X
- X /*
- X use the smallest rectangle
- X */
- X
- X if(w < *width) *width = w;
- X if(h < *height) *height = h;
- X
- X if(rx>root_x) root_x = rx;
- X if(ry>root_y) root_y = ry;
- X
- X /* stop when reach a shell,
- X don't go to top level shell */
- X if(XtIsShell(p)) break;
- X }
- X
- X /* Back to the widget's coordinate system */
- X
- X XtTranslateCoords(w,0,0,x,y);
- X *x = root_x - *x;
- X *y = root_y - *y;
- X
- X
- X}
- X
- X/*-----------------------------------------------------------------------*/
- X/* Do an "zoom" effect animation, from the selected text segment to the */
- X/* visible part of the widget */
- X/*-----------------------------------------------------------------------*/
- X
- Xstatic void zoom_open(w,s)
- XHyperWidget w;
- Xtext_segment *s;
- X{
- X int dx1,dx2,dy1,dy2;
- X
- X Position x ;
- X Position y ;
- X Dimension width ;
- X Dimension height ;
- X
- X /* selected rectangle */
- X
- X Position xs = s->x;
- X Position ys = s->y;
- X Dimension ws = s->width;
- X Dimension hs = s->height;
- X
- X
- X /* get the rectangle we want to zoom to */
- X
- X find_visible_part(w,&x,&y,&width,&height);
- X
- X /* make sure selected rectangle in visible */
- X
- X if(xs<x) xs = x;
- X if(ys<y) ys = y;
- X if(xs+ws > x+width) ws = x+width-xs;
- X if(ys+hs > y+height) hs = y+height-ys;
- X
- X /* get the offsets in each directions */
- X
- X dx1 = x-xs;
- X dy1 = y-ys;
- X dx2 = ((x+width)-(xs+ws));
- X dy2 = ((y+height)-(ys+hs));
- X
- X /* in the rectangles are differents */
- X
- X if(dx1 || dy1 || dx2 || dy2)
- X {
- X int min = 32000; /* <-- Can be buggy */
- X
- X /*
- X work in "left,top,bottom,right" rectangles (Mac)
- X rather than "x,y,width,height" (X)
- X It's easier for the animation
- X */
- X
- X int xws = xs+ws;
- X int yhs = ys+hs;
- X int xw = x + width;
- X int yh = y + height;
- X
- X
- X /* Get smallest non-null offset */
- X
- X if(dx1) min = MIN(min,ABS(dx1));
- X if(dx2) min = MIN(min,ABS(dx2));
- X if(dy1) min = MIN(min,ABS(dy1));
- X if(dy2) min = MIN(min,ABS(dy2));
- X
- X /* Scale offsets so minimun offset is 1 pixel */
- X
- X dx1 /= min;
- X dx2 /= min;
- X dy1 /= min;
- X dy2 /= min;
- X
- X /* Use speed .. */
- X
- X dx1 *= w->hyper.speed;
- X dx2 *= w->hyper.speed;
- X dy1 *= w->hyper.speed;
- X dy2 *= w->hyper.speed;
- X
- X /* Animate */
- X
- X while(min--)
- X {
- X XDrawRectangle(XtDisplay(w),XtWindow(w),
- X w->hyper.xor_gc,xs,ys,xws-xs,yhs-ys);
- X
- X /* Needed, otherwise X calls are buffered */
- X XSync(XtDisplay(w),False);
- X
- X XDrawRectangle(XtDisplay(w),XtWindow(w),
- X w->hyper.xor_gc,xs,ys,xws-xs,yhs-ys);
- X
- X xs += dx1;
- X ys += dy1;
- X
- X xws += dx2;
- X yhs += dy2;
- X
- X }
- X }
- X
- X}
- X
- X/*----------------------------------------------------------------------*/
- X/* Find the text segment at point (x,y) */
- X/*----------------------------------------------------------------------*/
- Xtext_segment *find_segment(w,x,y)
- XHyperWidget w;
- Xint x,y;
- X{
- X text_segment *s = w->hyper.first_seg;
- X
- X while(s)
- X {
- X if( s->type == HIGHLIGHT &&
- X x >= s->x &&
- X y >= s->y &&
- X x <= s->x + s->width &&
- X y <= s->y + s->height
- X )
- X return s;
- X s = s->next;
- X }
- X
- X return NULL;
- X}
- X
- X/*----------------------------------------------------------------------*/
- X/* highlight text under cursor */
- X/*----------------------------------------------------------------------*/
- Xstatic void hilite(w,on)
- XHyperWidget w;
- XBoolean on;
- X{
- X
- X text_segment *s = w->hyper.last_selected;
- X
- X if(s)
- X XDrawImageString(XtDisplay (w), XtWindow (w),
- X on?w->hyper.select_gc:s->gc,
- X s->x,
- X s->y+s->height,
- X s->text, s->length);
- X
- X}
- X
- X/*-----------------------------------------------------------------------*/
- X/* Check for mouse down */
- X/*-----------------------------------------------------------------------*/
- X
- Xstatic void select (w, event, args, n_args)
- XHyperWidget w;
- XXEvent *event;
- Xchar *args[];
- Xint n_args;
- X{
- X text_segment *s;
- X
- X /*
- X Find if the used clicked in an
- X highlighted text
- X */
- X
- X if(s = w->hyper.last_selected = find_segment(w,event->xbutton.x,event->xbutton.y))
- X hilite(w,TRUE);
- X}
- X
- X/*-----------------------------------------------------------------------*/
- X/* Check for mouse up */
- X/*-----------------------------------------------------------------------*/
- X
- Xstatic void activate (w, event, args, n_args)
- XHyperWidget w;
- XXEvent *event;
- Xchar *args[];
- Xint n_args;
- X{
- X hyperCallbackStruct cb;
- X text_segment *s;
- X
- X /*
- X Find if the used clicked in an
- X highlighted text
- X */
- X
- X if((s = find_segment(w,event->xbutton.x,event->xbutton.y))
- X && (s == w->hyper.last_selected))
- X {
- X hilite(w,FALSE);
- X
- X /* zoom if required */
- X
- X if(w->hyper.zoom) zoom_open(w,s);
- X
- X /* Fill callback struct */
- X
- X cb.text = s->text;
- X cb.length = s->length;
- X cb.reason = HYPER_REASON;
- X cb.event = event;
- X
- X /* call callbacks */
- X
- X XtCallCallbacks (w, XtNactivateCallback, &cb);
- X }
- X w->hyper.last_selected = NULL;
- X}
- X
- X/*-----------------------------------------------------------------------*/
- X/* Check for mouse moves */
- X/*-----------------------------------------------------------------------*/
- X
- Xstatic void cursor (w, event, args, n_args)
- XHyperWidget w;
- XXEvent *event;
- Xchar *args[];
- Xint n_args;
- X{
- X
- X text_segment *s;
- X
- X s = find_segment(w,event->xbutton.x,event->xbutton.y);
- X
- X if(s != w->hyper.last_cursor)
- X {
- X if(s)
- X XDefineCursor(XtDisplay(w),XtWindow(w),w->hyper.hand);
- X else
- X XUndefineCursor(XtDisplay(w),XtWindow(w));
- X hilite(w,s == w->hyper.last_selected);
- X w->hyper.last_cursor = s;
- X }
- X
- X}
- X
- X
- X/*-----------------------------------------------------------------------*/
- X/* Add a new text segment to the text */
- X/*-----------------------------------------------------------------------*/
- Xstatic void add_to_text(w,word,type)
- XHyperWidget w;
- Xchar *word;
- Xint type;
- X{
- X text_segment *s = XtNew(text_segment);
- X XCharStruct char_info;
- X int dir,ascent,desc;
- X text_segment *p,*q;
- X
- X s->next = NULL;
- X s->text = (word?XtNewString(word):NULL);
- X s->type = type;
- X s->gc = (type == HIGHLIGHT ? w->hyper.highlight_gc : w->hyper.normal_gc);
- X s->x = s->y = s->width = s->height = 0;
- X s->length = (word?strlen(word):0);
- X
- X XTextExtents(
- X (type == HIGHLIGHT ? w->hyper.highlight_font : w->hyper.normal_font),
- X word,
- X s->length,
- X &dir,&ascent,&desc,&char_info);
- X
- X s->height = ascent + desc;
- X s->desc = desc;
- X s->width = char_info.width;
- X
- X if(p = w->hyper.first_seg)
- X {
- X while(p)
- X {
- X q=p;
- X p=p->next;
- X }
- X q->next = s;
- X }
- X else w->hyper.first_seg = s;
- X}
- X
- X/*-----------------------------------------------------------------------*/
- X/* Rebuild the text structure. Called when the font changes */
- X/*-----------------------------------------------------------------------*/
- X
- Xstatic void create_new_text(w)
- XHyperWidget w;
- X{
- X text_segment *s = w->hyper.first_seg;
- X
- X w->hyper.first_seg = w->hyper.last_selected = w->hyper.last_cursor = NULL;
- X
- X while(s)
- X {
- X add_to_text(w,s->text,s->type);
- X s = s->next;
- X }
- X free_text(s);
- X calc_new_size(w);
- X}
- X
- X/*-----------------------------------------------------------------------*/
- X/* Build the text. Gets the chars from the funtion "get_next_char" */
- X/* using "data" as a parameter */
- X/*-----------------------------------------------------------------------*/
- X
- Xstatic void set_text(w,get_next_char,data)
- XHyperWidget w;
- Xchar (*get_next_char)();
- XXtPointer data;
- X{
- X char word[MAX_LINE_SIZE];
- X int i = 0;
- X char soh = w->hyper.start_of_highlight;
- X char eoh = w->hyper.end_of_highlight;
- X char c;
- X int mode = NORMAL;
- X
- X free_text(w->hyper.first_seg);
- X w->hyper.first_seg = w->hyper.last_selected = w->hyper.last_cursor = NULL;
- X w->hyper.grep_seg = NULL;
- X w->hyper.grep_txt = NULL;
- X w->hyper.grep_len = 0;
- X w->hyper.grep_off = 0;
- X
- X while(c = (get_next_char)(&data))
- X {
- X
- X /* New line */
- X
- X if(c == '\n')
- X {
- X word[i]=0;
- X if(i) add_to_text(w,word,mode);
- X add_to_text(w,NULL,NEWLINE);
- X i = 0;
- X }
- X
- X /* Start of highlight */
- X
- X else if(c == soh)
- X {
- X word[i]=0;
- X if(i) add_to_text(w,word,mode);
- X mode = HIGHLIGHT;
- X i = 0;
- X }
- X
- X /* End of highlight */
- X
- X else if(c == eoh)
- X {
- X word[i]=0;
- X if(i) add_to_text(w,word,mode);
- X mode = NORMAL;
- X i = 0;
- X }
- X else
- X {
- X if(c=='\t') c = ' ';
- X word[i++] = c;
- X if(i==MAX_LINE_SIZE)
- X {
- X word[--i]=0;
- X add_to_text(w,word,mode);
- X i=0;
- X word[i++] = c;
- X }
- X }
- X }
- X
- X /* flush .. */
- X
- X if(i)
- X {
- X word[i]=0;
- X add_to_text(w,word,mode);
- X }
- X
- X calc_new_size(w);
- X
- X}
- X
- X/*-----------------------------------------------------------------------*/
- X/* Create a new HyperWidget */
- X/*-----------------------------------------------------------------------*/
- X
- XWidget CreateHyper(parent,name,al,ac)
- XWidget parent;
- Xchar *name;
- XArgList al;
- Xint ac;
- X{
- X return XtCreateWidget(name,hyperWidgetClass,parent,al,ac);
- X}
- X
- X
- X/*-----------------------------------------------------------------------*/
- X/* Load the text from a file */
- X/*-----------------------------------------------------------------------*/
- X
- X/* provides chars to "set_text" routine */
- X
- Xstatic char get_from_file(f)
- XFILE **f;
- X{
- X int n = getc(*f);
- X return (n==EOF?0:(char)n);
- X}
- X
- X/* Public routine */
- X
- Xvoid HyperLoadFile(widget,fname)
- XWidget widget;
- Xchar *fname;
- X{
- X extern char *sys_errlist[];
- X
- X FILE *f = fopen(fname,"r");
- X if(f)
- X {
- X set_text(widget,get_from_file,(XtPointer)f);
- X fclose(f);
- X }
- X else
- X {
- X char msg[1024];
- X sprintf(msg,"%s: %s",fname,sys_errlist[errno]);
- X XtWarning(XtWidgetToApplicationContext(widget),msg);
- X }
- X
- X}
- X
- X/*-----------------------------------------------------------------------*/
- X/* Load text from memory buffer */
- X/*-----------------------------------------------------------------------*/
- X
- X/* provides chars to "set_text" routine */
- X
- Xstatic char get_from_buffer(buffer)
- Xchar **buffer;
- X{
- X char c = **buffer;
- X (*buffer)++;
- X return c;
- X}
- X
- X/* Public routine */
- X
- Xvoid HyperSetText(widget,text)
- XWidget widget;
- Xchar *text;
- X{
- X set_text(widget,get_from_buffer,(XtPointer)text);
- X}
- X
- X/*-----------------------------------------------------------------------*/
- X/* Specifies start and end of highlignt chars */
- X/*-----------------------------------------------------------------------*/
- X
- X#ifdef _NO_PROTO
- X
- Xvoid HyperSetTags(widget,start_highlight,end_highlight)
- XWidget widget;
- Xunsigned char start_highlight;
- Xunsigned char end_highlight;
- X
- X#else
- X
- Xvoid HyperSetTags(Widget widget,
- X unsigned char start_highlight,
- X unsigned char end_highlight)
- X
- X#endif
- X
- X{
- X ((HyperWidget)widget)->hyper.start_of_highlight = start_highlight;
- X ((HyperWidget)widget)->hyper.end_of_highlight = end_highlight;
- X}
- X
- X
- X/*-----------------------------------------------------------------------*/
- X/* convert a string to lower case */
- X/*-----------------------------------------------------------------------*/
- X
- Xstatic void lowcase(p)
- Xregister char *p;
- X{
- X while(*p)
- X {
- X if(isupper(*p)) *p += 32;
- X p++;
- X }
- X}
- X
- X/*-----------------------------------------------------------------------*/
- X/* Returns the text of the widget */
- X/* the memory is allocated. It must be freed by the application */
- X/* If include_tags if FALSE, the special characters are not returned */
- X/*-----------------------------------------------------------------------*/
- X
- X#ifdef _NO_PROTO
- X
- Xchar *HyperGetText(widget,include_tags)
- XWidget widget;
- XBoolean include_tags;
- X
- X#else
- X
- Xchar *HyperGetText(Widget widget,Boolean include_tags)
- X
- X#endif
- X{
- X
- X HyperWidget w = (HyperWidget)widget;
- X char *p ;
- X text_segment *s = w->hyper.first_seg;
- X int len = 1;
- X char soh[2];
- X char eoh[2];
- X
- X soh[0] = w->hyper.start_of_highlight;
- X eoh[0] = w->hyper.end_of_highlight;
- X
- X soh[1] = eoh[1] = 0;
- X
- X /* Get size of text */
- X
- X while(s)
- X {
- X len += s->length?s->length:1;
- X if(include_tags && s->type == HIGHLIGHT)
- X len += 2;
- X s = s->next;
- X }
- X
- X p = XtMalloc(len);
- X *p = 0;
- X
- X s = w->hyper.first_seg;
- X while(s)
- X {
- X if(s->length)
- X {
- X if(include_tags && s->type == HIGHLIGHT)
- X strcat(p,soh);
- X strcat(p,s->text);
- X if(include_tags && s->type == HIGHLIGHT)
- X strcat(p,eoh);
- X }
- X else
- X strcat(p,"\n");
- X s=s->next;
- X }
- X
- X return p;
- X
- X}
- X
- X/*-----------------------------------------------------------------------*/
- X/* Only for Motif */
- X/* If the widget is in a XmScrolledWindow, scroll it so the selection is */
- X/* visible */
- SHAR_EOF
- echo "End of part 3"
- echo "File Hyper.c is continued in part 4"
- echo "4" > s2_seq_.tmp
- exit 0
- --
- --
- Molecular Simulations, Inc. mail: dcmartin@msi.com
- 796 N. Pastoria Avenue uucp: uunet!dcmartin
- Sunnyvale, California 94086 at&t: 408/522-9236
-