diff options
author | treectrl <treectrl> | 2005-01-03 21:38:38 (GMT) |
---|---|---|
committer | treectrl <treectrl> | 2005-01-03 21:38:38 (GMT) |
commit | 14f072cf5e10637c71fe26199ce189db3709b208 (patch) | |
tree | cbc25a16bfd9298cad3dc920decc768e4fbbfcef | |
parent | 11b950493c1581db016ec145db6ae6cd6af00d04 (diff) | |
download | tktreectrl-14f072cf5e10637c71fe26199ce189db3709b208.zip tktreectrl-14f072cf5e10637c71fe26199ce189db3709b208.tar.gz tktreectrl-14f072cf5e10637c71fe26199ce189db3709b208.tar.bz2 |
New -backgroundimage option.
Fixed display bugs with "-doublebuffer window".
Macintosh drawing fixes.
-rw-r--r-- | generic/tkTreeDisplay.c | 224 |
1 files changed, 209 insertions, 15 deletions
diff --git a/generic/tkTreeDisplay.c b/generic/tkTreeDisplay.c index 8852cda..1d4abfa 100644 --- a/generic/tkTreeDisplay.c +++ b/generic/tkTreeDisplay.c @@ -5,7 +5,7 @@ * * Copyright (c) 2002-2004 Tim Baker * - * RCS: @(#) $Id: tkTreeDisplay.c,v 1.16 2004/10/24 18:33:00 treectrl Exp $ + * RCS: @(#) $Id: tkTreeDisplay.c,v 1.17 2005/01/03 21:38:38 treectrl Exp $ */ #include "tkTreeCtrl.h" @@ -1690,6 +1690,12 @@ static DItem *UpdateDInfoForRange(TreeCtrl *tree, DItem *dItemHead, Range *range TreeItem item; int maxX, maxY; int index, indexVis; +#ifdef BG_IMAGE + int bgImgWidth, bgImgHeight; + + if (tree->backgroundImage != NULL) + Tk_SizeOfImage(tree->backgroundImage, &bgImgWidth, &bgImgHeight); +#endif maxX = Tk_Width(tree->tkwin) - tree->inset; maxY = Tk_Height(tree->tkwin) - tree->inset; @@ -1747,6 +1753,15 @@ static DItem *UpdateDInfoForRange(TreeCtrl *tree, DItem *dItemHead, Range *range tree->columnTreeVis && ((dItem->oldY & 1) != (y & 1))) dItem->flags |= DITEM_DIRTY | DITEM_ALL_DIRTY; + +#ifdef BG_IMAGE + /* We can't copy the item to its new position unless it + * has the same part of the background image behind it */ + else if ((tree->backgroundImage != NULL) && + (((dItem->oldY + dInfo->yOrigin) % bgImgHeight) != + ((y + tree->yOrigin) % bgImgHeight))) + dItem->flags |= DITEM_DIRTY | DITEM_ALL_DIRTY; +#endif } /* Make a new DItem */ @@ -1840,6 +1855,15 @@ static DItem *UpdateDInfoForRange(TreeCtrl *tree, DItem *dItemHead, Range *range tree->columnTreeVis && ((dItem->oldY & 1) != (y & 1))) dItem->flags |= DITEM_DIRTY | DITEM_ALL_DIRTY; + +#ifdef BG_IMAGE + /* We can't copy the item to its new position unless it + * has the same part of the background image behind it */ + else if ((tree->backgroundImage != NULL) && + (((dItem->oldX + dInfo->xOrigin) % bgImgWidth) != + ((x + tree->xOrigin) % bgImgWidth))) + dItem->flags |= DITEM_DIRTY | DITEM_ALL_DIRTY; +#endif } /* Make a new DItem */ @@ -2190,9 +2214,23 @@ numCopy++; tree->copyGC, oldX, oldY, width, height, oldX, oldY + offset); +#if 1 + if (offset < 0) + { + dirtyMin = oldY + offset + height; + dirtyMax = oldY + height; + } + else + { + dirtyMin = oldY; + dirtyMax = oldY + offset; + } + Tree_InvalidateArea(tree, oldX, dirtyMin, oldX + width, dirtyMax); +#else dirtyMin = MAX(oldY, oldY + offset + height); dirtyMax = MIN(oldY + height, oldY + offset); Tree_InvalidateArea(tree, oldX, dirtyMin, width, dirtyMax - dirtyMin); +#endif dInfo->dirty[LEFT] = MIN(dInfo->dirty[LEFT], oldX); dInfo->dirty[TOP] = MIN(dInfo->dirty[TOP], oldY + offset); dInfo->dirty[RIGHT] = MAX(dInfo->dirty[RIGHT], oldX + width); @@ -2527,11 +2565,26 @@ numCopy++; if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) { + int dirtyMin, dirtyMax; XCopyArea(tree->display, dInfo->pixmap, dInfo->pixmap, tree->copyGC, oldX, oldY, width, height, oldX + offset, oldY); +#if 1 + if (offset < 0) + { + dirtyMin = oldX + offset + width; + dirtyMax = oldX + width; + } + else + { + dirtyMin = oldX; + dirtyMax = oldX + offset; + } + Tree_InvalidateArea(tree, dirtyMin, oldY, dirtyMax, oldY + height); +#else Tree_InvalidateArea(tree, oldX, oldY, width, height); +#endif dInfo->dirty[LEFT] = MIN(dInfo->dirty[LEFT], oldX + offset); dInfo->dirty[TOP] = MIN(dInfo->dirty[TOP], oldY); dInfo->dirty[RIGHT] = MAX(dInfo->dirty[RIGHT], oldX + offset + width); @@ -2558,13 +2611,17 @@ void TreeColumnProxy_Draw(TreeCtrl *tree) unsigned long gcMask; GC gc; +#if defined(TARGET_OS_MAC) + gcValues.function = GXxor; +#else gcValues.function = GXinvert; +#endif gcValues.graphics_exposures = False; gcMask = GCFunction | GCGraphicsExposures; gc = Tk_GetGC(tree->tkwin, gcMask, &gcValues); /* GXinvert doesn't work with XFillRectangle() on Win32 */ -#ifdef WIN32 +#if defined(WIN32) || defined(TARGET_OS_MAC) XDrawLine(tree->display, Tk_WindowId(tree->tkwin), gc, tree->columnProxy.sx, tree->inset, @@ -2688,6 +2745,64 @@ static TkRegion CalcWhiteSpaceRegion(TreeCtrl *tree) return wsRgn; } +#ifdef BG_IMAGE +/* + *---------------------------------------------------------------------- + * + * Tree_DrawTiledImage -- + * + * This procedure draws a tiled image in the indicated box. + * The image is offset to start at the upper left corner of the actual + * items drawing area. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void Tree_DrawTiledImage(TreeCtrl *tree, Drawable drawable, Tk_Image image, + int x1, int y1, int x2, int y2) +{ + int imgWidth, imgHeight; + int srcX, srcY; + int srcW, srcH; + int dstX, dstY; + + Tk_SizeOfImage(image, &imgWidth, &imgHeight); + + srcX = (x1 + tree->drawableXOrigin) % imgWidth; + dstX = x1; + while (dstX < x2) + { + srcW = imgWidth - srcX; + if (dstX + srcW > x2) { + srcW = x2 - dstX; + } + + srcY = (y1 + tree->drawableYOrigin) % imgHeight; + dstY = y1; + while (dstY < y2) + { + srcH = imgHeight - srcY; + if (dstY + srcH > y2) { + srcH = y2 - dstY; + } + Tk_RedrawImage(image, srcX, srcY, srcW, srcH, drawable, dstX, dstY); + srcY = 0; + dstY += srcH; + } + srcX = 0; + + /* the last tile gives dstX = x2 which ends the while loop; same for y above */ + dstX += srcW; + }; +} +#endif + void Tree_Display(ClientData clientData) { TreeCtrl *tree = (TreeCtrl *) clientData; @@ -2703,7 +2818,7 @@ void Tree_Display(ClientData clientData) XRectangle wsBox; if (tree->debug.enable && tree->debug.display && 0) - dbwin("Tree_Display %s\n", Tk_PathName(tree->tkwin)); + dbwin("Tree_Display %s\n", Tk_PathName(tkwin)); if (tree->deleted) { @@ -2820,9 +2935,9 @@ if (tree->debug.enable && tree->debug.display && 0) } minX = tree->inset; - maxX = Tk_Width(tree->tkwin) - tree->inset; + maxX = Tk_Width(tkwin) - tree->inset; minY = tree->inset + Tree_HeaderHeight(tree); - maxY = Tk_Height(tree->tkwin) - tree->inset; + maxY = Tk_Height(tkwin) - tree->inset; if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) drawable = dInfo->pixmap; @@ -2877,12 +2992,83 @@ if (tree->debug.enable && tree->debug.display && 0) } } +#ifdef BG_IMAGE + if (tree->backgroundImage != NULL) + { + wsRgnNew = CalcWhiteSpaceRegion(tree); + + /* If we scrolled, redraw entire whitespace area */ + if (dInfo->xOrigin != tree->xOrigin || + dInfo->yOrigin != tree->yOrigin) + { + wsRgnDif = wsRgnNew; + } + else + { + wsRgnDif = TkCreateRegion(); + TkSubtractRegion(wsRgnNew, dInfo->wsRgn, wsRgnDif); + } + TkClipBox(wsRgnDif, &wsBox); + if ((wsBox.width > 0) && (wsBox.height > 0)) + { + Drawable pixmap = Tk_GetPixmap(tree->display, Tk_WindowId(tkwin), + wsBox.width, wsBox.height, Tk_Depth(tkwin)); + GC gc = Tk_3DBorderGC(tkwin, tree->border, TK_3D_FLAT_GC); + +if (tree->debug.enable && tree->debug.display && tree->debug.eraseColor) +{ + Tk_FillRegion(tree->display, Tk_WindowId(tkwin), + tree->debug.gcErase, wsRgnDif); + DisplayDelay(tree); +} + + /* FIXME: only if backgroundImage is transparent */ + Tk_OffsetRegion(wsRgnDif, -wsBox.x, -wsBox.y); + Tk_FillRegion(tree->display, pixmap, gc, wsRgnDif); + Tk_OffsetRegion(wsRgnDif, wsBox.x, wsBox.y); + + tree->drawableXOrigin = tree->xOrigin + wsBox.x; + tree->drawableYOrigin = tree->yOrigin + wsBox.y; + + Tree_DrawTiledImage(tree, pixmap, tree->backgroundImage, + 0, 0, wsBox.width, wsBox.height); + + TkSetRegion(tree->display, tree->copyGC, wsRgnNew); +/* XSetClipOrigin(tree->display, tree->copyGC, 0, + 0);*/ + XCopyArea(tree->display, pixmap, drawable, tree->copyGC, + 0, 0, wsBox.width, wsBox.height, + wsBox.x, wsBox.y); + XSetClipMask(tree->display, tree->copyGC, None); +/* XSetClipOrigin(tree->display, tree->copyGC, 0, 0);*/ + + Tk_FreePixmap(tree->display, pixmap); + + if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) + { + dInfo->dirty[LEFT] = MIN(dInfo->dirty[LEFT], wsBox.x); + dInfo->dirty[TOP] = MIN(dInfo->dirty[TOP], wsBox.y); + dInfo->dirty[RIGHT] = MAX(dInfo->dirty[RIGHT], wsBox.x + wsBox.width); + dInfo->dirty[BOTTOM] = MAX(dInfo->dirty[BOTTOM], wsBox.y + wsBox.height); + } + } + if (wsRgnDif != wsRgnNew) + TkDestroyRegion(wsRgnDif); + TkDestroyRegion(dInfo->wsRgn); + dInfo->wsRgn = wsRgnNew; + } +#endif + dInfo->xOrigin = tree->xOrigin; dInfo->yOrigin = tree->yOrigin; /* Does this need to be here? */ dInfo->flags &= ~(DINFO_REDRAW_PENDING); +#ifdef BG_IMAGE + if (tree->backgroundImage == NULL) + { +#endif /* Calculate the current whitespace region, subtract the old whitespace * region, and fill the difference with the background color. */ wsRgnNew = CalcWhiteSpaceRegion(tree); @@ -2891,10 +3077,10 @@ if (tree->debug.enable && tree->debug.display && 0) TkClipBox(wsRgnDif, &wsBox); if ((wsBox.width > 0) && (wsBox.height > 0)) { - GC gc = Tk_3DBorderGC(tree->tkwin, tree->border, TK_3D_FLAT_GC); + GC gc = Tk_3DBorderGC(tkwin, tree->border, TK_3D_FLAT_GC); if (tree->debug.enable && tree->debug.display && tree->debug.eraseColor) { - Tk_FillRegion(tree->display, Tk_WindowId(tree->tkwin), + Tk_FillRegion(tree->display, Tk_WindowId(tkwin), tree->debug.gcErase, wsRgnDif); DisplayDelay(tree); } @@ -2910,6 +3096,9 @@ if (tree->debug.enable && tree->debug.display && 0) TkDestroyRegion(wsRgnDif); TkDestroyRegion(dInfo->wsRgn); dInfo->wsRgn = wsRgnNew; +#ifdef BG_IMAGE + } +#endif /* See if there are any dirty items */ count = 0; @@ -3054,19 +3243,24 @@ numDraw++; } if (tree->debug.enable && tree->debug.display) - dbwin("copy %d draw %d %s\n", numCopy, numDraw, Tk_PathName(tree->tkwin)); + dbwin("copy %d draw %d %s\n", numCopy, numDraw, Tk_PathName(tkwin)); if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) { - drawable = Tk_WindowId(tree->tkwin); - XCopyArea(tree->display, dInfo->pixmap, drawable, - tree->copyGC, - dInfo->dirty[LEFT], dInfo->dirty[TOP], - dInfo->dirty[RIGHT] - dInfo->dirty[LEFT], - dInfo->dirty[BOTTOM] - dInfo->dirty[TOP], - dInfo->dirty[LEFT],dInfo-> dirty[TOP]); + drawable = Tk_WindowId(tkwin); + + if (dInfo->dirty[LEFT] < dInfo->dirty[RIGHT]) + { + XCopyArea(tree->display, dInfo->pixmap, drawable, + tree->copyGC, + dInfo->dirty[LEFT], dInfo->dirty[TOP], + dInfo->dirty[RIGHT] - dInfo->dirty[LEFT], + dInfo->dirty[BOTTOM] - dInfo->dirty[TOP], + dInfo->dirty[LEFT], dInfo-> dirty[TOP]); + } } + /* XOR on */ TreeMarquee_Display(tree->marquee); TreeDragImage_Display(tree->dragImage); |