mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 21:53:06 +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):
|
* PARAMETER(S):
|
||||||
* [I] infoPtr : valid pointer to the listview structure
|
* [I] infoPtr : valid pointer to the listview structure
|
||||||
* [O] lpPos : will get the current icon position
|
* [O] lpPos : will get the current icon position
|
||||||
|
* [I] nItem : item id to get position for
|
||||||
*
|
*
|
||||||
* RETURN:
|
* RETURN:
|
||||||
* None
|
* None
|
||||||
*/
|
*/
|
||||||
|
#ifdef __REACTOS__
|
||||||
|
static void LISTVIEW_NextIconPosTop(LISTVIEW_INFO *infoPtr, LPPOINT lpPos, INT nItem)
|
||||||
|
#else
|
||||||
static void LISTVIEW_NextIconPosTop(LISTVIEW_INFO *infoPtr, LPPOINT lpPos)
|
static void LISTVIEW_NextIconPosTop(LISTVIEW_INFO *infoPtr, LPPOINT lpPos)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
INT nListWidth = infoPtr->rcList.right - infoPtr->rcList.left;
|
INT nListWidth = infoPtr->rcList.right - infoPtr->rcList.left;
|
||||||
|
|
||||||
|
@ -2749,11 +2754,16 @@ static void LISTVIEW_NextIconPosTop(LISTVIEW_INFO *infoPtr, LPPOINT lpPos)
|
||||||
* PARAMETER(S):
|
* PARAMETER(S):
|
||||||
* [I] infoPtr : valid pointer to the listview structure
|
* [I] infoPtr : valid pointer to the listview structure
|
||||||
* [O] lpPos : will get the current icon position
|
* [O] lpPos : will get the current icon position
|
||||||
|
* [I] nItem : item id to get position for
|
||||||
*
|
*
|
||||||
* RETURN:
|
* RETURN:
|
||||||
* None
|
* None
|
||||||
*/
|
*/
|
||||||
|
#ifdef __REACTOS__
|
||||||
|
static void LISTVIEW_NextIconPosLeft(LISTVIEW_INFO *infoPtr, LPPOINT lpPos, INT nItem)
|
||||||
|
#else
|
||||||
static void LISTVIEW_NextIconPosLeft(LISTVIEW_INFO *infoPtr, LPPOINT lpPos)
|
static void LISTVIEW_NextIconPosLeft(LISTVIEW_INFO *infoPtr, LPPOINT lpPos)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
|
INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
|
||||||
|
|
||||||
|
@ -2767,6 +2777,44 @@ static void LISTVIEW_NextIconPosLeft(LISTVIEW_INFO *infoPtr, LPPOINT lpPos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#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:
|
* DESCRIPTION:
|
||||||
* Moves an icon to the specified position.
|
* 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)
|
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);
|
void (*next_pos)(LISTVIEW_INFO *, LPPOINT);
|
||||||
|
#endif
|
||||||
POINT pos;
|
POINT pos;
|
||||||
INT i;
|
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_ALIGNLEFT: next_pos = LISTVIEW_NextIconPosLeft; break;
|
||||||
case LVA_ALIGNTOP: next_pos = LISTVIEW_NextIconPosTop; 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 */
|
case LVA_SNAPTOGRID: next_pos = LISTVIEW_NextIconPosTop; break; /* FIXME */
|
||||||
|
#endif
|
||||||
default: return FALSE;
|
default: return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
infoPtr->currIconPos.x = infoPtr->currIconPos.y = 0;
|
infoPtr->currIconPos.x = infoPtr->currIconPos.y = 0;
|
||||||
for (i = 0; i < infoPtr->nItemCount; i++)
|
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);
|
LISTVIEW_MoveIconTo(infoPtr, i, &pos, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7978,10 +8038,17 @@ static INT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem,
|
||||||
{
|
{
|
||||||
POINT pt;
|
POINT pt;
|
||||||
|
|
||||||
|
#ifdef __REACTOS__
|
||||||
if (infoPtr->dwStyle & LVS_ALIGNLEFT)
|
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);
|
LISTVIEW_NextIconPosLeft(infoPtr, &pt);
|
||||||
else
|
else
|
||||||
LISTVIEW_NextIconPosTop(infoPtr, &pt);
|
LISTVIEW_NextIconPosTop(infoPtr, &pt);
|
||||||
|
#endif
|
||||||
|
|
||||||
LISTVIEW_MoveIconTo(infoPtr, nItem, &pt, TRUE);
|
LISTVIEW_MoveIconTo(infoPtr, nItem, &pt, TRUE);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue