]> git.saurik.com Git - wxWidgets.git/blob - src/mgl/window.cpp
wxMGL update (no, it still doesn't work, I'm backuping it just in case my disk burns)
[wxWidgets.git] / src / mgl / window.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mgl/window.cpp
3 // Purpose: wxWindow
4 // Author: Vaclav Slavik
5 // (based on GTK & MSW implementations)
6 // RCS-ID: $Id$
7 // Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
8 // Licence: wxWindows license
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ===========================================================================
12 // declarations
13 // ===========================================================================
14
15 // ---------------------------------------------------------------------------
16 // headers
17 // ---------------------------------------------------------------------------
18
19 #ifdef __GNUG__
20 #pragma implementation "window.h"
21 #endif
22
23 // For compilers that support precompilation, includes "wx.h".
24 #include "wx/wxprec.h"
25
26 #ifdef __BORLANDC__
27 #pragma hdrstop
28 #endif
29
30 #ifndef WX_PRECOMP
31 #include "wx/window.h"
32 #include "wx/accel.h"
33 #include "wx/setup.h"
34 #include "wx/dc.h"
35 #include "wx/dcclient.h"
36 #include "wx/utils.h"
37 #include "wx/app.h"
38 #include "wx/panel.h"
39 #include "wx/caret.h"
40 #endif
41
42 #if wxUSE_DRAG_AND_DROP
43 #include "wx/dnd.h"
44 #endif
45
46 #include "wx/log.h"
47 #include "wx/sysopt.h"
48 #include "wx/mgl/private.h"
49 #include "wx/intl.h"
50 #include "wx/dcscreen.h"
51
52 #include <mgraph.hpp>
53
54 #if wxUSE_TOOLTIPS
55 #include "wx/tooltip.h"
56 #endif
57
58 // ---------------------------------------------------------------------------
59 // global variables
60 // ---------------------------------------------------------------------------
61
62 // MGL window manager and associated DC.
63 winmng_t *g_winMng = NULL;
64 MGLDevCtx *g_displayDC = NULL;
65
66 extern wxList WXDLLEXPORT wxPendingDelete;
67 // FIXME_MGL -- ???
68
69 static wxWindowMGL *g_focusedWindow;
70
71 // ---------------------------------------------------------------------------
72 // constants
73 // ---------------------------------------------------------------------------
74
75 // Custom identifiers used to distinguish between various event handlers
76 // and capture handlers passed to MGL_wm
77 enum
78 {
79 wxMGL_CAPTURE_MOUSE = 1,
80 wxMGL_CAPTURE_KEYB = 2
81 };
82
83
84 // ---------------------------------------------------------------------------
85 // private functions
86 // ---------------------------------------------------------------------------
87
88 static void wxWindowPainter(window_t *wnd, MGLDC *dc);
89
90 // wxCreateMGL_WM creates MGL display DC and associates it with winmng_t
91 // structure. Dimensions and depth of the DC are fetched from wxSystemOptions
92 // object.
93 // This function is *not* called from wxApp's initialization but rather at
94 // the time when WM is needed, i.e. when first wxWindow is created. This
95 // has two important effects:
96 // a) it is possible to write windowless wxMGL apps
97 // b) the app has plenty of time in wxApp::OnInit to feed wxSystemOptions
98 // with desired settings
99
100 bool wxCreateMGL_WM()
101 {
102 int mode;
103 int width = 640, height = 480, depth = 16;
104 int refresh = MGL_DEFAULT_REFRESH;
105
106 #if wxUSE_SYSTEM_OPTIONS
107 if ( wxSystemOptions::HasOption(wxT("mgl.screen-width") )
108 width = wxSystemOptions::GetOptionInt(wxT("mgl.screen-width"));
109 if ( wxSystemOptions::HasOption(wxT("mgl.screen-height") )
110 height = wxSystemOptions::GetOptionInt(wxT("mgl.screen-height"));
111 if ( wxSystemOptions::HasOption(wxT("mgl.screen-depth") )
112 depth = wxSystemOptions::GetOptionInt(wxT("mgl.screen-depth"));
113 if ( wxSystemOptions::HasOption(wxT("mgl.screen-refresh") )
114 refresh = wxSystemOptions::GetOptionInt(wxT("mgl.screen-refresh"));
115 #endif
116
117 mode = MGL_findMode(width, height, depth);
118 if ( mode == -1 )
119 {
120 wxLogWarning(_("Mode %ix%i-%i not available, falling back to default mode."), width, height, depth);
121 mode = 0; // always available
122 }
123 g_displayDC = new MGLDisplayDC(mode, 1, refresh);
124 if ( !g_displayDC->isValid() )
125 {
126 delete g_displayDC;
127 g_displayDC = NULL;
128 return FALSE;
129 }
130
131 g_winMng = MGL_wmCreate(g_displayDC->getDC());
132 if (!g_winMng)
133 return FALSE;
134
135 return TRUE;
136 }
137
138 void wxDestroyMGL_WM()
139 {
140 if (g_winMng)
141 {
142 MGL_wmDestroy(g_winMng);
143 g_winMng = NULL;
144 }
145 delete g_displayDC;
146 g_displayDC = NULL;
147 }
148
149
150 // ---------------------------------------------------------------------------
151 // event tables
152 // ---------------------------------------------------------------------------
153
154 // in wxUniv/MSW this class is abstract because it doesn't have DoPopupMenu()
155 // method
156 IMPLEMENT_ABSTRACT_CLASS(wxWindowMGL, wxWindowBase)
157
158 BEGIN_EVENT_TABLE(wxWindowMGL, wxWindowBase)
159 EVT_ERASE_BACKGROUND(wxWindowMGL::OnEraseBackground)
160 EVT_SET_FOCUS(wxWindowMGL::OnSetFocus)
161 END_EVENT_TABLE()
162
163 // ===========================================================================
164 // implementation
165 // ===========================================================================
166
167 // ----------------------------------------------------------------------------
168 // constructors and such
169 // ----------------------------------------------------------------------------
170
171 void wxWindowMGL::Init()
172 {
173 // generic:
174 InitBase();
175
176 // mgl specific:
177 if ( !g_winMng && !wxCreateMGL_WM() )
178 wxFatalError(_T("Can't initalize MGL, aborting!"));
179
180 m_wnd = NULL;
181 m_isShown = TRUE;
182 m_isBeingDeleted = FALSE;
183 m_isEnabled = TRUE;
184 m_frozen = FALSE;
185 m_paintMGLDC = NULL;
186 }
187
188 // Destructor
189 wxWindowMGL::~wxWindowMGL()
190 {
191 m_isBeingDeleted = TRUE;
192
193 if ( g_focusedWindow == this )
194 g_focusedWindow = NULL;
195 #if 0 // -- fixme - do we need this?
196 // VS: make sure there's no wxFrame with last focus set to us:
197 for (wxWindow *win = GetParent(); win; win = win->GetParent())
198 {
199 wxFrame *frame = wxDynamicCast(win, wxFrame);
200 if ( frame )
201 {
202 if ( frame->GetLastFocus() == this )
203 frame->SetLastFocus((wxWindow*)NULL);
204 break;
205 }
206 }
207 #endif
208
209 // VS: destroy children first and _then_ detach *this from its parent.
210 // If we'd do it the other way around, children wouldn't be able
211 // find their parent frame (see above).
212 DestroyChildren();
213
214 if ( m_parent )
215 m_parent->RemoveChild(this);
216
217 if ( m_wnd )
218 MGL_wmDestroyWindow(m_wnd);
219 }
220
221 // real construction (Init() must have been called before!)
222 bool wxWindowMGL::Create(wxWindow *parent,
223 wxWindowID id,
224 const wxPoint& pos,
225 const wxSize& size,
226 long style,
227 const wxString& name)
228 {
229 wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") );
230
231 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
232 return FALSE;
233
234 parent->AddChild(this);
235
236 if ( style & wxPOPUP_WINDOW )
237 {
238 // it is created hidden as other top level windows
239 m_isShown = FALSE;
240 }
241
242 m_wnd = MGL_wmCreateWindow(g_winMng,
243 parent ? parent->GetHandle() : NULL,
244 pos.x, pos.y, size.x, size.y);
245 MGL_wmSetWindowUserData(m_wnd, (void*) this);
246 MGL_wmSetWindowPainter(m_wnd, wxWindowPainter);
247 return TRUE;
248 }
249
250 // ---------------------------------------------------------------------------
251 // basic operations
252 // ---------------------------------------------------------------------------
253
254 void wxWindowMGL::SetFocus()
255 {
256 if (g_focusedWindow)
257 g_focusedWindow->KillFocus();
258
259 g_focusedWindow = this;
260
261 MGL_wmCaptureEvents(GetHandle(), EVT_KEYEVT | EVT_JOYEVT, wxMGL_CAPTURE_KEYB);
262
263 wxPanel *panel = wxDynamicCast(GetParent(), wxPanel);
264 if (panel)
265 panel->SetLastFocus((wxWindow*)this);
266
267 #if wxUSE_CARET
268 // caret needs to be informed about focus change
269 wxCaret *caret = GetCaret();
270 if (caret)
271 caret->OnSetFocus();
272 #endif // wxUSE_CARET
273
274 if (IsTopLevel())
275 {
276 wxActivateEvent event(wxEVT_ACTIVATE, TRUE, GetId());
277 event.SetEventObject(this);
278 GetEventHandler()->ProcessEvent(event);
279 }
280
281 wxFocusEvent event(wxEVT_SET_FOCUS, GetId());
282 event.SetEventObject(this);
283 GetEventHandler()->ProcessEvent(event);
284 }
285
286 void wxWindowMGL::KillFocus()
287 {
288 if ( g_focusedWindow != this ) return;
289 g_focusedWindow = NULL;
290
291 MGL_wmUncaptureEvents(GetHandle(), wxMGL_CAPTURE_KEYB);
292
293 #if wxUSE_CARET
294 // caret needs to be informed about focus change
295 wxCaret *caret = GetCaret();
296 if (caret)
297 caret->OnKillFocus();
298 #endif // wxUSE_CARET
299
300 if (IsTopLevel())
301 {
302 wxActivateEvent event(wxEVT_ACTIVATE, FALSE, GetId());
303 event.SetEventObject(this);
304 GetEventHandler()->ProcessEvent(event);
305 }
306
307 wxFocusEvent event(wxEVT_KILL_FOCUS, GetId());
308 event.SetEventObject(this);
309 GetEventHandler()->ProcessEvent(event);
310 }
311
312 // ----------------------------------------------------------------------------
313 // this wxWindowBase function is implemented here (in platform-specific file)
314 // because it is static and so couldn't be made virtual
315 // ----------------------------------------------------------------------------
316 wxWindow *wxWindowBase::FindFocus()
317 {
318 return (wxWindow*)g_focusedWindow;
319 }
320
321 bool wxWindowMGL::Show(bool show)
322 {
323 if ( !wxWindowBase::Show(show) )
324 return FALSE;
325
326 MGL_wmShowWindow(m_wnd, show);
327 return TRUE;
328 }
329
330 // Raise the window to the top of the Z order
331 void wxWindowMGL::Raise()
332 {
333 MGL_wmRaiseWindow(m_wnd);
334 }
335
336 // Lower the window to the bottom of the Z order
337 void wxWindowMGL::Lower()
338 {
339 MGL_wmLowerWindow(m_wnd);
340 }
341
342 void wxWindowMGL::CaptureMouse()
343 {
344 MGL_wmCaptureEvents(m_wnd, EVT_MOUSEEVT, wxMGL_CAPTURE_MOUSE);
345 }
346
347 void wxWindowMGL::ReleaseMouse()
348 {
349 MGL_wmUncaptureEvents(m_wnd, wxMGL_CAPTURE_MOUSE);
350 }
351
352 /* static */ wxWindow *wxWindowBase::GetCapture()
353 {
354 for (captureentry_t *c = g_winMng->capturedEvents; c; c = c->next)
355 {
356 if ( c->id == wxMGL_CAPTURE_MOUSE )
357 return (wxWindow*)c->wnd->userData;
358 }
359 return NULL;
360 }
361
362 bool wxWindowMGL::SetCursor(const wxCursor& cursor)
363 {
364 if ( !wxWindowBase::SetCursor(cursor) )
365 {
366 // no change
367 return FALSE;
368 }
369
370 if ( m_cursor.Ok() )
371 MGL_wmSetWindowCursor(m_wnd, *m_cursor.GetMGLCursor());
372
373 return TRUE;
374 }
375
376 void wxWindowMGL::WarpPointer(int x, int y)
377 {
378 ClientToScreen(&x, &y);
379 EVT_setMousePos(x, y);
380 }
381
382 #if WXWIN_COMPATIBILITY
383 // If nothing defined for this, try the parent.
384 // E.g. we may be a button loaded from a resource, with no callback function
385 // defined.
386 void wxWindowMGL::OnCommand(wxWindow& win, wxCommandEvent& event)
387 {
388 if ( GetEventHandler()->ProcessEvent(event) )
389 return;
390 if ( m_parent )
391 m_parent->GetEventHandler()->OnCommand(win, event);
392 }
393 #endif // WXWIN_COMPATIBILITY_2
394
395 #if WXWIN_COMPATIBILITY
396 wxObject* wxWindowMGL::GetChild(int number) const
397 {
398 // Return a pointer to the Nth object in the Panel
399 wxNode *node = GetChildren().First();
400 int n = number;
401 while (node && n--)
402 node = node->Next();
403 if ( node )
404 {
405 wxObject *obj = (wxObject *)node->Data();
406 return(obj);
407 }
408 else
409 return NULL;
410 }
411 #endif // WXWIN_COMPATIBILITY
412
413 // Set this window to be the child of 'parent'.
414 bool wxWindowMGL::Reparent(wxWindowBase *parent)
415 {
416 if ( !wxWindowBase::Reparent(parent) )
417 return FALSE;
418
419 MGL_wmReparentWindow(m_wnd, parent->GetHandle());
420
421 return TRUE;
422 }
423
424
425 // ---------------------------------------------------------------------------
426 // drag and drop
427 // ---------------------------------------------------------------------------
428
429 #if wxUSE_DRAG_AND_DROP
430
431 void wxWindowMGL::SetDropTarget(wxDropTarget *pDropTarget)
432 {
433 if ( m_dropTarget != 0 ) {
434 m_dropTarget->Revoke(m_hWnd);
435 delete m_dropTarget;
436 }
437
438 m_dropTarget = pDropTarget;
439 if ( m_dropTarget != 0 )
440 m_dropTarget->Register(m_hWnd);
441 }
442 // FIXME_MGL
443 #endif // wxUSE_DRAG_AND_DROP
444
445 // old style file-manager drag&drop support: we retain the old-style
446 // DragAcceptFiles in parallel with SetDropTarget.
447 void wxWindowMGL::DragAcceptFiles(bool accept)
448 {
449 #if 0 // FIXME_MGL
450 HWND hWnd = GetHwnd();
451 if ( hWnd )
452 ::DragAcceptFiles(hWnd, (BOOL)accept);
453 #endif
454 }
455
456 // ---------------------------------------------------------------------------
457 // moving and resizing
458 // ---------------------------------------------------------------------------
459
460 // Get total size
461 void wxWindowMGL::DoGetSize(int *x, int *y) const
462 {
463 if (x) *x = m_wnd->width;
464 if (y) *y = m_wnd->height;
465 }
466
467 void wxWindowMGL::DoGetPosition(int *x, int *y) const
468 {
469 if (x) *x = m_wnd->x;
470 if (y) *y = m_wnd->y;
471 }
472
473 void wxWindowMGL::DoScreenToClient(int *x, int *y) const
474 {
475 int ax, ay;
476 wxPoint co = GetClientAreaOrigin();
477
478 MGL_wmCoordGlobalToLocal(m_wnd, m_wnd->x, m_wnd->y, &ax, &ay);
479 ax -= co.x;
480 ay -= co.y;
481 if (x)
482 *x = ax;
483 if (y)
484 *y = ay;
485 }
486
487 void wxWindowMGL::DoClientToScreen(int *x, int *y) const
488 {
489 int ax, ay;
490 wxPoint co = GetClientAreaOrigin();
491
492 MGL_wmCoordGlobalToLocal(m_wnd, m_wnd->x+co.x, m_wnd->y+co.y, &ax, &ay);
493 if (x)
494 *x = ax;
495 if (y)
496 *y = ay;
497 }
498
499 // Get size *available for subwindows* i.e. excluding menu bar etc.
500 void wxWindowMGL::DoGetClientSize(int *x, int *y) const
501 {
502 DoGetSize(x, y);
503 }
504
505 void wxWindowMGL::DoMoveWindow(int x, int y, int width, int height)
506 {
507 MGL_wmSetWindowPosition(GetHandle(), x, y, width, height);
508 }
509
510 // set the size of the window: if the dimensions are positive, just use them,
511 // but if any of them is equal to -1, it means that we must find the value for
512 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
513 // which case -1 is a valid value for x and y)
514 //
515 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
516 // the width/height to best suit our contents, otherwise we reuse the current
517 // width/height
518 void wxWindowMGL::DoSetSize(int x, int y, int width, int height, int sizeFlags)
519 {
520 // get the current size and position...
521 int currentX, currentY;
522 GetPosition(&currentX, &currentY);
523 int currentW,currentH;
524 GetSize(&currentW, &currentH);
525
526 // ... and don't do anything (avoiding flicker) if it's already ok
527 if ( x == currentX && y == currentY &&
528 width == currentW && height == currentH )
529 {
530 return;
531 }
532
533 if ( x == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
534 x = currentX;
535 if ( y == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
536 y = currentY;
537
538 #if 0 // FIXME_MGL -- what's this good for?
539 AdjustForParentClientOrigin(x, y, sizeFlags);
540 #endif
541
542 wxSize size(-1, -1);
543 if ( width == -1 )
544 {
545 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
546 {
547 size = DoGetBestSize();
548 width = size.x;
549 }
550 else
551 {
552 // just take the current one
553 width = currentW;
554 }
555 }
556
557 if ( height == -1 )
558 {
559 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
560 {
561 if ( size.x == -1 )
562 {
563 size = DoGetBestSize();
564 }
565 //else: already called DoGetBestSize() above
566
567 height = size.y;
568 }
569 else
570 {
571 // just take the current one
572 height = currentH;
573 }
574 }
575
576 DoMoveWindow(x, y, width, height);
577
578 wxSizeEvent event(wxSize(width, height), GetId());
579 event.SetEventObject(this);
580 GetEventHandler()->ProcessEvent(event);
581 }
582
583 void wxWindowMGL::DoSetClientSize(int width, int height)
584 {
585 SetSize(width, height);
586 }
587
588 // ---------------------------------------------------------------------------
589 // text metrics
590 // ---------------------------------------------------------------------------
591
592 int wxWindowMGL::GetCharHeight() const
593 {
594 wxScreenDC dc;
595 dc.SetFont(m_font);
596 return dc.GetCharHeight();
597 }
598
599 int wxWindowMGL::GetCharWidth() const
600 {
601 wxScreenDC dc;
602 dc.SetFont(m_font);
603 return dc.GetCharWidth();
604 }
605
606 void wxWindowMGL::GetTextExtent(const wxString& string,
607 int *x, int *y,
608 int *descent, int *externalLeading,
609 const wxFont *theFont) const
610 {
611 wxScreenDC dc;
612 if (!theFont)
613 theFont = &m_font;
614 dc.GetTextExtent(string, x, y, descent, externalLeading, (wxFont*)theFont);
615 }
616
617 #if wxUSE_CARET && WXWIN_COMPATIBILITY
618 // ---------------------------------------------------------------------------
619 // Caret manipulation
620 // ---------------------------------------------------------------------------
621
622 void wxWindowMGL::CreateCaret(int w, int h)
623 {
624 SetCaret(new wxCaret(this, w, h));
625 }
626
627 void wxWindowMGL::CreateCaret(const wxBitmap *WXUNUSED(bitmap))
628 {
629 wxFAIL_MSG("not implemented");
630 }
631
632 void wxWindowMGL::ShowCaret(bool show)
633 {
634 wxCHECK_RET( m_caret, "no caret to show" );
635
636 m_caret->Show(show);
637 }
638
639 void wxWindowMGL::DestroyCaret()
640 {
641 SetCaret(NULL);
642 }
643
644 void wxWindowMGL::SetCaretPos(int x, int y)
645 {
646 wxCHECK_RET( m_caret, "no caret to move" );
647
648 m_caret->Move(x, y);
649 }
650
651 void wxWindowMGL::GetCaretPos(int *x, int *y) const
652 {
653 wxCHECK_RET( m_caret, "no caret to get position of" );
654
655 m_caret->GetPosition(x, y);
656 }
657 #endif // wxUSE_CARET
658
659
660 // ---------------------------------------------------------------------------
661 // activation/focus
662 // ---------------------------------------------------------------------------
663
664 void wxWindowMGL::OnSetFocus(wxFocusEvent& event)
665 {
666 // panel wants to track the window which was the last to have focus in it,
667 // so we want to set ourselves as the window which last had focus
668 //
669 // notice that it's also important to do it upwards the tree becaus
670 // otherwise when the top level panel gets focus, it won't set it back to
671 // us, but to some other sibling
672 wxWindow *win = (wxWindow *)this;
673 while ( win )
674 {
675 wxWindow *parent = win->GetParent();
676 wxPanel *panel = wxDynamicCast(parent, wxPanel);
677 if ( panel )
678 {
679 panel->SetLastFocus(win);
680 }
681
682 win = parent;
683 }
684
685 event.Skip();
686 }
687
688
689 // ---------------------------------------------------------------------------
690 // painting
691 // ---------------------------------------------------------------------------
692
693 void wxWindowMGL::Clear()
694 {
695 wxClientDC dc((wxWindow *)this);
696 wxBrush brush(GetBackgroundColour(), wxSOLID);
697 dc.SetBackground(brush);
698 dc.Clear();
699 }
700
701 void wxWindowMGL::Refresh(bool WXUNUSED(eraseBack), const wxRect *rect)
702 {
703 if ( rect )
704 {
705 rect_t r;
706 r.left = rect->GetLeft(), r.right = rect->GetRight();
707 r.top = rect->GetTop(), r.bottom = rect->GetBottom();
708 MGL_wmInvalidateWindowRect(GetHandle(), &r);
709 }
710 else
711 MGL_wmInvalidateWindow(GetHandle());
712 }
713
714 void wxWindowMGL::Update()
715 {
716 Refresh();
717 if ( !m_frozen )
718 MGL_wmUpdateDC(g_winMng);
719 }
720
721 void wxWindowMGL::Freeze()
722 {
723 m_frozen = TRUE;
724 m_refreshAfterThaw = FALSE;
725 }
726
727 void wxWindowMGL::Thaw()
728 {
729 m_frozen = FALSE;
730 if ( m_refreshAfterThaw )
731 Refresh();
732 }
733
734 static void wxWindowPainter(window_t *wnd, MGLDC *dc)
735 {
736 wxWindow *w = (wxWindow*) wnd->userData;
737 if (w)
738 {
739 MGLDevCtx ctx(dc);
740 w->HandlePaint(&ctx);
741 }
742 }
743
744 void wxWindowMGL::HandlePaint(MGLDevCtx *dc)
745 {
746 if ( m_frozen )
747 {
748 // Don't paint anything if the window is frozen.
749 return;
750 }
751
752 region_t *clip = NULL;
753 MGL_getClipRegionDC(*dc, clip);
754 m_updateRegion = wxRegion(MGLRegion(clip));
755 m_paintMGLDC = dc;
756
757 wxEraseEvent eventEr(m_windowId, NULL);
758 eventEr.SetEventObject(this);
759 GetEventHandler()->ProcessEvent(eventEr);
760
761 wxNcPaintEvent eventNc(GetId());
762 eventNc.SetEventObject(this);
763 GetEventHandler()->ProcessEvent(eventNc);
764
765 wxPaintEvent eventPt(GetId());
766 eventPt.SetEventObject(this);
767 GetEventHandler()->ProcessEvent(eventPt);
768 }
769
770 void wxWindowMGL::OnEraseBackground(wxEraseEvent& event)
771 {
772 Clear();
773 }
774
775
776 // Find the wxWindow at the current mouse position, returning the mouse
777 // position.
778 wxWindow* wxFindWindowAtPointer(wxPoint& pt)
779 {
780 return wxFindWindowAtPoint(pt = wxGetMousePosition());
781 }
782
783 wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
784 {
785 window_t *wnd = MGL_wmGetWindowAtPosition(g_winMng, pt.x, pt.y);
786 return (wxWindow*)wnd->userData;
787 }