X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ead60ec54b85c272711ae917b6a086741699567e..1c405bb51093fc7812fb66e7d47faac5707e02b5:/src/mgl/window.cpp diff --git a/src/mgl/window.cpp b/src/mgl/window.cpp index a76020c4ec..86b882527f 100644 --- a/src/mgl/window.cpp +++ b/src/mgl/window.cpp @@ -90,80 +90,6 @@ enum // private functions // --------------------------------------------------------------------------- -// wxCreateMGL_WM creates MGL display DC and associates it with winmng_t -// structure. Dimensions and depth of the DC are fetched from wxSystemOptions -// object. -// This function is *not* called from wxApp's initialization but rather at -// the time when WM is needed, i.e. when first wxWindow is created. This -// has two important effects: -// a) it is possible to write windowless wxMGL apps -// b) the app has plenty of time in wxApp::OnInit to feed wxSystemOptions -// with desired settings - -// FIXME_MGL -- move to app.cpp?? -static void wxDesktopPainter(window_t *wnd, MGLDC *dc) -{ - // FIXME_MGL - for now... - MGL_setColorRGB(0x63, 0x63, 0x96); - MGL_fillRectCoord(0, 0, wnd->width, wnd->height); -} - - -bool wxCreateMGL_WM() -{ - int mode; - int width = 640, height = 480, depth = 16; - int refresh = MGL_DEFAULT_REFRESH; - -#if wxUSE_SYSTEM_OPTIONS - // FIXME_MGL -- so what is The Proper Way? - if ( wxSystemOptions::HasOption(wxT("mgl.screen-width") ) - width = wxSystemOptions::GetOptionInt(wxT("mgl.screen-width")); - if ( wxSystemOptions::HasOption(wxT("mgl.screen-height") ) - height = wxSystemOptions::GetOptionInt(wxT("mgl.screen-height")); - if ( wxSystemOptions::HasOption(wxT("mgl.screen-depth") ) - depth = wxSystemOptions::GetOptionInt(wxT("mgl.screen-depth")); - if ( wxSystemOptions::HasOption(wxT("mgl.screen-refresh") ) - refresh = wxSystemOptions::GetOptionInt(wxT("mgl.screen-refresh")); -#endif - - mode = MGL_findMode(width, height, depth); - if ( mode == -1 ) - { - wxLogWarning(_("Mode %ix%i-%i not available, falling back to default mode."), width, height, depth); - mode = 0; // always available - } - g_displayDC = new MGLDisplayDC(mode, 1, refresh); - if ( !g_displayDC->isValid() ) - { - delete g_displayDC; - g_displayDC = NULL; - return FALSE; - } - - g_winMng = MGL_wmCreate(g_displayDC->getDC()); - if (!g_winMng) - return FALSE; - - MGL_wmSetWindowPainter(MGL_wmGetRootWindow(g_winMng), wxDesktopPainter); - - return TRUE; -} - -void wxDestroyMGL_WM() -{ - if ( g_winMng ) - { - MGL_wmDestroy(g_winMng); - g_winMng = NULL; - } - if ( g_displayDC ) - { - delete g_displayDC; - g_displayDC = NULL; - } -} - // Returns toplevel grandparent of given window: static wxWindowMGL* wxGetTopLevelParent(wxWindowMGL *win) { @@ -173,38 +99,59 @@ static wxWindowMGL* wxGetTopLevelParent(wxWindowMGL *win) return p; } +#ifdef __WXDEBUG__ +// Add an easy way to capture screenshots: +static void CaptureScreenshot() +{ + wxBusyCursor bcur; + + static int screenshot_num = 0; + char screenshot[128]; + sprintf(screenshot, "screenshot-%03i.png", screenshot_num++); + g_displayDC->savePNGFromDC(screenshot, 0, 0, + g_displayDC->sizex(), + g_displayDC->sizey()); +} +#endif + // --------------------------------------------------------------------------- // MGL_WM hooks: // --------------------------------------------------------------------------- -static void wxWindowPainter(window_t *wnd, MGLDC *dc) +static void MGLAPI wxWindowPainter(window_t *wnd, MGLDC *dc) { wxWindowMGL *w = (wxWindow*) wnd->userData; + if ( w && !(w->GetWindowStyle() & wxTRANSPARENT_WINDOW) ) { MGLDevCtx ctx(dc); w->HandlePaint(&ctx); } - // FIXME_MGL -- root window should be a regular window so that - // enter/leave and activate/deactivate events work correctly } -static ibool wxWindowMouseHandler(window_t *wnd, event_t *e) +static ibool MGLAPI wxWindowMouseHandler(window_t *wnd, event_t *e) { wxWindowMGL *win = (wxWindowMGL*)MGL_wmGetWindowUserData(wnd); + wxPoint orig(win->GetClientAreaOrigin()); wxPoint where; MGL_wmCoordGlobalToLocal(win->GetHandle(), e->where_x, e->where_y, &where.x, &where.y); - if ( !win->IsEnabled() ) return FALSE; + for (wxWindowMGL *w = win; w; w = w->GetParent()) + { + if ( !w->IsEnabled() ) + return FALSE; + if ( w->IsTopLevel() ) + break; + } wxEventType type = wxEVT_NULL; wxMouseEvent event; event.SetEventObject(win); event.SetTimestamp(e->when); - event.m_x = where.x; - event.m_y = where.y; + event.m_x = where.x - orig.x; + event.m_y = where.y - orig.y; event.m_shiftDown = e->modifiers & EVT_SHIFTKEY; event.m_controlDown = e->modifiers & EVT_CTRLSTATE; event.m_altDown = e->modifiers & EVT_LEFTALT; @@ -248,6 +195,10 @@ static ibool wxWindowMouseHandler(window_t *wnd, event_t *e) e->where_x, e->where_y, &event2.m_x, &event2.m_y); + wxPoint orig(gs_windowUnderMouse->GetClientAreaOrigin()); + event2.m_x -= orig.x; + event2.m_y -= orig.y; + event2.SetEventObject(gs_windowUnderMouse); event2.SetEventType(wxEVT_LEAVE_WINDOW); gs_windowUnderMouse->GetEventHandler()->ProcessEvent(event2); @@ -297,7 +248,20 @@ static ibool wxWindowMouseHandler(window_t *wnd, event_t *e) static long wxScanToKeyCode(event_t *event) { - #define KEY(mgl,wx) case mgl: key = wx; break; + // VS: make it __WXDEBUG__-only, since we have lots of wxLogTrace calls + // here and the arguments would be stored in non-debug executable even + // though wxLogTrace would be no-op... + #ifdef __WXDEBUG__ + #define KEY(mgl_key,wx_key) \ + case mgl_key: \ + wxLogTrace(_T("keyevents"), \ + _T("key " #mgl_key ", mapped to " #wx_key)); \ + key = wx_key; \ + break; + #else + #define KEY(mgl_key,wx_key) \ + case mgl_key: key = wx_key; break; + #endif long key = 0; switch ( EVT_scanCode(event->message) ) @@ -423,7 +387,7 @@ static long wxAsciiToKeyCode(event_t *event) return (long)EVT_asciiCode(event->message); } -static ibool wxWindowKeybHandler(window_t *wnd, event_t *e) +static ibool MGLAPI wxWindowKeybHandler(window_t *wnd, event_t *e) { wxWindowMGL *win = (wxWindowMGL*)MGL_wmGetWindowUserData(wnd); @@ -460,6 +424,14 @@ static ibool wxWindowKeybHandler(window_t *wnd, event_t *e) ret = win->GetEventHandler()->ProcessEvent(event); + +#ifdef __WXDEBUG__ + // Add an easy way to capture screenshots: + if ( event.m_keyCode == WXK_F1 && + event.m_shiftDown && event.m_controlDown ) + CaptureScreenshot(); +#endif + #if wxUSE_ACCEL if ( !ret ) { @@ -478,9 +450,9 @@ static ibool wxWindowKeybHandler(window_t *wnd, event_t *e) } #endif // wxUSE_ACCEL - /* wxMSW doesn't send char events with Alt pressed */ - /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x - will only be sent if it is not in an accelerator table. */ + // wxMSW doesn't send char events with Alt pressed + // Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x + // will only be sent if it is not in an accelerator table. event2.m_keyCode = wxAsciiToKeyCode(e); if ( !ret && event2.m_keyCode != 0 ) { @@ -488,6 +460,22 @@ static ibool wxWindowKeybHandler(window_t *wnd, event_t *e) ret = win->GetEventHandler()->ProcessEvent(event2); } + // Synthetize navigation key event, but do it only if the TAB key + // wasn't handled yet. + // FIXME_MGL - isn't this wxUniv's business? + if ( !ret && event.m_keyCode == WXK_TAB && + win->GetParent() && win->GetParent()->HasFlag(wxTAB_TRAVERSAL) ) + { + wxNavigationKeyEvent navEvent; + navEvent.SetEventObject(win->GetParent()); + // Shift-TAB goes in reverse direction: + navEvent.SetDirection(!event.m_shiftDown); + // Ctrl-TAB changes the (parent) window, i.e. switch notebook page: + navEvent.SetWindowChange(event.m_controlDown); + navEvent.SetCurrentFocus(wxStaticCast(win, wxWindow)); + ret = win->GetParent()->GetEventHandler()->ProcessEvent(navEvent); + } + return ret; } } @@ -510,8 +498,18 @@ END_EVENT_TABLE() // constructors and such // ---------------------------------------------------------------------------- +extern wxDisplayModeInfo wxGetDefaultDisplayMode(); + void wxWindowMGL::Init() { + // First of all, make sure window manager is up and running. If it is + // not the case, initialize it in default display mode + if ( !g_winMng ) + { + if ( !wxTheApp->SetDisplayMode(wxGetDefaultDisplayMode()) ) + wxFatalError(_("Cannot initialize display.")); + } + // generic: InitBase(); @@ -604,18 +602,35 @@ bool wxWindowMGL::Create(wxWindow *parent, wnd_parent = NULL; } - m_wnd = MGL_wmCreateWindow(g_winMng, wnd_parent, x, y, w, h); + window_t *wnd = MGL_wmCreateWindow(g_winMng, wnd_parent, x, y, w, h); + + MGL_wmSetWindowFlags(wnd, mgl_style); + MGL_wmShowWindow(wnd, m_isShown); + + SetMGLwindow_t(wnd); + + return TRUE; +} + +void wxWindowMGL::SetMGLwindow_t(struct window_t *wnd) +{ + if ( m_wnd ) + MGL_wmDestroyWindow(m_wnd); + + m_wnd = wnd; + if ( !m_wnd ) return; + + m_isShown = m_wnd->visible; - MGL_wmSetWindowFlags(m_wnd, mgl_style); MGL_wmSetWindowUserData(m_wnd, (void*) this); MGL_wmSetWindowPainter(m_wnd, wxWindowPainter); - MGL_wmShowWindow(m_wnd, m_isShown); - MGL_wmSetWindowCursor(m_wnd, *wxSTANDARD_CURSOR->GetMGLCursor()); - MGL_wmPushWindowEventHandler(m_wnd, wxWindowMouseHandler, EVT_MOUSEEVT, 0); MGL_wmPushWindowEventHandler(m_wnd, wxWindowKeybHandler, EVT_KEYEVT, 0); - - return TRUE; + + if ( m_cursor.Ok() ) + MGL_wmSetWindowCursor(m_wnd, *m_cursor.GetMGLCursor()); + else + MGL_wmSetWindowCursor(m_wnd, *wxSTANDARD_CURSOR->GetMGLCursor()); } // --------------------------------------------------------------------------- @@ -624,6 +639,8 @@ bool wxWindowMGL::Create(wxWindow *parent, void wxWindowMGL::SetFocus() { + if ( gs_focusedWindow == this ) return; + if ( gs_focusedWindow ) gs_focusedWindow->KillFocus(); @@ -639,7 +656,7 @@ void wxWindowMGL::SetFocus() #endif // wxUSE_CARET wxWindowMGL *active = wxGetTopLevelParent(this); - if ( active != gs_activeFrame ) + if ( !(m_windowStyle & wxPOPUP_WINDOW) && active != gs_activeFrame ) { if ( gs_activeFrame ) { @@ -675,14 +692,6 @@ void wxWindowMGL::KillFocus() caret->OnKillFocus(); #endif // wxUSE_CARET - if ( IsTopLevel() ) - { - // FIXME_MGL - this is wrong, see wxGTK! - wxActivateEvent event(wxEVT_ACTIVATE, FALSE, GetId()); - event.SetEventObject(this); - GetEventHandler()->ProcessEvent(event); - } - wxFocusEvent event(wxEVT_KILL_FOCUS, GetId()); event.SetEventObject(this); GetEventHandler()->ProcessEvent(event); @@ -729,7 +738,7 @@ void wxWindowMGL::Lower() MGL_wmLowerWindow(m_wnd); } -void wxWindowMGL::CaptureMouse() +void wxWindowMGL::DoCaptureMouse() { if ( gs_mouseCapture ) MGL_wmUncaptureEvents(gs_mouseCapture->m_wnd, wxMGL_CAPTURE_MOUSE); @@ -738,7 +747,7 @@ void wxWindowMGL::CaptureMouse() MGL_wmCaptureEvents(m_wnd, EVT_MOUSEEVT, wxMGL_CAPTURE_MOUSE); } -void wxWindowMGL::ReleaseMouse() +void wxWindowMGL::DoReleaseMouse() { wxASSERT_MSG( gs_mouseCapture == this, wxT("attempt to release mouse, but this window hasn't captured it") ) @@ -959,11 +968,15 @@ void wxWindowMGL::DoSetSize(int x, int y, int width, int height, int sizeFlags) } } - DoMoveWindow(x, y, width, height); + if ( m_wnd->x != x || m_wnd->y != y || + (int)m_wnd->width != width || (int)m_wnd->height != height ) + { + DoMoveWindow(x, y, width, height); - wxSizeEvent event(wxSize(width, height), GetId()); - event.SetEventObject(this); - GetEventHandler()->ProcessEvent(event); + wxSizeEvent event(wxSize(width, height), GetId()); + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(event); + } } void wxWindowMGL::DoSetClientSize(int width, int height) @@ -1055,6 +1068,7 @@ void wxWindowMGL::Clear() dc.Clear(); } +#include "wx/menu.h" void wxWindowMGL::Refresh(bool eraseBack, const wxRect *rect) { if ( m_eraseBackground == -1 ) @@ -1101,6 +1115,12 @@ void wxWindowMGL::HandlePaint(MGLDevCtx *dc) return; } +#if 0 // FIXME_MGL -- debugging stuff! + dc->setColorRGB(255,0,255); + dc->fillRect(-1000,-1000,2000,2000); + wxUsleep(50); +#endif + MGLRegion clip; dc->getClipRegion(clip); m_updateRegion = wxRegion(clip);