.\"remove .ig hn for full docs .de hi .ig eh .. .de eh .. .TH "" 3 "" "Version 3.0" "Free Widget Foundation" .SH NAME XfwfLabel .SH DESCRIPTION The Label class has the capability to display one or more lines of text in a single font. Otherwise it is the same as the Board class. The text can be left, right or center justified and it can be centered vertically or put against the top or the bottom of the widget. There is also a resource to set tab stops. The text is `grayed out' when the widget becomes insensitive (resource: \fIsensitive\fP), even though a Label widget has no actions of its own. .SS "Public variables" .ps-2 .TS center box; cBsss lB|lB|lB|lB l|l|l|l. XfwfLabel Name Class Type Default XtNlabel XtCLabel String NULL XtNtablist XtCTablist String NULL XtNfont XtCFont FontStruct XtDefaultFont XtNforeground XtCForeground Pixel XtDefaultForeground XtNalignment XtCAlignment Alignment 0 XtNtopMargin XtCTopMargin Dimension 2 XtNbottomMargin XtCBottomMargin Dimension 2 XtNleftMargin XtCLeftMargin Dimension 2 XtNrightMargin XtCRightMargin Dimension 2 XtNshrinkToFit XtCShrinkToFit Boolean False XtNrvStart XtCRvStart Int 0 XtNrvLength XtCRvLength Int 0 .TE .ps .TP .I "XtNlabel" The text is a single string, which may contain embedded newlines. There is no provision for changing fonts in the middle of a text. .hi .nf String label = NULL .fi .eh .TP .I "XtNtablist" A tablist can be provided for tabbing to particular columns within the label. .hi .nf String tablist = NULL .fi .eh .TP .I "XtNfont" The text is drawn in the font which is give as the \fIfont\fP resource. .hi .nf XFontStruct * font = XtDefaultFont .fi .eh .TP .I "XtNforeground" The foreground color is the color used to draw the text. .hi .nf Pixel foreground = XtDefaultForeground .fi .eh .TP .I "XtNalignment" The text can be aligned in the widget in nine ways: left, right or center, combined with top, center or bottom. Symbolic constants \fIXfwfTop\fP, \fIXfwfBottom\fP, \fIXfwfLeft\fP and \fIXfwfRight\fP can be added together to get the desired alignment. The alignment is actually a four-bit number made up of two parts of 2 bits added together: 1 is left, 2 is right, 0 is center, 4 is top, 8 is bottom, 0 is vertical center. Thus 5 (= 1 + 4) means top left and 2 (= 2 + 0) means center right. For easier specification, there is also a converter from strings, that accepts string like `top left' or `center right'. .hi .nf Alignment alignment = 0 .fi .eh .TP .I "XtNtopMargin" The \fItopmargin\fP is only used when the text is not centered. It gives the number of pixels between the frame and the top of the text. .hi .nf Dimension topMargin = 2 .fi .eh .TP .I "XtNbottomMargin" The \fIbottomMargin\fP is only used to compute the preferred size of the button in case \fIshrinkToFit = True\fP. .hi .nf Dimension bottomMargin = 2 .fi .eh .TP .I "XtNleftMargin" The \fIleftMargin\fP is only used when the text is not centered. It gives the number of pixels between the frame and the left edge of the text, and if possible also between the frame and the right edge of the text. .hi .nf Dimension leftMargin = 2 .fi .eh .TP .I "XtNrightMargin" The \fIrightMargin\fP is only used to compute the preferred size of the button in case \fIshrinkToFit = True\fP. .hi .nf Dimension rightMargin = 2 .fi .eh .TP .I "XtNshrinkToFit" Buttons will normally not occupy the full area of their parents. Most likely they will be a fixed size or a size depending on the label. By setting the \fIshrinkToFit\fP resource to True, the width and height are recomputed with every new label. .hi .nf Boolean shrinkToFit = False .fi .eh .TP .I "XtNrvStart" It is possible to set a part of the label apart by drawing it in reverse. The \fIrvStart\fP resource gives the index of the first character to draw in reverse video. .hi .nf int rvStart = 0 .fi .eh .TP .I "XtNrvLength" The \fIrvLength\fP resource contains the number of characters to draw in reverse video. .hi .nf int rvLength = 0 .fi .eh .TP .I "XtNtraversalOn" A label normally needs no keyboard interface, therefore traversal is turned off. .hi .nf traversalOn = False .fi .eh .ps-2 .TS center box; cBsss lB|lB|lB|lB l|l|l|l. XfwfBoard Name Class Type Default XtNabs_x XtCAbs_x Position 0 XtNrel_x XtCRel_x Float "0.0" XtNabs_y XtCAbs_y Position 0 XtNrel_y XtCRel_y Float "0.0" XtNabs_width XtCAbs_width Position 0 XtNrel_width XtCRel_width Float "1.0" XtNabs_height XtCAbs_height Position 0 XtNrel_height XtCRel_height Float "1.0" XtNhunit XtCHunit Float "1.0" XtNvunit XtCVunit Float "1.0" XtNlocation XtCLocation String NULL .TE .ps .ps-2 .TS center box; cBsss lB|lB|lB|lB l|l|l|l. XfwfFrame Name Class Type Default XtNcursor XtCCursor Cursor None XtNframeType XtCFrameType FrameType XfwfRaised XtNframeWidth XtCFrameWidth Dimension 0 XtNouterOffset XtCOuterOffset Dimension 0 XtNinnerOffset XtCInnerOffset Dimension 0 XtNshadowScheme XtCShadowScheme ShadowScheme XfwfAuto XtNtopShadowColor XtCTopShadowColor Pixel compute_topcolor XtNbottomShadowColor XtCBottomShadowColor Pixel compute_bottomcolor XtNtopShadowStipple XtCTopShadowStipple Bitmap NULL XtNbottomShadowStipple XtCBottomShadowStipple Bitmap NULL .TE .ps .ps-2 .TS center box; cBsss lB|lB|lB|lB l|l|l|l. XfwfCommon Name Class Type Default XtNtraversalOn XtCTraversalOn Boolean True XtNhighlightThickness XtCHighlightThickness Dimension 2 XtNhighlightColor XtCHighlightColor Pixel XtDefaultForeground XtNhighlightPixmap XtCHighlightPixmap Pixmap None XtNnextTop XtCNextTop Callback NULL XtNuserData XtCUserData Pointer NULL .TE .ps .ps-2 .TS center box; cBsss lB|lB|lB|lB l|l|l|l. Composite Name Class Type Default XtNchildren XtCChildren WidgetList NULL insertPosition XtCInsertPosition XTOrderProc NULL numChildren XtCNumChildren Cardinal 0 .TE .ps .ps-2 .TS center box; cBsss lB|lB|lB|lB l|l|l|l. Core Name Class Type Default XtNx XtCX Position 0 XtNy XtCY Position 0 XtNwidth XtCWidth Dimension 0 XtNheight XtCHeight Dimension 0 borderWidth XtCBorderWidth Dimension 0 XtNcolormap XtCColormap Colormap NULL XtNdepth XtCDepth Int 0 destroyCallback XtCDestroyCallback XTCallbackList NULL XtNsensitive XtCSensitive Boolean True XtNtm XtCTm XTTMRec NULL ancestorSensitive XtCAncestorSensitive Boolean False accelerators XtCAccelerators XTTranslations NULL borderColor XtCBorderColor Pixel 0 borderPixmap XtCBorderPixmap Pixmap NULL background XtCBackground Pixel 0 backgroundPixmap XtCBackgroundPixmap Pixmap NULL mappedWhenManaged XtCMappedWhenManaged Boolean True XtNscreen XtCScreen Screen * NULL .TE .ps .hi .SH "Importss" .nf .B incl "stip4.bm" .fi .nf .B incl .fi .nf .B incl .fi .hi .hi .SS "Private variables" For faster drawing, the number of lines in the text is stored in a private variable by the \fIset_values\fP and \fIinitialize\fP methods. .nf int nlines .fi The tablist is converted from string format to a list of int's for speed. .nf int * tabs .fi For drawing the text, this GC is used. .nf GC gc .fi This GC is for the text that is drawn in reverse video. .nf GC rv_gc .fi For graying out the text, another GC is used. .nf GC graygc .fi When the \fIshrinkToFit\fP resource is set, we need the minimum area necessary for the complete label to be visible. \fIlabel_width\fP and \fIlabel_height\fP include the size of \fImargin\fP. .nf Dimension label_width .fi .nf Dimension label_height .fi .hi .hi .SS "Methods" The new method \fIset_label\fP makes a copy of the string that is passed in, counts the number of lines and also draws the new label. This could have been done in \fIset_values\fP, but it is expected that subclasses will redraw the label frequently, so a more efficient way is provided. Note that this method does not resize the widget in case \fIshrinkToFit\fP is set. .nf set_label($, String newlabel) { Position x, y; Dimension w, h; XtFree($label); $label = XtNewString(newlabel); count_lines($); if (XtIsRealized($)) { $compute_inside($, x, y, w, h); XClearArea(XtDisplay($), XtWindow($), x, y, w, h, True); /* $expose($, NULL, NULL); */ } } .fi The \fIset_values\fP method checks the \fIbackground\fP resource, because is is used in the GC \fIgraygc\fP. When the text or the font change, the private variables \fInlines\fP, \fIlabel_height\fP and \fIlabel_width\fP are updated. \fIneed_count\fP is set to \fITrue\fP if the size of the label changes. \fIneed_count\fP implies \fIneed_redisplay\fP. .nf Boolean set_values(Widget old, Widget request, $, ArgList args, Cardinal * num_args) { Boolean need_redisplay = False, need_count = False; Position x, y; Dimension w, h, wd, ht; if ($background_pixel != $old$background_pixel) make_graygc($); if ($tablist != $old$tablist) { XtFree((String) $old$tabs); $tabs = XfwfTablist2Tabs($tablist); if ($label != NULL) need_count = True; } if ($font != $old$font) { make_gc($); if ($label != NULL) need_count = True; } if ($foreground != $old$foreground || $background_pixel != $old$background_pixel) { make_gc($); if ($label != NULL) need_redisplay = True; } if ($topMargin != $old$topMargin || $bottomMargin != $old$bottomMargin || $leftMargin != $old$leftMargin || $rightMargin != $old$rightMargin) need_count = True; if ($sensitive != $old$sensitive) if ($label != NULL) need_redisplay = True; if ($rvStart != $old$rvStart || $rvLength != $old$rvLength) if ($label != NULL) need_redisplay = True; if ($label != $old$label) { XtFree($old$label); $label = XtNewString($label); need_count = True; } if (need_count) { count_lines($); need_redisplay = True; } if (need_count $shrinkToFit) { $compute_inside($, x, y, w, h); wd = $label_width + $width - w; ht = $label_height + $height - h; if (wd != $width || ht != $height) { $set_abs_location($, CWWidth | CWHeight, 0, 0, wd, ht); need_redisplay = False; } } return need_redisplay; } .fi The \fIinitialize\fP methods creates the first GC's and initializes the private variables. It sets the GC's to \fINULL\fP and calls two utility routines to actually create them. .nf initialize(Widget request, $, ArgList args, Cardinal * num_args) { char *s; Position x, y; Dimension w, h, wd, ht; if ($label) $label = XtNewString($label); count_lines($); $gc = NULL; $rv_gc = NULL; $graygc = NULL; make_gc($); make_graygc($); $tabs = XfwfTablist2Tabs($tablist); if ($shrinkToFit) { $compute_inside($, x, y, w, h); wd = $label_width + $width - w; ht = $label_height + $height - h; $set_abs_location($, CWWidth | CWHeight, 0, 0, wd, ht); } } .fi The \fIexpose\fP method is responsible for drawing the text. The text is put in the position given in \fIalignment\fP. The text is always kept within the frame. If necessary, the text is clipped. The routine ends by calling the \fIexpose\fP method from the superclass, which is responsible for drawing the frame. The part of the text that is to appear in reverse video is drawn with the \fIrv_gc\fP GC. \fBdef\fP draw_line(dpy, win, from, to) = do { if ($rvStart >= to) rstart = to; else rstart = max($rvStart, from); if ($rvStart + $rvLength <= from) rend = rstart; else rend = min($rvStart + $rvLength, to); w1 = XfwfTextWidth($font, $label + from, rstart - from, $tabs); w2 = XfwfTextWidth($font, $label + rstart, rend - rstart, $tabs); w3 = XfwfTextWidth($font, $label + rend, to - rend, $tabs); if ($alignment XfwfLeft) x = rect.x; else if ($alignment XfwfRight) x = rect.x + rect.width - w1 - w2 - w3; else x = rect.x + (rect.width - w1 - w2 - w3)/2; if (w1) XfwfDrawImageString(dpy, win, $gc, x, y, $label + from, rstart - from, $tabs); if (w2) XfwfDrawImageString(dpy, win, $rv_gc, x + w1, y, $label + rstart, rend - rstart, $tabs); if (w3) XfwfDrawImageString(dpy, win, $gc, x + w1 + w2, y, $label + rend, to - rend, $tabs); }while (0 ) .nf expose($, XEvent * event, Region region) { Region reg; XRectangle rect; int baseline; int w1, w2, w3; char *s, *t; int x, y, i, j, rstart, rend; if (! XtIsRealized($)) return; #expose($, event, region); if ($label != NULL) { baseline = $font->ascent + $font->descent; $compute_inside($, rect.x, rect.y, rect.width, rect.height); rect.x += $leftMargin; rect.width -= $leftMargin + $rightMargin; rect.y += $topMargin; rect.height -= $topMargin + $bottomMargin; reg = XCreateRegion(); XUnionRectWithRegion(rect, reg, reg); if (region != NULL) XIntersectRegion(region, reg, reg); XSetRegion(XtDisplay($), $gc, reg); XSetRegion(XtDisplay($), $rv_gc, reg); if ($alignment XfwfTop) y = rect.y + $font->ascent; else if ($alignment XfwfBottom) y = rect.y + rect.height - $nlines * baseline + $font->ascent; else y = rect.y + (rect.height - $nlines * baseline)/2 + $font->ascent; for (i = 0, j = 0; $label[i]; i++) { if ($label[i] == '\\n') { draw_line(XtDisplay($), XtWindow($), j, i); j = i + 1; y += baseline; } } draw_line(XtDisplay($), XtWindow($), j, i); /* Gray out if not sensitive */ if (! $sensitive) { XSetRegion(XtDisplay($), $graygc, reg); XFillRectangle(XtDisplay($), XtWindow($), $graygc, rect.x, rect.y, rect.width, rect.height); XSetClipMask(XtDisplay($), $graygc, None); } XSetClipMask(XtDisplay($), $gc, None); XSetClipMask(XtDisplay($), $rv_gc, None); } } .fi .hi .hi .SH "Utilities" The \fImake_gc\fP routine creates the GC for the text. .nf make_gc($) { XtGCMask mask; XGCValues values; if ($gc != NULL) XtReleaseGC($, $gc); values.background = $background_pixel; values.foreground = $foreground; values.font = $font->fid; mask = GCFont | GCBackground | GCForeground; $gc = XtGetGC($, mask, values); if ($rv_gc != NULL) XtReleaseGC($, $rv_gc); values.foreground = $background_pixel; values.background = $foreground; values.font = $font->fid; mask = GCFont | GCBackground | GCForeground; $rv_gc = XtGetGC($, mask, values); } .fi The \fImake_graygc\fP routine creates a GC for graying out the text. It contains a stipple in the background color, that will be applied over the text. .nf make_graygc($) { XtGCMask mask; XGCValues values; if ($graygc != NULL) XtReleaseGC($, $graygc); values.foreground = $background_pixel; values.stipple = XCreateBitmapFromData(XtDisplay($), RootWindowOfScreen(XtScreen($)), stip4_bits, stip4_width, stip4_height); values.fill_style = FillStippled; mask = GCForeground | GCStipple | GCFillStyle; $graygc = XtGetGC($, mask, values); } .fi The funtion \fIcount_lines\fP computes the correct values for the private variables \fInlines\fP, \fIlabel_width\fP and \fIlabel_height\fP. .nf count_lines($) { String p, s; int w; $nlines = 0; $label_width = 0; if ($label) { for (p = $label, $nlines = 1, s = $label; *s; s++) { if (*s == '\\n') { $nlines++; w = XfwfTextWidth($font, p, s - p, $tabs); p = s + 1; if (w > $label_width) $label_width = w; } } w = XfwfTextWidth($font, p, s - p, $tabs); if (w > $label_width) $label_width = w; } $label_height = $nlines * ($font->ascent + $font->descent); $label_width += $leftMargin + $rightMargin; $label_height += $topMargin + $bottomMargin; } .fi .hi