source: trunk/athena/lib/Xj/Label.c @ 12350

Revision 12350, 12.6 KB checked in by ghudson, 26 years ago (diff)
Some RCS ID cleanup: delete $Log$ and replace other RCS keywords with $Id$.
Line 
1/*
2 * $Id: Label.c,v 1.2 1999-01-22 23:16:54 ghudson Exp $
3 *
4 * Copyright 1990, 1991 by the Massachusetts Institute of Technology.
5 *
6 * For copying and distribution information, please see the file
7 * <mit-copyright.h>.
8 *
9 */
10
11#if  (!defined(lint))  &&  (!defined(SABER))
12static char *rcsid =
13"$Id: Label.c,v 1.2 1999-01-22 23:16:54 ghudson Exp $";
14#endif
15
16#include "mit-copyright.h"
17#include <stdio.h>
18#include "Jets.h"
19#include "Label.h"
20
21extern int DEBUG;
22
23#define offset(field) XjOffset(LabelJet,field)
24
25static XjResource resources[] = {
26  { XjNx, XjCX, XjRInt, sizeof(int),
27      offset(core.x), XjRString, XjInheritValue },
28  { XjNy, XjCY, XjRInt, sizeof(int),
29      offset(core.y), XjRString, XjInheritValue },
30  { XjNwidth, XjCWidth, XjRInt, sizeof(int),
31      offset(core.width), XjRString, XjInheritValue },
32  { XjNheight, XjCHeight, XjRInt, sizeof(int),
33      offset(core.height), XjRString, XjInheritValue },
34  { XjNjustifyX, XjCJustify, XjRJustify, sizeof(int),
35      offset(label.justifyX), XjRString, XjCenterJustify },
36  { XjNjustifyY, XjCJustify, XjRJustify, sizeof(int),
37      offset(label.justifyY), XjRString, XjCenterJustify },
38  { XjNlabel, XjCLabel, XjRString, sizeof(char *),
39      offset(label.label), XjRString, "noname" },
40  { XjNicon, XjCIcon, XjRPixmap, sizeof(XjPixmap *),
41      offset(label.pixmap), XjRString, NULL },
42  { XjNleftIcon, XjCIcon, XjRPixmap, sizeof(XjPixmap *),
43      offset(label.leftPixmap), XjRString, NULL },
44  { XjNrightIcon, XjCIcon, XjRPixmap, sizeof(XjPixmap *),
45      offset(label.rightPixmap), XjRString, NULL },
46  { XjNforeground, XjCForeground, XjRColor, sizeof(int),
47      offset(label.foreground), XjRString, XjDefaultForeground },
48  { XjNbackground, XjCBackground, XjRColor, sizeof(int),
49      offset(label.background), XjRString, XjDefaultBackground },
50  { XjNreverseVideo, XjCReverseVideo, XjRBoolean, sizeof(Boolean),
51      offset(label.reverseVideo), XjRBoolean, (caddr_t)False },
52  { XjNfont, XjCFont, XjRFontStruct, sizeof(XFontStruct *),
53      offset(label.font), XjRString, XjDefaultFont },
54  { XjNpadding, XjCPadding, XjRInt, sizeof(int),
55      offset(label.padding), XjRString, "2" },
56};
57
58#undef offset
59
60static void initialize(), expose(), realize(), querySize(), move(),
61  destroy(), resize();
62
63LabelClassRec labelClassRec = {
64  {
65    /* class name */            "Label",
66    /* jet size   */            sizeof(LabelRec),
67    /* classInitialize */       NULL,
68    /* classInitialized? */     1,
69    /* initialize */            initialize,
70    /* prerealize */            NULL,
71    /* realize */               realize,
72    /* event */                 NULL,
73    /* expose */                expose,
74    /* querySize */             querySize,
75    /* move */                  move,
76    /* resize */                resize,
77    /* destroy */               destroy,
78    /* resources */             resources,
79    /* number of 'em */         XjNumber(resources)
80  }
81};
82
83JetClass labelJetClass = (JetClass)&labelClassRec;
84
85static void initialize(me)
86     LabelJet me;
87{
88  me->label.inverted = 0;
89  me->label.x = me->core.x;
90  me->label.y = me->core.y;
91}
92
93/*
94 * Things are currently broken screenwise.
95 * It will be fun to fix later. :)
96 */
97static void realize(me)
98     LabelJet me;
99{
100  unsigned long valuemask;
101  XGCValues values;
102
103  if (me->label.reverseVideo)
104    {
105      int temp;
106
107      temp = me->label.foreground;
108      me->label.foreground = me->label.background;
109      me->label.background = temp;
110    }
111
112  values.foreground = me->label.foreground;
113  values.background = me->label.background;
114  values.font = me->label.font->fid;
115  values.function = GXcopy;
116  values.graphics_exposures = False;
117  valuemask = ( GCForeground | GCBackground | GCFont |
118               GCFunction | GCGraphicsExposures );
119
120  me->label.gc_reverse = XjCreateGC(me->core.display,
121                                    me->core.window,
122                                    valuemask,
123                                    &values);
124
125  values.foreground = me->label.background;
126  values.background = me->label.foreground;
127  valuemask = ( GCForeground | GCBackground | GCFont |
128               GCFunction | GCGraphicsExposures );
129
130  me->label.gc = XjCreateGC(me->core.display,
131                            me->core.window,
132                            valuemask,
133                            &values);
134}
135
136static void destroy(me)
137     LabelJet me;
138{
139  XjFreeGC(me->core.display, me->label.gc);
140  XjFreeGC(me->core.display, me->label.gc_reverse);
141  if(me->label.pixmap)
142    XjFreePixmap(me->core.display, me->label.pixmap->pixmap);
143  if(me->label.leftPixmap)
144    XjFreePixmap(me->core.display, me->label.leftPixmap->pixmap);
145  if(me->label.rightPixmap)
146    XjFreePixmap(me->core.display, me->label.rightPixmap->pixmap);
147}
148
149static void drawLabel(me, dpy, win, gc, x, y, font, label, len, size)
150     LabelJet me;
151     Display *dpy;
152     Window win;
153     GC gc;
154     int x, y;
155     XFontStruct *font;
156     char *label;
157     int len;
158     XjSize *size;
159{
160  char *ptr1, *ptr2;
161  int width = 0;
162
163  size->width = 0;
164
165/*
166  unsigned long valuemask;
167  XGCValues values;
168
169  valuemask = ( GCForeground | GCBackground | GCFont );
170  XGetGCValues(dpy, gc, valuemask, &values);
171  if (values.font != font->fid)
172    {
173      values.font = font->fid;
174      XChangeGC(dpy, gc, valuemask, values);
175    }
176*/
177
178  ptr1 = ptr2 = label;
179  while(*ptr2 != '\0' && ((int) (ptr2-label)) < len)
180    {
181      switch(*ptr2)
182        {
183        case '\n':
184          if (me)
185            {
186              XDrawString(dpy, win, gc, x, y, ptr1, (int) (ptr2-ptr1));
187              x = me->label.x;
188            }
189          width = XTextWidth(font, ptr1, (int) (ptr2-ptr1));
190          if (width > size->width)
191            size->width = width;
192          y += font->ascent + font->descent;
193          ptr1 = ptr2 + 1;
194          break;
195
196        case '\\':
197          switch(*(ptr2 + 1))
198            {
199            case '\\':
200              break;
201
202            default:
203              break;
204            }
205          break;
206
207        default:
208          break;
209        }
210      ptr2++;
211    }
212
213  if (ptr2-ptr1)
214    {
215      if (me)
216        XDrawString(dpy, win, gc, x, y, ptr1, (int) (ptr2-ptr1));
217      width = XTextWidth(font, ptr1, (int) (ptr2-ptr1));
218      if (width > size->width)
219        size->width = width;
220      y += font->ascent + font->descent;
221    }
222
223  size->height = y;
224}
225
226static void querySize(me, size)
227     LabelJet me;
228     XjSize *size;
229{
230  if (DEBUG)
231    printf ("QS(label) '%s'\n", me->core.name);
232
233  if (me->label.pixmap)
234    {
235      size->width = me->label.pixmap->width;
236      size->height = me->label.pixmap->height;
237    }
238  else
239    {
240#ifndef SINGLELINE
241      drawLabel(NULL, NULL, NULL, NULL, 0, 0,
242                me->label.font,
243                me->label.label, strlen(me->label.label),
244                size);
245#else
246      size->width = XTextWidth(me->label.font,
247                               me->label.label,
248                               strlen(me->label.label));
249      size->height = me->label.font->ascent + me->label.font->descent;
250#endif
251    }
252
253  if (me->label.leftPixmap)
254    {
255      size->width += me->label.leftPixmap->width;
256      size->height = MAX(size->height, me->label.leftPixmap->height);
257    }
258
259  if (me->label.rightPixmap)
260    {
261      size->width += me->label.rightPixmap->width;
262      size->height = MAX(size->height, me->label.rightPixmap->height);
263    }
264}
265
266static void move(me, x, y)
267     LabelJet me;
268     int x, y;
269{
270  if (DEBUG)
271    printf ("MV(label) '%s' x=%d,y=%d\n", me->core.name, x, y);
272
273  me->label.x += (x - me->core.x);
274  me->label.y += (y - me->core.y);
275
276  me->label.leftX += (x - me->core.x);
277  me->label.leftY += (y - me->core.y);
278
279  me->label.rightX += (x - me->core.x);
280  me->label.rightY += (y - me->core.y);
281
282  me->core.x = x;
283  me->core.y = y;
284}
285
286static void resize(me, size)
287     LabelJet me;
288     XjSize *size;
289{
290  if (DEBUG)
291    printf ("RS(label) '%s' w=%d,h=%d\n", me->core.name,
292            size->width, size->height);
293
294  if (me->core.width != size->width
295      || me->core.height != size->height)
296
297    {
298#ifndef SINGLELINE
299      XjSize l_size;
300
301      drawLabel(NULL, NULL, NULL, NULL, 0, 0,
302                me->label.font,
303                me->label.label, strlen(me->label.label),
304                &l_size);
305#endif
306
307      /*  This isn't right... */
308      if (me->label.gc != NULL)
309        XFillRectangle(me->core.display, me->core.window,
310                       me->label.gc,
311                       me->core.x, me->core.y,
312                       me->core.width, me->core.height);
313
314      me->core.width = size->width;
315      me->core.height = size->height;
316
317      me->label.x = me->label.leftX = me->core.x;
318      me->label.y = me->label.leftY = me->label.rightY = me->core.y;
319      if (me->label.rightPixmap)
320        me->label.rightX = (me->core.x + me->core.width
321                            - me->label.rightPixmap->width);
322
323      /*
324       * Handle X Justification
325       */
326      if (me->label.justifyX == Center)
327        {
328          if (me->label.pixmap)
329            me->label.x += (me->core.width - me->label.pixmap->width) / 2;
330          else
331            {
332#ifndef SINGLELINE
333              me->label.x += (me->core.width - l_size.width) / 2;
334#else
335              me->label.x += (me->core.width
336                              - XTextWidth(me->label.font,
337                                           me->label.label,
338                                           strlen(me->label.label))) / 2;
339#endif
340            }
341        }
342
343      else if (me->label.justifyX == Right)
344        {
345          if (me->label.rightPixmap)
346            me->label.x = me->label.rightX - me->label.padding;
347          else
348            me->label.x = me->core.x + me->core.width - me->label.padding;
349
350          if (me->label.pixmap)
351            me->label.x -= me->label.pixmap->width;
352          else
353            {
354#ifndef SINGLELINE
355              me->label.x -= l_size.width;
356#else
357              me->label.x -= XTextWidth(me->label.font,
358                                        me->label.label,
359                                        strlen(me->label.label));
360#endif
361            }
362        }
363
364      else                      /* LEFT justify */
365        {
366          me->label.x += me->label.padding;
367          if (me->label.leftPixmap)
368            me->label.x += me->label.leftPixmap->width;
369        }
370
371
372
373      /*
374       * Handle Y Justification
375       */
376      if (me->label.justifyY == Center)
377        {
378          if (me->label.pixmap)
379            me->label.y += (me->core.height - me->label.pixmap->height) / 2;
380          else
381            {
382#ifndef SINGLELINE
383              me->label.y += (me->core.height - l_size.height)/2
384                + me->label.font->ascent;
385#else
386              me->label.y += ((me->core.height +
387                               (me->label.font->ascent /* -
388                                me->label.font->descent*/))
389                              / 2);
390#endif
391            }
392
393          if (me->label.leftPixmap)
394            me->label.leftY += (me->core.height -
395                                me->label.leftPixmap->height) / 2;
396          if (me->label.rightPixmap)
397            me->label.rightY += (me->core.height -
398                                 me->label.rightPixmap->height) / 2;
399        }
400
401      else if (me->label.justifyY == Bottom)
402        {
403          if (me->label.pixmap)
404            me->label.y += (me->core.height - me->label.pixmap->height);
405          else
406            me->label.y += (me->core.height - me->label.font->descent);
407
408          if (me->label.leftPixmap)
409            me->label.leftY += (me->core.height -
410                                me->label.leftPixmap->height);
411          if (me->label.rightPixmap)
412            me->label.rightY += (me->core.height -
413                                 me->label.rightPixmap->height);
414        }
415
416      else                      /* TOP justify */
417        {
418          if (! me->label.pixmap)
419            me->label.y += me->label.font->ascent;
420        }
421    }
422}
423
424
425static void expose(me, event)
426     Jet me;
427     XEvent *event;             /* ARGSUSED */
428{
429  LabelJet lj = (LabelJet) me;
430  XjSize size;
431
432  if (DEBUG)
433    printf ("EX(label) '%s'\n", lj->core.name);
434
435  if (lj->label.leftPixmap)
436    {
437      XCopyPlane(me->core.display,
438                 lj->label.leftPixmap->pixmap,
439                 me->core.window,
440                 (lj->label.inverted) ? lj->label.gc_reverse : lj->label.gc,
441                 0, 0,
442                 lj->label.leftPixmap->width,
443                 lj->label.leftPixmap->height,
444                 lj->label.leftX,
445                 lj->label.leftY,
446                 1);
447    }
448
449  if (lj->label.rightPixmap)
450    {
451      XCopyPlane(me->core.display,
452                 lj->label.rightPixmap->pixmap,
453                 me->core.window,
454                 (lj->label.inverted) ? lj->label.gc_reverse : lj->label.gc,
455                 0, 0,
456                 lj->label.rightPixmap->width,
457                 lj->label.rightPixmap->height,
458                 lj->label.rightX,
459                 lj->label.rightY,
460                 1);
461    }
462
463  if (lj->label.pixmap)
464    {
465      XCopyPlane(me->core.display,
466                 lj->label.pixmap->pixmap,
467                 me->core.window,
468                 (lj->label.inverted) ? lj->label.gc_reverse : lj->label.gc,
469                 0, 0,
470                 lj->label.pixmap->width,
471                 lj->label.pixmap->height,
472                 lj->label.x,
473                 lj->label.y,
474                 1);
475    }
476  else
477    {
478#ifndef SINGLELINE
479      drawLabel(lj, me->core.display, me->core.window,
480                (lj->label.inverted) ? lj->label.gc : lj->label.gc_reverse,
481                lj->label.x, lj->label.y,
482                lj->label.font,
483                lj->label.label, strlen(lj->label.label),
484                &size);
485#else
486      XDrawString(me->core.display, me->core.window,
487                  (lj->label.inverted) ? lj->label.gc : lj->label.gc_reverse,
488                  lj->label.x, lj->label.y,
489                  lj->label.label, strlen(lj->label.label));
490#endif
491    }
492}
493
494void setLabel(me, label)
495     LabelJet me;
496     char *label;
497{
498  if (me->label.pixmap)
499    return;
500
501  if (me->label.gc != NULL)
502    XFillRectangle(me->core.display, me->core.window,
503                   me->label.gc,
504                   me->core.x, me->core.y,
505                   me->core.width, me->core.height);
506  me->label.label = label;
507  expose((Jet) me, NULL);
508}
509
510void setPixmap(me, pixmap)
511     LabelJet me;
512     XjPixmap *pixmap;
513{
514  if (me->label.gc != NULL)
515    XFillRectangle(me->core.display, me->core.window,
516                   me->label.gc,
517                   me->core.x, me->core.y,
518                   me->core.width, me->core.height);
519  me->label.pixmap = pixmap;
520  expose((Jet) me, NULL);
521}
522
523void setState(me, which, state)
524     LabelJet me;
525     int which;                 /* ARGSUSED */
526     Boolean state;
527{
528  me->label.inverted = state;
529
530  expose((Jet) me, NULL);
531}
Note: See TracBrowser for help on using the repository browser.