From 8e3ca43b377fc5b5e0e1e0de67366878dc5eff5b Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Tue, 28 Sep 2004 18:59:28 +0000 Subject: [PATCH] Patch from Alberto Griggio to use the wxRenderer for drawing the header and buttons, plus some tweaks from me to calculate the height of the header based on font size. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@29506 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- .../gizmos/wxCode/include/wx/treelistctrl.h | 10 +- .../gizmos/wxCode/src/treelistctrl.cpp | 240 +++++++++++------- 2 files changed, 153 insertions(+), 97 deletions(-) diff --git a/wxPython/contrib/gizmos/wxCode/include/wx/treelistctrl.h b/wxPython/contrib/gizmos/wxCode/include/wx/treelistctrl.h index 3b30c4a380..ad8190dac9 100644 --- a/wxPython/contrib/gizmos/wxCode/include/wx/treelistctrl.h +++ b/wxPython/contrib/gizmos/wxCode/include/wx/treelistctrl.h @@ -145,7 +145,9 @@ class GIZMODLLEXPORT wxTreeListCtrl : public wxControl public: // creation // -------- - wxTreeListCtrl() {} + wxTreeListCtrl() + : m_header_win(0), m_main_win(0), m_headerHeight(0) + {} wxTreeListCtrl(wxWindow *parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, @@ -153,7 +155,7 @@ public: long style = wxTR_DEFAULT_STYLE, const wxValidator &validator = wxDefaultValidator, const wxString& name = wxTreeListCtrlNameStr ) - : m_header_win(0), m_main_win(0) + : m_header_win(0), m_main_win(0), m_headerHeight(0) { Create(parent, id, pos, size, style, validator, name); } @@ -542,10 +544,12 @@ protected: // void Init(); void OnSize(wxSizeEvent& event); - + void CalculateAndSetHeaderHeight(); + private: size_t fill_column; + size_t m_headerHeight; DECLARE_EVENT_TABLE() DECLARE_DYNAMIC_CLASS(wxTreeListCtrl) diff --git a/wxPython/contrib/gizmos/wxCode/src/treelistctrl.cpp b/wxPython/contrib/gizmos/wxCode/src/treelistctrl.cpp index 2fbdd14400..8aef1b7cba 100644 --- a/wxPython/contrib/gizmos/wxCode/src/treelistctrl.cpp +++ b/wxPython/contrib/gizmos/wxCode/src/treelistctrl.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include "wx/treelistctrl.h" @@ -47,6 +48,11 @@ #include #endif +#ifdef __WXMAC__ + #include "wx/mac/private.h" +#endif + + // --------------------------------------------------------------------------- // array types // --------------------------------------------------------------------------- @@ -80,8 +86,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"); @@ -549,7 +565,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 +637,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; @@ -1176,7 +1192,6 @@ void wxTreeListHeaderWindow::AdjustDC(wxDC& dc) void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) { - static const int HEADER_OFFSET_X = 1, HEADER_OFFSET_Y = 1; #ifdef __WXGTK__ wxClientDC dc( this ); #else @@ -1219,7 +1234,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 +1251,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,10 +1289,13 @@ 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-3), + m_parent->IsEnabled() ? 0 : wxCONTROL_DISABLED); } @@ -1639,14 +1657,22 @@ 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 @@ -1795,7 +1821,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() @@ -1848,17 +1873,23 @@ void wxTreeListMainWindow::Init() m_findTimer = new wxTimer (this, -1); - m_normalFont = wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT ); + m_underMouse = NULL; + +#if defined( __WXMAC__ ) && __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, @@ -3432,16 +3463,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)) + if ( !HasFlag(wxTR_NO_LINES) ) { - if (x > m_indent) - dc.DrawLine(x - m_indent, y_mid, x - m_btnWidth2, y_mid); + // 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)) - dc.DrawLine(m_btnWidth2-2, y_mid, - x - m_btnWidth2, y_mid); - dc.DrawLine(x + m_btnWidth2, y_mid, x /*+ m_spacing*/, y_mid); + x_start = 3; + dc.DrawLine(x_start, y_mid, x /*+ m_spacing*/, y_mid); } - + if (m_imageListButtons != NULL) { // draw the image button here @@ -3456,54 +3488,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); + flag |= wxCONTROL_EXPANDED; + if (item == m_underMouse) + flag |= wxCONTROL_CURRENT; - 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); + 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{ @@ -3518,7 +3521,7 @@ 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))) { + 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); @@ -3538,7 +3541,7 @@ void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc, { wxArrayTreeListItems& children = item->GetChildren(); int count = children.Count(); - int n, oldY; + int n, oldY = 0; // paint sublevel items first for (n=0; nHitTest(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 @@ -4125,13 +4160,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 ) { @@ -4342,13 +4376,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 @@ -4588,17 +4615,38 @@ 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::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 != m_headerHeight ) + { + m_headerHeight = h; + //m_header_win->SetSize(m_header_win->GetSize().x, m_headerHeight); + } + } +} + + void wxTreeListCtrl::OnSize(wxSizeEvent& WXUNUSED(event)) { 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); + printf("%d (%d, %d)\n", m_headerHeight, w, h); + if (m_header_win) + m_header_win->SetSize(0, 0, w, m_headerHeight); + if (m_main_win) + m_main_win->SetSize(0, m_headerHeight + 1, w, h - m_headerHeight - 1); } @@ -4702,8 +4750,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; }