Change the definition of ranges to exclude the upper bound.
This commit is contained in:
parent
bac35001fe
commit
fa81ec674b
|
@ -442,7 +442,7 @@ static inline char* debugrange(const RANGE* lprng)
|
||||||
if (lprng)
|
if (lprng)
|
||||||
{
|
{
|
||||||
char* buf = debug_getbuf();
|
char* buf = debug_getbuf();
|
||||||
snprintf(buf, DEBUG_BUFFER_SIZE, "(%d, %d)", lprng->lower, lprng->upper);
|
snprintf(buf, DEBUG_BUFFER_SIZE, "[%d, %d)", lprng->lower, lprng->upper);
|
||||||
return buf;
|
return buf;
|
||||||
} else return "(null)";
|
} else return "(null)";
|
||||||
}
|
}
|
||||||
|
@ -701,6 +701,20 @@ static BOOL ranges_add(RANGES ranges, RANGE range);
|
||||||
static BOOL ranges_del(RANGES ranges, RANGE range);
|
static BOOL ranges_del(RANGES ranges, RANGE range);
|
||||||
static void ranges_dump(RANGES ranges);
|
static void ranges_dump(RANGES ranges);
|
||||||
|
|
||||||
|
static inline BOOL ranges_additem(RANGES ranges, INT nItem)
|
||||||
|
{
|
||||||
|
RANGE range = { nItem, nItem + 1 };
|
||||||
|
|
||||||
|
return ranges_add(ranges, range);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline BOOL ranges_delitem(RANGES ranges, INT nItem)
|
||||||
|
{
|
||||||
|
RANGE range = { nItem, nItem + 1 };
|
||||||
|
|
||||||
|
return ranges_del(ranges, range);
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* ITERATOR DOCUMENTATION
|
* ITERATOR DOCUMENTATION
|
||||||
*
|
*
|
||||||
|
@ -778,7 +792,7 @@ static inline BOOL iterator_next(ITERATOR* i)
|
||||||
i->nItem++;
|
i->nItem++;
|
||||||
testitem:
|
testitem:
|
||||||
if (i->nItem == i->nSpecial) i->nItem++;
|
if (i->nItem == i->nSpecial) i->nItem++;
|
||||||
if (i->nItem <= i->range.upper) return TRUE;
|
if (i->nItem < i->range.upper) return TRUE;
|
||||||
|
|
||||||
pickarange:
|
pickarange:
|
||||||
if (i->ranges)
|
if (i->ranges)
|
||||||
|
@ -787,7 +801,7 @@ pickarange:
|
||||||
i->range = *(RANGE*)DPA_GetPtr(i->ranges->hdpa, i->index++);
|
i->range = *(RANGE*)DPA_GetPtr(i->ranges->hdpa, i->index++);
|
||||||
else goto end;
|
else goto end;
|
||||||
}
|
}
|
||||||
else if (i->nItem > i->range.upper) goto end;
|
else if (i->nItem >= i->range.upper) goto end;
|
||||||
|
|
||||||
i->nItem = i->range.lower;
|
i->nItem = i->range.lower;
|
||||||
if (i->nItem >= 0) goto testitem;
|
if (i->nItem >= 0) goto testitem;
|
||||||
|
@ -818,8 +832,8 @@ static inline BOOL iterator_prev(ITERATOR* i)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
i->nItem--;
|
|
||||||
testitem:
|
testitem:
|
||||||
|
i->nItem--;
|
||||||
if (i->nItem == i->nSpecial) i->nItem--;
|
if (i->nItem == i->nSpecial) i->nItem--;
|
||||||
if (i->nItem >= i->range.lower) return TRUE;
|
if (i->nItem >= i->range.lower) return TRUE;
|
||||||
|
|
||||||
|
@ -833,7 +847,7 @@ pickarange:
|
||||||
else if (!start && i->nItem < i->range.lower) goto end;
|
else if (!start && i->nItem < i->range.lower) goto end;
|
||||||
|
|
||||||
i->nItem = i->range.upper;
|
i->nItem = i->range.upper;
|
||||||
if (i->nItem >= 0) goto testitem;
|
if (i->nItem > 0) goto testitem;
|
||||||
end:
|
end:
|
||||||
return (i->nItem = i->nSpecial) != -1;
|
return (i->nItem = i->nSpecial) != -1;
|
||||||
}
|
}
|
||||||
|
@ -901,11 +915,12 @@ static BOOL iterator_frameditems(ITERATOR* i, LISTVIEW_INFO* infoPtr, const RECT
|
||||||
rcItem.right = rcItem.left + infoPtr->nItemWidth;
|
rcItem.right = rcItem.left + infoPtr->nItemWidth;
|
||||||
rcItem.bottom = rcItem.top + infoPtr->nItemHeight;
|
rcItem.bottom = rcItem.top + infoPtr->nItemHeight;
|
||||||
if (IntersectRect(&rcTemp, &rcItem, &frame))
|
if (IntersectRect(&rcTemp, &rcItem, &frame))
|
||||||
{
|
ranges_additem(i->ranges, nItem);
|
||||||
RANGE item_range = { nItem, nItem };
|
}
|
||||||
ranges_add(i->ranges, item_range);
|
if (TRACE_ON(listview))
|
||||||
TRACE(" icon=%d\n", nItem);
|
{
|
||||||
}
|
TRACE(" icon items:\n");
|
||||||
|
ranges_dump(i->ranges);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -920,7 +935,7 @@ static BOOL iterator_frameditems(ITERATOR* i, LISTVIEW_INFO* infoPtr, const RECT
|
||||||
upper = min((frame.bottom - 1) / infoPtr->nItemHeight, infoPtr->nItemCount - 1);
|
upper = min((frame.bottom - 1) / infoPtr->nItemHeight, infoPtr->nItemCount - 1);
|
||||||
if (upper < lower) return TRUE;
|
if (upper < lower) return TRUE;
|
||||||
i->range.lower = lower;
|
i->range.lower = lower;
|
||||||
i->range.upper = upper;
|
i->range.upper = upper + 1;
|
||||||
TRACE(" report=%s\n", debugrange(&i->range));
|
TRACE(" report=%s\n", debugrange(&i->range));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -944,7 +959,7 @@ static BOOL iterator_frameditems(ITERATOR* i, LISTVIEW_INFO* infoPtr, const RECT
|
||||||
{
|
{
|
||||||
item_range.lower = nCol * nPerCol + nFirstRow;
|
item_range.lower = nCol * nPerCol + nFirstRow;
|
||||||
if(item_range.lower >= infoPtr->nItemCount) break;
|
if(item_range.lower >= infoPtr->nItemCount) break;
|
||||||
item_range.upper = min(nCol * nPerCol + nLastRow, infoPtr->nItemCount - 1);
|
item_range.upper = min(nCol * nPerCol + nLastRow + 1, infoPtr->nItemCount);
|
||||||
TRACE(" list=%s\n", debugrange(&item_range));
|
TRACE(" list=%s\n", debugrange(&item_range));
|
||||||
ranges_add(i->ranges, item_range);
|
ranges_add(i->ranges, item_range);
|
||||||
}
|
}
|
||||||
|
@ -993,10 +1008,7 @@ static BOOL iterator_visibleitems(ITERATOR* i, LISTVIEW_INFO *infoPtr, HDC hdc)
|
||||||
rcItem.right = rcItem.left + infoPtr->nItemWidth;
|
rcItem.right = rcItem.left + infoPtr->nItemWidth;
|
||||||
rcItem.bottom = rcItem.top + infoPtr->nItemHeight;
|
rcItem.bottom = rcItem.top + infoPtr->nItemHeight;
|
||||||
if (!RectVisible(hdc, &rcItem))
|
if (!RectVisible(hdc, &rcItem))
|
||||||
{
|
ranges_delitem(i->ranges, i->nItem);
|
||||||
RANGE item_range = { i->nItem, i->nItem };
|
|
||||||
ranges_del(i->ranges, item_range);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* the iterator should restart on the next iterator_next */
|
/* the iterator should restart on the next iterator_next */
|
||||||
|
|
||||||
|
@ -2154,15 +2166,15 @@ static void LISTVIEW_PrintSelectionRanges(LISTVIEW_INFO *infoPtr)
|
||||||
* [I] flags : flags
|
* [I] flags : flags
|
||||||
*
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
* >0 : if Item 1 > Item 2
|
* > 0 : if range 1 > range 2
|
||||||
* <0 : if Item 2 > Item 1
|
* < 0 : if range 2 > range 1
|
||||||
* 0 : if Item 1 == Item 2
|
* = 0 : if range intersects range 2
|
||||||
*/
|
*/
|
||||||
static INT CALLBACK ranges_cmp(LPVOID range1, LPVOID range2, LPARAM flags)
|
static INT CALLBACK ranges_cmp(LPVOID range1, LPVOID range2, LPARAM flags)
|
||||||
{
|
{
|
||||||
if (((RANGE*)range1)->upper < ((RANGE*)range2)->lower)
|
if (((RANGE*)range1)->upper <= ((RANGE*)range2)->lower)
|
||||||
return -1;
|
return -1;
|
||||||
if (((RANGE*)range2)->upper < ((RANGE*)range1)->lower)
|
if (((RANGE*)range2)->upper <= ((RANGE*)range1)->lower)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2195,7 +2207,7 @@ static void ranges_dump(RANGES ranges)
|
||||||
|
|
||||||
static inline BOOL ranges_contain(RANGES ranges, INT nItem)
|
static inline BOOL ranges_contain(RANGES ranges, INT nItem)
|
||||||
{
|
{
|
||||||
RANGE srchrng = { nItem, nItem };
|
RANGE srchrng = { nItem, nItem + 1 };
|
||||||
|
|
||||||
TRACE("(nItem=%d)\n", nItem);
|
TRACE("(nItem=%d)\n", nItem);
|
||||||
if (TRACE_ON(listview)) ranges_dump(ranges);
|
if (TRACE_ON(listview)) ranges_dump(ranges);
|
||||||
|
@ -2209,7 +2221,7 @@ static INT ranges_itemcount(RANGES ranges)
|
||||||
for (i = 0; i < ranges->hdpa->nItemCount; i++)
|
for (i = 0; i < ranges->hdpa->nItemCount; i++)
|
||||||
{
|
{
|
||||||
RANGE *sel = DPA_GetPtr(ranges->hdpa, i);
|
RANGE *sel = DPA_GetPtr(ranges->hdpa, i);
|
||||||
count += sel->upper - sel->lower + 1;
|
count += sel->upper - sel->lower;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
@ -2217,12 +2229,9 @@ static INT ranges_itemcount(RANGES ranges)
|
||||||
|
|
||||||
static BOOL ranges_shift(RANGES ranges, INT nItem, INT delta, INT nUpper)
|
static BOOL ranges_shift(RANGES ranges, INT nItem, INT delta, INT nUpper)
|
||||||
{
|
{
|
||||||
RANGE srchrng, *chkrng;
|
RANGE srchrng = { nItem, nItem + 1 }, *chkrng;
|
||||||
INT index;
|
INT index;
|
||||||
|
|
||||||
srchrng.upper = nItem;
|
|
||||||
srchrng.lower = nItem;
|
|
||||||
|
|
||||||
index = DPA_Search(ranges->hdpa, &srchrng, 0, ranges_cmp, 0, DPAS_SORTED | DPAS_INSERTAFTER);
|
index = DPA_Search(ranges->hdpa, &srchrng, 0, ranges_cmp, 0, DPAS_SORTED | DPAS_INSERTAFTER);
|
||||||
if (index == -1) return TRUE;
|
if (index == -1) return TRUE;
|
||||||
|
|
||||||
|
@ -2231,8 +2240,8 @@ static BOOL ranges_shift(RANGES ranges, INT nItem, INT delta, INT nUpper)
|
||||||
chkrng = DPA_GetPtr(ranges->hdpa, index);
|
chkrng = DPA_GetPtr(ranges->hdpa, index);
|
||||||
if (chkrng->lower >= nItem)
|
if (chkrng->lower >= nItem)
|
||||||
chkrng->lower = max(min(chkrng->lower + delta, nUpper - 1), 0);
|
chkrng->lower = max(min(chkrng->lower + delta, nUpper - 1), 0);
|
||||||
if (chkrng->upper >= nItem)
|
if (chkrng->upper > nItem)
|
||||||
chkrng->upper = max(min(chkrng->upper + delta, nUpper - 1), 0);
|
chkrng->upper = max(min(chkrng->upper + delta, nUpper), 0);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -2350,13 +2359,13 @@ static BOOL ranges_del(RANGES ranges, RANGE range)
|
||||||
else if ( (chkrgn->upper <= remrgn.upper) &&
|
else if ( (chkrgn->upper <= remrgn.upper) &&
|
||||||
(chkrgn->lower < remrgn.lower) )
|
(chkrgn->lower < remrgn.lower) )
|
||||||
{
|
{
|
||||||
chkrgn->upper = remrgn.lower - 1;
|
chkrgn->upper = remrgn.lower;
|
||||||
}
|
}
|
||||||
/* case 4: overlap lower */
|
/* case 4: overlap lower */
|
||||||
else if ( (chkrgn->upper > remrgn.upper) &&
|
else if ( (chkrgn->upper > remrgn.upper) &&
|
||||||
(chkrgn->lower >= remrgn.lower) )
|
(chkrgn->lower >= remrgn.lower) )
|
||||||
{
|
{
|
||||||
chkrgn->lower = remrgn.upper + 1;
|
chkrgn->lower = remrgn.upper;
|
||||||
}
|
}
|
||||||
/* case 5: fully internal */
|
/* case 5: fully internal */
|
||||||
else
|
else
|
||||||
|
@ -2365,8 +2374,8 @@ static BOOL ranges_del(RANGES ranges, RANGE range)
|
||||||
if (!newrgn) return FALSE;
|
if (!newrgn) return FALSE;
|
||||||
tmprgn = *chkrgn;
|
tmprgn = *chkrgn;
|
||||||
newrgn->lower = chkrgn->lower;
|
newrgn->lower = chkrgn->lower;
|
||||||
newrgn->upper = remrgn.lower - 1;
|
newrgn->upper = remrgn.lower;
|
||||||
chkrgn->lower = remrgn.upper + 1;
|
chkrgn->lower = remrgn.upper;
|
||||||
DPA_InsertPtr(ranges->hdpa, index, newrgn);
|
DPA_InsertPtr(ranges->hdpa, index, newrgn);
|
||||||
chkrgn = &tmprgn;
|
chkrgn = &tmprgn;
|
||||||
}
|
}
|
||||||
|
@ -2822,15 +2831,13 @@ static BOOL set_owner_item(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isW,
|
||||||
/* and the selection is the only other state a virtual list may hold */
|
/* and the selection is the only other state a virtual list may hold */
|
||||||
if (lpLVItem->stateMask & LVIS_SELECTED)
|
if (lpLVItem->stateMask & LVIS_SELECTED)
|
||||||
{
|
{
|
||||||
RANGE range = { lpLVItem->iItem, lpLVItem->iItem };
|
|
||||||
|
|
||||||
if (lpLVItem->state & LVIS_SELECTED)
|
if (lpLVItem->state & LVIS_SELECTED)
|
||||||
{
|
{
|
||||||
if (lStyle & LVS_SINGLESEL) LISTVIEW_RemoveAllSelections(infoPtr, lpLVItem->iItem);
|
if (lStyle & LVS_SINGLESEL) LISTVIEW_RemoveAllSelections(infoPtr, lpLVItem->iItem);
|
||||||
ranges_add(infoPtr->selectionRanges, range);
|
ranges_additem(infoPtr->selectionRanges, lpLVItem->iItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ranges_del(infoPtr->selectionRanges, range);
|
ranges_delitem(infoPtr->selectionRanges, lpLVItem->iItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* notify the parent now that things have changed */
|
/* notify the parent now that things have changed */
|
||||||
|
@ -2923,17 +2930,15 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isW,
|
||||||
|
|
||||||
if (uChanged & LVIF_STATE)
|
if (uChanged & LVIF_STATE)
|
||||||
{
|
{
|
||||||
RANGE range = { lpLVItem->iItem, lpLVItem->iItem };
|
|
||||||
|
|
||||||
lpItem->state &= ~lpLVItem->stateMask;
|
lpItem->state &= ~lpLVItem->stateMask;
|
||||||
lpItem->state |= (lpLVItem->state & lpLVItem->stateMask);
|
lpItem->state |= (lpLVItem->state & lpLVItem->stateMask);
|
||||||
if (lpLVItem->state & lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_SELECTED)
|
if (lpLVItem->state & lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_SELECTED)
|
||||||
{
|
{
|
||||||
if (lStyle & LVS_SINGLESEL) LISTVIEW_RemoveAllSelections(infoPtr, lpLVItem->iItem);
|
if (lStyle & LVS_SINGLESEL) LISTVIEW_RemoveAllSelections(infoPtr, lpLVItem->iItem);
|
||||||
ranges_add(infoPtr->selectionRanges, range);
|
ranges_additem(infoPtr->selectionRanges, lpLVItem->iItem);
|
||||||
}
|
}
|
||||||
else if (lpLVItem->stateMask & LVIS_SELECTED)
|
else if (lpLVItem->stateMask & LVIS_SELECTED)
|
||||||
ranges_del(infoPtr->selectionRanges, range);
|
ranges_delitem(infoPtr->selectionRanges, lpLVItem->iItem);
|
||||||
|
|
||||||
/* if we are asked to change focus, and we manage it, do it */
|
/* if we are asked to change focus, and we manage it, do it */
|
||||||
if (lpLVItem->state & lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_FOCUSED)
|
if (lpLVItem->state & lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_FOCUSED)
|
||||||
|
@ -3341,8 +3346,9 @@ static void LISTVIEW_RefreshOwnerDraw(LISTVIEW_INFO *infoPtr, HDC hdc)
|
||||||
RANGE range = iterator_range(&i);
|
RANGE range = iterator_range(&i);
|
||||||
NMLVCACHEHINT nmlv;
|
NMLVCACHEHINT nmlv;
|
||||||
|
|
||||||
|
ZeroMemory(&nmlv, sizeof(NMLVCACHEHINT));
|
||||||
nmlv.iFrom = range.lower;
|
nmlv.iFrom = range.lower;
|
||||||
nmlv.iTo = range.upper;
|
nmlv.iTo = range.upper - 1;
|
||||||
notify_hdr(infoPtr, LVN_ODCACHEHINT, &nmlv.hdr);
|
notify_hdr(infoPtr, LVN_ODCACHEHINT, &nmlv.hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue