]>
Commit | Line | Data |
---|---|---|
4e04f777 WS |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: scroll.cpp | |
3 | // Purpose: wxScrolledWindow sample | |
4 | // Author: Robert Roebling | |
5 | // Modified by: | |
6 | // Created: | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (C) 1998 Robert Roebling, 2002 Ron Lee, 2003 Matt Gregory | |
9 | // Licence: wxWindows license | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
fdd3ed7a RR |
11 | |
12 | // For compilers that support precompilation, includes "wx/wx.h". | |
13 | #include "wx/wxprec.h" | |
14 | ||
15 | #ifdef __BORLANDC__ | |
16 | #pragma hdrstop | |
17 | #endif | |
18 | ||
19 | #ifndef WX_PRECOMP | |
20 | #include "wx/wx.h" | |
21 | #endif | |
22 | ||
23 | #include "wx/image.h" | |
053f9cc1 | 24 | #include "wx/listctrl.h" |
ed673c6a RR |
25 | #include "wx/sizer.h" |
26 | #include "wx/log.h" | |
27 | ||
db4ad642 RR |
28 | const long ID_QUIT = wxID_EXIT; |
29 | const long ID_ABOUT = wxID_ABOUT; | |
30 | const long ID_DELETE_ALL = 100; | |
31 | const long ID_INSERT_NEW = 101; | |
32 | ||
33 | // ---------------------------------------------------------------------- | |
34 | // a trivial example | |
35 | // ---------------------------------------------------------------------- | |
36 | ||
d9f4cc10 | 37 | // MySimpleCanvas: a scrolled window which draws a simple rectangle |
db4ad642 RR |
38 | class MySimpleCanvas: public wxScrolledWindow |
39 | { | |
40 | public: | |
41 | MySimpleCanvas() { } | |
d9f4cc10 | 42 | MySimpleCanvas(wxWindow *parent); |
db4ad642 RR |
43 | |
44 | private: | |
d9f4cc10 VZ |
45 | void OnPaint(wxPaintEvent& event); |
46 | ||
47 | enum | |
48 | { | |
49 | CANVAS_WIDTH = 292, | |
50 | CANVAS_HEIGHT = 297 | |
51 | }; | |
52 | ||
db4ad642 RR |
53 | DECLARE_DYNAMIC_CLASS(MyCanvas) |
54 | DECLARE_EVENT_TABLE() | |
55 | }; | |
56 | ||
57 | IMPLEMENT_DYNAMIC_CLASS(MySimpleCanvas, wxScrolledWindow) | |
58 | ||
59 | BEGIN_EVENT_TABLE(MySimpleCanvas, wxScrolledWindow) | |
60 | EVT_PAINT( MySimpleCanvas::OnPaint) | |
61 | END_EVENT_TABLE() | |
62 | ||
d9f4cc10 VZ |
63 | MySimpleCanvas::MySimpleCanvas(wxWindow *parent) |
64 | : wxScrolledWindow(parent, wxID_ANY, | |
65 | wxDefaultPosition, | |
66 | wxDefaultSize, | |
67 | wxSUNKEN_BORDER) | |
db4ad642 RR |
68 | { |
69 | SetScrollRate( 10, 10 ); | |
d9f4cc10 | 70 | SetVirtualSize( CANVAS_WIDTH, CANVAS_HEIGHT ); |
db4ad642 RR |
71 | SetBackgroundColour( *wxWHITE ); |
72 | } | |
73 | ||
c5a3900a | 74 | void MySimpleCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) |
db4ad642 RR |
75 | { |
76 | wxPaintDC dc(this); | |
77 | PrepareDC( dc ); | |
c5a3900a | 78 | |
db4ad642 RR |
79 | dc.SetPen( *wxRED_PEN ); |
80 | dc.SetBrush( *wxTRANSPARENT_BRUSH ); | |
d9f4cc10 | 81 | dc.DrawRectangle( 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT ); |
db4ad642 RR |
82 | } |
83 | ||
d9f4cc10 | 84 | // MySimpleFrame: a frame which contains a MySimpleCanvas |
db4ad642 RR |
85 | class MySimpleFrame: public wxFrame |
86 | { | |
87 | public: | |
88 | MySimpleFrame(); | |
89 | ||
db4ad642 | 90 | private: |
d9f4cc10 VZ |
91 | void OnClose(wxCommandEvent& WXUNUSED(event)) { Close(true); } |
92 | ||
db4ad642 RR |
93 | DECLARE_DYNAMIC_CLASS(MySimpleFrame) |
94 | DECLARE_EVENT_TABLE() | |
95 | }; | |
96 | ||
97 | ||
98 | IMPLEMENT_DYNAMIC_CLASS( MySimpleFrame, wxFrame ) | |
99 | ||
100 | BEGIN_EVENT_TABLE(MySimpleFrame,wxFrame) | |
d9f4cc10 | 101 | EVT_MENU(wxID_CLOSE, MySimpleFrame::OnClose) |
db4ad642 RR |
102 | END_EVENT_TABLE() |
103 | ||
104 | MySimpleFrame::MySimpleFrame() | |
d9f4cc10 VZ |
105 | : wxFrame(NULL, wxID_ANY, _T("wxScrolledWindow sample"), |
106 | wxDefaultPosition, wxSize(200, 200)) | |
db4ad642 RR |
107 | { |
108 | wxMenu *file_menu = new wxMenu(); | |
d9f4cc10 | 109 | file_menu->Append(wxID_CLOSE); |
db4ad642 RR |
110 | |
111 | wxMenuBar *menu_bar = new wxMenuBar(); | |
112 | menu_bar->Append(file_menu, _T("&File")); | |
113 | ||
114 | SetMenuBar( menu_bar ); | |
115 | ||
d9f4cc10 | 116 | new MySimpleCanvas(this); |
db4ad642 RR |
117 | } |
118 | ||
119 | // ---------------------------------------------------------------------- | |
120 | // a complex example | |
121 | // ---------------------------------------------------------------------- | |
fdd3ed7a RR |
122 | |
123 | // derived classes | |
124 | ||
125 | class MyFrame; | |
126 | class MyApp; | |
127 | ||
128 | // MyCanvas | |
129 | ||
130 | class MyCanvas: public wxScrolledWindow | |
131 | { | |
132 | public: | |
8a73bf3d | 133 | MyCanvas() {} |
fdd3ed7a | 134 | MyCanvas( wxWindow *parent, wxWindowID, const wxPoint &pos, const wxSize &size ); |
925e9792 | 135 | ~MyCanvas(){}; |
fdd3ed7a | 136 | void OnPaint( wxPaintEvent &event ); |
307f16e8 | 137 | void OnQueryPosition( wxCommandEvent &event ); |
ed673c6a RR |
138 | void OnAddButton( wxCommandEvent &event ); |
139 | void OnDeleteButton( wxCommandEvent &event ); | |
140 | void OnMoveButton( wxCommandEvent &event ); | |
141 | void OnScrollWin( wxCommandEvent &event ); | |
4686e0f6 VZ |
142 | void OnMouseRightDown( wxMouseEvent &event ); |
143 | void OnMouseWheel( wxMouseEvent &event ); | |
ed673c6a RR |
144 | |
145 | wxButton *m_button; | |
fdd3ed7a RR |
146 | |
147 | DECLARE_DYNAMIC_CLASS(MyCanvas) | |
148 | DECLARE_EVENT_TABLE() | |
149 | }; | |
150 | ||
2b5f62a0 VZ |
151 | |
152 | // ---------------------------------------------------------------------------- | |
153 | // Autoscrolling example. | |
154 | // ---------------------------------------------------------------------------- | |
155 | ||
156 | // this class uses the 'virtual' size attribute along with an internal | |
157 | // sizer to automatically set up scrollbars as needed | |
158 | ||
159 | class MyAutoScrollWindow : public wxScrolledWindow | |
160 | { | |
161 | private: | |
162 | ||
163 | wxButton *m_button; | |
164 | ||
165 | public: | |
166 | ||
167 | MyAutoScrollWindow( wxWindow *parent ); | |
168 | ||
169 | void OnResizeClick( wxCommandEvent &WXUNUSED( event ) ); | |
170 | ||
171 | DECLARE_EVENT_TABLE() | |
172 | }; | |
173 | ||
174 | ||
8a73bf3d VZ |
175 | // ---------------------------------------------------------------------------- |
176 | // MyScrolledWindow classes: examples of wxScrolledWindow usage | |
177 | // ---------------------------------------------------------------------------- | |
178 | ||
179 | // base class for both of them | |
180 | class MyScrolledWindowBase : public wxScrolledWindow | |
181 | { | |
182 | public: | |
2b5f62a0 VZ |
183 | MyScrolledWindowBase(wxWindow *parent) |
184 | : wxScrolledWindow(parent) | |
185 | , m_nLines( 100 ) | |
8a73bf3d | 186 | { |
2b5f62a0 VZ |
187 | wxClientDC dc(this); |
188 | dc.GetTextExtent(_T("Line 17"), NULL, &m_hLine); | |
8a73bf3d VZ |
189 | } |
190 | ||
191 | protected: | |
8a73bf3d VZ |
192 | // the height of one line on screen |
193 | wxCoord m_hLine; | |
194 | ||
195 | // the number of lines we draw | |
196 | size_t m_nLines; | |
197 | }; | |
198 | ||
199 | // this class does "stupid" redrawing - it redraws everything each time | |
2b5f62a0 VZ |
200 | // and sets the scrollbar extent directly. |
201 | ||
8a73bf3d VZ |
202 | class MyScrolledWindowDumb : public MyScrolledWindowBase |
203 | { | |
204 | public: | |
2b5f62a0 VZ |
205 | MyScrolledWindowDumb(wxWindow *parent) : MyScrolledWindowBase(parent) |
206 | { | |
207 | // no horz scrolling | |
b62ca03d | 208 | SetScrollbars(0, m_hLine, 0, m_nLines + 1, 0, 0, true /* no refresh */); |
2b5f62a0 | 209 | } |
8a73bf3d VZ |
210 | |
211 | virtual void OnDraw(wxDC& dc); | |
212 | }; | |
213 | ||
214 | // this class does "smart" redrawing - only redraws the lines which must be | |
2b5f62a0 VZ |
215 | // redrawn and sets the scroll rate and virtual size to affect the |
216 | // scrollbars. | |
217 | // | |
218 | // Note that this class should produce identical results to the one above. | |
219 | ||
8a73bf3d VZ |
220 | class MyScrolledWindowSmart : public MyScrolledWindowBase |
221 | { | |
222 | public: | |
2b5f62a0 VZ |
223 | MyScrolledWindowSmart(wxWindow *parent) : MyScrolledWindowBase(parent) |
224 | { | |
225 | // no horz scrolling | |
226 | SetScrollRate( 0, m_hLine ); | |
4e04f777 | 227 | SetVirtualSize( wxDefaultCoord, ( m_nLines + 1 ) * m_hLine ); |
2b5f62a0 | 228 | } |
8a73bf3d VZ |
229 | |
230 | virtual void OnDraw(wxDC& dc); | |
231 | }; | |
232 | ||
57ac1a56 RN |
233 | // ---------------------------------------------------------------------------- |
234 | // MyAutoTimedScrollingWindow: implements a text viewer with simple blocksize | |
235 | // selection to test auto-scrolling functionality | |
236 | // ---------------------------------------------------------------------------- | |
237 | ||
238 | class MyAutoTimedScrollingWindow : public wxScrolledWindow | |
239 | { | |
240 | protected: // member data | |
241 | // test data variables | |
242 | static const wxChar* sm_testData; | |
243 | static const int sm_lineCnt; // line count | |
244 | static const int sm_lineLen; // line length in characters | |
245 | // sizes for graphical data | |
246 | wxCoord m_fontH, m_fontW; | |
247 | // selection tracking | |
248 | wxPoint m_selStart; // beginning of blockwise selection | |
249 | wxPoint m_cursor; // end of blockwise selection (mouse position) | |
250 | ||
251 | protected: // gui stuff | |
252 | wxFont m_font; | |
253 | ||
254 | public: // interface | |
255 | MyAutoTimedScrollingWindow( wxWindow* parent ); | |
256 | wxRect DeviceCoordsToGraphicalChars(wxRect updRect) const; | |
257 | wxPoint DeviceCoordsToGraphicalChars(wxPoint pos) const; | |
258 | wxPoint GraphicalCharToDeviceCoords(wxPoint pos) const; | |
259 | wxRect LogicalCoordsToGraphicalChars(wxRect updRect) const; | |
260 | wxPoint LogicalCoordsToGraphicalChars(wxPoint pos) const; | |
261 | wxPoint GraphicalCharToLogicalCoords(wxPoint pos) const; | |
262 | void MyRefresh(); | |
263 | bool IsSelected(int chX, int chY) const; | |
264 | static bool IsInside(int k, int bound1, int bound2); | |
265 | static wxRect DCNormalize(wxCoord x, wxCoord y, wxCoord w, wxCoord h); | |
266 | ||
267 | protected: // event stuff | |
57ac1a56 RN |
268 | void OnDraw(wxDC& dc); |
269 | void OnMouseLeftDown(wxMouseEvent& event); | |
270 | void OnMouseLeftUp(wxMouseEvent& event); | |
271 | void OnMouseMove(wxMouseEvent& event); | |
e0666bdc | 272 | void OnMouseCaptureLost(wxMouseCaptureLostEvent& event); |
57ac1a56 | 273 | void OnScroll(wxScrollWinEvent& event); |
4686e0f6 VZ |
274 | |
275 | DECLARE_EVENT_TABLE() | |
57ac1a56 | 276 | }; |
2b5f62a0 | 277 | |
8a73bf3d | 278 | // ---------------------------------------------------------------------------- |
fdd3ed7a | 279 | // MyFrame |
8a73bf3d | 280 | // ---------------------------------------------------------------------------- |
fdd3ed7a RR |
281 | |
282 | class MyFrame: public wxFrame | |
283 | { | |
284 | public: | |
285 | MyFrame(); | |
286 | ||
287 | void OnAbout( wxCommandEvent &event ); | |
288 | void OnQuit( wxCommandEvent &event ); | |
8e217128 RR |
289 | void OnDeleteAll( wxCommandEvent &event ); |
290 | void OnInsertNew( wxCommandEvent &event ); | |
fdd3ed7a RR |
291 | |
292 | MyCanvas *m_canvas; | |
ed673c6a | 293 | wxTextCtrl *m_log; |
fdd3ed7a RR |
294 | |
295 | DECLARE_DYNAMIC_CLASS(MyFrame) | |
296 | DECLARE_EVENT_TABLE() | |
297 | }; | |
298 | ||
57ac1a56 | 299 | // ---------------------------------------------------------------------------- |
fdd3ed7a | 300 | // MyApp |
57ac1a56 | 301 | // ---------------------------------------------------------------------------- |
fdd3ed7a RR |
302 | |
303 | class MyApp: public wxApp | |
304 | { | |
305 | public: | |
306 | virtual bool OnInit(); | |
307 | }; | |
308 | ||
57ac1a56 RN |
309 | |
310 | // ---------------------------------------------------------------------------- | |
fdd3ed7a | 311 | // main program |
57ac1a56 | 312 | // ---------------------------------------------------------------------------- |
fdd3ed7a RR |
313 | |
314 | IMPLEMENT_APP(MyApp) | |
315 | ||
ed673c6a RR |
316 | // ids |
317 | ||
2b5f62a0 VZ |
318 | const long ID_ADDBUTTON = wxNewId(); |
319 | const long ID_DELBUTTON = wxNewId(); | |
320 | const long ID_MOVEBUTTON = wxNewId(); | |
321 | const long ID_SCROLLWIN = wxNewId(); | |
322 | const long ID_QUERYPOS = wxNewId(); | |
ed673c6a | 323 | |
2b5f62a0 | 324 | const long ID_NEWBUTTON = wxNewId(); |
ed673c6a | 325 | |
57ac1a56 | 326 | // ---------------------------------------------------------------------------- |
fdd3ed7a | 327 | // MyCanvas |
57ac1a56 | 328 | // ---------------------------------------------------------------------------- |
fdd3ed7a RR |
329 | |
330 | IMPLEMENT_DYNAMIC_CLASS(MyCanvas, wxScrolledWindow) | |
331 | ||
332 | BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow) | |
307f16e8 | 333 | EVT_PAINT( MyCanvas::OnPaint) |
4686e0f6 VZ |
334 | EVT_RIGHT_DOWN( MyCanvas::OnMouseRightDown) |
335 | EVT_MOUSEWHEEL( MyCanvas::OnMouseWheel) | |
307f16e8 | 336 | EVT_BUTTON( ID_QUERYPOS, MyCanvas::OnQueryPosition) |
ed673c6a RR |
337 | EVT_BUTTON( ID_ADDBUTTON, MyCanvas::OnAddButton) |
338 | EVT_BUTTON( ID_DELBUTTON, MyCanvas::OnDeleteButton) | |
339 | EVT_BUTTON( ID_MOVEBUTTON, MyCanvas::OnMoveButton) | |
340 | EVT_BUTTON( ID_SCROLLWIN, MyCanvas::OnScrollWin) | |
fdd3ed7a RR |
341 | END_EVENT_TABLE() |
342 | ||
343 | MyCanvas::MyCanvas( wxWindow *parent, wxWindowID id, | |
344 | const wxPoint &pos, const wxSize &size ) | |
2b5f62a0 | 345 | : wxScrolledWindow( parent, id, pos, size, wxSUNKEN_BORDER | wxTAB_TRAVERSAL, _T("test canvas") ) |
fdd3ed7a | 346 | { |
2b5f62a0 VZ |
347 | SetScrollRate( 10, 10 ); |
348 | SetVirtualSize( 500, 1000 ); | |
349 | ||
350 | (void) new wxButton( this, ID_ADDBUTTON, _T("add button"), wxPoint(10,10) ); | |
351 | (void) new wxButton( this, ID_DELBUTTON, _T("del button"), wxPoint(10,40) ); | |
352 | (void) new wxButton( this, ID_MOVEBUTTON, _T("move button"), wxPoint(150,10) ); | |
353 | (void) new wxButton( this, ID_SCROLLWIN, _T("scroll win"), wxPoint(250,10) ); | |
ed673c6a | 354 | |
aa06a8fd DW |
355 | #if 0 |
356 | ||
fdd3ed7a RR |
357 | wxString choices[] = |
358 | { | |
359 | "This", | |
360 | "is one of my", | |
361 | "really", | |
362 | "wonderful", | |
363 | "examples." | |
364 | }; | |
aa06a8fd | 365 | |
307f16e8 | 366 | m_button = new wxButton( this, ID_QUERYPOS, "Query position", wxPoint(10,110) ); |
aa06a8fd | 367 | |
422d0ff0 | 368 | (void) new wxTextCtrl( this, wxID_ANY, "wxTextCtrl", wxPoint(10,150), wxSize(80,wxDefaultCoord) ); |
aa06a8fd | 369 | |
b62ca03d | 370 | (void) new wxRadioButton( this, wxID_ANY, "Disable", wxPoint(10,190) ); |
aa06a8fd | 371 | |
b62ca03d | 372 | (void) new wxComboBox( this, wxID_ANY, "This", wxPoint(10,230), wxDefaultSize, 5, choices ); |
aa06a8fd | 373 | |
b62ca03d | 374 | (void) new wxRadioBox( this, wxID_ANY, "This", wxPoint(10,310), wxDefaultSize, 5, choices, 2, wxRA_SPECIFY_COLS ); |
053f9cc1 | 375 | |
b62ca03d | 376 | (void) new wxRadioBox( this, wxID_ANY, "This", wxPoint(10,440), wxDefaultSize, 5, choices, 2, wxRA_SPECIFY_ROWS ); |
e9158f7d | 377 | |
ed673c6a | 378 | wxListCtrl *m_listCtrl = new wxListCtrl( |
b62ca03d | 379 | this, wxID_ANY, wxPoint(200, 110), wxSize(180, 120), |
8a73bf3d | 380 | wxLC_REPORT | wxSIMPLE_BORDER | wxLC_SINGLE_SEL ); |
053f9cc1 | 381 | |
ed673c6a RR |
382 | m_listCtrl->InsertColumn(0, "First", wxLIST_FORMAT_LEFT, 90); |
383 | m_listCtrl->InsertColumn(1, "Last", wxLIST_FORMAT_LEFT, 90); | |
053f9cc1 | 384 | |
ed673c6a RR |
385 | for ( int i=0; i < 30; i++) |
386 | { | |
387 | char buf[20]; | |
388 | sprintf(buf, "Item %d", i); | |
389 | m_listCtrl->InsertItem(i, buf); | |
390 | } | |
391 | m_listCtrl->SetItemState( 3, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED ); | |
053f9cc1 | 392 | |
b62ca03d | 393 | (void) new wxListBox( this, wxID_ANY, wxPoint(260,280), wxSize(120,120), 5, choices, wxLB_ALWAYS_SB ); |
5e014a0c | 394 | |
aa06a8fd DW |
395 | #endif |
396 | ||
b62ca03d | 397 | wxPanel *test = new wxPanel( this, wxID_ANY, wxPoint(10, 110), wxSize(130,50), wxSIMPLE_BORDER | wxTAB_TRAVERSAL ); |
a60b1f5d | 398 | test->SetBackgroundColour( wxT("WHEAT") ); |
aa06a8fd DW |
399 | |
400 | #if 0 | |
401 | ||
b62ca03d | 402 | wxButton *test2 = new wxButton( test, wxID_ANY, "Hallo", wxPoint(10,10) ); |
aa06a8fd | 403 | |
b62ca03d | 404 | test = new wxPanel( this, wxID_ANY, wxPoint(160, 530), wxSize(130,120), wxSUNKEN_BORDER | wxTAB_TRAVERSAL ); |
a60b1f5d | 405 | test->SetBackgroundColour( wxT("WHEAT") ); |
ed673c6a | 406 | test->SetCursor( wxCursor( wxCURSOR_NO_ENTRY ) ); |
b62ca03d | 407 | test2 = new wxButton( test, wxID_ANY, "Hallo", wxPoint(10,10) ); |
ed673c6a | 408 | test2->SetCursor( wxCursor( wxCURSOR_PENCIL ) ); |
aa06a8fd | 409 | |
b62ca03d | 410 | test = new wxPanel( this, wxID_ANY, wxPoint(310, 530), wxSize(130,120), wxRAISED_BORDER | wxTAB_TRAVERSAL ); |
a60b1f5d | 411 | test->SetBackgroundColour( wxT("WHEAT") ); |
ed673c6a | 412 | test->SetCursor( wxCursor( wxCURSOR_PENCIL ) ); |
b62ca03d | 413 | test2 = new wxButton( test, wxID_ANY, "Hallo", wxPoint(10,10) ); |
ed673c6a | 414 | test2->SetCursor( wxCursor( wxCURSOR_NO_ENTRY ) ); |
5e014a0c | 415 | |
aa06a8fd DW |
416 | #endif |
417 | ||
a60b1f5d | 418 | SetBackgroundColour( wxT("BLUE") ); |
aa06a8fd | 419 | |
ed673c6a | 420 | SetCursor( wxCursor( wxCURSOR_IBEAM ) ); |
fdd3ed7a RR |
421 | } |
422 | ||
4686e0f6 | 423 | void MyCanvas::OnMouseRightDown( wxMouseEvent &event ) |
bf0c00c6 | 424 | { |
4686e0f6 VZ |
425 | wxPoint pt( event.GetPosition() ); |
426 | int x,y; | |
427 | CalcUnscrolledPosition( pt.x, pt.y, &x, &y ); | |
428 | wxLogMessage( wxT("Mouse down event at: %d %d, scrolled: %d %d"), pt.x, pt.y, x, y ); | |
429 | } | |
f6bcfd97 | 430 | |
4686e0f6 VZ |
431 | void MyCanvas::OnMouseWheel( wxMouseEvent &event ) |
432 | { | |
433 | wxPoint pt( event.GetPosition() ); | |
434 | int x,y; | |
435 | CalcUnscrolledPosition( pt.x, pt.y, &x, &y ); | |
436 | wxLogMessage( wxT("Mouse wheel event at: %d %d, scrolled: %d %d\n") | |
437 | wxT("Rotation: %d, delta = %d"), | |
438 | pt.x, pt.y, x, y, | |
439 | event.GetWheelRotation(), event.GetWheelDelta() ); | |
440 | ||
441 | event.Skip(); | |
bf0c00c6 RR |
442 | } |
443 | ||
444 | void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) | |
445 | { | |
446 | wxPaintDC dc( this ); | |
447 | PrepareDC( dc ); | |
448 | ||
2b5f62a0 | 449 | dc.DrawText( _T("Press mouse button to test calculations!"), 160, 50 ); |
bf0c00c6 | 450 | |
2b5f62a0 | 451 | dc.DrawText( _T("Some text"), 140, 140 ); |
aa06a8fd | 452 | |
bf0c00c6 RR |
453 | dc.DrawRectangle( 100, 160, 200, 200 ); |
454 | } | |
455 | ||
307f16e8 RR |
456 | void MyCanvas::OnQueryPosition( wxCommandEvent &WXUNUSED(event) ) |
457 | { | |
458 | wxPoint pt( m_button->GetPosition() ); | |
4693b20c | 459 | wxLogMessage( wxT("Position of \"Query position\" is %d %d"), pt.x, pt.y ); |
bf0c00c6 | 460 | pt = ClientToScreen( pt ); |
4693b20c | 461 | wxLogMessage( wxT("Position of \"Query position\" on screen is %d %d"), pt.x, pt.y ); |
307f16e8 RR |
462 | } |
463 | ||
ed673c6a RR |
464 | void MyCanvas::OnAddButton( wxCommandEvent &WXUNUSED(event) ) |
465 | { | |
4693b20c | 466 | wxLogMessage( wxT("Inserting button at position 10,70...") ); |
2b5f62a0 | 467 | wxButton *button = new wxButton( this, ID_NEWBUTTON, wxT("new button"), wxPoint(10,70), wxSize(80,25) ); |
bf0c00c6 | 468 | wxPoint pt( button->GetPosition() ); |
4693b20c | 469 | wxLogMessage( wxT("-> Position after inserting %d %d"), pt.x, pt.y ); |
ed673c6a RR |
470 | } |
471 | ||
256b8649 | 472 | void MyCanvas::OnDeleteButton( wxCommandEvent &WXUNUSED(event) ) |
ed673c6a | 473 | { |
4693b20c | 474 | wxLogMessage( wxT("Deleting button inserted with \"Add button\"...") ); |
ed673c6a RR |
475 | wxWindow *win = FindWindow( ID_NEWBUTTON ); |
476 | if (win) | |
477 | win->Destroy(); | |
478 | else | |
4693b20c | 479 | wxLogMessage( wxT("-> No window with id = ID_NEWBUTTON found.") ); |
ed673c6a RR |
480 | } |
481 | ||
482 | void MyCanvas::OnMoveButton( wxCommandEvent &event ) | |
483 | { | |
4693b20c | 484 | wxLogMessage( wxT("Moving button 10 pixels downward..") ); |
ed673c6a | 485 | wxWindow *win = FindWindow( event.GetId() ); |
bf0c00c6 | 486 | wxPoint pt( win->GetPosition() ); |
4693b20c | 487 | wxLogMessage( wxT("-> Position before move is %d %d"), pt.x, pt.y ); |
422d0ff0 | 488 | win->Move( wxDefaultCoord, pt.y + 10 ); |
bf0c00c6 | 489 | pt = win->GetPosition(); |
4693b20c | 490 | wxLogMessage( wxT("-> Position after move is %d %d"), pt.x, pt.y ); |
ed673c6a RR |
491 | } |
492 | ||
493 | void MyCanvas::OnScrollWin( wxCommandEvent &WXUNUSED(event) ) | |
494 | { | |
4693b20c | 495 | wxLogMessage( wxT("Scrolling 2 units up.\nThe white square and the controls should move equally!") ); |
ed673c6a | 496 | int x,y; |
8073eb40 | 497 | GetViewStart( &x, &y ); |
4e04f777 | 498 | Scroll( wxDefaultCoord, y+2 ); |
ed673c6a RR |
499 | } |
500 | ||
57ac1a56 | 501 | // ---------------------------------------------------------------------------- |
2b5f62a0 | 502 | // MyAutoScrollWindow |
57ac1a56 | 503 | // ---------------------------------------------------------------------------- |
2b5f62a0 VZ |
504 | |
505 | const long ID_RESIZEBUTTON = wxNewId(); | |
506 | const wxSize SMALL_BUTTON( 100, 50 ); | |
507 | const wxSize LARGE_BUTTON( 300, 100 ); | |
508 | ||
509 | BEGIN_EVENT_TABLE( MyAutoScrollWindow, wxScrolledWindow) | |
510 | EVT_BUTTON( ID_RESIZEBUTTON, MyAutoScrollWindow::OnResizeClick) | |
511 | END_EVENT_TABLE() | |
512 | ||
513 | MyAutoScrollWindow::MyAutoScrollWindow( wxWindow *parent ) | |
c5a3900a | 514 | : wxScrolledWindow( parent, -1, wxDefaultPosition, wxDefaultSize, |
3fa5153e | 515 | wxSUNKEN_BORDER|wxScrolledWindowStyle ) |
2b5f62a0 VZ |
516 | { |
517 | SetBackgroundColour( wxT("GREEN") ); | |
518 | ||
519 | // Set the rate we'd like for scrolling. | |
520 | ||
521 | SetScrollRate( 5, 5 ); | |
522 | ||
523 | // Populate a sizer with a 'resizing' button and some | |
524 | // other static decoration | |
525 | ||
526 | wxFlexGridSizer *innersizer = new wxFlexGridSizer( 2, 2 ); | |
527 | ||
528 | m_button = new wxButton( this, | |
529 | ID_RESIZEBUTTON, | |
530 | _T("Press me"), | |
531 | wxDefaultPosition, | |
532 | SMALL_BUTTON ); | |
533 | ||
2b5f62a0 VZ |
534 | m_button->SetSizeHints( SMALL_BUTTON.GetWidth(), SMALL_BUTTON.GetHeight() ); |
535 | ||
536 | innersizer->Add( m_button, | |
537 | 0, | |
69ce77e2 | 538 | wxALIGN_CENTER | wxALL, |
2b5f62a0 VZ |
539 | 20 ); |
540 | ||
b62ca03d | 541 | innersizer->Add( new wxStaticText( this, wxID_ANY, _T("This is just") ), |
2b5f62a0 VZ |
542 | 0, |
543 | wxALIGN_CENTER ); | |
544 | ||
b62ca03d | 545 | innersizer->Add( new wxStaticText( this, wxID_ANY, _T("some decoration") ), |
2b5f62a0 VZ |
546 | 0, |
547 | wxALIGN_CENTER ); | |
548 | ||
b62ca03d | 549 | innersizer->Add( new wxStaticText( this, wxID_ANY, _T("for you to scroll...") ), |
2b5f62a0 VZ |
550 | 0, |
551 | wxALIGN_CENTER ); | |
552 | ||
553 | // Then use the sizer to set the scrolled region size. | |
554 | ||
555 | SetSizer( innersizer ); | |
556 | } | |
557 | ||
558 | void MyAutoScrollWindow::OnResizeClick( wxCommandEvent &WXUNUSED( event ) ) | |
559 | { | |
560 | // Arbitrarily resize the button to change the minimum size of | |
561 | // the (scrolled) sizer. | |
562 | ||
563 | if( m_button->GetSize() == SMALL_BUTTON ) | |
564 | m_button->SetSizeHints( LARGE_BUTTON.GetWidth(), LARGE_BUTTON.GetHeight() ); | |
565 | else | |
566 | m_button->SetSizeHints( SMALL_BUTTON.GetWidth(), SMALL_BUTTON.GetHeight() ); | |
567 | ||
568 | // Force update layout and scrollbars, since nothing we do here | |
569 | // necessarily generates a size event which would do it for us. | |
570 | ||
571 | FitInside(); | |
572 | } | |
573 | ||
57ac1a56 | 574 | // ---------------------------------------------------------------------------- |
fdd3ed7a | 575 | // MyFrame |
57ac1a56 | 576 | // ---------------------------------------------------------------------------- |
fdd3ed7a | 577 | |
fdd3ed7a RR |
578 | IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame ) |
579 | ||
580 | BEGIN_EVENT_TABLE(MyFrame,wxFrame) | |
8e217128 RR |
581 | EVT_MENU (ID_DELETE_ALL, MyFrame::OnDeleteAll) |
582 | EVT_MENU (ID_INSERT_NEW, MyFrame::OnInsertNew) | |
fdd3ed7a RR |
583 | EVT_MENU (ID_ABOUT, MyFrame::OnAbout) |
584 | EVT_MENU (ID_QUIT, MyFrame::OnQuit) | |
585 | END_EVENT_TABLE() | |
586 | ||
587 | MyFrame::MyFrame() | |
b62ca03d | 588 | : wxFrame( (wxFrame *)NULL, wxID_ANY, _T("wxScrolledWindow sample"), |
57ac1a56 | 589 | wxPoint(20,20), wxSize(800,500) ) |
fdd3ed7a | 590 | { |
ed673c6a | 591 | wxMenu *file_menu = new wxMenu(); |
2b5f62a0 VZ |
592 | file_menu->Append( ID_DELETE_ALL, _T("Delete all")); |
593 | file_menu->Append( ID_INSERT_NEW, _T("Insert new")); | |
594 | file_menu->Append( ID_ABOUT, _T("&About..")); | |
595 | file_menu->Append( ID_QUIT, _T("E&xit\tAlt-X")); | |
fdd3ed7a | 596 | |
ed673c6a | 597 | wxMenuBar *menu_bar = new wxMenuBar(); |
2b5f62a0 | 598 | menu_bar->Append(file_menu, _T("&File")); |
fdd3ed7a | 599 | |
ed673c6a | 600 | SetMenuBar( menu_bar ); |
fdd3ed7a | 601 | |
8520f137 | 602 | #if wxUSE_STATUSBAR |
ed673c6a RR |
603 | CreateStatusBar(2); |
604 | int widths[] = { -1, 100 }; | |
605 | SetStatusWidths( 2, widths ); | |
8520f137 | 606 | #endif // wxUSE_STATUSBAR |
fdd3ed7a | 607 | |
57ac1a56 RN |
608 | wxBoxSizer *topsizer = new wxBoxSizer( wxHORIZONTAL ); |
609 | // subsizer splits topsizer down the middle | |
610 | wxBoxSizer *subsizer = new wxBoxSizer( wxVERTICAL ); | |
2b5f62a0 VZ |
611 | |
612 | // Setting an explicit size here is superfluous, it will be overridden | |
613 | // by the sizer in any case. | |
b62ca03d | 614 | m_canvas = new MyCanvas( this, wxID_ANY, wxPoint(0,0), wxSize(100,100) ); |
8a73bf3d | 615 | |
2b5f62a0 VZ |
616 | // This is done with ScrollRate/VirtualSize in MyCanvas ctor now, |
617 | // both should produce identical results. | |
618 | //m_canvas->SetScrollbars( 10, 10, 50, 100 ); | |
4e04f777 | 619 | |
57ac1a56 RN |
620 | subsizer->Add( m_canvas, 1, wxEXPAND ); |
621 | subsizer->Add( new MyAutoScrollWindow( this ), 1, wxEXPAND ); | |
8a73bf3d VZ |
622 | |
623 | wxSizer *sizerBtm = new wxBoxSizer(wxHORIZONTAL); | |
624 | sizerBtm->Add( new MyScrolledWindowDumb(this), 1, wxEXPAND ); | |
625 | sizerBtm->Add( new MyScrolledWindowSmart(this), 1, wxEXPAND ); | |
57ac1a56 RN |
626 | subsizer->Add( sizerBtm, 1, wxEXPAND ); |
627 | ||
628 | topsizer->Add( subsizer, 1, wxEXPAND ); | |
629 | topsizer->Add( new MyAutoTimedScrollingWindow( this ), 1, wxEXPAND ); | |
ed673c6a | 630 | |
ed673c6a | 631 | SetSizer( topsizer ); |
fdd3ed7a RR |
632 | } |
633 | ||
8e217128 RR |
634 | void MyFrame::OnDeleteAll( wxCommandEvent &WXUNUSED(event) ) |
635 | { | |
636 | m_canvas->DestroyChildren(); | |
637 | } | |
638 | ||
639 | void MyFrame::OnInsertNew( wxCommandEvent &WXUNUSED(event) ) | |
640 | { | |
b62ca03d | 641 | (void)new wxButton( m_canvas, wxID_ANY, _T("Hello"), wxPoint(100,100) ); |
8e217128 RR |
642 | } |
643 | ||
fdd3ed7a RR |
644 | void MyFrame::OnQuit( wxCommandEvent &WXUNUSED(event) ) |
645 | { | |
b62ca03d | 646 | Close( true ); |
fdd3ed7a RR |
647 | } |
648 | ||
649 | void MyFrame::OnAbout( wxCommandEvent &WXUNUSED(event) ) | |
650 | { | |
57ac1a56 RN |
651 | (void)wxMessageBox( _T("wxScroll demo\n") |
652 | _T("Robert Roebling (c) 1998\n") | |
653 | _T("Autoscrolling examples\n") | |
654 | _T("Ron Lee (c) 2002\n") | |
655 | _T("Auto-timed-scrolling example\n") | |
656 | _T("Matt Gregory (c) 2003\n"), | |
657 | _T("About wxScroll Demo"), | |
658 | wxICON_INFORMATION | wxOK ); | |
fdd3ed7a RR |
659 | } |
660 | ||
661 | //----------------------------------------------------------------------------- | |
662 | // MyApp | |
663 | //----------------------------------------------------------------------------- | |
664 | ||
665 | bool MyApp::OnInit() | |
666 | { | |
45e6e6f8 VZ |
667 | if ( !wxApp::OnInit() ) |
668 | return false; | |
669 | ||
db4ad642 RR |
670 | wxFrame *frame = new MyFrame(); |
671 | frame->Show( true ); | |
672 | ||
673 | frame = new MySimpleFrame(); | |
674 | frame->Show(); | |
fdd3ed7a | 675 | |
db4ad642 | 676 | return true; |
fdd3ed7a RR |
677 | } |
678 | ||
8a73bf3d VZ |
679 | // ---------------------------------------------------------------------------- |
680 | // MyScrolledWindowXXX | |
681 | // ---------------------------------------------------------------------------- | |
682 | ||
8a73bf3d VZ |
683 | void MyScrolledWindowDumb::OnDraw(wxDC& dc) |
684 | { | |
685 | // this is useful to see which lines are redrawn | |
686 | static size_t s_redrawCount = 0; | |
687 | dc.SetTextForeground(s_redrawCount++ % 2 ? *wxRED : *wxBLUE); | |
688 | ||
689 | wxCoord y = 0; | |
690 | for ( size_t line = 0; line < m_nLines; line++ ) | |
691 | { | |
692 | wxCoord yPhys; | |
693 | CalcScrolledPosition(0, y, NULL, &yPhys); | |
694 | ||
695 | dc.DrawText(wxString::Format(_T("Line %u (logical %d, physical %d)"), | |
b143cf70 | 696 | unsigned(line), y, yPhys), 0, y); |
8a73bf3d VZ |
697 | y += m_hLine; |
698 | } | |
699 | } | |
700 | ||
701 | void MyScrolledWindowSmart::OnDraw(wxDC& dc) | |
702 | { | |
703 | // this is useful to see which lines are redrawn | |
704 | static size_t s_redrawCount = 0; | |
705 | dc.SetTextForeground(s_redrawCount++ % 2 ? *wxRED : *wxBLUE); | |
706 | ||
707 | // update region is always in device coords, translate to logical ones | |
708 | wxRect rectUpdate = GetUpdateRegion().GetBox(); | |
709 | CalcUnscrolledPosition(rectUpdate.x, rectUpdate.y, | |
710 | &rectUpdate.x, &rectUpdate.y); | |
711 | ||
712 | size_t lineFrom = rectUpdate.y / m_hLine, | |
713 | lineTo = rectUpdate.GetBottom() / m_hLine; | |
714 | ||
715 | if ( lineTo > m_nLines - 1) | |
716 | lineTo = m_nLines - 1; | |
717 | ||
718 | wxCoord y = lineFrom*m_hLine; | |
719 | for ( size_t line = lineFrom; line <= lineTo; line++ ) | |
720 | { | |
721 | wxCoord yPhys; | |
722 | CalcScrolledPosition(0, y, NULL, &yPhys); | |
723 | ||
724 | dc.DrawText(wxString::Format(_T("Line %u (logical %d, physical %d)"), | |
b143cf70 | 725 | unsigned(line), y, yPhys), 0, y); |
8a73bf3d VZ |
726 | y += m_hLine; |
727 | } | |
728 | } | |
57ac1a56 RN |
729 | |
730 | // ---------------------------------------------------------------------------- | |
731 | // MyAutoTimedScrollingWindow | |
732 | // ---------------------------------------------------------------------------- | |
733 | ||
734 | BEGIN_EVENT_TABLE(MyAutoTimedScrollingWindow, wxScrolledWindow) | |
4ba64bde RR |
735 | EVT_LEFT_DOWN(MyAutoTimedScrollingWindow::OnMouseLeftDown) |
736 | EVT_LEFT_UP(MyAutoTimedScrollingWindow::OnMouseLeftUp) | |
737 | EVT_MOTION(MyAutoTimedScrollingWindow::OnMouseMove) | |
e0666bdc | 738 | EVT_MOUSE_CAPTURE_LOST(MyAutoTimedScrollingWindow::OnMouseCaptureLost) |
4ba64bde | 739 | EVT_SCROLLWIN(MyAutoTimedScrollingWindow::OnScroll) |
57ac1a56 RN |
740 | END_EVENT_TABLE() |
741 | ||
742 | MyAutoTimedScrollingWindow::MyAutoTimedScrollingWindow(wxWindow* parent) | |
4e04f777 | 743 | : wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize |
57ac1a56 RN |
744 | //, wxSUNKEN_BORDER) // can't seem to do it this way |
745 | , wxVSCROLL | wxHSCROLL | wxSUNKEN_BORDER) | |
746 | , m_selStart(-1, -1), m_cursor(-1, -1) | |
747 | , m_font(9, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL | |
748 | , wxFONTWEIGHT_NORMAL) | |
749 | { | |
750 | wxClientDC dc(this); | |
751 | // query dc for text size | |
752 | dc.SetFont(m_font); | |
753 | dc.GetTextExtent(wxString(_T("A")), &m_fontW, &m_fontH); | |
754 | // set up the virtual window | |
755 | SetScrollbars(m_fontW, m_fontH, sm_lineLen, sm_lineCnt); | |
756 | } | |
757 | ||
758 | wxRect MyAutoTimedScrollingWindow::DeviceCoordsToGraphicalChars | |
759 | (wxRect updRect) const | |
760 | { | |
761 | wxPoint pos(updRect.GetPosition()); | |
762 | pos = DeviceCoordsToGraphicalChars(pos); | |
763 | updRect.x = pos.x; | |
764 | updRect.y = pos.y; | |
765 | updRect.width /= m_fontW; | |
766 | updRect.height /= m_fontH; | |
767 | // the *CoordsToGraphicalChars() funcs round down to upper-left corner, | |
768 | // so an off-by-one correction is needed | |
769 | ++updRect.width; // kludge | |
770 | ++updRect.height; // kludge | |
771 | return updRect; | |
772 | } | |
773 | ||
774 | wxPoint MyAutoTimedScrollingWindow::DeviceCoordsToGraphicalChars | |
775 | (wxPoint pos) const | |
776 | { | |
777 | pos.x /= m_fontW; | |
778 | pos.y /= m_fontH; | |
779 | int vX, vY; | |
780 | GetViewStart(&vX, &vY); | |
781 | pos.x += vX; | |
782 | pos.y += vY; | |
783 | return pos; | |
784 | } | |
785 | ||
786 | wxPoint MyAutoTimedScrollingWindow::GraphicalCharToDeviceCoords | |
787 | (wxPoint pos) const | |
788 | { | |
789 | int vX, vY; | |
790 | GetViewStart(&vX, &vY); | |
791 | pos.x -= vX; | |
792 | pos.y -= vY; | |
793 | pos.x *= m_fontW; | |
794 | pos.y *= m_fontH; | |
795 | return pos; | |
796 | } | |
797 | ||
798 | wxRect MyAutoTimedScrollingWindow::LogicalCoordsToGraphicalChars | |
799 | (wxRect updRect) const | |
800 | { | |
801 | wxPoint pos(updRect.GetPosition()); | |
802 | pos = LogicalCoordsToGraphicalChars(pos); | |
803 | updRect.x = pos.x; | |
804 | updRect.y = pos.y; | |
805 | updRect.width /= m_fontW; | |
806 | updRect.height /= m_fontH; | |
807 | // the *CoordsToGraphicalChars() funcs round down to upper-left corner, | |
808 | // so an off-by-one correction is needed | |
809 | ++updRect.width; // kludge | |
810 | ++updRect.height; // kludge | |
811 | return updRect; | |
812 | } | |
813 | ||
814 | wxPoint MyAutoTimedScrollingWindow::LogicalCoordsToGraphicalChars | |
815 | (wxPoint pos) const | |
816 | { | |
817 | pos.x /= m_fontW; | |
818 | pos.y /= m_fontH; | |
819 | return pos; | |
820 | } | |
821 | ||
822 | wxPoint MyAutoTimedScrollingWindow::GraphicalCharToLogicalCoords | |
823 | (wxPoint pos) const | |
824 | { | |
825 | pos.x *= m_fontW; | |
826 | pos.y *= m_fontH; | |
827 | return pos; | |
828 | } | |
829 | ||
830 | void MyAutoTimedScrollingWindow::MyRefresh() | |
831 | { | |
832 | static wxPoint lastSelStart(-1, -1), lastCursor(-1, -1); | |
833 | // refresh last selected area (to deselect previously selected text) | |
834 | wxRect lastUpdRect( | |
835 | GraphicalCharToDeviceCoords(lastSelStart), | |
836 | GraphicalCharToDeviceCoords(lastCursor) | |
837 | ); | |
838 | // off-by-one corrections, necessary because it's not possible to know | |
839 | // when to round up until rect is normalized by lastUpdRect constructor | |
840 | lastUpdRect.width += m_fontW; // kludge | |
841 | lastUpdRect.height += m_fontH; // kludge | |
842 | // refresh currently selected (to select previously unselected text) | |
843 | wxRect updRect( | |
844 | GraphicalCharToDeviceCoords(m_selStart), | |
845 | GraphicalCharToDeviceCoords(m_cursor) | |
846 | ); | |
847 | // off-by-one corrections | |
848 | updRect.width += m_fontW; // kludge | |
849 | updRect.height += m_fontH; // kludge | |
850 | // find necessary refresh areas | |
851 | wxCoord rx = lastUpdRect.x; | |
852 | wxCoord ry = lastUpdRect.y; | |
853 | wxCoord rw = updRect.x - lastUpdRect.x; | |
854 | wxCoord rh = lastUpdRect.height; | |
855 | if (rw && rh) { | |
856 | RefreshRect(DCNormalize(rx, ry, rw, rh)); | |
857 | } | |
858 | rx = updRect.x; | |
859 | ry = updRect.y + updRect.height; | |
860 | rw= updRect.width; | |
861 | rh = (lastUpdRect.y + lastUpdRect.height) - (updRect.y + updRect.height); | |
862 | if (rw && rh) { | |
863 | RefreshRect(DCNormalize(rx, ry, rw, rh)); | |
864 | } | |
865 | rx = updRect.x + updRect.width; | |
866 | ry = lastUpdRect.y; | |
867 | rw = (lastUpdRect.x + lastUpdRect.width) - (updRect.x + updRect.width); | |
868 | rh = lastUpdRect.height; | |
869 | if (rw && rh) { | |
870 | RefreshRect(DCNormalize(rx, ry, rw, rh)); | |
871 | } | |
872 | rx = updRect.x; | |
873 | ry = lastUpdRect.y; | |
874 | rw = updRect.width; | |
875 | rh = updRect.y - lastUpdRect.y; | |
876 | if (rw && rh) { | |
877 | RefreshRect(DCNormalize(rx, ry, rw, rh)); | |
878 | } | |
879 | // update last | |
880 | lastSelStart = m_selStart; | |
881 | lastCursor = m_cursor; | |
882 | } | |
883 | ||
884 | bool MyAutoTimedScrollingWindow::IsSelected(int chX, int chY) const | |
885 | { | |
886 | if (IsInside(chX, m_selStart.x, m_cursor.x) | |
887 | && IsInside(chY, m_selStart.y, m_cursor.y)) { | |
4e04f777 | 888 | return true; |
57ac1a56 | 889 | } |
4e04f777 | 890 | return false; |
57ac1a56 RN |
891 | } |
892 | ||
893 | bool MyAutoTimedScrollingWindow::IsInside(int k, int bound1, int bound2) | |
894 | { | |
895 | if ((k >= bound1 && k <= bound2) || (k >= bound2 && k <= bound1)) { | |
4e04f777 | 896 | return true; |
57ac1a56 | 897 | } |
4e04f777 | 898 | return false; |
57ac1a56 RN |
899 | } |
900 | ||
901 | wxRect MyAutoTimedScrollingWindow::DCNormalize(wxCoord x, wxCoord y | |
902 | , wxCoord w, wxCoord h) | |
903 | { | |
904 | // this is needed to get rid of the graphical remnants from the selection | |
905 | // I think it's because DrawRectangle() excludes a pixel in either direction | |
906 | const int kludge = 1; | |
907 | // make (x, y) the top-left corner | |
908 | if (w < 0) { | |
909 | w = -w + kludge; | |
910 | x -= w; | |
911 | } else { | |
912 | x -= kludge; | |
913 | w += kludge; | |
914 | } | |
915 | if (h < 0) { | |
916 | h = -h + kludge; | |
917 | y -= h; | |
918 | } else { | |
919 | y -= kludge; | |
920 | h += kludge; | |
921 | } | |
922 | return wxRect(x, y, w, h); | |
923 | } | |
924 | ||
925 | void MyAutoTimedScrollingWindow::OnDraw(wxDC& dc) | |
926 | { | |
927 | dc.SetFont(m_font); | |
928 | wxBrush normBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW) | |
929 | , wxSOLID); | |
930 | wxBrush selBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT) | |
931 | , wxSOLID); | |
932 | dc.SetPen(*wxTRANSPARENT_PEN); | |
1663ec5f PC |
933 | const wxString str = sm_testData; |
934 | size_t strLength = str.length(); | |
935 | wxString::const_iterator str_i; | |
4e04f777 | 936 | |
57ac1a56 RN |
937 | // draw the characters |
938 | // 1. for each update region | |
939 | for (wxRegionIterator upd(GetUpdateRegion()); upd; ++upd) { | |
57ac1a56 RN |
940 | wxRect updRect = upd.GetRect(); |
941 | wxRect updRectInGChars(DeviceCoordsToGraphicalChars(updRect)); | |
942 | // 2. for each row of chars in the update region | |
943 | for (int chY = updRectInGChars.y | |
944 | ; chY <= updRectInGChars.y + updRectInGChars.height; ++chY) { | |
945 | // 3. for each character in the row | |
1663ec5f | 946 | bool isFirstX = true; |
57ac1a56 RN |
947 | for (int chX = updRectInGChars.x |
948 | ; chX <= updRectInGChars.x + updRectInGChars.width | |
949 | ; ++chX) { | |
950 | // 4. set up dc | |
951 | if (IsSelected(chX, chY)) { | |
952 | dc.SetBrush(selBrush); | |
953 | dc.SetTextForeground( wxSystemSettings::GetColour | |
954 | (wxSYS_COLOUR_HIGHLIGHTTEXT)); | |
955 | } else { | |
956 | dc.SetBrush(normBrush); | |
957 | dc.SetTextForeground( wxSystemSettings::GetColour | |
958 | (wxSYS_COLOUR_WINDOWTEXT)); | |
959 | } | |
960 | // 5. find position info | |
961 | wxPoint charPos = GraphicalCharToLogicalCoords(wxPoint | |
962 | (chX, chY)); | |
963 | // 6. draw! | |
964 | dc.DrawRectangle(charPos.x, charPos.y, m_fontW, m_fontH); | |
4e04f777 WS |
965 | size_t charIndex = chY * sm_lineLen + chX; |
966 | if (chY < sm_lineCnt && | |
967 | chX < sm_lineLen && | |
1663ec5f | 968 | charIndex < strLength) |
4e04f777 | 969 | { |
1663ec5f PC |
970 | if (isFirstX) |
971 | { | |
972 | str_i = str.begin() + charIndex; | |
973 | isFirstX = false; | |
974 | } | |
975 | dc.DrawText(*str_i, charPos.x, charPos.y); | |
976 | ++str_i; | |
57ac1a56 RN |
977 | } |
978 | } | |
979 | } | |
980 | } | |
981 | } | |
982 | ||
983 | void MyAutoTimedScrollingWindow::OnMouseLeftDown(wxMouseEvent& event) | |
984 | { | |
985 | // initial press of mouse button sets the beginning of the selection | |
986 | m_selStart = DeviceCoordsToGraphicalChars(event.GetPosition()); | |
987 | // set the cursor to the same position | |
988 | m_cursor = m_selStart; | |
989 | // draw/erase selection | |
990 | MyRefresh(); | |
991 | } | |
992 | ||
993 | void MyAutoTimedScrollingWindow::OnMouseLeftUp(wxMouseEvent& WXUNUSED(event)) | |
994 | { | |
995 | // this test is necessary | |
996 | if (HasCapture()) { | |
997 | // uncapture mouse | |
998 | ReleaseMouse(); | |
999 | } | |
1000 | } | |
1001 | ||
1002 | void MyAutoTimedScrollingWindow::OnMouseMove(wxMouseEvent& event) | |
1003 | { | |
1004 | // if user is dragging | |
1005 | if (event.Dragging() && event.LeftIsDown()) { | |
1006 | // set the new cursor position | |
1007 | m_cursor = DeviceCoordsToGraphicalChars(event.GetPosition()); | |
1008 | // draw/erase selection | |
1009 | MyRefresh(); | |
1010 | // capture mouse to activate auto-scrolling | |
1011 | if (!HasCapture()) { | |
1012 | CaptureMouse(); | |
1013 | } | |
1014 | } | |
1015 | } | |
1016 | ||
e0666bdc VZ |
1017 | void MyAutoTimedScrollingWindow::OnMouseCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event)) |
1018 | { | |
1019 | // we only capture mouse for timed scrolling, so nothing is needed here | |
1020 | // other than making sure to not call event.Skip() | |
1021 | } | |
1022 | ||
57ac1a56 RN |
1023 | void MyAutoTimedScrollingWindow::OnScroll(wxScrollWinEvent& event) |
1024 | { | |
1025 | // need to move the cursor when autoscrolling | |
1026 | // FIXME: the cursor also moves when the scrollbar arrows are clicked | |
1027 | if (HasCapture()) { | |
1028 | if (event.GetOrientation() == wxHORIZONTAL) { | |
687706f5 | 1029 | if (event.GetEventType() == wxEVT_SCROLLWIN_LINEUP) { |
57ac1a56 | 1030 | --m_cursor.x; |
687706f5 | 1031 | } else if (event.GetEventType() == wxEVT_SCROLLWIN_LINEDOWN) { |
57ac1a56 RN |
1032 | ++m_cursor.x; |
1033 | } | |
1034 | } else if (event.GetOrientation() == wxVERTICAL) { | |
687706f5 | 1035 | if (event.GetEventType() == wxEVT_SCROLLWIN_LINEUP) { |
57ac1a56 | 1036 | --m_cursor.y; |
687706f5 | 1037 | } else if (event.GetEventType() == wxEVT_SCROLLWIN_LINEDOWN) { |
57ac1a56 RN |
1038 | ++m_cursor.y; |
1039 | } | |
1040 | } | |
1041 | } | |
1042 | MyRefresh(); | |
1043 | event.Skip(); | |
1044 | } | |
1045 | ||
1046 | const int MyAutoTimedScrollingWindow::sm_lineCnt = 125; | |
1047 | const int MyAutoTimedScrollingWindow::sm_lineLen = 79; | |
4e04f777 | 1048 | const wxChar* MyAutoTimedScrollingWindow::sm_testData = |
49e7b7a2 | 1049 | _T("162 Cult of the genius out of vanity. Because we think well of ourselves, but ") |
4e04f777 WS |
1050 | _T("nonetheless never suppose ourselves capable of producing a painting like one of ") |
1051 | _T("Raphael's or a dramatic scene like one of Shakespeare's, we convince ourselves ") | |
1052 | _T("that the capacity to do so is quite extraordinarily marvelous, a wholly ") | |
1053 | _T("uncommon accident, or, if we are still religiously inclined, a mercy from on ") | |
1054 | _T("high. Thus our vanity, our self-love, promotes the cult of the genius: for only ") | |
1055 | _T("if we think of him as being very remote from us, as a miraculum, does he not ") | |
1056 | _T("aggrieve us (even Goethe, who was without envy, called Shakespeare his star of ") | |
49e7b7a2 | 1057 | _T("the most distant heights [\"William! Stern der schonsten Ferne\": from Goethe's, ") |
4e04f777 WS |
1058 | _T("\"Between Two Worlds\"]; in regard to which one might recall the lines: \"the ") |
1059 | _T("stars, these we do not desire\" [from Goethe's, \"Comfort in Tears\"]). But, aside ") | |
1060 | _T("from these suggestions of our vanity, the activity of the genius seems in no ") | |
1061 | _T("way fundamentally different from the activity of the inventor of machines, the ") | |
1062 | _T("scholar of astronomy or history, the master of tactics. All these activities ") | |
1063 | _T("are explicable if one pictures to oneself people whose thinking is active in ") | |
1064 | _T("one direction, who employ everything as material, who always zealously observe ") | |
1065 | _T("their own inner life and that of others, who perceive everywhere models and ") | |
1066 | _T("incentives, who never tire of combining together the means available to them. ") | |
1067 | _T("Genius too does nothing except learn first how to lay bricks then how to build, ") | |
1068 | _T("except continually seek for material and continually form itself around it. ") | |
1069 | _T("Every activity of man is amazingly complicated, not only that of the genius: ") | |
49e7b7a2 | 1070 | _T("but none is a \"miracle.\" Whence, then, the belief that genius exists only in ") |
4e04f777 WS |
1071 | _T("the artist, orator and philosopher? that only they have \"intuition\"? (Whereby ") |
1072 | _T("they are supposed to possess a kind of miraculous eyeglass with which they can ") | |
1073 | _T("see directly into \"the essence of the thing\"!) It is clear that people speak of ") | |
1074 | _T("genius only where the effects of the great intellect are most pleasant to them ") | |
1075 | _T("and where they have no desire to feel envious. To call someone \"divine\" means: ") | |
1076 | _T("\"here there is no need for us to compete.\" Then, everything finished and ") | |
1077 | _T("complete is regarded with admiration, everything still becoming is undervalued. ") | |
1078 | _T("But no one can see in the work of the artist how it has become; that is its ") | |
1079 | _T("advantage, for wherever one can see the act of becoming one grows somewhat ") | |
1080 | _T("cool. The finished and perfect art of representation repulses all thinking as ") | |
1081 | _T("to how it has become; it tyrannizes as present completeness and perfection. ") | |
1082 | _T("That is why the masters of the art of representation count above all as gifted ") | |
1083 | _T("with genius and why men of science do not. In reality, this evaluation of the ") | |
1084 | _T("former and undervaluation of the latter is only a piece of childishness in the ") | |
1085 | _T("realm of reason. ") | |
1086 | _T("\n\n") | |
49e7b7a2 | 1087 | _T("163 The serious workman. Do not talk about giftedness, inborn talents! One can ") |
4e04f777 WS |
1088 | _T("name great men of all kinds who were very little gifted. The acquired ") |
1089 | _T("greatness, became \"geniuses\" (as we put it), through qualities the lack of ") | |
1090 | _T("which no one who knew what they were would boast of: they all possessed that ") | |
1091 | _T("seriousness of the efficient workman which first learns to construct the parts ") | |
1092 | _T("properly before it ventures to fashion a great whole; they allowed themselves ") | |
1093 | _T("time for it, because they took more pleasure in making the little, secondary ") | |
1094 | _T("things well than in the effect of a dazzling whole. the recipe for becoming a ") | |
1095 | _T("good novelist, for example, is easy to give, but to carry it out presupposes ") | |
1096 | _T("qualities one is accustomed to overlook when one says \"I do not have enough ") | |
1097 | _T("talent.\" One has only to make a hundred or so sketches for novels, none longer ") | |
1098 | _T("than two pages but of such distinctness that every word in them is necessary; ") | |
1099 | _T("one should write down anecdotes each day until one has learned how to give them ") | |
1100 | _T("the most pregnant and effective form; one should be tireless in collecting and ") | |
1101 | _T("describing human types and characters; one should above all relate things to ") | |
1102 | _T("others and listen to others relate, keeping one's eyes and ears open for the ") | |
1103 | _T("effect produced on those present, one should travel like a landscape painter or ") | |
1104 | _T("costume designer; one should excerpt for oneself out of the individual sciences ") | |
1105 | _T("everything that will produce an artistic effect when it is well described, one ") | |
1106 | _T("should, finally, reflect on the motives of human actions, disdain no signpost ") | |
1107 | _T("to instruction about them and be a collector of these things by day and night. ") | |
1108 | _T("One should continue in this many-sided exercise some ten years: what is then ") | |
49e7b7a2 | 1109 | _T("created in the workshop, however, will be fit to go out into the world. What, ") |
4e04f777 WS |
1110 | _T("however, do most people do? They begin, not with the parts, but with the whole. ") |
1111 | _T("Perhaps they chance to strike a right note, excite attention and from then on ") | |
49e7b7a2 | 1112 | _T("strike worse and worse notes, for good, natural reasons. Sometimes, when the ") |
4e04f777 WS |
1113 | _T("character and intellect needed to formulate such a life-plan are lacking, fate ") |
1114 | _T("and need take their place and lead the future master step by step through all ") | |
1115 | _T("the stipulations of his trade. ") | |
1116 | _T("\n\n") | |
49e7b7a2 | 1117 | _T("164 Peril and profit in the cult of the genius. The belief in great, superior, ") |
4e04f777 WS |
1118 | _T("fruitful spirits is not necessarily, yet nonetheless is very frequently ") |
1119 | _T("associated with that religious or semi-religious superstition that these ") | |
1120 | _T("spirits are of supra-human origin and possess certain miraculous abilities by ") | |
1121 | _T("virtue of which they acquire their knowledge by quite other means than the rest ") | |
1122 | _T("of mankind. One ascribes to them, it seems, a direct view of the nature of the ") | |
1123 | _T("world, as it were a hole in the cloak of appearance, and believes that, by ") | |
1124 | _T("virtue of this miraculous seer's vision, they are able to communicate something ") | |
1125 | _T("conclusive and decisive about man and the world without the toil and ") | |
1126 | _T("rigorousness required by science. As long as there continue to be those who ") | |
1127 | _T("believe in the miraculous in the domain of knowledge one can perhaps concede ") | |
1128 | _T("that these people themselves derive some benefit from their belief, inasmuch as ") | |
1129 | _T("through their unconditional subjection to the great spirits they create for ") | |
1130 | _T("their own spirit during its time of development the finest form of discipline ") | |
1131 | _T("and schooling. On the other hand, it is at least questionable whether the ") | |
1132 | _T("superstitious belief in genius, in its privileges and special abilities, is of ") | |
1133 | _T("benefit to the genius himself if it takes root in him. It is in any event a ") | |
1134 | _T("dangerous sign when a man is assailed by awe of himself, whether it be the ") | |
1135 | _T("celebrated Caesar's awe of Caesar or the awe of one's own genius now under ") | |
1136 | _T("consideration; when the sacrificial incense which is properly rendered only to ") | |
1137 | _T("a god penetrates the brain of the genius, so that his head begins to swim and ") | |
1138 | _T("he comes to regard himself as something supra-human. The consequences that ") | |
1139 | _T("slowly result are: the feeling of irresponsibility, of exceptional rights, the ") | |
1140 | _T("belief that he confers a favor by his mere presence, insane rage when anyone ") | |
1141 | _T("attempts even to compare him with others, let alone to rate him beneath them, ") | |
1142 | _T("or to draw attention to lapses in his work. Because he ceases to practice ") | |
1143 | _T("criticism of himself, at last one pinion after the other falls out of his ") | |
1144 | _T("plumage: that superstitious eats at the roots of his powers and perhaps even ") | |
1145 | _T("turns him into a hypocrite after his powers have fled from him. For the great ") | |
1146 | _T("spirits themselves it is therefore probably more beneficial if they acquire an ") | |
1147 | _T("insight into the nature and origin of their powers, if they grasp, that is to ") | |
1148 | _T("say, what purely human qualities have come together in them and what fortunate ") | |
1149 | _T("circumstances attended them: in the first place undiminished energy, resolute ") | |
1150 | _T("application to individual goals, great personal courage, then the good fortune ") | |
1151 | _T("to receive an upbringing which offered in the early years the finest teachers, ") | |
1152 | _T("models and methods. To be sure, when their goal is the production of the ") | |
1153 | _T("greatest possible effect, unclarity with regard to oneself and that ") | |
1154 | _T("semi-insanity superadded to it has always achieved much; for what has been ") | |
1155 | _T("admired and envied at all times has been that power in them by virtue of which ") | |
1156 | _T("they render men will-less and sweep them away into the delusion that the ") | |
1157 | _T("leaders they are following are supra-natural. Indeed, it elevates and inspires ") | |
1158 | _T("men to believe that someone is in possession of supra-natural powers: to this ") | |
1159 | _T("extent Plato was right to say [Plato: Phaedrus, 244a] that madness has brought ") | |
49e7b7a2 | 1160 | _T("the greatest of blessings upon mankind. In rare individual cases this portion ") |
4e04f777 WS |
1161 | _T("of madness may, indeed, actually have been the means by which such a nature, ") |
1162 | _T("excessive in all directions, was held firmly together: in the life of ") | |
1163 | _T("individuals, too, illusions that are in themselves poisons often play the role ") | |
1164 | _T("of healers; yet, in the end, in the case of every \"genius\" who believes in his ") | |
1165 | _T("own divinity the poison shows itself to the same degree as his \"genius\" grows ") | |
1166 | _T("old: one may recall, for example, the case of Napoleon, whose nature certainly ") | |
1167 | _T("grew into the mighty unity that sets him apart from all men of modern times ") | |
1168 | _T("precisely through his belief in himself and his star and through the contempt ") | |
1169 | _T("for men that flowed from it; until in the end, however, this same belief went ") | |
1170 | _T("over into an almost insane fatalism, robbed him of his acuteness and swiftness ") | |
1171 | _T("of perception, and became the cause of his destruction."); |