generic implementation of wxHeaderCtrl API so far
[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_hover = COL_NONE;
60 m_scrollOffset = 0;
61 }
62
63 bool wxHeaderCtrl::Create(wxWindow *parent,
64 wxWindowID id,
65 const wxPoint& pos,
66 const wxSize& size,
67 long style,
68 const wxString& name)
69 {
70 if ( !wxHeaderCtrlBase::Create(parent, id, pos, size,
71 style, wxDefaultValidator, name) )
72 return false;
73
74 // tell the system to not paint the background at all to avoid flicker as
75 // we paint the entire window area in our OnPaint()
76 SetBackgroundStyle(wxBG_STYLE_CUSTOM);
77
78 return true;
79 }
80
81 wxHeaderCtrl::~wxHeaderCtrl()
82 {
83 }
84
85 // ----------------------------------------------------------------------------
86 // wxHeaderCtrl columns manipulation
87 // ----------------------------------------------------------------------------
88
89 unsigned int wxHeaderCtrl::DoGetCount() const
90 {
91 return m_cols.size();
92 }
93
94 void wxHeaderCtrl::DoInsert(const wxHeaderColumn& col, unsigned int idx)
95 {
96 m_cols.insert(m_cols.begin() + idx, col);
97 m_sortOrders.insert(m_sortOrders.begin() + idx, -1);
98
99 if ( m_cols[idx].IsShown() )
100 RefreshColsAfter(idx);
101 }
102
103 void wxHeaderCtrl::DoDelete(unsigned int idx)
104 {
105 m_cols.erase(m_cols.begin() + idx);
106 m_sortOrders.erase(m_sortOrders.begin() + idx);
107
108 RefreshColsAfter(idx);
109 }
110
111 void wxHeaderCtrl::DoShowColumn(unsigned int idx, bool show)
112 {
113 if ( show != m_cols[idx].IsShown() )
114 {
115 m_cols[idx].SetHidden(!show);
116
117 RefreshColsAfter(idx);
118 }
119 }
120
121 void wxHeaderCtrl::DoShowSortIndicator(unsigned int idx, int sortOrder)
122 {
123 if ( sortOrder != m_sortOrders[idx] )
124 {
125 m_sortOrders[idx] = sortOrder;
126
127 RefreshCol(idx);
128 }
129 }
130
131 // ----------------------------------------------------------------------------
132 // wxHeaderCtrl scrolling
133 // ----------------------------------------------------------------------------
134
135 void wxHeaderCtrl::DoScrollHorz(int dx)
136 {
137 m_scrollOffset += dx;
138
139 // don't call our own version which calls this function!
140 wxControl::ScrollWindow(dx, 0);
141 }
142
143 // ----------------------------------------------------------------------------
144 // wxHeaderCtrl geometry
145 // ----------------------------------------------------------------------------
146
147 wxSize wxHeaderCtrl::DoGetBestSize() const
148 {
149 // the vertical size is rather arbitrary but it looks better if we leave
150 // some space around the text
151 return wxSize(GetColStart(GetColumnCount()), (7*GetCharHeight())/4);
152 }
153
154 int wxHeaderCtrl::GetColStart(unsigned int idx) const
155 {
156 int pos = 0;
157 for ( unsigned n = 0; n < idx; n++ )
158 {
159 const wxHeaderColumn& col = m_cols[n];
160 if ( col.IsShown() )
161 pos += col.GetWidth();
162 }
163
164 return pos;
165 }
166
167 // ----------------------------------------------------------------------------
168 // wxHeaderCtrl repainting
169 // ----------------------------------------------------------------------------
170
171 void wxHeaderCtrl::RefreshCol(unsigned int idx)
172 {
173 wxRect rect = GetClientRect();
174 rect.x += GetColStart(idx);
175 rect.width = m_cols[idx].GetWidth();
176
177 RefreshRect(rect);
178 }
179
180 void wxHeaderCtrl::RefreshColsAfter(unsigned int idx)
181 {
182 wxRect rect = GetClientRect();
183 const int ofs = GetColStart(idx);
184 rect.x += ofs;
185 rect.width -= ofs;
186
187 RefreshRect(rect);
188 }
189
190 // ----------------------------------------------------------------------------
191 // wxHeaderCtrl event handlers
192 // ----------------------------------------------------------------------------
193
194 BEGIN_EVENT_TABLE(wxHeaderCtrl, wxControl)
195 EVT_PAINT(wxHeaderCtrl::OnPaint)
196
197 EVT_MOUSE_EVENTS(wxHeaderCtrl::OnMouse)
198 END_EVENT_TABLE()
199
200 void wxHeaderCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
201 {
202 int w, h;
203 GetClientSize(&w, &h);
204
205 wxAutoBufferedPaintDC dc(this);
206
207 dc.SetBackground(GetBackgroundColour());
208 dc.Clear();
209
210 // account for the horizontal scrollbar offset in the parent window
211 dc.SetDeviceOrigin(m_scrollOffset, 0);
212
213 const unsigned int count = m_cols.size();
214 int xpos = 0;
215 for ( unsigned int i = 0; i < count; i++ )
216 {
217 const wxHeaderColumn& col = m_cols[i];
218 if ( col.IsHidden() )
219 continue;
220
221 const int colWidth = col.GetWidth();
222
223 wxHeaderSortIconType sortArrow;
224 switch ( m_sortOrders[i] )
225 {
226 default:
227 wxFAIL_MSG( "wrong sort order value" );
228 // fall through
229
230 case -1:
231 sortArrow = wxHDR_SORT_ICON_NONE;
232 break;
233
234 case 0:
235 sortArrow = wxHDR_SORT_ICON_DOWN;
236 break;
237
238 case 1:
239 sortArrow = wxHDR_SORT_ICON_UP;
240 break;
241 }
242
243 int state = 0;
244 if ( IsEnabled() )
245 {
246 if ( i == m_hover )
247 state = wxCONTROL_CURRENT;
248 }
249 else // disabled
250 {
251 state = wxCONTROL_DISABLED;
252 }
253
254 wxHeaderButtonParams params;
255 params.m_labelText = col.GetTitle();
256 params.m_labelBitmap = col.GetBitmap();
257 params.m_labelAlignment = col.GetAlignment();
258
259 wxRendererNative::Get().DrawHeaderButton
260 (
261 this,
262 dc,
263 wxRect(xpos, 0, colWidth, h),
264 state,
265 sortArrow,
266 &params
267 );
268
269 xpos += colWidth;
270 }
271 }
272
273 void wxHeaderCtrl::OnMouse(wxMouseEvent& event)
274 {
275 event.Skip();
276 }
277
278 #endif // wxHAS_GENERIC_HEADERCTRL