diff options
author | Steve Northover <steve> | 2006-02-10 19:08:58 +0000 |
---|---|---|
committer | Steve Northover <steve> | 2006-02-10 19:08:58 +0000 |
commit | 501cddef55d98c472a410dbb933c0adba1cf9644 (patch) | |
tree | d0c4a1dfc0506f64ecdbe9ade86fe99feb795e5f | |
parent | d60307042554a2ad80509163fd1d15e5566b488d (diff) | |
download | eclipse.platform.swt-501cddef55d98c472a410dbb933c0adba1cf9644.tar.gz eclipse.platform.swt-501cddef55d98c472a410dbb933c0adba1cf9644.tar.xz eclipse.platform.swt-501cddef55d98c472a410dbb933c0adba1cf9644.zip |
custom draw
3 files changed, 583 insertions, 344 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java index 99c86cb7e1..805374ffca 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java @@ -52,7 +52,8 @@ public class Tree extends Composite { boolean ignoreSelect, ignoreExpand, ignoreDeselect, ignoreResize; boolean lockSelection, oldSelected, newSelected, ignoreColumnMove; boolean linesVisible, customDraw, printClient, painted; - int headerToolTipHandle; + boolean ignoreDraw, ignoreDrawSelected, ignoreItemHeight; + int scrollWidth, headerToolTipHandle; static final int INSET = 3; static final int GRID_WIDTH = 1; static final int SORT_WIDTH = 10; @@ -118,6 +119,32 @@ static int checkStyle (int style) { return checkBits (style, SWT.SINGLE, SWT.MULTI, 0, 0, 0, 0); } +void _addListener (int eventType, Listener listener) { + super._addListener (eventType, listener); + switch (eventType) { + case SWT.MeasureItem: + case SWT.EraseItem: + case SWT.PaintItem: + if (hwndHeader == 0) { + createParent (); + int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); + bits |= OS.TVS_NOHSCROLL; + OS.SetWindowLong (handle, OS.GWL_STYLE, bits); + /* + * Bug in Windows. When TVS_NOHSCROLL is set after items + * have been inserted into the tree, Windows shows the + * scroll bar. The fix is to check for this case and + * explicilty hide the scroll bar. + */ + int count = OS.SendMessage (handle, OS.TVM_GETCOUNT, 0, 0); + if (count != 0) { + if (!OS.IsWinCE) OS.ShowScrollBar (handle, OS.SB_HORZ, false); + } + } + break; + } +} + TreeItem _getItem (int hItem, int id) { if ((style & SWT.VIRTUAL) == 0) return items [id]; return id != -1 ? items [id] : new TreeItem (this, SWT.NONE, -1, -1, hItem); @@ -693,6 +720,7 @@ void createItem (TreeColumn column, int index) { /* When the first column is created, hide the horizontal scroll bar */ if (columnCount == 0) { + scrollWidth = 0; int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); bits |= OS.TVS_NOHSCROLL; OS.SetWindowLong (handle, OS.GWL_STYLE, bits); @@ -1049,10 +1077,13 @@ void destroyItem (TreeColumn column) { * and redraw the columns to the right. */ if (columnCount == 0) { - int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); - bits &= ~OS.TVS_NOHSCROLL; - OS.SetWindowLong (handle, OS.GWL_STYLE, bits); - OS.InvalidateRect (handle, null, true); + scrollWidth = 0; + if (!hooks (SWT.MeasureItem) && !hooks (SWT.EraseItem) && !hooks (SWT.PaintItem)) { + int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); + bits &= ~OS.TVS_NOHSCROLL; + OS.SetWindowLong (handle, OS.GWL_STYLE, bits); + OS.InvalidateRect (handle, null, true); + } } else { if (index == 0) { columns [0].style &= ~(SWT.LEFT | SWT.RIGHT | SWT.CENTER); @@ -1158,6 +1189,7 @@ void destroyItem (TreeItem item, int hItem) { imageList = null; if (hwndParent == 0 && !linesVisible) customDraw = false; items = new TreeItem [4]; + scrollWidth = 0; } updateScrollBar (); } @@ -1465,7 +1497,7 @@ public int getColumnCount () { public int[] getColumnOrder () { checkWidget (); if (hwndHeader == 0) return new int [0]; - int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0 ); + int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); int [] order = new int [count]; OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, count, order); return order; @@ -2182,6 +2214,7 @@ public void removeAll () { hAnchor = hInsert = hFirstIndexOf = hLastIndexOf = 0; items = new TreeItem [4]; updateScrollBar (); + scrollWidth = 0; } /** @@ -2758,12 +2791,18 @@ void setScrollWidth () { OS.SendMessage (hwndHeader, OS.HDM_GETITEM, i, hdItem); width += hdItem.cxy; } + setScrollWidth (Math.max (scrollWidth, width)); +} + +void setScrollWidth (int width) { + if (hwndHeader == 0 || hwndParent == 0) return; + scrollWidth = width; int left = 0; RECT rect = new RECT (); SCROLLINFO info = new SCROLLINFO (); info.cbSize = SCROLLINFO.sizeof; info.fMask = OS.SIF_RANGE | OS.SIF_PAGE; - if (count == 0) { + if (width == 0) { OS.GetScrollInfo (hwndParent, OS.SB_HORZ, info); info.nPage = info.nMax + 1; OS.SetScrollInfo (hwndParent, OS.SB_HORZ, info, true); @@ -2792,7 +2831,7 @@ void setScrollWidth () { if (playout.prc != 0) OS.HeapFree (hHeap, 0, playout.prc); if (playout.pwpos != 0) OS.HeapFree (hHeap, 0, playout.pwpos); SetWindowPos (hwndHeader, OS.HWND_TOP, pos.x - left, pos.y, pos.cx + left, pos.cy, OS.SWP_NOACTIVATE); - int w = pos.cx + (count == 0 ? 0 : OS.GetSystemMetrics (OS.SM_CXVSCROLL)); + int w = pos.cx + (width == 0 ? 0 : OS.GetSystemMetrics (OS.SM_CXVSCROLL)); int h = rect.bottom - rect.top - pos.cy; boolean oldIgnore = ignoreResize; ignoreResize = true; @@ -3639,10 +3678,10 @@ LRESULT WM_KEYDOWN (int wParam, int lParam) { int hDeselectItem = hItem; RECT rect1 = new RECT (); rect1.left = hAnchor; - OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect1); + OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, rect1); RECT rect2 = rect2 = new RECT (); rect2.left = hDeselectItem; - OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect2); + OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, rect2); int flags = rect1.top < rect2.top ? OS.TVGN_PREVIOUSVISIBLE : OS.TVGN_NEXTVISIBLE; while (hDeselectItem != hAnchor) { tvItem.hItem = hDeselectItem; @@ -3651,9 +3690,9 @@ LRESULT WM_KEYDOWN (int wParam, int lParam) { } int hSelectItem = hAnchor; rect1.left = hNewItem; - OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect1); + OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, rect1); rect2.left = hSelectItem; - OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect2); + OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, rect2); tvItem.state = OS.TVIS_SELECTED; flags = rect1.top < rect2.top ? OS.TVGN_PREVIOUSVISIBLE : OS.TVGN_NEXTVISIBLE; while (hSelectItem != hNewItem) { @@ -3707,7 +3746,7 @@ LRESULT WM_KEYDOWN (int wParam, int lParam) { int hVisible = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, hNewItem); if (hVisible == 0) break; rect.left = hVisible; - OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect); + OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, rect); if (rect.bottom > clientRect.bottom) break; if ((hNewItem = hVisible) == hItem) { OS.SendMessage (handle, OS.WM_VSCROLL, OS.SB_PAGEDOWN, 0); @@ -3749,6 +3788,7 @@ LRESULT WM_KEYDOWN (int wParam, int lParam) { rect1.left = hItem; rect2.left = hNewItem; int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); int fItemRect = (bits & OS.TVS_FULLROWSELECT) != 0 ? 0 : 1; + if (hooks (SWT.EraseItem) || hooks (SWT.PaintItem)) fItemRect = 0; OS.SendMessage (handle, OS.TVM_GETITEMRECT, fItemRect, rect1); OS.SendMessage (handle, OS.TVM_GETITEMRECT, fItemRect, rect2); /* @@ -3756,15 +3796,9 @@ LRESULT WM_KEYDOWN (int wParam, int lParam) { */ // OS.SendMessage (handle, OS.WM_SETREDRAW, 1, 0); OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); - if (OS.IsWinCE) { - OS.InvalidateRect (handle, rect1, false); - OS.InvalidateRect (handle, rect2, false); - OS.UpdateWindow (handle); - } else { - int flags = OS.RDW_UPDATENOW | OS.RDW_INVALIDATE; - OS.RedrawWindow (handle, rect1, 0, flags); - OS.RedrawWindow (handle, rect2, 0, flags); - } + OS.InvalidateRect (handle, rect1, true); + OS.InvalidateRect (handle, rect2, true); + OS.UpdateWindow (handle); } return LRESULT.ZERO; } @@ -4065,6 +4099,7 @@ LRESULT WM_LBUTTONDOWN (int wParam, int lParam) { rect1.left = hOldItem; rect2.left = hNewItem; int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); int fItemRect = (bits & OS.TVS_FULLROWSELECT) != 0 ? 0 : 1; + if (hooks (SWT.EraseItem) || hooks (SWT.PaintItem)) fItemRect = 0; OS.SendMessage (handle, OS.TVM_GETITEMRECT, fItemRect, rect1); OS.SendMessage (handle, OS.TVM_GETITEMRECT, fItemRect, rect2); /* @@ -4072,15 +4107,9 @@ LRESULT WM_LBUTTONDOWN (int wParam, int lParam) { */ // OS.SendMessage (handle, OS.WM_SETREDRAW, 1, 0); OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); - if (OS.IsWinCE) { - OS.InvalidateRect (handle, rect1, false); - OS.InvalidateRect (handle, rect2, false); - OS.UpdateWindow (handle); - } else { - int flags = OS.RDW_UPDATENOW | OS.RDW_INVALIDATE; - OS.RedrawWindow (handle, rect1, 0, flags); - OS.RedrawWindow (handle, rect2, 0, flags); - } + OS.InvalidateRect (handle, rect1, true); + OS.InvalidateRect (handle, rect2, true); + OS.UpdateWindow (handle); } } @@ -4110,10 +4139,10 @@ LRESULT WM_LBUTTONDOWN (int wParam, int lParam) { RECT rect1 = new RECT (); if (hAnchor == 0) hAnchor = hNewItem; rect1.left = hAnchor; - if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect1) != 0) { + if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, rect1) != 0) { RECT rect2 = rect2 = new RECT (); rect2.left = hNewItem; - OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect2); + OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, rect2); int flags = rect1.top < rect2.top ? OS.TVGN_NEXTVISIBLE : OS.TVGN_PREVIOUSVISIBLE; tvItem.state = OS.TVIS_SELECTED; int hItem = tvItem.hItem = hAnchor; @@ -4662,9 +4691,7 @@ LRESULT wmNotifyChild (int wParam, int lParam) { } case OS.NM_CUSTOMDRAW: { if (hdr.hwndFrom == hwndHeader) break; - if (!customDraw) { - if (findImageControl () == null) break; - } + if (!customDraw && findImageControl () == null) break; NMTVCUSTOMDRAW nmcd = new NMTVCUSTOMDRAW (); OS.MoveMemory (nmcd, lParam, NMTVCUSTOMDRAW.sizeof); switch (nmcd.dwDrawStage) { @@ -4727,94 +4754,188 @@ LRESULT wmNotifyChild (int wParam, int lParam) { */ TreeItem item = _getItem (nmcd.dwItemSpec, nmcd.lItemlParam); if (item == null) break; - if (nmcd.left >= nmcd.right || nmcd.top >= nmcd.bottom) { - break; - } + if (nmcd.left >= nmcd.right || nmcd.top >= nmcd.bottom) break; int hDC = nmcd.hdc; - OS.SaveDC (hDC); if (linesVisible) { RECT rect = new RECT (); OS.SetRect (rect, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom); OS.DrawEdge (hDC, rect, OS.BDR_SUNKENINNER, OS.BF_BOTTOM); } - int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); - if (!printClient && (bits & OS.TVS_FULLROWSELECT) == 0) { - if (hwndHeader != 0) { - int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); - if (count != 0) { - HDITEM hdItem = new HDITEM (); - hdItem.mask = OS.HDI_WIDTH; - int index = OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, 0, 0); - OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, hdItem); - int hRgn = OS.CreateRectRgn (nmcd.left, nmcd.top, nmcd.left + hdItem.cxy, nmcd.bottom); - OS.SelectClipRgn (hDC, hRgn); - OS.DeleteObject (hRgn); - } - } - } - if (item.font == -1 && item.foreground == -1 && item.background == -1) { - if (item.cellForeground == null && item.cellBackground == null && item.cellFont == null) { - return new LRESULT (OS.CDRF_DODEFAULT | OS.CDRF_NOTIFYPOSTPAINT); + int index = 0; + RECT clipRect = null; + if (hwndHeader != 0) { + index = OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, 0, 0); + int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); + if (count != 0) { + clipRect = new RECT (); + HDITEM hdItem = new HDITEM (); + hdItem.mask = OS.HDI_WIDTH; + OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, hdItem); + OS.SetRect (clipRect, nmcd.left, nmcd.top, nmcd.left + hdItem.cxy, nmcd.bottom); } } - int hFont = item.cellFont != null ? item.cellFont [0] : -1; + int clrText = -1, clrTextBk = -1; + int hFont = item.cellFont != null ? item.cellFont [index] : -1; if (hFont == -1) hFont = item.font; - if (hFont != -1) OS.SelectObject (hDC, hFont); if (OS.IsWindowEnabled (handle)) { - boolean useColor = true; + clrText = item.cellForeground != null ? item.cellForeground [index] : -1; + if (clrText == -1) clrText = item.foreground; + clrTextBk = item.cellBackground != null ? item.cellBackground [index] : -1; + if (clrTextBk == -1) clrTextBk = item.background; + } + /* + * Feature in Windows. When the mouse is pressed and the + * selection is first drawn for a tree, the previously + * selected item is redrawn but the the TVIS_SELECTED bits + * are not cleared. When the user moves the mouse slightly + * and a drag and drop operation is not started, the item is + * drawn again and this time with TVIS_SELECTED is cleared. + * This means that an item that contains colored cells will + * not draw with the correct background until the mouse is + * moved. The fix is to test for the selection colors and + * guess that the item is not selected. + * + * NOTE: This code does not work when the foreground and + * background of the tree are set to the selection colors + * but this does not happen in a regular application. + */ + boolean selected = false; + if (OS.IsWindowEnabled (handle)) { TVITEM tvItem = new TVITEM (); tvItem.mask = OS.TVIF_STATE; tvItem.hItem = item.handle; OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem); if ((tvItem.state & (OS.TVIS_SELECTED | OS.TVIS_DROPHILITED)) != 0) { - useColor = false; - /* - * Feature in Windows. When the mouse is pressed and the - * selection is first drawn for a tree, the previously - * selected item is redrawn but the the TVIS_SELECTED bits - * are not cleared. When the user moves the mouse slightly - * and a drag and drop operation is not started, the item is - * drawn again and this time with TVIS_SELECTED is cleared. - * This means that an item that contains colored cells will - * not draw with the correct background until the mouse is - * moved. The fix is to test for the selection colors and - * guess that the item is not selected. - * - * NOTE: This code does not work when the foreground and - * background of the tree are set to the selection colors - * but this does not happen in a regular application. - */ + selected = true; if (handle == OS.GetFocus ()) { if (OS.GetTextColor (hDC) != OS.GetSysColor (OS.COLOR_HIGHLIGHTTEXT)) { - useColor = true; + selected = false; } else { if (OS.GetBkColor (hDC) != OS.GetSysColor (OS.COLOR_HIGHLIGHT)) { - useColor = true; + selected = false; } } } } - int clrText = item.cellForeground != null ? item.cellForeground [0] : -1; - if (clrText == -1) clrText = item.foreground; - nmcd.clrText = clrText == -1 ? getForegroundPixel () : clrText; - int clrTextBk = item.cellBackground != null ? item.cellBackground [0] : -1; - if (clrTextBk == -1) clrTextBk = item.background; - if (clrTextBk == -1) { - Control control = findBackgroundControl (); - if (control == null) control = this; - if (control.backgroundImage == null) { - nmcd.clrTextBk = control.getBackgroundPixel (); + } + //TODO - BUG - measure and erase sent when first column is clipped + if (hooks (SWT.MeasureItem)) { + RECT itemRect = item.getBounds (index, true, true, false, false, false, hDC); + int nSavedDC = OS.SaveDC (hDC); + GCData data = new GCData (); + data.device = display; + data.hFont = hFont; + GC gc = GC.win32_new (hDC, data); + Event event = new Event (); + event.item = item; + event.gc = gc; + event.index = index; + event.x = itemRect.left; + event.y = itemRect.top; + event.width = itemRect.right - itemRect.left; + event.height = itemRect.bottom - itemRect.top; + sendEvent (SWT.MeasureItem, event); + event.gc = null; + gc.dispose (); + OS.RestoreDC (hDC, nSavedDC); + if (isDisposed () || item.isDisposed ()) break; + if (hwndHeader != 0) { + int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); + if (count == 0) { + if (event.x + event.width > scrollWidth) { + setScrollWidth (event.x + event.width); + } + } + } + if (!ignoreItemHeight) { + int itemHeight = OS.SendMessage (handle, OS.TVM_GETITEMHEIGHT, 0, 0); + if (event.height > itemHeight) { + OS.SendMessage (handle, OS.TVM_SETITEMHEIGHT, event.height, 0); + } + ignoreItemHeight = true; + } + } + ignoreDraw = ignoreDrawSelected = false; + if (hooks (SWT.EraseItem)) { + RECT cellRect = item.getBounds (index, true, true, true, true, true, hDC); + int nSavedDC = OS.SaveDC (hDC); + GCData data = new GCData (); + data.device = display; + data.foreground = clrText != -1 ? clrText : OS.GetTextColor (hDC); + data.background = clrTextBk != -1 ? clrTextBk : OS.GetBkColor (hDC); + data.hPen = OS.CreatePen (OS.PS_SOLID, 0, data.foreground); + data.hBrush = OS.CreateSolidBrush (data.background); + if (hFont != -1) data.hFont = hFont; + OS.SelectObject (hDC, data.hPen); + OS.SelectObject (hDC, data.hBrush); + GC gc = GC.win32_new (hDC, data); + Event event = new Event (); + event.index = index; + event.item = item; + event.gc = gc; + if (selected) event.detail |= SWT.SELECTED; + if ((nmcd.uItemState & OS.CDIS_FOCUS) != 0) event.detail |= SWT.FOCUSED; + event.x = cellRect.left; + event.y = cellRect.top; + event.width = cellRect.right - cellRect.left; + event.height = cellRect.bottom - cellRect.top; + if (hwndHeader != 0) { + int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); + if (count == 0) event.width = Math.max (event.width, scrollWidth); + } + event.height = cellRect.bottom - cellRect.top; + gc.setClipping (event.x, event.y, event.width, event.height); + sendEvent (SWT.EraseItem, event); + event.gc = null; + gc.dispose (); + OS.RestoreDC (hDC, nSavedDC); + if (isDisposed () || item.isDisposed ()) break; + ignoreDraw = !event.doit; + RECT textRect = item.getBounds (index, true, false, false, false, true, hDC); + if (event.doit) { + if ((event.detail & SWT.SELECTED) != 0) { + drawBackground (hDC, textRect, OS.GetBkColor (hDC)); + } else { + ignoreDrawSelected = true; } - } else { - nmcd.clrTextBk = clrTextBk; } + RECT itemRect = item.getBounds (index, true, true, false, false, false, hDC); + OS.SaveDC (hDC); + OS.SelectClipRgn (hDC, 0); + //TODO - bug in Windows selection or SWT itemRect + /*if (selected)*/ itemRect.right++; + if (linesVisible) itemRect.bottom++; + if (clipRect != null) { + OS.IntersectClipRect (hDC, clipRect.left, clipRect.top, clipRect.right, clipRect.bottom); + } + OS.ExcludeClipRect (hDC, itemRect.left, itemRect.top, itemRect.right, itemRect.bottom); + return new LRESULT (OS.CDRF_DODEFAULT | OS.CDRF_NOTIFYPOSTPAINT); + } + OS.SaveDC (hDC); + int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); + if (clipRect != null) { + if (!printClient && (bits & OS.TVS_FULLROWSELECT) == 0) { + int hRgn = OS.CreateRectRgn (clipRect.left, clipRect.top, clipRect.right, clipRect.bottom); + OS.SelectClipRgn (hDC, hRgn); + OS.DeleteObject (hRgn); + } + } + if (clrText == -1 && clrTextBk == -1 && hFont == -1) { + return new LRESULT (OS.CDRF_DODEFAULT | OS.CDRF_NOTIFYPOSTPAINT); + } + if (hFont != -1) OS.SelectObject (hDC, hFont); + if (OS.IsWindowEnabled (handle)) { + /* + * Feature in Windows. Windows does not fill the entire cell + * with the background color when TVS_FULLROWSELECT is not set. + * The fix is to fill it, event when the item is selected. + */ if ((bits & OS.TVS_FULLROWSELECT) == 0) { if (hwndHeader != 0) { int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); if (count != 0) { HDITEM hdItem = new HDITEM (); hdItem.mask = OS.HDI_WIDTH; - int index = OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, 0, 0); OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, hdItem); RECT rect = new RECT (); OS.SetRect (rect, nmcd.left, nmcd.top, nmcd.left + hdItem.cxy, nmcd.bottom); @@ -4825,18 +4946,15 @@ LRESULT wmNotifyChild (int wParam, int lParam) { rect.left = Math.min (itemRect.left, rect.right); } } - if (clrTextBk == -1) { - Control control = findImageControl (); - if (control != null) { - fillImageBackground (hDC, control, rect); - } - } else { - fillBackground (hDC, nmcd.clrTextBk, rect); - } + if (clrTextBk != -1) fillBackground (hDC, clrTextBk, rect); } } } - if (useColor) OS.MoveMemory (lParam, nmcd, NMTVCUSTOMDRAW.sizeof); + if (!selected) { + nmcd.clrText = clrText == -1 ? getForegroundPixel () : clrText; + nmcd.clrTextBk = clrTextBk == -1 ? getBackgroundPixel () : clrTextBk; + OS.MoveMemory (lParam, nmcd, NMTVCUSTOMDRAW.sizeof); + } } return new LRESULT (OS.CDRF_NEWFONT | OS.CDRF_NOTIFYPOSTPAINT); } @@ -4854,227 +4972,320 @@ LRESULT wmNotifyChild (int wParam, int lParam) { * and LPSTR_TEXTCALLBACK are used at the same time with * TVM_SETITEM. */ - if (nmcd.left >= nmcd.right || nmcd.top >= nmcd.bottom) { - break; - } + if (nmcd.left >= nmcd.right || nmcd.top >= nmcd.bottom) break; int hDC = nmcd.hdc; OS.RestoreDC (hDC, -1); OS.SetBkMode (hDC, OS.TRANSPARENT); int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); - boolean useColor = OS.IsWindowEnabled (handle); - if (useColor) { - if ((bits & OS.TVS_FULLROWSELECT) != 0) { - TVITEM tvItem = new TVITEM (); - tvItem.mask = OS.TVIF_STATE; - tvItem.hItem = item.handle; - OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem); - if ((tvItem.state & (OS.TVIS_SELECTED | OS.TVIS_DROPHILITED)) != 0) { - useColor = false; - /* - * Feature in Windows. When the mouse is pressed and the - * selection is first drawn for a tree, the previously - * selected item is redrawn but the the TVIS_SELECTED bits - * are not cleared. When the user moves the mouse slightly - * and a drag and drop operation is not started, the item is - * drawn again and this time with TVIS_SELECTED is cleared. - * This means that an item that contains colored cells will - * not draw with the correct background until the mouse is - * moved. The fix is to test for the selection colors and - * guess that the item is not selected. - * - * NOTE: This code does not work when the foreground and - * background of the tree are set to the selection colors - * but this does not happen in a regular application. - */ - if (handle == OS.GetFocus ()) { - if (OS.GetTextColor (hDC) != OS.GetSysColor (OS.COLOR_HIGHLIGHTTEXT)) { - useColor = true; - } else { - if (OS.GetBkColor (hDC) != OS.GetSysColor (OS.COLOR_HIGHLIGHT)) { - useColor = true; - } + boolean selected = false; + if (OS.IsWindowEnabled (handle)) { + TVITEM tvItem = new TVITEM (); + tvItem.mask = OS.TVIF_STATE; + tvItem.hItem = item.handle; + OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem); + if ((tvItem.state & (OS.TVIS_SELECTED | OS.TVIS_DROPHILITED)) != 0) { + selected = true; + /* + * Feature in Windows. When the mouse is pressed and the + * selection is first drawn for a tree, the previously + * selected item is redrawn but the the TVIS_SELECTED bits + * are not cleared. When the user moves the mouse slightly + * and a drag and drop operation is not started, the item is + * drawn again and this time with TVIS_SELECTED is cleared. + * This means that an item that contains colored cells will + * not draw with the correct background until the mouse is + * moved. The fix is to test for the selection colors and + * guess that the item is not selected. + * + * NOTE: This code does not work when the foreground and + * background of the tree are set to the selection colors + * but this does not happen in a regular application. + */ + if (handle == OS.GetFocus ()) { + if (OS.GetTextColor (hDC) != OS.GetSysColor (OS.COLOR_HIGHLIGHTTEXT)) { + selected = false; + } else { + if (OS.GetBkColor (hDC) != OS.GetSysColor (OS.COLOR_HIGHLIGHT)) { + selected = false; } } - } else { - /* - * Feature in Windows. When the mouse is pressed and the - * selection is first drawn for a tree, the item is drawn - * selected, but the TVIS_SELECTED bits for the item are - * not set. When the user moves the mouse slightly and - * a drag and drop operation is not started, the item is - * drawn again and this time TVIS_SELECTED is set. This - * means that an item that is in a tree that has the style - * TVS_FULLROWSELECT and that also contains colored cells - * will not draw the entire row selected until the user - * moves the mouse. The fix is to test for the selection - * colors and guess that the item is selected. - * - * NOTE: This code does not work when the foreground and - * background of the tree are set to the selection colors - * but this does not happen in a regular application. - */ - if (OS.GetTextColor (hDC) == OS.GetSysColor (OS.COLOR_HIGHLIGHTTEXT)) { - if (OS.GetBkColor (hDC) == OS.GetSysColor (OS.COLOR_HIGHLIGHT)) { - useColor = false; - } + } + } else { + /* + * Feature in Windows. When the mouse is pressed and the + * selection is first drawn for a tree, the item is drawn + * selected, but the TVIS_SELECTED bits for the item are + * not set. When the user moves the mouse slightly and + * a drag and drop operation is not started, the item is + * drawn again and this time TVIS_SELECTED is set. This + * means that an item that is in a tree that has the style + * TVS_FULLROWSELECT and that also contains colored cells + * will not draw the entire row selected until the user + * moves the mouse. The fix is to test for the selection + * colors and guess that the item is selected. + * + * NOTE: This code does not work when the foreground and + * background of the tree are set to the selection colors + * but this does not happen in a regular application. + */ + if (OS.GetTextColor (hDC) == OS.GetSysColor (OS.COLOR_HIGHLIGHTTEXT)) { + if (OS.GetBkColor (hDC) == OS.GetSysColor (OS.COLOR_HIGHLIGHT)) { + selected = true; } } } } - GCData data = new GCData(); - data.device = display; - GC gc = GC.win32_new (hDC, data); + int count = 0; + int [] order = null; + RECT clientRect = new RECT (); + OS.GetClientRect (scrolledHandle (), clientRect); + if (hwndHeader != 0) { + OS.MapWindowPoints (hwndParent, handle, clientRect, 2); + count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); + if (count != 0) { + order = new int [count]; + OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, count, order); + } + } + Point size = null; int x = 0, gridWidth = linesVisible ? GRID_WIDTH : 0; - Point size = null; - int count = hwndHeader != 0 ? OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0) : 0; for (int i=0; i<Math.max (1, count); i++) { - boolean drawItem = true; - int index = i, width = nmcd.right - nmcd.left; + int index = order == null ? i : order [i], width = nmcd.right - nmcd.left; if (count > 0 && hwndHeader != 0) { HDITEM hdItem = new HDITEM (); hdItem.mask = OS.HDI_WIDTH; - index = OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, i, 0); OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, hdItem); width = hdItem.cxy; } - RECT rect = new RECT (); - if (i == 0) { - drawItem = false; - if (useColor) { - Control control = findBackgroundControl (); - if (control != null && control.backgroundImage != null) { - /* - * Feature in Windows. When the mouse is pressed in a - * single select tree, the previous item is no longer - * selected, but the TVIS_SELECTED bits for that item - * are not set. The fix is to test for the selection - * colors and guess that the item is selected. - * - * NOTE: This code does not work when the foreground and - * background of the tree are set to the selection colors - * but this does not happen in a regular application. - */ - boolean selected = false; - if ((style & SWT.SINGLE) != 0) { - if (OS.GetTextColor (hDC) == OS.GetSysColor (OS.COLOR_HIGHLIGHTTEXT)) { - if (OS.GetBkColor (hDC) == OS.GetSysColor (OS.COLOR_HIGHLIGHT)) { - selected = true; - } - } - } else { - TVITEM tvItem = new TVITEM (); - tvItem.mask = OS.TVIF_STATE; - tvItem.hItem = item.handle; - OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem); - selected = (tvItem.state & (OS.TVIS_SELECTED | OS.TVIS_DROPHILITED)) != 0; + if (x + width > clientRect.left) { + RECT rect = new RECT (); + boolean drawItem = true, drawText = true, drawImage = true, drawBackground = true; + if (i == 0) { + drawItem = drawImage = drawText = drawBackground = false; + Control control = findImageControl (); + if (control != null) { + rect.left = item.handle; + if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect) != 0) { + drawItem = drawText = drawBackground = true; } - if (!selected) { - rect.left = item.handle; - if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect) != 0) { - drawItem = true; - } + rect.bottom -= gridWidth; + } + if (selected && !ignoreDraw && !ignoreDrawSelected) { + fillBackground (hDC, OS.GetBkColor (hDC), rect); + drawBackground = false; + } + if (hooks (SWT.EraseItem)) { + drawItem = drawText = drawImage = true; + rect = item.getBounds (index, true, true, false, false, true, hDC); + } + } else { + ignoreDraw = ignoreDrawSelected = false; + if (OS.IsWindowEnabled (handle)) { + /* set the default colors for the row */ + if ((bits & OS.TVS_FULLROWSELECT) == 0) { + OS.SetTextColor (hDC, getForegroundPixel ()); + OS.SetBkColor (hDC, getBackgroundPixel ()); } } - if (control == null) control = this; - OS.SetTextColor (hDC, getForegroundPixel ()); - OS.SetBkColor (hDC, control.getBackgroundPixel ()); + OS.SetRect (rect, x, nmcd.top, x + width, nmcd.bottom - gridWidth); } - } else { - OS.SetRect (rect, x, nmcd.top, x + width, nmcd.bottom - gridWidth); - } - if (drawItem) { - int clrTextBk = -1; - if (useColor) { - clrTextBk = item.cellBackground != null ? item.cellBackground [index] : -1; - if (clrTextBk == -1) clrTextBk = item.background; + int clrText = -1, clrTextBk = -1; + int hFont = item.cellFont != null ? item.cellFont [index] : -1; + if (hFont == -1) hFont = item.font; + if (OS.IsWindowEnabled (handle)) { + if (!selected || (index != 0 && (bits & OS.TVS_FULLROWSELECT) == 0)) { + clrText = item.cellForeground != null ? item.cellForeground [index] : -1; + if (clrText == -1) clrText = item.foreground; + clrTextBk = item.cellBackground != null ? item.cellBackground [index] : -1; + if (clrTextBk == -1) clrTextBk = item.background; + } } + /* needed or tree expand draws in the next column */ if (clrTextBk == -1) { if (printClient || (bits & OS.TVS_FULLROWSELECT) != 0) { clrTextBk = OS.GetBkColor (hDC); } } - if (clrTextBk != -1) { - fillBackground (hDC, clrTextBk, rect); - } else { - Control control = findImageControl (); - if (control != null) { - if (i == 0 && (bits & OS.TVS_FULLROWSELECT) == 0) { - int right = Math.min (rect.right, width); - OS.SetRect (rect, rect.left, rect.top, right, rect.bottom); - fillImageBackground (hDC, control, rect); - if (handle == OS.GetFocus ()) { - int uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0); - if ((uiState & OS.UISF_HIDEFOCUS) == 0) { - int hItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); - if (hItem == item.handle) OS.DrawFocusRect (hDC, rect); + if (drawItem) { + if (drawBackground && !ignoreDraw && !ignoreDrawSelected) { + if (clrTextBk != -1) { + fillBackground (hDC, clrTextBk, rect); + } else { + Control control = findImageControl (); + if (control != null) { + if (i == 0 && (bits & OS.TVS_FULLROWSELECT) == 0) { + int right = Math.min (rect.right, width); + OS.SetRect (rect, rect.left, rect.top, right, rect.bottom); + fillImageBackground (hDC, control, rect); + if (handle == OS.GetFocus ()) { + int uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0); + if ((uiState & OS.UISF_HIDEFOCUS) == 0) { + int hItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); + if (hItem == item.handle) OS.DrawFocusRect (hDC, rect); + } + } + rect.left = Math.min (rect.right, rect.left + 2); + } else { + fillImageBackground (hDC, control, rect); } } - rect.left = Math.min (rect.right, rect.left + 2); - } else { - fillImageBackground (hDC, control, rect); } } - } - if (i > 0) { - Image image = null; - if (index == 0) { - image = item.image; - } else { - Image [] images = item.images; - if (images != null) image = images [index]; - } - if (image != null) { - Rectangle bounds = image.getBounds (); - if (size == null) size = getImageSize (); - gc.drawImage (image, 0, 0, bounds.width, bounds.height, rect.left, rect.top, size.x, size.y); - OS.SetRect (rect, rect.left + size.x + INSET, rect.top, rect.right - INSET, rect.bottom); - } else { - OS.SetRect (rect, rect.left + INSET, rect.top, rect.right - INSET, rect.bottom); - } - } - /* - * Bug in Windows. When DrawText() is used with DT_VCENTER - * and DT_ENDELLIPSIS, the ellipsis can draw outside of the - * rectangle when the rectangle is empty. The fix is avoid - * all text drawing for empty rectangles. - */ - if (rect.left < rect.right) { - String string = null; - if (index == 0) { - string = item.text; - } else { - String [] strings = item.strings; - if (strings != null) string = strings [index]; + if (i != 0) { + if (hooks (SWT.MeasureItem)) { + RECT itemRect = item.getBounds (index, true, true, false, false, false, hDC); + int nSavedDC = OS.SaveDC (hDC); + GCData data = new GCData (); + data.device = display; + data.hFont = hFont; + GC gc = GC.win32_new (hDC, data); + Event event = new Event (); + event.item = item; + event.index = index; + event.gc = gc; + event.x = itemRect.left; + event.y = itemRect.top; + event.width = itemRect.right - itemRect.left; + event.height = itemRect.bottom - itemRect.top; + sendEvent (SWT.MeasureItem, event); + event.gc = null; + gc.dispose (); + OS.RestoreDC (hDC, nSavedDC); + if (isDisposed () || item.isDisposed ()) break; + } + if (hooks (SWT.EraseItem)) { + RECT cellRect = item.getBounds (index, true, true, true, true, true, hDC); + int nSavedDC = OS.SaveDC (hDC); + GCData data = new GCData (); + data.device = display; + data.foreground = clrText != -1 ? clrText : OS.GetTextColor (hDC); + data.background = clrTextBk != -1 ? clrTextBk : OS.GetBkColor (hDC); + data.hPen = OS.CreatePen (OS.PS_SOLID, 0, data.foreground); + data.hBrush = OS.CreateSolidBrush (data.background); + data.hFont = hFont; + GC gc = GC.win32_new (hDC, data); + Event event = new Event (); + event.item = item; + event.index = index; + event.gc = gc; + if (selected) event.detail |= SWT.SELECTED; + if ((nmcd.uItemState & OS.CDIS_FOCUS) != 0) event.detail |= SWT.FOCUSED; + event.x = cellRect.left; + event.y = cellRect.top; + event.width = cellRect.right - cellRect.left; + event.height = cellRect.bottom - cellRect.top; + gc.setClipping (event.x, event.y, event.width, event.height); + sendEvent (SWT.EraseItem, event); + event.gc = null; + gc.dispose (); + OS.RestoreDC (hDC, nSavedDC); + if (isDisposed () || item.isDisposed ()) break; + ignoreDraw = !event.doit; + } } - if (string != null) { - int hFont = item.cellFont != null ? item.cellFont [index] : -1; - if (hFont == -1) hFont = item.font; - hFont = hFont != -1 ? OS.SelectObject (hDC, hFont) : -1; - int clrText = -1; - if (useColor) { - clrText = item.cellForeground != null ? item.cellForeground [index] : -1; - if (clrText == -1) clrText = item.foreground; - clrText = clrText != -1 ? OS.SetTextColor (hDC, clrText) : -1; + if (drawImage) { + Image image = null; + if (index == 0) { + image = item.image; + } else { + Image [] images = item.images; + if (images != null) image = images [index]; } - int oldMode = clrTextBk != -1 ? OS.SetBkMode (hDC, OS.TRANSPARENT) : -1; - int flags = OS.DT_NOPREFIX | OS.DT_SINGLELINE | OS.DT_VCENTER; - if (i != 0) flags |= OS.DT_ENDELLIPSIS; - flags |= OS.DT_LEFT; - TreeColumn column = columns != null ? columns [index] : null; - if (column != null) { - if ((column.style & SWT.LEFT) != 0) flags |= OS.DT_LEFT; - if ((column.style & SWT.CENTER) != 0) flags |= OS.DT_CENTER; - if ((column.style & SWT.RIGHT) != 0) flags |= OS.DT_RIGHT; + int inset = i != 0 ? INSET : 0; + if (image != null) { + Rectangle bounds = image.getBounds (); + if (size == null) size = getImageSize (); + //int y = rect.top + (index == 0 ? (getItemHeight () - size.y) / 2 : 0); + int y = rect.top; + if (!ignoreDraw) { + //TODO - share GC, clip the drawing for index == 0 + GCData data = new GCData(); + data.device = display; + GC gc = GC.win32_new (hDC, data); + //if (index == 0) { //must clear + //gc.setClipping (rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); + //} + gc.drawImage (image, 0, 0, bounds.width, bounds.height, rect.left, y, size.x, size.y); + gc.dispose (); + } + OS.SetRect (rect, rect.left + size.x + INSET, rect.top, rect.right - inset, rect.bottom); + } else { + OS.SetRect (rect, rect.left + INSET, rect.top, rect.right - inset, rect.bottom); + } + } + if (drawText) { + /* + * Bug in Windows. When DrawText() is used with DT_VCENTER + * and DT_ENDELLIPSIS, the ellipsis can draw outside of the + * rectangle when the rectangle is empty. The fix is avoid + * all text drawing for empty rectangles. + */ + if (rect.left < rect.right) { + String string = null; + if (index == 0) { + string = item.text; + } else { + String [] strings = item.strings; + if (strings != null) string = strings [index]; + } + if (string != null) { + hFont = hFont != -1 ? OS.SelectObject (hDC, hFont) : -1; + clrText = clrText != -1 ? OS.SetTextColor (hDC, clrText) : -1; + int flags = OS.DT_NOPREFIX | OS.DT_SINGLELINE | OS.DT_VCENTER; + if (index != 0) flags |= OS.DT_ENDELLIPSIS; + TreeColumn column = columns != null ? columns [index] : null; + if (column != null) { + if ((column.style & SWT.CENTER) != 0) flags |= OS.DT_CENTER; + if ((column.style & SWT.RIGHT) != 0) flags |= OS.DT_RIGHT; + } + TCHAR buffer = new TCHAR (getCodePage (), string, false); + if (!ignoreDraw) OS.DrawText (hDC, buffer, buffer.length (), rect, flags); + OS.DrawText (hDC, buffer, buffer.length (), rect, flags | OS.DT_CALCRECT); + if (hFont != -1) OS.SelectObject (hDC, hFont); + if (clrText != -1) OS.SetTextColor (hDC, clrText); + } } - TCHAR buffer = new TCHAR (getCodePage (), string, false); - OS.DrawText (hDC, buffer, buffer.length (), rect, flags); - if (hFont != -1) OS.SelectObject (hDC, hFont); - if (clrText != -1) OS.SetTextColor (hDC, clrText); - if (oldMode != -1) OS.SetBkMode (hDC, oldMode); } } + if (hooks (SWT.PaintItem)) { + RECT itemRect = item.getBounds (index, true, true, false, false, false, hDC); + int nSavedDC = OS.SaveDC (hDC); + GCData data = new GCData (); + data.device = display; + data.hFont = hFont; + data.foreground = clrText != -1 ? clrText : OS.GetTextColor (hDC); + data.background = clrTextBk != -1 ? clrTextBk : OS.GetBkColor (hDC); + data.hPen = OS.CreatePen (OS.PS_SOLID, 0, data.foreground); + data.hBrush = OS.CreateSolidBrush (data.background); + OS.SelectObject (hDC, data.hPen); + OS.SelectObject (hDC, data.hBrush); + GC gc = GC.win32_new (hDC, data); + Event event = new Event (); + event.item = item; + event.index = index; + event.gc = gc; + if (selected) event.detail |= SWT.SELECTED; + if ((nmcd.uItemState & OS.CDIS_FOCUS) != 0) event.detail |= SWT.FOCUSED; + event.x = itemRect.left; + event.y = itemRect.top; + event.width = itemRect.right - itemRect.left; + event.height = itemRect.bottom - itemRect.top; + RECT cellRect = item.getBounds (index, true, true, true, true, true, hDC); + int cellWidth = cellRect.right - cellRect.left; + if (hwndHeader != 0) { + int columnCount = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); + if (columnCount == 0) cellWidth = Math.max (cellWidth, scrollWidth); + } + gc.setClipping (cellRect.left, cellRect.top, cellWidth, cellRect.bottom - cellRect.top); + sendEvent (SWT.PaintItem, event); + event.gc = null; + gc.dispose (); + OS.RestoreDC (hDC, nSavedDC); + if (isDisposed () || item.isDisposed ()) break; + } } x += width; + if (x > clientRect.right) break; } if (count > 0) { if (printClient || (bits & OS.TVS_FULLROWSELECT) != 0) { @@ -5085,7 +5296,6 @@ LRESULT wmNotifyChild (int wParam, int lParam) { //drawBackground (hDC, rect); } } - gc.dispose (); if (linesVisible) { if (printClient && (bits & OS.TVS_FULLROWSELECT) != 0) { if (hwndHeader != 0) { @@ -5121,8 +5331,8 @@ LRESULT wmNotifyChild (int wParam, int lParam) { } OS.DrawEdge (hDC, rect, OS.BDR_SUNKENINNER, OS.BF_BOTTOM); } - return new LRESULT (OS.CDRF_DODEFAULT); } + return new LRESULT (OS.CDRF_DODEFAULT); } break; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TreeColumn.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TreeColumn.java index a5a4e7ef87..66ed2e7005 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TreeColumn.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TreeColumn.java @@ -326,13 +326,12 @@ public void pack () { int index = parent.indexOf (this); if (index == -1) return; int columnWidth = 0; - int hwnd = parent.handle; + int hwnd = parent.handle, hwndHeader = parent.hwndHeader; + RECT headerRect = new RECT (); + OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, headerRect); int hDC = OS.GetDC (hwnd); int oldFont = 0, newFont = OS.SendMessage (hwnd, OS.WM_GETFONT, 0, 0); if (newFont != 0) oldFont = OS.SelectObject (hDC, newFont); - int cp = parent.getCodePage (); - RECT rect = new RECT (); - int flags = OS.DT_CALCRECT | OS.DT_NOPREFIX; TVITEM tvItem = new TVITEM (); tvItem.mask = OS.TVIF_PARAM; tvItem.hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); @@ -340,46 +339,43 @@ public void pack () { OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, tvItem); TreeItem item = tvItem.lParam != -1 ? parent.items [tvItem.lParam] : null; if (item != null) { - int hFont = -1; - if (item.cellFont != null) hFont = item.cellFont [index]; + int hFont = item.cellFont != null ? item.cellFont [index] : -1; if (hFont == -1) hFont = item.font; - if (index == 0) { - if ((parent.style & SWT.VIRTUAL) == 0 && !item.cached && !parent.painted) { - tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_TEXT; - tvItem.pszText = OS.LPSTR_TEXTCALLBACK; - OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, tvItem); - tvItem.mask = OS.TVIF_PARAM; - } - rect.left = item.handle; - if (OS.SendMessage (hwnd, OS.TVM_GETITEMRECT, 1, rect) != 0) { - columnWidth = Math.max (columnWidth, rect.right); - } - } else { - int imageWidth = 0, textWidth = 0; - Image image = item.images != null ? item.images [index] : null; - if (image != null) { - Rectangle bounds = image.getBounds (); - imageWidth = bounds.width; - } - String string = item.strings != null ? item.strings [index] : null; - if (string != null) { - TCHAR buffer = new TCHAR (cp, string, false); - if (hFont != -1) hFont = OS.SelectObject (hDC, hFont); - OS.DrawText (hDC, buffer, buffer.length (), rect, flags); - if (hFont != -1) OS.SelectObject (hDC, hFont); - textWidth = rect.right - rect.left; - } - columnWidth = Math.max (columnWidth, imageWidth + textWidth + Tree.INSET * 3); + if (hFont != -1) hFont = OS.SelectObject (hDC, hFont); + RECT itemRect = item.getBounds (index, true, true, false, false, false, hDC); + if (hFont != -1) OS.SelectObject (hDC, hFont); + if (parent.hooks (SWT.MeasureItem)) { + int nSavedDC = OS.SaveDC (hDC); + GCData data = new GCData (); + data.device = display; + data.hFont = hFont; + GC gc = GC.win32_new (hDC, data); + Event event = new Event (); + event.item = item; + event.gc = gc; + event.index = index; + event.x = itemRect.left; + event.y = itemRect.top; + event.width = itemRect.right - itemRect.left; + event.height = itemRect.bottom - itemRect.top; + parent.sendEvent (SWT.MeasureItem, event); + event.gc = null; + gc.dispose (); + OS.RestoreDC (hDC, nSavedDC); + if (isDisposed () || parent.isDisposed ()) break; + //itemRect.left = event.x; + itemRect.right = event.x + event.width; } + columnWidth = Math.max (columnWidth, itemRect.right - headerRect.left); } tvItem.hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, tvItem.hItem); } - TCHAR buffer = new TCHAR (cp, text, false); + RECT rect = new RECT (); + int flags = OS.DT_CALCRECT | OS.DT_NOPREFIX; + TCHAR buffer = new TCHAR (parent.getCodePage (), text, false); OS.DrawText (hDC, buffer, buffer.length (), rect, flags); int headerWidth = rect.right - rect.left + Tree.HEADER_MARGIN; - if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { - headerWidth += Tree.HEADER_EXTRA; - } + if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) headerWidth += Tree.HEADER_EXTRA; if (image != null || parent.sortColumn == this) { Image headerImage = null; if (parent.sortColumn == this && parent.sortDirection != SWT.NULL) { @@ -395,7 +391,7 @@ public void pack () { Rectangle bounds = headerImage.getBounds (); headerWidth += bounds.width; } - int margin = 0, hwndHeader = parent.hwndHeader; + int margin = 0; if (hwndHeader != 0 && OS.COMCTL32_VERSION >= OS.VERSION (5, 80)) { margin = OS.SendMessage (hwndHeader, OS.HDM_GETBITMAPMARGIN, 0, 0); } else { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TreeItem.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TreeItem.java index 598a84b686..601d9e44de 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TreeItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TreeItem.java @@ -401,11 +401,15 @@ public Rectangle getBounds (int index) { return new Rectangle (rect.left, rect.top, width, height); } -//TODO - take into account grid (add boolean arg) to damage less during redraw RECT getBounds (int index, boolean getText, boolean getImage, boolean full) { + return getBounds (index, getText, getImage, full, false, true, 0); +} + +//TODO - take into account grid (add boolean arg) to damage less during redraw +RECT getBounds (int index, boolean getText, boolean getImage, boolean fullText, boolean fullImage, boolean clip, int hDC) { if (!getText && !getImage) return new RECT (); + int hwnd = parent.handle; if ((parent.style & SWT.VIRTUAL) == 0 && !cached && !parent.painted) { - int hwnd = parent.handle; TVITEM tvItem = new TVITEM (); tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_TEXT; tvItem.hItem = handle; @@ -420,12 +424,11 @@ RECT getBounds (int index, boolean getText, boolean getImage, boolean full) { } RECT rect = new RECT (); if (firstColumn) { - int hwnd = parent.handle; rect.left = handle; if (OS.SendMessage (hwnd, OS.TVM_GETITEMRECT, 1, rect) == 0) { return new RECT (); } - if (getImage) { + if (getImage && !fullImage) { if (OS.SendMessage (hwnd, OS.TVM_GETIMAGELIST, OS.TVSIL_NORMAL, 0) != 0) { Point size = parent.getImageSize (); rect.left -= size.x + Tree.INSET; @@ -434,13 +437,17 @@ RECT getBounds (int index, boolean getText, boolean getImage, boolean full) { if (!getText) rect.right = rect.left; } } - if (getText && hwndHeader != 0 && columnCount != 0) { - RECT headerRect = new RECT (); - if (OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, headerRect) == 0) { - return new RECT (); - } - if (full || headerRect.right < rect.right) { - rect.right = headerRect.right; + if (fullText || fullImage || clip) { + if (hwndHeader != 0 && columnCount != 0) { + RECT headerRect = new RECT (); + if (OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, headerRect) == 0) { + return new RECT (); + } + if (fullText) rect.right = headerRect.right; + if (fullImage) rect.left = headerRect.left; + if (clip && headerRect.right < rect.right) { + rect.right = headerRect.right; + } } } } else { @@ -449,14 +456,15 @@ RECT getBounds (int index, boolean getText, boolean getImage, boolean full) { if (OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, headerRect) == 0) { return new RECT (); } - int hwnd = parent.handle; rect.left = handle; if (OS.SendMessage (hwnd, OS.TVM_GETITEMRECT, 0, rect) == 0) { return new RECT (); } rect.left = headerRect.left; - rect.right = headerRect.right; - if (!getText || !getImage) { + if (fullText) { + rect.right = headerRect.right; + } else { + rect.right = headerRect.left; Image image = null; if (index == 0) { image = this.image; @@ -465,13 +473,37 @@ RECT getBounds (int index, boolean getText, boolean getImage, boolean full) { } if (image != null) { Point size = parent.getImageSize (); - if (getImage) { - rect.right = Math.min (rect.left + size.x, rect.right); - } else { - rect.left = Math.min (rect.left + size.x, rect.right); + rect.right += size.x; + } + if (getText) { + String string = index == 0 ? text : strings != null ? strings [index] : null; + if (string != null) { + RECT textRect = new RECT (); + TCHAR buffer = new TCHAR (parent.getCodePage (), string, false); + int flags = OS.DT_NOPREFIX | OS.DT_SINGLELINE | OS.DT_CALCRECT; + int hNewDC = hDC, hFont = 0; + if (hDC == 0) { + hNewDC = OS.GetDC (hwnd); + hFont = cellFont != null ? cellFont [index] : -1; + if (hFont == -1) hFont = font; + if (hFont == -1) hFont = OS.SendMessage (hwnd, OS.WM_GETFONT, 0, 0); + hFont = OS.SelectObject (hNewDC, hFont); + } + OS.DrawText (hNewDC, buffer, buffer.length (), textRect, flags); + if (hDC == 0) { + OS.SelectObject (hNewDC, hFont); + OS.ReleaseDC (hwnd, hNewDC); + } + if (getImage) { + rect.right += textRect.right - textRect.left + Tree.INSET * 3; + } else { + rect.left = rect.right + Tree.INSET; + rect.right = rect.left + (textRect.right - textRect.left) + Tree.INSET; + } } - } else { - if (getImage) rect.right = rect.left; + } + if (clip && headerRect.right < rect.right) { + rect.right = headerRect.right; } } } @@ -891,6 +923,7 @@ void redraw () { full = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0) != 0; } } + if (parent.hooks (SWT.EraseItem) || parent.hooks (SWT.PaintItem)) full = true; if (OS.SendMessage (hwnd, OS.TVM_GETITEMRECT, full ? 0 : 1, rect) != 0) { OS.InvalidateRect (hwnd, rect, true); } |