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