add wxEVT_COMMAND_HEADER_SEPARATOR_DCLICK and semi-automatic header resizing support
[wxWidgets.git] / src / common / headerctrlcmn.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/headerctrlcmn.cpp
3 // Purpose: implementation of wxHeaderCtrlBase
4 // Author: Vadim Zeitlin
5 // Created: 2008-12-02
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 // ----------------------------------------------------------------------------
32 // constants
33 // ----------------------------------------------------------------------------
34
35 namespace
36 {
37
38 const unsigned int wxNO_COLUMN = static_cast<unsigned>(-1);
39
40 } // anonymous namespace
41
42 // ============================================================================
43 // wxHeaderCtrlBase implementation
44 // ============================================================================
45
46 extern WXDLLIMPEXP_DATA_CORE(const char) wxHeaderCtrlNameStr[] = "wxHeaderCtrl";
47
48 BEGIN_EVENT_TABLE(wxHeaderCtrlBase, wxControl)
49 EVT_HEADER_SEPARATOR_DCLICK(wxID_ANY, wxHeaderCtrlBase::OnSeparatorDClick)
50 END_EVENT_TABLE()
51
52 void wxHeaderCtrlBase::ScrollWindow(int dx,
53 int WXUNUSED_UNLESS_DEBUG(dy),
54 const wxRect * WXUNUSED_UNLESS_DEBUG(rect))
55
56 {
57 // this doesn't make sense at all
58 wxASSERT_MSG( !dy, "header window can't be scrolled vertically" );
59
60 // this would actually be nice to support for "frozen" headers but it isn't
61 // supported currently
62 wxASSERT_MSG( !rect, "header window can't be scrolled partially" );
63
64 DoScrollHorz(dx);
65 }
66
67 void wxHeaderCtrlBase::OnSeparatorDClick(wxHeaderCtrlEvent& event)
68 {
69 const unsigned col = event.GetColumn();
70
71 int w = wxWindowBase::GetTextExtent(GetColumn(col).GetTitle()).x;
72 w += 2*GetCharWidth(); // add some arbitrary margins around text
73
74 if ( !UpdateColumnWidthToFit(col, w) )
75 event.Skip();
76 else
77 UpdateColumn(col);
78 }
79
80 // ============================================================================
81 // wxHeaderCtrlSimple implementation
82 // ============================================================================
83
84 void wxHeaderCtrlSimple::Init()
85 {
86 m_sortKey = wxNO_COLUMN;
87 }
88
89 wxHeaderColumnBase& wxHeaderCtrlSimple::GetColumn(unsigned int idx)
90 {
91 return m_cols[idx];
92 }
93
94 void wxHeaderCtrlSimple::DoInsert(const wxHeaderColumnSimple& col, unsigned int idx)
95 {
96 m_cols.insert(m_cols.begin() + idx, col);
97
98 UpdateColumnCount();
99 }
100
101 void wxHeaderCtrlSimple::DoDelete(unsigned int idx)
102 {
103 m_cols.erase(m_cols.begin() + idx);
104 if ( idx == m_sortKey )
105 m_sortKey = wxNO_COLUMN;
106
107 UpdateColumnCount();
108 }
109
110 void wxHeaderCtrlSimple::DeleteAllColumns()
111 {
112 m_cols.clear();
113 m_sortKey = wxNO_COLUMN;
114
115 UpdateColumnCount();
116 }
117
118
119 void wxHeaderCtrlSimple::DoShowColumn(unsigned int idx, bool show)
120 {
121 if ( show != m_cols[idx].IsShown() )
122 {
123 m_cols[idx].SetHidden(!show);
124
125 UpdateColumn(idx);
126 }
127 }
128
129 void wxHeaderCtrlSimple::DoShowSortIndicator(unsigned int idx, bool ascending)
130 {
131 RemoveSortIndicator();
132
133 m_cols[idx].SetAsSortKey(ascending);
134 m_sortKey = idx;
135
136 UpdateColumn(idx);
137 }
138
139 void wxHeaderCtrlSimple::RemoveSortIndicator()
140 {
141 if ( m_sortKey != wxNO_COLUMN )
142 {
143 const unsigned sortOld = m_sortKey;
144 m_sortKey = wxNO_COLUMN;
145
146 m_cols[sortOld].UnsetAsSortKey();
147
148 UpdateColumn(sortOld);
149 }
150 }
151
152 // ============================================================================
153 // wxHeaderCtrlEvent implementation
154 // ============================================================================
155
156 IMPLEMENT_DYNAMIC_CLASS(wxHeaderCtrlEvent, wxNotifyEvent)
157
158 const wxEventType wxEVT_COMMAND_HEADER_CLICK = wxNewEventType();
159 const wxEventType wxEVT_COMMAND_HEADER_RIGHT_CLICK = wxNewEventType();
160 const wxEventType wxEVT_COMMAND_HEADER_MIDDLE_CLICK = wxNewEventType();
161
162 const wxEventType wxEVT_COMMAND_HEADER_DCLICK = wxNewEventType();
163 const wxEventType wxEVT_COMMAND_HEADER_RIGHT_DCLICK = wxNewEventType();
164 const wxEventType wxEVT_COMMAND_HEADER_MIDDLE_DCLICK = wxNewEventType();
165
166 const wxEventType wxEVT_COMMAND_HEADER_SEPARATOR_DCLICK = wxNewEventType();