📄 xpdftree.cc
字号:
//========================================================================//// XPDFTree.cc//// Copyright 2002-2003 Glyph & Cog, LLC////========================================================================#include <stdlib.h>#include "gmem.h"#include "XPDFTreeP.h"//------------------------------------------------------------------------#define xpdfTreeIndent 16//------------------------------------------------------------------------struct _XPDFTreeEntry { Widget widget; XPDFTreeEntry *children; XPDFTreeEntry *next;};//------------------------------------------------------------------------static void classPartInitialize(WidgetClass widgetClass);static void initialize(Widget requestWidget, Widget newWidget, ArgList args, Cardinal *numArgs);static void destroy(Widget widget);static void destroySubtree(XPDFTreeEntry *e);static void resize(Widget widget);static void redisplay(Widget widget, XEvent *event, Region region);static void redisplaySubtree(XPDFTreeWidget w, XPDFTreeEntry *e, XEvent *event, Region region);static void drawExpandedIcon(XPDFTreeWidget w, Position x, Position y);static void drawCollapsedIcon(XPDFTreeWidget w, Position x, Position y);static Boolean setValues(Widget oldWidget, Widget requestWidget, Widget newWidget, ArgList args, Cardinal *numArgs);static void setValuesAlmost(Widget oldWidget, Widget newWidget, XtWidgetGeometry *request, XtWidgetGeometry *reply);static XtGeometryResult queryGeometry(Widget widget, XtWidgetGeometry *request, XtWidgetGeometry *reply);static XtGeometryResult geometryManager(Widget widget, XtWidgetGeometry *request, XtWidgetGeometry *reply);static void changeManaged(Widget widget);static void initConstraint(Widget requestWidget, Widget newWidget, ArgList args, Cardinal *numArgs);static void destroyConstraint(Widget widget);static void deleteSubtree(Widget widget);static Boolean constraintSetValues(Widget oldWidget, Widget requestWidget, Widget newWidget, ArgList args, Cardinal *numArgs);static void insertChildOnList(XPDFTreeEntry *e, XPDFTreeEntry **listHead);static void deleteChildFromList(XPDFTreeEntry *e, XPDFTreeEntry **listHead);static void createGC(Widget widget);static void destroyGC(Widget widget);static void layout(Widget widget, Widget instigator);static int layoutSubtree(XPDFTreeWidget w, Widget instigator, XPDFTreeEntry *e, Position x, Position y, Boolean visible);static void calcSize(Widget widget, Widget instigator, Dimension *totalWidth, Dimension *totalHeight);static void calcSubtreeSize(XPDFTreeWidget w, Widget instigator, XPDFTreeEntry *e, Dimension *width, Dimension *height);static Boolean needRelayout(Widget oldWidget, Widget newWidget);static void click(Widget widget, XEvent *event, String *params, Cardinal *numParams);static Boolean findPosition(XPDFTreeWidget w, int x, int y, XPDFTreeEntry **e, Boolean *onExpandIcon);static Boolean findPositionInSubtree(XPDFTreeWidget w, int x, int y, XPDFTreeEntry **e, Boolean *onExpandIcon);//------------------------------------------------------------------------static XtResource resources[] = { { XmNmarginWidth, XmCMarginWidth, XmRHorizontalDimension, sizeof(Dimension), XtOffsetOf(XPDFTreeRec, tree.marginWidth), XmRImmediate, (XtPointer)0 }, { XmNmarginHeight, XmCMarginHeight, XmRVerticalDimension, sizeof(Dimension), XtOffsetOf(XPDFTreeRec, tree.marginHeight), XmRImmediate, (XtPointer)0 }, { XPDFNselectionCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(XPDFTreeRec, tree.selectCallback), XmRImmediate, (XtPointer)NULL }};static XmSyntheticResource synResources[] = { { XmNmarginWidth, sizeof(Dimension), XtOffsetOf(XPDFTreeRec, tree.marginWidth),#if XmVERSION > 1 XmeFromHorizontalPixels, XmeToHorizontalPixels#else _XmFromHorizontalPixels, _XmToHorizontalPixels#endif }, { XmNmarginHeight, sizeof(Dimension), XtOffsetOf(XPDFTreeRec, tree.marginHeight),#if XmVERSION > 1 XmeFromVerticalPixels, XmeToVerticalPixels#else _XmFromVerticalPixels, _XmToVerticalPixels#endif }};static XtResource constraints[] = { { XPDFNentryParent, XPDFCentryParent, XmRWidget, sizeof(Widget), XtOffsetOf(XPDFTreeConstraintRec, tree.entryParent), XmRImmediate, (XtPointer)NULL }, { XPDFNentryExpanded, XPDFCentryExpanded, XmRBoolean, sizeof(Boolean), XtOffsetOf(XPDFTreeConstraintRec, tree.entryExpanded), XmRImmediate, (XtPointer)False }, { XPDFNentryPosition, XPDFCentryPosition, XmRInt, sizeof(int), XtOffsetOf(XPDFTreeConstraintRec, tree.entryPosition), XmRImmediate, (XtPointer)0 }};static char defaultTranslations[] = "<Btn1Down>: XPDFTreeClick()";static XtActionsRec actions[] = { { "XPDFTreeClick", click }};externaldef(xpdftreeclassrec) XPDFTreeClassRec xpdfTreeClassRec = { { // Core (WidgetClass)&xmManagerClassRec, // superclass "XPDFTree", // class_name sizeof(XPDFTreeRec), // widget_size NULL, // class_initialize &classPartInitialize, // class_part_initialize FALSE, // class_inited &initialize, // initialize NULL, // initialize_hook XtInheritRealize, // realize actions, // actions XtNumber(actions), // num_actions resources, // resources XtNumber(resources), // num_resources NULLQUARK, // xrm_class TRUE, // compress_motion XtExposeCompressMaximal, // compress_exposure TRUE, // compress_enterleave FALSE, // visible_interest &destroy, // destroy &resize, // resize &redisplay, // expose &setValues, // set_values NULL, // set_values_hook &setValuesAlmost, // set_values_almost NULL, // get_values_hook NULL, // accept_focus XtVersion, // version NULL, // callback_private defaultTranslations, // tm_table &queryGeometry, // query_geometry NULL, // display_accelerator NULL // extension }, { // Composite &geometryManager, // geometry_manager &changeManaged, // change_managed XtInheritInsertChild, // insert_child XtInheritDeleteChild, // delete_child NULL // extension }, { // Constraint constraints, // constraint_resources XtNumber(constraints), // constraint_num_resources sizeof(XPDFTreeConstraintRec), // constraint_size &initConstraint, // constraint_initialize &destroyConstraint, // constraint_destroy &constraintSetValues, // constraint_set_values NULL // extension }, { // XmManager XtInheritTranslations, // translations#if XmVERSION > 1 synResources, // syn_resources XtNumber(synResources), // num_syn_resources#else NULL, // syn_resources 0, // num_syn_resources#endif NULL, // syn_constraint_resources 0, // num_syn_constraint_res's XmInheritParentProcess, // parent_process NULL // extension }, { // XPDFTree &createGC, // createGC &destroyGC, // destroyGC &layout, // layout &calcSize, // calcSize &needRelayout, // needRelayout NULL // extension }};externaldef(xpdftreewidgetclass) WidgetClass xpdfTreeWidgetClass = (WidgetClass)&xpdfTreeClassRec;//------------------------------------------------------------------------static void classPartInitialize(WidgetClass widgetCls) { XPDFTreeWidgetClass wc = (XPDFTreeWidgetClass)widgetCls; XPDFTreeWidgetClass sc = (XPDFTreeWidgetClass)wc->coreClass.superclass; // method inheritance if (wc->treeClass.createGC == XPDFInheritCreateGC) { wc->treeClass.createGC = sc->treeClass.createGC; } if (wc->treeClass.destroyGC == XPDFInheritDestroyGC) { wc->treeClass.destroyGC = sc->treeClass.destroyGC; } if (wc->treeClass.layout == XPDFInheritLayout) { wc->treeClass.layout = sc->treeClass.layout; } if (wc->treeClass.calcSize == XPDFInheritCalcSize) { wc->treeClass.calcSize = sc->treeClass.calcSize; } if (wc->treeClass.needRelayout == XPDFInheritNeedRelayout) { wc->treeClass.needRelayout = sc->treeClass.needRelayout; }}static void initialize(Widget requestWidget, Widget newWidget, ArgList args, Cardinal *numArgs) { XPDFTreeWidget nw = (XPDFTreeWidget)newWidget; XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass(newWidget); nw->tree.root = NULL; nw->tree.redrawY = -1; if (cls->treeClass.createGC) { (*cls->treeClass.createGC)(newWidget); } else { createGC(newWidget); }}static void destroy(Widget widget) { XPDFTreeWidget w = (XPDFTreeWidget)widget; XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass(widget); if (w->tree.root) { destroySubtree(w->tree.root); w->tree.root = NULL; } if (cls->treeClass.destroyGC) { (*cls->treeClass.destroyGC)(widget); } else { destroyGC(widget); }}static void destroySubtree(XPDFTreeEntry *e) { if (e->children) { destroySubtree(e->children); } if (e->next) { destroySubtree(e->next); }}static void resize(Widget widget) { XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass(widget); if (cls->treeClass.layout) { (*cls->treeClass.layout)(widget, NULL); } else { layout(widget, NULL); }}static void redisplay(Widget widget, XEvent *event, Region region) { XPDFTreeWidget w = (XPDFTreeWidget)widget; XPDFTreeEntry *e; if (w->tree.redrawY >= 0) { XClearArea(XtDisplay((Widget)w), XtWindow((Widget)w), 0, w->tree.redrawY, w->core.width, w->core.height, False); w->tree.redrawY = -1; } for (e = w->tree.root; e; e = e->next) { redisplaySubtree(w, e, event, region); }}static void redisplaySubtree(XPDFTreeWidget w, XPDFTreeEntry *e, XEvent *event, Region region) { XPDFTreeConstraint c; Position x, y, y2; XPDFTreeEntry *child; (*XtClass(e->widget)->core_class.expose)(e->widget, event, region); c = XPDFTreeCPart(e->widget); x = e->widget->core.x; y = e->widget->core.y + e->widget->core.height / 2; if (e->children) { if (c->entryExpanded) { drawExpandedIcon(w, x - 8, y); y2 = y; // make gcc happy for (child = e->children; child; child = child->next) { y2 = child->widget->core.y + child->widget->core.height / 2; XDrawLine(XtDisplay((Widget)w), XtWindow((Widget)w), w->tree.dottedGC, x - 8, y2, x + 6, y2); redisplaySubtree(w, child, event, region); } XDrawLine(XtDisplay((Widget)w), XtWindow((Widget)w), w->tree.dottedGC, x - 8, y + 2, x - 8, y2); } else { drawCollapsedIcon(w, x - 8, y); } }}static void drawExpandedIcon(XPDFTreeWidget w, Position x, Position y) { XPoint pts[4]; pts[0].x = x - 4; pts[0].y = y - 2; pts[1].x = x + 4; pts[1].y = y - 2; pts[2].x = x; pts[2].y = y + 2; pts[3].x = x - 4; pts[3].y = y - 2; XDrawLines(XtDisplay((Widget)w), XtWindow((Widget)w), w->tree.plainGC, pts, 4, CoordModeOrigin);}static void drawCollapsedIcon(XPDFTreeWidget w, Position x, Position y) { XPoint pts[4]; pts[0].x = x - 2; pts[0].y = y - 4; pts[1].x = x - 2; pts[1].y = y + 4; pts[2].x = x + 2; pts[2].y = y; pts[3].x = x - 2; pts[3].y = y - 4; XDrawLines(XtDisplay((Widget)w), XtWindow((Widget)w), w->tree.plainGC, pts, 4, CoordModeOrigin);}static Boolean setValues(Widget oldWidget, Widget requestWidget, Widget newWidget, ArgList args, Cardinal *numArgs) { XPDFTreeWidget ow = (XPDFTreeWidget)oldWidget; XPDFTreeWidget nw = (XPDFTreeWidget)newWidget; XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass(nw); Boolean relayout, redisp; // check to see if layout-affecting resources have changed if (cls->treeClass.needRelayout) { relayout = (*cls->treeClass.needRelayout)((Widget)ow, (Widget)nw); } else { relayout = needRelayout((Widget)ow, (Widget)nw); } redisp = False; if (relayout) { // calculate a new ideal size (reset the widget size first so // calcSize will compute a new one) if (nw->core.width == ow->core.width) { nw->core.width = 0; } if (nw->core.height == ow->core.height) { nw->core.height = 0; } if (cls->treeClass.calcSize) { (*cls->treeClass.calcSize)((Widget)nw, NULL, &nw->core.width, &nw->core.height); } else { calcSize((Widget)nw, NULL, &nw->core.width, &nw->core.height); } // if resources have changed but size hasn't, layout manually // (because Xt just looks at the size) if (nw->core.width == ow->core.width && nw->core.height == ow->core.height) { if (cls->treeClass.layout) { (*cls->treeClass.layout)((Widget)nw, NULL); } else { layout((Widget)nw, NULL); } redisp = True; } } return redisp;}static void setValuesAlmost(Widget oldWidget, Widget newWidget, XtWidgetGeometry *request, XtWidgetGeometry *reply) { XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass(newWidget); // our parent rejected a geometry request, so accept the compromise // and relayout if (!reply->request_mode) { if (cls->treeClass.layout) { (*cls->treeClass.layout)(newWidget, NULL); } else { layout(newWidget, NULL); } } *request = *reply;}static XtGeometryResult queryGeometry(Widget widget, XtWidgetGeometry *request, XtWidgetGeometry *reply) { XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass(widget); if (!XtIsRealized(widget)) { reply->width = XtWidth(widget); reply->height = XtHeight(widget); } else { reply->width = 0; reply->height = 0; } if (cls->treeClass.calcSize) { (*cls->treeClass.calcSize)(widget, NULL, &reply->width, &reply->height); } else { calcSize(widget, NULL, &reply->width, &reply->height); }#if XmVERSION > 1 return XmeReplyToQueryGeometry(widget, request, reply);#else if ((request->request_mode & CWWidth) && (request->request_mode & CWHeight) && request->width == reply->width && request->height == reply->height) { return XtGeometryYes; } if (reply->width == XtWidth(widget) && reply->height == XtHeight(widget)) { return XtGeometryNo; } reply->request_mode = CWWidth | CWHeight; return XtGeometryAlmost;#endif}static XtGeometryResult geometryManager(Widget widget, XtWidgetGeometry *request, XtWidgetGeometry *reply) { XPDFTreeWidget w = (XPDFTreeWidget)XtParent(widget); XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass(w); Dimension curWidth, curHeight, curBW; XtWidgetGeometry parentReq; XtGeometryResult result; // deny any requests for a new position if ((request->request_mode & CWX) || (request->request_mode & CWY)) { return XtGeometryNo; } // save the current geometry curWidth = w->core.width; curHeight = w->core.height; curBW = w->core.border_width; // make the requested changes if (request->request_mode & CWWidth) { w->core.width = request->width;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -