/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): */ /*----------------------------------------------------------------------*/ /* */ /* Name: */ /* Description: XfeLabel widget source. */ /* Author: Ramiro Estrugo */ /* */ /*----------------------------------------------------------------------*/ #include #if 0 #include #endif /*----------------------------------------------------------------------*/ /* */ /* Warnings and messages */ /* */ /*----------------------------------------------------------------------*/ #define MESSAGE1 "Widget is not a XfeLabel." #define MESSAGE2 "If XmNtruncateLabel is true, XmNtruncateProc cannot be NULL." #define MESSAGE3 "Cannot edit label because parent is not XfeToolBar." #define INSENSITIVE_OFFSET 1 /*----------------------------------------------------------------------*/ /* */ /* Core class methods */ /* */ /*----------------------------------------------------------------------*/ static void ClassPartInit (WidgetClass); static void Initialize (Widget,Widget,ArgList,Cardinal *); static void Destroy (Widget); static Boolean SetValues (Widget,Widget,Widget,ArgList,Cardinal *); static void GetValuesHook (Widget,ArgList,Cardinal *); /*----------------------------------------------------------------------*/ /* */ /* XfePrimitive class methods */ /* */ /*----------------------------------------------------------------------*/ static void PreferredGeometry (Widget,Dimension *,Dimension *); static void PrepareComponents (Widget,int); static void LayoutComponents (Widget); static void DrawComponents (Widget,XEvent *,Region,XRectangle *); /*----------------------------------------------------------------------*/ /* */ /* XfeLabel class methods */ /* */ /*----------------------------------------------------------------------*/ static void LayoutString (Widget); static void DrawString (Widget,XEvent *,Region,XRectangle *); static void DrawSelection (Widget,XEvent *,Region,XRectangle *); static GC GetLabelGC (Widget); static GC GetSelectionGC (Widget); /*----------------------------------------------------------------------*/ /* */ /* Misc XfeLabel functions */ /* */ /*----------------------------------------------------------------------*/ static XmString CreateTruncatedString (Widget); static void InvokeSelectionChangedCallback (Widget,XEvent *); /*----------------------------------------------------------------------*/ /* */ /* XfeLabel Resources */ /* */ /*----------------------------------------------------------------------*/ static XtResource resources[] = { /* Callback resources */ { XmNselectionChangedCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XfeLabelRec , xfe_label . selection_changed_callback), XmRImmediate, (XtPointer) NULL }, /* Label resources */ { XmNlabelAlignment, XmCLabelAlignment, XmRAlignment, sizeof(unsigned char), XtOffsetOf(XfeLabelRec , xfe_label . label_alignment), XmRImmediate, (XtPointer) XmALIGNMENT_CENTER }, { XmNlabelDirection, XmCLabelDirection, XmRStringDirection, sizeof(unsigned char), XtOffsetOf(XfeLabelRec , xfe_label . label_direction), XmRImmediate, (XtPointer) XmSTRING_DIRECTION_L_TO_R }, { XmNfontList, XmCFontList, XmRFontList, sizeof(XmFontList), XtOffsetOf(XfeLabelRec , xfe_label . font_list), XmRImmediate, (XtPointer) NULL }, { XmNlabelString, XmCLabelString, XmRXmString, sizeof(XmString), XtOffsetOf(XfeLabelRec , xfe_label . label_string), XmRImmediate, (XtPointer) NULL }, /* Truncation resources */ { XmNtruncateLabel, XmCTruncateLabel, XmRBoolean, sizeof(Boolean), XtOffsetOf(XfeLabelRec , xfe_label . truncate_label), XmRImmediate, (XtPointer) False }, { XmNtruncateProc, XmCTruncateProc, XmRProc, sizeof(XtPointer), XtOffsetOf(XfeLabelRec , xfe_label . truncate_proc), XmRImmediate, (XtPointer) NULL }, /* Selection resources */ { XmNselected, XmCSelected, XmRBoolean, sizeof(Boolean), XtOffsetOf(XfeLabelRec , xfe_label . selected), XmRImmediate, (XtPointer) False }, { XmNselectionColor, XmCSelectionColor, XmRPixel, sizeof(Pixel), XtOffsetOf(XfeLabelRec , xfe_label . selection_color), XmRCallProc, (XtPointer) _XfeCallProcSelectPixel }, { XmNselectionModifiers, XmCSelectionModifiers, XmRModifiers, sizeof(Modifiers), XtOffsetOf(XfeLabelRec , xfe_label . selection_modifiers), XmRImmediate, (XtPointer) None }, /* Edit resources */ { XmNeditModifiers, XmCEditModifiers, XmRModifiers, sizeof(Modifiers), XtOffsetOf(XfeLabelRec , xfe_label . edit_modifiers), XmRImmediate, (XtPointer) None }, /* Force XmNbufferType to XmBUFFER_SHARED */ { XmNbufferType, XmCBufferType, XmRBufferType, sizeof(unsigned char), XtOffsetOf(XfeLabelRec , xfe_primitive . buffer_type), XmRImmediate, (XtPointer) XmBUFFER_SHARED }, /* Force XmNtraversalOn to False */ { XmNtraversalOn, XmCTraversalOn, XmRBoolean, sizeof(Boolean), XtOffsetOf(XfeLabelRec , primitive . traversal_on), XmRImmediate, (XtPointer) False }, /* Force XmNhighlightThickness to 0 */ { XmNhighlightThickness, XmCHighlightThickness, XmRHorizontalDimension, sizeof(Dimension), XtOffsetOf(XfeLabelRec , primitive . highlight_thickness), XmRImmediate, (XtPointer) 0 }, }; /*----------------------------------------------------------------------*/ /* */ /* XfeLabel translations */ /* */ /*----------------------------------------------------------------------*/ static char default_translations[] ="\ : Btn1Down()\n\ c: Focus()\n\ :osfHelp: Help()\n\ : Enter()\n\ : Leave()"; /*----------------------------------------------------------------------*/ /* */ /* XfeButton actions */ /* */ /*----------------------------------------------------------------------*/ static XtActionsRec actions[] = { { "Btn1Down", _XfeLabelBtn1Down }, }; /*----------------------------------------------------------------------*/ /* */ /* XfeLabel widget class record initialization */ /* */ /*----------------------------------------------------------------------*/ _XFE_WIDGET_CLASS_RECORD(label,Label) = { { /* Core Part */ (WidgetClass) &xfePrimitiveClassRec, /* superclass */ "XfeLabel", /* class_name */ sizeof(XfeLabelRec), /* widget_size */ NULL, /* class_initialize */ ClassPartInit, /* class_part_initialize*/ FALSE, /* class_inited */ Initialize, /* initialize */ NULL, /* initialize_hook */ XtInheritRealize, /* realize */ actions, /* actions */ XtNumber(actions), /* num_actions */ (XtResource *)resources, /* resources */ XtNumber(resources), /* num_resources */ NULLQUARK, /* xrm_class */ TRUE, /* compress_motion */ XtExposeCompressMaximal, /* compress_exposure */ TRUE, /* compress_enterleave */ FALSE, /* visible_interest */ Destroy, /* destroy */ XtInheritResize, /* resize */ XtInheritExpose, /* expose */ SetValues, /* set_values */ NULL, /* set_values_hook */ XtInheritSetValuesAlmost, /* set_values_almost */ GetValuesHook, /* get_values_hook */ NULL, /* accept_focus */ XtVersion, /* version */ NULL, /* callback_private */ default_translations, /* tm_table */ XtInheritQueryGeometry, /* query_geometry */ XtInheritDisplayAccelerator, /* display accel */ NULL, /* extension */ }, /* XmPrimitive Part */ { XmInheritBorderHighlight, /* border_highlight */ XmInheritBorderUnhighlight, /* border_unhighlight */ XtInheritTranslations, /* translations */ NULL, /* arm_and_activate */ NULL, /* syn resources */ 0, /* num syn_resources */ NULL, /* extension */ }, /* XfePrimitive Part */ { XfeInheritBitGravity, /* bit_gravity */ PreferredGeometry, /* preferred_geometry */ XfeInheritUpdateBoundary, /* update_boundary */ PrepareComponents, /* prepare_components */ LayoutComponents, /* layout_components */ XfeInheritDrawBackground, /* draw_background */ XfeInheritDrawShadow, /* draw_shadow */ DrawComponents, /* draw_components */ NULL, /* extension */ }, /* XfeLabel Part */ { LayoutString, /* layout_string */ DrawString, /* draw_string */ DrawSelection, /* draw_selection */ GetLabelGC, /* get_label_gc */ GetSelectionGC, /* get_selection_gc */ NULL, /* extension */ }, }; /*----------------------------------------------------------------------*/ /* */ /* xfeLabelWidgetClass declaration. */ /* */ /*----------------------------------------------------------------------*/ _XFE_WIDGET_CLASS(label,Label); /*----------------------------------------------------------------------*/ /* */ /* Core class methods */ /* */ /*----------------------------------------------------------------------*/ static void ClassPartInit(WidgetClass wc) { XfeLabelWidgetClass cc = (XfeLabelWidgetClass) wc; XfeLabelWidgetClass sc = (XfeLabelWidgetClass) wc->core_class.superclass; /* Resolve inheritance of all XfeLabel class methods */ _XfeResolve(cc,sc,xfe_label_class,layout_string, XfeInheritLayoutString); _XfeResolve(cc,sc,xfe_label_class,draw_string, XfeInheritDrawString); _XfeResolve(cc,sc,xfe_label_class,draw_selection, XfeInheritDrawSelection); _XfeResolve(cc,sc,xfe_label_class,get_label_gc, XfeInheritGetLabelGC); _XfeResolve(cc,sc,xfe_label_class,get_selection_gc, XfeInheritGetSelectionGC); } /*----------------------------------------------------------------------*/ static void Initialize(Widget rw,Widget nw,ArgList args,Cardinal *nargs) { XfeLabelPart * lp = _XfeLabelPart(nw); /* Make sure rep types are ok */ XfeRepTypeCheck(nw,XmRAlignment,&lp->label_alignment, XmALIGNMENT_CENTER); XfeRepTypeCheck(nw,XmRStringDirection,&lp->label_direction, XmSTRING_DIRECTION_L_TO_R); /* Make sure the label is set up properly */ lp->label_string = XfeXmStringCopy(nw,lp->label_string,XtName(nw)); /* Make sure the font list is set up properly */ lp->font_list = XfeXmFontListCopy(nw,lp->font_list,XmLABEL_FONTLIST); /* Allocate the label GCs */ lp->label_GC = XfeAllocateStringGc(nw,lp->font_list, _XfeForeground(nw),None,True); /* Allocate the label insensitive GCs */ lp->insensitive_top_GC = XfeAllocateStringGc(nw,lp->font_list, _XfeTopShadowColor(nw), None,True); lp->insensitive_bottom_GC = XfeAllocateStringGc(nw,lp->font_list, _XfeBottomShadowColor(nw), None,True); /* Allocate the selection GCs */ lp->selection_GC = XfeAllocateColorGc(nw,lp->selection_color,None,True); /* Initialize private members */ lp->misc_offset = 0; /* Finish of initialization */ _XfePrimitiveChainInitialize(rw,nw,xfeLabelWidgetClass); } /*----------------------------------------------------------------------*/ static void Destroy(Widget w) { XfeLabelPart * lp = _XfeLabelPart(w); /* Release GCs */ XtReleaseGC(w,lp->label_GC); XtReleaseGC(w,lp->insensitive_top_GC); XtReleaseGC(w,lp->insensitive_bottom_GC); XtReleaseGC(w,lp->selection_GC); /* Free the label string */ XmStringFree(lp->label_string); /* Free the font list */ XmFontListFree(lp->font_list); } /*----------------------------------------------------------------------*/ static Boolean SetValues(Widget ow,Widget rw,Widget nw,ArgList args,Cardinal *nargs) { XfeLabelPart * np = _XfeLabelPart(nw); XfeLabelPart * op = _XfeLabelPart(ow); Boolean label_gc_flag = False; Boolean selection_gc_flag = False; Boolean insensitive_top_gc_flag = False; Boolean insensitive_bottom_gc_flag = False; /* font_list */ if (np->font_list != op->font_list) { /* Make sure the new font is ok */ np->font_list = XfeXmFontListCopy(nw,np->font_list,XmLABEL_FONTLIST); /* Free the old fontlist */ if (op->font_list) { XmFontListFree(op->font_list); } label_gc_flag = True; insensitive_bottom_gc_flag = True; insensitive_top_gc_flag = True; _XfeConfigFlags(nw) |= XfeConfigGLE; _XfePrepareFlags(nw) |= _XFE_PREPARE_LABEL_STRING; } /* label_string */ if (np->label_string != op->label_string) { /* Free the old string if needed */ if (op->label_string) { XmStringFree(op->label_string); } /* Make sure the new string is ok */ np->label_string = XfeXmStringCopy(nw,np->label_string,XtName(nw)); _XfeConfigFlags(nw) |= XfeConfigGLE; _XfePrepareFlags(nw) |= _XFE_PREPARE_LABEL_STRING; } /* foreground */ if (_XfeForeground(nw) != _XfeForeground(ow)) { label_gc_flag = True; _XfeConfigFlags(nw) |= XfeConfigExpose; } /* bottom_shadow_color */ if (_XfeBottomShadowColor(nw) != _XfeBottomShadowColor(ow)) { insensitive_bottom_gc_flag = True; if (!_XfeIsSensitive(nw)) { _XfeConfigFlags(nw) |= XfeConfigExpose; } } /* top_shadow_color */ if (_XfeTopShadowColor(nw) != _XfeTopShadowColor(ow)) { insensitive_top_gc_flag = True; if (!_XfeIsSensitive(nw)) { _XfeConfigFlags(nw) |= XfeConfigExpose; } } /* label_alignment */ if (np->label_alignment != op->label_alignment) { /* Make sure the new label alignment is ok */ XfeRepTypeCheck(nw,XmRAlignment,&np->label_alignment, XmALIGNMENT_CENTER); _XfeConfigFlags(nw) |= XfeConfigLE; } /* label_direction */ if (np->label_direction != op->label_direction) { /* Make sure the new label direction is ok */ XfeRepTypeCheck(nw,XmRStringDirection,&np->label_direction, XmSTRING_DIRECTION_L_TO_R); _XfeConfigFlags(nw) |= XfeConfigExpose; } /* selected */ if (np->selected != op->selected) { _XfeConfigFlags(nw) |= XfeConfigExpose; } /* selection_color */ if (np->selection_color != op->selection_color) { selection_gc_flag = True; _XfeConfigFlags(nw) |= XfeConfigExpose; } /* Update the label GC */ if (label_gc_flag) { /* Release the old label GC */ XtReleaseGC(nw,np->label_GC); /* Allocate the new label GC */ np->label_GC = XfeAllocateStringGc(nw,np->font_list, _XfeForeground(nw),None,True); } /* Update the selection GC */ if (selection_gc_flag) { /* Release the old selection GC */ XtReleaseGC(nw,np->selection_GC); /* Allocate the new selection GC */ np->selection_GC = XfeAllocateColorGc(nw,np->selection_color, None,True); } /* Update the insens top GC */ if (insensitive_top_gc_flag) { /* Release the old label GC */ XtReleaseGC(nw,np->insensitive_top_GC); /* Allocate the new label GC */ np->insensitive_top_GC = XfeAllocateStringGc(nw,np->font_list, _XfeTopShadowColor(nw), None,True); } /* Update the insens bottom GC */ if (insensitive_bottom_gc_flag) { /* Release the old label GC */ XtReleaseGC(nw,np->insensitive_bottom_GC); /* Allocate the new label GC */ np->insensitive_bottom_GC = XfeAllocateStringGc(nw,np->font_list, _XfeBottomShadowColor(nw), None,True); } return _XfePrimitiveChainSetValues(ow,rw,nw,xfeLabelWidgetClass); } /*----------------------------------------------------------------------*/ static void GetValuesHook(Widget w,ArgList av,Cardinal * pav) { XfeLabelPart * lp = _XfeLabelPart(w); Cardinal i; for (i = 0; i < *pav; i++) { /* XmNlabelString */ if (strcmp(av[i].name,XmNlabelString) == 0) { XmString label_copy = XmStringCopy(lp->label_string); /* av[i] = label_copy */ _XfeGetValuesCastAndAssign(av,i,label_copy); } /* XmNfontList */ else if (strcmp(av[i].name,XmNfontList) == 0) { XmFontList font_copy = XmFontListCopy(lp->font_list); /* av[i] = font_copy */ _XfeGetValuesCastAndAssign(av,i,font_copy); } } } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* XfePrimitive methods */ /* */ /*----------------------------------------------------------------------*/ static void PreferredGeometry(Widget w,Dimension *width,Dimension *height) { XfeLabelPart * lp = _XfeLabelPart(w); *width = _XfeOffsetLeft(w) + _XfeOffsetRight(w) + lp->label_rect.width; *height = _XfeOffsetTop(w) + _XfeOffsetBottom(w) + lp->label_rect.height; } /*----------------------------------------------------------------------*/ static void PrepareComponents(Widget w,int flags) { if (flags & _XFE_PREPARE_LABEL_STRING) { XfeLabelPart * lp = _XfeLabelPart(w); /* Obtain the labels's dimensions */ XmStringExtent(lp->font_list, lp->label_string, &lp->label_rect.width, &lp->label_rect.height); } } /*----------------------------------------------------------------------*/ static void LayoutComponents(Widget w) /*----------------------------------------------------------------------*/ { /* Invoke layout_string method */ _XfeLabelLayoutString(w); } /*----------------------------------------------------------------------*/ static void DrawComponents(Widget w,XEvent *event,Region region,XRectangle * clip_rect) { /* Invoke draw_selection method */ _XfeLabelDrawSelection(w,event,region,clip_rect); /* Invoke draw_string method */ _XfeLabelDrawString(w,event,region,clip_rect); } /*----------------------------------------------------------------------*/ static GC GetLabelGC(Widget w) { XfeLabelPart * lp = _XfeLabelPart(w); return lp->label_GC; } /*----------------------------------------------------------------------*/ static GC GetSelectionGC(Widget w) { XfeLabelPart * lp = _XfeLabelPart(w); return lp->selection_GC; } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* XfeLabel methods */ /* */ /*----------------------------------------------------------------------*/ static void LayoutString(Widget w) /*----------------------------------------------------------------------*/ { XfeLabelPart * lp = _XfeLabelPart(w); /* Layout the label according to the alignment */ switch(lp->label_alignment) { case XmALIGNMENT_BEGINNING: lp->label_rect.x = _XfeBoundaryX(w); break; case XmALIGNMENT_CENTER: lp->label_rect.x = (_XfeWidth(w) - lp->label_rect.width) / 2; break; case XmALIGNMENT_END: lp->label_rect.x = XfeWidth(w) - lp->label_rect.width - _XfeOffsetRight(w); break; } /* the label is always centered vertically */ lp->label_rect.y = (_XfeHeight(w) - lp->label_rect.height) / 2; } /*----------------------------------------------------------------------*/ static void DrawString(Widget w,XEvent * event,Region region,XRectangle * clip_rect) { XfeLabelPart * lp = _XfeLabelPart(w); XRectangle rect; XmString string = NULL; Boolean need_to_free_string = False; /* Make sure the label has something before drawing */ if (!lp->label_rect.width || !lp->label_rect.height || !lp->label_string) { return; } /* The height and y coordinate are the same regardless of truncation */ rect.height = lp->label_rect.height; rect.y = lp->label_rect.y; /* Determine whether we need to truncate the string */ if (lp->truncate_label && (lp->label_rect.width > _XfeBoundaryWidth(w))) { string = CreateTruncatedString(w); rect.width = _XfeBoundaryWidth(w); rect.x = _XfeBoundaryX(w); need_to_free_string = True; } else { string = lp->label_string; rect.width = lp->label_rect.width; rect.x = lp->label_rect.x; need_to_free_string = False; } assert( string != NULL ); /* Determine which gc to use to render the label */ if (_XfeIsSensitive(w)) { /* Draw the string once */ XmStringDraw(XtDisplay(w), _XfePrimitiveDrawable(w), lp->font_list, string, _XfeLabelGetLabelGC(w), rect.x + lp->misc_offset, rect.y + lp->misc_offset, rect.width, lp->label_alignment, lp->label_direction, &_XfeBoundary(w)); } else { /* Draw the string twice to achieve that cool insensitve look */ XmStringDraw(XtDisplay(w), _XfePrimitiveDrawable(w), lp->font_list, string, lp->insensitive_top_GC, rect.x + INSENSITIVE_OFFSET + lp->misc_offset, rect.y + INSENSITIVE_OFFSET + lp->misc_offset, rect.width, lp->label_alignment, lp->label_direction, &_XfeBoundary(w)); XmStringDraw(XtDisplay(w), _XfePrimitiveDrawable(w), lp->font_list, string, lp->insensitive_bottom_GC, rect.x + lp->misc_offset, rect.y + lp->misc_offset, rect.width, lp->label_alignment, lp->label_direction, &_XfeBoundary(w)); } /* Free the string if needed */ if (need_to_free_string) { XmStringFree(string); } } /*----------------------------------------------------------------------*/ static void DrawSelection(Widget w,XEvent * event,Region region,XRectangle * clip_rect) { XfeLabelPart * lp = _XfeLabelPart(w); Dimension dx; Dimension dy; /* Make sure the widget is selected */ if (!lp->selected) { return; } /* Make sure the label has something before drawing */ if (!lp->label_rect.width || !lp->label_rect.height || !lp->label_string) { return; } /* Compute the extra offset for the selection */ dx = XfeMin(_XfeMarginLeft(w),_XfeMarginRight(w)); dx = XfeMin(dx,1); dy = XfeMin(_XfeMarginTop(w),_XfeMarginBottom(w)); dy = XfeMin(dy,1); XFillRectangle(XtDisplay(w), _XfePrimitiveDrawable(w), _XfeLabelGetSelectionGC(w), lp->label_rect.x - dx, lp->label_rect.y - dy, lp->label_rect.width + 2 * dx, lp->label_rect.height + 2 * dy); } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* XfeLabel Method invocation functions */ /* */ /*----------------------------------------------------------------------*/ /* extern */ void _XfeLabelLayoutString(Widget w) { XfeLabelWidgetClass lc = (XfeLabelWidgetClass) XtClass(w); if (lc->xfe_label_class.layout_string) { (*lc->xfe_label_class.layout_string)(w); } } /*----------------------------------------------------------------------*/ /* extern */ void _XfeLabelDrawString(Widget w, XEvent * event, Region region, XRectangle * clip_rect) { XfeLabelWidgetClass lc = (XfeLabelWidgetClass) XtClass(w); if (lc->xfe_label_class.draw_string) { (*lc->xfe_label_class.draw_string)(w,event,region,clip_rect); } } /*----------------------------------------------------------------------*/ /* extern */ void _XfeLabelDrawSelection(Widget w, XEvent * event, Region region, XRectangle * clip_rect) { XfeLabelWidgetClass lc = (XfeLabelWidgetClass) XtClass(w); if (lc->xfe_label_class.draw_selection) { (*lc->xfe_label_class.draw_selection)(w,event,region,clip_rect); } } /*----------------------------------------------------------------------*/ /* extern */ GC _XfeLabelGetLabelGC(Widget w) { XfeLabelWidgetClass lc = (XfeLabelWidgetClass) XtClass(w); assert( lc->xfe_label_class.get_label_gc != NULL ); return (*lc->xfe_label_class.get_label_gc)(w); } /*----------------------------------------------------------------------*/ /* extern */ GC _XfeLabelGetSelectionGC(Widget w) { XfeLabelWidgetClass lc = (XfeLabelWidgetClass) XtClass(w); assert( lc->xfe_label_class.get_selection_gc != NULL ); return (*lc->xfe_label_class.get_selection_gc)(w); } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* Misc XfeLabel functions */ /* */ /*----------------------------------------------------------------------*/ static XmString CreateTruncatedString(Widget w) { XfeLabelPart * lp = _XfeLabelPart(w); XmString result = NULL; /* Make sure the truncate proc is good */ if (lp->truncate_proc) { String psz_tmp; /* Access the label as a psz String */ XmStringGetLtoR(lp->label_string,XmFONTLIST_DEFAULT_TAG,&psz_tmp); if (psz_tmp) { Dimension max_width = _XfeBoundaryWidth(w) - lp->misc_offset; if (!_XfeIsSensitive(w)) { max_width -= 1; } /* Create a truncated string */ result = (*lp->truncate_proc)(psz_tmp, XmFONTLIST_DEFAULT_TAG, lp->font_list, max_width); /* Free the psz String */ XtFree(psz_tmp); } } else { _XfeWarning(w,MESSAGE2); } return result; } /*----------------------------------------------------------------------*/ static void InvokeSelectionChangedCallback(Widget w,XEvent * event) { XfeLabelPart * lp = _XfeLabelPart(w); /* Invoke the callbacks only if needed */ if (lp->selection_changed_callback) { XfeLabelSelectionChangedCallbackStruct cbs; cbs.event = event; cbs.reason = XmCR_SELECTION_CHANGED; cbs.selected = lp->selected; /* Flush the display */ XFlush(XtDisplay(w)); /* Invoke the Callback List */ XtCallCallbackList(w,lp->selection_changed_callback,&cbs); } } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* XfeLabel action procedures */ /* */ /*----------------------------------------------------------------------*/ /* extern */ void _XfeLabelBtn1Down(Widget w,XEvent * event,char ** params,Cardinal * nparams) { XfeLabelPart * lp = _XfeLabelPart(w); /* Make sure we are not pretending to be insensitive */ if (!_XfeIsSensitive(w)) { return; } /* Look for modifiers that matche the selection modifiers */ if (_XfeLabelAcceptSelectionEvent(w,event,True)) { _XfeLabelSetSelected(w,event,!lp->selected,True); return; } /* Look for modifiers that matche the edit modifiers */ if (_XfeLabelAcceptEditEvent(w,event,True)) { _XfeLabelEdit(w,event,params,nparams); } } /*----------------------------------------------------------------------*/ /* extern */ void _XfeLabelSelect(Widget w,XEvent * event,char ** params,Cardinal * nparams) { XfeLabelPart * lp = _XfeLabelPart(w); _XfeLabelSetSelected(w,event,!lp->selected,True); } /*----------------------------------------------------------------------*/ /* extern */ void _XfeLabelEdit(Widget w,XEvent * event,char ** params,Cardinal * nparams) { XfeLabelPart * lp = _XfeLabelPart(w); /* Add fancy edit stuff here */ assert( 0 ); #if 0 /* Make sure parent is XfeToolBar */ if (!XfeIsToolBar(_XfeParent(w))) { _XfeWarning(w,MESSAGE3); return; } /* Ask the toolbar to edit us */ XfeToolBarEditItem(_XfeParent(w), w, lp->label_rect.x, lp->label_rect.y, lp->label_rect.width, lp->label_rect.height); #endif } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* XfeLabel private functions */ /* */ /*----------------------------------------------------------------------*/ /* extern */ Boolean _XfeLabelAcceptSelectionEvent(Widget w,XEvent * event,Boolean inside_label) { XfeLabelPart * lp = _XfeLabelPart(w); Boolean result = False; /* Look for modifiers that matches the selection modifiers */ if ((XfeEventGetModifiers(event) & lp->selection_modifiers) || (lp->selection_modifiers == AnyModifier)) { /* Make sure the event's x,y occured inside the label if needed */ if (inside_label) { int x; int y; /* Determine if the pointer is in the label */ result = (XfeEventGetXY(event,&x,&y) && XfePointInRect(&lp->label_rect,x,y)); } else { result = True; } } return result; } /*----------------------------------------------------------------------*/ /* extern */ Boolean _XfeLabelAcceptEditEvent(Widget w,XEvent * event,Boolean inside_label) { XfeLabelPart * lp = _XfeLabelPart(w); Boolean result = False; /* Look for modifiers that matches the edit modifiers */ if ((XfeEventGetModifiers(event) & lp->edit_modifiers) || (lp->edit_modifiers == AnyModifier)) { /* Make sure the event's x,y occured inside the label if needed */ if (inside_label) { int x; int y; /* Determine if the pointer is in the label */ result = (XfeEventGetXY(event,&x,&y) && XfePointInRect(&lp->label_rect,x,y)); } else { result = True; } } return result; } /*----------------------------------------------------------------------*/ /* extern */ void _XfeLabelSetSelected(Widget w, XEvent * event, Boolean selected, Boolean invoke_callbacks) { XfeLabelPart * lp = _XfeLabelPart(w); assert( XfeIsLabel(w) ); /* Make sure the selection has changed */ if (lp->selected == selected) { return; } /* Assign the new selection */ lp->selected = selected; /* Make sure the widget is alive and kicking before drawing */ if (_XfeIsRealized(w) && _XfeIsManaged(w)) { /* Erase the old stuff */ _XfePrimitiveClearBackground(w); /* Redraw the buffer */ _XfePrimitiveDrawEverything(w,NULL,NULL); /* Draw the buffer onto the window */ XfeExpose(w,NULL,NULL); } /* Invoke the selection callbacks if needed */ if (invoke_callbacks) { InvokeSelectionChangedCallback(w,event); } } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /* */ /* XfeLabel Public Methods */ /* */ /*----------------------------------------------------------------------*/ /* extern */ Widget XfeCreateLabel(Widget pw,char * name,ArgList av,Cardinal ac) { return XtCreateWidget(name,xfeLabelWidgetClass,pw,av,ac); } /*----------------------------------------------------------------------*/ /* extern */ void XfeLabelSetString(Widget w,XmString xm_label) { XfeLabelPart * lp = _XfeLabelPart(w); assert( _XfeIsAlive(w) ); /* Make sure the label is different */ if (XmStringByteCompare(xm_label,lp->label_string)) { return; } /* Free the old string */ XmStringFree(lp->label_string); /* Make a copy of the given string or set it to "" if null */ if (xm_label) { lp->label_string = XfeXmStringCopy(w,xm_label,XtName(w)); } else { lp->label_string = XmStringCreate("",XmFONTLIST_DEFAULT_TAG); } /* Prepare the label */ _XfePrimitivePrepareComponents(w,_XFE_PREPARE_LABEL_STRING); /* Relayout the widget */ _XfePrimitiveLayoutComponents(w); /* Make sure the widget is realized before drawing anything */ if (!XtIsRealized(w)) { return; } /* Erase the old stuff */ _XfePrimitiveClearBackground(w); /* Redraw the buffer */ _XfePrimitiveDrawEverything(w,NULL,NULL); /* Draw the buffer onto the window */ XfeExpose(w,NULL,NULL); } /*----------------------------------------------------------------------*/ /* extern */ void XfeLabelSetStringPSZ(Widget w,String psz_label) { XfeLabelPart * lp = _XfeLabelPart(w); XmString xm_new_label; assert( _XfeIsAlive(w) ); /* Set the new string */ if (psz_label) { xm_new_label = XmStringCreate(psz_label,XmFONTLIST_DEFAULT_TAG); } else { xm_new_label = XmStringCreate("",XmFONTLIST_DEFAULT_TAG); } /* Make sure the label is different */ if (XmStringByteCompare(xm_new_label,lp->label_string)) { XmStringFree(xm_new_label); return; } /* Free the old string */ XmStringFree(lp->label_string); lp->label_string = xm_new_label; /* Prepare the label */ _XfePrimitivePrepareComponents(w,_XFE_PREPARE_LABEL_STRING); /* Relayout the widget */ _XfePrimitiveLayoutComponents(w); /* Make sure the widget is realized before drawing anything */ if (!XtIsRealized(w)) { return; } /* Erase the old stuff */ _XfePrimitiveClearBackground(w); /* Redraw the buffer */ _XfePrimitiveDrawEverything(w,NULL,NULL); /* Draw the buffer onto the window */ XfeExpose(w,NULL,NULL); } /*----------------------------------------------------------------------*/ /* extern */ void XfeLabelSetSelected(Widget w,Boolean selected) { assert( XfeIsLabel(w) ); _XfeLabelSetSelected(w,NULL,selected,False); } /*----------------------------------------------------------------------*/