1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/collheaderctrlg.cpp
3 // Purpose: Generic wxCollapsibleHeaderCtrl implementation
4 // Author: Tobias Taschner
5 // Created: 2015-09-19
6 // Copyright: (c) 2015 wxWidgets development team
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // ----------------------------------------------------------------------------
11 // headers
12 // ----------------------------------------------------------------------------
13
14 #include "wx/wxprec.h"
15
16 #include "wx/defs.h"
17
18 #if wxUSE_COLLPANE
19
20 #include "wx/collheaderctrl.h"
21
22 #ifndef WX_PRECOMP
23 #include "wx/dcclient.h"
24 #include "wx/sizer.h"
25 #endif // !WX_PRECOMP
26
27 #include "wx/renderer.h"
28
29 #ifdef __WXMSW__
30 #include "wx/msw/private.h"
31 #endif // __WXMSW__
32
33 // if we have another implementation of this class we should extract
34 // the lines below to a common file
35
36 const char wxCollapsibleHeaderCtrlNameStr[] = "collapsibleHeader";
37
38 wxDEFINE_EVENT(wxEVT_COLLAPSIBLEHEADER_CHANGED, wxCommandEvent);
39
40 // ============================================================================
41 // implementation
42 // ============================================================================
43
Init()44 void wxGenericCollapsibleHeaderCtrl::Init()
45 {
46 m_collapsed = true;
47 m_inWindow = false;
48 m_mouseDown = false;
49 }
50
Create(wxWindow * parent,wxWindowID id,const wxString & label,const wxPoint & pos,const wxSize & size,long style,const wxValidator & validator,const wxString & name)51 bool wxGenericCollapsibleHeaderCtrl::Create(wxWindow *parent,
52 wxWindowID id,
53 const wxString& label,
54 const wxPoint& pos,
55 const wxSize& size,
56 long style,
57 const wxValidator& validator,
58 const wxString& name)
59 {
60 if ( !wxCollapsibleHeaderCtrlBase::Create(parent, id, label, pos, size,
61 style, validator, name) )
62 {
63 return false;
64 }
65
66 Bind(wxEVT_PAINT, &wxGenericCollapsibleHeaderCtrl::OnPaint, this);
67 Bind(wxEVT_LEFT_DOWN, &wxGenericCollapsibleHeaderCtrl::OnLeftDown, this);
68 Bind(wxEVT_LEFT_UP, &wxGenericCollapsibleHeaderCtrl::OnLeftUp, this);
69 Bind(wxEVT_ENTER_WINDOW, &wxGenericCollapsibleHeaderCtrl::OnEnterWindow, this);
70 Bind(wxEVT_LEAVE_WINDOW, &wxGenericCollapsibleHeaderCtrl::OnLeaveWindow, this);
71 Bind(wxEVT_CHAR, &wxGenericCollapsibleHeaderCtrl::OnChar, this);
72 Bind(wxEVT_SET_FOCUS, &wxGenericCollapsibleHeaderCtrl::OnFocus, this);
73 Bind(wxEVT_KILL_FOCUS, &wxGenericCollapsibleHeaderCtrl::OnFocus, this);
74
75 return true;
76 }
77
DoGetBestClientSize() const78 wxSize wxGenericCollapsibleHeaderCtrl::DoGetBestClientSize() const
79 {
80 wxGenericCollapsibleHeaderCtrl* const
81 self = const_cast<wxGenericCollapsibleHeaderCtrl*>(this);
82
83 // The code here parallels that of OnPaint() -- except without drawing.
84 wxClientDC dc(self);
85
86 wxSize size = wxRendererNative::Get().GetCollapseButtonSize(self, dc);
87
88 wxString text;
89 wxControl::FindAccelIndex(GetLabel(), &text);
90
91 const wxSize textSize = dc.GetTextExtent(text);
92
93 size.x += FromDIP(2) + textSize.x;
94 if ( textSize.y > size.y )
95 size.y = textSize.y;
96
97 #ifdef __WXMSW__
98 size.IncBy(wxGetSystemMetrics(SM_CXFOCUSBORDER, this),
99 wxGetSystemMetrics(SM_CYFOCUSBORDER, this));
100 #endif // __WXMSW__
101
102 return size;
103 }
104
SetCollapsed(bool collapsed)105 void wxGenericCollapsibleHeaderCtrl::SetCollapsed(bool collapsed)
106 {
107 m_collapsed = collapsed;
108 Refresh();
109 }
110
DoSetCollapsed(bool collapsed)111 void wxGenericCollapsibleHeaderCtrl::DoSetCollapsed(bool collapsed)
112 {
113 SetCollapsed(collapsed);
114
115 wxCommandEvent evt(wxEVT_COLLAPSIBLEHEADER_CHANGED, GetId());
116 evt.SetEventObject(this);
117 ProcessEvent(evt);
118 }
119
OnFocus(wxFocusEvent & event)120 void wxGenericCollapsibleHeaderCtrl::OnFocus(wxFocusEvent& event)
121 {
122 Refresh();
123 event.Skip();
124 }
125
OnChar(wxKeyEvent & event)126 void wxGenericCollapsibleHeaderCtrl::OnChar(wxKeyEvent& event)
127 {
128 switch (event.GetKeyCode())
129 {
130 case WXK_SPACE:
131 case WXK_RETURN:
132 DoSetCollapsed(!m_collapsed);
133 break;
134 default:
135 event.Skip();
136 break;
137 }
138 }
139
OnEnterWindow(wxMouseEvent & event)140 void wxGenericCollapsibleHeaderCtrl::OnEnterWindow(wxMouseEvent& event)
141 {
142 m_inWindow = true;
143 Refresh();
144 event.Skip();
145 }
146
OnLeaveWindow(wxMouseEvent & event)147 void wxGenericCollapsibleHeaderCtrl::OnLeaveWindow(wxMouseEvent& event)
148 {
149 m_inWindow = false;
150 Refresh();
151 event.Skip();
152 }
153
OnLeftUp(wxMouseEvent & event)154 void wxGenericCollapsibleHeaderCtrl::OnLeftUp(wxMouseEvent& event)
155 {
156 m_mouseDown = false;
157 DoSetCollapsed(!m_collapsed);
158 event.Skip();
159 }
160
OnLeftDown(wxMouseEvent & event)161 void wxGenericCollapsibleHeaderCtrl::OnLeftDown(wxMouseEvent& event)
162 {
163 m_mouseDown = true;
164 Refresh();
165 event.Skip();
166 }
167
OnPaint(wxPaintEvent & WXUNUSED (event))168 void wxGenericCollapsibleHeaderCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
169 {
170 wxPaintDC dc(this);
171
172 wxRect rect(wxPoint(0, 0), GetClientSize());
173
174 wxSize btnSize = wxRendererNative::Get().GetCollapseButtonSize(this, dc);
175
176 wxRect btnRect(wxPoint(0, 0), btnSize);
177 btnRect = btnRect.CenterIn(rect, wxVERTICAL);
178
179 int flags = 0;
180
181 if ( m_inWindow )
182 flags |= wxCONTROL_CURRENT;
183
184 if ( m_mouseDown )
185 flags |= wxCONTROL_PRESSED;
186
187 if ( !m_collapsed )
188 flags |= wxCONTROL_EXPANDED;
189
190 wxRendererNative::Get().DrawCollapseButton(this, dc, btnRect, flags);
191
192 wxString text;
193 int indexAccel = wxControl::FindAccelIndex(GetLabel(), &text);
194
195 wxSize textSize = dc.GetTextExtent(text);
196
197 wxRect textRect(wxPoint(btnSize.x + FromDIP(2), 0), textSize);
198 textRect = textRect.CenterIn(rect, wxVERTICAL);
199
200 dc.DrawLabel(text, textRect, wxALIGN_CENTRE_VERTICAL, indexAccel);
201
202 #ifdef __WXMSW__
203 if ( HasFocus() )
204 wxRendererNative::Get().DrawFocusRect(this, dc, textRect.Inflate(1), flags);
205 #endif
206 }
207
208
209 #endif // wxUSE_COLLPANE
210