#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include "x11/ScrollBoxP.h"
#include <stdio.h>
#define INITIAL_WIDTH 300
#define INITIAL_HEIGHT 300
static XtResource resources[] =
{
{ XtNhSpace, XtCHSpace, XtRDimension, sizeof(Dimension),
XtOffset(ScrollBoxWidget, scrollBox.h_space),
XtRImmediate, (XtPointer)4 },
{ XtNvSpace, XtCVSpace, XtRDimension, sizeof(Dimension),
XtOffset(ScrollBoxWidget, scrollBox.v_space),
XtRImmediate, (XtPointer)4 },
{ XtNheightInc, XtCHeightInc, XtRDimension, sizeof(Dimension),
XtOffset(ScrollBoxWidget, scrollBox.increment_height),
XtRImmediate, (XtPointer)13 },
{ XtNwidthInc, XtCWidthInc, XtRDimension, sizeof(Dimension),
XtOffset(ScrollBoxWidget, scrollBox.increment_width),
XtRImmediate, (XtPointer)7 },
};
static void Initialize(Widget, Widget, ArgList, Cardinal *);
static void Resize(Widget);
static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *);
static void ChangeManaged(Widget);
static XtGeometryResult QueryGeometry(Widget, XtWidgetGeometry *,
XtWidgetGeometry *);
static XtGeometryResult GeometryManager(Widget, XtWidgetGeometry *,
XtWidgetGeometry *);
static void RefigureLocations(Widget);
ScrollBoxClassRec scrollBoxClassRec = {
{
(WidgetClass) &compositeClassRec,
"scrollBox",
sizeof(ScrollBoxRec),
NULL,
NULL,
FALSE,
Initialize,
NULL,
XtInheritRealize,
NULL,
0,
resources,
XtNumber(resources),
NULLQUARK,
TRUE,
TRUE,
TRUE,
FALSE,
NULL,
Resize,
NULL,
SetValues,
NULL,
XtInheritSetValuesAlmost,
NULL,
NULL,
XtVersion,
NULL,
NULL,
QueryGeometry,
XtInheritDisplayAccelerator,
NULL
},{
GeometryManager,
ChangeManaged,
XtInheritInsertChild,
XtInheritDeleteChild,
NULL
},{
0,
}
};
WidgetClass scrollBoxWidgetClass = (WidgetClass)&scrollBoxClassRec;
static void DoLayout(Widget w, Boolean doit)
{
ScrollBoxWidget sbw = (ScrollBoxWidget)w;
Widget wmain, vscroll, hscroll, child;
Dimension mw, mh;
Dimension vh;
Dimension hw;
Position vx;
Position hy;
Cardinal i;
if (sbw->composite.num_children != 3)
XtAppError(XtWidgetToApplicationContext(w),
"ScrollBox: must manage exactly three widgets.");
for (i = 0; i < sbw->composite.num_children; i++)
{
child = sbw->composite.children[i];
if (!XtIsManaged(child))
XtAppError(XtWidgetToApplicationContext(w),
"ScrollBox: all three widgets must be managed.");
}
wmain = sbw->composite.children[0];
vscroll = sbw->composite.children[1];
hscroll = sbw->composite.children[2];
mw = sbw->core.width - (2 * sbw->scrollBox.h_space) -
vscroll->core.width - (2 * vscroll->core.border_width) -
(2 * wmain->core.border_width);
mh = sbw->core.height - (2 * sbw->scrollBox.v_space) -
hscroll->core.height - (2 * hscroll->core.border_width) -
(2 * wmain->core.border_width);
mw = (mw / sbw->scrollBox.increment_width) *
sbw->scrollBox.increment_width;
mh = ((mh / sbw->scrollBox.increment_height) *
sbw->scrollBox.increment_height) +
sbw->scrollBox.increment_height;
vx = wmain->core.x + mw + sbw->scrollBox.h_space +
wmain->core.border_width + vscroll->core.border_width;
hy = wmain->core.y + mh + sbw->scrollBox.v_space +
wmain->core.border_width + hscroll->core.border_width;
vh = mh;
hw = mw;
if (doit)
{
XtResizeWidget(wmain, mw, mh, 1);
XtResizeWidget(vscroll, vscroll->core.width, vh, 1);
XtMoveWidget(vscroll, vx, vscroll->core.y);
XtResizeWidget(hscroll, hw, hscroll->core.height, 1);
XtMoveWidget(hscroll, hscroll->core.x, hy);
}
}
static XtGeometryResult GeometryManager(Widget w, XtWidgetGeometry *request,
XtWidgetGeometry *reply)
{
XtWidgetGeometry allowed;
if (request->request_mode & ~(XtCWQueryOnly | CWWidth | CWHeight))
return XtGeometryNo;
if (request->request_mode & CWWidth)
allowed.width = request->width;
else
allowed.width = w->core.width;
if (request->request_mode & CWHeight)
allowed.height = request->height;
else
allowed.height = w->core.height;
if (allowed.width == w->core.width && allowed.height == w->core.height)
return XtGeometryNo;
if (!(request->request_mode & XtCWQueryOnly))
RefigureLocations(w);
return XtGeometryYes;
}
static void RefigureLocations(Widget w)
{
DoLayout(w, False);
}
static XtGeometryResult QueryGeometry(Widget w, XtWidgetGeometry *request,
XtWidgetGeometry *reply_return)
{
XtGeometryResult result=XtGeometryNo;
request->request_mode &= CWWidth | CWHeight;
if (request->request_mode == 0)
return XtGeometryYes;
if (request->request_mode & CWHeight)
{
if (request->height < INITIAL_HEIGHT)
{
result = XtGeometryAlmost;
reply_return->height = INITIAL_HEIGHT;
reply_return->request_mode &= CWHeight;
}
else
result = XtGeometryYes;
}
if (request->request_mode & CWWidth)
{
if (request->width < INITIAL_WIDTH)
{
result = XtGeometryAlmost;
reply_return->width = INITIAL_WIDTH;
reply_return->request_mode &= CWWidth;
}
else
result = XtGeometryYes;
}
return result;
}
static void Resize(Widget w)
{
DoLayout(w, True);
}
static void ChangeManaged(Widget w)
{
DoLayout(w, True);
}
static void Initialize(Widget request, Widget new,
ArgList args, Cardinal *num_args)
{
ScrollBoxWidget newsbw = (ScrollBoxWidget)new;
if (newsbw->core.width == 0)
newsbw->core.width = INITIAL_WIDTH;
if (newsbw->core.height == 0)
newsbw->core.height = INITIAL_HEIGHT;
}
static Boolean SetValues(Widget current, Widget request, Widget new,
ArgList args, Cardinal *num_args)
{
ScrollBoxWidget sbwcurrent = (ScrollBoxWidget)current;
ScrollBoxWidget sbwnew = (ScrollBoxWidget)new;
if ((sbwnew->scrollBox.h_space != sbwcurrent->scrollBox.h_space) ||
(sbwnew->scrollBox.v_space != sbwcurrent->scrollBox.v_space))
DoLayout(new, True);
return False;
}