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
This commit is contained in:
Robin Dunn 2004-09-28 18:59:28 +00:00
parent 3180bc0e63
commit 8e3ca43b37
2 changed files with 153 additions and 97 deletions

View File

@ -145,7 +145,9 @@ class GIZMODLLEXPORT wxTreeListCtrl : public wxControl
public: public:
// creation // creation
// -------- // --------
wxTreeListCtrl() {} wxTreeListCtrl()
: m_header_win(0), m_main_win(0), m_headerHeight(0)
{}
wxTreeListCtrl(wxWindow *parent, wxWindowID id = -1, wxTreeListCtrl(wxWindow *parent, wxWindowID id = -1,
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,
@ -153,7 +155,7 @@ public:
long style = wxTR_DEFAULT_STYLE, long style = wxTR_DEFAULT_STYLE,
const wxValidator &validator = wxDefaultValidator, const wxValidator &validator = wxDefaultValidator,
const wxString& name = wxTreeListCtrlNameStr ) 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); Create(parent, id, pos, size, style, validator, name);
} }
@ -542,10 +544,12 @@ protected:
// void Init(); // void Init();
void OnSize(wxSizeEvent& event); void OnSize(wxSizeEvent& event);
void CalculateAndSetHeaderHeight();
private: private:
size_t fill_column; size_t fill_column;
size_t m_headerHeight;
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
DECLARE_DYNAMIC_CLASS(wxTreeListCtrl) DECLARE_DYNAMIC_CLASS(wxTreeListCtrl)

View File

@ -39,6 +39,7 @@
#include <wx/dcclient.h> #include <wx/dcclient.h>
#include <wx/dcscreen.h> #include <wx/dcscreen.h>
#include <wx/scrolwin.h> #include <wx/scrolwin.h>
#include <wx/renderer.h>
#include "wx/treelistctrl.h" #include "wx/treelistctrl.h"
@ -47,6 +48,11 @@
#include <wx/gtk/win_gtk.h> #include <wx/gtk/win_gtk.h>
#endif #endif
#ifdef __WXMAC__
#include "wx/mac/private.h"
#endif
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// array types // array types
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -80,8 +86,18 @@ const int PIXELS_PER_UNIT = 10;
const int LINEATROOT = 5; const int LINEATROOT = 5;
const int MARGIN = 2; const int MARGIN = 2;
const int MININDENT = 10; const int MININDENT = 10;
const int BTNWIDTH = 11; const int BTNWIDTH = 9; //11;
const int BTNHEIGHT = 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"); const wxChar* wxTreeListCtrlNameStr = wxT("treelistctrl");
@ -549,7 +565,6 @@ public:
void OnChar( wxKeyEvent &event ); void OnChar( wxKeyEvent &event );
void OnMouse( wxMouseEvent &event ); void OnMouse( wxMouseEvent &event );
void OnIdle( wxIdleEvent &event ); void OnIdle( wxIdleEvent &event );
void OnSize(wxSizeEvent& event); // ALB
void OnScroll(wxScrollWinEvent& event); // ALB void OnScroll(wxScrollWinEvent& event); // ALB
// implementation helpers // implementation helpers
@ -622,6 +637,7 @@ protected:
wxTreeListItem *m_dropTarget; wxTreeListItem *m_dropTarget;
wxCursor m_oldCursor; // cursor is changed while dragging wxCursor m_oldCursor; // cursor is changed while dragging
wxTreeListItem *m_oldSelection; wxTreeListItem *m_oldSelection;
wxTreeListItem *m_underMouse; // for visual effects
wxTimer *m_renameTimer; wxTimer *m_renameTimer;
wxString m_renameRes; wxString m_renameRes;
@ -1176,7 +1192,6 @@ void wxTreeListHeaderWindow::AdjustDC(wxDC& dc)
void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
{ {
static const int HEADER_OFFSET_X = 1, HEADER_OFFSET_Y = 1;
#ifdef __WXGTK__ #ifdef __WXGTK__
wxClientDC dc( this ); wxClientDC dc( this );
#else #else
@ -1219,7 +1234,11 @@ void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
dc.SetPen( *wxWHITE_PEN ); 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 // if we have an image, draw it on the right of the label
int image = column.GetImage(); //item.m_image; int image = column.GetImage(); //item.m_image;
@ -1232,10 +1251,6 @@ void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
//else: ignore the column image //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_width = 0;
int text_x = x; int text_x = x;
int image_offset = cw - ix - 1; int image_offset = cw - ix - 1;
@ -1274,10 +1289,13 @@ void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
x += wCol; x += wCol;
} }
int more_w = m_owner->GetSize().x - x; int more_w = m_owner->GetSize().x - x -1;
if (more_w > 0) 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,15 +1657,23 @@ wxTreeListItem *wxTreeListItem::HitTest(const wxPoint& point,
flags |= wxTREE_HITTEST_ONITEMLOWERPART; flags |= wxTREE_HITTEST_ONITEMLOWERPART;
// check for button hit // check for button hit
if (HasPlus() && theCtrl->HasButtons()) { int xCross = m_x; // - theCtrl->GetLineSpacing();
int bntX = m_x - theCtrl->m_btnWidth2; #ifdef __WXMAC__
int bntY = y_mid - theCtrl->m_btnHeight2; // according to the drawing code the triangels are drawn
if ((point.x > bntX) && (point.x < (bntX + theCtrl->m_btnWidth)) && // at -4 , -4 from the position up to +10/+10 max
(point.y > bntY) && (point.y < (bntY + theCtrl->m_btnHeight))) { 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; flags |= wxTREE_HITTEST_ONITEMBUTTON;
return this; return this;
} }
}
// check for image hit // check for image hit
if (theCtrl->m_imgWidth > 0) { if (theCtrl->m_imgWidth > 0) {
@ -1795,7 +1821,6 @@ BEGIN_EVENT_TABLE(wxTreeListMainWindow, wxScrolledWindow)
EVT_SET_FOCUS (wxTreeListMainWindow::OnSetFocus) EVT_SET_FOCUS (wxTreeListMainWindow::OnSetFocus)
EVT_KILL_FOCUS (wxTreeListMainWindow::OnKillFocus) EVT_KILL_FOCUS (wxTreeListMainWindow::OnKillFocus)
EVT_IDLE (wxTreeListMainWindow::OnIdle) EVT_IDLE (wxTreeListMainWindow::OnIdle)
//? EVT_SIZE (wxTreeListMainWindow::OnSize)
EVT_SCROLLWIN (wxTreeListMainWindow::OnScroll) EVT_SCROLLWIN (wxTreeListMainWindow::OnScroll)
END_EVENT_TABLE() END_EVENT_TABLE()
@ -1848,17 +1873,23 @@ void wxTreeListMainWindow::Init()
m_findTimer = new wxTimer (this, -1); 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_boldFont = wxFont( m_normalFont.GetPointSize(),
m_normalFont.GetFamily(), m_normalFont.GetFamily(),
m_normalFont.GetStyle(), m_normalFont.GetStyle(),
wxBOLD, wxBOLD,
m_normalFont.GetUnderlined()); m_normalFont.GetUnderlined(),
m_normalFont.GetFaceName(),
m_normalFont.GetEncoding());
} }
static const int HEADER_HEIGHT = 23;
bool wxTreeListMainWindow::Create(wxTreeListCtrl *parent, bool wxTreeListMainWindow::Create(wxTreeListCtrl *parent,
wxWindowID id, wxWindowID id,
const wxPoint& pos, const wxPoint& pos,
@ -3432,14 +3463,15 @@ void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc,
// clip to the column width // clip to the column width
wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000); wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000);
if (!HasFlag(wxTR_NO_LINES)) if ( !HasFlag(wxTR_NO_LINES) )
{ {
if (x > m_indent) // draw the horizontal line here
dc.DrawLine(x - m_indent, y_mid, x - m_btnWidth2, y_mid); int x_start = x;
if (x > (signed)m_indent)
x_start -= m_indent;
else if (HasFlag(wxTR_LINES_AT_ROOT)) else if (HasFlag(wxTR_LINES_AT_ROOT))
dc.DrawLine(m_btnWidth2-2, y_mid, x_start = 3;
x - m_btnWidth2, y_mid); dc.DrawLine(x_start, y_mid, x /*+ m_spacing*/, y_mid);
dc.DrawLine(x + m_btnWidth2, y_mid, x /*+ m_spacing*/, y_mid);
} }
if (m_imageListButtons != NULL) if (m_imageListButtons != NULL)
@ -3456,54 +3488,25 @@ void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc,
wxIMAGELIST_DRAW_TRANSPARENT); wxIMAGELIST_DRAW_TRANSPARENT);
dc.DestroyClippingRegion(); dc.DestroyClippingRegion();
} }
else if (HasFlag(wxTR_TWIST_BUTTONS)) else // no custom buttons
{ {
// draw the twisty button here static const int wImage = 9;
dc.SetPen(*wxBLACK_PEN); static const int hImage = 9;
dc.SetBrush(*m_hilightBrush);
wxPoint button[3];
int flag = 0;
if (item->IsExpanded()) if (item->IsExpanded())
{ flag |= wxCONTROL_EXPANDED;
button[0].x = x - (m_btnWidth2+1); if (item == m_underMouse)
button[0].y = y_mid - (m_btnHeight/3); flag |= wxCONTROL_CURRENT;
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); wxRendererNative::Get().DrawTreeItemButton(
} this, dc,
else // if (HasFlag(wxTR_HAS_BUTTONS)) wxRect(x - wImage/2, y_mid - hImage/2, wImage, hImage),
{ flag);
// 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);
} }
if (!HasFlag(wxTR_NO_LINES)) { 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) { if (m_imgWidth > 0) {
dc.DrawLine(x+m_btnWidth2, y_mid, x+m_indent-m_imgWidth2, y_mid); dc.DrawLine(x+m_btnWidth2, y_mid, x+m_indent-m_imgWidth2, y_mid);
}else{ }else{
@ -3518,7 +3521,7 @@ void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc,
wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000); wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000);
// draw the horizontal line here // 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; int x2 = x - m_indent;
if (m_imgWidth > 0) { if (m_imgWidth > 0) {
dc.DrawLine(x2, y_mid, x2+m_indent-m_imgWidth2, y_mid); 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(); wxArrayTreeListItems& children = item->GetChildren();
int count = children.Count(); int count = children.Count();
int n, oldY; int n, oldY = 0;
// paint sublevel items first // paint sublevel items first
for (n=0; n<count; ++n) { for (n=0; n<count; ++n) {
@ -4108,6 +4111,38 @@ void wxTreeListMainWindow::OnMouse( wxMouseEvent &event )
{ {
if ( !m_anchor ) return; 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 // we process left mouse up event (enables in-place edit), right down
// (pass to the user code), left dbl click (activate item) and // (pass to the user code), left dbl click (activate item) and
// dragging/moving events for items drag-and-drop // dragging/moving events for items drag-and-drop
@ -4125,13 +4160,12 @@ void wxTreeListMainWindow::OnMouse( wxMouseEvent &event )
if ( event.LeftDown() ) if ( event.LeftDown() )
SetFocus(); SetFocus();
wxClientDC dc(this); // wxClientDC dc(this);
PrepareDC(dc); // PrepareDC(dc);
wxCoord x = dc.DeviceToLogicalX( event.GetX() ); // wxCoord x = dc.DeviceToLogicalX( event.GetX() );
wxCoord y = dc.DeviceToLogicalY( event.GetY() ); // wxCoord y = dc.DeviceToLogicalY( event.GetY() );
wxCoord &x = pt.x;
int flags = 0; wxCoord &y = pt.y;
wxTreeListItem *item = m_anchor->HitTest(wxPoint(x,y), this, flags, 0);
if ( event.Dragging() && !m_isDragging ) if ( event.Dragging() && !m_isDragging )
{ {
@ -4342,13 +4376,6 @@ void wxTreeListMainWindow::OnIdle( wxIdleEvent &WXUNUSED(event) )
AdjustMyScrollbars(); 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) void wxTreeListMainWindow::OnScroll(wxScrollWinEvent& event)
{ {
// FIXME // FIXME
@ -4588,17 +4615,38 @@ bool wxTreeListCtrl::Create(wxWindow *parent, wxWindowID id,
m_header_win = new wxTreeListHeaderWindow(this, -1, m_main_win, m_header_win = new wxTreeListHeaderWindow(this, -1, m_main_win,
wxPoint(0, 0), wxDefaultSize, wxPoint(0, 0), wxDefaultSize,
wxTAB_TRAVERSAL); wxTAB_TRAVERSAL);
CalculateAndSetHeaderHeight();
return TRUE; 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)) void wxTreeListCtrl::OnSize(wxSizeEvent& WXUNUSED(event))
{ {
int w, h; int w, h;
GetClientSize(&w, &h); GetClientSize(&w, &h);
if(m_header_win) printf("%d (%d, %d)\n", m_headerHeight, w, h);
m_header_win->SetSize(0, 0, w, HEADER_HEIGHT); if (m_header_win)
if(m_main_win) m_header_win->SetSize(0, 0, w, m_headerHeight);
m_main_win->SetSize(0, HEADER_HEIGHT + 1, w, h - HEADER_HEIGHT - 1); 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) bool wxTreeListCtrl::SetFont(const wxFont& font)
{ {
if(m_header_win) m_header_win->SetFont(font); if (m_header_win)
if(m_main_win) {
m_header_win->SetFont(font);
CalculateAndSetHeaderHeight();
}
if (m_main_win)
return m_main_win->SetFont(font); return m_main_win->SetFont(font);
else return FALSE; else return FALSE;
} }