]> git.saurik.com Git - wxWidgets.git/blame - samples/keyboard/keyboard.cpp
A little black magic... When the C++ object (for a window or
[wxWidgets.git] / samples / keyboard / keyboard.cpp
CommitLineData
7de7aed4
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: keyboard.cpp
3// Purpose: Keyboard wxWindows sample
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 07.04.02
7// RCS-ID: $Id$
8// Copyright: (c) 2002 Vadim Zeitlin
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx/wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27// for all others, include the necessary headers (this file is usually all you
28// need because it includes almost all "standard" wxWindows headers)
29#ifndef WX_PRECOMP
30 #include "wx/wx.h"
31#endif
32
33// ----------------------------------------------------------------------------
34// private classes
35// ----------------------------------------------------------------------------
36
37// Define a new application type, each program should derive a class from wxApp
38class MyApp : public wxApp
39{
40public:
41 // override base class virtuals
42 // ----------------------------
43
44 // this one is called on application startup and is a good place for the app
45 // initialization (doing it here and not in the ctor allows to have an error
46 // return: if OnInit() returns false, the application terminates)
47 virtual bool OnInit();
48};
49
50// Define a new frame type: this is going to be our main frame
51class MyFrame : public wxFrame
52{
53public:
54 // ctor(s)
55 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
56 long style = wxDEFAULT_FRAME_STYLE);
57
58 ~MyFrame() { delete m_logTarget; }
59
60 // event handlers (these functions should _not_ be virtual)
61 void OnQuit(wxCommandEvent& event);
62 void OnAbout(wxCommandEvent& event);
63 void OnClear(wxCommandEvent& event);
64 void OnSkip(wxCommandEvent& event);
62fa9712 65 void OnShowRaw(wxCommandEvent& event);
7de7aed4
VZ
66
67 void OnSize(wxSizeEvent& event);
68
69private:
70 wxLog *m_logTarget;
71
72 class TextWindow *m_winText;
73 wxListBox *m_lboxLog;
74
75 // any class wishing to process wxWindows events must use this macro
76 DECLARE_EVENT_TABLE()
77};
78
79// A log target which just redirects the messages to a listbox
80class LboxLogger : public wxLog
81{
82public:
83 LboxLogger(wxListBox *lbox, wxLog *logOld)
84 {
85 m_lbox = lbox;
86 //m_lbox->Disable(); -- looks ugly under MSW
87 m_logOld = logOld;
88 }
89
90 virtual ~LboxLogger()
91 {
92 wxLog::SetActiveTarget(m_logOld);
93 }
94
95private:
96 // implement sink functions
97 virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t)
98 {
99 // don't put trace messages into listbox or we can get into infinite
100 // recursion
101 if ( level == wxLOG_Trace )
102 {
103 if ( m_logOld )
104 {
105 // cast is needed to call protected method
106 ((LboxLogger *)m_logOld)->DoLog(level, szString, t);
107 }
108 }
109 else
110 {
111 wxLog::DoLog(level, szString, t);
112 }
113 }
114
115 virtual void DoLogString(const wxChar *szString, time_t t)
116 {
117 wxString msg;
118 TimeStamp(&msg);
119 msg += szString;
120
121 #ifdef __WXUNIVERSAL__
122 m_lbox->AppendAndEnsureVisible(msg);
123 #else // other ports don't have this method yet
124 m_lbox->Append(msg);
125 m_lbox->SetFirstItem(m_lbox->GetCount() - 1);
126 #endif
127 }
128
129 // the control we use
130 wxListBox *m_lbox;
131
132 // the old log target
133 wxLog *m_logOld;
134};
135
136class TextWindow : public wxWindow
137{
138public:
139 TextWindow(wxWindow *parent)
140 : wxWindow(parent, -1, wxDefaultPosition, wxDefaultSize,
141 wxRAISED_BORDER)
142 {
143 m_skip = TRUE;
62fa9712 144 m_showRaw = FALSE;
7de7aed4
VZ
145
146 SetBackgroundColour(*wxBLUE);
147 }
148
149 void SetSkip(bool skip) { m_skip = skip; }
62fa9712 150 void SetShowRaw(bool show) { m_showRaw = show; }
7de7aed4
VZ
151
152protected:
153 void OnKeyDown(wxKeyEvent& event) { LogEvent(_T("Key down"), event); }
154 void OnKeyUp(wxKeyEvent& event) { LogEvent(_T("Key up"), event); }
155 void OnChar(wxKeyEvent& event) { LogEvent(_T("Char"), event); }
156
157 void OnPaint(wxPaintEvent& event)
158 {
159 wxPaintDC dc(this);
160 dc.SetTextForeground(*wxWHITE);
161 dc.DrawLabel(_T("Press keys here"), GetClientRect(), wxALIGN_CENTER);
162 }
163
164private:
165 static inline wxChar GetChar(bool on, wxChar c) { return on ? c : _T('-'); }
166
167 void LogEvent(const wxChar *name, wxKeyEvent& event);
168
169 bool m_skip;
62fa9712 170 bool m_showRaw;
7de7aed4
VZ
171
172 DECLARE_EVENT_TABLE()
173};
174
175BEGIN_EVENT_TABLE(TextWindow, wxWindow)
176 EVT_KEY_DOWN(TextWindow::OnKeyDown)
177 EVT_KEY_UP(TextWindow::OnKeyUp)
178 EVT_CHAR(TextWindow::OnChar)
179
180 EVT_PAINT(TextWindow::OnPaint)
181END_EVENT_TABLE()
182
183// ----------------------------------------------------------------------------
184// constants
185// ----------------------------------------------------------------------------
186
187// IDs for the controls and the menu commands
188enum
189{
190 // menu items
191 Keyboard_Quit = 1,
192
193 Keyboard_Clear,
194 Keyboard_Skip,
62fa9712 195 Keyboard_ShowRaw,
7de7aed4
VZ
196
197 // it is important for the id corresponding to the "About" command to have
198 // this standard value as otherwise it won't be handled properly under Mac
199 // (where it is special and put into the "Apple" menu)
200 Keyboard_About = wxID_ABOUT
201};
202
203// ----------------------------------------------------------------------------
204// event tables and other macros for wxWindows
205// ----------------------------------------------------------------------------
206
207// the event tables connect the wxWindows events with the functions (event
208// handlers) which process them. It can be also done at run-time, but for the
209// simple menu events like this the static method is much simpler.
210BEGIN_EVENT_TABLE(MyFrame, wxFrame)
211 EVT_MENU(Keyboard_Quit, MyFrame::OnQuit)
212 EVT_MENU(Keyboard_About, MyFrame::OnAbout)
213
214 EVT_MENU(Keyboard_Clear, MyFrame::OnClear)
215 EVT_MENU(Keyboard_Skip, MyFrame::OnSkip)
62fa9712 216 EVT_MENU(Keyboard_ShowRaw, MyFrame::OnShowRaw)
7de7aed4
VZ
217
218 EVT_SIZE(MyFrame::OnSize)
219END_EVENT_TABLE()
220
221// Create a new application object: this macro will allow wxWindows to create
222// the application object during program execution (it's better than using a
223// static object for many reasons) and also declares the accessor function
224// wxGetApp() which will return the reference of the right type (i.e. MyApp and
225// not wxApp)
226IMPLEMENT_APP(MyApp)
227
228// ============================================================================
229// implementation
230// ============================================================================
231
232// ----------------------------------------------------------------------------
233// the application class
234// ----------------------------------------------------------------------------
235
236// 'Main program' equivalent: the program execution "starts" here
237bool MyApp::OnInit()
238{
239 // create the main application window
240 MyFrame *frame = new MyFrame(_T("Keyboard wxWindows App"),
241 wxPoint(50, 50), wxSize(450, 340));
242
243 // and show it (the frames, unlike simple controls, are not shown when
244 // created initially)
245 frame->Show(TRUE);
246
247 // success: wxApp::OnRun() will be called which will enter the main message
248 // loop and the application will run. If we returned FALSE here, the
249 // application would exit immediately.
250 return TRUE;
251}
252
253// ----------------------------------------------------------------------------
254// main frame
255// ----------------------------------------------------------------------------
256
257// frame constructor
258MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, long style)
259 : wxFrame(NULL, -1, title, pos, size, style),
260 m_winText(NULL)
261{
262#if wxUSE_MENUS
263 // create a menu bar
264 wxMenu *menuFile = new wxMenu;
265 menuFile->Append(Keyboard_Clear, _T("&Clear log\tCtrl-L"));
266 menuFile->AppendSeparator();
267 menuFile->Append(Keyboard_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
268
269 wxMenu *menuKeys = new wxMenu;
62fa9712
VZ
270 menuKeys->AppendCheckItem(Keyboard_ShowRaw, _T("Show &raw keys\tCtrl-R"));
271 menuKeys->AppendSeparator();
7de7aed4
VZ
272 menuKeys->AppendCheckItem(Keyboard_Skip, _T("&Skip key down\tCtrl-S"));
273
274 // the "About" item should be in the help menu
275 wxMenu *menuHelp = new wxMenu;
276 menuHelp->Append(Keyboard_About, _T("&About...\tF1"), _T("Show about dialog"));
277
278 // now append the freshly created menu to the menu bar...
279 wxMenuBar *menuBar = new wxMenuBar();
280 menuBar->Append(menuFile, _T("&File"));
281 menuBar->Append(menuKeys, _T("&Keys"));
282 menuBar->Append(menuHelp, _T("&Help"));
283
284 // ... and attach this menu bar to the frame
285 SetMenuBar(menuBar);
286
287 menuBar->Check(Keyboard_Skip, TRUE);
62fa9712
VZ
288
289#ifndef wxHAS_RAW_KEY_CODES
290 menuBar->Enable(Keyboard_ShowRaw, FALSE);
291#endif // !wxHAS_RAW_KEY_CODES
7de7aed4
VZ
292#endif // wxUSE_MENUS
293
294 m_winText = new TextWindow(this);
295 m_lboxLog = new wxListBox(this, -1);
296
297 m_logTarget = new LboxLogger(m_lboxLog, wxLog::GetActiveTarget());
298 wxLog::SetActiveTarget(m_logTarget);
299
300#if wxUSE_STATUSBAR
301 // create a status bar just for fun (by default with 1 pane only)
302 CreateStatusBar(2);
303 SetStatusText(_T("Welcome to wxWindows!"));
304#endif // wxUSE_STATUSBAR
305}
306
307// event handlers
308
309void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
310{
311 // TRUE is to force the frame to close
312 Close(TRUE);
313}
314
315void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
316{
62fa9712
VZ
317 wxString msg = _T("Demonstrates keyboard event processing in wxWindows\n")
318