mirror of
https://github.com/reactos/reactos.git
synced 2025-07-30 19:11:51 +00:00
[COMCTL32] Implement a simple version of snap to grid for listview
This commit is contained in:
parent
1bee97358e
commit
963d39bf66
1 changed files with 69 additions and 2 deletions
|
@ -2723,11 +2723,16 @@ static DWORD LISTVIEW_MapIndexToId(const LISTVIEW_INFO *infoPtr, INT iItem)
|
|||
* PARAMETER(S):
|
||||
* [I] infoPtr : valid pointer to the listview structure
|
||||
* [O] lpPos : will get the current icon position
|
||||
* [I] nItem : item id to get position for
|
||||
*
|
||||
* RETURN:
|
||||
* None
|
||||
*/
|
||||
#ifdef __REACTOS__
|
||||
static void LISTVIEW_NextIconPosTop(LISTVIEW_INFO *infoPtr, LPPOINT lpPos, INT nItem)
|
||||
#else
|
||||
static void LISTVIEW_NextIconPosTop(LISTVIEW_INFO *infoPtr, LPPOINT lpPos)
|
||||
#endif
|
||||
{
|
||||
INT nListWidth = infoPtr->rcList.right - infoPtr->rcList.left;
|
||||
|
||||
|
@ -2749,11 +2754,16 @@ static void LISTVIEW_NextIconPosTop(LISTVIEW_INFO *infoPtr, LPPOINT lpPos)
|
|||
* PARAMETER(S):
|
||||
* [I] infoPtr : valid pointer to the listview structure
|
||||
* [O] lpPos : will get the current icon position
|
||||
* [I] nItem : item id to get position for
|
||||
*
|
||||
* RETURN:
|
||||
* None
|
||||
*/
|
||||
#ifdef __REACTOS__
|
||||
static void LISTVIEW_NextIconPosLeft(LISTVIEW_INFO *infoPtr, LPPOINT lpPos, INT nItem)
|
||||
#else
|
||||
static void LISTVIEW_NextIconPosLeft(LISTVIEW_INFO *infoPtr, LPPOINT lpPos)
|
||||
#endif
|
||||
{
|
||||
INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
|
||||
|
||||
|
@ -2766,7 +2776,45 @@ static void LISTVIEW_NextIconPosLeft(LISTVIEW_INFO *infoPtr, LPPOINT lpPos)
|
|||
infoPtr->currIconPos.y = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef __REACTOS__
|
||||
/***
|
||||
* DESCRIPTION:
|
||||
* Returns the grid position closest to the already placed icon.
|
||||
* The returned position is not offset by Origin.
|
||||
*
|
||||
* PARAMETER(S):
|
||||
* [I] infoPtr : valid pointer to the listview structure
|
||||
* [O] lpPos : will get the current icon position
|
||||
* [I] nItem : item id to get position for
|
||||
*
|
||||
* RETURN:
|
||||
* None
|
||||
*/
|
||||
static void LISTVIEW_NextIconPosSnap(LISTVIEW_INFO *infoPtr, LPPOINT lpPos, INT nItem)
|
||||
{
|
||||
INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
|
||||
INT nListWidth = infoPtr->rcList.right - infoPtr->rcList.left;
|
||||
INT nMaxColumns = nListWidth / infoPtr->nItemWidth;
|
||||
INT nMaxRows = nListHeight / infoPtr->nItemHeight;
|
||||
POINT oldPosition;
|
||||
|
||||
// get the existing x and y position and then snap to the closest grid square
|
||||
oldPosition.x = (LONG_PTR)DPA_GetPtr(infoPtr->hdpaPosX, nItem);
|
||||
oldPosition.y = (LONG_PTR)DPA_GetPtr(infoPtr->hdpaPosY, nItem);
|
||||
|
||||
// FIXME: This could should deal with multiple icons in the same grid square
|
||||
// equivalent of max(0, round(oldPosition / itemSize) * itemSize), but without need for 'round' function
|
||||
(*lpPos).x = max(0, oldPosition.x + (infoPtr->nItemWidth >> 1) - (oldPosition.x + (infoPtr->nItemWidth >> 1)) % infoPtr->nItemWidth);
|
||||
(*lpPos).y = max(0, oldPosition.y + (infoPtr->nItemHeight >> 1) - (oldPosition.y + (infoPtr->nItemHeight >> 1)) % infoPtr->nItemHeight);
|
||||
|
||||
// deal with any icons that have gone out of range
|
||||
if ((*lpPos).x > nListWidth) (*lpPos).x = nMaxColumns * infoPtr->nItemWidth;
|
||||
if ((*lpPos).y > nListHeight) (*lpPos).y = nMaxRows * infoPtr->nItemHeight;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/***
|
||||
* DESCRIPTION:
|
||||
* Moves an icon to the specified position.
|
||||
|
@ -2819,7 +2867,11 @@ static BOOL LISTVIEW_MoveIconTo(const LISTVIEW_INFO *infoPtr, INT nItem, const P
|
|||
*/
|
||||
static BOOL LISTVIEW_Arrange(LISTVIEW_INFO *infoPtr, INT nAlignCode)
|
||||
{
|
||||
#ifdef __REACTOS__
|
||||
void (*next_pos)(LISTVIEW_INFO *, LPPOINT, INT);
|
||||
#else
|
||||
void (*next_pos)(LISTVIEW_INFO *, LPPOINT);
|
||||
#endif
|
||||
POINT pos;
|
||||
INT i;
|
||||
|
||||
|
@ -2837,14 +2889,22 @@ static BOOL LISTVIEW_Arrange(LISTVIEW_INFO *infoPtr, INT nAlignCode)
|
|||
{
|
||||
case LVA_ALIGNLEFT: next_pos = LISTVIEW_NextIconPosLeft; break;
|
||||
case LVA_ALIGNTOP: next_pos = LISTVIEW_NextIconPosTop; break;
|
||||
#ifdef __REACTOS__
|
||||
case LVA_SNAPTOGRID: next_pos = LISTVIEW_NextIconPosSnap; break;
|
||||
#else
|
||||
case LVA_SNAPTOGRID: next_pos = LISTVIEW_NextIconPosTop; break; /* FIXME */
|
||||
#endif
|
||||
default: return FALSE;
|
||||
}
|
||||
|
||||
infoPtr->currIconPos.x = infoPtr->currIconPos.y = 0;
|
||||
for (i = 0; i < infoPtr->nItemCount; i++)
|
||||
{
|
||||
next_pos(infoPtr, &pos);
|
||||
#ifdef __REACTOS__
|
||||
next_pos(infoPtr, &pos, i);
|
||||
#else
|
||||
next_pos(infoPtr, &pos);
|
||||
#endif
|
||||
LISTVIEW_MoveIconTo(infoPtr, i, &pos, FALSE);
|
||||
}
|
||||
|
||||
|
@ -7978,10 +8038,17 @@ static INT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem,
|
|||
{
|
||||
POINT pt;
|
||||
|
||||
#ifdef __REACTOS__
|
||||
if (infoPtr->dwStyle & LVS_ALIGNLEFT)
|
||||
LISTVIEW_NextIconPosLeft(infoPtr, &pt, nItem);
|
||||
else
|
||||
LISTVIEW_NextIconPosTop(infoPtr, &pt, nItem);
|
||||
#else
|
||||
if (infoPtr->dwStyle & LVS_ALIGNLEFT)
|
||||
LISTVIEW_NextIconPosLeft(infoPtr, &pt);
|
||||
else
|
||||
LISTVIEW_NextIconPosTop(infoPtr, &pt);
|
||||
#endif
|
||||
|
||||
LISTVIEW_MoveIconTo(infoPtr, nItem, &pt, TRUE);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue