]> git.saurik.com Git - wxWidgets.git/blame_incremental - samples/splitter/splitter.cpp
Blind implementation of YieldFor() for OSX/Cocoa, copied from OSX/Carbon
[wxWidgets.git] / samples / splitter / splitter.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: splitter.cpp
3// Purpose: wxSplitterWindow sample
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows license
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#ifndef WX_PRECOMP
28 #include "wx/log.h"
29
30 #include "wx/app.h"
31 #include "wx/frame.h"
32
33 #include "wx/scrolwin.h"
34 #include "wx/menu.h"
35
36 #include "wx/textdlg.h" // for wxGetTextFromUser
37#endif
38
39#include "wx/splitter.h"
40#include "wx/dcmirror.h"
41
42#ifndef __WXMSW__
43 #include "../sample.xpm"
44#endif
45
46// ----------------------------------------------------------------------------
47// constants
48// ----------------------------------------------------------------------------
49
50// ID for the menu commands
51enum
52{
53 SPLIT_QUIT = 1,
54 SPLIT_HORIZONTAL,
55 SPLIT_VERTICAL,
56 SPLIT_UNSPLIT,
57 SPLIT_LIVE,
58 SPLIT_BORDER,
59 SPLIT_3DSASH,
60 SPLIT_SETPOSITION,
61 SPLIT_SETMINSIZE,
62 SPLIT_SETGRAVITY,
63 SPLIT_REPLACE
64};
65
66// ----------------------------------------------------------------------------
67// our classes
68// ----------------------------------------------------------------------------
69
70class MyApp: public wxApp
71{
72public:
73 MyApp() { }
74
75 virtual bool OnInit();
76
77 wxDECLARE_NO_COPY_CLASS(MyApp);
78};
79
80class MyFrame: public wxFrame
81{
82public:
83 MyFrame();
84 virtual ~MyFrame();
85
86 void ToggleFlag(int flag, bool enable);
87
88 // Menu commands
89 void OnSplitHorizontal(wxCommandEvent& event);
90 void OnSplitVertical(wxCommandEvent& event);
91 void OnUnsplit(wxCommandEvent& event);
92 void OnToggleLive(wxCommandEvent& event)
93 { ToggleFlag(wxSP_LIVE_UPDATE, event.IsChecked()); }
94 void OnToggleBorder(wxCommandEvent& event)
95 { ToggleFlag(wxSP_BORDER, event.IsChecked()); }
96 void OnToggle3DSash(wxCommandEvent& event)
97 { ToggleFlag(wxSP_3DSASH, event.IsChecked()); }
98 void OnSetPosition(wxCommandEvent& event);
99 void OnSetMinSize(wxCommandEvent& event);
100 void OnSetGravity(wxCommandEvent& event);
101 void OnReplace(wxCommandEvent &event);
102
103 void OnQuit(wxCommandEvent& event);
104
105 // Menu command update functions
106 void OnUpdateUIHorizontal(wxUpdateUIEvent& event);
107 void OnUpdateUIVertical(wxUpdateUIEvent& event);
108 void OnUpdateUIUnsplit(wxUpdateUIEvent& event);
109
110private:
111 wxScrolledWindow *m_left, *m_right;
112
113 wxSplitterWindow* m_splitter;
114 wxWindow *m_replacewindow;
115
116 DECLARE_EVENT_TABLE()
117 wxDECLARE_NO_COPY_CLASS(MyFrame);
118};
119
120class MySplitterWindow : public wxSplitterWindow
121{
122public:
123 MySplitterWindow(wxFrame *parent);
124
125 // event handlers
126 void OnPositionChanged(wxSplitterEvent& event);
127 void OnPositionChanging(wxSplitterEvent& event);
128 void OnDClick(wxSplitterEvent& event);
129 void OnUnsplitEvent(wxSplitterEvent& event);
130
131private:
132 wxFrame *m_frame;
133
134 DECLARE_EVENT_TABLE()
135 wxDECLARE_NO_COPY_CLASS(MySplitterWindow);
136};
137
138class MyCanvas: public wxScrolledWindow
139{
140public:
141 MyCanvas(wxWindow* parent, bool mirror);
142 virtual ~MyCanvas(){};
143
144 virtual void OnDraw(wxDC& dc);
145
146private:
147 bool m_mirror;
148
149 wxDECLARE_NO_COPY_CLASS(MyCanvas);
150};
151
152// ============================================================================
153// implementation
154// ============================================================================
155
156// ----------------------------------------------------------------------------
157// MyApp
158// ----------------------------------------------------------------------------
159
160IMPLEMENT_APP(MyApp)
161
162bool MyApp::OnInit()
163{
164 if ( !wxApp::OnInit() )
165 return false;
166
167 // create and show the main frame
168 MyFrame* frame = new MyFrame;
169
170 frame->Show(true);
171
172 return true;
173}
174
175// ----------------------------------------------------------------------------
176// MyFrame
177// ----------------------------------------------------------------------------
178
179BEGIN_EVENT_TABLE(MyFrame, wxFrame)
180 EVT_MENU(SPLIT_VERTICAL, MyFrame::OnSplitVertical)
181 EVT_MENU(SPLIT_HORIZONTAL, MyFrame::OnSplitHorizontal)
182 EVT_MENU(SPLIT_UNSPLIT, MyFrame::OnUnsplit)
183 EVT_MENU(SPLIT_LIVE, MyFrame::OnToggleLive)
184 EVT_MENU(SPLIT_BORDER, MyFrame::OnToggleBorder)
185 EVT_MENU(SPLIT_3DSASH, MyFrame::OnToggle3DSash)
186 EVT_MENU(SPLIT_SETPOSITION, MyFrame::OnSetPosition)
187 EVT_MENU(SPLIT_SETMINSIZE, MyFrame::OnSetMinSize)
188 EVT_MENU(SPLIT_SETGRAVITY, MyFrame::OnSetGravity)
189 EVT_MENU(SPLIT_REPLACE, MyFrame::OnReplace)
190
191 EVT_MENU(SPLIT_QUIT, MyFrame::OnQuit)
192
193 EVT_UPDATE_UI(SPLIT_VERTICAL, MyFrame::OnUpdateUIVertical)
194 EVT_UPDATE_UI(SPLIT_HORIZONTAL, MyFrame::OnUpdateUIHorizontal)
195 EVT_UPDATE_UI(SPLIT_UNSPLIT, MyFrame::OnUpdateUIUnsplit)
196END_EVENT_TABLE()
197
198// My frame constructor
199MyFrame::MyFrame()
200 : wxFrame(NULL, wxID_ANY, _T("wxSplitterWindow sample"),
201 wxDefaultPosition, wxSize(420, 300),
202 wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
203{
204 SetIcon(wxICON(sample));
205
206#if wxUSE_STATUSBAR
207 CreateStatusBar(2);
208#endif // wxUSE_STATUSBAR
209
210 // Make a menubar
211 wxMenu *splitMenu = new wxMenu;
212 splitMenu->Append(SPLIT_VERTICAL,
213 _T("Split &Vertically\tCtrl-V"),
214 _T("Split vertically"));
215 splitMenu->Append(SPLIT_HORIZONTAL,
216 _T("Split &Horizontally\tCtrl-H"),
217 _T("Split horizontally"));
218 splitMenu->Append(SPLIT_UNSPLIT,
219 _T("&Unsplit\tCtrl-U"),
220 _T("Unsplit"));
221 splitMenu->AppendSeparator();
222
223 splitMenu->AppendCheckItem(SPLIT_LIVE,
224 _T("&Live update\tCtrl-L"),
225 _T("Toggle live update mode"));
226 splitMenu->AppendCheckItem(SPLIT_BORDER,
227 _T("3D &Border"),
228 _T("Toggle wxSP_BORDER flag"));
229 splitMenu->Check(SPLIT_BORDER, true);
230 splitMenu->AppendCheckItem(SPLIT_3DSASH,
231 _T("&3D Sash"),
232 _T("Toggle wxSP_3DSASH flag"));
233 splitMenu->Check(SPLIT_3DSASH, true);
234 splitMenu->Append(SPLIT_SETPOSITION,
235 _T("Set splitter &position\tCtrl-P"),
236 _T("Set the splitter position"));
237 splitMenu->Append(SPLIT_SETMINSIZE,
238 _T("Set &min size\tCtrl-M"),
239 _T("Set minimum pane size"));
240 splitMenu->Append(SPLIT_SETGRAVITY,
241 _T("Set &gravity\tCtrl-G"),
242 _T("Set gravity of sash"));
243 splitMenu->AppendSeparator();
244
245 splitMenu->Append(SPLIT_REPLACE,
246 _T("&Replace right window"),
247 _T("Replace right window"));
248 splitMenu->AppendSeparator();
249
250 splitMenu->Append(SPLIT_QUIT, _T("E&xit\tAlt-X"), _T("Exit"));
251
252 wxMenuBar *menuBar = new wxMenuBar;
253 menuBar->Append(splitMenu, _T("&Splitter"));
254
255 SetMenuBar(menuBar);
256
257 menuBar->Check(SPLIT_LIVE, true);
258 m_splitter = new MySplitterWindow(this);
259
260 m_splitter->SetSashGravity(1.0);
261
262#if 1
263 m_left = new MyCanvas(m_splitter, true);
264 m_left->SetBackgroundColour(*wxRED);
265 m_left->SetScrollbars(20, 20, 5, 5);
266 m_left->SetCursor(wxCursor(wxCURSOR_MAGNIFIER));
267
268 m_right = new MyCanvas(m_splitter, false);
269 m_right->SetBackgroundColour(*wxCYAN);
270 m_right->SetScrollbars(20, 20, 5, 5);
271#else // for testing kbd navigation inside the splitter
272 m_left = new wxTextCtrl(m_splitter, wxID_ANY, _T("first text"));
273 m_right = new wxTextCtrl(m_splitter, wxID_ANY, _T("second text"));
274#endif
275
276 // you can also do this to start with a single window
277#if 0
278 m_right->Show(false);
279 m_splitter->Initialize(m_left);
280#else
281 // you can also try -100
282 m_splitter->SplitVertically(m_left, m_right, 100);
283#endif
284
285#if wxUSE_STATUSBAR
286 SetStatusText(_T("Min pane size = 0"), 1);
287#endif // wxUSE_STATUSBAR
288
289 m_replacewindow = (wxWindow *)0;
290}
291
292MyFrame::~MyFrame()
293{
294 if (m_replacewindow) {
295 m_replacewindow->Destroy();
296 m_replacewindow = (wxWindow *)0;
297 }
298}
299
300// menu command handlers
301
302void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
303{
304 Close(true);
305}
306
307void MyFrame::OnSplitHorizontal(wxCommandEvent& WXUNUSED(event) )
308{
309 if ( m_splitter->IsSplit() )
310 m_splitter->Unsplit();
311 m_left->Show(true);
312 m_right->Show(true);
313 m_splitter->SplitHorizontally( m_left, m_right );
314
315#if wxUSE_STATUSBAR
316 SetStatusText(_T("Splitter split horizontally"), 1);
317#endif // wxUSE_STATUSBAR
318}
319
320void MyFrame::OnSplitVertical(wxCommandEvent& WXUNUSED(event) )
321{
322 if ( m_splitter->IsSplit() )
323 m_splitter->Unsplit();
324 m_left->Show(true);
325 m_right->Show(true);
326 m_splitter->SplitVertically( m_left, m_right );
327
328#if wxUSE_STATUSBAR
329 SetStatusText(_T("Splitter split vertically"), 1);
330#endif // wxUSE_STATUSBAR
331}
332
333void MyFrame::OnUnsplit(wxCommandEvent& WXUNUSED(event) )
334{
335 if ( m_splitter->IsSplit() )
336 m_splitter->Unsplit();
337#if wxUSE_STATUSBAR
338 SetStatusText(_T("No splitter"));
339#endif // wxUSE_STATUSBAR
340}
341
342void MyFrame::ToggleFlag(int flag, bool enable)
343{
344 long style = m_splitter->GetWindowStyleFlag();
345 if ( enable )
346 style |= flag;
347 else
348 style &= ~flag;
349
350 m_splitter->SetWindowStyleFlag(style);
351
352 // we need to move sash to redraw it
353 int pos = m_splitter->GetSashPosition();
354 m_splitter->SetSashPosition(pos + 1);
355 m_splitter->SetSashPosition(pos);
356}
357
358void MyFrame::OnSetPosition(wxCommandEvent& WXUNUSED(event) )
359{
360 wxString str;
361 str.Printf( wxT("%d"), m_splitter->GetSashPosition());
362#if wxUSE_TEXTDLG
363 str = wxGetTextFromUser(_T("Enter splitter position:"), _T(""), str, this);
364#endif
365 if ( str.empty() )
366 return;
367
368 long pos;
369 if ( !str.ToLong(&pos) )
370 {
371 wxLogError(_T("The splitter position should be an integer."));
372 return;
373 }
374
375 m_splitter->SetSashPosition(pos);
376
377 wxLogStatus(this, _T("Splitter position set to %ld"), pos);
378}
379
380void MyFrame::OnSetMinSize(wxCommandEvent& WXUNUSED(event) )
381{
382 wxString str;
383 str.Printf( wxT("%d"), m_splitter->GetMinimumPaneSize());
384#if wxUSE_TEXTDLG
385 str = wxGetTextFromUser(_T("Enter minimal size for panes:"), _T(""), str, this);
386#endif
387 if ( str.empty() )
388 return;
389
390 int minsize = wxStrtol( str, (wxChar**)NULL, 10 );
391 m_splitter->SetMinimumPaneSize(minsize);
392#if wxUSE_STATUSBAR
393 str.Printf( wxT("Min pane size = %d"), minsize);
394 SetStatusText(str, 1);
395#endif // wxUSE_STATUSBAR
396}
397
398void MyFrame::OnSetGravity(wxCommandEvent& WXUNUSED(event) )
399{
400 wxString str;
401 str.Printf( wxT("%g"), m_splitter->GetSashGravity());
402#if wxUSE_TEXTDLG
403 str = wxGetTextFromUser(_T("Enter sash gravity (0,1):"), _T(""), str, this);
404#endif
405 if ( str.empty() )
406 return;
407
408 double gravity = wxStrtod( str, (wxChar**)NULL);
409 m_splitter->SetSashGravity(gravity);
410#if wxUSE_STATUSBAR
411 str.Printf( wxT("Gravity = %g"), gravity);
412 SetStatusText(str, 1);
413#endif // wxUSE_STATUSBAR
414}
415
416void MyFrame::OnReplace(wxCommandEvent& WXUNUSED(event) )
417{
418 if (m_replacewindow == 0) {
419 m_replacewindow = m_splitter->GetWindow2();
420 m_splitter->ReplaceWindow(m_replacewindow, new wxPanel(m_splitter, wxID_ANY));
421 m_replacewindow->Hide();
422 } else {
423 wxWindow *empty = m_splitter->GetWindow2();
424 m_splitter->ReplaceWindow(empty, m_replacewindow);
425 m_replacewindow->Show();
426 m_replacewindow = 0;
427 empty->Destroy();
428 }
429}
430
431// Update UI handlers
432
433void MyFrame::OnUpdateUIHorizontal(wxUpdateUIEvent& event)
434{
435 event.Enable( (!m_splitter->IsSplit()) || (m_splitter->GetSplitMode() != wxSPLIT_HORIZONTAL) );
436}
437
438void MyFrame::OnUpdateUIVertical(wxUpdateUIEvent& event)
439{
440 event.Enable( ( (!m_splitter->IsSplit()) || (m_splitter->GetSplitMode() != wxSPLIT_VERTICAL) ) );
441}
442
443void MyFrame::OnUpdateUIUnsplit(wxUpdateUIEvent& event)
444{
445 event.Enable( m_splitter->IsSplit() );
446}
447
448// ----------------------------------------------------------------------------
449// MySplitterWindow
450// ----------------------------------------------------------------------------
451
452BEGIN_EVENT_TABLE(MySplitterWindow, wxSplitterWindow)
453 EVT_SPLITTER_SASH_POS_CHANGED(wxID_ANY, MySplitterWindow::OnPositionChanged)
454 EVT_SPLITTER_SASH_POS_CHANGING(wxID_ANY, MySplitterWindow::OnPositionChanging)
455
456 EVT_SPLITTER_DCLICK(wxID_ANY, MySplitterWindow::OnDClick)
457
458 EVT_SPLITTER_UNSPLIT(wxID_ANY, MySplitterWindow::OnUnsplitEvent)
459END_EVENT_TABLE()
460
461MySplitterWindow::MySplitterWindow(wxFrame *parent)
462 : wxSplitterWindow(parent, wxID_ANY,
463 wxDefaultPosition, wxDefaultSize,
464 wxSP_3D | wxSP_LIVE_UPDATE |
465 wxCLIP_CHILDREN /* | wxSP_NO_XP_THEME */ )
466{
467 m_frame = parent;
468}
469
470void MySplitterWindow::OnPositionChanged(wxSplitterEvent& event)
471{
472 wxLogStatus(m_frame, _T("Position has changed, now = %d (or %d)"),
473 event.GetSashPosition(), GetSashPosition());
474
475 event.Skip();
476}
477
478void MySplitterWindow::OnPositionChanging(wxSplitterEvent& event)
479{
480 wxLogStatus(m_frame, _T("Position is changing, now = %d (or %d)"),
481 event.GetSashPosition(), GetSashPosition());
482
483 event.Skip();
484}
485
486void MySplitterWindow::OnDClick(wxSplitterEvent& event)
487{
488#if wxUSE_STATUSBAR
489 m_frame->SetStatusText(_T("Splitter double clicked"), 1);
490#endif // wxUSE_STATUSBAR
491
492 event.Skip();
493}
494
495void MySplitterWindow::OnUnsplitEvent(wxSplitterEvent& event)
496{
497#if wxUSE_STATUSBAR
498 m_frame->SetStatusText(_T("Splitter unsplit"), 1);
499#endif // wxUSE_STATUSBAR
500
501 event.Skip();
502}
503
504// ----------------------------------------------------------------------------
505// MyCanvas
506// ----------------------------------------------------------------------------
507
508MyCanvas::MyCanvas(wxWindow* parent, bool mirror)
509 : wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
510 wxHSCROLL | wxVSCROLL | wxNO_FULL_REPAINT_ON_RESIZE)
511{
512 m_mirror = mirror;
513}
514
515void MyCanvas::OnDraw(wxDC& dcOrig)
516{
517 wxMirrorDC dc(dcOrig, m_mirror);
518
519 dc.SetPen(*wxBLACK_PEN);
520 dc.DrawLine(0, 0, 100, 200);
521
522 dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
523 dc.DrawText(_T("Testing"), 50, 50);
524
525 dc.SetPen(*wxRED_PEN);
526 dc.SetBrush(*wxGREEN_BRUSH);
527 dc.DrawRectangle(120, 120, 100, 80);
528}
529