gecko-dev/cmd/xfe/XfeWidgets/Xfe/Divider.c

646 строки
19 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*----------------------------------------------------------------------*/
/* */
/* Name: <Xfe/Divider.c> */
/* Description: XfeDivider widget source. */
/* Author: Ramiro Estrugo <ramiro@netscape.com> */
/* */
/*----------------------------------------------------------------------*/
#include <Xfe/DividerP.h>
#include <stdio.h>
#define MESSAGE1 "Widget is not an XfeDivider."
#define MESSAGE2 "XmNdividerChildType can only be set at creationg time."
#define MESSAGE3 "Only one child attachment can be XmNalwaysVisible."
#define MESSAGE4 "The descendant for XfeDividerAddDragDescendant() is invalid."
#define MESSAGE5 "Cannot find a valid ancestor attachment for '%s'."
/*----------------------------------------------------------------------*/
/* */
/* Core class methods */
/* */
/*----------------------------------------------------------------------*/
static void CoreClassInitialize (void);
static void CoreInitialize (Widget,Widget,ArgList,Cardinal *);
static void CoreDestroy (Widget);
static Boolean CoreSetValues (Widget,Widget,Widget,ArgList,Cardinal *);
/*----------------------------------------------------------------------*/
/* */
/* XfeManager class methods */
/* */
/*----------------------------------------------------------------------*/
static void PreferredGeometry (Widget,Dimension *,Dimension *);
static Boolean AcceptStaticChild (Widget);
static Boolean InsertStaticChild (Widget);
static Boolean DeleteStaticChild (Widget);
static void LayoutStaticChildren (Widget);
/*----------------------------------------------------------------------*/
/* */
/* Static layout functions */
/* */
/*----------------------------------------------------------------------*/
static void LayoutStaticVertical (Widget);
static void LayoutStaticHorizontal (Widget);
/*----------------------------------------------------------------------*/
/* */
/* Rep type registration functions */
/* */
/*----------------------------------------------------------------------*/
static void DividerRegisterRepTypes (void);
/*----------------------------------------------------------------------*/
/* */
/* XfeDivider resources */
/* */
/*----------------------------------------------------------------------*/
static XtResource resources[] =
{
/* Divider resources */
{
XmNdividerFixedSize,
XmCDividerFixedWidth,
XmRDimension,
sizeof(Dimension),
XtOffsetOf(XfeDividerRec , xfe_divider . divider_fixed_size),
XmRImmediate,
(XtPointer) 100
},
{
XmNdividerPercentage,
XmCDividerPercentage,
XmRInt,
sizeof(int),
XtOffsetOf(XfeDividerRec , xfe_divider . divider_percentage),
XmRImmediate,
(XtPointer) 20
},
{
XmNdividerTarget,
XmCDividerTarget,
XmRCardinal,
sizeof(Cardinal),
XtOffsetOf(XfeDividerRec , xfe_divider . divider_target),
XmRImmediate,
(XtPointer) 0
},
{
XmNdividerType,
XmCDividerType,
XmRDividerType,
sizeof(unsigned char),
XtOffsetOf(XfeDividerRec , xfe_divider . divider_type),
XmRImmediate,
(XtPointer) XmDIVIDER_PERCENTAGE
},
/* Force XmNusePreferredHeight and XmNusePreferredWidth to False */
{
XmNusePreferredHeight,
XmCUsePreferredHeight,
XmRBoolean,
sizeof(Boolean),
XtOffsetOf(XfeDividerRec , xfe_manager . use_preferred_height),
XmRImmediate,
(XtPointer) False
},
{
XmNusePreferredWidth,
XmCUsePreferredWidth,
XmRBoolean,
sizeof(Boolean),
XtOffsetOf(XfeDividerRec , xfe_manager . use_preferred_width),
XmRImmediate,
(XtPointer) False
},
};
/*----------------------------------------------------------------------*/
/* */
/* Widget Class Record Initialization */
/* */
/*----------------------------------------------------------------------*/
_XFE_WIDGET_CLASS_RECORD(divider,Divider) =
{
{
(WidgetClass) &xfeOrientedClassRec, /* superclass */
"XfeDivider", /* class_name */
sizeof(XfeDividerRec), /* widget_size */
CoreClassInitialize, /* class_initialize */
NULL, /* class_part_initialize*/
FALSE, /* class_inited */
CoreInitialize, /* initialize */
NULL, /* initialize_hook */
XtInheritRealize, /* realize */
NULL, /* actions */
0, /* num_actions */
(XtResource *)resources, /* resources */
XtNumber(resources), /* num_resources */
NULLQUARK, /* xrm_class */
TRUE, /* compress_motion */
XtExposeCompressMaximal, /* compress_exposure */
TRUE, /* compress_enterleave */
FALSE, /* visible_interest */
CoreDestroy, /* destroy */
XtInheritResize, /* resize */
XtInheritExpose, /* expose */
CoreSetValues, /* set_values */
NULL, /* set_values_hook */
XtInheritSetValuesAlmost, /* set_values_almost */
NULL, /* get_values_hook */
NULL, /* access_focus */
XtVersion, /* version */
NULL, /* callback_private */
XtInheritTranslations, /* tm_table */
XtInheritQueryGeometry, /* query_geometry */
XtInheritDisplayAccelerator, /* display accelerator */
NULL, /* extension */
},
/* Composite Part */
{
XtInheritGeometryManager, /* geometry_manager */
XtInheritChangeManaged, /* change_managed */
XtInheritInsertChild, /* insert_child */
XtInheritDeleteChild, /* delete_child */
NULL /* extension */
},
/* Constraint Part */
{
NULL, /* constraint res */
0, /* num constraint res */
sizeof(XfeOrientedConstraintRec), /* constraint size */
NULL, /* init proc */
NULL, /* destroy proc */
NULL, /* set values proc */
NULL, /* extension */
},
/* XmManager Part */
{
XtInheritTranslations, /* tm_table */
NULL, /* syn resources */
0, /* num syn_resources */
NULL, /* syn_cont_resources */
0, /* num_syn_cont_resource*/
XmInheritParentProcess, /* parent_process */
NULL, /* extension */
},
/* XfeManager Part */
{
XfeInheritBitGravity, /* bit_gravity */
PreferredGeometry, /* preferred_geometry */
XfeInheritUpdateBoundary, /* update_boundary */
XfeInheritUpdateChildrenInfo, /* update_children_info */
XfeInheritLayoutWidget, /* layout_widget */
AcceptStaticChild, /* accept_static_child */
InsertStaticChild, /* insert_static_child */
DeleteStaticChild, /* delete_static_child */
LayoutStaticChildren, /* layout_static_children */
NULL, /* change_managed */
NULL, /* prepare_components */
NULL, /* layout_components */
NULL, /* draw_background */
XfeInheritDrawShadow, /* draw_shadow */
NULL, /* draw_components */
XfeInheritDrawAccentBorder, /* draw_accent_border */
NULL, /* extension */
},
/* XfeDynamicManager Part */
{
NULL, /* accept_dynamic_child */
NULL, /* insert_dynamic_child */
NULL, /* delete_dynamic_child */
NULL, /* layout_dynamic_children */
NULL, /* extension */
},
/* XfeOriented Part */
{
NULL, /* enter */
NULL, /* leave */
NULL, /* motion */
NULL, /* drag_start */
NULL, /* drag_end */
NULL, /* drag_motion */
NULL, /* des_enter */
NULL, /* des_leave */
NULL, /* des_motion */
NULL, /* des_drag_start */
NULL, /* des_drag_end */
NULL, /* des_drag_motion */
NULL, /* extension */
},
/* XfeDivider Part */
{
NULL, /* extension */
},
};
/*----------------------------------------------------------------------*/
/* */
/* xfeDividerWidgetClass declaration. */
/* */
/*----------------------------------------------------------------------*/
_XFE_WIDGET_CLASS(divider,Divider);
/*----------------------------------------------------------------------*/
/* */
/* Rep type registration functions */
/* */
/*----------------------------------------------------------------------*/
static void
DividerRegisterRepTypes(void)
{
static String divider_names[] =
{
"divider_fixed_size",
"divider_percentage",
NULL
};
XfeRepTypeRegister(XmRDividerType,divider_names);
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* Core Class methods */
/* */
/*----------------------------------------------------------------------*/
static void
CoreClassInitialize()
{
/* Register XfeDivider Representation Types */
DividerRegisterRepTypes();
}
/*----------------------------------------------------------------------*/
static void
CoreInitialize(Widget rw,Widget nw,ArgList av,Cardinal * ac)
{
XfeDividerPart * dp = _XfeDividerPart(nw);
/* Make sure rep types are ok */
XfeRepTypeCheck(nw,XmRDividerType,&dp->divider_type,XmDIVIDER_PERCENTAGE);
/* Finish of initialization */
_XfeManagerChainInitialize(rw,nw,xfeDividerWidgetClass);
}
/*----------------------------------------------------------------------*/
static void
CoreDestroy(Widget w)
{
XfeDividerPart * dp = _XfeDividerPart(w);
}
/*----------------------------------------------------------------------*/
static Boolean
CoreSetValues(Widget ow,Widget rw,Widget nw,ArgList av,Cardinal * ac)
{
XfeDividerPart * np = _XfeDividerPart(nw);
XfeDividerPart * op = _XfeDividerPart(ow);
/* XmNdividerFixedSize */
if (np->divider_fixed_size != op->divider_fixed_size)
{
_XfemConfigFlags(nw) |= XfeConfigLayout;
}
/* XmNdividerPercentage */
if (np->divider_percentage != op->divider_percentage)
{
_XfemConfigFlags(nw) |= XfeConfigLayout;
}
/* XmNdividerTarget */
if (np->divider_target != op->divider_target)
{
_XfemConfigFlags(nw) |= XfeConfigLayout;
}
/* XmNdividerType */
if (np->divider_type != op->divider_type)
{
_XfemConfigFlags(nw) |= XfeConfigGLE;
/* Make sure the new divider type is ok */
XfeRepTypeCheck(nw,XmRDividerType,&np->divider_type,
XmDIVIDER_PERCENTAGE);
}
return _XfeManagerChainSetValues(ow,rw,nw,xfeDividerWidgetClass);
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* XfeManager class methods */
/* */
/*----------------------------------------------------------------------*/
static void
PreferredGeometry(Widget w,Dimension * width,Dimension * height)
{
/* XfeDividerPart * dp = _XfeDividerPart(w); */
*width = _XfemOffsetLeft(w) + _XfemOffsetRight(w);
*height = _XfemOffsetTop(w) + _XfemOffsetBottom(w);
/* Vertical */
if (_XfeOrientedOrientation(w) == XmVERTICAL)
{
*width += _XfemMaxStaticWidth(w);
*height += _XfemTotalStaticWidth(w);
}
/* Horizontal */
else
{
*width += _XfemTotalStaticWidth(w);
*height += _XfemMaxStaticWidth(w);
}
}
/*----------------------------------------------------------------------*/
static Boolean
AcceptStaticChild(Widget child)
{
Widget w = _XfeParent(child);
/* We can accept up to 2 children */
return (_XfemNumStaticChildren(w) < 2);
}
/*----------------------------------------------------------------------*/
static Boolean
InsertStaticChild(Widget child)
{
/* Widget w = _XfeParent(child); */
/* XfeDividerPart * dp = _XfeDividerPart(w); */
/* XfeDividerConstraintPart * cp = _XfeDividerConstraintPart(child); */
return True;
}
/*----------------------------------------------------------------------*/
static Boolean
DeleteStaticChild(Widget child)
{
/* Widget w = XtParent(child); */
/* XfeDividerPart * dp = _XfeDividerPart(w); */
return True;
}
/*----------------------------------------------------------------------*/
static void
LayoutStaticChildren(Widget w)
{
XfeDividerPart * dp = _XfeDividerPart(w);
/* Vertical */
if (_XfeOrientedOrientation(w) == XmVERTICAL)
{
LayoutStaticVertical(w);
}
/* Horizontal */
else
{
LayoutStaticHorizontal(w);
}
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* Static layout functions */
/* */
/*----------------------------------------------------------------------*/
static void
LayoutStaticVertical(Widget w)
{
XfeDividerPart * dp = _XfeDividerPart(w);
Widget one = _XfemStaticChildrenIndex(w,0);
Widget two = _XfemStaticChildrenIndex(w,1);
int one_x;
int one_y;
int one_width;
int one_height;
int two_x;
int two_y;
int two_width;
int two_height;
assert( dp->divider_target == 0 || dp->divider_target == 1 );
assert( dp->divider_fixed_size > 0 );
assert( dp->divider_fixed_size <= _XfeWidth(w) );
assert( dp->divider_percentage >= 0 );
assert( dp->divider_percentage <= 100 );
/* children[0] is the target */
if (dp->divider_target == 0)
{
/* Offset */
if (dp->divider_type == XmDIVIDER_FIXED_SIZE)
{
one_height = dp->divider_fixed_size;
one_width = _XfemBoundaryWidth(w);
one_x = _XfemBoundaryX(w);
one_y = _XfemBoundaryY(w);
two_height = _XfemBoundaryHeight(w) - one_height;
two_width = _XfemBoundaryWidth(w);
two_x = _XfemBoundaryY(w);
two_y = _XfemBoundaryY(w) + _XfemBoundaryHeight(w) - two_height;
}
/* Percentage */
else
{
one_height = (dp->divider_percentage * _XfemBoundaryHeight(w)) / 100;
one_width = _XfemBoundaryWidth(w);
one_x = _XfemBoundaryX(w);
one_y = _XfemBoundaryY(w);
two_height = _XfemBoundaryHeight(w) - one_height;
two_width = _XfemBoundaryWidth(w);
two_x = _XfemBoundaryX(w);
two_y = _XfemBoundaryY(w) + _XfemBoundaryHeight(w) - two_height;
}
}
/* children[1] is the target */
else
{
/* Offset */
if (dp->divider_type == XmDIVIDER_FIXED_SIZE)
{
two_height = dp->divider_fixed_size;
two_width = _XfemBoundaryWidth(w);
two_x = _XfemBoundaryY(w);
two_y = _XfemBoundaryY(w) + _XfemBoundaryHeight(w) - two_height;
one_height = _XfemBoundaryHeight(w) - two_height;
one_width = _XfemBoundaryWidth(w);
one_x = _XfemBoundaryX(w);
one_y = _XfemBoundaryY(w);
}
/* Percentage */
else
{
two_height = (dp->divider_percentage * _XfemBoundaryHeight(w)) / 100;
two_width = _XfemBoundaryWidth(w);
two_x = _XfemBoundaryX(w);
two_y = _XfemBoundaryY(w) + _XfemBoundaryHeight(w) - two_height;
one_height = _XfemBoundaryHeight(w) - two_height;
one_width = _XfemBoundaryWidth(w);
one_x = _XfemBoundaryX(w);
one_y = _XfemBoundaryY(w);
}
}
if (_XfeIsAlive(one))
{
_XfeConfigureWidget(one,one_x,one_y,one_width,one_height);
}
if (_XfeIsAlive(two))
{
_XfeConfigureWidget(two,two_x,two_y,two_width,two_height);
}
}
/*----------------------------------------------------------------------*/
static void
LayoutStaticHorizontal(Widget w)
{
XfeDividerPart * dp = _XfeDividerPart(w);
Widget one = _XfemStaticChildrenIndex(w,0);
Widget two = _XfemStaticChildrenIndex(w,1);
int one_x;
int one_y;
int one_width;
int one_height;
int two_x;
int two_y;
int two_width;
int two_height;
assert( dp->divider_target == 0 || dp->divider_target == 1 );
assert( dp->divider_fixed_size > 0 );
assert( dp->divider_fixed_size <= _XfeWidth(w) );
assert( dp->divider_percentage >= 0 );
assert( dp->divider_percentage <= 100 );
/* children[0] is the target */
if (dp->divider_target == 0)
{
/* Offset */
if (dp->divider_type == XmDIVIDER_FIXED_SIZE)
{
one_width = dp->divider_fixed_size;
one_height = _XfemBoundaryHeight(w);
one_x = _XfemBoundaryX(w);
one_y = _XfemBoundaryY(w);
two_width = _XfemBoundaryWidth(w) - one_width;
two_height = _XfemBoundaryHeight(w);
two_x = _XfemBoundaryX(w) + _XfemBoundaryWidth(w) - two_width;
two_y = _XfemBoundaryY(w);
}
/* Percentage */
else
{
one_width = (dp->divider_percentage * _XfemBoundaryWidth(w)) / 100;
one_height = _XfemBoundaryHeight(w);
one_x = _XfemBoundaryX(w);
one_y = _XfemBoundaryY(w);
two_width = _XfemBoundaryWidth(w) - one_width;
two_height = _XfemBoundaryHeight(w);
two_x = _XfemBoundaryX(w) + _XfemBoundaryWidth(w) - two_width;
two_y = _XfemBoundaryY(w);
}
}
/* children[1] is the target */
else
{
/* Offset */
if (dp->divider_type == XmDIVIDER_FIXED_SIZE)
{
two_width = dp->divider_fixed_size;
two_height = _XfemBoundaryHeight(w);
two_x = _XfemBoundaryX(w) + _XfemBoundaryWidth(w) - two_width;
two_y = _XfemBoundaryY(w);
one_width = _XfemBoundaryWidth(w) - two_width;
one_height = _XfemBoundaryHeight(w);
one_x = _XfemBoundaryX(w);
one_y = _XfemBoundaryY(w);
}
/* Percentage */
else
{
two_width = (dp->divider_percentage * _XfemBoundaryWidth(w)) / 100;
two_height = _XfemBoundaryHeight(w);
two_x = _XfemBoundaryX(w) + _XfemBoundaryWidth(w) - two_width;
two_y = _XfemBoundaryY(w);
one_width = _XfemBoundaryWidth(w) - two_width;
one_height = _XfemBoundaryHeight(w);
one_x = _XfemBoundaryX(w);
one_y = _XfemBoundaryY(w);
}
}
if (_XfeIsAlive(one))
{
_XfeConfigureWidget(one,one_x,one_y,one_width,one_height);
}
if (_XfeIsAlive(two))
{
_XfeConfigureWidget(two,two_x,two_y,two_width,two_height);
}
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* XfeDivider public methods */
/* */
/*----------------------------------------------------------------------*/
/* extern */ Widget
XfeCreateDivider(Widget pw,char * name,Arg * av,Cardinal ac)
{
return XtCreateWidget(name,xfeDividerWidgetClass,pw,av,ac);
}
/*----------------------------------------------------------------------*/