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:
parent
6cfd83b985
commit
b9cacc438a
|
@ -100,7 +100,6 @@ typedef struct tagLISTVIEW_ITEM
|
||||||
UINT state;
|
UINT state;
|
||||||
LPARAM lParam;
|
LPARAM lParam;
|
||||||
INT iIndent;
|
INT iIndent;
|
||||||
POINT ptPosition;
|
|
||||||
BOOL valid;
|
BOOL valid;
|
||||||
} LISTVIEW_ITEM;
|
} LISTVIEW_ITEM;
|
||||||
|
|
||||||
|
@ -153,8 +152,10 @@ typedef struct tagLISTVIEW_INFO
|
||||||
RECT rcFocus;
|
RECT rcFocus;
|
||||||
DWORD dwStyle; /* the cached window GWL_STYLE */
|
DWORD dwStyle; /* the cached window GWL_STYLE */
|
||||||
DWORD dwLvExStyle; /* extended listview style */
|
DWORD dwLvExStyle; /* extended listview style */
|
||||||
HDPA hdpaItems;
|
|
||||||
UINT nItemCount;
|
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;
|
PFNLVCOMPARE pfnCompare;
|
||||||
LPARAM lParamSort;
|
LPARAM lParamSort;
|
||||||
HWND hwndEdit;
|
HWND hwndEdit;
|
||||||
|
@ -1297,11 +1298,8 @@ static BOOL LISTVIEW_GetItemMeasures(LISTVIEW_INFO *infoPtr, INT nItem,
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
|
if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
|
||||||
{
|
{
|
||||||
/* FIXME: what about virtual listview? */
|
TopLeft.x = (LONG)DPA_GetPtr(infoPtr->hdpaPosX, nItem);
|
||||||
HDPA hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem);
|
TopLeft.y = (LONG)DPA_GetPtr(infoPtr->hdpaPosY, nItem);
|
||||||
LISTVIEW_ITEM * lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
|
|
||||||
if (!lpItem) return FALSE;
|
|
||||||
TopLeft = lpItem->ptPosition;
|
|
||||||
}
|
}
|
||||||
else if (uView == LVS_LIST)
|
else if (uView == LVS_LIST)
|
||||||
{
|
{
|
||||||
|
@ -1347,6 +1345,7 @@ static BOOL LISTVIEW_GetItemMeasures(LISTVIEW_INFO *infoPtr, INT nItem,
|
||||||
TopLeft.x -= scrollInfo.nPos;
|
TopLeft.x -= scrollInfo.nPos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TRACE("TopLeft=%s\n", debugpoint(&TopLeft));
|
||||||
|
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
/* compute position point (ala LVM_GETITEMPOSITION) */
|
/* compute position point (ala LVM_GETITEMPOSITION) */
|
||||||
|
@ -3901,6 +3900,8 @@ static LRESULT LISTVIEW_DeleteAllItems(LISTVIEW_INFO *infoPtr)
|
||||||
/* reinitialize listview memory */
|
/* reinitialize listview memory */
|
||||||
bResult = DPA_DeleteAllPtrs(infoPtr->hdpaItems);
|
bResult = DPA_DeleteAllPtrs(infoPtr->hdpaItems);
|
||||||
infoPtr->nItemCount = 0;
|
infoPtr->nItemCount = 0;
|
||||||
|
DPA_DeleteAllPtrs(infoPtr->hdpaPosX);
|
||||||
|
DPA_DeleteAllPtrs(infoPtr->hdpaPosY);
|
||||||
|
|
||||||
/* align items (set position of each item) */
|
/* align items (set position of each item) */
|
||||||
if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
|
if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
|
||||||
|
@ -4105,6 +4106,8 @@ static LRESULT LISTVIEW_DeleteItem(LISTVIEW_INFO *infoPtr, INT nItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
bResult = DPA_Destroy(hdpaSubItems);
|
bResult = DPA_Destroy(hdpaSubItems);
|
||||||
|
DPA_DeletePtr(infoPtr->hdpaPosX, nItem);
|
||||||
|
DPA_DeletePtr(infoPtr->hdpaPosY, nItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
LISTVIEW_ShiftIndices(infoPtr,nItem,-1);
|
LISTVIEW_ShiftIndices(infoPtr,nItem,-1);
|
||||||
|
@ -6052,11 +6055,7 @@ static LRESULT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem,
|
||||||
infoPtr->nItemCount++;
|
infoPtr->nItemCount++;
|
||||||
|
|
||||||
if (!LISTVIEW_SetItemT(infoPtr, lpLVItem, isW))
|
if (!LISTVIEW_SetItemT(infoPtr, lpLVItem, isW))
|
||||||
{
|
goto undo;
|
||||||
DPA_DeletePtr(infoPtr->hdpaItems, nItem);
|
|
||||||
infoPtr->nItemCount--;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if we're sorted, sort the list, and update the index */
|
/* if we're sorted, sort the list, and update the index */
|
||||||
if (is_sorted)
|
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
|
/* Add the subitem list to the items array. Do this last in case we go to
|
||||||
* fail during the above.
|
* fail during the above.
|
||||||
*/
|
*/
|
||||||
|
@ -6099,6 +6110,9 @@ static LRESULT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem,
|
||||||
TRACE(" <- %d\n", nItem);
|
TRACE(" <- %d\n", nItem);
|
||||||
return nItem;
|
return nItem;
|
||||||
|
|
||||||
|
undo:
|
||||||
|
DPA_DeletePtr(infoPtr->hdpaItems, nItem);
|
||||||
|
infoPtr->nItemCount--;
|
||||||
fail:
|
fail:
|
||||||
DPA_DeletePtr(hdpaSubItems, 0);
|
DPA_DeletePtr(hdpaSubItems, 0);
|
||||||
DPA_Destroy (hdpaSubItems);
|
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)
|
static BOOL LISTVIEW_SetItemPosition(LISTVIEW_INFO *infoPtr, INT nItem, POINT pt)
|
||||||
{
|
{
|
||||||
UINT lStyle = infoPtr->dwStyle;
|
UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
|
||||||
UINT uView = lStyle & LVS_TYPEMASK;
|
|
||||||
LISTVIEW_ITEM *lpItem;
|
|
||||||
HDPA hdpaSubItems;
|
|
||||||
BOOL bResult = FALSE;
|
|
||||||
|
|
||||||
TRACE("(nItem=%d, &pt=%s\n", nItem, debugpoint(&pt));
|
TRACE("(nItem=%d, &pt=%s\n", nItem, debugpoint(&pt));
|
||||||
|
|
||||||
if (lStyle & LVS_OWNERDATA)
|
if (nItem < 0 || nItem >= infoPtr->nItemCount ||
|
||||||
return FALSE;
|
!(uView == LVS_ICON || uView == LVS_SMALLICON)) return FALSE;
|
||||||
|
|
||||||
if ((nItem >= 0) || (nItem < infoPtr->nItemCount))
|
/* This point value seems to be an undocumented feature.
|
||||||
{
|
* The best guess is that it means either at the origin,
|
||||||
if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
|
* 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)
|
||||||
{
|
{
|
||||||
if ( (hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem)) )
|
pt.x -= (infoPtr->iconSpacing.cx - infoPtr->iconSize.cx) / 2;
|
||||||
{
|
pt.y -= ICON_TOP_PADDING;
|
||||||
if ( (lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0)) )
|
|
||||||
{
|
|
||||||
POINT orig = lpItem->ptPosition;
|
|
||||||
bResult = TRUE;
|
|
||||||
if ((pt.x == -1) && (pt.y == -1))
|
|
||||||
{
|
|
||||||
/* 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return bResult;
|
/* 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;
|
||||||
|
|
||||||
|
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 */
|
/* allocate memory for the data structure */
|
||||||
infoPtr->hdpaItems = DPA_Create(10);
|
infoPtr->hdpaItems = DPA_Create(10);
|
||||||
|
infoPtr->hdpaPosX = DPA_Create(10);
|
||||||
|
infoPtr->hdpaPosY = DPA_Create(10);
|
||||||
|
|
||||||
/* allocate memory for the selection ranges */
|
/* allocate memory for the selection ranges */
|
||||||
infoPtr->hdpaSelectionRanges = DPA_Create(10);
|
infoPtr->hdpaSelectionRanges = DPA_Create(10);
|
||||||
|
|
Loading…
Reference in New Issue