Listview N3
Dimitrie O. Paun
dpaun at rogers.com
Thu Oct 10 11:34:34 CDT 2002
ChangeLog
Fix silly redraw bug introduced in previous patch
Tidy up, and simplify large item drawing.
--- dlls/comctl32/listview.c.N2 Thu Oct 10 10:38:50 2002
+++ dlls/comctl32/listview.c Thu Oct 10 12:31:32 2002
@@ -27,6 +27,7 @@
* TODO:
* -- Drawing optimizations.
* -- Hot item handling.
+ * -- Expand large item in ICON mode when the cursor is flying over the icon or text.
*
* Notifications:
* LISTVIEW_Notify : most notifications from children (editbox and header)
@@ -3205,153 +3206,87 @@
* [I] infoPtr : valid pointer to the listview structure
* [I] hdc : device context handle
* [I] nItem : item index
- * [I] rcItem : clipping rectangle
*
* RETURN:
* TRUE: if item is focused
* FALSE: otherwise
*/
-static BOOL LISTVIEW_DrawLargeItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, RECT rcItem)
+static void LISTVIEW_DrawLargeItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem)
{
- WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' };
- LVITEMW lvItem;
- UINT uFormat;
- RECT rcIcon, rcFocus, rcLabel, *lprcFocus;
-
- TRACE("(hdc=%x, nItem=%d, rcItem=%s)\n", hdc, nItem, debugrect(&rcItem));
-
- /* get information needed for drawing the item */
- lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
- lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED | LVIS_STATEIMAGEMASK;
- lvItem.iItem = nItem;
- lvItem.iSubItem = 0;
- lvItem.cchTextMax = DISP_TEXT_SIZE;
- lvItem.pszText = szDispText;
- *lvItem.pszText = '\0';
- if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return FALSE;
- TRACE(" lvItem=%s\n", debuglvitem_t(&lvItem, TRUE));
+ WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' };
+ RECT rcIcon, rcLabel, *lprcFocus;
+ LVITEMW lvItem;
+ UINT uFormat;
+ TEXTATTR ta;
- /* now check if we need to update the focus rectangle */
- lprcFocus = infoPtr->bFocus && (lvItem.state & LVIS_FOCUSED) ? &infoPtr->rcFocus : 0;
-
- if (!LISTVIEW_GetItemMeasures(infoPtr, nItem, NULL, NULL, &rcIcon, &rcLabel)) return FALSE;
+ TRACE("(hdc=%x, nItem=%d)\n", hdc, nItem);
- /* Set the item to the boundary box for now */
- TRACE("rcIcon=%s, rcLabel=%s\n", debugrect(&rcIcon), debugrect(&rcLabel));
+ /* get information needed for drawing the item */
+ lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
+ lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED | LVIS_STATEIMAGEMASK;
+ lvItem.iItem = nItem;
+ lvItem.iSubItem = 0;
+ lvItem.pszText = szDispText;
+ lvItem.cchTextMax = DISP_TEXT_SIZE;
+ if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return;
+ TRACE(" lvItem=%s\n", debuglvitem_t(&lvItem, TRUE));
- /* Figure out text colours etc. depending on state
- * At least the following states exist; there may be more.
- * Many items may be selected
- * At most one item may have the focus
- * The application may not actually be active currently
- * 1. The item is not selected in any way
- * 2. The cursor is flying over the icon or text and the text is being
- * expanded because it is not fully displayed currently.
- * 3. The item is selected and is focussed, i.e. the user has not clicked
- * in the blank area of the window, and the window (or application?)
- * still has the focus.
- * 4. As 3 except that a different window has the focus
- * 5. The item is the selected item of all the items, but the user has
- * clicked somewhere else on the window.
- * Only a few of these are handled currently. In particular 2 is not yet
- * handled since we do not support the functionality currently (or at least
- * we didn't when I wrote this)
- */
+ /* now check if we need to update the focus rectangle */
+ lprcFocus = infoPtr->bFocus && (lvItem.state & LVIS_FOCUSED) ? &infoPtr->rcFocus : 0;
+
+ if (!LISTVIEW_GetItemMeasures(infoPtr, nItem, NULL, NULL, &rcIcon, &rcLabel)) return;
- if (lvItem.state & LVIS_SELECTED)
- {
- /* set item colors */
- SetBkColor(hdc, comctl32_color.clrHighlight);
- SetTextColor(hdc, comctl32_color.clrHighlightText);
- SetBkMode (hdc, OPAQUE);
- /* set raster mode */
- SetROP2(hdc, R2_XORPEN);
- /* When exactly is it in XOR? while being dragged? */
- }
- else
- {
- /* set item colors */
- if ( (infoPtr->clrTextBk == CLR_DEFAULT) || (infoPtr->clrTextBk == CLR_NONE) )
- {
- SetBkMode(hdc, TRANSPARENT);
- }
- else
+ /* Set the item to the boundary box for now */
+ TRACE("rcIcon=%s, rcLabel=%s\n", debugrect(&rcIcon), debugrect(&rcLabel));
+
+ /* state icons */
+ if (infoPtr->himlState)
{
- SetBkMode(hdc, OPAQUE);
- SetBkColor(hdc, infoPtr->clrTextBk);
+ UINT uStateImage = (lvItem.state & LVIS_STATEIMAGEMASK) >> 12;
+ INT x = rcIcon.left - infoPtr->iconStateSize.cx + 10;
+ INT y = rcIcon.top + infoPtr->iconSize.cy - infoPtr->iconStateSize.cy + 4;
+ if (uStateImage > 0)
+ ImageList_Draw(infoPtr->himlState, uStateImage - 1, hdc, x, y, ILD_NORMAL);
}
- SetTextColor(hdc, infoPtr->clrText);
- /* set raster mode */
- SetROP2(hdc, R2_COPYPEN);
- }
-
- /* In cases 2,3 and 5 (see above) the full text is displayed, with word
- * wrapping and long words split.
- * In cases 1 and 4 only a portion of the text is displayed with word
- * wrapping and both word and end ellipsis. (I don't yet know about path
- * ellipsis)
- */
- uFormat = lprcFocus ? LV_FL_DT_FLAGS : LV_ML_DT_FLAGS;
+ /* draw the icon */
+ if (infoPtr->himlNormal && lvItem.iImage >=0)
+ ImageList_Draw (infoPtr->himlNormal, lvItem.iImage, hdc,
+ rcIcon.left + ICON_LR_HALF, rcIcon.top + ICON_TOP_PADDING,
+ (lvItem.state & LVIS_SELECTED) ? ILD_SELECTED : ILD_NORMAL);
- /* state icons */
- if (infoPtr->himlState != NULL)
- {
- UINT uStateImage = (lvItem.state & LVIS_STATEIMAGEMASK) >> 12;
- INT x, y;
+ /* Draw the text below the icon */
- x = rcIcon.left - infoPtr->iconStateSize.cx + 10;
- y = rcIcon.top + infoPtr->iconSize.cy - infoPtr->iconStateSize.cy + 4;
- if (uStateImage > 0)
- ImageList_Draw(infoPtr->himlState, uStateImage - 1, hdc, x, y, ILD_NORMAL);
- }
-
- /* draw the icon */
- if (infoPtr->himlNormal != NULL)
- {
- if (lvItem.iImage >= 0)
- ImageList_Draw (infoPtr->himlNormal, lvItem.iImage, hdc,
- rcIcon.left + ICON_LR_HALF, rcIcon.top + ICON_TOP_PADDING,
- (lvItem.state & LVIS_SELECTED) ? ILD_SELECTED : ILD_NORMAL);
- }
+ /* Don't bother painting item being edited */
+ if ((infoPtr->bEditing && lprcFocus) || !lvItem.pszText || !lstrlenW(lvItem.pszText))
+ {
+ if(lprcFocus) SetRectEmpty(lprcFocus);
+ return;
+ }
- /* Draw the text below the icon */
+ select_text_attr(infoPtr, hdc, lvItem.state & LVIS_SELECTED, &ta);
- /* Don't bother painting item being edited */
- if ((infoPtr->bEditing && lprcFocus) || !lvItem.pszText || !lstrlenW(lvItem.pszText))
- {
- if(lprcFocus) SetRectEmpty(lprcFocus);
- return FALSE;
- }
+ uFormat = lprcFocus ? LV_FL_DT_FLAGS : LV_ML_DT_FLAGS;
- /* draw label */
+ /* draw label */
- /* I am sure of most of the uFormat values. However I am not sure about
- * whether we need or do not need the following:
- * DT_EXTERNALLEADING, DT_INTERNAL, DT_CALCRECT, DT_NOFULLWIDTHCHARBREAK,
- * DT_PATH_ELLIPSIS, DT_RTLREADING,
- * We certainly do not need
- * DT_BOTTOM, DT_VCENTER, DT_MODIFYSTRING, DT_LEFT, DT_RIGHT, DT_PREFIXONLY,
- * DT_SINGLELINE, DT_TABSTOP, DT_EXPANDTABS
- */
+ /* I am sure of most of the uFormat values. However I am not sure about
+ * whether we need or do not need the following:
+ * DT_EXTERNALLEADING, DT_INTERNAL, DT_CALCRECT, DT_NOFULLWIDTHCHARBREAK,
+ * DT_PATH_ELLIPSIS, DT_RTLREADING,
+ * We certainly do not need
+ * DT_BOTTOM, DT_VCENTER, DT_MODIFYSTRING, DT_LEFT, DT_RIGHT, DT_PREFIXONLY,
+ * DT_SINGLELINE, DT_TABSTOP, DT_EXPANDTABS
+ */
- /* If the text is being drawn without clipping (i.e. the full text) then we
- * need to jump through a few hoops to ensure that it all gets displayed and
- * that the background is complete
- */
- rcFocus = rcLabel; /* save for focus */
- if (lvItem.state & LVIS_SELECTED)
- ExtTextOutW(hdc, rcLabel.left, rcLabel.top, ETO_OPAQUE, &rcLabel, 0, 0, 0);
- /* else ? What if we are losing the focus? will we not get a complete
- * background?
- */
+ if (lvItem.state & LVIS_SELECTED)
+ ExtTextOutW(hdc, rcLabel.left, rcLabel.top, ETO_OPAQUE, &rcLabel, 0, 0, 0);
- DrawTextW (hdc, lvItem.pszText, -1, &rcLabel, uFormat);
- TRACE("text at rcLabel=%s is %s\n", debugrect(&rcLabel), debugstr_w(lvItem.pszText));
+ DrawTextW (hdc, lvItem.pszText, -1, &rcLabel, uFormat);
- if(lprcFocus) CopyRect(lprcFocus, &rcFocus);
+ if(lprcFocus) *lprcFocus = rcLabel;
- return lprcFocus != NULL;
+ set_text_attr(hdc, &ta);
}
/***
@@ -3643,18 +3578,12 @@
if (LISTVIEW_GetItemState(infoPtr, i.nItem, LVIS_FOCUSED))
continue;
- if (!LISTVIEW_GetItemListOrigin(infoPtr, i.nItem, &Position)) continue;
- rcItem.left = Position.x;
- rcItem.top = Position.y;
- rcItem.bottom = rcItem.top + infoPtr->nItemHeight;
- rcItem.right = rcItem.left + infoPtr->nItemWidth;
- OffsetRect(&rcItem, Origin.x, Origin.y);
-
if (cdmode & CDRF_NOTIFYITEMDRAW)
cditemmode = notify_customdrawitem (infoPtr, hdc, i.nItem, 0, CDDS_ITEMPREPAINT);
if (cditemmode & CDRF_SKIPDEFAULT) continue;
- LISTVIEW_DrawLargeItem(infoPtr, hdc, i.nItem, rcItem);
+ if (!LISTVIEW_GetItemListOrigin(infoPtr, i.nItem, &Position)) continue;
+ LISTVIEW_DrawLargeItem(infoPtr, hdc, i.nItem);
if (cditemmode & CDRF_NOTIFYPOSTPAINT)
notify_customdrawitem(infoPtr, hdc, i.nItem, 0, CDDS_ITEMPOSTPAINT);
@@ -3670,7 +3599,7 @@
if (cditemmode & CDRF_SKIPDEFAULT)
return;
- LISTVIEW_DrawLargeItem(infoPtr, hdc, infoPtr->nFocusedItem, rcItem);
+ LISTVIEW_DrawLargeItem(infoPtr, hdc, infoPtr->nFocusedItem);
if (cditemmode & CDRF_NOTIFYPOSTPAINT)
notify_customdrawitem(infoPtr, hdc, i.nItem, 0, CDDS_ITEMPOSTPAINT);
@@ -7063,6 +6992,7 @@
infoPtr->nFocusedItem = -1;
infoPtr->nSelectionMark = -1;
infoPtr->nHotItem = -1;
+ infoPtr->bRedraw = TRUE;
infoPtr->iconSpacing.cx = GetSystemMetrics(SM_CXICONSPACING);
infoPtr->iconSpacing.cy = GetSystemMetrics(SM_CYICONSPACING);
infoPtr->nEditLabelItem = -1;
More information about the wine-patches
mailing list