зеркало из https://github.com/mozilla/gecko-dev.git
2793 строки
69 KiB
C
2793 строки
69 KiB
C
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Name: <Xfe/Button.c> */
|
|
/* Description: XfeButton widget source. */
|
|
/* Author: Ramiro Estrugo <ramiro@netscape.com> */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
#include <Xfe/ButtonP.h>
|
|
#include <Xfe/ManagerP.h>
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Warnings and messages */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
#define MESSAGE1 "Widget is not a XfeButton."
|
|
|
|
|
|
#define MESSAGE2 "XmNpixmap needs to have the same depth as the XfeButton."
|
|
#define MESSAGE3 "Cannot obtain geometry info for XmNpixmap."
|
|
#define MESSAGE4 "Cannot obtain geometry info for XmNarmedPixmap."
|
|
#define MESSAGE5 "Cannot obtain geometry info for XmNraisedPixmap."
|
|
#define MESSAGE6 "Cannot obtain geometry info for XmNinsensitivePixmap."
|
|
#define MESSAGE7 "Cannot use XmNarmedPixmap since XmNpixmap is bad."
|
|
#define MESSAGE8 "Cannot use XmNraisedPixmap since XmNpixmap is bad."
|
|
#define MESSAGE9 "Cannot use XmNinsensitivePixmap since XmNpixmap is bad."
|
|
#define MESSAGE10 "XmNarmedPixmap dimensions do not match XmNpixmap."
|
|
#define MESSAGE11 "XmNraisedPixmap dimensions do not match XmNpixmap."
|
|
#define MESSAGE12 "XmNinsensitivePixmap dimensions do not match XmNpixmap."
|
|
#define MESSAGE13 "XmNarmedPixmap needs to have same depth as the XfeButton."
|
|
#define MESSAGE14 "XmNraisedPixmap needs to have same depth as the XfeButton."
|
|
#define MESSAGE15 "XmNinsensitivePixmap needs to have same depth as the XfeButton."
|
|
#define MESSAGE16 "XfeButtonPreferredGeometry: The given layout is invalid."
|
|
#define MESSAGE17 "XmNarmed can only be set for XmBUTTON_TOGGLE XmNbuttonType."
|
|
#define MESSAGE18 "XmNraised can only be set when XmNraiseOnEnter is True."
|
|
|
|
#define RAISE_OFFSET(bp) \
|
|
(bp->raise_on_enter ? bp->raise_border_thickness : 0)
|
|
|
|
#define XY_IN_LABEL(_lp,_x,_y) XfePointInRect(&(_lp)->label_rect,(_x),(_y))
|
|
#define XY_IN_PIXMAP(_bp,_x,_y) XfePointInRect(&(_bp)->pixmap_rect,(_x),(_y))
|
|
|
|
#define MIN_COMP_WIDTH(_lp,_bp) \
|
|
XfeMin((_bp)->pixmap_rect.width,(_lp)->label_rect.width)
|
|
|
|
#define MIN_COMP_HEIGHT(_lp,_bp) \
|
|
XfeMin((bp)->pixmap_rect.height,(_lp)->label_rect.height)
|
|
|
|
#define UNDERLINE_SPACING 1
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Core class methods */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void ClassInitialize (void);
|
|
static void ClassPartInit (WidgetClass);
|
|
static void Initialize (Widget,Widget,ArgList,Cardinal *);
|
|
static void Destroy (Widget);
|
|
static Boolean SetValues (Widget,Widget,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 *);
|
|
static void DrawBackground (Widget,XEvent *,Region,XRectangle *);
|
|
static void DrawShadow (Widget,XEvent *,Region,XRectangle *);
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfeLabel class methods */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void LayoutString (Widget);
|
|
static void DrawString (Widget,XEvent *,Region,XRectangle *);
|
|
static GC GetLabelGC (Widget);
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfeButton class methods */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void LayoutPixmap (Widget);
|
|
static void DrawPixmap (Widget,XEvent *,Region,XRectangle *);
|
|
static void DrawRaiseBorder (Widget,XEvent *,Region,XRectangle *);
|
|
static void DrawUnderline (Widget,XEvent *,Region,XRectangle *);
|
|
static void ArmTimeout (XtPointer,XtIntervalId *);
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Misc XfeButton functions */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void PixmapPrepare (Widget);
|
|
static void PixmapArmedPrepare (Widget);
|
|
static void PixmapRaisedPrepare (Widget);
|
|
static void PixmapInsensPrepare (Widget);
|
|
|
|
static void StringLayoutLabelOnBottom (Widget);
|
|
static void StringLayoutLabelOnLeft (Widget);
|
|
static void StringLayoutLabelOnRight (Widget);
|
|
static void StringLayoutLabelOnTop (Widget);
|
|
static void StringLayoutLabelOnly (Widget);
|
|
|
|
static void InvokeCallback (Widget,XtCallbackList,int,XEvent *);
|
|
|
|
static Boolean AcceptEvent (Widget,XEvent *);
|
|
static Boolean SpacingContainsXY (Widget,int,int);
|
|
|
|
static void TransparentCursorSetState (Widget,Boolean);
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Resource Callprocs */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void DefaultArmBackground (Widget,int,XrmValue *);
|
|
static void DefaultRaiseBackground (Widget,int,XrmValue *);
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfeButton Resources */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static XtResource resources[] =
|
|
{
|
|
/* Callback resources */
|
|
{
|
|
XmNactivateCallback,
|
|
XmCCallback,
|
|
XmRCallback,
|
|
sizeof(XtCallbackList),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . activate_callback),
|
|
XmRImmediate,
|
|
(XtPointer) NULL
|
|
},
|
|
{
|
|
XmNarmCallback,
|
|
XmCCallback,
|
|
XmRCallback,
|
|
sizeof(XtCallbackList),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . arm_callback),
|
|
XmRImmediate,
|
|
(XtPointer) NULL
|
|
},
|
|
{
|
|
XmNbutton3DownCallback,
|
|
XmCCallback,
|
|
XmRCallback,
|
|
sizeof(XtCallbackList),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . button_3_down_callback),
|
|
XmRImmediate,
|
|
(XtPointer) NULL
|
|
},
|
|
{
|
|
XmNbutton3UpCallback,
|
|
XmCCallback,
|
|
XmRCallback,
|
|
sizeof(XtCallbackList),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . button_3_up_callback),
|
|
XmRImmediate,
|
|
(XtPointer) NULL
|
|
},
|
|
{
|
|
XmNdisarmCallback,
|
|
XmCCallback,
|
|
XmRCallback,
|
|
sizeof(XtCallbackList),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . disarm_callback),
|
|
XmRImmediate,
|
|
(XtPointer) NULL
|
|
},
|
|
|
|
/* Label resources */
|
|
{
|
|
XmNraiseForeground,
|
|
XmCRaiseForeground,
|
|
XmRPixel,
|
|
sizeof(Pixel),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . raise_foreground),
|
|
XmRCallProc,
|
|
(XtPointer) _XfeCallProcCopyForeground
|
|
},
|
|
|
|
/* Pixmap resources */
|
|
{
|
|
XmNarmedPixmap,
|
|
XmCArmedPixmap,
|
|
XmRPixmap,
|
|
sizeof(Pixmap),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . armed_pixmap),
|
|
XmRImmediate,
|
|
(XtPointer) XmUNSPECIFIED_PIXMAP
|
|
},
|
|
{
|
|
XmNinsensitivePixmap,
|
|
XmCInsensitivePixmap,
|
|
XmRPixmap,
|
|
sizeof(Pixmap),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . insensitive_pixmap),
|
|
XmRImmediate,
|
|
(XtPointer) XmUNSPECIFIED_PIXMAP
|
|
},
|
|
{
|
|
XmNpixmap,
|
|
XmCPixmap,
|
|
XmRPixmap,
|
|
sizeof(Pixmap),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . pixmap),
|
|
XmRImmediate,
|
|
(XtPointer) XmUNSPECIFIED_PIXMAP
|
|
},
|
|
{
|
|
XmNraisedPixmap,
|
|
XmCRaisedPixmap,
|
|
XmRPixmap,
|
|
sizeof(Pixmap),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . raised_pixmap),
|
|
XmRImmediate,
|
|
(XtPointer) XmUNSPECIFIED_PIXMAP
|
|
},
|
|
{
|
|
XmNarmedPixmapMask,
|
|
XmCArmedPixmapMask,
|
|
XmRPixmap,
|
|
sizeof(Pixmap),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . armed_pixmap_mask),
|
|
XmRImmediate,
|
|
(XtPointer) XmUNSPECIFIED_PIXMAP
|
|
},
|
|
{
|
|
XmNinsensitivePixmapMask,
|
|
XmCInsensitivePixmapMask,
|
|
XmRPixmap,
|
|
sizeof(Pixmap),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . insensitive_pixmap_mask),
|
|
XmRImmediate,
|
|
(XtPointer) XmUNSPECIFIED_PIXMAP
|
|
},
|
|
{
|
|
XmNpixmapMask,
|
|
XmCPixmapMask,
|
|
XmRPixmap,
|
|
sizeof(Pixmap),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . pixmap_mask),
|
|
XmRImmediate,
|
|
(XtPointer) XmUNSPECIFIED_PIXMAP
|
|
},
|
|
{
|
|
XmNraisedPixmapMask,
|
|
XmCRaisedPixmapMask,
|
|
XmRPixmap,
|
|
sizeof(Pixmap),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . raised_pixmap_mask),
|
|
XmRImmediate,
|
|
(XtPointer) XmUNSPECIFIED_PIXMAP
|
|
},
|
|
|
|
/* Raise resources */
|
|
{
|
|
XmNfillOnEnter,
|
|
XmCFillOnEnter,
|
|
XmRBoolean,
|
|
sizeof(Boolean),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . fill_on_enter),
|
|
XmRImmediate,
|
|
(XtPointer) False
|
|
},
|
|
{
|
|
XmNraised,
|
|
XmCRaised,
|
|
XmRBoolean,
|
|
sizeof(Boolean),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . raised),
|
|
XmRImmediate,
|
|
(XtPointer) False
|
|
},
|
|
{
|
|
XmNraiseBackground,
|
|
XmCRaiseBackground,
|
|
XmRPixel,
|
|
sizeof(Pixel),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . raise_background),
|
|
XmRCallProc,
|
|
(XtPointer) DefaultRaiseBackground
|
|
},
|
|
{
|
|
XmNraiseBorderThickness,
|
|
XmCRaiseBorderThickness,
|
|
XmRHorizontalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . raise_border_thickness),
|
|
XmRImmediate,
|
|
(XtPointer) 1
|
|
},
|
|
{
|
|
XmNraiseOnEnter,
|
|
XmCRaiseOnEnter,
|
|
XmRBoolean,
|
|
sizeof(Boolean),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . raise_on_enter),
|
|
XmRImmediate,
|
|
(XtPointer) True
|
|
},
|
|
|
|
/* Arm resources */
|
|
{
|
|
XmNfillOnArm,
|
|
XmCFillOnArm,
|
|
XmRBoolean,
|
|
sizeof(Boolean),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . fill_on_arm),
|
|
XmRImmediate,
|
|
(XtPointer) True
|
|
},
|
|
{
|
|
XmNarmBackground,
|
|
XmCArmBackground,
|
|
XmRPixel,
|
|
sizeof(Pixel),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . arm_background),
|
|
XmRCallProc,
|
|
(XtPointer) DefaultArmBackground
|
|
},
|
|
{
|
|
XmNarmForeground,
|
|
XmCArmForeground,
|
|
XmRPixel,
|
|
sizeof(Pixel),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . arm_foreground),
|
|
XmRCallProc,
|
|
(XtPointer) _XfeCallProcCopyForeground
|
|
},
|
|
{
|
|
XmNarmOffset,
|
|
XmCArmOffset,
|
|
XmRHorizontalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . arm_offset),
|
|
XmRImmediate,
|
|
(XtPointer) 0
|
|
},
|
|
{
|
|
XmNarmed,
|
|
XmCArmed,
|
|
XmRBoolean,
|
|
sizeof(Boolean),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . armed),
|
|
XmRImmediate,
|
|
(XtPointer) False
|
|
},
|
|
{
|
|
XmNdeterminate,
|
|
XmCDeterminate,
|
|
XmRBoolean,
|
|
sizeof(Boolean),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . determinate),
|
|
XmRImmediate,
|
|
(XtPointer) True
|
|
},
|
|
|
|
{
|
|
XmNunderlineThickness,
|
|
XmCUnderlineThickness,
|
|
XmRHorizontalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . underline_thickness),
|
|
XmRImmediate,
|
|
(XtPointer) 0
|
|
},
|
|
|
|
/* Misc resources */
|
|
{
|
|
XmNbuttonLayout,
|
|
XmCButtonLayout,
|
|
XmRButtonLayout,
|
|
sizeof(unsigned char),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . button_layout),
|
|
XmRImmediate,
|
|
(XtPointer) XmBUTTON_LABEL_ON_BOTTOM
|
|
},
|
|
{
|
|
XmNbuttonTrigger,
|
|
XmCButtonTrigger,
|
|
XmRButtonTrigger,
|
|
sizeof(unsigned char),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . button_trigger),
|
|
XmRImmediate,
|
|
(XtPointer) XmBUTTON_TRIGGER_ANYWHERE
|
|
},
|
|
{
|
|
XmNbuttonType,
|
|
XmCButtonType,
|
|
XmRButtonType,
|
|
sizeof(unsigned char),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . button_type),
|
|
XmRImmediate,
|
|
(XtPointer) XmBUTTON_PUSH
|
|
},
|
|
{
|
|
XmNemulateMotif,
|
|
XmCEmulateMotif,
|
|
XmRBoolean,
|
|
sizeof(Boolean),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . emulate_motif),
|
|
XmRImmediate,
|
|
(XtPointer) True
|
|
},
|
|
{
|
|
XmNspacing,
|
|
XmCSpacing,
|
|
XmRHorizontalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . spacing),
|
|
XmRImmediate,
|
|
(XtPointer) 4
|
|
},
|
|
|
|
/* Cursor resources */
|
|
{
|
|
XmNtransparentCursor,
|
|
XmCCursor,
|
|
XmRCursor,
|
|
sizeof(Cursor),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . transparent_cursor),
|
|
XmRImmediate,
|
|
(XtPointer) None
|
|
},
|
|
|
|
|
|
/* Force margins to 0 */
|
|
{
|
|
XmNmarginBottom,
|
|
XmCMarginBottom,
|
|
XmRVerticalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfeButtonRec , xfe_primitive . margin_bottom),
|
|
XmRImmediate,
|
|
(XtPointer) 0
|
|
},
|
|
{
|
|
XmNmarginLeft,
|
|
XmCMarginLeft,
|
|
XmRHorizontalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfeButtonRec , xfe_primitive . margin_left),
|
|
XmRImmediate,
|
|
(XtPointer) 0
|
|
},
|
|
{
|
|
XmNmarginRight,
|
|
XmCMarginRight,
|
|
XmRHorizontalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfeButtonRec , xfe_primitive . margin_right),
|
|
XmRImmediate,
|
|
(XtPointer) 0
|
|
},
|
|
{
|
|
XmNmarginTop,
|
|
XmCMarginTop,
|
|
XmRVerticalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfeButtonRec , xfe_primitive . margin_top),
|
|
XmRImmediate,
|
|
(XtPointer) 0
|
|
},
|
|
|
|
/* Force buffer type to XmBUFFER_SHARED */
|
|
{
|
|
XmNbufferType,
|
|
XmCBufferType,
|
|
XmRBufferType,
|
|
sizeof(unsigned char),
|
|
XtOffsetOf(XfeButtonRec , xfe_primitive . buffer_type),
|
|
XmRImmediate,
|
|
(XtPointer) XmBUFFER_SHARED
|
|
},
|
|
};
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfeButton Synthetic Resources */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static XmSyntheticResource syn_resources[] =
|
|
{
|
|
{
|
|
XmNarmOffset,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . arm_offset),
|
|
_XmFromHorizontalPixels,
|
|
_XmToHorizontalPixels
|
|
},
|
|
{
|
|
XmNraiseBorderThickness,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . raise_border_thickness),
|
|
_XmFromHorizontalPixels,
|
|
_XmToHorizontalPixels
|
|
},
|
|
{
|
|
XmNunderlineThickness,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . underline_thickness),
|
|
_XmFromHorizontalPixels,
|
|
_XmToHorizontalPixels
|
|
},
|
|
{
|
|
XmNspacing,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfeButtonRec , xfe_button . spacing),
|
|
_XmFromHorizontalPixels,
|
|
_XmToHorizontalPixels
|
|
},
|
|
};
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfeButton actions */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static XtActionsRec actions[] =
|
|
{
|
|
{ "Enter", _XfeButtonEnter },
|
|
{ "Leave", _XfeButtonLeave },
|
|
{ "Motion", _XfeButtonMotion },
|
|
{ "Activate", _XfeButtonActivate },
|
|
{ "Arm", _XfeButtonArm },
|
|
{ "Disarm", _XfeButtonDisarm },
|
|
{ "ArmAndActivate", _XfeButtonArmAndActivate },
|
|
{ "Btn3Down", _XfeButtonBtn3Down },
|
|
{ "Btn3Up", _XfeButtonBtn3Up },
|
|
};
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfeButton translations */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static char default_translations[] ="\
|
|
<Key>space: ArmAndActivate()\n\
|
|
c<Btn1Down>: Focus()\n\
|
|
<Btn1Down>: Arm()\n\
|
|
<Btn1Up>: Activate() Disarm()\n\
|
|
<Btn3Down>: Btn3Down()\n\
|
|
<Btn3Up>: Btn3Up()\n\
|
|
~c ~s ~a ~m<Key>Return: ArmAndActivate()\n\
|
|
~c ~s ~a ~m<Key>space: ArmAndActivate()\n\
|
|
:<Key>osfHelp: Help()\n\
|
|
<Enter>: Enter()\n\
|
|
<Leave>: Leave()";
|
|
|
|
static char motion_add_translations[] ="\
|
|
<Motion>: Motion()";
|
|
|
|
static char _XfeButtonMotionRemoveTranslations[] ="\
|
|
<Motion>: ";
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfeButton widget class record initialization */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
_XFE_WIDGET_CLASS_RECORD(button,Button) =
|
|
{
|
|
{
|
|
/* Core Part */
|
|
(WidgetClass) &xfeLabelClassRec, /* superclass */
|
|
"XfeButton", /* class_name */
|
|
sizeof(XfeButtonRec), /* widget_size */
|
|
ClassInitialize, /* 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 */
|
|
NULL, /* 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 */
|
|
_XfeButtonArmAndActivate, /* arm_and_activate */
|
|
(XmSyntheticResource *)syn_resources, /* syn resources */
|
|
XtNumber(syn_resources), /* num syn_resources */
|
|
NULL, /* extension */
|
|
},
|
|
|
|
/* XfePrimitive Part */
|
|
{
|
|
XfeInheritBitGravity, /* bit_gravity */
|
|
PreferredGeometry, /* preferred_geometry */
|
|
XfeInheritUpdateBoundary, /* update_boundary */
|
|
PrepareComponents, /* prepare_components */
|
|
LayoutComponents, /* layout_components */
|
|
DrawBackground, /* draw_background */
|
|
DrawShadow, /* draw_shadow */
|
|
DrawComponents, /* draw_components */
|
|
NULL, /* extension */
|
|
},
|
|
|
|
/* XfeLabel Part */
|
|
{
|
|
LayoutString, /* layout_string */
|
|
DrawString, /* draw_string */
|
|
XfeInheritDrawSelection, /* draw_selection */
|
|
GetLabelGC, /* get_label_gc */
|
|
XfeInheritGetSelectionGC, /* get_selection_gc */
|
|
NULL, /* extension */
|
|
},
|
|
|
|
/* XfeButton Part */
|
|
{
|
|
LayoutPixmap, /* layout_pixmap */
|
|
DrawPixmap, /* draw_pixmap */
|
|
DrawRaiseBorder, /* draw_raise_border */
|
|
DrawUnderline, /* draw_underline */
|
|
ArmTimeout, /* arm_timeout */
|
|
NULL, /* extension */
|
|
},
|
|
};
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* xfeButtonWidgetClass declaration. */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
_XFE_WIDGET_CLASS(button,Button);
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfeButton resource call procedures */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
DefaultArmBackground(Widget w,int offset,XrmValue * value)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
static Pixel arm_background;
|
|
|
|
if (bp->fill_on_arm)
|
|
{
|
|
arm_background = XfeSelectPixel(w,bp->raise_background);
|
|
}
|
|
else
|
|
{
|
|
arm_background = _XfeBackgroundPixel(w);
|
|
}
|
|
|
|
value->addr = (XPointer) &arm_background;
|
|
value->size = sizeof(arm_background);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
DefaultRaiseBackground(Widget w,int offset,XrmValue * value)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
static Pixel raise_background;
|
|
|
|
if (bp->fill_on_enter)
|
|
{
|
|
raise_background = XfeSelectPixel(w,_XfeBackgroundPixel(w));
|
|
}
|
|
else
|
|
{
|
|
raise_background = _XfeBackgroundPixel(w);
|
|
}
|
|
|
|
value->addr = (XPointer) &raise_background;
|
|
value->size = sizeof(raise_background);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Rep type registration functions */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
XfeButtonRegisterRepTypes(void)
|
|
{
|
|
static String layout_names[] =
|
|
{
|
|
"button_label_only",
|
|
"button_label_on_bottom",
|
|
"button_label_on_left",
|
|
"button_label_on_right",
|
|
"button_label_on_top",
|
|
"button_pixmap_only",
|
|
NULL
|
|
};
|
|
|
|
static String trigger_names[] =
|
|
{
|
|
"button_trigger_anywhere",
|
|
"button_trigger_label",
|
|
"button_trigger_pixmap",
|
|
"button_trigger_either",
|
|
"button_trigger_neither",
|
|
NULL
|
|
};
|
|
|
|
static String type_names[] =
|
|
{
|
|
"button_none",
|
|
"button_push",
|
|
"button_toggle",
|
|
NULL
|
|
};
|
|
|
|
XfeRepTypeRegister(XmRButtonLayout,layout_names);
|
|
XfeRepTypeRegister(XmRButtonTrigger,trigger_names);
|
|
XfeRepTypeRegister(XmRButtonType,type_names);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Core class methods */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
ClassInitialize()
|
|
{
|
|
/* Register XfeButton representation types */
|
|
XfeButtonRegisterRepTypes();
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
ClassPartInit(WidgetClass wc)
|
|
{
|
|
XfeButtonWidgetClass cc = (XfeButtonWidgetClass) wc;
|
|
XfeButtonWidgetClass sc = (XfeButtonWidgetClass) wc->core_class.superclass;
|
|
|
|
/* Resolve inheritance of all XfeButton class methods */
|
|
_XfeResolve(cc,sc,xfe_button_class,layout_pixmap,XfeInheritLayoutPixmap);
|
|
_XfeResolve(cc,sc,xfe_button_class,draw_pixmap,XfeInheritDrawPixmap);
|
|
|
|
_XfeResolve(cc,sc,xfe_button_class,draw_raise_border,
|
|
XfeInheritDrawRaiseBorder);
|
|
|
|
_XfeResolve(cc,sc,xfe_button_class,draw_underline,
|
|
XfeInheritDrawUnderline);
|
|
|
|
_XfeResolve(cc,sc,xfe_button_class,arm_timeout,XfeInheritArmTimeout);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
Initialize(Widget rw,Widget nw,ArgList args,Cardinal *nargs)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(nw);
|
|
XfeLabelPart * lp = _XfeLabelPart(nw);
|
|
|
|
/* Make sure rep types are ok */
|
|
XfeRepTypeCheck(nw,XmRButtonType,&bp->button_type,
|
|
XmBUTTON_PUSH);
|
|
|
|
XfeRepTypeCheck(nw,XmRButtonLayout,&bp->button_layout,
|
|
XmBUTTON_LABEL_ON_BOTTOM);
|
|
|
|
XfeRepTypeCheck(nw,XmRButtonTrigger,&bp->button_trigger,
|
|
XmBUTTON_TRIGGER_ANYWHERE);
|
|
|
|
/* Allocate the label raised GCs */
|
|
bp->label_raised_GC = XfeAllocateStringGc(nw,lp->font_list,
|
|
bp->raise_foreground,
|
|
None,True);
|
|
|
|
|
|
/* Allocate the label armed GCs */
|
|
bp->label_armed_GC = XfeAllocateStringGc(nw,lp->font_list,
|
|
bp->arm_foreground,
|
|
None,True);
|
|
|
|
/* Allocate the armed GCs */
|
|
bp->armed_GC = XfeAllocateColorGc(nw,bp->arm_background,None,True);
|
|
|
|
/* Allocate the raised GCs */
|
|
bp->raised_GC = XfeAllocateColorGc(nw,bp->raise_background,None,True);
|
|
|
|
/* Allocate the pixmap GC */
|
|
bp->pixmap_GC = XfeAllocateTransparentGc(nw);
|
|
|
|
/* Initialize other private members */
|
|
bp->clicking = False;
|
|
bp->transparent_cursor_state = False;
|
|
|
|
/* Make sure the background gc is allocated if needed */
|
|
if (_XfePixmapGood(bp->insensitive_pixmap))
|
|
{
|
|
_XfePrimitiveAllocateBackgroundGC(nw);
|
|
}
|
|
|
|
/* Need to track motion if trigger is not anywhere */
|
|
if (bp->button_trigger != XmBUTTON_TRIGGER_ANYWHERE)
|
|
{
|
|
XfeOverrideTranslations(nw,motion_add_translations);
|
|
}
|
|
|
|
/* Finish of initialization */
|
|
_XfePrimitiveChainInitialize(rw,nw,xfeButtonWidgetClass);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
Destroy(Widget w)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
|
|
/* Release GCs */
|
|
XtReleaseGC(w,bp->raised_GC);
|
|
XtReleaseGC(w,bp->label_raised_GC);
|
|
|
|
XtReleaseGC(w,bp->armed_GC);
|
|
XtReleaseGC(w,bp->label_armed_GC);
|
|
|
|
XtReleaseGC(w,bp->pixmap_GC);
|
|
|
|
/* Remove all CallBacks */
|
|
/* XtRemoveAllCallbacks(w,XmNactivateCallback); */
|
|
/* XtRemoveAllCallbacks(w,XmNarmCallback); */
|
|
/* XtRemoveAllCallbacks(w,XmNdisarmCallback); */
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static Boolean
|
|
SetValues(Widget ow,Widget rw,Widget nw,ArgList args,Cardinal *nargs)
|
|
{
|
|
XfeButtonPart * np = _XfeButtonPart(nw);
|
|
XfeButtonPart * op = _XfeButtonPart(ow);
|
|
XfeLabelPart * nlp = _XfeLabelPart(nw);
|
|
|
|
Boolean raised_gc_flag = False;
|
|
Boolean label_raised_gc_flag = False;
|
|
|
|
Boolean armed_gc_flag = False;
|
|
Boolean label_armed_gc_flag = False;
|
|
|
|
/* button_type */
|
|
if (np->button_type != op->button_type)
|
|
{
|
|
/* Make sure the new button type is ok */
|
|
XfeRepTypeCheck(nw,XmRButtonType,&np->button_type,
|
|
XmBUTTON_PUSH);
|
|
|
|
#if 0
|
|
/* If the new button_type is not toggle, make sure we are not armed */
|
|
if (np->button_type != XmBUTTON_TOGGLE)
|
|
{
|
|
np->armed = False;
|
|
}
|
|
#endif
|
|
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
}
|
|
|
|
/* button_layout */
|
|
if (np->button_layout != op->button_layout)
|
|
{
|
|
/* Make sure the new layout type is ok */
|
|
XfeRepTypeCheck(nw,XmRButtonLayout,&np->button_layout,
|
|
XmBUTTON_LABEL_ON_BOTTOM);
|
|
|
|
_XfeConfigFlags(nw) |= XfeConfigGLE;
|
|
}
|
|
|
|
/* button_trigger */
|
|
if (np->button_trigger != op->button_trigger)
|
|
{
|
|
/* Make sure the new trigger type is ok */
|
|
XfeRepTypeCheck(nw,XmRButtonTrigger,&np->button_trigger,
|
|
XmBUTTON_TRIGGER_ANYWHERE);
|
|
|
|
/* No motion tracking */
|
|
if (np->button_trigger == XmBUTTON_TRIGGER_ANYWHERE)
|
|
{
|
|
XfeOverrideTranslations(nw,_XfeButtonMotionRemoveTranslations);
|
|
}
|
|
/* Yes motion tracking */
|
|
else
|
|
{
|
|
XfeOverrideTranslations(nw,motion_add_translations);
|
|
}
|
|
}
|
|
|
|
/* raise_border_thickness */
|
|
if (np->raise_border_thickness != op->raise_border_thickness)
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigGLE;
|
|
}
|
|
|
|
/* arm_offset */
|
|
if (np->arm_offset != op->arm_offset)
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigGLE;
|
|
}
|
|
|
|
|
|
/* background */
|
|
if (_XfeBackgroundPixel(nw) != _XfeBackgroundPixel(ow))
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
}
|
|
|
|
if (np->determinate != op->determinate)
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
}
|
|
|
|
/* spacing */
|
|
if (np->spacing != op->spacing)
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigGLE;
|
|
}
|
|
|
|
/* pixmap */
|
|
if (np->pixmap != op->pixmap)
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigGLE;
|
|
|
|
_XfePrepareFlags(nw) |= _XFE_PREPARE_BUTTON_PIXMAP;
|
|
}
|
|
|
|
/* armed_pixmap */
|
|
if (np->armed_pixmap != op->armed_pixmap)
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
|
|
_XfePrepareFlags(nw) |= _XFE_PREPARE_BUTTON_ARMED_PIXMAP;
|
|
}
|
|
|
|
/* raised_pixmap */
|
|
if (np->raised_pixmap != op->raised_pixmap)
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
|
|
_XfePrepareFlags(nw) |= _XFE_PREPARE_BUTTON_RAISED_PIXMAP;
|
|
}
|
|
|
|
/* insensitive_pixmap */
|
|
if (np->insensitive_pixmap != op->insensitive_pixmap)
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
|
|
_XfePrepareFlags(nw) |= _XFE_PREPARE_BUTTON_INSENSITIVE_PIXMAP;
|
|
|
|
/* Make sure the background gc is allocated if needed */
|
|
if (_XfePixmapGood(np->insensitive_pixmap))
|
|
{
|
|
_XfePrimitiveAllocateBackgroundGC(nw);
|
|
}
|
|
}
|
|
|
|
/* armed */
|
|
if (np->armed != op->armed)
|
|
{
|
|
if (np->button_type == XmBUTTON_TOGGLE)
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
}
|
|
else
|
|
{
|
|
_XfeWarning(nw,MESSAGE17);
|
|
|
|
np->armed = op->armed;
|
|
}
|
|
}
|
|
|
|
/* raise_on_enter */
|
|
if (np->raise_on_enter != op->raise_on_enter)
|
|
{
|
|
/* Make sure we are not raised if raise_on_enter changes */
|
|
np->raised = False;
|
|
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
}
|
|
|
|
/* raised */
|
|
if (np->raised != op->raised)
|
|
{
|
|
if (!np->raise_on_enter)
|
|
{
|
|
_XfeWarning(nw,MESSAGE18);
|
|
|
|
np->raised = op->raised;
|
|
}
|
|
else
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
}
|
|
}
|
|
|
|
/* sensitive */
|
|
if (_XfeSensitive(nw) != _XfeSensitive(ow))
|
|
{
|
|
/* If button is now insensitive make sure old states are cleared */
|
|
if (!_XfeSensitive(nw))
|
|
{
|
|
np->armed = False;
|
|
np->clicking = False;
|
|
np->raised = False;
|
|
}
|
|
else
|
|
{
|
|
/* Button is now sensitive and pointer is inside */
|
|
if (_XfePointerInside(nw) && np->raise_on_enter)
|
|
{
|
|
/* The button is raised if the pointer is still inside */
|
|
np->raised = True;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* pretend_sensitive */
|
|
if (_XfePretendSensitive(nw) != _XfePretendSensitive(ow))
|
|
{
|
|
/*
|
|
* If button is now pretending to be insensitive, make sure
|
|
* old states are cleared
|
|
*/
|
|
if (!_XfePretendSensitive(nw))
|
|
{
|
|
np->armed = False;
|
|
np->clicking = False;
|
|
np->raised = False;
|
|
}
|
|
else
|
|
{
|
|
/* Button is now sensitive and pointer is inside */
|
|
if (_XfePointerInside(nw) && np->raise_on_enter)
|
|
{
|
|
/* The button is raised if the pointer is still inside */
|
|
np->raised = True;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* raise_foreground */
|
|
if (np->raise_foreground != op->raise_foreground)
|
|
{
|
|
label_raised_gc_flag = True;
|
|
|
|
if (np->raised)
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
}
|
|
}
|
|
|
|
/* arm_foreground */
|
|
if (np->arm_foreground != op->arm_foreground)
|
|
{
|
|
label_armed_gc_flag = True;
|
|
|
|
if (np->armed)
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
}
|
|
}
|
|
|
|
|
|
/* fill_on_arm */
|
|
if (np->fill_on_arm != op->fill_on_arm)
|
|
{
|
|
if (np->armed)
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
}
|
|
}
|
|
|
|
/* fill_on_enter */
|
|
if (np->fill_on_enter != op->fill_on_enter)
|
|
{
|
|
if (np->raised)
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
}
|
|
}
|
|
|
|
/* arm_background */
|
|
if (np->arm_background != op->arm_background)
|
|
{
|
|
armed_gc_flag = True;
|
|
|
|
if (np->armed && np->fill_on_arm)
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
}
|
|
}
|
|
|
|
/* raise_background */
|
|
if (np->raise_background != op->raise_background)
|
|
{
|
|
raised_gc_flag = True;
|
|
|
|
if (np->raised && np->fill_on_enter)
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
}
|
|
}
|
|
|
|
/* Update the label raised GC */
|
|
if (label_raised_gc_flag)
|
|
{
|
|
/* Release the old label raised GC */
|
|
XtReleaseGC(nw,np->label_raised_GC);
|
|
|
|
/* Allocate the new label raised GC */
|
|
np->label_raised_GC = XfeAllocateStringGc(nw,nlp->font_list,
|
|
np->raise_foreground,
|
|
None,True);
|
|
}
|
|
|
|
/* Update the label armed GC */
|
|
if (label_armed_gc_flag)
|
|
{
|
|
/* Release the old label armed GC */
|
|
XtReleaseGC(nw,np->label_armed_GC);
|
|
|
|
/* Allocate the new label armed GC */
|
|
np->label_armed_GC = XfeAllocateStringGc(nw,nlp->font_list,
|
|
np->arm_foreground,
|
|
None,True);
|
|
}
|
|
|
|
/* Update the armed GC */
|
|
if (armed_gc_flag)
|
|
{
|
|
/* Release the old armed GC */
|
|
XtReleaseGC(nw,np->armed_GC);
|
|
|
|
/* Allocate the new armed GC */
|
|
np->armed_GC = XfeAllocateColorGc(nw,np->arm_background,None,True);
|
|
}
|
|
|
|
/* Update the raised GC */
|
|
if (raised_gc_flag)
|
|
{
|
|
/* Release the old raised GC */
|
|
XtReleaseGC(nw,np->raised_GC);
|
|
|
|
/* Allocate the new raised GC */
|
|
np->raised_GC = XfeAllocateColorGc(nw,np->raise_background,None,True);
|
|
}
|
|
|
|
return _XfePrimitiveChainSetValues(ow,rw,nw,xfeButtonWidgetClass);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfePrimitive methods */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
PreferredGeometry(Widget w,Dimension *width,Dimension *height)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
XfeLabelPart * lp = _XfeLabelPart(w);
|
|
|
|
*width = _XfeOffsetLeft(w) + _XfeOffsetRight(w);
|
|
*height = _XfeOffsetTop(w) + _XfeOffsetBottom(w);
|
|
|
|
/* Include the arm_offset if needed */
|
|
if (bp->button_type != XmBUTTON_NONE)
|
|
{
|
|
*width += (2 * bp->arm_offset);
|
|
*height += (2 * bp->arm_offset);
|
|
}
|
|
|
|
/* Include the raise_border_thickenss if needed */
|
|
if (bp->raise_on_enter)
|
|
{
|
|
*width += (2 * bp->raise_border_thickness);
|
|
*height += (2 * bp->raise_border_thickness);
|
|
}
|
|
|
|
switch(bp->button_layout)
|
|
{
|
|
case XmBUTTON_LABEL_ONLY:
|
|
|
|
*width += lp->label_rect.width;
|
|
*height += lp->label_rect.height;
|
|
|
|
break;
|
|
|
|
case XmBUTTON_LABEL_ON_BOTTOM:
|
|
case XmBUTTON_LABEL_ON_TOP:
|
|
|
|
if (bp->pixmap_rect.width && bp->pixmap_rect.height)
|
|
{
|
|
*width +=
|
|
XfeMax(bp->pixmap_rect.width,lp->label_rect.width);
|
|
|
|
*height +=
|
|
(bp->pixmap_rect.height + lp->label_rect.height + bp->spacing);
|
|
}
|
|
else
|
|
{
|
|
*width += lp->label_rect.width;
|
|
*height += lp->label_rect.height;
|
|
}
|
|
|
|
break;
|
|
|
|
case XmBUTTON_LABEL_ON_LEFT:
|
|
case XmBUTTON_LABEL_ON_RIGHT:
|
|
|
|
if (bp->pixmap_rect.width && bp->pixmap_rect.height)
|
|
{
|
|
*height +=
|
|
XfeMax(bp->pixmap_rect.height,lp->label_rect.height);
|
|
|
|
*width +=
|
|
(bp->pixmap_rect.width + lp->label_rect.width + bp->spacing);
|
|
}
|
|
else
|
|
{
|
|
*width += lp->label_rect.width;
|
|
*height += lp->label_rect.height;
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
case XmBUTTON_PIXMAP_ONLY:
|
|
|
|
*width += bp->pixmap_rect.width;
|
|
*height += bp->pixmap_rect.height;
|
|
|
|
break;
|
|
}
|
|
|
|
/* Include the underline thickness if needed */
|
|
if ((bp->underline_thickness > 0) &&
|
|
(bp->button_layout != XmBUTTON_PIXMAP_ONLY))
|
|
{
|
|
Dimension underline_height =
|
|
bp->underline_thickness +
|
|
UNDERLINE_SPACING;
|
|
|
|
if (bp->button_layout == XmBUTTON_LABEL_ON_BOTTOM ||
|
|
bp->button_layout == XmBUTTON_LABEL_ON_TOP ||
|
|
bp->button_layout == XmBUTTON_LABEL_ONLY)
|
|
{
|
|
*height += underline_height;
|
|
}
|
|
else if (bp->button_layout == XmBUTTON_LABEL_ON_LEFT ||
|
|
bp->button_layout == XmBUTTON_LABEL_ON_RIGHT)
|
|
{
|
|
/* Obtain the difference in height for the pixmap and label */
|
|
int height_difference =
|
|
(int) bp->pixmap_rect.height -
|
|
(int) lp->label_rect.height;
|
|
|
|
/* Pixmap is taller. We might have space for the underline */
|
|
if (height_difference > 0)
|
|
{
|
|
/* Not enough. Add the extra needed space to the height */
|
|
if (height_difference < underline_height)
|
|
{
|
|
*height += (underline_height - height_difference);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
PrepareComponents(Widget w,int flags)
|
|
{
|
|
if (flags & _XFE_PREPARE_BUTTON_PIXMAP)
|
|
{
|
|
PixmapPrepare(w);
|
|
}
|
|
|
|
if (flags & _XFE_PREPARE_BUTTON_ARMED_PIXMAP)
|
|
{
|
|
PixmapArmedPrepare(w);
|
|
}
|
|
|
|
if (flags & _XFE_PREPARE_BUTTON_RAISED_PIXMAP)
|
|
{
|
|
PixmapRaisedPrepare(w);
|
|
}
|
|
|
|
if (flags & _XFE_PREPARE_BUTTON_INSENSITIVE_PIXMAP)
|
|
{
|
|
PixmapInsensPrepare(w);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
LayoutComponents(Widget w)
|
|
/*----------------------------------------------------------------------*/
|
|
{
|
|
/* Invoke layout_string method */
|
|
_XfeLabelLayoutString(w);
|
|
|
|
/* Invoke layout_pixmap method */
|
|
_XfeButtonLayoutPixmap(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);
|
|
|
|
/* Invoke draw_pixmap method */
|
|
_XfeButtonDrawPixmap(w,event,region,clip_rect);
|
|
|
|
/* Invoke draw_raise_border method */
|
|
_XfeButtonDrawRaiseBorder(w,event,region,clip_rect);
|
|
|
|
/* Invoke draw_underline method */
|
|
_XfeButtonDrawUnderline(w,event,region,clip_rect);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
DrawShadow(Widget w,XEvent * event,Region region,XRectangle * clip_rect)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
unsigned char shadow_type = _XfeShadowType(w);
|
|
Boolean need_shadow = True;
|
|
|
|
if (!_XfeShadowThickness(w))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (bp->raise_on_enter)
|
|
{
|
|
if (bp->armed)
|
|
{
|
|
shadow_type = XmSHADOW_IN;
|
|
}
|
|
else if (bp->raised)
|
|
{
|
|
shadow_type = XmSHADOW_OUT;
|
|
}
|
|
else
|
|
{
|
|
need_shadow = False;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* For both toggle and push the shadow depends on the arming state */
|
|
if (bp->button_type != XmBUTTON_NONE)
|
|
{
|
|
shadow_type = bp->armed ? XmSHADOW_IN : XmSHADOW_OUT;
|
|
}
|
|
}
|
|
|
|
/* Draw the shadow only if needed */
|
|
if (need_shadow)
|
|
{
|
|
Dimension raise_offset = RAISE_OFFSET(bp);
|
|
|
|
_XmDrawShadows(XtDisplay(w),
|
|
|
|
_XfePrimitiveDrawable(w),
|
|
|
|
_XfeTopShadowGC(w),_XfeBottomShadowGC(w),
|
|
|
|
_XfeHighlightThickness(w) + raise_offset,
|
|
|
|
_XfeHighlightThickness(w) + raise_offset,
|
|
|
|
_XfeWidth(w) -
|
|
2 * _XfeHighlightThickness(w) -
|
|
2 * raise_offset,
|
|
|
|
_XfeHeight(w) -
|
|
2 * _XfeHighlightThickness(w) -
|
|
2 * raise_offset,
|
|
|
|
_XfeShadowThickness(w),
|
|
|
|
shadow_type);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
DrawBackground(Widget w,XEvent *event,Region region,XRectangle * clip_rect)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
|
|
/* Fill the background if needed */
|
|
if (bp->fill_on_arm && bp->armed)
|
|
{
|
|
XFillRectangle(XtDisplay(w),
|
|
_XfePrimitiveDrawable(w),
|
|
bp->armed_GC,
|
|
0,0,
|
|
_XfeWidth(w),_XfeHeight(w));
|
|
}
|
|
else if (bp->fill_on_enter && (bp->raised || _XfePointerInside(w)))
|
|
{
|
|
XFillRectangle(XtDisplay(w),
|
|
_XfePrimitiveDrawable(w),
|
|
bp->raised_GC,
|
|
0,0,
|
|
_XfeWidth(w),_XfeHeight(w));
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfeLabel methods */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
LayoutString(Widget w)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
|
|
if ((bp->button_layout == XmBUTTON_LABEL_ONLY) ||
|
|
!bp->pixmap_rect.width || !bp->pixmap_rect.height)
|
|
{
|
|
StringLayoutLabelOnly(w);
|
|
}
|
|
else
|
|
{
|
|
/* Layout the label according to the button's layout */
|
|
switch(bp->button_layout)
|
|
{
|
|
case XmBUTTON_LABEL_ON_BOTTOM:
|
|
|
|
StringLayoutLabelOnBottom(w);
|
|
|
|
break;
|
|
|
|
case XmBUTTON_LABEL_ON_TOP:
|
|
|
|
StringLayoutLabelOnTop(w);
|
|
|
|
break;
|
|
|
|
case XmBUTTON_LABEL_ON_LEFT:
|
|
|
|
StringLayoutLabelOnLeft(w);
|
|
|
|
break;
|
|
|
|
case XmBUTTON_LABEL_ON_RIGHT:
|
|
|
|
StringLayoutLabelOnRight(w);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
DrawString(Widget w,XEvent * event,Region region,XRectangle * clip_rect)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
XfeLabelPart * lp = _XfeLabelPart(w);
|
|
XfeLabelWidgetClass lwc = (XfeLabelWidgetClass) xfeLabelWidgetClass;
|
|
|
|
/* Make sure the label needs to be drawn */
|
|
if (bp->button_layout == XmBUTTON_PIXMAP_ONLY)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Set the label's misc offset to the arm offset if needed */
|
|
lp->misc_offset = bp->armed ? bp->arm_offset : 0;
|
|
|
|
|
|
/* Explicit invoke of XfeLabel's draw_string() method */
|
|
(*lwc->xfe_label_class.draw_string)(w,event,region,clip_rect);
|
|
|
|
/* Restore the label's misc offset */
|
|
lp->misc_offset = 0;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static GC
|
|
GetLabelGC(Widget w)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
XfeLabelPart * lp = _XfeLabelPart(w);
|
|
GC gc = lp->label_GC;
|
|
|
|
if (bp->armed)
|
|
{
|
|
gc = bp->label_armed_GC;
|
|
}
|
|
else if (bp->raised)
|
|
{
|
|
gc = bp->label_raised_GC;
|
|
}
|
|
|
|
return gc;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfeButton class methods */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
LayoutPixmap(Widget w)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
XfeLabelPart * lp = _XfeLabelPart(w);
|
|
|
|
if ((bp->button_layout == XmBUTTON_PIXMAP_ONLY) ||
|
|
!lp->label_rect.width || !lp->label_rect.height)
|
|
{
|
|
bp->pixmap_rect.x = (_XfeWidth(w) - bp->pixmap_rect.width) / 2;
|
|
bp->pixmap_rect.y = (_XfeHeight(w) - bp->pixmap_rect.height) / 2;
|
|
}
|
|
else
|
|
{
|
|
Dimension raise_offset = RAISE_OFFSET(bp);
|
|
|
|
/* Layout the label according to the button's layout */
|
|
switch(bp->button_layout)
|
|
{
|
|
case XmBUTTON_LABEL_ON_BOTTOM:
|
|
|
|
bp->pixmap_rect.x = (_XfeWidth(w) - bp->pixmap_rect.width) / 2;
|
|
|
|
bp->pixmap_rect.y = _XfeOffsetTop(w) + raise_offset;
|
|
|
|
break;
|
|
|
|
case XmBUTTON_LABEL_ON_TOP:
|
|
|
|
bp->pixmap_rect.x = (_XfeWidth(w) - bp->pixmap_rect.width) / 2;
|
|
|
|
bp->pixmap_rect.y =
|
|
_XfeHeight(w) -
|
|
_XfeOffsetBottom(w) -
|
|
bp->pixmap_rect.height -
|
|
raise_offset;
|
|
|
|
break;
|
|
|
|
case XmBUTTON_LABEL_ON_LEFT:
|
|
|
|
bp->pixmap_rect.y = (_XfeHeight(w) - bp->pixmap_rect.height) / 2;
|
|
|
|
bp->pixmap_rect.x =
|
|
_XfeWidth(w) -
|
|
_XfeOffsetRight(w) -
|
|
bp->pixmap_rect.width -
|
|
raise_offset;
|
|
|
|
break;
|
|
|
|
case XmBUTTON_LABEL_ON_RIGHT:
|
|
|
|
bp->pixmap_rect.y = (_XfeHeight(w) - bp->pixmap_rect.height) / 2;
|
|
|
|
bp->pixmap_rect.x = _XfeOffsetLeft(w) + raise_offset;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
DrawPixmap(Widget w,XEvent * event,Region region,XRectangle * clip_rect)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
Pixmap pixmap = XmUNSPECIFIED_PIXMAP;
|
|
Pixmap mask = XmUNSPECIFIED_PIXMAP;
|
|
Boolean insensitive = False;
|
|
|
|
/* Make sure the pixmap needs to be drawn */
|
|
if (bp->button_layout == XmBUTTON_LABEL_ONLY)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Determine if the button is insensitive */
|
|
insensitive = (!_XfeIsSensitive(w) || !bp->determinate);
|
|
|
|
/* Determine which pixmap to use */
|
|
/* for indeterminate state, use insensitive pixmap */
|
|
if (insensitive && _XfePixmapGood(bp->insensitive_pixmap))
|
|
{
|
|
pixmap = bp->insensitive_pixmap;
|
|
mask = bp->insensitive_pixmap_mask;
|
|
}
|
|
else if (bp->armed && _XfePixmapGood(bp->armed_pixmap))
|
|
{
|
|
pixmap = bp->armed_pixmap;
|
|
mask = bp->armed_pixmap_mask;
|
|
}
|
|
else if (bp->raised && _XfePixmapGood(bp->raised_pixmap))
|
|
{
|
|
pixmap = bp->raised_pixmap;
|
|
mask = bp->raised_pixmap_mask;
|
|
}
|
|
else
|
|
{
|
|
pixmap = bp->pixmap;
|
|
mask = bp->pixmap_mask;
|
|
}
|
|
|
|
/* Make sure the pixmap is good before rendering it */
|
|
if (_XfePixmapGood(pixmap) &&
|
|
bp->pixmap_rect.width &&
|
|
bp->pixmap_rect.height)
|
|
{
|
|
Dimension offset = bp->armed ? bp->arm_offset : 0;
|
|
Position x = bp->pixmap_rect.x + offset;
|
|
Position y = bp->pixmap_rect.y + offset;
|
|
|
|
if (_XfePixmapGood(mask))
|
|
{
|
|
XSetClipOrigin(XtDisplay(w),bp->pixmap_GC,x,y);
|
|
XSetClipMask(XtDisplay(w),bp->pixmap_GC,mask);
|
|
}
|
|
else
|
|
{
|
|
XSetClipMask(XtDisplay(w),bp->pixmap_GC,None);
|
|
}
|
|
|
|
XCopyArea(XtDisplay(w),
|
|
pixmap,
|
|
_XfePrimitiveDrawable(w),
|
|
bp->pixmap_GC,
|
|
0,0,
|
|
bp->pixmap_rect.width,
|
|
bp->pixmap_rect.height,
|
|
x,
|
|
y);
|
|
|
|
/*
|
|
* If the button is insensitive and the pixmap we just
|
|
* rendered is not the XmNinsensitivePixmap, then we
|
|
* need to also render the insensitive effect.
|
|
*/
|
|
if (insensitive && (pixmap != bp->insensitive_pixmap))
|
|
{
|
|
assert( _XfeBackgroundGC(w) != NULL );
|
|
|
|
XfeStippleRectangle(XtDisplay(w),
|
|
_XfePrimitiveDrawable(w),
|
|
_XfeBackgroundGC(w),
|
|
x,
|
|
y,
|
|
bp->pixmap_rect.width,
|
|
bp->pixmap_rect.height,
|
|
2);
|
|
}
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
DrawRaiseBorder(Widget w,XEvent *event,Region region,XRectangle * clip_rect)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
|
|
/* Make sure the thickness of the raise border ain't 0 */
|
|
if (bp->raise_border_thickness == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* The border is only needed if raise_on_enter is true or we are in
|
|
* a special clicking state (between Arm() and Disarm())
|
|
*/
|
|
if (!bp->raise_on_enter && !bp->armed)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (bp->raised || (bp->raise_on_enter && bp->armed && bp->clicking))
|
|
{
|
|
XfeDrawRectangle(XtDisplay(w),
|
|
|
|
_XfePrimitiveDrawable(w),
|
|
|
|
_XfeHighlightGC(w),
|
|
|
|
_XfeHighlightThickness(w),
|
|
|
|
_XfeHighlightThickness(w),
|
|
|
|
_XfeWidth(w) - 2 * _XfeHighlightThickness(w),
|
|
|
|
_XfeHeight(w) - 2 * _XfeHighlightThickness(w),
|
|
|
|
bp->raise_border_thickness);
|
|
}
|
|
else
|
|
{
|
|
XfeDrawRectangle(XtDisplay(w),
|
|
|
|
_XfePrimitiveDrawable(w),
|
|
|
|
_XfemBackgroundGC(XtParent(w)),
|
|
|
|
_XfeHighlightThickness(w),
|
|
|
|
_XfeHighlightThickness(w),
|
|
|
|
_XfeWidth(w) - 2 * _XfeHighlightThickness(w),
|
|
|
|
_XfeHeight(w) - 2 * _XfeHighlightThickness(w),
|
|
|
|
bp->raise_border_thickness);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
DrawUnderline(Widget w,XEvent *event,Region region,XRectangle * clip_rect)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
XfeLabelPart * lp = _XfeLabelPart(w);
|
|
GC underline_gc = NULL;
|
|
|
|
/* Make sure there is a label to underline */
|
|
if (bp->button_layout == XmBUTTON_PIXMAP_ONLY)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Make sure the underline thickness ain't 0 */
|
|
if (bp->underline_thickness == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
underline_gc = _XfeLabelGetLabelGC(w);
|
|
|
|
assert( underline_gc != NULL );
|
|
|
|
XFillRectangle(XtDisplay(w),_XfePrimitiveDrawable(w),
|
|
|
|
underline_gc,
|
|
|
|
lp->label_rect.x,
|
|
|
|
lp->label_rect.y +
|
|
lp->label_rect.height +
|
|
UNDERLINE_SPACING,
|
|
|
|
lp->label_rect.width,
|
|
|
|
bp->underline_thickness);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
ArmTimeout(XtPointer client_data,XtIntervalId * id)
|
|
{
|
|
/* Write me */
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Misc XfeButton functions */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
PixmapPrepare(Widget w)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
|
|
_XfePixmapPrepare(w,
|
|
&bp->pixmap,
|
|
&bp->pixmap_rect.width,
|
|
&bp->pixmap_rect.height,
|
|
XmNpixmap);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
PixmapArmedPrepare(Widget w)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
XRectangle rect;
|
|
|
|
_XfePixmapPrepare(w,
|
|
&bp->armed_pixmap,
|
|
&rect.width,
|
|
&rect.height,
|
|
XmNarmedPixmap);
|
|
|
|
if (_XfePixmapGood(bp->armed_pixmap))
|
|
{
|
|
/* Make sure the normal pixmap is defined */
|
|
if (_XfePixmapGood(bp->pixmap))
|
|
{
|
|
/* Make sure the geometry matches the main pixmap's */
|
|
if ((rect.width != bp->pixmap_rect.width) ||
|
|
(rect.height != bp->pixmap_rect.height))
|
|
{
|
|
bp->armed_pixmap = XmUNSPECIFIED_PIXMAP;
|
|
|
|
_XfeWarning(w,MESSAGE10);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bp->armed_pixmap = XmUNSPECIFIED_PIXMAP;
|
|
|
|
_XfeWarning(w,MESSAGE7);
|
|
}
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
PixmapRaisedPrepare(Widget w)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
XRectangle rect;
|
|
|
|
_XfePixmapPrepare(w,
|
|
&bp->raised_pixmap,
|
|
&rect.width,
|
|
&rect.height,
|
|
XmNraisedPixmap);
|
|
|
|
if (_XfePixmapGood(bp->raised_pixmap))
|
|
{
|
|
/* Make sure the normal pixmap is defined */
|
|
if (_XfePixmapGood(bp->pixmap))
|
|
{
|
|
/* Make sure the geometry matches the main pixmap's */
|
|
if ((rect.width != bp->pixmap_rect.width) ||
|
|
(rect.height != bp->pixmap_rect.height))
|
|
{
|
|
bp->raised_pixmap = XmUNSPECIFIED_PIXMAP;
|
|
|
|
_XfeWarning(w,MESSAGE11);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bp->raised_pixmap = XmUNSPECIFIED_PIXMAP;
|
|
|
|
_XfeWarning(w,MESSAGE8);
|
|
}
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
PixmapInsensPrepare(Widget w)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
XRectangle rect;
|
|
|
|
_XfePixmapPrepare(w,
|
|
&bp->insensitive_pixmap,
|
|
&rect.width,
|
|
&rect.height,
|
|
XmNinsensitivePixmap);
|
|
|
|
if (_XfePixmapGood(bp->insensitive_pixmap))
|
|
{
|
|
/* Make sure the normal pixmap is defined */
|
|
if (_XfePixmapGood(bp->pixmap))
|
|
{
|
|
/* Make sure the geometry matches the main pixmap's */
|
|
if ((rect.width != bp->pixmap_rect.width) ||
|
|
(rect.height != bp->pixmap_rect.height))
|
|
{
|
|
bp->insensitive_pixmap = XmUNSPECIFIED_PIXMAP;
|
|
|
|
_XfeWarning(w,MESSAGE12);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bp->insensitive_pixmap = XmUNSPECIFIED_PIXMAP;
|
|
|
|
_XfeWarning(w,MESSAGE9);
|
|
}
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
StringLayoutLabelOnly(Widget w)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
XfeLabelPart * lp = _XfeLabelPart(w);
|
|
|
|
/* Layout horizontally according to alignment */
|
|
switch(lp->label_alignment)
|
|
{
|
|
case XmALIGNMENT_BEGINNING:
|
|
|
|
lp->label_rect.x = _XfeBoundaryX(w) + RAISE_OFFSET(bp);
|
|
|
|
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) -
|
|
RAISE_OFFSET(bp);
|
|
|
|
break;
|
|
}
|
|
|
|
/* Layout vertically centred */
|
|
lp->label_rect.y = (_XfeHeight(w) - lp->label_rect.height) / 2;
|
|
|
|
/* Subtract the underline thickness if needed */
|
|
if (bp->underline_thickness > 0)
|
|
{
|
|
lp->label_rect.y -=
|
|
((bp->underline_thickness + UNDERLINE_SPACING) / 2);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
StringLayoutLabelOnBottom(Widget w)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
XfeLabelPart * lp = _XfeLabelPart(w);
|
|
|
|
/* Layout horizontally according to alignment */
|
|
switch(lp->label_alignment)
|
|
{
|
|
case XmALIGNMENT_BEGINNING:
|
|
|
|
lp->label_rect.x = _XfeBoundaryX(w) + RAISE_OFFSET(bp);
|
|
|
|
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) -
|
|
RAISE_OFFSET(bp);
|
|
|
|
break;
|
|
}
|
|
|
|
/* Layout horizontally on bottom */
|
|
lp->label_rect.y =
|
|
_XfeHeight(w) -
|
|
_XfeOffsetBottom(w) -
|
|
lp->label_rect.height -
|
|
RAISE_OFFSET(bp);
|
|
|
|
/* Subtract the underline thickness if needed */
|
|
if (bp->underline_thickness > 0)
|
|
{
|
|
lp->label_rect.y -= (bp->underline_thickness + UNDERLINE_SPACING);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
StringLayoutLabelOnTop(Widget w)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
XfeLabelPart * lp = _XfeLabelPart(w);
|
|
|
|
/* Layout horizontally according to alignment */
|
|
switch(lp->label_alignment)
|
|
{
|
|
case XmALIGNMENT_BEGINNING:
|
|
|
|
lp->label_rect.x = _XfeBoundaryX(w) + RAISE_OFFSET(bp);
|
|
|
|
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) -
|
|
RAISE_OFFSET(bp);
|
|
|
|
break;
|
|
}
|
|
|
|
/* Layout horizontally on top */
|
|
lp->label_rect.y = _XfeOffsetTop(w) + RAISE_OFFSET(bp);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
StringLayoutLabelOnLeft(Widget w)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
XfeLabelPart * lp = _XfeLabelPart(w);
|
|
|
|
lp->label_rect.x = _XfeOffsetLeft(w) + RAISE_OFFSET(bp);
|
|
|
|
lp->label_rect.y = (_XfeHeight(w) - lp->label_rect.height) / 2;
|
|
|
|
/* Subtract the underline thickness if needed */
|
|
if (bp->underline_thickness > 0)
|
|
{
|
|
lp->label_rect.y -=
|
|
((bp->underline_thickness + UNDERLINE_SPACING) / 2);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
StringLayoutLabelOnRight(Widget w)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
XfeLabelPart * lp = _XfeLabelPart(w);
|
|
|
|
lp->label_rect.x =
|
|
_XfeWidth(w) -
|
|
_XfeOffsetRight(w) -
|
|
lp->label_rect.width -
|
|
RAISE_OFFSET(bp);
|
|
|
|
lp->label_rect.y = (_XfeHeight(w) - lp->label_rect.height) / 2;
|
|
|
|
/* Subtract the underline thickness if needed */
|
|
if (bp->underline_thickness > 0)
|
|
{
|
|
lp->label_rect.y -=
|
|
((bp->underline_thickness + UNDERLINE_SPACING) / 2);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
InvokeCallback(Widget w,XtCallbackList list,int reason,XEvent * event)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
|
|
/* Invoke the callbacks only if needed */
|
|
if (list)
|
|
{
|
|
XfeButtonCallbackStruct cbs;
|
|
|
|
cbs.event = event;
|
|
cbs.reason = reason;
|
|
cbs.armed = bp->armed;
|
|
cbs.raised = bp->raised;
|
|
|
|
/* Flush the display */
|
|
XFlush(XtDisplay(w));
|
|
|
|
/* Invoke the Callback List */
|
|
XtCallCallbackList(w,list,&cbs);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static Boolean
|
|
AcceptEvent(Widget w,XEvent * event)
|
|
{
|
|
int x;
|
|
int y;
|
|
|
|
/* Obtain the event coords */
|
|
if (XfeEventGetXY(event,&x,&y))
|
|
{
|
|
return XfeButtonAcceptXY(w,x,y);
|
|
}
|
|
|
|
return False;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static Boolean
|
|
SpacingContainsXY(Widget w,int x,int y)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
XfeLabelPart * lp = _XfeLabelPart(w);
|
|
|
|
/* Check whether the coords are inside the spacing only if its > 0 */
|
|
if (bp->spacing > 0)
|
|
{
|
|
XRectangle rect;
|
|
|
|
if (bp->button_layout == XmBUTTON_LABEL_ON_BOTTOM)
|
|
{
|
|
XfeRectSet(&rect,
|
|
(_XfeWidth(w) - MIN_COMP_WIDTH(lp,bp)) / 2,
|
|
lp->label_rect.y - bp->spacing,
|
|
MIN_COMP_WIDTH(lp,bp),
|
|
bp->spacing);
|
|
}
|
|
else if (bp->button_layout == XmBUTTON_LABEL_ON_TOP)
|
|
{
|
|
XfeRectSet(&rect,
|
|
(_XfeWidth(w) - MIN_COMP_WIDTH(lp,bp)) / 2,
|
|
bp->pixmap_rect.y - bp->spacing,
|
|
MIN_COMP_WIDTH(lp,bp),
|
|
bp->spacing);
|
|
}
|
|
else if (bp->button_layout == XmBUTTON_LABEL_ON_LEFT)
|
|
{
|
|
XfeRectSet(&rect,
|
|
bp->pixmap_rect.x - bp->spacing,
|
|
(_XfeHeight(w) - MIN_COMP_HEIGHT(lp,bp)) / 2,
|
|
bp->spacing,
|
|
MIN_COMP_HEIGHT(lp,bp));
|
|
}
|
|
else if (bp->button_layout == XmBUTTON_LABEL_ON_RIGHT)
|
|
{
|
|
XfeRectSet(&rect,
|
|
lp->label_rect.x - bp->spacing,
|
|
(_XfeHeight(w) - MIN_COMP_HEIGHT(lp,bp)) / 2,
|
|
bp->spacing,
|
|
MIN_COMP_HEIGHT(lp,bp));
|
|
}
|
|
|
|
return XfePointInRect(&rect,x,y);
|
|
}
|
|
|
|
return False;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
TransparentCursorSetState(Widget w,Boolean state)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
|
|
/* Make sure the transparent cursor is good and we are sensitive */
|
|
if (!_XfeCursorGood(bp->transparent_cursor) || !_XfeIsSensitive(w))
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Make sure the state has changed */
|
|
if (state == bp->transparent_cursor_state)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Update the state */
|
|
bp->transparent_cursor_state = state;
|
|
|
|
if(state)
|
|
{
|
|
XfeCursorDefine(w,bp->transparent_cursor);
|
|
}
|
|
else
|
|
{
|
|
XfeCursorUndefine(w);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfeButton Method invocation functions */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfeButtonLayoutPixmap(Widget w)
|
|
{
|
|
XfeButtonWidgetClass bc = (XfeButtonWidgetClass) XtClass(w);
|
|
|
|
if (bc->xfe_button_class.layout_pixmap)
|
|
{
|
|
(*bc->xfe_button_class.layout_pixmap)(w);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfeButtonDrawPixmap(Widget w,
|
|
XEvent * event,
|
|
Region region,
|
|
XRectangle * clip_rect)
|
|
{
|
|
XfeButtonWidgetClass bc = (XfeButtonWidgetClass) XtClass(w);
|
|
|
|
if (bc->xfe_button_class.draw_pixmap)
|
|
{
|
|
(*bc->xfe_button_class.draw_pixmap)(w,event,region,clip_rect);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfeButtonDrawRaiseBorder(Widget w,
|
|
XEvent * event,
|
|
Region region,
|
|
XRectangle * clip_rect)
|
|
{
|
|
XfeButtonWidgetClass bc = (XfeButtonWidgetClass) XtClass(w);
|
|
|
|
if (bc->xfe_button_class.draw_raise_border)
|
|
{
|
|
(*bc->xfe_button_class.draw_raise_border)(w,event,region,clip_rect);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfeButtonDrawUnderline(Widget w,
|
|
XEvent * event,
|
|
Region region,
|
|
XRectangle * clip_rect)
|
|
{
|
|
XfeButtonWidgetClass bc = (XfeButtonWidgetClass) XtClass(w);
|
|
|
|
if (bc->xfe_button_class.draw_underline)
|
|
{
|
|
(*bc->xfe_button_class.draw_underline)(w,event,region,clip_rect);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfeButtonArmTimeout(Widget w,XtPointer client_data,XtIntervalId * id)
|
|
{
|
|
XfeButtonWidgetClass bc = (XfeButtonWidgetClass) XtClass(w);
|
|
|
|
if (bc->xfe_button_class.arm_timeout)
|
|
{
|
|
(*bc->xfe_button_class.arm_timeout)(client_data,id);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfeButton action procedures */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfeButtonEnter(Widget w,XEvent * event,char ** params,Cardinal * nparams)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
Boolean redisplay = False;
|
|
|
|
/* Accept the event based on the button_trigger resource. This needs to
|
|
* happen before we call _XfePrimitiveEnter() so that enter callbacks
|
|
* don't get called.
|
|
*/
|
|
if (!AcceptEvent(w,event))
|
|
{
|
|
/* Turn the transparent cursor on */
|
|
TransparentCursorSetState(w,True);
|
|
|
|
return;
|
|
}
|
|
|
|
if (XfeEventGetModifiers(event) & Button1Mask)
|
|
{
|
|
if (bp->transparent_cursor_state)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* First, invoke the XfePrimitive's enter action */
|
|
_XfePrimitiveEnter(w,event,params,nparams);
|
|
|
|
/* Make sure we are not pretending to be insensitive */
|
|
if (!_XfeIsSensitive(w))
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Adjust armed state if needed */
|
|
if (bp->clicking && !bp->emulate_motif)
|
|
{
|
|
bp->armed = True;
|
|
|
|
redisplay = True;
|
|
}
|
|
|
|
/* Adjust raised state if needed */
|
|
if (bp->raise_on_enter)
|
|
{
|
|
if (!bp->clicking)
|
|
{
|
|
bp->raised = True;
|
|
|
|
redisplay = True;
|
|
}
|
|
}
|
|
else if (bp->fill_on_enter)
|
|
{
|
|
redisplay = True;
|
|
}
|
|
|
|
if (redisplay)
|
|
{
|
|
/* 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
|
|
_XfeButtonLeave(Widget w,XEvent * event,char ** params,Cardinal * nparams)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
Boolean redisplay = False;
|
|
|
|
/* Turn the transparent cursor off if needed */
|
|
if (bp->button_trigger != XmBUTTON_TRIGGER_ANYWHERE)
|
|
{
|
|
TransparentCursorSetState(w,False);
|
|
}
|
|
|
|
/* First, invoke the XfePrimitive's leave action */
|
|
_XfePrimitiveLeave(w,event,params,nparams);
|
|
|
|
/* Make sure we are not pretending to be insensitive */
|
|
if (!_XfeIsSensitive(w))
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Adjust armed state if needed */
|
|
if (bp->armed && !bp->emulate_motif)
|
|
{
|
|
bp->armed = False;
|
|
|
|
redisplay = True;
|
|
}
|
|
|
|
/* Adjust raised state if needed */
|
|
if (bp->raise_on_enter)
|
|
{
|
|
if (!bp->clicking)
|
|
{
|
|
bp->raised = False;
|
|
|
|
redisplay = True;
|
|
}
|
|
}
|
|
else if (bp->fill_on_enter)
|
|
{
|
|
redisplay = True;
|
|
}
|
|
|
|
if (redisplay)
|
|
{
|
|
/* 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
|
|
_XfeButtonMotion(Widget w,XEvent * event,char ** params,Cardinal * nparams)
|
|
{
|
|
/* Make sure a button is not being pressed */
|
|
if (XfeEventGetModifiers(event) & Button1Mask)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* If the event is accepted, pretend we got an enter event. If not,
|
|
* pretend we got a leave event.
|
|
*/
|
|
if (AcceptEvent(w,event))
|
|
{
|
|
if (!_XfePointerInside(w))
|
|
{
|
|
/* Turn the transparent cursor off */
|
|
TransparentCursorSetState(w,False);
|
|
|
|
_XfeButtonEnter(w,event,params,nparams);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (_XfePointerInside(w))
|
|
{
|
|
_XfeButtonLeave(w,event,params,nparams);
|
|
|
|
/* Turn the transparent cursor on */
|
|
TransparentCursorSetState(w,True);
|
|
}
|
|
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfeButtonActivate(Widget w,XEvent * event,char ** params,Cardinal * nparams)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
|
|
/* Make sure we are not insenitsive (or pretending to be insensitive) */
|
|
if (!_XfeIsSensitive(w))
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Make sure we are indeed clicking */
|
|
if (!bp->clicking)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Invoke callbacks only if pointer is still inside button */
|
|
if (_XfePointerInside(w))
|
|
{
|
|
InvokeCallback(w,bp->activate_callback,XmCR_ACTIVATE,event);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfeButtonArm(Widget w,XEvent * event,char ** params,Cardinal * nparams)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
XfeLabelPart * lp = _XfeLabelPart(w);
|
|
Boolean accept_event;
|
|
|
|
/* Make sure we are not pretending to be insensitive */
|
|
if (!_XfeIsSensitive(w))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_XfePrimitiveFocus(w,event,params,nparams);
|
|
|
|
/* Determine whether this event is acceptable */
|
|
accept_event = AcceptEvent(w,event);
|
|
|
|
/* Look for a Select() action */
|
|
if (_XfeLabelAcceptSelectionEvent(w,event,!accept_event))
|
|
{
|
|
_XfeLabelSetSelected(w,event,!lp->selected,True);
|
|
|
|
return;
|
|
}
|
|
|
|
/* Look for a Edit() action */
|
|
if (_XfeLabelAcceptEditEvent(w,event,!accept_event))
|
|
{
|
|
_XfeLabelEdit(w,event,params,nparams);
|
|
|
|
return;
|
|
}
|
|
|
|
/* Make sure the event is accepted */
|
|
if (!accept_event)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Make sure we are not already clicking */
|
|
if (bp->clicking)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* We are now clicking */
|
|
bp->clicking = True;
|
|
|
|
/* If we are in none mode, do nothing more */
|
|
if (bp->button_type == XmBUTTON_NONE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Being simultaneously armed and raised is confusing, so its out */
|
|
if (bp->raise_on_enter)
|
|
{
|
|
bp->raised = False;
|
|
}
|
|
|
|
/* If we are in toggle mode, toggle the armed state */
|
|
if (bp->button_type == XmBUTTON_TOGGLE)
|
|
{
|
|
bp->armed = !bp->armed;
|
|
}
|
|
/* Otherwise turn it on */
|
|
else
|
|
{
|
|
bp->armed = True;
|
|
}
|
|
|
|
/* Erase the old stuff */
|
|
_XfePrimitiveClearBackground(w);
|
|
|
|
/* Redraw the buffer */
|
|
_XfePrimitiveDrawEverything(w,NULL,NULL);
|
|
|
|
/* Draw the buffer onto the window */
|
|
XfeExpose(w,NULL,NULL);
|
|
|
|
/* If we are in toggle mode, invoke the appropiate callback */
|
|
if (bp->button_type == XmBUTTON_TOGGLE)
|
|
{
|
|
if (bp->armed)
|
|
{
|
|
InvokeCallback(w,bp->arm_callback,XmCR_ARM,event);
|
|
}
|
|
else
|
|
{
|
|
InvokeCallback(w,bp->disarm_callback,XmCR_DISARM,event);
|
|
}
|
|
}
|
|
/* Otherwise invoke the arm callback */
|
|
else
|
|
{
|
|
InvokeCallback(w,bp->arm_callback,XmCR_ARM,event);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfeButtonDisarm(Widget w,XEvent * event,char ** params,Cardinal * nparams)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
|
|
/* Make sure we are not pretending to be insensitive */
|
|
if (!_XfeIsSensitive(w))
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Make sure we are indeed clicking */
|
|
if (!bp->clicking)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* If we are in none mode, do nothing more */
|
|
if (bp->button_type == XmBUTTON_NONE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* We are now no longer clicking */
|
|
bp->clicking = False;
|
|
|
|
/* Raise the button if needed and the pointer is still inside */
|
|
if (bp->raise_on_enter && _XfePointerInside(w))
|
|
{
|
|
bp->raised = True;
|
|
}
|
|
|
|
if (bp->button_type != XmBUTTON_TOGGLE)
|
|
{
|
|
bp->armed = False;
|
|
|
|
/* Erase the old stuff */
|
|
_XfePrimitiveClearBackground(w);
|
|
|
|
/* Redraw the buffer */
|
|
_XfePrimitiveDrawEverything(w,NULL,NULL);
|
|
|
|
/* Draw the buffer onto the window */
|
|
XfeExpose(w,NULL,NULL);
|
|
|
|
InvokeCallback(w,bp->disarm_callback,XmCR_DISARM,event);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfeButtonArmAndActivate(Widget w,
|
|
XEvent * event,
|
|
char ** params,
|
|
Cardinal * nparams)
|
|
{
|
|
/* Make sure we are not pretending to be insensitive */
|
|
if (!_XfeIsSensitive(w))
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Accept the event based on the button_trigger resource */
|
|
if (!AcceptEvent(w,event))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_XfeButtonArm(w,event,params,nparams);
|
|
|
|
_XfeButtonActivate(w,event,params,nparams);
|
|
|
|
_XfeButtonDisarm(w,event,params,nparams);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfeButtonBtn3Down(Widget w,XEvent * event,char ** params,Cardinal * nparams)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
|
|
/* Make sure we are not pretending to be insensitive */
|
|
if (!_XfeIsSensitive(w))
|
|
{
|
|
return;
|
|
}
|
|
|
|
InvokeCallback(w,bp->button_3_down_callback,XmCR_BUTTON_3_DOWN,event);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfeButtonBtn3Up(Widget w,XEvent * event,char ** params,Cardinal * nparams)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
|
|
/* Make sure we are not pretending to be insensitive */
|
|
if (!_XfeIsSensitive(w))
|
|
{
|
|
return;
|
|
}
|
|
|
|
InvokeCallback(w,bp->button_3_up_callback,XmCR_BUTTON_3_UP,event);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfeButton Public Methods */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
Widget
|
|
XfeCreateButton(Widget parent,char *name,Arg *args,Cardinal count)
|
|
{
|
|
return (XtCreateWidget(name,xfeButtonWidgetClass,parent,args,count));
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
XfeButtonPreferredGeometry(Widget w,
|
|
unsigned char layout,
|
|
Dimension * width_out,
|
|
Dimension * height_out)
|
|
{
|
|
XfeButtonPart * bp;
|
|
Dimension width;
|
|
Dimension height;
|
|
unsigned char old_layout;
|
|
|
|
assert( _XfeIsAlive(w) );
|
|
assert( XfeIsButton(w) );
|
|
|
|
bp = _XfeButtonPart(w);
|
|
|
|
/* Make sure the new layout is valid */
|
|
if (!XfeRepTypeCheck(w,XmRButtonLayout,&layout,XmBUTTON_LABEL_ON_BOTTOM))
|
|
{
|
|
_XfeWarning(w,MESSAGE16);
|
|
|
|
return;
|
|
}
|
|
|
|
/* Remember the old layout */
|
|
old_layout = bp->button_layout;
|
|
|
|
bp->button_layout = layout;
|
|
|
|
_XfePrimitivePreferredGeometry(w,&width,&height);
|
|
|
|
bp->button_layout = old_layout;
|
|
|
|
if (width_out)
|
|
{
|
|
*width_out = width;
|
|
}
|
|
|
|
if (height_out)
|
|
{
|
|
*height_out = height;
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ Boolean
|
|
XfeButtonAcceptXY(Widget w,int x,int y)
|
|
{
|
|
XfeButtonPart * bp = _XfeButtonPart(w);
|
|
XfeLabelPart * lp = _XfeLabelPart(w);
|
|
Boolean result = True;
|
|
|
|
/* Anywhere */
|
|
if (bp->button_trigger == XmBUTTON_TRIGGER_ANYWHERE)
|
|
{
|
|
result = True;
|
|
}
|
|
/* Label */
|
|
else if (bp->button_trigger == XmBUTTON_TRIGGER_LABEL)
|
|
{
|
|
if (bp->button_layout != XmBUTTON_PIXMAP_ONLY)
|
|
{
|
|
result = XY_IN_LABEL(lp,x,y);
|
|
}
|
|
}
|
|
/* Pixmap */
|
|
else if (bp->button_trigger == XmBUTTON_TRIGGER_PIXMAP)
|
|
{
|
|
if (bp->button_layout != XmBUTTON_LABEL_ONLY)
|
|
{
|
|
result = XY_IN_PIXMAP(bp,x,y);
|
|
}
|
|
}
|
|
/* Neither */
|
|
else if(bp->button_trigger == XmBUTTON_TRIGGER_NEITHER)
|
|
{
|
|
result = (!XY_IN_LABEL(lp,x,y) && !XY_IN_PIXMAP(bp,x,y));
|
|
}
|
|
/* Either */
|
|
else if (bp->button_trigger == XmBUTTON_TRIGGER_EITHER)
|
|
{
|
|
if (bp->button_layout == XmBUTTON_LABEL_ONLY)
|
|
{
|
|
result = XY_IN_LABEL(lp,x,y);
|
|
}
|
|
else if (bp->button_layout == XmBUTTON_PIXMAP_ONLY)
|
|
{
|
|
result = XY_IN_PIXMAP(bp,x,y);
|
|
}
|
|
else
|
|
{
|
|
result = (XY_IN_LABEL(lp,x,y) ||
|
|
XY_IN_PIXMAP(bp,x,y) ||
|
|
SpacingContainsXY(w,x,y));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|