X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1e03b21d31b26d7a1f9a5869ff2499636f906a4d..77b7cd4fc381ada7099a0efcb3d124c2704f79fb:/wxPython/contrib/gizmos/wxCode/src/treelistctrl.cpp diff --git a/wxPython/contrib/gizmos/wxCode/src/treelistctrl.cpp b/wxPython/contrib/gizmos/wxCode/src/treelistctrl.cpp index a03013f754..8a59591666 100644 --- a/wxPython/contrib/gizmos/wxCode/src/treelistctrl.cpp +++ b/wxPython/contrib/gizmos/wxCode/src/treelistctrl.cpp @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include "wx/treelistctrl.h" @@ -47,6 +49,11 @@ #include #endif +#ifdef __WXMAC__ + #include "wx/mac/private.h" +#endif + + // --------------------------------------------------------------------------- // array types // --------------------------------------------------------------------------- @@ -80,8 +87,18 @@ const int PIXELS_PER_UNIT = 10; const int LINEATROOT = 5; const int MARGIN = 2; const int MININDENT = 10; -const int BTNWIDTH = 11; -const int BTNHEIGHT = 11; +const int BTNWIDTH = 9; //11; +const int BTNHEIGHT = 9; //11; + +// extra margins around the text label +static const int EXTRA_WIDTH = 4; +static const int EXTRA_HEIGHT = 4; + +// offset for the header window +static const int HEADER_OFFSET_X = 1; +static const int HEADER_OFFSET_Y = 1; + + const wxChar* wxTreeListCtrlNameStr = wxT("treelistctrl"); @@ -136,6 +153,7 @@ public: void DrawCurrent(); void AdjustDC(wxDC& dc); + void OnEraseBackground( wxEraseEvent& event ); void OnPaint( wxPaintEvent &event ); void OnMouse( wxMouseEvent &event ); void OnSetFocus( wxFocusEvent &event ); @@ -549,7 +567,6 @@ public: void OnChar( wxKeyEvent &event ); void OnMouse( wxMouseEvent &event ); void OnIdle( wxIdleEvent &event ); - void OnSize(wxSizeEvent& event); // ALB void OnScroll(wxScrollWinEvent& event); // ALB // implementation helpers @@ -622,6 +639,7 @@ protected: wxTreeListItem *m_dropTarget; wxCursor m_oldCursor; // cursor is changed while dragging wxTreeListItem *m_oldSelection; + wxTreeListItem *m_underMouse; // for visual effects wxTimer *m_renameTimer; wxString m_renameRes; @@ -1059,9 +1077,10 @@ void wxTreeListTextCtrl::OnKillFocus( wxFocusEvent &event ) IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow,wxWindow); BEGIN_EVENT_TABLE(wxTreeListHeaderWindow,wxWindow) - EVT_PAINT (wxTreeListHeaderWindow::OnPaint) - EVT_MOUSE_EVENTS (wxTreeListHeaderWindow::OnMouse) - EVT_SET_FOCUS (wxTreeListHeaderWindow::OnSetFocus) + EVT_ERASE_BACKGROUND (wxTreeListHeaderWindow::OnEraseBackground) + EVT_PAINT (wxTreeListHeaderWindow::OnPaint) + EVT_MOUSE_EVENTS (wxTreeListHeaderWindow::OnMouse) + EVT_SET_FOCUS (wxTreeListHeaderWindow::OnSetFocus) END_EVENT_TABLE() void wxTreeListHeaderWindow::Init() @@ -1094,7 +1113,7 @@ wxTreeListHeaderWindow::wxTreeListHeaderWindow( wxWindow *win, m_owner = owner; m_resizeCursor = new wxCursor(wxCURSOR_SIZEWE); - SetBackgroundColour(wxSystemSettings::GetSystemColour( + SetBackgroundColour(wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE)); } @@ -1120,7 +1139,7 @@ void wxTreeListHeaderWindow::DoDrawRect( wxDC *dc, int x, int y, int w, int h ) dc->SetBrush( *wxTRANSPARENT_BRUSH ); - dc->SetPen( wxPen(wxSystemSettings::GetSystemColour( + dc->SetPen( wxPen(wxSystemSettings::GetColour( wxSYS_COLOUR_BTNSHADOW), 1, wxSOLID)); dc->DrawLine( x+w-m_corner+1, y, x+w, y+h ); // right (outer) dc->DrawRectangle( x, y+h, w+1, 1 ); // bottom (outer) @@ -1145,7 +1164,7 @@ void wxTreeListHeaderWindow::DoDrawRect( wxDC *dc, int x, int y, int w, int h ) dc->DrawLine( x+w-m_corner+1, y, x+w, y+h ); // right (outer) dc->DrawRectangle( x, y+h, w+1, 1 ); // bottom (outer) - wxPen pen(wxSystemSettings::GetSystemColour( + wxPen pen(wxSystemSettings::GetColour( wxSYS_COLOUR_BTNSHADOW ), 1, wxSOLID); dc->SetPen( pen ); @@ -1174,34 +1193,42 @@ void wxTreeListHeaderWindow::AdjustDC(wxDC& dc) dc.SetDeviceOrigin( -x * xpix, 0 ); } + +void wxTreeListHeaderWindow::OnEraseBackground( wxEraseEvent& event ) +{ +} + void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) { - static const int HEADER_OFFSET_X = 1, HEADER_OFFSET_Y = 1; #ifdef __WXGTK__ - wxClientDC dc( this ); + wxClientDC real_dc( this ); #else - wxPaintDC dc( this ); + wxPaintDC real_dc( this ); #endif - PrepareDC( dc ); - AdjustDC( dc ); - - dc.BeginDrawing(); - - dc.SetFont( GetFont() ); + AdjustDC( real_dc ); // width and height of the entire header window int w, h; GetClientSize( &w, &h ); m_owner->CalcUnscrolledPosition(w, 0, &w, NULL); + // Setup double buffering to eliminate the flicker + wxMemoryDC dc; + wxBitmap buffer(w, h); + dc.SelectObject(buffer); + dc.SetBackground(wxBrush(GetBackgroundColour())); + dc.Clear(); + + dc.BeginDrawing(); + dc.SetFont( GetFont() ); dc.SetBackgroundMode(wxTRANSPARENT); // do *not* use the listctrl colour for headers - one day we will have a // function to set it separately //dc.SetTextForeground( *wxBLACK ); dc.SetTextForeground(wxSystemSettings:: - GetSystemColour( wxSYS_COLOUR_WINDOWTEXT )); + GetColour( wxSYS_COLOUR_WINDOWTEXT )); int x = HEADER_OFFSET_X; @@ -1219,7 +1246,11 @@ void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) dc.SetPen( *wxWHITE_PEN ); - DoDrawRect( &dc, x, HEADER_OFFSET_Y, cw, h-2 ); + //DoDrawRect( &dc, x, HEADER_OFFSET_Y, cw, h-2 ); + wxRendererNative::Get().DrawHeaderButton( + this, dc, wxRect(x, HEADER_OFFSET_Y, cw, h - 2), + m_parent->IsEnabled() ? 0 : wxCONTROL_DISABLED); + // if we have an image, draw it on the right of the label int image = column.GetImage(); //item.m_image; @@ -1232,10 +1263,6 @@ void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) //else: ignore the column image } - // extra margins around the text label - static const int EXTRA_WIDTH = 3; - static const int EXTRA_HEIGHT = 4; - int text_width = 0; int text_x = x; int image_offset = cw - ix - 1; @@ -1274,14 +1301,19 @@ void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) x += wCol; } - int more_w = m_owner->GetSize().x - x; + int more_w = m_owner->GetSize().x - x -1; if (more_w > 0) { - DoDrawRect( &dc, x, HEADER_OFFSET_Y, more_w, h-2 ); + //DoDrawRect( &dc, x, HEADER_OFFSET_Y, more_w, h-2 ); + wxRendererNative::Get().DrawHeaderButton( + this, dc, wxRect(x, HEADER_OFFSET_Y, more_w, h-2), + m_parent->IsEnabled() ? 0 : wxCONTROL_DISABLED); } - + // Finish up by drawing the buffer to the real dc dc.EndDrawing(); + dc.SelectObject(wxNullBitmap); + real_dc.DrawBitmap(buffer, 0, 0, false); } void wxTreeListHeaderWindow::DrawCurrent() @@ -1629,7 +1661,7 @@ wxTreeListItem *wxTreeListItem::HitTest(const wxPoint& point, { // evaluate the item int h = theCtrl->GetLineHeight(this); - if ((point.y > m_y) && (point.y < m_y + h)) + if ((point.y > m_y) && (point.y <= m_y + h)) { // check for above/below middle int y_mid = m_y + h/2; @@ -1639,19 +1671,29 @@ wxTreeListItem *wxTreeListItem::HitTest(const wxPoint& point, flags |= wxTREE_HITTEST_ONITEMLOWERPART; // check for button hit - if (HasPlus() && theCtrl->HasButtons()) { - int bntX = m_x - theCtrl->m_btnWidth2; - int bntY = y_mid - theCtrl->m_btnHeight2; - if ((point.x > bntX) && (point.x < (bntX + theCtrl->m_btnWidth)) && - (point.y > bntY) && (point.y < (bntY + theCtrl->m_btnHeight))) { - flags |= wxTREE_HITTEST_ONITEMBUTTON; - return this; - } + int xCross = m_x; // - theCtrl->GetLineSpacing(); +#ifdef __WXMAC__ + // according to the drawing code the triangels are drawn + // at -4 , -4 from the position up to +10/+10 max + if ((point.x > xCross-4) && (point.x < xCross+10) && + (point.y > y_mid-4) && (point.y < y_mid+10) && + HasPlus() && theCtrl->HasButtons() ) +#else + // 5 is the size of the plus sign + if ((point.x > xCross-6) && (point.x < xCross+6) && + (point.y > y_mid-6) && (point.y < y_mid+6) && + HasPlus() && theCtrl->HasButtons() ) +#endif + { + flags |= wxTREE_HITTEST_ONITEMBUTTON; + return this; } // check for image hit - if (theCtrl->m_imgWidth > 0) { + if (theCtrl->m_imgWidth > 0 && GetImage() != NO_IMAGE) { int imgX = m_x - theCtrl->m_imgWidth2; + if (HasPlus() && theCtrl->HasButtons()) + imgX += theCtrl->m_btnWidth + LINEATROOT; int imgY = y_mid - theCtrl->m_imgHeight2; if ((point.x >= imgX) && (point.x <= (imgX + theCtrl->m_imgWidth)) && (point.y >= imgY) && (point.y <= (imgY + theCtrl->m_imgHeight))) { @@ -1744,6 +1786,7 @@ wxTreeListItem *wxTreeListItem::HitTest(const wxPoint& point, column = i; return res; } + x += w; } } @@ -1794,7 +1837,6 @@ BEGIN_EVENT_TABLE(wxTreeListMainWindow, wxScrolledWindow) EVT_SET_FOCUS (wxTreeListMainWindow::OnSetFocus) EVT_KILL_FOCUS (wxTreeListMainWindow::OnKillFocus) EVT_IDLE (wxTreeListMainWindow::OnIdle) -//? EVT_SIZE (wxTreeListMainWindow::OnSize) EVT_SCROLLWIN (wxTreeListMainWindow::OnScroll) END_EVENT_TABLE() @@ -1817,7 +1859,7 @@ void wxTreeListMainWindow::Init() m_hilightBrush = new wxBrush ( - wxSystemSettings::GetSystemColour + wxSystemSettings::GetColour ( wxSYS_COLOUR_HIGHLIGHT ), @@ -1826,7 +1868,7 @@ void wxTreeListMainWindow::Init() m_hilightUnfocusedBrush = new wxBrush ( - wxSystemSettings::GetSystemColour + wxSystemSettings::GetColour ( wxSYS_COLOUR_BTNSHADOW ), @@ -1847,17 +1889,23 @@ void wxTreeListMainWindow::Init() m_findTimer = new wxTimer (this, -1); - m_normalFont = wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT ); + m_underMouse = NULL; + +#if defined( __WXMAC__ ) && defined(__WXMAC_CARBON__) + m_normalFont.MacCreateThemeFont( kThemeViewsFont ) ; +#else + m_normalFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ); +#endif m_boldFont = wxFont( m_normalFont.GetPointSize(), m_normalFont.GetFamily(), m_normalFont.GetStyle(), wxBOLD, - m_normalFont.GetUnderlined()); + m_normalFont.GetUnderlined(), + m_normalFont.GetFaceName(), + m_normalFont.GetEncoding()); } -static const int HEADER_HEIGHT = 23; - bool wxTreeListMainWindow::Create(wxTreeListCtrl *parent, wxWindowID id, const wxPoint& pos, @@ -1867,17 +1915,20 @@ bool wxTreeListMainWindow::Create(wxTreeListCtrl *parent, const wxString& name ) { #ifdef __WXMAC__ - int major,minor; - wxGetOsVersion( &major, &minor ); - - if (style & wxTR_HAS_BUTTONS) style |= wxTR_MAC_BUTTONS; - if (style & wxTR_HAS_BUTTONS) style &= ~wxTR_HAS_BUTTONS; - style &= ~wxTR_LINES_AT_ROOT; - style |= wxTR_NO_LINES; - if (major < 10) - style |= wxTR_ROW_LINES; + if ( !(style & wxTR_DONT_ADJUST_MAC)) + { + int major,minor; + wxGetOsVersion( &major, &minor ); + + if (style & wxTR_HAS_BUTTONS) style |= wxTR_TWIST_BUTTONS; + if (style & wxTR_HAS_BUTTONS) style &= ~wxTR_HAS_BUTTONS; + style &= ~wxTR_LINES_AT_ROOT; + style |= wxTR_NO_LINES; + if (major < 10) + style |= wxTR_ROW_LINES; + } #endif - + wxScrolledWindow::Create( parent, id, pos, size, style|wxHSCROLL|wxVSCROLL, name ); @@ -1885,7 +1936,7 @@ bool wxTreeListMainWindow::Create(wxTreeListCtrl *parent, SetValidator( validator ); #endif - SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_LISTBOX ) ); + SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX ) ); #ifdef __WXMSW__ { @@ -3252,13 +3303,7 @@ void wxTreeListMainWindow::PaintItem(wxTreeListItem *item, wxDC& dc) colText = GetForegroundColour(); } - wxPen *pen = -#ifndef __WXMAC__ - // don't draw rect outline if we already have the - // background color under Mac - (item->IsSelected() && m_hasFocus) ? wxBLACK_PEN : -#endif // !__WXMAC__ - wxTRANSPARENT_PEN; + dc.SetPen(*wxTRANSPARENT_PEN); long text_w = 0, text_h = 0; @@ -3266,22 +3311,24 @@ void wxTreeListMainWindow::PaintItem(wxTreeListItem *item, wxDC& dc) int total_h = GetLineHeight(item); - if (item->IsSelected() && HasFlag (wxTR_FULL_ROW_HIGHLIGHT)) { - dc.SetBrush(*(m_hasFocus ? m_hilightBrush : m_hilightUnfocusedBrush)); - int offset = HasFlag(wxTR_ROW_LINES) ? 1 : 0; - dc.DrawRectangle (0, item->GetY() + offset, - m_owner->GetHeaderWindow()->GetWidth(), total_h-offset); - colText = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHTTEXT); - }else{ + if (item->IsSelected() && HasFlag(wxTR_FULL_ROW_HIGHLIGHT)) { + dc.SetBrush(*(m_hasFocus ? m_hilightBrush : m_hilightUnfocusedBrush)); + dc.SetPen(*wxBLACK_PEN); + colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); + } else { wxColour colBg; if (attr && attr->HasBackgroundColour()) { colBg = attr->GetBackgroundColour(); - }else{ - colBg = m_backgroundColour; + } else { + colBg = GetBackgroundColour(); } - dc.SetBrush(wxBrush(colBg, wxTRANSPARENT)); + dc.SetBrush(wxBrush(colBg, wxSOLID)); } + int offset = HasFlag(wxTR_ROW_LINES) ? 1 : 0; + dc.DrawRectangle(0, item->GetY() + offset, + m_owner->GetHeaderWindow()->GetWidth(), total_h-offset); + dc.SetBackgroundMode(wxTRANSPARENT); int text_extraH = (total_h > text_h) ? (total_h - text_h)/2 : 0; int img_extraH = (total_h > m_imgHeight)? (total_h-m_imgHeight)/2: 0; @@ -3292,9 +3339,9 @@ void wxTreeListMainWindow::PaintItem(wxTreeListItem *item, wxDC& dc) int image; int image_x = 0; int image_w = 0; - if(i == GetMainColumn()) { + if (i == GetMainColumn()) { image = item->GetCurrentImage(); - if (HasButtons()) { + if (item->HasPlus()) { image_x = item->GetX() + (m_btnWidth-m_btnWidth2) + LINEATROOT; }else{ image_x = item->GetX() - m_imgWidth2; @@ -3325,19 +3372,19 @@ void wxTreeListMainWindow::PaintItem(wxTreeListItem *item, wxDC& dc) } int text_x = image_x + image_w; - if (item->IsSelected() && (i==GetMainColumn()) && !HasFlag (wxTR_FULL_ROW_HIGHLIGHT)) + if (item->IsSelected() && (i==GetMainColumn()) && !HasFlag(wxTR_FULL_ROW_HIGHLIGHT)) { + dc.SetPen(*wxBLACK_PEN); dc.SetBrush(*(m_hasFocus ? m_hilightBrush : m_hilightUnfocusedBrush)); int offset = HasFlag (wxTR_ROW_LINES) ? 1 : 0; - dc.DrawRectangle (text_x, item->GetY() + offset, text_w, total_h-offset); + int width = wxMin(text_w+2, colwidth - text_x - x_colstart); + dc.DrawRectangle(text_x-1, item->GetY() + offset, width, total_h-offset); dc.SetBackgroundMode(wxTRANSPARENT); - dc.SetTextForeground(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHTTEXT)); + dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT)); }else{ dc.SetTextForeground(colText); } - dc.SetPen(*pen); - wxDCClipper clipper (dc, x_colstart, item->GetY(), colwidth, total_h); if (image != NO_IMAGE) { @@ -3399,6 +3446,9 @@ void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc, if (IsExposed(exposed_x, exposed_y, 10000, h)) // 10000 = very much { + // draw item + PaintItem(item, dc); + if (HasFlag(wxTR_ROW_LINES)) { //dc.DestroyClippingRegion(); @@ -3429,6 +3479,17 @@ void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc, // clip to the column width wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000); + if ( !HasFlag(wxTR_NO_LINES) ) + { + // draw the horizontal line here + int x_start = x; + if (x > (signed)m_indent) + x_start -= m_indent; + else if (HasFlag(wxTR_LINES_AT_ROOT)) + x_start = 3; + dc.DrawLine(x_start, y_mid, x /*+ m_spacing*/, y_mid); + } + if (m_imageListButtons != NULL) { // draw the image button here @@ -3443,54 +3504,25 @@ void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc, wxIMAGELIST_DRAW_TRANSPARENT); dc.DestroyClippingRegion(); } - else if (HasFlag(wxTR_TWIST_BUTTONS)) + else // no custom buttons { - // draw the twisty button here - dc.SetPen(*wxBLACK_PEN); - dc.SetBrush(*m_hilightBrush); - - wxPoint button[3]; + static const int wImage = 9; + static const int hImage = 9; + int flag = 0; if (item->IsExpanded()) - { - button[0].x = x - (m_btnWidth2+1); - button[0].y = y_mid - (m_btnHeight/3); - button[1].x = x + (m_btnWidth2+1); - button[1].y = button[0].y; - button[2].x = x; - button[2].y = button[0].y + (m_btnHeight2+1); - } - else - { - button[0].x = x - (m_btnWidth/3); - button[0].y = y_mid - (m_btnHeight2+1); - button[1].x = button[0].x; - button[1].y = y_mid + (m_btnHeight2+1); - button[2].x = button[0].x + (m_btnWidth2+1); - button[2].y = y_mid; - } - dc.DrawPolygon(3, button); - - dc.SetPen(m_dottedPen); - } - else // if (HasFlag(wxTR_HAS_BUTTONS)) - { - // draw the plus sign here - dc.SetPen(*wxGREY_PEN); - dc.SetBrush(*wxWHITE_BRUSH); - dc.DrawRectangle (x-m_btnWidth2, y_mid-m_btnHeight2, - m_btnWidth, m_btnHeight); - dc.SetPen(*wxBLACK_PEN); - dc.DrawLine (x-(m_btnWidth2-3), y_mid, - x+(m_btnWidth2-2), y_mid); - if (!item->IsExpanded()) - dc.DrawLine (x, y_mid-(m_btnHeight2-2), - x, y_mid+(m_btnHeight2-1)); - dc.SetPen(m_dottedPen); + flag |= wxCONTROL_EXPANDED; + if (item == m_underMouse) + flag |= wxCONTROL_CURRENT; + + wxRendererNative::Get().DrawTreeItemButton( + this, dc, + wxRect(x - wImage/2, y_mid - hImage/2, wImage, hImage), + flag); } if (!HasFlag(wxTR_NO_LINES)) { - if (!(level == 0) && !((level == 1) && HasFlag(wxTR_HIDE_ROOT))) { + if (/*!(level == 0) &&*/ !((level == 1) && HasFlag(wxTR_HIDE_ROOT))) { if (m_imgWidth > 0) { dc.DrawLine(x+m_btnWidth2, y_mid, x+m_indent-m_imgWidth2, y_mid); }else{ @@ -3505,19 +3537,15 @@ void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc, wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000); // draw the horizontal line here - if (!(level == 0) && !((level == 1) && HasFlag(wxTR_HIDE_ROOT))) { - int x2 = x; - if (!HasButtons()) x2 = x - m_indent; + if (/*!(level == 0) &&*/ !((level == 1) && HasFlag(wxTR_HIDE_ROOT))) { + int x2 = x - m_indent; if (m_imgWidth > 0) { dc.DrawLine(x2, y_mid, x2+m_indent-m_imgWidth2, y_mid); }else{ - dc.DrawLine(x2, y_mid, x2+m_btnWidth2+LINEATROOT-MARGIN, y_mid); + dc.DrawLine(x2, y_mid, x2+m_btnWidth2+LINEATROOT+MARGIN, y_mid); } } } - - // draw item - PaintItem(item, dc); } // restore DC objects @@ -3528,46 +3556,26 @@ void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc, if (item->IsExpanded()) { wxArrayTreeListItems& children = item->GetChildren(); + int count = children.Count(); + int n, oldY = 0; - // clip to the column width - size_t clip_width = m_owner->GetHeaderWindow()-> - GetColumn(m_main_column).GetWidth(); - wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000); - - // process lower levels - int oldY; - if (m_imgWidth > 0) { - oldY = y_mid + m_imgHeight2; - }else{ - oldY = y_mid + h/2; + // paint sublevel items first + for (n=0; nHasPlus() && HasButtons()) { - y2 = y + h/2 - m_btnHeight2; - if (HasButtons()) { - dc.DrawLine(x+m_indent, oldY, x+m_indent, y2); - }else{ - dc.DrawLine(x, oldY, x, y2); - } - oldY = y2 + m_btnHeight; - }else{ - y2 = y + h/2; - if (HasButtons()) { - dc.DrawLine(x+m_indent, oldY, x+m_indent, y2); - }else{ - dc.DrawLine(x, oldY, x, y2); - } - oldY = y2; - } - } + // then draw the connecting lines + if (!HasFlag(wxTR_NO_LINES) && count > 0) + { + // clip to the column width + size_t clip_width = m_owner->GetHeaderWindow()->GetColumn(m_main_column).GetWidth(); + wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000); - PaintLevel (children[n], dc, level+1, y, x_colstart); + // draw line down to last child + oldY += GetLineHeight(children[n-1]) >> 1; + if (HasButtons()) y_mid += 5; + dc.DrawLine(x, y_mid, x, oldY); } } } @@ -4024,12 +4032,8 @@ wxTreeItemId wxTreeListMainWindow::HitTest(const wxPoint& point, int& flags, return wxTreeItemId(); } - wxClientDC dc(this); - PrepareDC(dc); - wxCoord x = dc.DeviceToLogicalX( point.x ); - wxCoord y = dc.DeviceToLogicalY( point.y ); - wxTreeListItem *hit = m_anchor->HitTest(wxPoint(x, y), this, flags, - column, 0); + wxTreeListItem *hit = m_anchor->HitTest(CalcUnscrolledPosition(point), + this, flags, column, 0); if (hit == NULL) { flags = wxTREE_HITTEST_NOWHERE; @@ -4123,6 +4127,38 @@ void wxTreeListMainWindow::OnMouse( wxMouseEvent &event ) { if ( !m_anchor ) return; + wxPoint pt = CalcUnscrolledPosition(event.GetPosition()); + + // Is the mouse over a tree item button? + int flags = 0; + wxTreeListItem *item = m_anchor->HitTest(pt, this, flags, 0); + wxTreeListItem *underMouse = item; + + if (underMouse && (flags & wxTREE_HITTEST_ONITEMBUTTON) && + !event.LeftIsDown() && !m_isDragging && + (!m_renameTimer || !m_renameTimer->IsRunning())) + { + } + else + { + underMouse = NULL; + } + + if (underMouse != m_underMouse) + { + if (m_underMouse) + { + // unhighlight old item + wxTreeListItem *tmp = m_underMouse; + m_underMouse = NULL; + RefreshLine( tmp ); + } + + m_underMouse = underMouse; + if (m_underMouse) + RefreshLine( m_underMouse ); + } + // we process left mouse up event (enables in-place edit), right down // (pass to the user code), left dbl click (activate item) and // dragging/moving events for items drag-and-drop @@ -4140,13 +4176,12 @@ void wxTreeListMainWindow::OnMouse( wxMouseEvent &event ) if ( event.LeftDown() ) SetFocus(); - wxClientDC dc(this); - PrepareDC(dc); - wxCoord x = dc.DeviceToLogicalX( event.GetX() ); - wxCoord y = dc.DeviceToLogicalY( event.GetY() ); - - int flags = 0; - wxTreeListItem *item = m_anchor->HitTest(wxPoint(x,y), this, flags, 0); +// wxClientDC dc(this); +// PrepareDC(dc); +// wxCoord x = dc.DeviceToLogicalX( event.GetX() ); +// wxCoord y = dc.DeviceToLogicalY( event.GetY() ); + wxCoord &x = pt.x; + wxCoord &y = pt.y; if ( event.Dragging() && !m_isDragging ) { @@ -4357,13 +4392,6 @@ void wxTreeListMainWindow::OnIdle( wxIdleEvent &WXUNUSED(event) ) AdjustMyScrollbars(); } -void wxTreeListMainWindow::OnSize(wxSizeEvent& WXUNUSED(event)) -{ -// int w, h; -// GetClientSize(&w, &h); -// m_header_win->SetSize(0, 0, w, HEADER_HEIGHT); -} - void wxTreeListMainWindow::OnScroll(wxScrollWinEvent& event) { // FIXME @@ -4469,7 +4497,7 @@ void wxTreeListMainWindow::RefreshSubtree(wxTreeListItem *item) int cw = 0; int ch = 0; - GetClientSize( &cw, &ch ); // GetVirtualSize??? + GetVirtualSize( &cw, &ch ); wxRect rect; rect.x = dc.LogicalToDeviceX( 0 ); @@ -4491,7 +4519,7 @@ void wxTreeListMainWindow::RefreshLine( wxTreeListItem *item ) int cw = 0; int ch = 0; - GetClientSize( &cw, &ch ); // GetVirtualSize ?? + GetVirtualSize( &cw, &ch ); wxRect rect; rect.x = dc.LogicalToDeviceX( 0 ); @@ -4603,17 +4631,44 @@ bool wxTreeListCtrl::Create(wxWindow *parent, wxWindowID id, m_header_win = new wxTreeListHeaderWindow(this, -1, m_main_win, wxPoint(0, 0), wxDefaultSize, wxTAB_TRAVERSAL); + CalculateAndSetHeaderHeight(); return TRUE; } -void wxTreeListCtrl::OnSize(wxSizeEvent& WXUNUSED(event)) +void wxTreeListCtrl::CalculateAndSetHeaderHeight() +{ + if ( m_header_win ) + { + // we use 'g' to get the descent, too + int w, h, d; + m_header_win->GetTextExtent(wxT("Hg"), &w, &h, &d); + h += d + 2 * HEADER_OFFSET_Y + EXTRA_HEIGHT; + + // only update if changed + if ( h != (int)m_headerHeight ) + { + m_headerHeight = (size_t)h; + m_header_win->SetSize(m_header_win->GetSize().x, m_headerHeight); + } + } +} + +void wxTreeListCtrl::DoHeaderLayout() { int w, h; GetClientSize(&w, &h); - if(m_header_win) - m_header_win->SetSize(0, 0, w, HEADER_HEIGHT); - if(m_main_win) - m_main_win->SetSize(0, HEADER_HEIGHT + 1, w, h - HEADER_HEIGHT - 1); + if (m_header_win) + { + m_header_win->SetSize(0, 0, w, m_headerHeight); + m_header_win->Refresh(false); + } + if (m_main_win) + m_main_win->SetSize(0, m_headerHeight + 1, w, h - m_headerHeight - 1); +} + +void wxTreeListCtrl::OnSize(wxSizeEvent& WXUNUSED(event)) +{ + DoHeaderLayout(); } @@ -4717,8 +4772,12 @@ void wxTreeListCtrl::SetItemFont(const wxTreeItemId& item, bool wxTreeListCtrl::SetFont(const wxFont& font) { - if(m_header_win) m_header_win->SetFont(font); - if(m_main_win) + if (m_header_win) + { + m_header_win->SetFont(font); + CalculateAndSetHeaderHeight(); + } + if (m_main_win) return m_main_win->SetFont(font); else return FALSE; } @@ -4898,8 +4957,7 @@ void wxTreeListCtrl::ScrollTo(const wxTreeItemId& item) wxTreeItemId wxTreeListCtrl::HitTest(const wxPoint& pos, int& flags, int& column) { - return m_main_win->HitTest(m_main_win->ScreenToClient(ClientToScreen(pos)), - flags, column); + return m_main_win->HitTest(pos, flags, column); } bool wxTreeListCtrl::GetBoundingRect(const wxTreeItemId& item, wxRect& rect, @@ -4925,10 +4983,16 @@ wxTreeItemId wxTreeListCtrl::FindItem (const wxTreeItemId& item, const wxString& { return m_main_win->FindItem (item, str, flags); } bool wxTreeListCtrl::SetBackgroundColour(const wxColour& colour) -{ return m_main_win->SetBackgroundColour(colour); } +{ + if (!m_main_win) return false; + return m_main_win->SetBackgroundColour(colour); +} bool wxTreeListCtrl::SetForegroundColour(const wxColour& colour) -{ return m_main_win->SetForegroundColour(colour); } +{ + if (!m_main_win) return false; + return m_main_win->SetForegroundColour(colour); +} size_t wxTreeListCtrl::GetColumnCount() const { return m_main_win->GetColumnCount(); } @@ -4955,7 +5019,10 @@ wxString wxTreeListCtrl::GetColumnText(size_t column) const { return m_header_win->GetColumnText(column); } void wxTreeListCtrl::AddColumn(const wxTreeListColumnInfo& col) -{ m_header_win->AddColumn(col); } +{ + m_header_win->AddColumn(col); + DoHeaderLayout(); +} void wxTreeListCtrl::InsertColumn(size_t before, const wxTreeListColumnInfo& col) @@ -5015,3 +5082,9 @@ void wxTreeListCtrl::Refresh(bool erase, const wxRect* rect) void wxTreeListCtrl::SetFocus() { m_main_win->SetFocus(); } + +wxSize wxTreeListCtrl::DoGetBestSize() const +{ + // something is better than nothing... + return wxSize(100,80); +}