📄 xpdftree.cc
字号:
} if (request->request_mode & CWHeight) { w->core.height = request->height; } if (request->request_mode & CWBorderWidth) { w->core.border_width = request->border_width; } // calculate the new ideal size parentReq.width = 0; parentReq.height = 0; if (cls->treeClass.calcSize) { (*cls->treeClass.calcSize)((Widget)w, widget, &parentReq.width, &reply->height); } else { calcSize((Widget)w, widget, &parentReq.width, &reply->height); } // send geometry request to our parent parentReq.request_mode = CWWidth | CWHeight; if (request->request_mode & XtCWQueryOnly) { parentReq.request_mode |= XtCWQueryOnly; } result = XtMakeGeometryRequest((Widget)w, &parentReq, NULL); if (result == XtGeometryAlmost) { result = XtGeometryNo; } if (result == XtGeometryNo || (request->request_mode & XtCWQueryOnly)) { // restore the original geometry w->core.width = curWidth; w->core.height = curHeight; w->core.border_width = curBW; } else { if (cls->treeClass.layout) { (*cls->treeClass.layout)((Widget)w, widget); } else { layout((Widget)w, widget); } } return result;}static void changeManaged(Widget widget) { Dimension width, height; XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass(widget); // compute the ideal size if (!XtIsRealized(widget)) { width = XtWidth(widget); height = XtHeight(widget); } else { width = 0; height = 0; } if (cls->treeClass.calcSize) { (*cls->treeClass.calcSize)(widget, NULL, &width, &height); } else { calcSize(widget, NULL, &width, &height); } // make resize request to parent -- keep asking until we get a yes // or no while (XtMakeResizeRequest(widget, width, height, &width, &height) == XtGeometryAlmost) ; // relayout if (cls->treeClass.layout) { (*cls->treeClass.layout)(widget, NULL); } else { layout(widget, NULL); }#if XmVERSION > 1 // update keyboard traversal XmeNavigChangeManaged(widget);#else _XmNavigChangeManaged(widget);#endif}static void initConstraint(Widget requestWidget, Widget newWidget, ArgList args, Cardinal *numArgs) { XPDFTreeWidget w = (XPDFTreeWidget)XtParent(newWidget); XPDFTreeConstraint c; c = XPDFTreeCPart(newWidget); c->e = (XPDFTreeEntry *)gmalloc(sizeof(XPDFTreeEntry)); c->e->widget = newWidget; c->e->children = NULL; c->e->next = NULL; if (c->entryParent) { insertChildOnList(c->e, &XPDFTreeCPart(c->entryParent)->e->children); } else { insertChildOnList(c->e, &w->tree.root); }}static void destroyConstraint(Widget widget) { deleteSubtree(widget);}static void deleteSubtree(Widget widget) { XPDFTreeWidget w = (XPDFTreeWidget)XtParent(widget); XPDFTreeConstraint c; c = XPDFTreeCPart(widget); if (!c->e) { return; } while (c->e->children) { deleteSubtree(c->e->children->widget); } if (c->entryParent) { deleteChildFromList(c->e, &XPDFTreeCPart(c->entryParent)->e->children); } else { deleteChildFromList(c->e, &w->tree.root); } gfree(c->e); c->e = NULL;}static Boolean constraintSetValues(Widget oldWidget, Widget requestWidget, Widget newWidget, ArgList args, Cardinal *numArgs) { XPDFTreeWidget w = (XPDFTreeWidget)XtParent(newWidget); XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass((Widget)w); XPDFTreeConstraint oc, nc; Boolean relayout; Dimension width, height; if (!XtIsManaged(newWidget)) { return False; } oc = XPDFTreeCPart(oldWidget); nc = XPDFTreeCPart(newWidget); relayout = False; if (nc->entryParent != oc->entryParent || nc->entryPosition != oc->entryPosition) { if (oc->entryParent) { deleteChildFromList(oc->e, &XPDFTreeCPart(oc->entryParent)->e->children); } else { deleteChildFromList(oc->e, &w->tree.root); } if (nc->entryParent) { insertChildOnList(nc->e, &XPDFTreeCPart(nc->entryParent)->e->children); } else { insertChildOnList(nc->e, &w->tree.root); } relayout = True; } else if (nc->entryExpanded != oc->entryExpanded) { relayout = True; } if (relayout) { // calculate a new ideal size (reset the widget size first so // calcSize will compute a new one) width = 0; height = 0; if (cls->treeClass.calcSize) { (*cls->treeClass.calcSize)((Widget)w, NULL, &width, &height); } else { calcSize((Widget)w, NULL, &width, &height); } // make resize request to parent -- keep asking until we get a yes // or no while (XtMakeResizeRequest((Widget)w, width, height, &width, &height) == XtGeometryAlmost) ; // relayout the widget if (cls->treeClass.layout) { (*cls->treeClass.layout)((Widget)w, NULL); } else { layout((Widget)w, NULL); } } return relayout;}static void insertChildOnList(XPDFTreeEntry *e, XPDFTreeEntry **listHead) { int pos; XPDFTreeEntry *e2; pos = XPDFTreeCPart(e->widget)->entryPosition; if (!*listHead || pos < XPDFTreeCPart((*listHead)->widget)->entryPosition) { e->next = *listHead; *listHead = e; } else { for (e2 = *listHead; e2->next && pos >= XPDFTreeCPart(e2->next->widget)->entryPosition; e2 = e2->next) ; e->next = e2->next; e2->next = e; }}static void deleteChildFromList(XPDFTreeEntry *e, XPDFTreeEntry **listHead) { XPDFTreeEntry **p; for (p = listHead; *p; p = &(*p)->next) { if (*p == e) { *p = e->next; e->next = NULL; return; } }}static void createGC(Widget widget) { XPDFTreeWidget w = (XPDFTreeWidget)widget; XGCValues gcValues; gcValues.foreground = w->manager.foreground; gcValues.line_width = 0; gcValues.line_style = LineSolid; w->tree.plainGC = XtGetGC(widget, GCForeground | GCLineWidth | GCLineStyle, &gcValues); gcValues.line_style = LineOnOffDash; gcValues.dashes = 1; gcValues.dash_offset = 0; w->tree.dottedGC = XtGetGC(widget, GCForeground | GCLineWidth | GCLineStyle | GCDashList | GCDashOffset, &gcValues);}static void destroyGC(Widget widget) { XPDFTreeWidget w = (XPDFTreeWidget)widget; XtReleaseGC(widget, w->tree.plainGC); XtReleaseGC(widget, w->tree.dottedGC);}static void layout(Widget widget, Widget instigator) { XPDFTreeWidget w = (XPDFTreeWidget)widget; XPDFTreeEntry *e; Position x, y; x = w->tree.marginWidth + xpdfTreeIndent; y = w->tree.marginHeight; for (e = w->tree.root; e; e = e->next) { y = layoutSubtree(w, instigator, e, x, y, True); }}static int layoutSubtree(XPDFTreeWidget w, Widget instigator, XPDFTreeEntry *e, Position x, Position y, Boolean visible) { Widget ew; XPDFTreeEntry *child; XPDFTreeConstraint c; ew = e->widget; if (!XtIsManaged(ew)) { return y; } c = XPDFTreeCPart(ew); // place this entry if (ew) { if (visible) { if (ew == instigator) { ew->core.x = x; ew->core.y = y; } else {#if XmVERSION > 1 XmeConfigureObject(ew, x, y, ew->core.width, ew->core.height, ew->core.border_width);#else _XmConfigureObject(ew, x, y, ew->core.width, ew->core.height, ew->core.border_width);#endif } y += ew->core.height + 2 * ew->core.border_width; } } // place this entry's children x += xpdfTreeIndent; for (child = e->children; child; child = child->next) { y = layoutSubtree(w, instigator, child, x, y, visible && (!c || c->entryExpanded)); } return y;}static void calcSize(Widget widget, Widget instigator, Dimension *totalWidth, Dimension *totalHeight) { XPDFTreeWidget w = (XPDFTreeWidget)widget; XPDFTreeEntry *e; Dimension w1, h1, w2, h2; w1 = h1 = 0; for (e = w->tree.root; e; e = e->next) { calcSubtreeSize(w, instigator, e, &w2, &h2); if (w2 > w1) { w1 = w2; } h1 += h2; } w1 += xpdfTreeIndent + 2 * w->tree.marginWidth; h1 += 2 * w->tree.marginHeight; if (h1 == 0) { h1 = 1; } if (!*totalWidth) { *totalWidth = w1; } if (!*totalHeight) { *totalHeight = h1; }}static void calcSubtreeSize(XPDFTreeWidget w, Widget instigator, XPDFTreeEntry *e, Dimension *width, Dimension *height) { Widget ew; XPDFTreeEntry *child; XPDFTreeConstraint c; XtWidgetGeometry geom; Dimension w1, h1, w2, h2; ew = e->widget; if (!XtIsManaged(ew)) { *width = *height = 0; return; } c = XPDFTreeCPart(ew); // get size of this entry if (ew) { if (!XtIsManaged(ew)) { *width = *height = 0; return; } if (ew == instigator) { w1 = ew->core.width; h1 = ew->core.height; } else { XtQueryGeometry(ew, NULL, &geom); w1 = (geom.request_mode & CWWidth) ? geom.width : ew->core.width; h1 = (geom.request_mode & CWHeight) ? geom.height : ew->core.height; } h1 += 2 * ew->core.border_width; } else { // root of tree w1 = 0; h1 = 0; } // if this entry is expanded, get size of all of its children if (c->entryExpanded) { for (child = e->children; child; child = child->next) { calcSubtreeSize(w, instigator, child, &w2, &h2); w2 += xpdfTreeIndent; if (w2 > w1) { w1 = w2; } h1 += h2; } } *width = w1; *height = h1;}static Boolean needRelayout(Widget oldWidget, Widget newWidget) { XPDFTreeWidget ow = (XPDFTreeWidget)oldWidget; XPDFTreeWidget nw = (XPDFTreeWidget)newWidget; if (nw->tree.marginWidth != ow->tree.marginWidth || nw->tree.marginHeight != ow->tree.marginHeight) { return True; } return False;}static void click(Widget widget, XEvent *event, String *params, Cardinal *numParams) { XPDFTreeWidget w = (XPDFTreeWidget)widget; XButtonPressedEvent *bpe; XPDFTreeEntry *e; Boolean onExpandIcon; XPDFTreeConstraint c; XPDFTreeSelectCallbackStruct cbs; if (event->type != ButtonPress) { return; } bpe = (XButtonPressedEvent *)event; if (findPosition(w, bpe->x, bpe->y, &e, &onExpandIcon)) { if (onExpandIcon) { c = XPDFTreeCPart(e->widget); w->tree.redrawY = e->widget->core.y; XtVaSetValues(e->widget, XPDFNentryExpanded, !c->entryExpanded, NULL); } else { XmProcessTraversal(e->widget, XmTRAVERSE_CURRENT); XtCallActionProc(widget, "ManagerGadgetActivate", event, NULL, 0); cbs.reason = XmCR_ACTIVATE; cbs.event = event; cbs.selectedItem = e->widget; XtCallCallbackList(widget, w->tree.selectCallback, &cbs); } }}static Boolean findPosition(XPDFTreeWidget w, int x, int y, XPDFTreeEntry **e, Boolean *onExpandIcon) { XPDFTreeEntry *e2; for (e2 = w->tree.root; e2; e2 = e2->next) { *e = e2; if (findPositionInSubtree(w, x, y, e, onExpandIcon)) { return True; } } return False;}// If (x,y) falls on either an expand/collapse icon or a label gadget,// set *<e> and *<onExpandIcon> and return true.static Boolean findPositionInSubtree(XPDFTreeWidget w, int x, int y, XPDFTreeEntry **e, Boolean *onExpandIcon) { Widget child; XPDFTreeConstraint c; XPDFTreeEntry *e2; int y1; child = (*e)->widget; y1 = child->core.y + child->core.height / 2; if (x >= child->core.x && x < child->core.x + child->core.width && y >= child->core.y && y < child->core.y + child->core.height) { *onExpandIcon = False; return True; } else if (x >= child->core.x - 16 && x < child->core.x - 4 && y >= y1 - 6 && y < y1 + 6 && (*e)->children) { *onExpandIcon = True; return True; } c = XPDFTreeCPart(child); if (!c || c->entryExpanded) { for (e2 = (*e)->children; e2; e2 = e2->next) { *e = e2; if (findPositionInSubtree(w, x, y, e, onExpandIcon)) { return True; } } } return False;}Widget XPDFCreateTree(Widget parent, char *name, ArgList argList, Cardinal numArgs) { return XtCreateWidget(name, xpdfTreeWidgetClass, parent, argList, numArgs);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -