]> git.saurik.com Git - wxWidgets.git/blame - src/mgl/window.cpp
added new text event macros description
[wxWidgets.git] / src / mgl / window.cpp
CommitLineData
32b8ec41 1/////////////////////////////////////////////////////////////////////////////
a4bbc9f7
VS
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
32b8ec41
VZ
9/////////////////////////////////////////////////////////////////////////////
10
a4bbc9f7
VS
11// ===========================================================================
12// declarations
13// ===========================================================================
14
15// ---------------------------------------------------------------------------
16// headers
17// ---------------------------------------------------------------------------
32b8ec41
VZ
18
19#ifdef __GNUG__
20 #pragma implementation "window.h"
21#endif
22
a4bbc9f7
VS
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.
63winmng_t *g_winMng = NULL;
64MGLDevCtx *g_displayDC = NULL;
65
66extern wxList WXDLLEXPORT wxPendingDelete;
67 // FIXME_MGL -- ???
7bdc1879
VS
68
69// the window that has keyboard+joystick focus:
70static wxWindowMGL *g_focusedWindow = NULL;
71// the window that is currently under mouse cursor:
72static wxWindowMGL *g_windowUnderMouse = NULL;
a4bbc9f7
VS
73
74// ---------------------------------------------------------------------------
75// constants
76// ---------------------------------------------------------------------------
77
78// Custom identifiers used to distinguish between various event handlers
79// and capture handlers passed to MGL_wm
80enum
81{
82 wxMGL_CAPTURE_MOUSE = 1,
83 wxMGL_CAPTURE_KEYB = 2
84};
85
86
87// ---------------------------------------------------------------------------
88// private functions
89// ---------------------------------------------------------------------------
90
a4bbc9f7
VS
91// wxCreateMGL_WM creates MGL display DC and associates it with winmng_t
92// structure. Dimensions and depth of the DC are fetched from wxSystemOptions
93// object.
94// This function is *not* called from wxApp's initialization but rather at
95// the time when WM is needed, i.e. when first wxWindow is created. This
96// has two important effects:
97// a) it is possible to write windowless wxMGL apps
98// b) the app has plenty of time in wxApp::OnInit to feed wxSystemOptions
99// with desired settings
100
fd495ab3 101// FIXME_MGL -- move to app.cpp??
ef344ff8
VS
102static void wxDesktopPainter(window_t *wnd, MGLDC *dc)
103{
104 // FIXME_MGL - for now...
105 MGL_setColorRGB(0x63, 0x63, 0x96);
106 MGL_fillRectCoord(0, 0, wnd->width, wnd->height);
107}
108
109
a4bbc9f7
VS
110bool wxCreateMGL_WM()
111{
112 int mode;
113 int width = 640, height = 480, depth = 16;
114 int refresh = MGL_DEFAULT_REFRESH;
115
116#if wxUSE_SYSTEM_OPTIONS
ef344ff8 117 // FIXME_MGL -- so what is The Proper Way?
a4bbc9f7
VS
118 if ( wxSystemOptions::HasOption(wxT("mgl.screen-width") )
119 width = wxSystemOptions::GetOptionInt(wxT("mgl.screen-width"));
120 if ( wxSystemOptions::HasOption(wxT("mgl.screen-height") )
121 height = wxSystemOptions::GetOptionInt(wxT("mgl.screen-height"));
122 if ( wxSystemOptions::HasOption(wxT("mgl.screen-depth") )
123 depth = wxSystemOptions::GetOptionInt(wxT("mgl.screen-depth"));
124 if ( wxSystemOptions::HasOption(wxT("mgl.screen-refresh") )
125 refresh = wxSystemOptions::GetOptionInt(wxT("mgl.screen-refresh"));
126#endif
127
128 mode = MGL_findMode(width, height, depth);
129 if ( mode == -1 )
130 {
131 wxLogWarning(_("Mode %ix%i-%i not available, falling back to default mode."), width, height, depth);
132 mode = 0; // always available
133 }
134 g_displayDC = new MGLDisplayDC(mode, 1, refresh);
135 if ( !g_displayDC->isValid() )
136 {
137 delete g_displayDC;
138 g_displayDC = NULL;
139 return FALSE;
140 }
141
142 g_winMng = MGL_wmCreate(g_displayDC->getDC());
143 if (!g_winMng)
144 return FALSE;
ef344ff8
VS
145
146 MGL_wmSetWindowPainter(MGL_wmGetRootWindow(g_winMng), wxDesktopPainter);
a4bbc9f7
VS
147
148 return TRUE;
149}
150
151void wxDestroyMGL_WM()
152{
7bdc1879 153 if ( g_winMng )
a4bbc9f7
VS
154 {
155 MGL_wmDestroy(g_winMng);
156 g_winMng = NULL;
157 }
7bdc1879
VS
158 if ( g_displayDC )
159 {
160 delete g_displayDC;
161 g_displayDC = NULL;
162 }
a4bbc9f7
VS
163}
164
7bdc1879
VS
165// ---------------------------------------------------------------------------
166// MGL_WM hooks:
167// ---------------------------------------------------------------------------
168
169static void wxWindowPainter(window_t *wnd, MGLDC *dc)
170{
171 wxWindowMGL *w = (wxWindow*) wnd->userData;
172 if (w)
173 {
174 MGLDevCtx ctx(dc);
175 w->HandlePaint(&ctx);
176 }
ef344ff8
VS
177 // FIXME_MGL -- root window should be a regular window so that
178 // enter/leave and activate/deactivate events work correctly
179}
180
181static ibool wxWindowMouseHandler(window_t *wnd, event_t *e)
182{
183 wxWindowMGL *win = (wxWindowMGL*)MGL_wmGetWindowUserData(wnd);
184 wxPoint where = win->ScreenToClient(wxPoint(e->where_x, e->where_y));
185
186 wxEventType type = wxEVT_NULL;
187 wxMouseEvent event;
188 event.SetEventObject(win);
189 event.SetTimestamp(e->when);
190 event.m_x = where.x;
191 event.m_y = where.y;
192 event.m_shiftDown = e->modifiers & EVT_SHIFTKEY;
193 event.m_controlDown = e->modifiers & EVT_CTRLSTATE;
194 event.m_altDown = e->modifiers & EVT_LEFTALT;
195 event.m_metaDown = e->modifiers & EVT_RIGHTALT;
196 event.m_leftDown = e->modifiers & EVT_LEFTBUT;
197 event.m_middleDown = e->modifiers & EVT_MIDDLEBUT;
198 event.m_rightDown = e->modifiers & EVT_RIGHTBUT;
199
200 switch (e->what)
201 {
202 case EVT_MOUSEDOWN:
203 if ( e->message & EVT_LEFTBMASK )
204 type = (e->message & EVT_DBLCLICK) ?
205 wxEVT_LEFT_DCLICK : wxEVT_LEFT_DOWN;
206 else if ( e->message & EVT_MIDDLEBMASK )
207 type = (e->message & EVT_DBLCLICK) ?
208 wxEVT_MIDDLE_DCLICK : wxEVT_MIDDLE_DOWN;
209 else if ( e->message & EVT_RIGHTBMASK )
210 type = (e->message & EVT_DBLCLICK) ?
211 wxEVT_RIGHT_DCLICK : wxEVT_RIGHT_DOWN;
212 break;
213
214 case EVT_MOUSEUP:
215 if ( e->message & EVT_LEFTBMASK )
216 type = wxEVT_LEFT_UP;
217 else if ( e->message & EVT_MIDDLEBMASK )
218 type = wxEVT_MIDDLE_UP;
219 else if ( e->message & EVT_RIGHTBMASK )
220 type = wxEVT_RIGHT_UP;
221 break;
222
223 case EVT_MOUSEMOVE:
224 if ( win != g_windowUnderMouse )
225 {
226 if ( g_windowUnderMouse )
227 {
228 wxMouseEvent event2(event);
229 wxPoint where2 = g_windowUnderMouse->ScreenToClient(
230 wxPoint(e->where_x, e->where_y));
231 event2.m_x = where2.x;
232 event2.m_y = where2.y;
233 event2.SetEventObject(g_windowUnderMouse);
234 event2.SetEventType(wxEVT_LEAVE_WINDOW);
235 g_windowUnderMouse->GetEventHandler()->ProcessEvent(event2);
236 }
237
238 wxMouseEvent event3(event);
239 event3.SetEventType(wxEVT_ENTER_WINDOW);
240 win->GetEventHandler()->ProcessEvent(event3);
241
242 g_windowUnderMouse = win;
243 }
244
245 type = wxEVT_MOTION;
246 break;
247
248 default:
249 break;
250 }
251
252 if ( type == wxEVT_NULL )
253 {
254 return FALSE;
255 }
256 else
257 {
258 event.SetEventType(type);
259 return win->GetEventHandler()->ProcessEvent(event);
260 }
261}
262
263static ibool wxWindowKeybHandler(window_t *wnd, event_t *e)
264{
265 // FIXME_MGL
266 return FALSE;
267}
268
269static ibool wxWindowJoyHandler(window_t *wnd, event_t *e)
270{
271 // FIXME_MGL
272 return FALSE;
7bdc1879 273}
a4bbc9f7
VS
274
275// ---------------------------------------------------------------------------
276// event tables
277// ---------------------------------------------------------------------------
278
ef344ff8 279// in wxUniv this class is abstract because it doesn't have DoPopupMenu()
a4bbc9f7
VS
280IMPLEMENT_ABSTRACT_CLASS(wxWindowMGL, wxWindowBase)
281
282BEGIN_EVENT_TABLE(wxWindowMGL, wxWindowBase)
a4bbc9f7
VS
283END_EVENT_TABLE()
284
285// ===========================================================================
286// implementation
287// ===========================================================================
288
289// ----------------------------------------------------------------------------
290// constructors and such
291// ----------------------------------------------------------------------------
292
293void wxWindowMGL::Init()
294{
295 // generic:
296 InitBase();
297
298 // mgl specific:
a4bbc9f7
VS
299 m_wnd = NULL;
300 m_isShown = TRUE;
301 m_isBeingDeleted = FALSE;
302 m_isEnabled = TRUE;
303 m_frozen = FALSE;
304 m_paintMGLDC = NULL;
305}
306
307// Destructor
308wxWindowMGL::~wxWindowMGL()
309{
310 m_isBeingDeleted = TRUE;
311
312 if ( g_focusedWindow == this )
7bdc1879 313 KillFocus();
ef344ff8
VS
314 if ( g_windowUnderMouse == this )
315 g_windowUnderMouse = NULL;
a4bbc9f7
VS
316
317 // VS: destroy children first and _then_ detach *this from its parent.
318 // If we'd do it the other way around, children wouldn't be able
319 // find their parent frame (see above).
320 DestroyChildren();
321
322 if ( m_parent )
323 m_parent->RemoveChild(this);
324
325 if ( m_wnd )
326 MGL_wmDestroyWindow(m_wnd);
327}
328
329// real construction (Init() must have been called before!)
330bool wxWindowMGL::Create(wxWindow *parent,
331 wxWindowID id,
332 const wxPoint& pos,
333 const wxSize& size,
334 long style,
335 const wxString& name)
336{
7bdc1879
VS
337 // FIXME_MGL -- temporary!
338 //wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") );
a4bbc9f7
VS
339
340 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
341 return FALSE;
342
7bdc1879
VS
343 if ( parent ) // FIXME_MGL temporary
344 parent->AddChild(this);
345 else
346 m_isShown=FALSE;// FIXME_MGL -- temporary, simulates wxTLW/wxFrame
a4bbc9f7
VS
347
348 if ( style & wxPOPUP_WINDOW )
349 {
350 // it is created hidden as other top level windows
351 m_isShown = FALSE;
352 }
353
ef344ff8
VS
354 int x, y, w, h;
355 x = pos.x, y = pos.y;
356 if ( x == -1 )
357 x = 0; // FIXME_MGL, something better, see GTK+
358 if ( y == -1 )
359 y = 0; // FIXME_MGL, something better, see GTK+
360 w = WidthDefault(size.x);
361 h = HeightDefault(size.y);
362
a4bbc9f7
VS
363 m_wnd = MGL_wmCreateWindow(g_winMng,
364 parent ? parent->GetHandle() : NULL,
ef344ff8
VS
365 x, y, w, h);
366
a4bbc9f7
VS
367 MGL_wmSetWindowUserData(m_wnd, (void*) this);
368 MGL_wmSetWindowPainter(m_wnd, wxWindowPainter);
ef344ff8
VS
369 MGL_wmShowWindow(m_wnd, m_isShown);
370 MGL_wmSetWindowCursor(m_wnd, *wxSTANDARD_CURSOR->GetMGLCursor());
371
372 MGL_wmPushWindowEventHandler(m_wnd, wxWindowMouseHandler, EVT_MOUSEEVT, 0);
373 MGL_wmPushWindowEventHandler(m_wnd, wxWindowKeybHandler, EVT_KEYEVT, 0);
374 MGL_wmPushWindowEventHandler(m_wnd, wxWindowJoyHandler, EVT_JOYEVT, 0);
375
a4bbc9f7
VS
376 return TRUE;
377}
378
379// ---------------------------------------------------------------------------
380// basic operations
381// ---------------------------------------------------------------------------
382
383void wxWindowMGL::SetFocus()
384{
385 if (g_focusedWindow)
386 g_focusedWindow->KillFocus();
387
388 g_focusedWindow = this;
389
ef344ff8 390 MGL_wmCaptureEvents(GetHandle(), EVT_KEYEVT|EVT_JOYEVT, wxMGL_CAPTURE_KEYB);
a4bbc9f7 391
a4bbc9f7
VS
392#if wxUSE_CARET
393 // caret needs to be informed about focus change
394 wxCaret *caret = GetCaret();
395 if (caret)
396 caret->OnSetFocus();
397#endif // wxUSE_CARET
32b8ec41 398
ef344ff8 399 if ( IsTopLevel() )
a4bbc9f7
VS
400 {
401 wxActivateEvent event(wxEVT_ACTIVATE, TRUE, GetId());
402 event.SetEventObject(this);
403 GetEventHandler()->ProcessEvent(event);
404 }
405
406 wxFocusEvent event(wxEVT_SET_FOCUS, GetId());
407 event.SetEventObject(this);
408 GetEventHandler()->ProcessEvent(event);
409}
32b8ec41 410
a4bbc9f7 411void wxWindowMGL::KillFocus()
32b8ec41 412{
a4bbc9f7
VS
413 if ( g_focusedWindow != this ) return;
414 g_focusedWindow = NULL;
415
7bdc1879
VS
416 if ( m_isBeingDeleted ) return;
417
a4bbc9f7
VS
418 MGL_wmUncaptureEvents(GetHandle(), wxMGL_CAPTURE_KEYB);
419
420#if wxUSE_CARET
421 // caret needs to be informed about focus change
422 wxCaret *caret = GetCaret();
7bdc1879 423 if ( caret )
a4bbc9f7
VS
424 caret->OnKillFocus();
425#endif // wxUSE_CARET
426
7bdc1879 427 if ( IsTopLevel() )
a4bbc9f7
VS
428 {
429 wxActivateEvent event(wxEVT_ACTIVATE, FALSE, GetId());
430 event.SetEventObject(this);
431 GetEventHandler()->ProcessEvent(event);
432 }
433
434 wxFocusEvent event(wxEVT_KILL_FOCUS, GetId());
435 event.SetEventObject(this);
436 GetEventHandler()->ProcessEvent(event);
32b8ec41
VZ
437}
438
a4bbc9f7
VS
439// ----------------------------------------------------------------------------
440// this wxWindowBase function is implemented here (in platform-specific file)
441// because it is static and so couldn't be made virtual
442// ----------------------------------------------------------------------------
32b8ec41
VZ
443wxWindow *wxWindowBase::FindFocus()
444{
a4bbc9f7
VS
445 return (wxWindow*)g_focusedWindow;
446}
447
448bool wxWindowMGL::Show(bool show)
449{
450 if ( !wxWindowBase::Show(show) )
451 return FALSE;
452
453 MGL_wmShowWindow(m_wnd, show);
454 return TRUE;
455}
456
457// Raise the window to the top of the Z order
458void wxWindowMGL::Raise()
459{
460 MGL_wmRaiseWindow(m_wnd);
461}
462
463// Lower the window to the bottom of the Z order
464void wxWindowMGL::Lower()
465{
466 MGL_wmLowerWindow(m_wnd);
467}
468
469void wxWindowMGL::CaptureMouse()
470{
471 MGL_wmCaptureEvents(m_wnd, EVT_MOUSEEVT, wxMGL_CAPTURE_MOUSE);
472}
473
474void wxWindowMGL::ReleaseMouse()
475{
476 MGL_wmUncaptureEvents(m_wnd, wxMGL_CAPTURE_MOUSE);
477}
478
479/* static */ wxWindow *wxWindowBase::GetCapture()
480{
481 for (captureentry_t *c = g_winMng->capturedEvents; c; c = c->next)
482 {
483 if ( c->id == wxMGL_CAPTURE_MOUSE )
484 return (wxWindow*)c->wnd->userData;
485 }
486 return NULL;
487}
488
489bool wxWindowMGL::SetCursor(const wxCursor& cursor)
490{
491 if ( !wxWindowBase::SetCursor(cursor) )
492 {
493 // no change
494 return FALSE;
495 }
496
497 if ( m_cursor.Ok() )
498 MGL_wmSetWindowCursor(m_wnd, *m_cursor.GetMGLCursor());
ef344ff8
VS
499 else
500 MGL_wmSetWindowCursor(m_wnd, *wxSTANDARD_CURSOR->GetMGLCursor());
501
502 // FIXME_MGL -- should it set children's cursor or not?!
a4bbc9f7
VS
503
504 return TRUE;
505}
506
507void wxWindowMGL::WarpPointer(int x, int y)
508{
509 ClientToScreen(&x, &y);
510 EVT_setMousePos(x, y);
511}
512
513#if WXWIN_COMPATIBILITY
514// If nothing defined for this, try the parent.
515// E.g. we may be a button loaded from a resource, with no callback function
516// defined.
517void wxWindowMGL::OnCommand(wxWindow& win, wxCommandEvent& event)
518{
519 if ( GetEventHandler()->ProcessEvent(event) )
520 return;
521 if ( m_parent )
522 m_parent->GetEventHandler()->OnCommand(win, event);
523}
524#endif // WXWIN_COMPATIBILITY_2
525
526#if WXWIN_COMPATIBILITY
527wxObject* wxWindowMGL::GetChild(int number) const
528{
529 // Return a pointer to the Nth object in the Panel
530 wxNode *node = GetChildren().First();
531 int n = number;
532 while (node && n--)
533 node = node->Next();
534 if ( node )
535 {
536 wxObject *obj = (wxObject *)node->Data();
537 return(obj);
538 }
539 else
540 return NULL;
541}
542#endif // WXWIN_COMPATIBILITY
543
544// Set this window to be the child of 'parent'.
545bool wxWindowMGL::Reparent(wxWindowBase *parent)
546{
547 if ( !wxWindowBase::Reparent(parent) )
548 return FALSE;
549
550 MGL_wmReparentWindow(m_wnd, parent->GetHandle());
551
552 return TRUE;
553}
554
555
556// ---------------------------------------------------------------------------
557// drag and drop
558// ---------------------------------------------------------------------------
559
560#if wxUSE_DRAG_AND_DROP
561
562void wxWindowMGL::SetDropTarget(wxDropTarget *pDropTarget)
563{
564 if ( m_dropTarget != 0 ) {
565 m_dropTarget->Revoke(m_hWnd);
566 delete m_dropTarget;
567 }
568
569 m_dropTarget = pDropTarget;
570 if ( m_dropTarget != 0 )
571 m_dropTarget->Register(m_hWnd);
572}
573// FIXME_MGL
574#endif // wxUSE_DRAG_AND_DROP
575
576// old style file-manager drag&drop support: we retain the old-style
577// DragAcceptFiles in parallel with SetDropTarget.
578void wxWindowMGL::DragAcceptFiles(bool accept)
579{
580#if 0 // FIXME_MGL
581 HWND hWnd = GetHwnd();
582 if ( hWnd )
583 ::DragAcceptFiles(hWnd, (BOOL)accept);
584#endif
585}
586
587// ---------------------------------------------------------------------------
588// moving and resizing
589// ---------------------------------------------------------------------------
590
591// Get total size
592void wxWindowMGL::DoGetSize(int *x, int *y) const
593{
594 if (x) *x = m_wnd->width;
595 if (y) *y = m_wnd->height;
596}
597
598void wxWindowMGL::DoGetPosition(int *x, int *y) const
599{
600 if (x) *x = m_wnd->x;
601 if (y) *y = m_wnd->y;
602}
603
604void wxWindowMGL::DoScreenToClient(int *x, int *y) const
605{
606 int ax, ay;
607 wxPoint co = GetClientAreaOrigin();
608
609 MGL_wmCoordGlobalToLocal(m_wnd, m_wnd->x, m_wnd->y, &ax, &ay);
610 ax -= co.x;
611 ay -= co.y;
612 if (x)
613 *x = ax;
614 if (y)
615 *y = ay;
616}
617
618void wxWindowMGL::DoClientToScreen(int *x, int *y) const
619{
620 int ax, ay;
621 wxPoint co = GetClientAreaOrigin();
622
623 MGL_wmCoordGlobalToLocal(m_wnd, m_wnd->x+co.x, m_wnd->y+co.y, &ax, &ay);
624 if (x)
625 *x = ax;
626 if (y)
627 *y = ay;
628}
629
630// Get size *available for subwindows* i.e. excluding menu bar etc.
631void wxWindowMGL::DoGetClientSize(int *x, int *y) const
632{
633 DoGetSize(x, y);
634}
635
636void wxWindowMGL::DoMoveWindow(int x, int y, int width, int height)
637{
638 MGL_wmSetWindowPosition(GetHandle(), x, y, width, height);
639}
640
641// set the size of the window: if the dimensions are positive, just use them,
642// but if any of them is equal to -1, it means that we must find the value for
643// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
644// which case -1 is a valid value for x and y)
645//
646// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
647// the width/height to best suit our contents, otherwise we reuse the current
648// width/height
649void wxWindowMGL::DoSetSize(int x, int y, int width, int height, int sizeFlags)
650{
651 // get the current size and position...
652 int currentX, currentY;
653 GetPosition(&currentX, &currentY);
654 int currentW,currentH;
655 GetSize(&currentW, &currentH);
656
657 // ... and don't do anything (avoiding flicker) if it's already ok
658 if ( x == currentX && y == currentY &&
659 width == currentW && height == currentH )
660 {
661 return;
662 }
663
664 if ( x == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
665 x = currentX;
666 if ( y == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
667 y = currentY;
668
669#if 0 // FIXME_MGL -- what's this good for?
670 AdjustForParentClientOrigin(x, y, sizeFlags);
671#endif
672
673 wxSize size(-1, -1);
674 if ( width == -1 )
675 {
676 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
677 {
678 size = DoGetBestSize();
679 width = size.x;
680 }
681 else
682 {
683 // just take the current one
684 width = currentW;
685 }
686 }
687
688 if ( height == -1 )
689 {
690 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
691 {
692 if ( size.x == -1 )
693 {
694 size = DoGetBestSize();
695 }
696 //else: already called DoGetBestSize() above
697
698 height = size.y;
699 }
700 else
701 {
702 // just take the current one
703 height = currentH;
704 }
705 }
706
707 DoMoveWindow(x, y, width, height);
708
709 wxSizeEvent event(wxSize(width, height), GetId());
710 event.SetEventObject(this);
711 GetEventHandler()->ProcessEvent(event);
712}
713
714void wxWindowMGL::DoSetClientSize(int width, int height)
715{
716 SetSize(width, height);
717}
718
719// ---------------------------------------------------------------------------
720// text metrics
721// ---------------------------------------------------------------------------
722
723int wxWindowMGL::GetCharHeight() const
724{
725 wxScreenDC dc;
726 dc.SetFont(m_font);
727 return dc.GetCharHeight();
728}
729
730int wxWindowMGL::GetCharWidth() const
731{
732 wxScreenDC dc;
733 dc.SetFont(m_font);
734 return dc.GetCharWidth();
735}
736
737void wxWindowMGL::GetTextExtent(const wxString& string,
738 int *x, int *y,
739 int *descent, int *externalLeading,
740 const wxFont *theFont) const
741{
742 wxScreenDC dc;
743 if (!theFont)
744 theFont = &m_font;
745 dc.GetTextExtent(string, x, y, descent, externalLeading, (wxFont*)theFont);
746}
747
748#if wxUSE_CARET && WXWIN_COMPATIBILITY
749// ---------------------------------------------------------------------------
750// Caret manipulation
751// ---------------------------------------------------------------------------
752
753void wxWindowMGL::CreateCaret(int w, int h)
754{
755 SetCaret(new wxCaret(this, w, h));
756}
757
758void wxWindowMGL::CreateCaret(const wxBitmap *WXUNUSED(bitmap))
759{
760 wxFAIL_MSG("not implemented");
761}
762
763void wxWindowMGL::ShowCaret(bool show)
764{
765 wxCHECK_RET( m_caret, "no caret to show" );
766
767 m_caret->Show(show);
768}
769
770void wxWindowMGL::DestroyCaret()
771{
772 SetCaret(NULL);
773}
774
775void wxWindowMGL::SetCaretPos(int x, int y)
776{
777 wxCHECK_RET( m_caret, "no caret to move" );
778
779 m_caret->Move(x, y);
780}
781
782void wxWindowMGL::GetCaretPos(int *x, int *y) const
783{
784 wxCHECK_RET( m_caret, "no caret to get position of" );
785
786 m_caret->GetPosition(x, y);
787}
788#endif // wxUSE_CARET
789
790
a4bbc9f7
VS
791// ---------------------------------------------------------------------------
792// painting
793// ---------------------------------------------------------------------------
794
795void wxWindowMGL::Clear()
796{
797 wxClientDC dc((wxWindow *)this);
798 wxBrush brush(GetBackgroundColour(), wxSOLID);
799 dc.SetBackground(brush);
800 dc.Clear();
801}
802
803void wxWindowMGL::Refresh(bool WXUNUSED(eraseBack), const wxRect *rect)
804{
805 if ( rect )
806 {
807 rect_t r;
808 r.left = rect->GetLeft(), r.right = rect->GetRight();
809 r.top = rect->GetTop(), r.bottom = rect->GetBottom();
810 MGL_wmInvalidateWindowRect(GetHandle(), &r);
811 }
812 else
813 MGL_wmInvalidateWindow(GetHandle());
814}
815
816void wxWindowMGL::Update()
817{
a4bbc9f7
VS
818 if ( !m_frozen )
819 MGL_wmUpdateDC(g_winMng);
820}
821
822void wxWindowMGL::Freeze()
823{
824 m_frozen = TRUE;
825 m_refreshAfterThaw = FALSE;
826}
827
828void wxWindowMGL::Thaw()
829{
830 m_frozen = FALSE;
831 if ( m_refreshAfterThaw )
832 Refresh();
833}
834
a4bbc9f7
VS
835void wxWindowMGL::HandlePaint(MGLDevCtx *dc)
836{
837 if ( m_frozen )
838 {
839 // Don't paint anything if the window is frozen.
fd495ab3 840 m_refreshAfterThaw = TRUE;
a4bbc9f7
VS
841 return;
842 }
ef344ff8 843
fd495ab3
VS
844 MGLRegion clip;
845 dc->getClipRegion(clip);
846 m_updateRegion = wxRegion(clip);
a4bbc9f7
VS
847 m_paintMGLDC = dc;
848
7bdc1879
VS
849 {
850 wxWindowDC dc((wxWindow*)this);
851 wxEraseEvent eventEr(m_windowId, &dc);
a4bbc9f7
VS
852 eventEr.SetEventObject(this);
853 GetEventHandler()->ProcessEvent(eventEr);
7bdc1879 854 }
a4bbc9f7
VS
855
856 wxNcPaintEvent eventNc(GetId());
857 eventNc.SetEventObject(this);
858 GetEventHandler()->ProcessEvent(eventNc);
859
860 wxPaintEvent eventPt(GetId());
861 eventPt.SetEventObject(this);
862 GetEventHandler()->ProcessEvent(eventPt);
a4bbc9f7 863
7bdc1879 864 m_paintMGLDC = NULL;
fd495ab3 865 m_updateRegion.Clear();
a4bbc9f7
VS
866}
867
868
869// Find the wxWindow at the current mouse position, returning the mouse
870// position.
871wxWindow* wxFindWindowAtPointer(wxPoint& pt)
872{
873 return wxFindWindowAtPoint(pt = wxGetMousePosition());
874}
875
876wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
877{
878 window_t *wnd = MGL_wmGetWindowAtPosition(g_winMng, pt.x, pt.y);
879 return (wxWindow*)wnd->userData;
32b8ec41 880}