use more complicated layout; added wxTE_PROCESS_TAB test
[wxWidgets.git] / samples / taborder / taborder.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: taborder.cpp
3 // Purpose: Sample for testing TAB navigation
4 // Author: Vadim Zeitlin
5 // RCS-ID: $Id$
6 // Copyright: (c) 2007 Vadim Zeitlin
7 // Licence: wxWindows license
8 /////////////////////////////////////////////////////////////////////////////
9
10 // ============================================================================
11 // declarations
12 // ============================================================================
13
14 // ----------------------------------------------------------------------------
15 // headers
16 // ----------------------------------------------------------------------------
17
18 #include "wx/wxprec.h"
19
20 #ifdef __BORLANDC__
21 #pragma hdrstop
22 #endif
23
24 #ifndef WX_PRECOMP
25 #include "wx/app.h"
26 #include "wx/frame.h"
27 #include "wx/menu.h"
28
29 #include "wx/panel.h"
30
31 #include "wx/button.h"
32 #include "wx/listbox.h"
33 #include "wx/textctrl.h"
34 #endif
35
36 #include "wx/notebook.h"
37
38 // ----------------------------------------------------------------------------
39 // constants
40 // ----------------------------------------------------------------------------
41
42 // menu commands and controls ids
43 enum
44 {
45 // file menu
46 TabOrder_Quit = wxID_EXIT,
47 TabOrder_About = wxID_ABOUT,
48
49 // navigation menu
50 TabOrder_TabForward = 200,
51 TabOrder_TabBackward,
52
53 TabOrder_Max
54 };
55
56 // status panes: first one is for temporary messages, the second one shows
57 // current focus
58 enum
59 {
60 StatusPane_Default,
61 StatusPane_Focus,
62 StatusPane_Max
63 };
64
65 // ----------------------------------------------------------------------------
66 // declarations of the classes used in this sample
67 // ----------------------------------------------------------------------------
68
69 // the main application class
70 class MyApp : public wxApp
71 {
72 public:
73 virtual bool OnInit();
74 };
75
76 // and the main sample window
77 class MyFrame : public wxFrame
78 {
79 public:
80 MyFrame();
81
82 private:
83 void OnAbout(wxCommandEvent& event);
84 void OnQuit(wxCommandEvent& event);
85
86 void OnTabForward(wxCommandEvent& event);
87 void OnTabBackward(wxCommandEvent& event);
88
89 void OnIdle(wxIdleEvent& event);
90
91 void DoNavigate(long flags)
92 {
93 wxNavigationKeyEvent event;
94 event.SetFlags(flags);
95 if ( m_panel->ProcessEvent(event) )
96 wxLogStatus(this, _T("Navigation event processed"));
97 else
98 wxLogStatus(this, _T("Navigation event ignored"));
99 }
100
101 wxPanel *m_panel;
102
103 DECLARE_EVENT_TABLE()
104 };
105
106 // and the panel taking up MyFrame client area
107 class MyPanel : public wxPanel
108 {
109 public:
110 MyPanel(wxWindow *parent);
111
112 private:
113 wxWindow *CreateButtonPage(wxWindow *parent);
114 wxWindow *CreateTextPage(wxWindow *parent);
115 };
116
117 // a text control which checks if processing Tab presses in controls with
118 // wxTE_PROCESS_TAB style really works
119 class MyTabTextCtrl : public wxTextCtrl
120 {
121 public:
122 MyTabTextCtrl(wxWindow *parent, const wxString& value, int flags = 0)
123 : wxTextCtrl(parent, wxID_ANY, value,
124 wxDefaultPosition, wxDefaultSize,
125 wxTE_PROCESS_TAB)
126 {
127 Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MyTabTextCtrl::OnKeyDown));
128 }
129
130 private:
131 void OnKeyDown(wxKeyEvent& event)
132 {
133 if ( event.GetKeyCode() == WXK_TAB &&
134 wxMessageBox
135 (
136 _T("Let the Tab be used for navigation?"),
137 _T("wxWidgets TabOrder sample: Tab key pressed"),
138 wxICON_QUESTION | wxYES_NO,
139 this
140 ) != wxYES )
141 {
142 // skip Skip() below: we consume the Tab press ourselves and so the
143 // focus shouldn't change
144 return;
145 }
146
147 event.Skip();
148 }
149 };
150
151 // ============================================================================
152 // implementation
153 // ============================================================================
154
155 // ----------------------------------------------------------------------------
156 // MyApp
157 // ----------------------------------------------------------------------------
158
159 IMPLEMENT_APP(MyApp)
160
161 bool MyApp::OnInit()
162 {
163 if ( !wxApp::OnInit() )
164 return false;
165
166 MyFrame *frame = new MyFrame;
167 frame->Show(true);
168
169 return true;
170 }
171
172 // ----------------------------------------------------------------------------
173 // MyFrame
174 // ----------------------------------------------------------------------------
175
176 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
177 EVT_MENU(TabOrder_Quit, MyFrame::OnQuit)
178 EVT_MENU(TabOrder_About, MyFrame::OnAbout)
179
180 EVT_MENU(TabOrder_TabForward, MyFrame::OnTabForward)
181 EVT_MENU(TabOrder_TabBackward, MyFrame::OnTabBackward)
182
183 EVT_IDLE(MyFrame::OnIdle)
184 END_EVENT_TABLE()
185
186 MyFrame::MyFrame()
187 : wxFrame(NULL, wxID_ANY, _T("TabOrder wxWidgets Sample"),
188 wxDefaultPosition, wxSize(700, 450))
189 {
190 wxMenu *menuFile = new wxMenu;
191 menuFile->Append(TabOrder_About);
192 menuFile->AppendSeparator();
193 menuFile->Append(TabOrder_Quit);
194
195 wxMenu *menuNav = new wxMenu;
196 menuNav->Append(TabOrder_TabForward, _T("Tab &forward\tCtrl-F"),
197 _T("Emulate a <Tab> press"));
198 menuNav->Append(TabOrder_TabBackward, _T("Tab &backward\tCtrl-B"),
199 _T("Emulate a <Shift-Tab> press"));
200
201 wxMenuBar *mbar = new wxMenuBar;
202 mbar->Append(menuFile, _T("&File"));
203 mbar->Append(menuNav, _T("&Navigate"));
204
205 SetMenuBar(mbar);
206
207 m_panel = new MyPanel(this);
208
209 CreateStatusBar(StatusPane_Max);
210 }
211
212 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
213 {
214 Close(true);
215 }
216
217 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
218 {
219 wxMessageBox(_T("Tab navigation sample\n(c) 2007 Vadim Zeitlin"),
220 _T("About TabOrder wxWidgets Sample"), wxOK, this);
221 }
222
223 void MyFrame::OnTabForward(wxCommandEvent& WXUNUSED(event))
224 {
225 DoNavigate(wxNavigationKeyEvent::IsForward | wxNavigationKeyEvent::FromTab);
226 }
227
228 void MyFrame::OnTabBackward(wxCommandEvent& WXUNUSED(event))
229 {
230 DoNavigate(wxNavigationKeyEvent::IsBackward | wxNavigationKeyEvent::FromTab);
231 }
232
233 void MyFrame::OnIdle( wxIdleEvent& WXUNUSED(event) )
234 {
235 // track the window which has the focus in the status bar
236 static wxWindow *s_windowFocus = NULL;
237 wxWindow *focus = wxWindow::FindFocus();
238 if ( focus != s_windowFocus )
239 {
240 s_windowFocus = focus;
241
242 wxString msg;
243 if ( focus )
244 {
245 msg.Printf(_T("Focus is at %s"), s_windowFocus->GetName().c_str());
246 }
247 else
248 {
249 msg = _T("No focus");
250 }
251
252 SetStatusText(msg, StatusPane_Focus);
253 }
254 }
255
256 // ----------------------------------------------------------------------------
257 // MyPanel
258 // ----------------------------------------------------------------------------
259
260 MyPanel::MyPanel(wxWindow *parent)
261 : wxPanel(parent, wxID_ANY)
262 {
263 wxNotebook *notebook = new wxNotebook(this, wxID_ANY);
264 notebook->AddPage(CreateButtonPage(notebook), _T("Button"));
265 notebook->AddPage(CreateTextPage(notebook), _T("Text"));
266
267 wxSizer *sizerV = new wxBoxSizer(wxVERTICAL);
268 sizerV->Add(notebook, wxSizerFlags(1).Expand());
269
270 wxListBox *lbox = new wxListBox(this, wxID_ANY);
271 lbox->AppendString(_T("Just a"));
272 lbox->AppendString(_T("simple"));
273 lbox->AppendString(_T("listbox"));
274 sizerV->Add(lbox, wxSizerFlags(1).Expand());
275
276 SetSizerAndFit(sizerV);
277 }
278
279 wxWindow *MyPanel::CreateButtonPage(wxWindow *parent)
280 {
281 wxSizerFlags flagsBorder = wxSizerFlags().Border().Centre();
282
283 wxPanel *page = new wxPanel(parent);
284 wxSizer *sizerPage = new wxBoxSizer(wxHORIZONTAL);
285 sizerPage->Add(new wxButton(page, wxID_ANY, _T("&First")), flagsBorder);
286 sizerPage->Add(new wxStaticText(page, wxID_ANY, _T("[st&atic]")),
287 flagsBorder);
288 sizerPage->Add(new wxButton(page, wxID_ANY, _T("&Second")), flagsBorder);
289
290 page->SetSizer(sizerPage);
291
292 return page;
293 }
294
295 wxWindow *MyPanel::CreateTextPage(wxWindow *parent)
296 {
297 wxSizerFlags flagsBorder = wxSizerFlags().Border();
298
299 wxSizer *sizerPage = new wxBoxSizer(wxVERTICAL);
300 wxPanel *page = new wxPanel(parent);
301
302 wxSizer *sizerH = new wxBoxSizer(wxHORIZONTAL);
303 sizerH->Add(new wxStaticText(page, wxID_ANY, _T("&Label:")), flagsBorder);
304 sizerH->Add(new MyTabTextCtrl(page, _T("TAB ignored here")), flagsBorder);
305 sizerPage->Add(sizerH, wxSizerFlags(1).Expand());
306
307 sizerH = new wxBoxSizer(wxHORIZONTAL);
308 sizerH->Add(new wxStaticText(page, wxID_ANY, _T("&Another one::")), flagsBorder);
309 sizerH->Add(new MyTabTextCtrl(page, _T("press Tab here"), wxTE_PROCESS_TAB),
310 flagsBorder);
311 sizerPage->Add(sizerH, wxSizerFlags(1).Expand());
312
313 page->SetSizer(sizerPage);
314
315 return page;
316 }
317