- Rewrite wxHeaderCtrl to be virtual-like: even if we don't need an infinite
[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 // ----------------------------------------------------------------------------
95 // wxHeaderCtrl scrolling
96 // ----------------------------------------------------------------------------
97
98 void wxHeaderCtrl::DoScrollHorz(int dx)
99 {
100 m_scrollOffset += dx;
101
102 // don't call our own version which calls this function!
103 wxControl::ScrollWindow(dx, 0);
104 }
105
106 // ----------------------------------------------------------------------------
107 // wxHeaderCtrl geometry
108 // ----------------------------------------------------------------------------
109
110 wxSize wxHeaderCtrl::DoGetBestSize() const
111 {
112 // the vertical size is rather arbitrary but it looks better if we leave
113 // some space around the text
114 return wxSize(GetColStart(GetColumnCount()), (7*GetCharHeight())/4);
115 }
116
117 int wxHeaderCtrl::GetColStart(unsigned int idx) const
118 {
119 int pos = 0;
120 for ( unsigned n = 0; n < idx; n++ )
121 {
122 const wxHeaderColumn& col = m_cols[n];
123 if ( col.IsShown() )
124 pos += col.GetWidth();
125 }
126
127 return pos;
128 }
129
130 // ----------------------------------------------------------------------------
131 // wxHeaderCtrl repainting
132 // ----------------------------------------------------------------------------
133
134 void wxHeaderCtrl::RefreshCol(unsigned int idx)
135 {
136 wxRect rect = GetClientRect();
137 rect.x += GetColStart(idx);
138 rect.width = m_cols[idx].GetWidth();
139
140 RefreshRect(rect);
141 }
142
143 void wxHeaderCtrl::RefreshColsAfter(unsigned int idx)
144 {
145 wxRect rect = GetClientRect();
146 const int ofs = GetColStart(idx);
147 rect.x += ofs;
148 rect.width -= ofs;
149
150 RefreshRect(rect);
151 }
152
153 // ----------------------------------------------------------------------------
154 // wxHeaderCtrl event handlers
155 // ----------------------------------------------------------------------------
156
157 BEGIN_EVENT_TABLE(wxHeaderCtrl, wxControl)
158 EVT_PAINT(wxHeaderCtrl::OnPaint)
159
160 EVT_MOUSE_EVENTS(wxHeaderCtrl::OnMouse)
161 END_EVENT_TABLE()
162
163 void wxHeaderCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
164 {
165 int w, h;
166 GetClientSize(&w, &h);
167
168 wxAutoBufferedPaintDC dc(this);
169
170 dc.SetBackground(GetBackgroundColour());
171 dc.Clear();
172
173 // account for the horizontal scrollbar offset in the parent window
174 dc.SetDeviceOrigin(m_scrollOffset, 0);
175
176 const unsigned int count = m_cols.size();
177 int xpos = 0;
178 for ( unsigned int i = 0; i < count; i++ )
179 {
180 const wxHeaderColumn& col = m_cols[i];
181 if ( col.IsHidden() )
182 continue;
183
184 const int colWidth = col.GetWidth();
185
186 wxHeaderSortIconType sortArrow;
187 switch ( m_sortOrders[i] )
188 {
189 default:
190 wxFAIL_MSG( "wrong sort order value" );
191 // fall through
192
193 case -1:
194 sortArrow = wxHDR_SORT_ICON_NONE;
195 break;
196
197 case 0:
198 sortArrow = wxHDR_SORT_ICON_DOWN;
199 break;
200
201 case 1:
202 sortArrow = wxHDR_SORT_ICON_UP;
203 break;
204 }
205
206 int state = 0;
207 if ( IsEnabled() )
208 {
209 if ( i == m_hover )
210 state = wxCONTROL_CURRENT;
211 }
212 else // disabled
213 {
214 state = wxCONTROL_DISABLED;
215 }
216
217 wxHeaderButtonParams params;
218 params.m_labelText = col.GetTitle();
219 params.m_labelBitmap = col.GetBitmap();
220 params.m_labelAlignment = col.GetAlignment();
221
222 wxRendererNative::Get().DrawHeaderButton
223 (
224 this,
225 dc,
226 wxRect(xpos, 0, colWidth, h),
227 state,
228 sortArrow,
229 &params
230 );
231
232 xpos += colWidth;
233 }
234 }
235
236 void wxHeaderCtrl::OnMouse(wxMouseEvent& event)
237 {
238 event.Skip();
239 }
240
241 #endif // wxHAS_GENERIC_HEADERCTRL