update the generic wxHeaderCtrl implementation after r57161
[wxWidgets.git] / src / generic / headerctrlg.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/headerctrlg.cpp
3 // Purpose: generic wxHeaderCtrl implementation
4 // Author: Vadim Zeitlin
5 // Created: 2008-12-03
6 // RCS-ID: $Id$
7 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #ifndef WX_PRECOMP
27 #endif // WX_PRECOMP
28
29 #include "wx/headerctrl.h"
30
31 #ifdef wxHAS_GENERIC_HEADERCTRL
32
33 #include "wx/dcbuffer.h"
34 #include "wx/renderer.h"
35
36 // ----------------------------------------------------------------------------
37 // constants
38 // ----------------------------------------------------------------------------
39
40 namespace
41 {
42
43 const unsigned NO_SORT = (unsigned)-1;
44
45 const unsigned COL_NONE = (unsigned)-1;
46
47 } // anonymous namespace
48
49 // ============================================================================
50 // wxHeaderCtrl implementation
51 // ============================================================================
52
53 // ----------------------------------------------------------------------------
54 // wxHeaderCtrl creation
55 // ----------------------------------------------------------------------------
56
57 void wxHeaderCtrl::Init()
58 {
59 m_numColumns = 0;
60 m_hover = COL_NONE;
61 m_scrollOffset = 0;
62 }
63
64 bool wxHeaderCtrl::Create(wxWindow *parent,
65 wxWindowID id,
66 const wxPoint& pos,
67 const wxSize& size,
68 long style,
69 const wxString& name)
70 {
71 if ( !wxHeaderCtrlBase::Create(parent, id, pos, size,
72 style, wxDefaultValidator, name) )
73 return false;
74
75 // tell the system to not paint the background at all to avoid flicker as
76 // we paint the entire window area in our OnPaint()
77 SetBackgroundStyle(wxBG_STYLE_CUSTOM);
78
79 return true;
80 }
81
82 wxHeaderCtrl::~wxHeaderCtrl()
83 {
84 }
85
86 // ----------------------------------------------------------------------------
87 // wxHeaderCtrl columns manipulation
88 // ----------------------------------------------------------------------------
89
90 void wxHeaderCtrl::DoSetCount(unsigned int count)
91 {
92 m_numColumns = count;
93
94 Refresh();
95 }
96
97 unsigned int wxHeaderCtrl::DoGetCount() const
98 {
99 return m_numColumns;
100 }
101
102 void wxHeaderCtrl::DoUpdate(unsigned int idx)
103 {
104 // we need to refresh not only this column but also the ones after it in
105 // case it was shown or hidden or its width changed -- it would be nice to
106 // avoid doing this unnecessary by storing the old column width (TODO)
107 RefreshColsAfter(idx);
108 }
109
110 // ----------------------------------------------------------------------------
111 // wxHeaderCtrl scrolling
112 // ----------------------------------------------------------------------------
113
114 void wxHeaderCtrl::DoScrollHorz(int dx)
115 {
116 m_scrollOffset += dx;
117
118 // don't call our own version which calls this function!
119 wxControl::ScrollWindow(dx, 0);
120 }
121
122 // ----------------------------------------------------------------------------
123 // wxHeaderCtrl geometry
124 // ----------------------------------------------------------------------------
125
126 wxSize wxHeaderCtrl::DoGetBestSize() const
127 {
128 // the vertical size is rather arbitrary but it looks better if we leave
129 // some space around the text
130 return wxSize(GetColStart(GetColumnCount()), (7*GetCharHeight())/4);
131 }
132
133 int wxHeaderCtrl::GetColStart(unsigned int idx) const
134 {
135 wxHeaderCtrl * const self = const_cast<wxHeaderCtrl *>(this);
136
137 int pos = 0;
138 for ( unsigned n = 0; n < idx; n++ )
139 {
140 const wxHeaderColumnBase& col = self->GetColumn(n);
141 if ( col.IsShown() )
142 pos += col.GetWidth();
143 }
144
145 return pos;
146 }
147
148 // ----------------------------------------------------------------------------
149 // wxHeaderCtrl repainting
150 // ----------------------------------------------------------------------------
151
152 void wxHeaderCtrl::RefreshCol(unsigned int idx)
153 {
154 wxRect rect = GetClientRect();
155 rect.x += GetColStart(idx);
156 rect.width = GetColumn(idx).GetWidth();
157
158 RefreshRect(rect);
159 }
160
161 void wxHeaderCtrl::RefreshColsAfter(unsigned int idx)
162 {
163 wxRect rect = GetClientRect();
164 const int ofs = GetColStart(idx);
165 rect.x += ofs;
166 rect.width -= ofs;
167
168 RefreshRect(rect);
169 }
170
171 // ----------------------------------------------------------------------------
172 // wxHeaderCtrl event handlers
173 // ----------------------------------------------------------------------------
174
175 BEGIN_EVENT_TABLE(wxHeaderCtrl, wxControl)
176 EVT_PAINT(wxHeaderCtrl::OnPaint)
177
178 EVT_MOUSE_EVENTS(wxHeaderCtrl::OnMouse)
179 END_EVENT_TABLE()
180
181 void wxHeaderCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
182 {
183 int w, h;
184 GetClientSize(&w, &h);
185
186 wxAutoBufferedPaintDC dc(this);
187
188 dc.SetBackground(GetBackgroundColour());
189 dc.Clear();
190
191 // account for the horizontal scrollbar offset in the parent window
192 dc.SetDeviceOrigin(m_scrollOffset, 0);
193
194 const unsigned int count = m_numColumns;
195 int xpos = 0;
196 for ( unsigned int i = 0; i < count; i++ )
197 {
198 const wxHeaderColumnBase& col = GetColumn(i);
199 if ( col.IsHidden() )
200 continue;
201
202 const int colWidth = col.GetWidth();
203
204 wxHeaderSortIconType sortArrow;
205 if ( col.IsSortKey() )
206 {
207 sortArrow = col.IsSortOrderAscending() ? wxHDR_SORT_ICON_UP
208 : wxHDR_SORT_ICON_DOWN;
209 }
210 else // not sorting by this column
211 {
212 sortArrow = wxHDR_SORT_ICON_NONE;
213 }
214
215 int state = 0;
216 if ( IsEnabled() )
217 {
218 if ( i == m_hover )
219 state = wxCONTROL_CURRENT;
220 }
221 else // disabled
222 {
223 state = wxCONTROL_DISABLED;
224 }
225
226 wxHeaderButtonParams params;
227 params.m_labelText = col.GetTitle();
228 params.m_labelBitmap = col.GetBitmap();
229 params.m_labelAlignment = col.GetAlignment();
230
231 wxRendererNative::Get().DrawHeaderButton
232 (
233 this,
234 dc,
235 wxRect(xpos, 0, colWidth, h),
236 state,
237 sortArrow,
238 &params
239 );
240
241 xpos += colWidth;
242 }
243 }
244
245 void wxHeaderCtrl::OnMouse(wxMouseEvent& event)
246 {
247 event.Skip();
248 }
249
250 #endif // wxHAS_GENERIC_HEADERCTRL