diff options
author | treectrl <treectrl> | 2002-12-17 05:04:00 (GMT) |
---|---|---|
committer | treectrl <treectrl> | 2002-12-17 05:04:00 (GMT) |
commit | 51219bf94e57870b142db498f63180828d6990d9 (patch) | |
tree | 2aaef21ae17c7dc8591f1fdf095fb4fbeeef8197 /generic/tkTreeDrag.c | |
download | tktreectrl-51219bf94e57870b142db498f63180828d6990d9.zip tktreectrl-51219bf94e57870b142db498f63180828d6990d9.tar.gz tktreectrl-51219bf94e57870b142db498f63180828d6990d9.tar.bz2 |
Initial revision
Diffstat (limited to 'generic/tkTreeDrag.c')
-rw-r--r-- | generic/tkTreeDrag.c | 436 |
1 files changed, 436 insertions, 0 deletions
diff --git a/generic/tkTreeDrag.c b/generic/tkTreeDrag.c new file mode 100644 index 0000000..f6cc1e9 --- /dev/null +++ b/generic/tkTreeDrag.c @@ -0,0 +1,436 @@ +#include "tkTreeCtrl.h" + +typedef struct DragElem DragElem; +typedef struct DragImage DragImage; + +struct DragElem +{ + int x, y, width, height; + DragElem *next; +}; + +struct DragImage +{ + TreeCtrl *tree; + int visible; + int x, y; /* offset to draw at in canvas coords */ + int bounds[4]; /* bounds of all DragElems */ + DragElem *elem; + int onScreen; /* TRUE if is displayed */ + int sx, sy; /* Window coords where displayed */ +}; + +static Tk_OptionSpec optionSpecs[] = { + {TK_OPTION_BOOLEAN, "-visible", (char *) NULL, (char *) NULL, + "0", -1, Tk_Offset(DragImage, visible), + 0, (ClientData) NULL, 0}, + {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, 0, 0} +}; + +static Tk_OptionTable optionTable = NULL; + +static DragElem *DragElem_Alloc(DragImage *dragImage) +{ + DragElem *elem = (DragElem *) ckalloc(sizeof(DragElem)); + DragElem *walk = dragImage->elem; + memset(elem, '\0', sizeof(DragElem)); + if (dragImage->elem == NULL) + dragImage->elem = elem; + else + { + while (walk->next != NULL) + walk = walk->next; + walk->next = elem; + } + return elem; +} + +static DragElem *DragElem_Free(DragImage *dragImage, DragElem *elem) +{ + DragElem *next = elem->next; + WFREE(elem, DragElem); + return next; +} + +int TreeDragImage_Init(TreeCtrl *tree) +{ + DragImage *dragImage; + + if (optionTable == NULL) + optionTable = Tk_CreateOptionTable(tree->interp, optionSpecs); + + dragImage = (DragImage *) ckalloc(sizeof(DragImage)); + memset(dragImage, '\0', sizeof(DragImage)); + dragImage->tree = tree; + if (Tk_InitOptions(tree->interp, (char *) dragImage, optionTable, + tree->tkwin) != TCL_OK) + { + WFREE(dragImage, DragImage); + return TCL_ERROR; + } + tree->dragImage = (TreeDragImage) dragImage; + return TCL_OK; +} + +void TreeDragImage_Free(TreeDragImage dragImage_) +{ + DragImage *dragImage = (DragImage *) dragImage_; + DragElem *elem = dragImage->elem; + + while (elem != NULL) + elem = DragElem_Free(dragImage, elem); + Tk_FreeConfigOptions((char *) dragImage, optionTable, + dragImage->tree->tkwin); + WFREE(dragImage, DragImage); +} + +void TreeDragImage_Display(TreeDragImage dragImage_) +{ + DragImage *dragImage = (DragImage *) dragImage_; + TreeCtrl *tree = dragImage->tree; + + if (!dragImage->onScreen && dragImage->visible) + { + dragImage->sx = 0 - tree->xOrigin; + dragImage->sy = 0 - tree->yOrigin; + TreeDragImage_Draw(dragImage_, Tk_WindowId(tree->tkwin), dragImage->sx, dragImage->sy); + dragImage->onScreen = TRUE; + } +} + +void TreeDragImage_Undisplay(TreeDragImage dragImage_) +{ + DragImage *dragImage = (DragImage *) dragImage_; + TreeCtrl *tree = dragImage->tree; + + if (dragImage->onScreen) + { + TreeDragImage_Draw(dragImage_, Tk_WindowId(tree->tkwin), dragImage->sx, dragImage->sy); + dragImage->onScreen = FALSE; + } +} + +static int DragImage_Config(DragImage *dragImage, int objc, Tcl_Obj *CONST objv[]) +{ + TreeCtrl *tree = dragImage->tree; + Tk_SavedOptions savedOptions; + int mask, result; + + result = Tk_SetOptions(tree->interp, (char *) dragImage, optionTable, + objc, objv, tree->tkwin, &savedOptions, &mask); + if (result != TCL_OK) + { + Tk_RestoreSavedOptions(&savedOptions); + return TCL_ERROR; + } + Tk_FreeSavedOptions(&savedOptions); +#if 0 + if (mask & CONF_VISIBLE) + { + if (dragImage->visible) + TreeDragImage_Display(); + else + TreeDragImage_Unisplay(); + } +#endif + return TCL_OK; +} + +void TreeDragImage_Draw(TreeDragImage dragImage_, Drawable drawable, int x, int y) +{ + DragImage *dragImage = (DragImage *) dragImage_; + TreeCtrl *tree = dragImage->tree; + DragElem *elem = dragImage->elem; + DotState dotState; + +/* if (!dragImage->visible) + return; */ + if (elem == NULL) + return; + + DotRect_Setup(tree, drawable, &dotState); + + while (elem != NULL) + { + DotRect_Draw(&dotState, + x + dragImage->x + elem->x, + y + dragImage->y + elem->y, + elem->width, elem->height); + elem = elem->next; + } + + DotRect_Restore(&dotState); +} + +int DragImageCmd(ClientData clientData, Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[]) +{ + TreeCtrl *tree = (TreeCtrl *) clientData; + DragImage *dragImage = (DragImage *) tree->dragImage; + static CONST char *commandNames[] = { "add", "cget", "clear", "configure", + "offset", "visible", (char *) NULL }; + enum { COMMAND_ADD, COMMAND_CGET, COMMAND_CLEAR, COMMAND_CONFIGURE, + COMMAND_OFFSET, COMMAND_VISIBLE }; + int index; + + if (objc < 3) + { + Tcl_WrongNumArgs(interp, 2, objv, "command ?arg arg...?"); + return TCL_ERROR; + } + + if (Tcl_GetIndexFromObj(interp, objv[2], commandNames, "command", 0, + &index) != TCL_OK) + { + return TCL_ERROR; + } + + switch (index) + { + /* T dragimage add I ?C? ?E ...? */ + case COMMAND_ADD: + { + XRectangle rects[20]; + TreeItem item; + TreeItemColumn itemColumn; + TreeColumn treeColumn; + int i, count, columnIndex; + int indent, width, totalWidth; + int x, y, w, h; + DragElem *elem; + StyleDrawArgs drawArgs; + + if (objc < 4) + { + Tcl_WrongNumArgs(interp, 3, objv, "item ?column? ?element ...?"); + return TCL_ERROR; + } + if (TreeItem_FromObj(tree, objv[3], &item, 0) != TCL_OK) + return TCL_ERROR; + + Tree_ItemBbox(tree, item, &x, &y, &w, &h); + + drawArgs.tree = tree; + drawArgs.drawable = None; + drawArgs.state = TreeItem_GetState(tree, item); + drawArgs.y = y; + drawArgs.height = h; + + TreeDragImage_Undisplay(tree->dragImage); + + if (objc > 4) + { + if (TreeItem_ColumnFromObj(tree, item, objv[4], &itemColumn, &columnIndex) != TCL_OK) + { + TreeDragImage_Display(tree->dragImage); + return TCL_ERROR; + } + drawArgs.style = TreeItemColumn_GetStyle(tree, itemColumn); + if (drawArgs.style == NULL) + { + TreeDragImage_Display(tree->dragImage); + break; + } + totalWidth = 0; + treeColumn = tree->columns; + for (i = 0; i < columnIndex; i++) + { + totalWidth += TreeColumn_UseWidth(treeColumn); + treeColumn = TreeColumn_Next(treeColumn); + } + if (TreeColumn_Index(treeColumn) == tree->columnTree) + indent = TreeItem_Indent(tree, item); + else + indent = 0; + drawArgs.x = x + indent + totalWidth; + drawArgs.width = TreeColumn_UseWidth(treeColumn) - indent; + drawArgs.justify = TreeColumn_Justify(treeColumn); + count = TreeStyle_GetElemRects(&drawArgs, objc - 5, objv + 5, rects); + if (count == -1) + { + TreeDragImage_Display(tree->dragImage); + return TCL_ERROR; + } + for (i = 0; i < count; i++) + { + elem = DragElem_Alloc(dragImage); + elem->x = rects[i].x; + elem->y = rects[i].y; + elem->width = rects[i].width; + elem->height = rects[i].height; + } + } + else + { + totalWidth = 0; + treeColumn = tree->columns; + itemColumn = TreeItem_GetFirstColumn(tree, item); + while (itemColumn != NULL) + { + width = TreeColumn_UseWidth(treeColumn); + if (TreeColumn_Index(treeColumn) == tree->columnTree) + indent = TreeItem_Indent(tree, item); + else + indent = 0; + drawArgs.style = TreeItemColumn_GetStyle(tree, itemColumn); + if (drawArgs.style != NULL) + { + drawArgs.x = x + indent + totalWidth; + drawArgs.width = width - indent; + drawArgs.justify = TreeColumn_Justify(treeColumn); + count = TreeStyle_GetElemRects(&drawArgs, 0, NULL, rects); + if (count == -1) + { + TreeDragImage_Display(tree->dragImage); + return TCL_ERROR; + } + for (i = 0; i < count; i++) + { + elem = DragElem_Alloc(dragImage); + elem->x = rects[i].x; + elem->y = rects[i].y; + elem->width = rects[i].width; + elem->height = rects[i].height; + } + } + totalWidth += width; + treeColumn = TreeColumn_Next(treeColumn); + itemColumn = TreeItemColumn_GetNext(tree, itemColumn); + } + } + dragImage->bounds[0] = 100000; + dragImage->bounds[1] = 100000; + dragImage->bounds[2] = -100000; + dragImage->bounds[3] = -100000; + for (elem = dragImage->elem; + elem != NULL; + elem = elem->next) + { + if (elem->x < dragImage->bounds[0]) + dragImage->bounds[0] = elem->x; + if (elem->y < dragImage->bounds[1]) + dragImage->bounds[1] = elem->y; + if (elem->x + elem->width > dragImage->bounds[2]) + dragImage->bounds[2] = elem->x + elem->width; + if (elem->y + elem->height > dragImage->bounds[3]) + dragImage->bounds[3] = elem->y + elem->height; + } + TreeDragImage_Display(tree->dragImage); + break; + } + + /* T dragimage cget option */ + case COMMAND_CGET: + { + Tcl_Obj *resultObjPtr; + + if (objc != 4) + { + Tcl_WrongNumArgs(interp, 3, objv, "option"); + return TCL_ERROR; + } + resultObjPtr = Tk_GetOptionValue(interp, (char *) dragImage, + optionTable, objv[4], tree->tkwin); + if (resultObjPtr == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, resultObjPtr); + break; + } + + /* T dragimage clear */ + case COMMAND_CLEAR: + { + if (dragImage->elem != NULL) + { + DragElem *elem = dragImage->elem; + TreeDragImage_Undisplay(tree->dragImage); +/* if (dragImage->visible) + DragImage_Redraw(dragImage); */ + while (elem != NULL) + elem = DragElem_Free(dragImage, elem); + dragImage->elem = NULL; + } + break; + } + + /* T dragimage configure ?option? ?value? ?option value ...? */ + case COMMAND_CONFIGURE: + { + Tcl_Obj *resultObjPtr; + + if (objc < 3) + { + Tcl_WrongNumArgs(interp, 3, objv, "?option? ?value?"); + return TCL_ERROR; + } + if (objc <= 4) + { + resultObjPtr = Tk_GetOptionInfo(interp, (char *) dragImage, + optionTable, + (objc == 3) ? (Tcl_Obj *) NULL : objv[3], + tree->tkwin); + if (resultObjPtr == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, resultObjPtr); + break; + } + return DragImage_Config(dragImage, objc - 3, objv + 3); + } + + /* T dragimage offset ?x y? */ + case COMMAND_OFFSET: + { + int x, y; + + if (objc != 3 && objc != 5) + { + Tcl_WrongNumArgs(interp, 3, objv, "?x y?"); + return TCL_ERROR; + } + if (objc == 3) + { + FormatResult(interp, "%d %d", dragImage->x, dragImage->y); + break; + } + if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) + return TCL_ERROR; + if (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) + return TCL_ERROR; + TreeDragImage_Undisplay(tree->dragImage); +/* if (dragImage->visible) + DragImage_Redraw(dragImage); */ + dragImage->x = x; + dragImage->y = y; + TreeDragImage_Display(tree->dragImage); + break; + } + + /* T dragimage visible ?boolean? */ + case COMMAND_VISIBLE: + { + int visible; + + if (objc != 3 && objc != 4) + { + Tcl_WrongNumArgs(interp, 3, objv, "?boolean?"); + return TCL_ERROR; + } + if (objc == 4) + { + if (Tcl_GetBooleanFromObj(interp, objv[3], &visible) != TCL_OK) + return TCL_ERROR; + if (visible != dragImage->visible) + { + dragImage->visible = visible; + TreeDragImage_Undisplay(tree->dragImage); + TreeDragImage_Display(tree->dragImage); + } + } + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(dragImage->visible)); + break; + } + } + + return TCL_OK; +} |