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:
// 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)

View File

@ -39,6 +39,7 @@
#include <wx/dcclient.h>
#include <wx/dcscreen.h>
#include <wx/scrolwin.h>
#include <wx/renderer.h>
#include "wx/treelistctrl.h"
@ -47,6 +48,11 @@
#include <wx/gtk/win_gtk.h>
#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,14 +3463,15 @@ 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)
@ -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; n<count; ++n) {
@ -4108,6 +4111,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
@ -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;
}