|
|
// small icon view (positional view, not list)
#include "ctlspriv.h"
#include "listview.h"
int ListView_SItemHitTest(LV* plv, int x, int y, UINT* pflags, int *piSubItem) {
int iHit; UINT flags; POINT pt; RECT rcState; RECT rcLabel; RECT rcIcon;
if (piSubItem) *piSubItem = 0;
// Map window-relative coordinates to view-relative coords...
//
pt.x = x + plv->ptOrigin.x; pt.y = y + plv->ptOrigin.y;
// If we find an uncomputed item, recompute them all now...
//
if (plv->rcView.left == RECOMPUTE) ListView_Recompute(plv);
flags = 0;
if (ListView_IsOwnerData( plv )) { int cSlots; POINT ptWnd; LISTITEM item; int iWidth = 0, iHeight = 0;
cSlots = ListView_GetSlotCount( plv, TRUE, &iWidth, &iHeight ); iHit = ListView_CalcHitSlot( plv, pt, cSlots, iWidth, iHeight ); ListView_SGetRectsOwnerData( plv, iHit, &rcIcon, &rcLabel, &item, FALSE ); ptWnd.x = x; ptWnd.y = y;
if (PtInRect(&rcIcon, ptWnd)) { flags = LVHT_ONITEMICON; } else if (PtInRect(&rcLabel, ptWnd)) { flags = LVHT_ONITEMLABEL; } } else { for (iHit = 0; iHit < ListView_Count(plv); iHit++) { LISTITEM* pitem = ListView_FastGetZItemPtr(plv, iHit); POINT ptItem;
ptItem.x = pitem->pt.x; ptItem.y = pitem->pt.y;
rcIcon.top = ptItem.y; rcIcon.bottom = ptItem.y + plv->cyItem;
rcLabel.top = rcIcon.top; rcLabel.bottom = rcIcon.bottom;
// Quick, easy rejection test...
//
if (pt.y < rcIcon.top || pt.y >= rcIcon.bottom) continue;
rcIcon.left = ptItem.x; rcIcon.right = ptItem.x + plv->cxSmIcon; rcState.bottom = rcIcon.bottom; rcState.right = rcIcon.left; rcState.left = rcState.right - (plv->cxState + LV_ICONTOSTATEOFFSET(plv)); rcState.top = rcState.bottom - plv->cyState;
rcLabel.left = rcIcon.right; rcLabel.right = rcLabel.left + pitem->cxSingleLabel;
if (PtInRect(&rcIcon, pt)) { flags = LVHT_ONITEMICON; } else if (PtInRect(&rcLabel, pt)) { flags = LVHT_ONITEMLABEL; } else if (PtInRect(&rcState, pt)) { flags = LVHT_ONITEMSTATEICON; } if (flags) break; } }
if (flags == 0) { flags = LVHT_NOWHERE; iHit = -1; } else { if (!ListView_IsOwnerData( plv )) iHit = DPA_GetPtrIndex(plv->hdpa, (void*)ListView_FastGetZItemPtr(plv, iHit)); }
*pflags = flags; return iHit; }
void ListView_SGetRectsOwnerData( LV* plv, int iItem, RECT* prcIcon, RECT* prcLabel, LISTITEM* pitem, BOOL fUsepitem ) { RECT rcIcon; RECT rcLabel; int cSlots;
// calculate itemx, itemy, itemsSingleLabel from iItem
cSlots = ListView_GetSlotCount( plv, TRUE, NULL, NULL ); pitem->iWorkArea = 0; // OwnerData doesn't support workareas
ListView_SetIconPos( plv, pitem, iItem, cSlots );
// calculate lable sizes
// Note the rect we return should be the min of the size returned and the slot size...
ListView_IRecomputeLabelSize( plv, pitem, iItem, NULL, fUsepitem );
rcIcon.left = pitem->pt.x - plv->ptOrigin.x; rcIcon.right = rcIcon.left + plv->cxSmIcon; rcIcon.top = pitem->pt.y - plv->ptOrigin.y; rcIcon.bottom = rcIcon.top + plv->cyItem; *prcIcon = rcIcon;
rcLabel.left = rcIcon.right; if (pitem->cxSingleLabel < (plv->cxItem - plv->cxSmIcon)) rcLabel.right = rcLabel.left + pitem->cxSingleLabel; else rcLabel.right = rcLabel.left + plv->cxItem - plv->cxSmIcon; rcLabel.top = rcIcon.top; rcLabel.bottom = rcIcon.bottom; *prcLabel = rcLabel; }
void ListView_SGetRects(LV* plv, LISTITEM* pitem, RECT* prcIcon, RECT* prcLabel, LPRECT prcBounds) {
ASSERT( !ListView_IsOwnerData( plv ));
if (pitem->pt.x == RECOMPUTE) { ListView_Recompute(plv); }
prcIcon->left = pitem->pt.x - plv->ptOrigin.x; prcIcon->right = prcIcon->left + plv->cxSmIcon; prcIcon->top = pitem->pt.y - plv->ptOrigin.y; prcIcon->bottom = prcIcon->top + plv->cyItem;
prcLabel->left = prcIcon->right; prcLabel->right = prcLabel->left + pitem->cxSingleLabel; prcLabel->top = prcIcon->top; prcLabel->bottom = prcIcon->bottom; }
// Return the index of the first item >= *pszLookup.
//
int ListView_DoLookupString(LV* plv, LPCTSTR pszLookup, UINT flags, int iStart, int j) { int i; BOOL fExact; int k; LISTITEM* pitem; LISTITEM* pitemLast = NULL;
ASSERT( !ListView_IsOwnerData( plv ));
fExact = FALSE; i = iStart; while ((i >= iStart) && (i < j)) { int result; k = (i + j) / 2; pitem = ListView_FastGetItemPtr(plv, k); if (pitem == pitemLast) break; pitemLast = pitem; result = ListView_CompareString(plv, k, pszLookup, flags, 0);
if (plv->ci.style & LVS_SORTDESCENDING) result = -result;
switch (result) { case 0: fExact = TRUE; // fall through
case 1: j = k; break; case -1: i = k + 1; break; } } // For substrings, return index only if exact match was found.
//
if (!(flags & (LVFI_SUBSTRING | LVFI_PARTIAL)) && !fExact) return -1;
if (i < 0) i = 0; if ((!(flags & LVFI_NEARESTXY)) && ListView_CompareString(plv, i, pszLookup, flags, 1)) { i = -1; } return i; }
int ListView_LookupString(LV* plv, LPCTSTR pszLookup, UINT flags, int iStart) { int iret; if (!pszLookup) return 0; iret = ListView_DoLookupString(plv, pszLookup, flags, iStart, ListView_Count(plv)); if (iret == -1 && (flags & LVFI_WRAP)) { iret = ListView_DoLookupString(plv, pszLookup, flags, 0, iStart); } return iret; }
|