1 /* $Id: test1.c,v 1.3 2002/01/16 00:48:04 dannybackx Exp $ */
2 
3 #if 0
4 Article: 68453 of comp.windows.x.motif
5 Message-ID: <3A15422D.986F04B@ist.co.uk>
6 Date: Fri, 17 Nov 2000 14:35:25 +0000
7 From: Antony Fountain <af@ist.co.uk>
8 Reply-To: af@ist.co.uk
9 Organization: Imperial Software Technology
10 X-Mailer: Mozilla 4.75 [en] (X11; U; SunOS 5.6 sun4u)
11 X-Accept-Language: en
12 MIME-Version: 1.0
13 Newsgroups: comp.windows.x.motif
14 To: kgandhi@my-deja.com
15 Subject: Re: Colored Items in ScrolledList Widget
16 References: <8updrj$a95$1@nnrp1.deja.com>
17 Content-Type: multipart/mixed;
18  boundary="------------AABEF9C00BE38D33C59E0864"
19 NNTP-Posting-Host: isbalham.ist.co.uk
20 X-Trace: 17 Nov 2000 14:34:40 GMT, isbalham.ist.co.uk
21 Lines: 333
22 Path: news.tu-darmstadt.de!news.hrz.uni-kassel.de!news-fra1.dfn.de!news.tele.dk!193.190.198.17!newsfeeds.belnet.be!news.belnet.be!psinet-eu-nl!psiuk-p4!uknet!psiuk-n!nnrp1.news.uk.psi.net!isbalham.ist.co.uk
23 Xref: news.tu-darmstadt.de comp.windows.x.motif:68453
24 
25 This is a multi-part message in MIME format.
26 --------------AABEF9C00BE38D33C59E0864
27 Content-Type: text/plain; charset=us-ascii
28 Content-Transfer-Encoding: 7bit
29 
30 kgandhi@my-deja.com wrote:
31 
32 > I have been informed that Motif 2.0 and higher allows for different
33 > colored items in a ScrolledList widget due to the fact that XmStrings
34 > (of which items are created) allow colors. I have checked a Reference
35 > Manual for Motif 2.1 and do not find any function to create XmStrings
36 > with color arguments. How exactly does one code in a specific colored
37 > item which is different than the XmNbackground and XmNforeground color
38 > resource for a ScrolledList?
39 >
40 > Sent via Deja.com http://www.deja.com/
41 > Before you buy.
42 
43 The way this works is as follows:
44 
45 You need to create a render table which has some renditions in it
46 
47 that have the XmNrenditionForeground/XmNrenditionBackground resources set.
48 
49 You then need to ensure that you wrap whatever segments you want colored
50 
51 in your compound string with XmSTRING_COMPONENT_RENDITION_BEGIN/
52 
53 XmSTRING_COMPONENT_RENDITION_END segments such that the XmSTRING_COMPONENT_RENDITION_BEGIN
54 
55 tag matches the relevent rendition. XmStringGenerate will do this for you.
56 
57 Then apply the render table to the widget where you are drawing the compound strings
58 
59 (the list).
60 
61 Basic outline:
62 
63     Create a render table with a "red" rendition...
64 
65     XmRendition red_rendition;
66 
67     XmRendition renditions[MAX_RENDITIONS];
68 
69     XmRenderTable table;
70 
71     Arg args[8];
72 
73     Cardinal n, renditions_count = 0;
74 
75     Pixel red_pixel = ...; /* Whatever: XtConvertAndStore() ... */
76 
77     n = 0;
78 
79     XtSetArg (args[n], XmNrenditionForeground, red_pixel); n++;
80 
81     ... /* Other rendition arguments */
82 
83     red_rendition = XmRenditionCreate (some_widget, "red", args, n);
84 
85     renditions[renditions_count++] = red_rendition;
86 
87     /* Add any other renditions */
88 
89     ...
90 
91     /* Create the render table using the renditions */
92 
93     render_table = XmRenderTableAddRenditions (NULL, renditions, renditions_count, XmMERGE_NEW);
94 
95     /* Now create your compound strings... */
96 
97     XmString red_segment = XmStringGenerate ((XtPointer) "This should be red",
98 
99                                              NULL, /* Or some segment tag */
100 
101                                              XmCHARSET_TEXT,
102 
103                                              "red"); /* Must match the rendition tag */
104 
105     /* Create rest of compound strings */
106 
107     ...
108 
109     /* Apply the render table to the list */
110 
111     XtVaSetValues (list, XmNrenderTable, render_table, NULL);
112 
113     I hope this is of some help. The above is sketchy. Enclosed is an example
114 
115     program which gives a multi-column, multi-font, multi-colored list widget
116 
117     using the Motif 2.1 render table/tablist routines.
118 
119     Yours faithfully,
120 
121     --
122 ************************************************************
123  Antony Fountain            Principal Software Engineer
124                             Imperial Software Technology
125 
126  120 Hawthorne Ave., Suite 101        252 Kings Road
127  Palo Alto, CA  94301                 Reading RG1 4HP U.K.
128  Tel: (650) 688-0200                  Tel: +44 118 958 7055
129  Fax: (650) 688-1054                  Fax: +44 118 958 9005
130 
131  af@ist.co.uk                         http://www.ist.co.uk/
132 ************************************************************
133 
134 
135 #endif
136 
137 
138 
139 /* rendered_list.c: illustrates all the features of
140 ** render tables and renditions by creating a
141 ** multi-column, multi-font, multi-color List widget.
142 */
143 #include <stdio.h>
144 #include <stdlib.h>
145 #include <Xm/Xm.h>
146 #include <Xm/RowColumn.h>
147 #include <Xm/List.h>
148 
149 /* ConvertStringToPixel()
150 ** A utility function to convert a color name to a Pixel
151 */
ConvertStringToPixel(Widget widget,char * name)152 Pixel ConvertStringToPixel (Widget widget, char *name)
153 {
154         XrmValue from_value, to_value; /* For resource conversion */
155 
156         from_value.addr = name;
157         from_value.size = strlen( name ) + 1;
158         to_value.addr   = NULL;
159         XtConvertAndStore (widget, XmRString, &from_value, XmRPixel, &to_value);
160 
161         if (to_value.addr) {
162 		return (*((Pixel*) to_value.addr)) ;
163         }
164 
165 	return XmUNSPECIFIED_PIXEL ;
166 }
167 
168 /*
169 ** A convenient structure to hold the data
170 ** for creating various renditions
171 */
172 typedef struct RenditionData_s
173 {
174 	char *tag;
175 	char *color;
176 	char *font;
177 } RenditionData_t;
178 
179 #define MAX_COLUMNS    4
180 
181 RenditionData_t rendition_data[MAX_COLUMNS] =
182 {
183 	{ "one",   "red",    "fixed"                                                      },
184 	{ "two",   "green",  "-adobe-helvetica-bold-r-normal--10-100-75-75-*-*-iso8859-1" },
185 	{ "three", "blue",   "bembo-bold"                                                 },
186 	{ "four",  "orange", "-adobe-*-medium-i-normal--24-240-75-75-*-*-iso8859-1"       }
187 };
188 
189 /*
190 ** Arbitrary data to display in the List
191 */
192 static char *poem[] =
193 {
194 	"Mary", "had a",           "little",    "lamb",
195 	"Its",  "fleece",          "was white", "as snow",
196 	"And",  "everywhere that", "Mary",      "went",
197 	"The",  "lamb was",        "sure",      "to follow",
198 	(char *) 0
199 };
200 
201 /*
202 ** CreateListData(): routine to convert the
203 ** poem into an array of compound strings
204 */
CreateListData(int * count)205 XmStringTable CreateListData (int *count)
206 {
207 	XmStringTable table  = (XmStringTable) 0 ;
208 	int           line   = 0 ;
209 	int           column = 0 ;
210 	int           index  = 0 ;
211 	XmString      entry ;
212 	XmString      row =NULL;
213 	XmString      tmp =NULL;
214 	XmString      tab;
215 
216 
217 #if 0
218 	tab = XmStringComponentCreate (XmSTRING_COMPONENT_TAB, NULL, 0);
219 #endif
220 
221 	tab = XmStringComponentCreate (XmSTRING_COMPONENT_TAB, 0, NULL);
222 
223 	while (poem[index] != (char *) 0) {
224 		/* create a compound string, using the rendition tag */
225 		entry = XmStringGenerate ((XtPointer) poem[index],
226 					  NULL,
227 					  XmCHARSET_TEXT,
228 					  rendition_data[column].tag) ;
229 
230 		if (row != (XmString)NULL) {
231 			tmp = XmStringConcat (row, tab) ;
232 			XmStringFree (row) ;
233 			row = XmStringConcatAndFree (tmp, entry) ;
234 		}
235 		else {
236 			row = entry ;
237 		}
238 
239 		++column ;
240 
241 		if (column == MAX_COLUMNS) {
242 			if (table == (XmStringTable) 0) {
243 				table = (XmStringTable) XtMalloc((unsigned) 1 * sizeof (XmString)) ;
244 			}
245 			else {
246 				table = (XmStringTable) XtRealloc((char *) table, (unsigned) (line + 1) * sizeof (XmString)) ;
247 			}
248 
249 			table[line++] = row ;
250 			row           = (XmString) 0 ;
251 			column        = 0 ;
252 		}
253 
254 		index++ ;
255 	}
256 
257 	XmStringFree (tab) ;
258 
259 	table[line] = (XmString) 0 ;
260 
261 	*count = line ;
262 
263 	return table ;
264 }
265 
266 int
main(int argc,char * argv[])267 main (int argc, char *argv[])
268 {
269 	Widget        toplevel, rowcol, list;
270 	XtAppContext  app;
271 	Arg           args[10];
272 	XmTab         tabs[MAX_COLUMNS];
273 	XmTabList     tablist;
274 	XmRendition   renditions[MAX_COLUMNS];
275 	XmRenderTable rendertable;
276 	XmStringTable xmstring_table;
277 	int           xmstring_count;
278 	Pixel         pixels[MAX_COLUMNS];
279 	int           n, i;
280 
281 	XtSetLanguageProc (NULL, NULL, NULL);
282 	toplevel = XtVaOpenApplication (&app, "Demos", NULL, 0, &argc, argv, NULL,
283 					sessionShellWidgetClass, NULL);
284 
285 	rowcol = XmCreateRowColumn (toplevel, "rowcol", NULL, 0) ;
286 
287 	/* Create some colors */
288 	for (i = 0 ; i < MAX_COLUMNS ; i++) {
289 		pixels[i] = ConvertStringToPixel (toplevel, rendition_data[i].color) ;
290 	}
291 
292 	/* Create tab stops for columnar output */
293 	for (i = 0 ; i < MAX_COLUMNS ; i++) {
294 		tabs[i] = XmTabCreate ((float) 1.5,
295 				       XmINCHES,
296 				       ((i == 0) ? XmABSOLUTE : XmRELATIVE),
297 				       XmALIGNMENT_BEGINNING,
298 				       ".") ;
299 	}
300 
301 	/* Create a tablist table which contains the tabs */
302 	tablist = XmTabListInsertTabs (NULL, tabs, XtNumber (tabs), 0) ;
303 
304 	/* Create some multi-font/color renditions, and use the tablist */
305 	/* This will be inherited if we use it on the first rendition   */
306 	for (i = 0 ; i < MAX_COLUMNS ; i++) {
307 		n = 0 ;
308 
309 		if (i == 0) {
310 			XtSetArg (args[n], XmNtabList, tablist); n++;
311 		}
312 
313 		XtSetArg (args[n], XmNrenditionForeground, pixels[i]); n++;
314 		XtSetArg (args[n], XmNfontName, rendition_data[i].font); n++;
315 		XtSetArg (args[n], XmNfontType, XmFONT_IS_FONT); n++;
316 		renditions[i] = XmRenditionCreate (toplevel, rendition_data[i].tag, args, n);
317 	}
318 
319 	/* Create the Render Table */
320 	rendertable = XmRenderTableAddRenditions (NULL, renditions, XtNumber (renditions), XmMERGE_NEW) ;
321 
322 	/* Create the multi-column data for the list */
323 
324 	xmstring_table = CreateListData (&xmstring_count) ;
325 
326 	/* Create the List, using the render table */
327 	n = 0;
328 	XtSetArg (args[n], XmNrenderTable, rendertable); n++;
329 	XtSetArg (args[n], XmNitems, xmstring_table); n++;
330 	XtSetArg (args[n], XmNitemCount, xmstring_count); n++;
331 	XtSetArg (args[n], XmNwidth, 400); n++;
332 	XtSetArg (args[n], XmNvisibleItemCount, xmstring_count + 1); n++;
333 	list = XmCreateScrolledList (rowcol, "list", args, n);
334 	XtManageChild (list);
335 
336 	/* Free the memory now the widget has the data */
337 	/* First, the compound strings */
338 	for (i = 0 ; i < xmstring_count ; i++)
339 		XmStringFree (xmstring_table[i]) ;
340 	XtFree((char *) xmstring_table) ;
341 
342 	/* Secondly, the XmTab objects */
343 	for ( i = 0 ; i < XtNumber (tabs) ; i++)
344 		XmTabFree (tabs[i]);
345 
346 	/* Thirdly, the XmTabList object */
347 	XmTabListFree (tablist) ;
348 
349 	/* Fourthly, the XmRendition objects */
350 	for (i = 0 ; i < XtNumber (renditions) ; i++)
351 		XmRenditionFree (renditions[i]) ;
352 
353 	/* Lastly, the XmRenderTable object */
354 	XmRenderTableFree (rendertable) ;
355 
356 	XtManageChild (rowcol);
357 	XtRealizeWidget (toplevel);
358 
359 #if 1
360         LessTifTestMainLoop(toplevel);
361 #else
362 	XtAppMainLoop (app);
363 #endif
364 
365 	exit(0); /* avoid compiler warnings */
366 }
367