1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* $TOG: MenuButton.c /main/9 1998/04/09 17:51:40 mgreess $
- *
- * (c) Copyright 1996 Digital Equipment Corporation.
- * (c) Copyright 1996 Hewlett-Packard Company.
- * (c) Copyright 1996 International Business Machines Corp.
- * (c) Copyright 1986, 1991, 1996 Sun Microsystems, Inc.
- * (c) Copyright 1996 Novell, Inc.
- * (c) Copyright 1996 FUJITSU LIMITED.
- * (c) Copyright 1996 Hitachi.
- */
- /*
- * Copyright (C) 1986,1991 Sun Microsystems, Inc
- * All rights reserved.
- * Notice of copyright on this source code
- * product does not indicate publication.
- *
- * RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by
- * the U.S. Government is subject to restrictions as set forth
- * in subparagraph (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software Clause at DFARS 252.227-7013 (Oct. 1988)
- * and FAR 52.227-19 (c) (June 1987).
- *
- * Sun Microsystems, Inc., 2550 Garcia Avenue,
- * Mountain View, California 94043.
- *
- */
- /*
- * The DtMenuButton widget is rigged with the Motif widget binary compatibilit
- * mechanism. All Motif-specific changes for this mechanism are preceded
- * by a comment including the string "MotifBc".
- *
- * For a description of the Motif widget binary compatibility mechanism
- * see the reference manual entry on XmResolveAllPartOffsets().
- *
- */
- #include <Dt/DtMsgsP.h>
- #include "MenuButtonP.h"
- #include <Xm/LabelP.h>
- #include <Xm/MenuUtilP.h>
- #include <Xm/DrawP.h>
- #include <Xm/XmP.h>
- #include <Xm/XmPrivate.h> /* _XmRecordEvent, _XmSetInDragMode, ... */
- #include <X11/keysymdef.h>
- #include "DtWidgetI.h"
- /*
- * MotifBc
- */
- #define DtMenuButtonIndex (XmLabelIndex + 1)
- static XmOffsetPtr ipot; /* Instance part offset table */
- static XmOffsetPtr cpot; /* Constraint part offset table */
- #ifndef Max
- #define Max(x, y) (((x) > (y)) ? (x) : (y))
- #endif
- #define GLYPH_PIX_SPACE 4 /* pixels between label and bit map */
- /*
- * MotifBc
- */
- #define CascadingCallback(w) XmField(w,ipot,DtMenuButton,cascading_callback,XtCallbackList)
- #define MenuRect(w) XmField(w,ipot,DtMenuButton,menu_rect,XRectangle)
- #define LNormalGC(w) XmField(w,ipot,XmLabel,normal_GC,GC)
- #define LAlignment(w) XmField(w,ipot,XmLabel,alignment,unsigned char)
- #define LRecomputeSize(w) XmField(w,ipot,XmLabel,recompute_size,Boolean)
- #define LLabelType(w) XmField(w,ipot,XmLabel,label_type,unsigned char)
- /* Access macro definitions */
- #define MB_PVT_SMENU(mb) XmField(mb,ipot,DtMenuButton,private_submenu,Boolean)
- #define MB_LAST_TIMESTAMP(mb) XmField(mb,ipot,DtMenuButton,last_timestamp,Time)
- #define MB_SMENU(mb) XmField(mb,ipot,DtMenuButton,submenu,Widget)
- #define MB_PIXMAP(mb) XmField(mb,ipot,DtMenuButton,menu_pixmap,Pixmap)
- #define MB_GLYPH_X(mb) (XmField(mb,ipot,DtMenuButton,menu_rect,XRectangle)).x
- #define MB_GLYPH_Y(mb) (XmField(mb,ipot,DtMenuButton,menu_rect,XRectangle)).y
- #define MB_GLYPH_WIDTH(mb) (XmField(mb,ipot,DtMenuButton,menu_rect,XRectangle)).width
- #define MB_GLYPH_HEIGHT(mb) (XmField(mb,ipot,DtMenuButton,menu_rect,XRectangle)).height
- #define MB_ARMED(mb) XmField(mb,ipot,DtMenuButton,armed,Boolean)
- #define MB_POPPED_UP(mb) XmField(mb,ipot,DtMenuButton,popped_up,Boolean)
- #define MB_GC(mb) XmField(mb,ipot,DtMenuButton,gc,GC)
- /******** Static Function Declarations ********/
- static void ClassInitialize (void);
- static void AdjustMenuButtonSize(
- DtMenuButtonWidget menubtn,
- Boolean adjustWidth,
- Boolean adjustHeight) ;
- static void Arm(
- DtMenuButtonWidget mb) ;
- static void ArmAndActivate(
- Widget wid,
- XEvent *event,
- String *params,
- Cardinal *num_params) ;
- static void CalculateMenuGlyphSize(
- DtMenuButtonWidget menubtn) ;
- static void CallCascadingCallbacks(
- Widget w,
- XEvent *event) ;
- static void Destroy(
- Widget wid) ;
- static void Disarm(
- DtMenuButtonWidget mb,
- Boolean pop_down) ;
- static void DrawArrow(
- Widget wid);
- static void Draw3DShadows(
- DtMenuButtonWidget mb) ;
- static void DrawMenuGlyph(
- DtMenuButtonWidget mb) ;
- static void GetGC(
- DtMenuButtonWidget mb);
- static void Initialize(
- Widget w_req,
- Widget w_new,
- ArgList args,
- Cardinal *num_args) ;
- static void LocateMenuGlyph(
- DtMenuButtonWidget menubtn) ;
- static void MenuButtonHandler(
- Widget wid,
- XtPointer cd,
- XEvent *event,
- Boolean *cont_to_dispatch) ;
- static void Popup(
- DtMenuButtonWidget mb,
- XEvent *event,
- Boolean call_cbacks );
- static void Redisplay(
- Widget mb,
- XEvent *event,
- Region region) ;
- static void Resize(
- Widget mb) ;
- static void Select(
- Widget wid,
- XEvent *event,
- String *param,
- Cardinal *num_param) ;
- static Boolean SetValues(
- Widget cw,
- Widget rw,
- Widget nw,
- ArgList args,
- Cardinal *num_args) ;
- static void GetTopManager(
- Widget w,
- Widget *topManager) ;
- /******** End Static Function Declarations ********/
- /*
- * event translation tables for menubutton.
- */
- static char menuButton_translations[] = "\
- <Key>space:Select()\n\
- <Key>osfSelect:Select()";
- static XtActionsRec menuButton_actions [] = {
- {"Select", Select}
- };
-
- /* MotifBc */
- #define DtOffset(field) XmPartOffset(DtMenuButton,field)
- #define XmPrimOffset(field) XmPartOffset(XmPrimitive,field)
- #define XmLabelOffset(field) XmPartOffset(XmLabel,field)
- static XmPartResource resources[] = {
- {
- DtNcascadingCallback,
- DtCCallback,
- XmRCallback,
- sizeof (XtCallbackList),
- DtOffset(cascading_callback),
- XmRCallback,
- NULL
- },
- {
- DtNsubMenuId,
- DtCMenuWidget, /* submenu */
- XmRMenuWidget,
- sizeof (Widget),
- DtOffset(submenu),
- XmRMenuWidget,
- (XtPointer) NULL
- },
- {
- DtNcascadePixmap,
- DtCPixmap,
- XmRPrimForegroundPixmap,
- sizeof(Pixmap),
- DtOffset(menu_pixmap),
- XmRImmediate,
- (XtPointer) XmUNSPECIFIED_PIXMAP
- },
- {
- XmNshadowThickness,
- XmCShadowThickness,
- XmRHorizontalDimension,
- sizeof (Dimension),
- XmPrimOffset(shadow_thickness),
- XmRImmediate,
- (XtPointer) 2
- },
- {
- XmNtraversalOn,
- XmCTraversalOn,
- XmRBoolean,
- sizeof(Boolean),
- XmPrimOffset(traversal_on),
- XmRImmediate,
- (XtPointer) TRUE
- },
- {
- XmNhighlightThickness,
- XmCHighlightThickness,
- XmRHorizontalDimension,
- sizeof (Dimension),
- XmPrimOffset(highlight_thickness),
- XmRImmediate,
- (XtPointer) 2
- },
- {
- XmNmarginWidth,
- XmCMarginWidth,
- XmRHorizontalDimension,
- sizeof (Dimension),
- XmLabelOffset(margin_width),
- XmRImmediate,
- (XtPointer)6
- },
- };
-
- externaldef(xmmenubuttonclassrec)
- DtMenuButtonClassRec dtMenuButtonClassRec = {
- { /* core class record */
- (WidgetClass) &xmLabelClassRec, /* superclass ptr */
- "DtMenuButton", /* class_name */
- sizeof(DtMenuButtonPart), /* size of Pulldown widget */
- (XtProc)ClassInitialize, /* class init proc */
- NULL, /* chained class init */
- FALSE, /* class is not init'ed */
- Initialize, /* widget init proc */
- NULL, /* init_hook proc */
- XtInheritRealize, /* widget realize proc */
- menuButton_actions, /* class action table */
- XtNumber (menuButton_actions), /* num of actions */
- (XtResourceList)resources, /* this class's resource list*/
- XtNumber (resources), /* resource_count */
- NULLQUARK, /* xrm_class */
- TRUE, /* compress motion */
- XtExposeCompressMaximal, /* compress exposure */
- TRUE, /* compress enter-leave */
- FALSE, /* no VisibilityNotify */
- Destroy, /* class destroy proc */
- Resize, /* class resize proc */
- Redisplay, /* expose proc */
- SetValues, /* set_value proc */
- NULL, /* set_value_hook proc */
- XtInheritSetValuesAlmost, /* set_value_almost proc */
- NULL, /* get_values_hook */
- NULL, /* class accept focus proc */
- XtVersionDontCheck, /* current version */
- NULL, /* callback offset list */
- menuButton_translations, /* default translation table */
- XtInheritQueryGeometry, /* query geo proc */
- NULL, /* display accelerator*/
- (XtPointer)NULL, /* extension */
- },
- {
- /* Primitive Class record */
- XmInheritWidgetProc, /* border_highlight */
- XmInheritWidgetProc, /* border_uhighlight */
- XtInheritTranslations, /* translations */
- ArmAndActivate, /* arm & activate */
- NULL, /* get resources */
- 0, /* num get_resources */
- (XtPointer)NULL, /* extension */
- },
- { /* Label Class record */
- XmInheritWidgetProc, /* set override callback */
- XmInheritMenuProc, /* menu procedures */
- XtInheritTranslations, /* menu traversal xlation */
- NULL, /* extension */
- },
- { /* menu_button class record */
- NULL, /* extension */
- }
- };
-
-
- /*
- * Now make a public symbol that points to this class record.
- */
-
- externaldef(dtmenubuttonwidgetclass)
- WidgetClass dtMenuButtonWidgetClass =
- (WidgetClass) &dtMenuButtonClassRec;
-
- /*
- * MotifBc, to calculate offset var. ipot
- */
- static void
- ClassInitialize(void)
- {
- XmResolveAllPartOffsets(dtMenuButtonWidgetClass, &ipot, &cpot);
- }
- static void
- Draw3DShadows(
- DtMenuButtonWidget mb )
- {
- if (XtIsRealized((Widget)mb))
- XmeDrawShadows (XtDisplay (mb), XtWindow (mb),
- mb->primitive.top_shadow_GC,
- mb->primitive.bottom_shadow_GC,
- mb->primitive.highlight_thickness,
- mb->primitive.highlight_thickness,
- mb->core.width - 2 *
- mb->primitive.highlight_thickness,
- mb->core.height - 2 *
- mb->primitive.highlight_thickness,
- mb->primitive.shadow_thickness,
- (MB_ARMED(mb) == TRUE) ? XmSHADOW_IN: XmSHADOW_OUT);
- }
-
-
- static void
- DrawMenuGlyph(
- DtMenuButtonWidget mb )
- {
- if ((MB_GLYPH_WIDTH(mb) != 0)){
- if(MB_PIXMAP(mb) != XmUNSPECIFIED_PIXMAP)
- XCopyArea (XtDisplay(mb),
- MB_PIXMAP(mb),
- XtWindow(mb),
- LNormalGC(mb), 0, 0,
- MB_GLYPH_WIDTH(mb), MB_GLYPH_HEIGHT(mb),
- MB_GLYPH_X(mb), MB_GLYPH_Y(mb));
- else
- DrawArrow((Widget)mb);
- }
- }
-
- /*
- * Redisplay the widget.
- */
- static void
- Redisplay(
- Widget mb,
- XEvent *event,
- Region region )
- {
- if (XtIsRealized (mb)) {
- /* Label expose method does the initial work */
- XtExposeProc expose;
- _DtProcessLock();
- expose = xmLabelClassRec.core_class.expose;
- _DtProcessUnlock();
- (* expose)(mb, event, region) ;
-
- DrawMenuGlyph((DtMenuButtonWidget) mb);
- Draw3DShadows ((DtMenuButtonWidget) mb);
- }
- }
- static void
- Arm(
- DtMenuButtonWidget mb )
- {
- XmProcessTraversal( (Widget) mb, XmTRAVERSE_CURRENT);
- if (MB_ARMED(mb) == FALSE) {
- MB_ARMED(mb) = TRUE;
- DrawMenuGlyph(mb);
- Draw3DShadows (mb);
- }
- }
- static void
- ArmAndActivate(
- Widget wid,
- XEvent *event,
- String *params,
- Cardinal *num_params )
- {
- DtMenuButtonWidget mb = (DtMenuButtonWidget) wid ;
-
- if(MB_SMENU(mb) == (Widget)NULL ||
- event == (XEvent*) NULL)
- return;
- if (!_XmIsEventUnique(event))
- return;
-
- Popup(mb, event, TRUE);
- _XmSetInDragMode((Widget)mb,FALSE);
- if (!XmProcessTraversal(MB_SMENU(mb), XmTRAVERSE_CURRENT))
- XtSetKeyboardFocus(XtParent(MB_SMENU(mb)), MB_SMENU(mb));
- _XmRecordEvent(event);
- }
- static void
- Disarm(
- DtMenuButtonWidget mb,
- Boolean pop_down )
- {
- if (MB_ARMED(mb) == TRUE) {
- MB_ARMED(mb) = FALSE;
-
- if (pop_down == TRUE &&
- MB_SMENU(mb) != (Widget)NULL)
- XtUnmanageChild(MB_SMENU(mb));
-
- Draw3DShadows(mb);
- DrawMenuGlyph(mb);
- }
- }
- /*ARGSUSED*/
- static void
- Select(
- Widget wid,
- XEvent *event,
- String *param,
- Cardinal *num_param )
- {
- DtMenuButtonWidget mb = (DtMenuButtonWidget) wid ;
- XtActionProc arm_and_activate;
-
- if(MB_POPPED_UP(mb) == TRUE) {
- Disarm(mb,TRUE);
- return;
- }
-
- _DtProcessLock();
- arm_and_activate = ((DtMenuButtonClassRec *)(mb->core.widget_class))->
- primitive_class.arm_and_activate;
- _DtProcessUnlock();
- (* arm_and_activate) ((Widget) mb, event, NULL, NULL);
- }
- static void
- PreMenuButtonHandler(
- Widget wid,
- XtPointer cd,
- XEvent *event,
- Boolean *cont_to_dispatch)
- {
- DtMenuButtonWidget mb = (DtMenuButtonWidget) wid ;
-
- if(MB_SMENU(mb) == (Widget)NULL ||
- event->xany.type != ButtonPress ||
- event->xbutton.time <= MB_LAST_TIMESTAMP(mb))
- return;
- if(event->xbutton.button==Button1||event->xbutton.button==Button3)
- {
- String btnstr=NULL;
- XtVaGetValues(MB_SMENU(mb), XmNmenuPost, &btnstr, NULL);
- if (btnstr==NULL || !strcmp(btnstr,"") ||
- !strcmp(btnstr, "<Btn3Down>"))
- event->xbutton.button=Button3;
- else if (!strcmp(btnstr, "<Btn1Down>"))
- event->xbutton.button=Button1;
- else
- XtWarning(MB_POST);
- }
- }
- static void
- MenuButtonHandler(
- Widget wid,
- XtPointer cd,
- XEvent *event,
- Boolean *cont_to_dispatch)
- {
- DtMenuButtonWidget mb = (DtMenuButtonWidget) wid ;
-
- if(MB_SMENU(mb) == (Widget)NULL ||
- event->xany.type != ButtonPress ||
- event->xbutton.time <= MB_LAST_TIMESTAMP(mb))
- return;
- else
- MB_LAST_TIMESTAMP(mb) = event->xbutton.time;
-
- Popup (mb, event, TRUE);
- }
- static void
- CallCascadingCallbacks(
- Widget w,
- XEvent *event )
- {
- DtMenuButtonWidget mb = (DtMenuButtonWidget)w;
- XmAnyCallbackStruct cback;
-
- if(MB_POPPED_UP(mb) == TRUE)
- return;
-
- cback.reason = DtCR_CASCADING;
- cback.event = event;
-
- XtCallCallbackList ((Widget) mb,
- CascadingCallback(mb), &cback);
- }
- static void
- PopdownCallback(Widget w, XtPointer client_data, XtPointer call_data)
- {
- DtMenuButtonWidget mb = (DtMenuButtonWidget)client_data;
- Disarm(mb,FALSE);
- MB_POPPED_UP(mb) = FALSE;
- MB_LAST_TIMESTAMP(mb) = XtLastTimestampProcessed(XtDisplay(mb));
- }
- static void
- PopupCallback(Widget w, XtPointer client_data, XtPointer call_data)
- {
- DtMenuButtonWidget mb = (DtMenuButtonWidget)client_data;
- Arm(mb);
- MB_POPPED_UP(mb) = TRUE;
- }
- /*
- * Call the cascading callbacks and popup any submenu.
- */
- static void
- Popup(
- DtMenuButtonWidget mb,
- XEvent *event,
- Boolean call_cbacks )
- {
- Position x=0, y=0;
- Position root_x=0, root_y=0;
- Position save_x = 0, save_y = 0;
- Dimension sw=0, sh=0;
- int dx = 0, dy = 0;
- Screen *screen;
- if((MB_SMENU(mb) == (Widget)NULL) ||
- (MB_POPPED_UP(mb) == TRUE))
- return;
-
- if (call_cbacks)
- CallCascadingCallbacks((Widget)mb, event);
-
- x = (Position)((int)XtWidth((Widget)mb) - (int)XtWidth(MB_SMENU(mb)))/2;
- y = XtHeight((Widget)mb) - mb->primitive.highlight_thickness + 1;
- XtTranslateCoords((Widget)mb, x,y, &root_x, &root_y);
-
- /* Check if not completely on the screen */
- screen = XtScreen(mb);
- sw = WidthOfScreen(screen);
- sh = HeightOfScreen(screen);
- if((dx = root_x - sw + XtWidth(MB_SMENU(mb))) > 0)
- root_x -= dx;
- if((dy = root_y - sh + XtHeight(MB_SMENU(mb))) > 0) {
- root_y -= (2 - (mb->primitive.highlight_thickness<<1));
- root_y -= (XtHeight(mb) + XtHeight(MB_SMENU(mb)));
- }
-
- save_x = event->xbutton.x_root;
- save_y = event->xbutton.y_root;
-
- event->xbutton.x_root = root_x;
- event->xbutton.y_root = root_y;
- /* Position the menu */
- XmMenuPosition(MB_SMENU(mb),(XButtonPressedEvent*)event);
- event->xbutton.x_root = save_x;
- event->xbutton.y_root = save_y;
-
- XtManageChild(MB_SMENU(mb));
- }
- /*
- * Get the menu glyph size set up.
- */
- static void
- CalculateMenuGlyphSize(
- DtMenuButtonWidget menubtn )
- {
- Window rootwin;
- int x,y; /* must be int */
- unsigned int width, height, border, depth; /* must be int */
-
- if (MB_PIXMAP(menubtn) != XmUNSPECIFIED_PIXMAP) {
- XGetGeometry(XtDisplay(menubtn), MB_PIXMAP(menubtn),
- &rootwin, &x, &y, &width, &height,
- &border, &depth);
-
- MB_GLYPH_WIDTH(menubtn) = (Dimension) width;
- MB_GLYPH_HEIGHT(menubtn) = (Dimension) height;
- } else {
- int ht, st;
- Dimension side;
- unsigned int text_height;
-
- ht = menubtn->primitive.highlight_thickness;
- st = menubtn->primitive.shadow_thickness;
- text_height = Lab_TextRect_height(menubtn);
-
- side = Max( (text_height * 2 / 3) + 2 * (ht + st),
- (2*(ht + (st-1) +1)) +1 );
- MB_GLYPH_WIDTH(menubtn) =
- MB_GLYPH_HEIGHT(menubtn) = side;
- }
- }
- /*
- * Set up the menu glyph location.
- */
- static void
- LocateMenuGlyph(
- DtMenuButtonWidget menubtn )
- {
- Dimension buffer;
-
- MB_GLYPH_X(menubtn) =
- XtWidth (menubtn) -
- menubtn->primitive.highlight_thickness -
- menubtn->primitive.shadow_thickness -
- Lab_MarginWidth(menubtn) -
- MB_GLYPH_WIDTH(menubtn);
-
- buffer = menubtn->primitive.highlight_thickness +
- menubtn->primitive.shadow_thickness +
- Lab_MarginHeight(menubtn);
-
- MB_GLYPH_Y(menubtn) = (Position)((int)buffer +
- (((int)XtHeight(menubtn) - 2*(int)buffer) -
- (int)MB_GLYPH_HEIGHT(menubtn)) / 2);
- }
- /*
- * Make room for menu glyph in menu button.
- */
- static void
- AdjustMenuButtonSize(
- DtMenuButtonWidget menubtn,
- Boolean adjustWidth,
- Boolean adjustHeight )
- {
- Dimension delta;
-
- /*
- * Modify the size of the menubutton to acommadate the menu.
- * The menu should fit inside MarginRight.
- */
- if ((int)(MB_GLYPH_WIDTH(menubtn) + GLYPH_PIX_SPACE) >
- (int)Lab_MarginRight(menubtn)) {
- delta = MB_GLYPH_WIDTH(menubtn) + GLYPH_PIX_SPACE -
- Lab_MarginRight(menubtn);
- Lab_MarginRight(menubtn) += delta;
-
- if (adjustWidth)
- XtWidth(menubtn) += delta;
- else {
- if (LAlignment(menubtn) == XmALIGNMENT_END)
- Lab_TextRect_x(menubtn) -= delta;
- else
- if (LAlignment(menubtn) == XmALIGNMENT_CENTER)
- Lab_TextRect_x(menubtn) -= delta/2;
- }
- }
-
- /*
- * the menu height should fit inside of
- * TextRect + marginTop + marginBottom
- */
- delta = MB_GLYPH_HEIGHT(menubtn) +
- 2 * (Lab_MarginHeight(menubtn) +
- menubtn->primitive.shadow_thickness +
- menubtn->primitive.highlight_thickness);
-
- if (delta > XtHeight(menubtn)) {
- delta -= XtHeight(menubtn);
- Lab_MarginTop(menubtn) += delta/2;
- Lab_TextRect_y(menubtn) += delta/2;
- Lab_MarginBottom(menubtn) += delta - (delta/2);
-
- if (adjustHeight)
- XtHeight(menubtn) += delta;
- }
-
- LocateMenuGlyph(menubtn);
- }
- /*
- * Destroy the widget
- */
- static void
- Destroy(
- Widget wid )
- {
- DtMenuButtonWidget mb = (DtMenuButtonWidget) wid ;
- XmRowColumnWidget submenu = (XmRowColumnWidget) MB_SMENU(mb);
- Widget shell;
-
- XtRemoveAllCallbacks ((Widget) mb, DtNcascadingCallback);
-
- if(submenu != (XmRowColumnWidget)NULL) {
- shell = XtParent((Widget)submenu);
- XtRemoveCallback(shell, XtNpopupCallback,PopupCallback, (XtPointer)mb);
- XtRemoveCallback(shell, XtNpopdownCallback, PopdownCallback,(XtPointer)mb);
- }
-
- if(MB_PVT_SMENU(mb) == TRUE) {
- XtDestroyWidget((Widget)submenu);
- MB_SMENU(mb) = NULL;
- MB_PVT_SMENU(mb) = FALSE;
- }
- }
-
- /*
- * Resize Method.
- */
- static void
- Resize(
- Widget mb )
- {
- if (mb != (Widget)NULL) {
- /* Label resize method lays out the label string */
- XtWidgetProc resize;
- _DtProcessLock();
- resize = xmLabelClassRec.core_class.resize;
- _DtProcessUnlock();
- (* resize) (mb);
- LocateMenuGlyph ((DtMenuButtonWidget) mb);
- }
- }
- /*
- * Set Values Method.
- */
- static Boolean
- SetValues(
- Widget cw,
- Widget rw,
- Widget nw,
- ArgList args,
- Cardinal *num_args )
- {
- DtMenuButtonWidget old = (DtMenuButtonWidget) cw ;
- DtMenuButtonWidget requested = (DtMenuButtonWidget) rw ;
- DtMenuButtonWidget new_w = (DtMenuButtonWidget) nw ;
- Boolean flag = FALSE;
- Boolean adjustWidth = FALSE;
- Boolean adjustHeight = FALSE;
- unsigned char rowcol_type = 0;
- Boolean menu_glyph_changed = FALSE;
-
- if (MB_SMENU(new_w) != (Widget)NULL) {
- XtVaGetValues(MB_SMENU(new_w), XmNrowColumnType,
- &rowcol_type, NULL);
- if(rowcol_type != XmMENU_POPUP) {
- MB_SMENU(new_w) = NULL;
- XtError(MB_SUBMENU);
- }
- }
-
- /* Never let traversal become FALSE */
- new_w->primitive.traversal_on = TRUE;
-
- if ((LRecomputeSize(new_w)) ||
- (requested->core.width <= 0))
- adjustWidth = TRUE;
-
- if ((LRecomputeSize(new_w)) ||
- (requested->core.height <= 0))
- adjustHeight = TRUE;
-
- /* get new pixmap size */
- if ((MB_PIXMAP(old) != MB_PIXMAP (new_w)) ||
- (Lab_TextRect_height(old) != Lab_TextRect_height(new_w))) {
- CalculateMenuGlyphSize (new_w);
- menu_glyph_changed = TRUE;
- }
- if ((old->primitive.foreground !=
- new_w->primitive.foreground) ||
- (old->core.background_pixel !=
- new_w->core.background_pixel)) {
- menu_glyph_changed = TRUE;
- GetGC(new_w);
- }
- /*
- * Resize widget if submenu appeared or disappeared, or if the
- * menu glyph changed.
- */
-
- if ( menu_glyph_changed == TRUE ||
- (LLabelType(old) != LLabelType(new_w)) ||
- (MB_SMENU(old) != MB_SMENU(new_w))) {
-
- AdjustMenuButtonSize (new_w, adjustWidth, adjustHeight);
-
- flag = TRUE;
-
- if ((MB_SMENU(old) != MB_SMENU(new_w))) {
-
- if(MB_SMENU(new_w)) {
- XtRemoveEventHandler((Widget)new_w,
- ButtonPressMask, False,
- PreMenuButtonHandler, MB_SMENU(old));
- XtInsertEventHandler((Widget)new_w,
- ButtonPressMask, False,
- PreMenuButtonHandler, MB_SMENU(new_w),
- XtListHead);
- XtAddCallback(XtParent(
- MB_SMENU(new_w)),
- XtNpopdownCallback,
- PopdownCallback, (XtPointer)new_w);
- XtAddCallback(XtParent(
- MB_SMENU(new_w)),
- XtNpopupCallback,
- PopupCallback, (XtPointer)new_w);
- }
-
- if(MB_PVT_SMENU(old) == TRUE) {
- XtDestroyWidget(MB_SMENU(old));
- MB_PVT_SMENU(new_w) = FALSE;
- }
-
- }
-
- } else if ((new_w->primitive.highlight_thickness !=
- old->primitive.highlight_thickness) ||
- (new_w->primitive.shadow_thickness !=
- old->primitive.shadow_thickness) ||
- (Lab_MarginRight (new_w) != Lab_MarginRight (old)) ||
- (Lab_MarginHeight (new_w) != Lab_MarginHeight (old)) ||
- (Lab_MarginTop (new_w) != Lab_MarginTop (old)) ||
- (Lab_MarginBottom (new_w) != Lab_MarginBottom (old))) {
- CalculateMenuGlyphSize (new_w);
- AdjustMenuButtonSize (new_w,adjustWidth, adjustHeight);
- flag = TRUE;
- } else if ((Lab_MarginWidth(new_w) != Lab_MarginWidth(old)) ||
- (new_w->core.width != old->core.width) ||
- (new_w->core.height != old->core.height)) {
- LocateMenuGlyph (new_w);
- flag = TRUE;
- }
-
- return (flag);
- }
- /*
- * Initialize
- */
- static void
- Initialize(
- Widget w_req,
- Widget w_new,
- ArgList args,
- Cardinal *num_args )
- {
- DtMenuButtonWidget req = (DtMenuButtonWidget) w_req ;
- DtMenuButtonWidget new_w = (DtMenuButtonWidget) w_new ;
- Widget topManager;
- Boolean adjustWidth = FALSE;
- Boolean adjustHeight = FALSE;
- Widget parent = XtParent(new_w);
- unsigned char rowcol_type = 0;
- char *name = NULL;
-
- if ((XmIsRowColumn (parent))) {
- XtVaGetValues(parent, XmNrowColumnType,
- &rowcol_type, NULL);
- if(rowcol_type != XmWORK_AREA)
- XtError(MB_PARENT);
- }
- name = XtMalloc(10 + strlen(new_w->core.name));
- sprintf(name,"submenu_%s",new_w->core.name);
-
- GetTopManager(w_new,&topManager);
- MB_SMENU(new_w) = XmCreatePopupMenu(topManager, name, NULL, 0);
- /* Remove our passive grab */
- XtUngrabButton(topManager, RC_PostButton(MB_SMENU(new_w)), AnyModifier);
- MB_PVT_SMENU(new_w) = TRUE;
-
- MB_ARMED(new_w) = FALSE;
- MB_POPPED_UP(new_w) = FALSE;
- MB_LAST_TIMESTAMP(new_w) = 0;
- MB_GC(new_w) = (GC)NULL;
-
- if (req->core.width <= 0)
- adjustWidth = TRUE;
-
- if (req->core.height <= 0)
- adjustHeight = TRUE;
-
- CalculateMenuGlyphSize (new_w);
- AdjustMenuButtonSize (new_w, adjustWidth, adjustHeight);
- GetGC(new_w);
-
- new_w->primitive.traversal_on = TRUE;
-
- if(MB_SMENU(new_w) != (Widget)NULL) {
- XtInsertEventHandler((Widget)new_w, ButtonPressMask,
- False, PreMenuButtonHandler, MB_SMENU(new_w), XtListHead);
- XtAddEventHandler((Widget)new_w, ButtonPressMask,
- FALSE, MenuButtonHandler, MB_SMENU(new_w));
- XtAddCallback(XtParent(MB_SMENU(new_w)), XtNpopdownCallback,
- PopdownCallback, (XtPointer)new_w);
- XtAddCallback(XtParent(MB_SMENU(new_w)), XtNpopupCallback,
- PopupCallback, (XtPointer)new_w);
- }
- XtFree(name);
- }
- static void
- DrawArrow(
- Widget wid )
- {
- GC gc, tsGC, bsGC;
- Pixel tsc, bsc;
- int ht,st;
- unsigned int text_height;
- DtMenuButtonWidget mb = (DtMenuButtonWidget) wid ;
- Window win = XtWindow(wid);
- Display *dpy = XtDisplay(wid);
-
- ht = mb->primitive.highlight_thickness;
- st = mb->primitive.shadow_thickness;
- text_height = Lab_TextRect_height(mb);
- tsc = mb->primitive.top_shadow_color;
- bsc = mb->primitive.bottom_shadow_color;
- tsGC = mb->primitive.top_shadow_GC;
- bsGC = mb->primitive.bottom_shadow_GC;
- gc = MB_GC(mb);
- /* armed arrow */
- if(MB_ARMED(mb) == TRUE) {
- XFillRectangle(dpy, win, gc,
- MB_GLYPH_X(mb), MB_GLYPH_Y(mb),
- MB_GLYPH_WIDTH(mb), MB_GLYPH_HEIGHT(mb));
- XmeDrawArrow(dpy, win,
- bsGC, tsGC, gc,
- MB_GLYPH_X(mb) + ht + st - 1,
- MB_GLYPH_Y(mb) + ht + st - 1,
- MB_GLYPH_WIDTH(mb) - 2*(ht + st - 1),
- MB_GLYPH_HEIGHT(mb) - 2*(ht + st - 1),
- st, XmARROW_DOWN);
- } else {
- /* standard (unarmed) arrow */
-
- XFillRectangle(dpy, win, gc,
- MB_GLYPH_X(mb), MB_GLYPH_Y(mb),
- MB_GLYPH_WIDTH(mb), MB_GLYPH_HEIGHT(mb));
- XmeDrawArrow(dpy, win,
- tsGC, bsGC, gc,
- MB_GLYPH_X(mb) + ht + st - 1,
- MB_GLYPH_Y(mb) + ht + st - 1,
- MB_GLYPH_WIDTH(mb) - 2*(ht + st - 1),
- MB_GLYPH_HEIGHT(mb) - 2*(ht + st - 1),
- st, XmARROW_DOWN);
- }
- }
- static void
- GetGC(
- DtMenuButtonWidget mb)
- {
- XGCValues values;
- Pixel bg;
- if(MB_GC(mb) != (GC)NULL) {
- XtReleaseGC((Widget)mb, MB_GC(mb));
- MB_GC(mb) = (GC)NULL;
- }
- bg = mb->core.background_pixel;
- values.foreground = values.background = bg;
- values.graphics_exposures = FALSE;
- MB_GC(mb) = XtGetGC ((Widget) mb,
- GCForeground | GCBackground | GCGraphicsExposures, &values);
- }
- /*
- *************************************************************************
- *
- * Public Routines
- *
- *************************************************************************
- */
- Widget
- DtCreateMenuButton(
- Widget parent,
- char *name,
- ArgList al,
- Cardinal ac )
- {
- return XtCreateWidget(name,dtMenuButtonWidgetClass,parent, al, ac);
- }
- static void
- GetTopManager(
- Widget w,
- Widget *topManager )
- {
- while (XmIsManager(XtParent(w)))
- w = XtParent(w);
-
- * topManager = w;
- }
-
|