Maintain the item position in {,SMALL}ICON mode separataly from the

item, so that we have it even in LVS_OWNERDATA.
This commit is contained in:
Dimitrie O. Paun 2002-10-07 18:50:21 +00:00 committed by Alexandre Julliard
parent 6cfd83b985
commit b9cacc438a
1 changed files with 49 additions and 68 deletions

View File

@ -100,7 +100,6 @@ typedef struct tagLISTVIEW_ITEM
UINT state;
LPARAM lParam;
INT iIndent;
POINT ptPosition;
BOOL valid;
} LISTVIEW_ITEM;
@ -153,8 +152,10 @@ typedef struct tagLISTVIEW_INFO
RECT rcFocus;
DWORD dwStyle; /* the cached window GWL_STYLE */
DWORD dwLvExStyle; /* extended listview style */
HDPA hdpaItems;
UINT nItemCount;
HDPA hdpaItems;
HDPA hdpaPosX; /* maintains the (X, Y) coordinates of the */
HDPA hdpaPosY; /* items in LVS_ICON, and LVS_SMALLICON modes */
PFNLVCOMPARE pfnCompare;
LPARAM lParamSort;
HWND hwndEdit;
@ -1297,11 +1298,8 @@ static BOOL LISTVIEW_GetItemMeasures(LISTVIEW_INFO *infoPtr, INT nItem,
/************************************************************/
if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
{
/* FIXME: what about virtual listview? */
HDPA hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem);
LISTVIEW_ITEM * lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
if (!lpItem) return FALSE;
TopLeft = lpItem->ptPosition;
TopLeft.x = (LONG)DPA_GetPtr(infoPtr->hdpaPosX, nItem);
TopLeft.y = (LONG)DPA_GetPtr(infoPtr->hdpaPosY, nItem);
}
else if (uView == LVS_LIST)
{
@ -1347,6 +1345,7 @@ static BOOL LISTVIEW_GetItemMeasures(LISTVIEW_INFO *infoPtr, INT nItem,
TopLeft.x -= scrollInfo.nPos;
}
}
TRACE("TopLeft=%s\n", debugpoint(&TopLeft));
/************************************************************/
/* compute position point (ala LVM_GETITEMPOSITION) */
@ -3901,6 +3900,8 @@ static LRESULT LISTVIEW_DeleteAllItems(LISTVIEW_INFO *infoPtr)
/* reinitialize listview memory */
bResult = DPA_DeleteAllPtrs(infoPtr->hdpaItems);
infoPtr->nItemCount = 0;
DPA_DeleteAllPtrs(infoPtr->hdpaPosX);
DPA_DeleteAllPtrs(infoPtr->hdpaPosY);
/* align items (set position of each item) */
if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
@ -4105,6 +4106,8 @@ static LRESULT LISTVIEW_DeleteItem(LISTVIEW_INFO *infoPtr, INT nItem)
}
bResult = DPA_Destroy(hdpaSubItems);
DPA_DeletePtr(infoPtr->hdpaPosX, nItem);
DPA_DeletePtr(infoPtr->hdpaPosY, nItem);
}
LISTVIEW_ShiftIndices(infoPtr,nItem,-1);
@ -6052,11 +6055,7 @@ static LRESULT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem,
infoPtr->nItemCount++;
if (!LISTVIEW_SetItemT(infoPtr, lpLVItem, isW))
{
DPA_DeletePtr(infoPtr->hdpaItems, nItem);
infoPtr->nItemCount--;
goto fail;
}
goto undo;
/* if we're sorted, sort the list, and update the index */
if (is_sorted)
@ -6072,6 +6071,18 @@ static LRESULT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem,
}
}
/* make room for the position, if we are in the right mode */
if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
{
if (DPA_InsertPtr(infoPtr->hdpaPosX, nItem, 0) == -1)
goto undo;
if (DPA_InsertPtr(infoPtr->hdpaPosY, nItem, 0) == -1)
{
DPA_DeletePtr(infoPtr->hdpaPosX, nItem);
goto undo;
}
}
/* Add the subitem list to the items array. Do this last in case we go to
* fail during the above.
*/
@ -6099,6 +6110,9 @@ static LRESULT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem,
TRACE(" <- %d\n", nItem);
return nItem;
undo:
DPA_DeletePtr(infoPtr->hdpaItems, nItem);
infoPtr->nItemCount--;
fail:
DPA_DeletePtr(hdpaSubItems, 0);
DPA_Destroy (hdpaSubItems);
@ -6785,68 +6799,33 @@ static BOOL LISTVIEW_SetItemCount(LISTVIEW_INFO *infoPtr, INT nItems, DWORD dwFl
*/
static BOOL LISTVIEW_SetItemPosition(LISTVIEW_INFO *infoPtr, INT nItem, POINT pt)
{
UINT lStyle = infoPtr->dwStyle;
UINT uView = lStyle & LVS_TYPEMASK;
LISTVIEW_ITEM *lpItem;
HDPA hdpaSubItems;
BOOL bResult = FALSE;
UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
TRACE("(nItem=%d, &pt=%s\n", nItem, debugpoint(&pt));
if (lStyle & LVS_OWNERDATA)
return FALSE;
if (nItem < 0 || nItem >= infoPtr->nItemCount ||
!(uView == LVS_ICON || uView == LVS_SMALLICON)) return FALSE;
if ((nItem >= 0) || (nItem < infoPtr->nItemCount))
{
if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
{
if ( (hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem)) )
{
if ( (lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0)) )
{
POINT orig = lpItem->ptPosition;
bResult = TRUE;
/* This point value seems to be an undocumented feature.
* The best guess is that it means either at the origin,
* or at true beginning of the list. I will assume the origin. */
if ((pt.x == -1) && (pt.y == -1))
LISTVIEW_GetOrigin(infoPtr, &pt);
else if (uView == LVS_ICON)
{
/* This point value seems to be an undocumented feature. The
* best guess is that it means either at the origin, or at
* the true beginning of the list. I will assume the origin.
*/
if (!LISTVIEW_GetOrigin(infoPtr, &pt))
pt.x = pt.y = 0;
if (uView == LVS_ICON)
{
pt.x += (infoPtr->iconSpacing.cx - infoPtr->iconSize.cx) / 2;
pt.y += ICON_TOP_PADDING;
}
TRACE("requested special (-1,-1), set to origin %s\n", debugpoint(&pt));
pt.x -= (infoPtr->iconSpacing.cx - infoPtr->iconSize.cx) / 2;
pt.y -= ICON_TOP_PADDING;
}
lpItem->ptPosition = *&pt;
if (uView == LVS_ICON)
{
lpItem->ptPosition.y -= ICON_TOP_PADDING;
lpItem->ptPosition.x -= (infoPtr->iconSpacing.cx - infoPtr->iconSize.cx) / 2;
if ((lpItem->ptPosition.y < 0) || (lpItem->ptPosition.x < 0))
{
FIXME("failed orig=%s, intent=%s, is %s, setting neg to 0\n",
debugpoint(&orig), debugpoint(&pt), debugpoint(&lpItem->ptPosition));
/*
if (lpItem->ptPosition.x < 0) lpItem->ptPosition.x = 0;
if (lpItem->ptPosition.y < 0) lpItem->ptPosition.y = 0;
*/
}
else
{
TRACE("orig=%s, intent=%s, is %s\n", debugpoint(&orig), debugpoint(&pt), debugpoint(&lpItem->ptPosition));
}
}
}
}
}
}
/* Allocating a POINTER for every item is too resource intensive,
* so we'll keep the (x,y) in different arrays */
if (DPA_InsertPtr(infoPtr->hdpaPosX, nItem, (void *)pt.x) == nItem &&
DPA_InsertPtr(infoPtr->hdpaPosY, nItem, (void *)pt.y) == nItem )
return TRUE;
return bResult;
ERR("We should never fail here (nItem=%d, pt=%s), please report.\n",
nItem, debugpoint(&pt));
return FALSE;
}
/***
@ -7224,6 +7203,8 @@ static LRESULT LISTVIEW_Create(HWND hwnd, LPCREATESTRUCTW lpcs)
/* allocate memory for the data structure */
infoPtr->hdpaItems = DPA_Create(10);
infoPtr->hdpaPosX = DPA_Create(10);
infoPtr->hdpaPosY = DPA_Create(10);
/* allocate memory for the selection ranges */
infoPtr->hdpaSelectionRanges = DPA_Create(10);