summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authortreectrl <treectrl>2007-04-21 21:34:00 (GMT)
committertreectrl <treectrl>2007-04-21 21:34:00 (GMT)
commit9b77e9e7deb66533f2b70a21659508cb760338f8 (patch)
tree8716bfb0b480091b2998a61dc27c90f798c3b6e4 /generic
parent54e5169747c056eac04265cbb1ec52633ba55f6e (diff)
downloadtktreectrl-9b77e9e7deb66533f2b70a21659508cb760338f8.zip
tktreectrl-9b77e9e7deb66533f2b70a21659508cb760338f8.tar.gz
tktreectrl-9b77e9e7deb66533f2b70a21659508cb760338f8.tar.bz2
Fixed partially-exposed transparent photo images not being redrawn when scrolling under X11. This involved creating a wrapper around Tk_RedrawImage to ensure proper clipping of the source image to the bounds of the destination drawable. A new data type TreeDrawable remembers the height and width of a drawable.
Diffstat (limited to 'generic')
-rw-r--r--generic/tkTreeColumn.c130
-rw-r--r--generic/tkTreeCtrl.h21
-rw-r--r--generic/tkTreeDisplay.c99
-rw-r--r--generic/tkTreeElem.c4
-rw-r--r--generic/tkTreeElem.h3
-rw-r--r--generic/tkTreeItem.c60
-rw-r--r--generic/tkTreeStyle.c8
-rw-r--r--generic/tkTreeUtils.c60
8 files changed, 226 insertions, 159 deletions
diff --git a/generic/tkTreeColumn.c b/generic/tkTreeColumn.c
index 88d0796..e683514 100644
--- a/generic/tkTreeColumn.c
+++ b/generic/tkTreeColumn.c
@@ -7,7 +7,7 @@
* Copyright (c) 2002-2003 Christian Krone
* Copyright (c) 2003 ActiveState Corporation
*
- * RCS: @(#) $Id: tkTreeColumn.c,v 1.77 2007/01/23 22:41:30 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeColumn.c,v 1.78 2007/04/21 21:34:00 treectrl Exp $
*/
#include "tkTreeCtrl.h"
@@ -4324,7 +4324,7 @@ errorExit:
static void
Column_DrawArrow(
TreeColumn column, /* Column record. */
- Drawable drawable, /* Where to draw. */
+ TreeDrawable td, /* Where to draw. */
int x, int y, /* Top-left corner of the column's header. */
struct Layout layout /* Size/position info. */
)
@@ -4344,8 +4344,8 @@ Column_DrawArrow(
image = PerStateImage_ForState(tree, &column->arrowImage, state, NULL);
if (image != NULL) {
- Tk_RedrawImage(image, 0, 0, layout.arrowWidth, layout.arrowHeight,
- drawable,
+ Tree_RedrawImage(image, 0, 0, layout.arrowWidth, layout.arrowHeight,
+ td,
x + layout.arrowLeft + sunken,
y + (height - (layout.arrowHeight + arrowPadY)) / 2 + sunken);
return;
@@ -4356,7 +4356,7 @@ Column_DrawArrow(
int bx, by;
bx = x + layout.arrowLeft + sunken;
by = y + (height - (layout.arrowHeight + arrowPadY)) / 2 + sunken;
- Tree_DrawBitmap(tree, bitmap, drawable, NULL, NULL,
+ Tree_DrawBitmap(tree, bitmap, td.drawable, NULL, NULL,
0, 0,
(unsigned int) layout.arrowWidth, (unsigned int) layout.arrowHeight,
bx, by);
@@ -4364,7 +4364,7 @@ Column_DrawArrow(
}
if (tree->useTheme) {
- if (TreeTheme_DrawHeaderArrow(tree, drawable,
+ if (TreeTheme_DrawHeaderArrow(tree, td.drawable,
column->arrow == ARROW_UP, x + layout.arrowLeft + sunken,
y + (height - (layout.arrowHeight + arrowPadY)) / 2 + sunken,
layout.arrowWidth, layout.arrowHeight) == TCL_OK)
@@ -4415,14 +4415,13 @@ Column_DrawArrow(
points[i].y += sunken;
}
- border = PerStateBorder_ForState(tree, &column->border,
- Column_MakeState(column), NULL);
+ border = PerStateBorder_ForState(tree, &column->border, state, NULL);
if (border == NULL)
border = tree->border;
- XDrawLines(tree->display, drawable,
+ XDrawLines(tree->display, td.drawable,
Tk_3DBorderGC(tree->tkwin, border, color2),
points + 2, 3, CoordModeOrigin);
- XDrawLines(tree->display, drawable,
+ XDrawLines(tree->display, td.drawable,
Tk_3DBorderGC(tree->tkwin, border, color1),
points, 2, CoordModeOrigin);
}
@@ -4447,7 +4446,7 @@ Column_DrawArrow(
static void
Column_Draw(
TreeColumn column, /* Column record. */
- Drawable drawable, /* Where to draw. */
+ TreeDrawable td, /* Where to draw. */
int x, int y, /* Top-left corner of the column's header. */
int dragImage /* TRUE if we are creating a transparent
* drag image for this header. */
@@ -4473,14 +4472,14 @@ Column_Draw(
if (dragImage) {
GC gc = Tk_GCForColor(tree->columnDrag.color, Tk_WindowId(tree->tkwin));
- XFillRectangle(tree->display, drawable, gc, x, y, width, height);
+ XFillRectangle(tree->display, td.drawable, gc, x, y, width, height);
} else {
if (tree->useTheme) {
- theme = TreeTheme_DrawHeaderItem(tree, drawable, column->state,
+ theme = TreeTheme_DrawHeaderItem(tree, td.drawable, column->state,
column->arrow, x, y, width, height);
}
if (theme != TCL_OK)
- Tk_Fill3DRectangle(tree->tkwin, drawable, border,
+ Tk_Fill3DRectangle(tree->tkwin, td.drawable, border,
x, y, width, height, 0, TK_RELIEF_FLAT);
}
@@ -4492,7 +4491,7 @@ Column_Draw(
+ column->imagePadY[PAD_BOTTOM_RIGHT];
iy = y + (height - h) / 2 + sunken;
iy += column->imagePadY[PAD_TOP_LEFT];
- Tk_RedrawImage(column->image, 0, 0, imgW, imgH, drawable, ix, iy);
+ Tree_RedrawImage(column->image, 0, 0, imgW, imgH, td, ix, iy);
} else if (column->bitmap != None) {
int imgW, imgH, bx, by, h;
@@ -4502,7 +4501,7 @@ Column_Draw(
+ column->imagePadY[PAD_BOTTOM_RIGHT];
by = y + (height - h) / 2 + sunken;
by += column->imagePadY[PAD_TOP_LEFT];
- Tree_DrawBitmapWithGC(tree, column->bitmap, drawable, column->bitmapGC,
+ Tree_DrawBitmapWithGC(tree, column->bitmap, td.drawable, column->bitmapGC,
0, 0, (unsigned int) imgW, (unsigned int) imgH,
bx, by);
}
@@ -4519,7 +4518,7 @@ Column_Draw(
gcValues.graphics_exposures = False;
mask = GCFont | GCForeground | GCGraphicsExposures;
gc = Tree_GetGC(tree, mask, &gcValues);
- TextLayout_Draw(tree->display, drawable, gc,
+ TextLayout_Draw(tree->display, td.drawable, gc,
column->textLayout,
x + layout.textLeft + sunken,
y + (height - h) / 2 + column->textPadY[PAD_TOP_LEFT] + sunken,
@@ -4555,7 +4554,7 @@ Column_Draw(
+ column->textPadY[PAD_BOTTOM_RIGHT];
ty = y + (height - h) / 2 + layout.fm.ascent + sunken;
ty += column->textPadY[PAD_TOP_LEFT];
- Tk_DrawChars(tree->display, drawable, gc,
+ Tk_DrawChars(tree->display, td.drawable, gc,
layout.tkfont, text, textLen, tx, ty);
if (text != staticStr)
ckfree(text);
@@ -4568,10 +4567,10 @@ Column_Draw(
/* Under Aqua, we let the Appearance Manager draw the sort arrow */
if (theme != TCL_OK)
#endif
- Column_DrawArrow(column, drawable, x, y, layout);
+ Column_DrawArrow(column, td, x, y, layout);
if (theme != TCL_OK)
- Tk_Draw3DRectangle(tree->tkwin, drawable, border,
+ Tk_Draw3DRectangle(tree->tkwin, td.drawable, border,
x, y, width, height, column->borderWidth, relief);
}
@@ -4603,7 +4602,7 @@ SetImageForColumn(
)
{
Tk_PhotoHandle photoH;
- Pixmap pixmap;
+ TreeDrawable td;
int width = column->useWidth; /* the entire column, not just what is visible */
int height = tree->headerHeight;
XImage *ximage;
@@ -4616,22 +4615,24 @@ SetImageForColumn(
return NULL;
}
- pixmap = Tk_GetPixmap(tree->display, Tk_WindowId(tree->tkwin),
+ td.width = width;
+ td.height = height;
+ td.drawable = Tk_GetPixmap(tree->display, Tk_WindowId(tree->tkwin),
width, height, Tk_Depth(tree->tkwin));
- Column_Draw(column, pixmap, 0, 0, TRUE);
+ Column_Draw(column, td, 0, 0, TRUE);
/* Pixmap -> XImage */
- ximage = XGetImage(tree->display, pixmap, 0, 0,
+ ximage = XGetImage(tree->display, td.drawable, 0, 0,
(unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap);
if (ximage == NULL)
- panic("ximage is NULL");
+ panic("tkTreeColumn.c:SetImageForColumn() ximage is NULL");
/* XImage -> Tk_Image */
Tree_XImage2Photo(tree->interp, photoH, ximage, tree->columnDrag.alpha);
XDestroyImage(ximage);
- Tk_FreePixmap(tree->display, pixmap);
+ Tk_FreePixmap(tree->display, td.drawable);
return Tk_GetImage(tree->interp, tree->tkwin, "::TreeCtrl::ImageColumn",
NULL, (ClientData) NULL);
@@ -4686,65 +4687,69 @@ DrawDragIndicator(
static void
DrawHeaderLeft(
TreeCtrl *tree, /* Widget info. */
- Drawable drawable /* Where to draw. */
+ TreeDrawable td /* Where to draw. */
)
{
TreeColumn column = tree->columnLockLeft;
Tk_Window tkwin = tree->tkwin;
int x = Tree_HeaderLeft(tree), y = Tree_HeaderTop(tree);
- Drawable pixmap;
+ TreeDrawable td2;
- pixmap = Tk_GetPixmap(tree->display, Tk_WindowId(tkwin),
- Tk_Width(tkwin), Tree_HeaderBottom(tree), Tk_Depth(tkwin));
+ td2.width = Tk_Width(tkwin);
+ td2.height = Tree_HeaderBottom(tree);
+ td2.drawable = Tk_GetPixmap(tree->display, Tk_WindowId(tkwin),
+ td2.width, td2.height, Tk_Depth(tkwin));
while (column != NULL && column->lock == COLUMN_LOCK_LEFT) {
if (column->visible) {
- Column_Draw(column, pixmap, x, y, FALSE);
+ Column_Draw(column, td2, x, y, FALSE);
x += column->useWidth;
}
column = column->next;
}
- DrawDragIndicator(tree, pixmap, COLUMN_LOCK_LEFT);
+ DrawDragIndicator(tree, td2.drawable, COLUMN_LOCK_LEFT);
- XCopyArea(tree->display, pixmap, drawable,
+ XCopyArea(tree->display, td2.drawable, td.drawable,
tree->copyGC, Tree_HeaderLeft(tree), y,
x - Tree_HeaderLeft(tree), tree->headerHeight,
Tree_HeaderLeft(tree), y);
- Tk_FreePixmap(tree->display, pixmap);
+ Tk_FreePixmap(tree->display, td2.drawable);
}
static void
DrawHeaderRight(
TreeCtrl *tree, /* Widget info. */
- Drawable drawable /* Where to draw. */
+ TreeDrawable td /* Where to draw. */
)
{
TreeColumn column = tree->columnLockRight;
Tk_Window tkwin = tree->tkwin;
int x = Tree_ContentRight(tree), y = Tree_HeaderTop(tree);
- Drawable pixmap;
+ TreeDrawable td2;
- pixmap = Tk_GetPixmap(tree->display, Tk_WindowId(tkwin),
- Tk_Width(tkwin), Tree_HeaderBottom(tree), Tk_Depth(tkwin));
+ td2.width = Tk_Width(tkwin);
+ td2.height = Tree_HeaderBottom(tree);
+ td2.drawable = Tk_GetPixmap(tree->display, Tk_WindowId(tkwin),
+ td2.width, td2.height, Tk_Depth(tkwin));
while (column != NULL && column->lock == COLUMN_LOCK_RIGHT) {
if (column->visible) {
- Column_Draw(column, pixmap, x, y, FALSE);
+ Column_Draw(column, td2, x, y, FALSE);
x += column->useWidth;
}
column = column->next;
}
- DrawDragIndicator(tree, pixmap, COLUMN_LOCK_RIGHT);
+ DrawDragIndicator(tree, td2.drawable, COLUMN_LOCK_RIGHT);
- XCopyArea(tree->display, pixmap, drawable,
+ XCopyArea(tree->display, td2.drawable, td.drawable,
tree->copyGC, Tree_ContentRight(tree), y,
x - Tree_ContentRight(tree), tree->headerHeight,
Tree_ContentRight(tree), y);
- Tk_FreePixmap(tree->display, pixmap);
+ Tk_FreePixmap(tree->display, td2.drawable);
}
/*
@@ -4766,13 +4771,15 @@ DrawHeaderRight(
void
Tree_DrawHeader(
TreeCtrl *tree, /* Widget info. */
- Drawable drawable, /* Where to draw. */
+ TreeDrawable td, /* Where to draw. */
int x, int y /* Top-left corner of the header. */
)
{
TreeColumn column = tree->columns;
Tk_Window tkwin = tree->tkwin;
int minX, maxX, width, height;
+ Drawable drawable = td.drawable;
+ TreeDrawable tp;
Drawable pixmap;
/* Update layout if needed */
@@ -4782,17 +4789,21 @@ Tree_DrawHeader(
minX = Tree_ContentLeft(tree);
maxX = Tree_ContentRight(tree);
- if (tree->doubleBuffer == DOUBLEBUFFER_ITEM)
- pixmap = Tk_GetPixmap(tree->display, Tk_WindowId(tkwin),
- Tk_Width(tkwin), Tree_HeaderBottom(tree), Tk_Depth(tkwin));
- else
- pixmap = drawable;
+ if (tree->doubleBuffer == DOUBLEBUFFER_ITEM) {
+ tp.width = Tk_Width(tkwin);
+ tp.height = Tree_HeaderBottom(tree);
+ tp.drawable = Tk_GetPixmap(tree->display, Tk_WindowId(tkwin),
+ tp.width, tp.height, Tk_Depth(tkwin));
+ } else {
+ tp = td;
+ }
+ pixmap = tp.drawable;
column = tree->columnLockNone;
while (column != NULL && column->lock == COLUMN_LOCK_NONE) {
if (column->visible) {
if ((x < maxX) && (x + column->useWidth > minX))
- Column_Draw(column, pixmap, x, y, FALSE);
+ Column_Draw(column, tp, x, y, FALSE);
x += column->useWidth;
}
column = column->next;
@@ -4823,9 +4834,9 @@ Tree_DrawHeader(
DrawDragIndicator(tree, pixmap, COLUMN_LOCK_NONE);
if (Tree_WidthOfLeftColumns(tree) > 0)
- DrawHeaderLeft(tree, pixmap);
+ DrawHeaderLeft(tree, tp);
if (Tree_WidthOfRightColumns(tree) > 0)
- DrawHeaderRight(tree, pixmap);
+ DrawHeaderRight(tree, tp);
if (tree->columnDrag.column != NULL) {
Tk_Image image;
@@ -4836,22 +4847,7 @@ Tree_DrawHeader(
image = SetImageForColumn(tree, tree->columnDrag.column);
x += tree->columnDrag.offset;
-#if !defined(WIN32) && !defined(MAC_TCL) && !defined(MAC_OSX_TK)
- /*
- * Do boundary clipping, so that Tk_RedrawImage is passed
- * valid coordinates. [Tk Bug 979239]
- */
- if (x < minX) {
- ix = minX - x;
- iw -= ix;
- x = minX;
- w -= ix;
- }
- if (x + w > maxX) {
- iw -= (x + w) - maxX;
- }
-#endif
- Tk_RedrawImage(image, ix, iy, iw, ih, pixmap, x, y);
+ Tree_RedrawImage(image, ix, iy, iw, ih, tp, x, y);
Tk_FreeImage(image);
}
}
diff --git a/generic/tkTreeCtrl.h b/generic/tkTreeCtrl.h
index 7bd1bef..fc4b7a2 100644
--- a/generic/tkTreeCtrl.h
+++ b/generic/tkTreeCtrl.h
@@ -7,7 +7,7 @@
* Copyright (c) 2002-2003 Christian Krone
* Copyright (c) 2003 ActiveState Corporation
*
- * RCS: @(#) $Id: tkTreeCtrl.h,v 1.89 2007/01/31 23:21:44 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeCtrl.h,v 1.90 2007/04/21 21:34:00 treectrl Exp $
*/
#include "tkPort.h"
@@ -92,6 +92,13 @@ struct PerStateType
/*****/
+typedef struct
+{
+ Drawable drawable;
+ int width;
+ int height;
+} TreeDrawable;
+
typedef struct GCCache GCCache;
struct GCCache
{
@@ -537,9 +544,9 @@ extern int TreeItem_TotalHeight(TreeCtrl *tree, TreeItem self);
extern void TreeItem_InvalidateHeight(TreeCtrl *tree, TreeItem self);
extern void TreeItem_SpansInvalidate(TreeCtrl *tree, TreeItem item_);
extern int *TreeItem_GetSpans(TreeCtrl *tree, TreeItem item_);
-extern void TreeItem_Draw(TreeCtrl *tree, TreeItem self, int lock, int x, int y, int width, int height, Drawable drawable, int minX, int maxX, int index);
-extern void TreeItem_DrawLines(TreeCtrl *tree, TreeItem self, int x, int y, int width, int height, Drawable drawable);
-extern void TreeItem_DrawButton(TreeCtrl *tree, TreeItem self, int x, int y, int width, int height, Drawable drawable);
+extern void TreeItem_Draw(TreeCtrl *tree, TreeItem self, int lock, int x, int y, int width, int height, TreeDrawable td, int minX, int maxX, int index);
+extern void TreeItem_DrawLines(TreeCtrl *tree, TreeItem self, int x, int y, int width, int height, TreeDrawable td);
+extern void TreeItem_DrawButton(TreeCtrl *tree, TreeItem self, int x, int y, int width, int height, TreeDrawable td);
extern int TreeItem_ReallyVisible(TreeCtrl *tree, TreeItem self);
extern void TreeItem_FreeResources(TreeCtrl *tree, TreeItem self);
extern void TreeItem_Release(TreeCtrl *tree, TreeItem item);
@@ -592,7 +599,7 @@ struct StyleDrawArgs
int y;
int width;
int height;
- Drawable drawable;
+ TreeDrawable td;
int state; /* STATE_xxx */
Tk_Justify justify;
int bounds[4];
@@ -714,7 +721,7 @@ extern int TreeColumn_Visible(TreeColumn column_);
extern int TreeColumn_Squeeze(TreeColumn column_);
extern int TreeColumn_BackgroundCount(TreeColumn column_);
extern GC TreeColumn_BackgroundGC(TreeColumn column_, int which);
-extern void Tree_DrawHeader(TreeCtrl *tree, Drawable drawable, int x, int y);
+extern void Tree_DrawHeader(TreeCtrl *tree, TreeDrawable td, int x, int y);
extern int TreeColumn_WidthOfItems(TreeColumn column_);
extern void TreeColumn_InvalidateWidth(TreeColumn column_);
extern void TreeColumn_Init(TreeCtrl *tree);
@@ -882,6 +889,8 @@ extern void TextLayout_Draw(Display *display, Drawable drawable, GC gc,
extern void DrawXORLine(Display *display, Drawable drawable, int x1, int y1,
int x2, int y2);
#endif
+extern void Tree_RedrawImage(Tk_Image image, int imageX, int imageY,
+ int width, int height, TreeDrawable td, int drawableX, int drawableY);
extern void Tree_DrawBitmapWithGC(TreeCtrl *tree, Pixmap bitmap, Drawable drawable,
GC gc, int src_x, int src_y, int width, int height, int dest_x, int dest_y);
extern void Tree_DrawBitmap(TreeCtrl *tree, Pixmap bitmap, Drawable drawable,
diff --git a/generic/tkTreeDisplay.c b/generic/tkTreeDisplay.c
index 02af68c..0d4f460 100644
--- a/generic/tkTreeDisplay.c
+++ b/generic/tkTreeDisplay.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 2002-2006 Tim Baker
*
- * RCS: @(#) $Id: tkTreeDisplay.c,v 1.83 2007/01/31 23:23:49 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeDisplay.c,v 1.84 2007/04/21 21:34:00 treectrl Exp $
*/
#include "tkTreeCtrl.h"
@@ -90,13 +90,6 @@ struct TreeColumnDInfo_
int width; /* Last seen column width */
};
-struct DPixmap
-{
- Pixmap pixmap;
- int width;
- int height;
-};
-
/* Display information for a TreeCtrl. */
struct TreeDInfo_
{
@@ -117,8 +110,8 @@ struct TreeDInfo_
int rItemMax; /* size of rItem[] */
int itemHeight; /* Observed max TreeItem height */
int itemWidth; /* Observed max TreeItem width */
- struct DPixmap pixmapW; /* Pixmap as big as the window */
- struct DPixmap pixmapI; /* Pixmap as big as the largest item */
+ TreeDrawable pixmapW; /* Pixmap as big as the window */
+ TreeDrawable pixmapI; /* Pixmap as big as the largest item */
TkRegion dirtyRgn; /* DOUBLEBUFFER_WINDOW */
int flags; /* DINFO_XXX */
int xScrollIncrement; /* Last seen TreeCtr.xScrollIncrement */
@@ -3846,8 +3839,8 @@ ScrollVerticalComplex(
if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) {
int dirtyMin, dirtyMax;
- XCopyArea(tree->display, dInfo->pixmapW.pixmap,
- dInfo->pixmapW.pixmap, tree->copyGC,
+ XCopyArea(tree->display, dInfo->pixmapW.drawable,
+ dInfo->pixmapW.drawable, tree->copyGC,
oldX, oldY, width, height,
oldX, oldY + offset);
if (offset < 0) {
@@ -3964,7 +3957,8 @@ ScrollHorizontalSimple(
damageRgn = Tree_GetRegion(tree);
if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) {
- XCopyArea(tree->display, dInfo->pixmapW.pixmap, dInfo->pixmapW.pixmap,
+ XCopyArea(tree->display, dInfo->pixmapW.drawable,
+ dInfo->pixmapW.drawable,
tree->copyGC,
x, minY, width, maxY - minY,
x + offset, minY);
@@ -4062,8 +4056,8 @@ ScrollVerticalSimple(
damageRgn = Tree_GetRegion(tree);
if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) {
- XCopyArea(tree->display, dInfo->pixmapW.pixmap, dInfo->pixmapW.pixmap,
- tree->copyGC,
+ XCopyArea(tree->display, dInfo->pixmapW.drawable,
+ dInfo->pixmapW.drawable, tree->copyGC,
minX, y, maxX - minX, height,
minX, y + offset);
Tree_InvalidateArea(tree, minX, dirtyMin, maxX, dirtyMax);
@@ -4209,8 +4203,8 @@ ScrollHorizontalComplex(
if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) {
int dirtyMin, dirtyMax;
- XCopyArea(tree->display, dInfo->pixmapW.pixmap,
- dInfo->pixmapW.pixmap, tree->copyGC,
+ XCopyArea(tree->display, dInfo->pixmapW.drawable,
+ dInfo->pixmapW.drawable, tree->copyGC,
oldX, oldY, width, height,
oldX + offset, oldY);
if (offset < 0) {
@@ -5077,8 +5071,8 @@ DisplayDItem(
DItemArea *area,
int lock, /* Which set of columns. */
int bounds[4], /* TREE_AREA_xxx bounds of drawing. */
- Drawable pixmap, /* Where to draw. */
- Drawable drawable /* Where to copy to. */
+ TreeDrawable pixmap, /* Where to draw. */
+ TreeDrawable drawable /* Where to copy to. */
)
{
Tk_Window tkwin = tree->tkwin;
@@ -5133,7 +5127,7 @@ DisplayDItem(
pixmap,
0, right - left,
dItem->index);
- XCopyArea(tree->display, pixmap, drawable,
+ XCopyArea(tree->display, pixmap.drawable, drawable.drawable,
tree->copyGC,
0, 0,
right - left, bottom - top,
@@ -5265,27 +5259,27 @@ TreeDisplay_WasThereTrouble(
static Pixmap
DisplayGetPixmap(
TreeCtrl *tree,
- struct DPixmap *dPixmap,
+ TreeDrawable *dPixmap,
int width,
int height
)
{
Tk_Window tkwin = tree->tkwin;
- if (dPixmap->pixmap == None) {
- dPixmap->pixmap = Tk_GetPixmap(tree->display,
+ if (dPixmap->drawable == None) {
+ dPixmap->drawable = Tk_GetPixmap(tree->display,
Tk_WindowId(tkwin), width, height, Tk_Depth(tkwin));
dPixmap->width = width;
dPixmap->height = height;
} else if ((dPixmap->width < width) || (dPixmap->height < height)) {
- Tk_FreePixmap(tree->display, dPixmap->pixmap);
- dPixmap->pixmap = Tk_GetPixmap(tree->display,
+ Tk_FreePixmap(tree->display, dPixmap->drawable);
+ dPixmap->drawable = Tk_GetPixmap(tree->display,
Tk_WindowId(tkwin), width, height, Tk_Depth(tkwin));
dPixmap->width = width;
dPixmap->height = height;
}
- return dPixmap->pixmap;
+ return dPixmap->drawable;
}
/*
@@ -5315,8 +5309,9 @@ Tree_Display(
TreeDInfo dInfo = tree->dInfo;
DItem *dItem;
Tk_Window tkwin = tree->tkwin;
- Drawable drawable = Tk_WindowId(tkwin);
- int minX, minY, maxX, maxY, height, width;
+ Drawable drawable;
+ TreeDrawable tdrawable;
+ int minX, minY, maxX, maxY;
int count;
int numCopy = 0, numDraw = 0;
TkRegion wsRgnNew, wsRgnDif;
@@ -5595,10 +5590,15 @@ displayRetry:
goto displayRetry;
}
+ tdrawable.width = Tk_Width(tkwin);
+ tdrawable.height = Tk_Height(tkwin);
if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) {
- drawable = DisplayGetPixmap(tree, &dInfo->pixmapW,
- Tk_Width(tkwin), Tk_Height(tkwin));
+ tdrawable.drawable = DisplayGetPixmap(tree, &dInfo->pixmapW,
+ tdrawable.width, tdrawable.height);
+ } else {
+ tdrawable.drawable = Tk_WindowId(tkwin);
}
+ drawable = tdrawable.drawable;
/* XOR off */
TreeColumnProxy_Undisplay(tree);
@@ -5613,7 +5613,7 @@ displayRetry:
tree->debug.gcDraw, minX, minY, maxX - minX, maxY - minY);
DisplayDelay(tree);
}
- Tree_DrawHeader(tree, drawable, 0 - tree->xOrigin, Tree_HeaderTop(tree));
+ Tree_DrawHeader(tree, tdrawable, 0 - tree->xOrigin, Tree_HeaderTop(tree));
if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) {
DblBufWinDirty(tree, minX, minY, maxX, maxY);
}
@@ -5761,13 +5761,14 @@ displayRetry:
/* Display dirty items */
if (count > 0) {
- Drawable pixmap = drawable;
+ TreeDrawable tpixmap = tdrawable;
if (tree->doubleBuffer != DOUBLEBUFFER_NONE) {
/* Allocate pixmap for largest item */
- width = MIN(Tk_Width(tkwin), dInfo->itemWidth);
- height = MIN(Tk_Height(tkwin), dInfo->itemHeight);
- pixmap = DisplayGetPixmap(tree, &dInfo->pixmapI, width, height);
+ tpixmap.width = MIN(Tk_Width(tkwin), dInfo->itemWidth);
+ tpixmap.height = MIN(Tk_Height(tkwin), dInfo->itemHeight);
+ tpixmap.drawable = DisplayGetPixmap(tree, &dInfo->pixmapI,
+ tpixmap.width, tpixmap.height);
}
for (dItem = dInfo->dItem;
@@ -5787,7 +5788,7 @@ displayRetry:
}
if (dItem->area.flags & DITEM_DIRTY) {
drawn += DisplayDItem(tree, dItem, &dItem->area,
- COLUMN_LOCK_NONE, dInfo->bounds, pixmap, drawable);
+ COLUMN_LOCK_NONE, dInfo->bounds, tpixmap, tdrawable);
}
}
if (!dInfo->emptyL) {
@@ -5803,7 +5804,7 @@ displayRetry:
}
if (dItem->left.flags & DITEM_DIRTY) {
drawn += DisplayDItem(tree, dItem, &dItem->left, COLUMN_LOCK_LEFT,
- dInfo->boundsL, pixmap, drawable);
+ dInfo->boundsL, tpixmap, tdrawable);
}
}
if (!dInfo->emptyR) {
@@ -5819,7 +5820,7 @@ displayRetry:
}
if (dItem->right.flags & DITEM_DIRTY) {
drawn += DisplayDItem(tree, dItem, &dItem->right, COLUMN_LOCK_RIGHT,
- dInfo->boundsR, pixmap, drawable);
+ dInfo->boundsR, tpixmap, tdrawable);
}
}
numDraw += drawn ? 1 : 0;
@@ -5841,7 +5842,7 @@ displayRetry:
TkClipBox(dInfo->dirtyRgn, &box);
if (box.width > 0 && box.height > 0) {
TkSetRegion(tree->display, tree->copyGC, dInfo->dirtyRgn);
- XCopyArea(tree->display, dInfo->pixmapW.pixmap, drawable,
+ XCopyArea(tree->display, dInfo->pixmapW.drawable, drawable,
tree->copyGC,
box.x, box.y,
box.width, box.height,
@@ -6518,15 +6519,15 @@ Tree_RelayoutWindow(
dInfo->flags |= DINFO_DRAW_WHITESPACE;
if (tree->doubleBuffer != DOUBLEBUFFER_WINDOW) {
- if (dInfo->pixmapW.pixmap != None) {
- Tk_FreePixmap(tree->display, dInfo->pixmapW.pixmap);
- dInfo->pixmapW.pixmap = None;
+ if (dInfo->pixmapW.drawable != None) {
+ Tk_FreePixmap(tree->display, dInfo->pixmapW.drawable);
+ dInfo->pixmapW.drawable = None;
}
}
if (tree->doubleBuffer == DOUBLEBUFFER_NONE) {
- if (dInfo->pixmapI.pixmap != None) {
- Tk_FreePixmap(tree->display, dInfo->pixmapI.pixmap);
- dInfo->pixmapI.pixmap = None;
+ if (dInfo->pixmapI.drawable != None) {
+ Tk_FreePixmap(tree->display, dInfo->pixmapI.drawable);
+ dInfo->pixmapI.drawable = None;
}
}
@@ -7361,10 +7362,10 @@ TreeDInfo_Free(
Tk_FreeGC(tree->display, dInfo->scrollGC);
if (dInfo->flags & DINFO_REDRAW_PENDING)
Tcl_CancelIdleCall(Tree_Display, (ClientData) tree);
- if (dInfo->pixmapW.pixmap != None)
- Tk_FreePixmap(tree->display, dInfo->pixmapW.pixmap);
- if (dInfo->pixmapI.pixmap != None)
- Tk_FreePixmap(tree->display, dInfo->pixmapI.pixmap);
+ if (dInfo->pixmapW.drawable != None)
+ Tk_FreePixmap(tree->display, dInfo->pixmapW.drawable);
+ if (dInfo->pixmapI.drawable != None)
+ Tk_FreePixmap(tree->display, dInfo->pixmapI.drawable);
if (dInfo->xScrollIncrements != NULL)
ckfree((char *) dInfo->xScrollIncrements);
if (dInfo->yScrollIncrements != NULL)
diff --git a/generic/tkTreeElem.c b/generic/tkTreeElem.c
index 8289bfe..1fc39fa 100644
--- a/generic/tkTreeElem.c
+++ b/generic/tkTreeElem.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 2002-2006 Tim Baker
*
- * RCS: @(#) $Id: tkTreeElem.c,v 1.64 2007/01/31 00:52:01 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeElem.c,v 1.65 2007/04/21 21:34:00 treectrl Exp $
*/
#include "tkTreeCtrl.h"
@@ -1743,7 +1743,7 @@ static void DisplayProcImage(TreeElementArgs *args)
imgW = args->display.width;
if (imgH > args->display.height)
imgH = args->display.height;
- Tk_RedrawImage(image, 0, 0, imgW, imgH, args->display.drawable, x, y);
+ Tree_RedrawImage(image, 0, 0, imgW, imgH, args->display.td, x, y);
}
static void NeededProcImage(TreeElementArgs *args)
diff --git a/generic/tkTreeElem.h b/generic/tkTreeElem.h
index d17f3f4..e0ab803 100644
--- a/generic/tkTreeElem.h
+++ b/generic/tkTreeElem.h
@@ -5,7 +5,7 @@
*
* Copyright (c) 2002-2006 Tim Baker
*
- * RCS: @(#) $Id: tkTreeElem.h,v 1.26 2007/01/31 00:51:07 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeElem.h,v 1.27 2007/04/21 21:34:01 treectrl Exp $
*/
typedef struct TreeElementType TreeElementType;
@@ -41,6 +41,7 @@ struct TreeElementArgs
#define STICKY_E 0x4000
#define STICKY_S 0x8000
int sticky;
+ TreeDrawable td;
Drawable drawable;
int bounds[4];
} display;
diff --git a/generic/tkTreeItem.c b/generic/tkTreeItem.c
index 7ee38c3..a989e89 100644
--- a/generic/tkTreeItem.c
+++ b/generic/tkTreeItem.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 2002-2006 Tim Baker
*
- * RCS: @(#) $Id: tkTreeItem.c,v 1.100 2007/01/23 22:41:31 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeItem.c,v 1.101 2007/04/21 21:34:01 treectrl Exp $
*/
#include "tkTreeCtrl.h"
@@ -3590,7 +3590,7 @@ ItemDrawBackground(
TreeColumn treeColumn, /* Tree-column token. */
TreeItem item, /* Item record. */
Column *column, /* First column. */
- Drawable drawable, /* Where to draw. */
+ TreeDrawable drawable, /* Where to draw. */
int x, int y, /* Area of the item to draw. */
int width, int height, /* ^ */
int index /* Used to select a color from the
@@ -3606,9 +3606,9 @@ ItemDrawBackground(
* FIXME: If the background image is non-transparent, there is no
* need to erase first.
*/
- XFillRectangle(tree->display, drawable, gc, x, y, width, height);
+ XFillRectangle(tree->display, drawable.drawable, gc, x, y, width, height);
if (tree->backgroundImage != NULL) {
- Tree_DrawTiledImage(tree, drawable, tree->backgroundImage, x, y,
+ Tree_DrawTiledImage(tree, drawable.drawable, tree->backgroundImage, x, y,
x + width, y + height,
tree->drawableXOrigin, tree->drawableYOrigin);
}
@@ -3949,7 +3949,7 @@ TreeItem_WalkSpans(
spanCount = Item_GetSpans(tree, item, treeColumn, spans);
drawArgs.tree = tree;
- drawArgs.drawable = None;
+ drawArgs.td.drawable = None;
totalWidth = 0;
for (spanIndex = 0; spanIndex < spanCount; spanIndex++) {
@@ -4023,7 +4023,7 @@ SpanWalkProc_Draw(
Column *itemColumn = (Column *) spanPtr->itemColumn;
int i, x;
struct {
- Drawable drawable;
+ TreeDrawable td;
int minX;
int maxX;
int index;
@@ -4034,14 +4034,14 @@ SpanWalkProc_Draw(
(drawArgs->x + drawArgs->width <= data->minX))
return 0;
- drawArgs->drawable = data->drawable;
+ drawArgs->td = data->td;
/* Draw background colors. */
if (spanPtr->span == 1) {
/* Important point: use drawArgs->width since an item's width may
* be totally different than tree->columnVis' width. */
ItemDrawBackground(tree, treeColumn, item, itemColumn,
- drawArgs->drawable, drawArgs->x, drawArgs->y,
+ drawArgs->td, drawArgs->x, drawArgs->y,
drawArgs->width, drawArgs->height, data->index);
} else {
x = drawArgs->x;
@@ -4050,7 +4050,7 @@ SpanWalkProc_Draw(
if ((columnWidth > 0) && (x < data->maxX) &&
(x + columnWidth > data->minX)) {
ItemDrawBackground(tree, treeColumn, item, itemColumn,
- drawArgs->drawable, x, drawArgs->y,
+ drawArgs->td, x, drawArgs->y,
columnWidth, drawArgs->height, data->index);
}
x += columnWidth;
@@ -4066,10 +4066,10 @@ SpanWalkProc_Draw(
if (spanPtr->treeColumn == tree->columnTree) {
if (tree->showLines)
TreeItem_DrawLines(tree, item, drawArgs->x, drawArgs->y,
- drawArgs->width, drawArgs->height, data->drawable);
+ drawArgs->width, drawArgs->height, data->td);
if (tree->showButtons)
TreeItem_DrawButton(tree, item, drawArgs->x, drawArgs->y,
- drawArgs->width, drawArgs->height, data->drawable);
+ drawArgs->width, drawArgs->height, data->td);
}
/* Stop walking if we went past the right edge of the dirty area. */
@@ -4099,20 +4099,20 @@ TreeItem_Draw(
int lock, /* Which columns. */
int x, int y, /* Drawable coordinates of the item. */
int width, int height, /* Total size of the item. */
- Drawable drawable, /* Where to draw. */
+ TreeDrawable td, /* Where to draw. */
int minX, int maxX, /* Left/right edge that needs to be drawn. */
int index /* Used to select a color from a
* tree-column's -itembackground option. */
)
{
struct {
- Drawable drawable;
+ TreeDrawable td;
int minX;
int maxX;
int index;
} clientData;
- clientData.drawable = drawable;
+ clientData.td = td;
clientData.minX = minX;
clientData.maxX = maxX;
clientData.index = index;
@@ -4145,7 +4145,7 @@ TreeItem_DrawLines(
TreeItem item, /* Item token. */
int x, int y, /* Drawable coordinates of columnTree. */
int width, int height, /* Total size of columnTree. */
- Drawable drawable /* Where to draw. */
+ TreeDrawable td /* Where to draw. */
)
{
TreeItem parent, walk;
@@ -4198,12 +4198,12 @@ TreeItem_DrawLines(
if (tree->lineStyle == LINE_STYLE_DOT) {
for (i = 0; i < tree->lineThickness; i++)
- Tree_VDotLine(tree, drawable, tree->lineGC,
+ Tree_VDotLine(tree, td.drawable, tree->lineGC,
lineLeft + i,
top,
bottom);
} else
- XFillRectangle(tree->display, drawable, tree->lineGC,
+ XFillRectangle(tree->display, td.drawable, tree->lineGC,
lineLeft,
top,
tree->lineThickness,
@@ -4217,12 +4217,12 @@ TreeItem_DrawLines(
if (hasPrev || hasNext) {
if (tree->lineStyle == LINE_STYLE_DOT) {
for (i = 0; i < tree->lineThickness; i++)
- Tree_HDotLine(tree, drawable, tree->lineGC,
+ Tree_HDotLine(tree, td.drawable, tree->lineGC,
lineLeft + vert,
lineTop + i,
x /* + tree->columnTreeLeft */ + indent);
} else
- XFillRectangle(tree->display, drawable, tree->lineGC,
+ XFillRectangle(tree->display, td.drawable, tree->lineGC,
lineLeft + vert,
lineTop,
left + tree->useIndent - (lineLeft + vert),
@@ -4247,12 +4247,12 @@ TreeItem_DrawLines(
if (item != NULL) {
if (tree->lineStyle == LINE_STYLE_DOT) {
for (i = 0; i < tree->lineThickness; i++)
- Tree_VDotLine(tree, drawable, tree->lineGC,
+ Tree_VDotLine(tree, td.drawable, tree->lineGC,
lineLeft + i,
y,
y + height);
} else
- XFillRectangle(tree->display, drawable, tree->lineGC,
+ XFillRectangle(tree->display, td.drawable, tree->lineGC,
lineLeft,
y,
tree->lineThickness,
@@ -4283,7 +4283,7 @@ TreeItem_DrawButton(
TreeItem item, /* Item token. */
int x, int y, /* Drawable coordinates of columnTree. */
int width, int height, /* Total size of columnTree. */
- Drawable drawable /* Where to draw. */
+ TreeDrawable td /* Where to draw. */
)
{
int indent, left, lineLeft, lineTop;
@@ -4309,7 +4309,7 @@ TreeItem_DrawButton(
if (image != NULL) {
int imgW, imgH;
Tk_SizeOfImage(image, &imgW, &imgH);
- Tk_RedrawImage(image, 0, 0, imgW, imgH, drawable,
+ Tree_RedrawImage(image, 0, 0, imgW, imgH, td,
left + (tree->useIndent - imgW) / 2,
y + (height - imgH) / 2);
return;
@@ -4322,7 +4322,7 @@ TreeItem_DrawButton(
Tk_SizeOfBitmap(tree->display, bitmap, &bmpW, &bmpH);
bx = left + (tree->useIndent - bmpW) / 2;
by = y + (height - bmpH) / 2;
- Tree_DrawBitmap(tree, bitmap, drawable, NULL, NULL,
+ Tree_DrawBitmap(tree, bitmap, td.drawable, NULL, NULL,
0, 0, (unsigned int) bmpW, (unsigned int) bmpH,
bx, by);
return;
@@ -4330,9 +4330,9 @@ TreeItem_DrawButton(
if (tree->useTheme) {
int bw, bh;
- if (TreeTheme_GetButtonSize(tree, drawable, item->state & STATE_OPEN,
+ if (TreeTheme_GetButtonSize(tree, td.drawable, item->state & STATE_OPEN,
&bw, &bh) == TCL_OK) {
- if (TreeTheme_DrawButton(tree, drawable, item->state & STATE_OPEN,
+ if (TreeTheme_DrawButton(tree, td.drawable, item->state & STATE_OPEN,
left + (tree->useIndent - bw) / 2, y + (height - bh) / 2,
bw, bh) == TCL_OK) {
return;
@@ -4354,7 +4354,7 @@ TreeItem_DrawButton(
buttonTop = y + (height - tree->buttonSize) / 2;
/* Erase button background */
- XFillRectangle(tree->display, drawable,
+ XFillRectangle(tree->display, td.drawable,
Tk_3DBorderGC(tree->tkwin, tree->border, TK_3D_FLAT_GC),
buttonLeft + tree->buttonThickness,
buttonTop + tree->buttonThickness,
@@ -4362,14 +4362,14 @@ TreeItem_DrawButton(
tree->buttonSize - tree->buttonThickness);
/* Draw button outline */
- XDrawRectangle(tree->display, drawable, tree->buttonGC,
+ XDrawRectangle(tree->display, td.drawable, tree->buttonGC,
buttonLeft + w1,
buttonTop + w1,
tree->buttonSize - tree->buttonThickness + macoffset,
tree->buttonSize - tree->buttonThickness + macoffset);
/* Horizontal '-' */
- XFillRectangle(tree->display, drawable, tree->buttonGC,
+ XFillRectangle(tree->display, td.drawable, tree->buttonGC,
buttonLeft + tree->buttonThickness * 2,
lineTop,
tree->buttonSize - tree->buttonThickness * 4,
@@ -4377,7 +4377,7 @@ TreeItem_DrawButton(
if (!(item->state & STATE_OPEN)) {
/* Finish '+' */
- XFillRectangle(tree->display, drawable, tree->buttonGC,
+ XFillRectangle(tree->display, td.drawable, tree->buttonGC,
lineLeft,
buttonTop + tree->buttonThickness * 2,
tree->buttonThickness,
diff --git a/generic/tkTreeStyle.c b/generic/tkTreeStyle.c
index 851420f..a983d08 100644
--- a/generic/tkTreeStyle.c
+++ b/generic/tkTreeStyle.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 2002-2006 Tim Baker
*
- * RCS: @(#) $Id: tkTreeStyle.c,v 1.74 2007/01/31 00:52:17 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeStyle.c,v 1.75 2007/04/21 21:34:01 treectrl Exp $
*/
#include "tkTreeCtrl.h"
@@ -2347,7 +2347,8 @@ void TreeStyle_Draw(
args.tree = tree;
args.state = drawArgs->state;
- args.display.drawable = drawArgs->drawable;
+ args.display.td = drawArgs->td;
+ args.display.drawable = drawArgs->td.drawable;
for (i = 0; i < masterStyle->numElements; i++) {
struct Layout *layout = &layouts[i];
@@ -2541,7 +2542,8 @@ TreeStyle_UpdateWindowPositions(
args.tree = tree;
args.state = drawArgs->state;
- args.display.drawable = drawArgs->drawable;
+ args.display.td = drawArgs->td;
+ args.display.drawable = drawArgs->td.drawable;
for (i = 0; i < numElements; i++) {
struct Layout *layout = &layouts[i];
diff --git a/generic/tkTreeUtils.c b/generic/tkTreeUtils.c
index 403b39d..2827532 100644
--- a/generic/tkTreeUtils.c
+++ b/generic/tkTreeUtils.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 2002-2006 Tim Baker
*
- * RCS: @(#) $Id: tkTreeUtils.c,v 1.66 2007/03/03 22:16:44 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeUtils.c,v 1.67 2007/04/21 21:34:01 treectrl Exp $
*/
#include "tkTreeCtrl.h"
@@ -1146,6 +1146,64 @@ Tree_UnsetClipMask(
/*
*----------------------------------------------------------------------
*
+ * Tree_RedrawImage --
+ *
+ * Wrapper around Tk_RedrawImage to clip the drawing to the actual
+ * area of the drawable. If you try to draw a transparent photo
+ * image outside the bounds of a drawable, X11 will silently fail
+ * and nothing will be drawn. See tkImgPhoto.c:ImgPhotoDisplay.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Stuff is drawn.
+ *
+ *----------------------------------------------------------------------
+ */
+void Tree_RedrawImage(
+ Tk_Image image,
+ int imageX,
+ int imageY,
+ int width,
+ int height,
+ TreeDrawable td,
+ int drawableX,
+ int drawableY
+ )
+{
+#if 0
+ int ix = imageX, iy = imageY, iw = width, ih = height;
+#endif
+ if (drawableX < 0) {
+ imageX = 0 - drawableX;
+ width -= imageX;
+ drawableX = 0;
+ }
+ if (drawableX + width > td.width) {
+ width -= (drawableX + width) - td.width;
+ }
+ if (drawableY < 0) {
+ imageY = 0 - drawableY;
+ height -= imageY;
+ drawableY = 0;
+ }
+ if (drawableY + height > td.height) {
+ height -= (drawableY + height) - td.height;
+ }
+#if 0
+ if (ix != imageX || iy != imageY || iw != width || ih != height)
+ dbwin("Tree_RedrawImage clipped %d,%d,%d,%d -> %d,%d,%d,%d\n", ix,iy,iw,ih, imageX, imageY, width, height);
+#endif
+ if (width > 0 && height > 0) {
+ Tk_RedrawImage(image, imageX, imageY, width, height, td.drawable,
+ drawableX, drawableY);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* Tree_DrawBitmapWithGC --
*
* Draw part of a bitmap.