home *** CD-ROM | disk | FTP | other *** search
- /* -*- 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/MenuUtil.c> */
- /* Description: Menu/RowColum misc utilities source. */
- /* Author: Ramiro Estrugo <ramiro@netscape.com> */
- /* */
- /*----------------------------------------------------------------------*/
-
-
- #include <Xfe/XfeP.h>
- #include <Xfe/ManagerP.h>
- #include <Xfe/CascadeP.h>
- #include <Xfe/BmCascadeP.h>
- #include <Xfe/BmButtonP.h>
-
- #include <Xm/RowColumnP.h>
-
- #include <Xm/DisplayP.h>
-
- #include <Xm/CascadeBGP.h>
- #include <Xm/CascadeBP.h>
-
- /*----------------------------------------------------------------------*/
- /* */
- /* Menus */
- /* */
- /*----------------------------------------------------------------------*/
- /* extern */ Widget
- XfeCascadeGetSubMenu(Widget w)
- {
- assert( w != NULL );
- assert( (XmIsCascadeButton(w) ||
- XmIsCascadeButtonGadget(w) ||
- XfeIsCascade(w)) );
-
- if (XmIsCascadeButton(w))
- {
- return ((XmCascadeButtonWidget) w) -> cascade_button . submenu;
- }
- else if (XfeIsCascade(w))
- {
- return ((XfeCascadeWidget) w) -> xfe_cascade . sub_menu_id;
- }
-
- return ((XmCascadeButtonGadget) w) -> cascade_button . submenu;
- }
- /*----------------------------------------------------------------------*/
- /* extern */ void
- XfeMenuPositionXY(Widget menu,Position x_root,Position y_root)
- {
- XButtonPressedEvent be;
-
- assert( _XfeIsAlive(menu) );
- assert( XmIsRowColumn(menu) );
-
- /* In the motif source code, only the x_root and y_root members are used */
- be.x_root = x_root;
- be.y_root = y_root;
-
- XmMenuPosition(menu,&be);
- }
- /*----------------------------------------------------------------------*/
- /* extern */ int
- XfeMenuItemPositionIndex(Widget item)
- {
- XmRowColumnConstraintRec * rccp;
-
- assert( _XfeIsAlive(item) );
- assert( XmIsRowColumn(_XfeParent(item)) );
- assert( XtIsObject(item) );
-
- rccp = (XmRowColumnConstraintRec *) (item -> core . constraints);
-
- return (int) rccp -> row_column . position_index;
- }
- /*----------------------------------------------------------------------*/
- /* extern */ Widget
- XfeMenuItemAtPosition(Widget menu,int position)
- {
- Widget item = NULL;
- #if 0
- XmRowColumnConstraintRec * rccp;
-
- assert( _XfeIsAlive(item) );
- assert( XmIsRowColumn(_XfeParent(item)) );
-
- rccp = (XmRowColumnConstraintRec *) (item -> core . constraints);
-
- return (int) rccp -> row_column . position_index;
- #endif
-
- return item;
- }
- /*----------------------------------------------------------------------*/
- /* extern */ Boolean
- XfeMenuIsFull(Widget menu)
- {
- Dimension screen_height;
- Widget last;
-
- assert( _XfeIsAlive(menu) );
- assert( XmIsRowColumn(menu) );
-
- screen_height = XfeScreenHeight(menu);
-
- last = XfeChildrenGetLast(menu);
-
- if (!last)
- {
- return False;
- }
-
- /*
- * The menu is "full" if its height plus that of a potential new child
- * are longer than the screen height. Assume the new child will be
- * the same height as the last child in the menu.
- */
- if ((_XfeHeight(menu) + (3 * _XfeHeight(last))) > XfeScreenHeight(menu))
- {
- return True;
- }
-
- return False;
- }
- /*----------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------*/
- /* */
- /* Option menus */
- /* */
- /*----------------------------------------------------------------------*/
- /* extern */ Boolean
- XfeMenuIsOptionMenu(Widget menu)
- {
- return (XmIsRowColumn(menu) && (RC_Type(menu) == XmMENU_OPTION));
- }
- /*----------------------------------------------------------------------*/
- /* extern */ void
- XfeOptionMenuSetItem(Widget menu,Cardinal i)
- {
- Widget submenu;
-
- assert( _XfeIsAlive(menu) );
- assert( XfeMenuIsOptionMenu(menu) );
-
- submenu = RC_OptionSubMenu(menu);
-
- if (_XfeIsAlive(submenu))
- {
- if ((i >= 0) && (i < _XfemNumChildren(submenu)))
- {
- XtVaSetValues(menu,XmNmenuHistory,_XfeChildrenIndex(submenu,i),NULL);
- }
- }
- }
- /*----------------------------------------------------------------------*/
- /* extern */ int
- XfeOptionMenuGetItem(Widget menu)
- {
- Cardinal i;
- Widget submenu;
-
- assert( _XfeIsAlive(menu) );
- assert( XfeMenuIsOptionMenu(menu) );
-
- submenu = RC_OptionSubMenu(menu);
-
- if (_XfeIsAlive(submenu))
- {
- for (i = 0; i < _XfemNumChildren(submenu); i++)
- {
- if (_XfeChildrenIndex(submenu,i) == RC_MemWidget(menu))
- {
- return (int) i;
- }
- }
- }
-
- return -1;
- }
- /*----------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------*
- *
- * Traverse a menu hierarchy
- *
- *
- *
- *----------------------------------------------------------------------*/
- /* extern */ Widget
- XfeMenuGetMoreButton(Widget menu,String more_button_name)
- {
- Widget last;
-
- assert( _XfeIsAlive(menu) );
- assert( XmIsRowColumn(menu) );
- assert( more_button_name != NULL );
-
- last = XfeChildrenGetLast(menu);
-
- if (_XfeIsAlive(last) &&
- (XmIsCascadeButton(last) || XmIsCascadeButtonGadget(last)) &&
- (strcmp(XtName(last),more_button_name) == 0))
- {
- return last;
- }
-
- return NULL;
- }
- /*----------------------------------------------------------------------*/
- /* extern */ Widget
- XfeMenuFindLastMoreMenu(Widget menu,String more_button_name)
- {
- Widget more_button;
- Widget submenu;
-
- assert( _XfeIsAlive(menu) );
- assert( XmIsRowColumn(menu) );
- assert( more_button_name != NULL );
-
- /* First check if this menu is not full */
- if (!XfeMenuIsFull(menu))
- {
- return menu;
- }
-
- /* Look for the "More..." button */
- more_button = XfeMenuGetMoreButton(menu,more_button_name);
-
- /* If no more button is found, then this menu is the last one */
- if (!more_button)
- {
- return menu;
- }
-
- /* Get the submenu for the more button */
- submenu = XfeCascadeGetSubMenu(more_button);
-
- assert( _XfeIsAlive(submenu) );
-
- /* Recurse into the submenu */
- return XfeMenuFindLastMoreMenu(submenu,more_button_name);
- }
- /*----------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------*/
- /* */
- /* Display grabbed access. */
- /* */
- /*----------------------------------------------------------------------*/
- /* extern */ Boolean
- XfeDisplayIsUserGrabbed(Widget w)
- {
- XmDisplayRec * xm_display;
-
- assert( _XfeIsAlive(w) );
-
- xm_display = (XmDisplayRec *) XmGetXmDisplay(XtDisplay(w));
-
- assert( xm_display != NULL );
-
- return xm_display->display.userGrabbed;
- }
- /*----------------------------------------------------------------------*/
- /* extern */ void
- XfeDisplaySetUserGrabbed(Widget w,Boolean grabbed)
- {
- XmDisplayRec * xm_display;
-
- assert( _XfeIsAlive(w) );
-
- xm_display = (XmDisplayRec *) XmGetXmDisplay(XtDisplay(w));
-
- assert( xm_display != NULL );
-
- xm_display->display.userGrabbed = grabbed;
- }
- /*----------------------------------------------------------------------*/
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* Menu item functions. */
- /* */
- /*----------------------------------------------------------------------*/
- /* extern */ Widget
- XfeMenuItemNextItem(Widget item)
- {
- int position_index;
- Widget parent;
- Cardinal num_children;
- Widget next = NULL;
-
- assert( _XfeIsAlive(item) );
- assert( XtIsObject(item) );
-
- parent = _XfeParent(item);
-
- assert( XmIsRowColumn(_XfeParent(item)) );
-
- position_index = XfeMenuItemPositionIndex(item);
-
- num_children = _XfemNumChildren(parent);
-
- if (position_index < (num_children - 1))
- {
- next = _XfeChildrenIndex(parent,position_index + 1);
- }
-
- return next;
- }
- /*----------------------------------------------------------------------*/
- /* extern */ Widget
- XfeMenuItemPreviousItem(Widget item)
- {
- int position_index;
- Widget parent;
- Cardinal num_children;
- Widget previous = NULL;
-
- assert( _XfeIsAlive(item) );
- assert( XtIsObject(item) );
-
- parent = _XfeParent(item);
-
- assert( XmIsRowColumn(_XfeParent(item)) );
-
- position_index = XfeMenuItemPositionIndex(item);
-
- num_children = _XfemNumChildren(parent);
-
- if (position_index > 0)
- {
- previous = _XfeChildrenIndex(parent,position_index - 1);
- }
-
- return previous;
- }
- /*----------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------*/
- /* */
- /* Private accent functions. */
- /* */
- /*----------------------------------------------------------------------*/
- #define ACCENT_DRAW 1
- #define ACCENT_ERASE 2
-
- static void AccentBottom (Widget,GC,GC,Dimension,Dimension,
- Dimension,Dimension,int);
- static void AccentAll (Widget,GC,GC,Dimension,Dimension,
- Dimension,Dimension,int);
- static void AccentTop (Widget,GC,GC,Dimension,Dimension,
- Dimension,Dimension,int);
-
- /*----------------------------------------------------------------------*/
- /* */
- /* Public accent drawing functions. */
- /* */
- /*----------------------------------------------------------------------*/
- /* extern */ void
- XfeMenuItemDrawAccent(Widget item,
- unsigned char accent_type,
- Dimension offset_left,
- Dimension offset_right,
- Dimension shadow_thickness,
- Dimension accent_thickness)
- {
- Widget pw;
- GC top_gc;
- GC bottom_gc;
- XGCValues values;
- int top_subwindow_mode;
- int bottom_subwindow_mode;
-
- /* duh */
- if (accent_type == XmACCENT_NONE)
- {
- return;
- }
-
- assert( _XfeIsAlive(item) );
- assert( XmIsPushButton(item) || XmIsCascadeButton(item) );
-
- pw = _XfeParent(item);
-
- assert( XmIsRowColumn(pw) );
-
- top_gc = _XfemTopShadowGC(pw);
- bottom_gc = _XfemBottomShadowGC(pw);
-
- /* Remember the old wubwindow mode values */
- XGetGCValues(XtDisplay(item),top_gc,GCSubwindowMode,&values);
-
- top_subwindow_mode = values.subwindow_mode;
-
- XGetGCValues(XtDisplay(item),bottom_gc,GCSubwindowMode,&values);
-
- bottom_subwindow_mode = values.subwindow_mode;
-
- /* Force the subwindow mode to IncludeInferiors */
- XSetSubwindowMode(XtDisplay(item),top_gc,IncludeInferiors);
- XSetSubwindowMode(XtDisplay(item),bottom_gc,IncludeInferiors);
-
- switch(accent_type)
- {
- case XmACCENT_BOTTOM:
- AccentBottom(item,top_gc,bottom_gc,offset_left,offset_right,
- shadow_thickness,accent_thickness,ACCENT_DRAW);
- break;
-
- case XmACCENT_ALL:
- AccentAll(item,top_gc,bottom_gc,offset_left,offset_right,
- shadow_thickness,accent_thickness,ACCENT_DRAW);
- break;
-
- case XmACCENT_TOP:
- AccentTop(item,top_gc,bottom_gc,offset_left,offset_right,
- shadow_thickness,accent_thickness,ACCENT_DRAW);
- break;
-
- default:
- break;
- }
-
- /* Restore the old subwindow mode */
- XSetSubwindowMode(XtDisplay(item),top_gc,top_subwindow_mode);
- XSetSubwindowMode(XtDisplay(item),bottom_gc,bottom_subwindow_mode);
- }
- /*----------------------------------------------------------------------*/
- /* extern */ void
- XfeMenuItemEraseAccent(Widget item,
- unsigned char accent_type,
- Dimension offset_left,
- Dimension offset_right,
- Dimension shadow_thickness,
- Dimension accent_thickness)
- {
- Widget pw;
- GC gc;
- XGCValues values;
- int subwindow_mode;
-
- /* duh */
- if (accent_type == XmACCENT_NONE)
- {
- return;
- }
-
- assert( _XfeIsAlive(item) );
- assert( XmIsPushButton(item) || XmIsCascadeButton(item) );
-
- pw = _XfeParent(item);
-
- assert( XmIsRowColumn(pw) );
-
- gc = _XfemBackgroundGC(pw);
-
- /* Remember the old wubwindow mode values */
- XGetGCValues(XtDisplay(item),gc,GCSubwindowMode,&values);
-
- subwindow_mode = values.subwindow_mode;
-
- /* Force the subwindow mode to IncludeInferiors */
- XSetSubwindowMode(XtDisplay(item),gc,IncludeInferiors);
-
- switch(accent_type)
- {
- case XmACCENT_BOTTOM:
- AccentBottom(item,gc,None,offset_left,offset_right,
- shadow_thickness,accent_thickness,ACCENT_ERASE);
- break;
-
- case XmACCENT_ALL:
- AccentAll(item,gc,None,offset_left,offset_right,
- shadow_thickness,accent_thickness,ACCENT_ERASE);
- break;
-
- case XmACCENT_TOP:
- AccentTop(item,gc,None,offset_left,offset_right,
- shadow_thickness,accent_thickness,ACCENT_ERASE);
- break;
-
- default:
- break;
- }
-
- /* Restore the old subwindow mode */
- XSetSubwindowMode(XtDisplay(item),gc,subwindow_mode);
- }
- /*----------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------*/
- /* */
- /* Private accent functions. */
- /* */
- /*----------------------------------------------------------------------*/
- static void
- AccentBottom(Widget w,
- GC top_gc,
- GC bottom_gc,
- Dimension offset_left,
- Dimension offset_right,
- Dimension shadow_thickness,
- Dimension accent_thickness,
- int code)
- {
- Widget pw = _XfeParent(w);
- int position_index = XfeMenuItemPositionIndex(w);
- Cardinal num_children = _XfemNumChildren(pw);
- Position x;
- Position y;
- Dimension width;
- Dimension height = 2 * shadow_thickness + accent_thickness;
-
- assert( code == ACCENT_DRAW || code == ACCENT_ERASE );
-
- /* Last item */
- if (position_index == (num_children - 1))
- {
- x = _XfeX(w) + offset_left;
- y = _XfeY(w) + _XfeHeight(w) - height;
-
- width = _XfeWidth(w) - offset_left - offset_right;
- }
- /* Any other item */
- else
- {
- x = _XfeX(w) + offset_left;
- y = _XfeY(w) + _XfeHeight(w) - height / 2;
-
- width = _XfeWidth(w) - offset_left - offset_right;
- }
-
- if (code == ACCENT_DRAW)
- {
- /* Draw accent */
- _XmDrawShadows(XtDisplay(pw),_XfeWindow(pw),top_gc,bottom_gc,
- x,y,width,height,shadow_thickness,XmSHADOW_IN);
- }
- else
- {
- /* Erase accent */
- XfeDrawRectangle(XtDisplay(pw),_XfeWindow(pw),top_gc,
- x,y,width,height,shadow_thickness);
- }
- }
- /*----------------------------------------------------------------------*/
- static void
- AccentTop(Widget w,
- GC top_gc,
- GC bottom_gc,
- Dimension offset_left,
- Dimension offset_right,
- Dimension shadow_thickness,
- Dimension accent_thickness,
- int code)
- {
- Widget pw = _XfeParent(w);
- int position_index = XfeMenuItemPositionIndex(w);
- Position x;
- Position y;
- Dimension width;
- Dimension height = 2 * shadow_thickness + accent_thickness;
-
- assert( code == ACCENT_DRAW || code == ACCENT_ERASE );
-
- /* First item */
- if (position_index == 0)
- {
- x = _XfeX(w) + offset_left;
- y = _XfeY(w);
-
- width = _XfeWidth(w) - offset_left - offset_right;
- }
- /* Any other item */
- else
- {
- x = _XfeX(w) + offset_left;
- y = _XfeY(w) - height / 2;
-
- width = _XfeWidth(w) - offset_left - offset_right;
- }
-
- if (code == ACCENT_DRAW)
- {
- /* Draw accent */
- _XmDrawShadows(XtDisplay(pw),_XfeWindow(pw),top_gc,bottom_gc,
- x,y,width,height,shadow_thickness,XmSHADOW_IN);
- }
- else
- {
- /* Erase accent */
- XfeDrawRectangle(XtDisplay(pw),_XfeWindow(pw),top_gc,
- x,y,width,height,shadow_thickness);
- }
- }
- /*----------------------------------------------------------------------*/
- static void
- AccentAll(Widget w,
- GC top_gc,
- GC bottom_gc,
- Dimension offset_left,
- Dimension offset_right,
- Dimension shadow_thickness,
- Dimension accent_thickness,
- int code)
- {
- #if 1
- if (code == ACCENT_DRAW)
- {
- /* Draw accent */
- _XmDrawShadows(XtDisplay(w),_XfeWindow(w),
- top_gc,bottom_gc,
- _XfeHighlightThickness(w),
- _XfeHighlightThickness(w),
- _XfeWidth(w) - 2 * _XfeHighlightThickness(w),
- _XfeHeight(w) - 2 * _XfeHighlightThickness(w),
- _XfeShadowThickness(w),
- XmSHADOW_OUT);
- }
- else
- {
- /* Erase accent */
- XfeDrawRectangle(XtDisplay(w),_XfeWindow(w),top_gc,
- _XfeHighlightThickness(w),
- _XfeHighlightThickness(w),
- _XfeWidth(w) - 2 * _XfeHighlightThickness(w),
- _XfeHeight(w) - 2 * _XfeHighlightThickness(w),
- _XfeShadowThickness(w));
- }
- #else
- Widget pw = _XfeParent(w);
- int position_index = XfeMenuItemPositionIndex(w);
- Cardinal num_children = _XfemNumChildren(pw);
- Position x;
- Position y;
- Dimension width;
- Dimension height;
- Dimension total_thickness = shadow_thickness + accent_thickness;
-
- assert( code == ACCENT_DRAW || code == ACCENT_ERASE );
-
- /* One and only */
- if (num_children == 1)
- {
- x = _XfeX(w) + offset_left;
- y = _XfeY(w);
-
- width = _XfeWidth(w) - offset_left - offset_right;
- height = _XfeHeight(w);
- }
- else
- {
- Dimension overlap = (2 * shadow_thickness + accent_thickness) / 2;
-
- /* First item */
- if (position_index == 0)
- {
- x = _XfeX(w) + offset_left;
- y = _XfeY(w);
-
- width = _XfeWidth(w) - offset_left - offset_right;
-
- height = _XfeHeight(w) + overlap;
- }
- /* Last item */
- else if (position_index == (num_children - 1))
- {
- x = _XfeX(w) + offset_left;
- y = _XfeY(w) - overlap;
-
- width = _XfeWidth(w) - offset_left - offset_right;
-
- height = _XfeHeight(w) + overlap;
- }
- /* In between two others */
- else
- {
- x = _XfeX(w) + offset_left;
- y = _XfeY(w) - overlap;
-
- width = _XfeWidth(w) - offset_left - offset_right;
-
- height = _XfeHeight(w) + 2 * total_thickness;
- }
- }
-
- if (code == ACCENT_DRAW)
- {
- /* Draw accent */
- _XmDrawShadows(XtDisplay(pw),_XfeWindow(pw),top_gc,bottom_gc,
- x,y,width,height,shadow_thickness,XmSHADOW_IN);
-
- x += total_thickness;
- y += total_thickness;
-
- width -= (2 * total_thickness);
- height -= (2 * total_thickness);
-
- _XmDrawShadows(XtDisplay(pw),_XfeWindow(pw),top_gc,bottom_gc,
- x,y,width,height,shadow_thickness,XmSHADOW_OUT);
- }
- else
- {
- /* Erase accent */
- XfeDrawRectangle(XtDisplay(pw),_XfeWindow(pw),top_gc,
- x,y,width,height,shadow_thickness);
-
- x += total_thickness;
- y += total_thickness;
-
- width -= (2 * total_thickness);
- height -= (2 * total_thickness);
-
- XfeDrawRectangle(XtDisplay(pw),_XfeWindow(pw),top_gc,
- x,y,width,height,shadow_thickness);
- }
- #endif
- }
- /*----------------------------------------------------------------------*/
- /* extern */ unsigned char
- XfeMenuType(Widget menu)
- {
- assert( _XfeIsAlive(menu) );
- assert( XmIsRowColumn(menu) );
-
- return RC_Type(menu);
- }
- /*----------------------------------------------------------------------*/
-