[comp.windows.x.motif] Multiline label wont work for me

woodruff@addvax.llnl.gov (Woodruff, John P) (04/11/91)

looks wrong.  Instead of new-line, the text of the label occupies a
single line, with a punctuation that resembles a Yen (currency) symbol
where \n was input.

I have seen this same appearance regardless of whether text was in 
the app-defaults file, or was bound to the (label or dialog) widgets
messageString resource with XtSetValues at run time.

Thanks for any help

tjhorton@vis.toronto.edu ("Timothy J. Horton") (04/11/91)

woodruff@addvax.llnl.gov writes:
Re: Multiline label wont work for me
>looks wrong.  Instead of new-line, the text of the label occupies a
>single line, with a punctuation that resembles a Yen (currency) symbol
>where \n was input.
>
>I have seen this same appearance regardless of whether text was in 
>the app-defaults file, or was bound to the (label or dialog) widgets
>messageString resource with XtSetValues at run time.

I think that's a "frequently asked question."  If you specify the newline
in an argument to XmStringCreate it gets converted properly, I think, but
not if you specify the string in a resource (defaults) file.  Right?
(Do I have it switched around?).  Seems the trick is in the processing of
the breaks in the string.  I suggest you read up on XmString formats.  You
may have to add your own resource convertor, to take care of newlines.
Again, I've seen this before here somewhere;  check the FAQs.

lanzo@wgate.UUCP (Mark Lanzo) (04/12/91)

In a prior article woodruff@addvax.llnl.gov wrote:
    looks wrong.  Instead of new-line, the text of the label occupies a
    single line, with a punctuation that resembles a Yen (currency) symbol
    where \n was input.
    
    I have seen this same appearance regardless of whether text was in 
    the app-defaults file, or was bound to the (label or dialog) widgets
    messageString resource with XtSetValues at run time.

You need to create your label string using some function like
XmStringCreateLtoR() instead of just using XmStringCreate().

Unfortunately, this doesn't do you any good when it comes to 
putting multiline label strings in the resource file.  
This is a horrendous kludge, but seems to work:

    Use XtGetValues() to get the XmNlabelString 
    Use XmStringGetLtoR to get the text component of the XmNlabelString.
    Use XmStringCreateLtoR to make a multiline XmString from the text.
    Use XtSetValues() to replace the string.

As an example, here is a hack I put together which allowed me to 
have multiline strings on some MessageBox widgets I had in an
application.  I presume that you can figure out what the
ARGLIST_RESET and ARGLIST_ADD macros do.

Disclaimer:  this is a hack.  Use at your own risk, etc. etc.
If anyone has a better way, I'd love to hear it.

			Hope this helps,

				-- Mark --

Replies to:
uunet!wgate!lanzo 		
lanzo@wgate.wgate.com ?? 
>>> Warning: return address in header is probably incorrect, use the above <<<

-----------------------------------%<----------------------------------------

/*
 * This routine takes a message box widget, gets the message string
 * component, and replaces it with a multiline message string.
 *
 * The Motif libraries apparently use XmStringCreate (or a close
 * relative) for creating the message strings for the widgets.
 * This has the disadvantage of only allowing single line messages.
 * I want multiline messages, so here I fetch the message string,
 * and rebuild it using XmStringCreateLtoR, which will create a 
 * multi-line compound string, by parsing "\n" characters
 * in the input text string.
 * 
 * I also remove any tabs in the string.  There are two reasons for
 * this:  (1) It makes it easy to indent continuation lines in the
 * resource file, and (2) tabs look ugly anyways on most fonts, 
 * since they do not normally represent whitespace in the font set.
 * [Instead you tend to get things like miniature 'HT' or 'TAB'
 * symbols].
 *
 * I suspect that there is a better way to do this, but I don't know
 * what it is offhand.
 *
 * Note that this routine works by using XmMessageBoxGetChild() to
 * get the message-label (which is an XmLabelGadget), and then
 * modifying the message-labels XmNlabelString resource directly.
 * It does *NOT* work reliably to try replacing the 
 * XmNmessageString resource for the MessageBox widget instead.
 * This may be a bug in the Motif libraries; I don't know.
 */

void ConvertToMultilineMessage(msg)
    Widget msg;		    /* ID of a MessageBox widget */
    {
    XmString msg_str;
    char * text;
    register char * in, * out, c;
    int i, buflen;

    /* Find the message label (an XmLabelGadget) */
    msg = XmMessageBoxGetChild(msg, XmDIALOG_MESSAGE_LABEL);
    if (!msg) return;

    /* 
     *  note that XtGetValues(), XmStringGetLtoR both return malloc'ed
     *  copies of the items, so I must free them myself.  It is also 
     *  safe to modify them in place.
     */
    ARGLIST_RESET();
    ARGLIST_ADD(XmNlabelString,&msg_str);
    XtGetValues(msg,ARGS);

    if (!XmStringGetLtoR(msg_str,XmSTRING_DEFAULT_CHARSET,&text)) return;
    XmStringFree(msg_str);	/* dispose of old string */

    /* Remove tabs */
    in = out = text;
    while((c = *in++))
	if (c != '\t') 
	    *out++ = c;
    *out = 0;

    msg_str = XmStringCreateLtoR(text,XmSTRING_DEFAULT_CHARSET);
    XtFree(text);		/* dispose of malloc'ed text */
    if (msg_str) 
	{
	ARGLIST_RESET();
	ARGLIST_ADD(XmNlabelString,msg_str);
	XtSetValues(msg,ARGS);
	XmStringFree(msg_str); /* dispose string since Motif will clone it */
	}
    }