From: tommc@hpcvusc.cv.hp.com (Tom McFarland)
Subject: Re: Scrolled Text scrolling behaviour
Reply-To: tommc@cv.hp.com
Organization: Hewlett Packard UTD-Corvallis
Date: Thu, 28 Jan 1993 19:23:04 GMT

In article <15JAN199312352029@reg.triumf.ca>, fwj@reg.triumf.ca (JONES,FRED_W.) writes:
|> My application uses a fixed-size scrolled text region (5 lines and 80
|> columns) for a running display of diagnostic messages and other
|> informational output, and I'm having trouble getting the right scrolling
|> behaviour.

There is no easy way to get the behavior you want.  If you are not using
word wrap, I can suggest a solution (but it ain't pretty).  Before adding
the new message, get the current top character (XmTextGetTopCharacter).
The position returned is the text position of the beginning of the top
line currently displayed in the text widget.  Knowing that position, you
can scan forward for a newline character (in 1.2, you can use the
XmTextFindString call), add one, and after adding your new message
set the calculated position as the new top character (XmTextSetTopCharacter).

So the sequence would be:

   XmTextPosition old_top, new_top;
   Boolean found = False;

   old_top = XmTextGetTopCharacter((Widget)tw);
   found = XmTextFindString((Widget)tw, old_top, "\n", XmTEXT_FORWARD,
			    &new_top);
   new_top++;

   /* Add your new message */
   if (found) XmTextSetTopCharacter((Widget)tw, new_top);


If you are implementing with pre-1.2, you'll need to implement your own
XmTextFindString() functionality.

Hope this helps,

Tom McFarland
Hewlett-Packard, Co.
R&D Motif team
<tommc@cv.hp.com>

|> I use the following to add a line of text to the widget and ensure that 
|> it is visible:
|> 
|>    ...
|> Widget emsgarea;   /* The Text widget */
|> 
|> void emsg1_(msg)
|>    char *msg;
|> {
|>    XmTextInsert(emsgarea, XmTextGetLastPosition(emsgarea), "\n" );
|>    XmTextInsert(emsgarea, XmTextGetLastPosition(emsgarea), msg);
|>    XmTextShowPosition(emsgarea, XmTextGetLastPosition(emsgarea));
|> }
|> 
|> I hoped that this would scroll one line at a time to display the new
|> text, but it doesn't.  After the initial text fills up the window,
|> adding the next line causes all the previous text to scroll off the
|> screen and the new line appears at the top of the window.  This is
|> highly undesirable if you are putting out multi-line messages, and seems
|> unnecessary in any case.
|> 
|> The code to implement the scrolled text window is as follows (generated
|> by XDesigner):   emainbb is the parent, a BulletinBoard.
|> 
|>           ....
|> 	char from_s [256];    /* For font list conversion */
|> 	XrmValue from_value, to_value; /* ditto */
|>           ....
|> 
|> 	XtSetArg(al[ac], XmNcolumns, 80); ac++;
|> 	XtSetArg(al[ac], XmNeditable, FALSE); ac++;
|> 	XtSetArg(al[ac], XmNcursorPositionVisible, FALSE); ac++;
|> 	sprintf ( from_s, "-dec-terminal-medium-r-normal--
|>                   14-140-75-75-c-80-iso8859-1" );
|> 	from_value.size = strlen(from_s)+1;
|> 	from_value.addr = from_s;
|> 	XtConvert(emainbb, XmRString, &from_value, XmRFontList, &to_value);
|> 	XtSetArg(al[ac], XmNfontList, *(int *)to_value.addr); ac++;
|> 	XtSetArg(al[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++;
|> 	XtSetArg(al[ac], XmNrows, 5); ac++;
|> 	XtSetArg(al[ac], XmNwordWrap, TRUE); ac++;
|> 	XtSetArg(al[ac], XmNscrollHorizontal, FALSE); ac++;
|> 	emsgarea = XmCreateScrolledText ( emainbb, "emsgarea", al, ac );
|> 	ac = 0;
|> 	widget167 = XtParent ( emsgarea );
|> 	XtSetArg(al[ac], XmNx, 10); ac++;
|> 	XtSetArg(al[ac], XmNy, 160); ac++;
|> 	XtSetArg(al[ac], XmNwidth, 677); ac++;
|> 	XtSetArg(al[ac], XmNheight, 112); ac++;
|>         XtSetValues ( widget167,al, ac );
|> 
|> 
|> Any suggestions on how to get one-line scrolling would be greatly
|> appreciated.
|> 
|> Thanks
|> Frederick Jones
|> fwj@reg.triumf.ca
Newsgroups: comp.windows.x.motif