X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a679e1298b3f07cb421a756692e58107f3ad5d3e..90d0ab3443af62c1055cb7151be753aca89a20ee:/src/mgl/window.cpp diff --git a/src/mgl/window.cpp b/src/mgl/window.cpp index 36e2e13443..36baf4f2cb 100644 --- a/src/mgl/window.cpp +++ b/src/mgl/window.cpp @@ -4,7 +4,7 @@ // Author: Vaclav Slavik // (based on GTK & MSW implementations) // RCS-ID: $Id$ -// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com) +// Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com) // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// @@ -29,6 +29,7 @@ #ifndef WX_PRECOMP #include "wx/window.h" + #include "wx/msgdlg.h" #include "wx/accel.h" #include "wx/setup.h" #include "wx/dc.h" @@ -65,6 +66,9 @@ MGLDevCtx *g_displayDC = NULL; // the window that has keyboard focus: static wxWindowMGL *gs_focusedWindow = NULL; +// the window that is about to be focused after currently focused +// one looses focus: +static wxWindow *gs_toBeFocusedWindow = NULL; // the window that is currently under mouse cursor: static wxWindowMGL *gs_windowUnderMouse = NULL; // the window that has mouse capture @@ -99,20 +103,34 @@ static wxWindowMGL* wxGetTopLevelParent(wxWindowMGL *win) return p; } -#ifdef __WXDEBUG__ -// Add an easy way to capture screenshots: -static void CaptureScreenshot() +// An easy way to capture screenshots: +static void wxCaptureScreenshot(bool activeWindowOnly) { - wxBusyCursor bcur; - +#ifdef __DOS__ + #define SCREENSHOT_FILENAME _T("sshot%03i.png") +#else + #define SCREENSHOT_FILENAME _T("screenshot-%03i.png") +#endif 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()); + wxString screenshot; + + do + { + screenshot.Printf(SCREENSHOT_FILENAME, screenshot_num++); + } while ( wxFileExists(screenshot) && screenshot_num < 1000 ); + + wxRect r(0, 0, g_displayDC->sizex(), g_displayDC->sizey()); + + if ( activeWindowOnly && gs_activeFrame ) + { + r.Intersect(gs_activeFrame->GetRect()); + } + + g_displayDC->savePNGFromDC(screenshot.mb_str(), + r.x, r. y, r.x+r.width, r.y+r.height); + + wxMessageBox(_("Screenshot captured: ") + wxString(screenshot)); } -#endif // --------------------------------------------------------------------------- // MGL_WM hooks: @@ -159,23 +177,33 @@ static ibool MGLAPI wxWindowMouseHandler(window_t *wnd, event_t *e) event.m_leftDown = e->modifiers & EVT_LEFTBUT; event.m_middleDown = e->modifiers & EVT_MIDDLEBUT; event.m_rightDown = e->modifiers & EVT_RIGHTBUT; - + switch (e->what) { case EVT_MOUSEDOWN: - if ( e->message & EVT_LEFTBMASK ) - type = (e->message & EVT_DBLCLICK) ? - wxEVT_LEFT_DCLICK : wxEVT_LEFT_DOWN; - else if ( e->message & EVT_MIDDLEBMASK ) - type = (e->message & EVT_DBLCLICK) ? - wxEVT_MIDDLE_DCLICK : wxEVT_MIDDLE_DOWN; - else if ( e->message & EVT_RIGHTBMASK ) - type = (e->message & EVT_DBLCLICK) ? - wxEVT_RIGHT_DCLICK : wxEVT_RIGHT_DOWN; - + // Change focus if the user clicks outside focused window: if ( win->AcceptsFocus() && wxWindow::FindFocus() != win ) win->SetFocus(); + if ( e->message & EVT_DBLCLICK ) + { + if ( e->message & EVT_LEFTBMASK ) + type = wxEVT_LEFT_DCLICK; + else if ( e->message & EVT_MIDDLEBMASK ) + type = wxEVT_MIDDLE_DCLICK; + else if ( e->message & EVT_RIGHTBMASK ) + type = wxEVT_RIGHT_DCLICK; + } + else + { + if ( e->message & EVT_LEFTBMASK ) + type = wxEVT_LEFT_DOWN; + else if ( e->message & EVT_MIDDLEBMASK ) + type = wxEVT_MIDDLE_DOWN; + else if ( e->message & EVT_RIGHTBMASK ) + type = wxEVT_RIGHT_DOWN; + } + break; case EVT_MOUSEUP: @@ -399,6 +427,23 @@ static long wxScanToKeyCode(event_t *event, bool translate) return key; } +static bool wxHandleSpecialKeys(wxKeyEvent& event) +{ + // Add an easy way to capture screenshots: + if ( event.m_keyCode == WXK_SNAPSHOT + #ifdef __WXDEBUG__ // FIXME_MGL - remove when KB_sysReq works in MGL! + || (event.m_keyCode == WXK_F1 && + event.m_shiftDown && event.m_controlDown) + ) + #endif + { + wxCaptureScreenshot(event.m_altDown/*only active wnd?*/); + return TRUE; + } + + return FALSE; +} + static ibool MGLAPI wxWindowKeybHandler(window_t *wnd, event_t *e) { wxWindowMGL *win = (wxWindowMGL*)MGL_wmGetWindowUserData(wnd); @@ -436,35 +481,9 @@ static ibool MGLAPI 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 ) - { - for (wxWindowMGL *w = win; w; w = w->GetParent()) - { - int command = w->GetAcceleratorTable()->GetCommand(event); - if ( command != -1 ) - { - wxCommandEvent eventc(wxEVT_COMMAND_MENU_SELECTED, command); - ret = w->GetEventHandler()->ProcessEvent(eventc); - break; - } - if ( w->IsTopLevel() ) - break; - } - } -#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. + // will only be sent if it is not in an accelerator table: event2.m_keyCode = wxScanToKeyCode(e, FALSE); if ( !ret && event2.m_keyCode != 0 ) { @@ -473,7 +492,7 @@ static ibool MGLAPI wxWindowKeybHandler(window_t *wnd, event_t *e) } // Synthetize navigation key event, but do it only if the TAB key - // wasn't handled yet. + // wasn't handled yet: if ( !ret && event.m_keyCode == WXK_TAB && win->GetParent() && win->GetParent()->HasFlag(wxTAB_TRAVERSAL) ) { @@ -487,6 +506,11 @@ static ibool MGLAPI wxWindowKeybHandler(window_t *wnd, event_t *e) ret = win->GetParent()->GetEventHandler()->ProcessEvent(navEvent); } + // Finally, process special meaning keys that are usually + // a responsibility of OS or window manager: + if ( !ret ) + ret = wxHandleSpecialKeys(event); + return ret; } } @@ -499,6 +523,7 @@ static ibool MGLAPI wxWindowKeybHandler(window_t *wnd, event_t *e) IMPLEMENT_ABSTRACT_CLASS(wxWindowMGL, wxWindowBase) BEGIN_EVENT_TABLE(wxWindowMGL, wxWindowBase) + EVT_IDLE(wxWindowMGL::OnIdle) END_EVENT_TABLE() // =========================================================================== @@ -544,12 +569,17 @@ wxWindowMGL::~wxWindowMGL() if (gs_activeFrame == this) { - gs_activeFrame = NULL; - // activate next frame in Z-order: - if ( m_wnd->prev ) - { - wxWindowMGL *win = (wxWindowMGL*)m_wnd->prev->userData; - win->SetFocus(); + gs_activeFrame = NULL; + // activate next frame in Z-order: + if ( m_wnd->prev ) + { + wxWindowMGL *win = (wxWindowMGL*)m_wnd->prev->userData; + win->SetFocus(); + } + else if ( m_wnd->next ) + { + wxWindowMGL *win = (wxWindowMGL*)m_wnd->next->userData; + win->SetFocus(); } } @@ -591,6 +621,7 @@ bool wxWindowMGL::Create(wxWindow *parent, x = 0; // FIXME_MGL, something better, see GTK+ if ( y == -1 ) y = 0; // FIXME_MGL, something better, see GTK+ + AdjustForParentClientOrigin(x, y, 0); w = WidthDefault(size.x); h = HeightDefault(size.y); @@ -652,8 +683,14 @@ void wxWindowMGL::SetFocus() { if ( gs_focusedWindow == this ) return; + wxWindowMGL *oldFocusedWindow = gs_focusedWindow; + if ( gs_focusedWindow ) + { + gs_toBeFocusedWindow = (wxWindow*)this; gs_focusedWindow->KillFocus(); + gs_toBeFocusedWindow = NULL; + } gs_focusedWindow = this; @@ -677,6 +714,7 @@ void wxWindowMGL::SetFocus() wxFocusEvent event(wxEVT_SET_FOCUS, GetId()); event.SetEventObject(this); + event.SetWindow((wxWindow*)oldFocusedWindow); GetEventHandler()->ProcessEvent(event); #if wxUSE_CARET @@ -705,6 +743,7 @@ void wxWindowMGL::KillFocus() wxFocusEvent event(wxEVT_KILL_FOCUS, GetId()); event.SetEventObject(this); + event.SetWindow(gs_toBeFocusedWindow); GetEventHandler()->ProcessEvent(event); } @@ -726,11 +765,20 @@ bool wxWindowMGL::Show(bool show) if (!show && gs_activeFrame == this) { - // activate next frame in Z-order: - if ( m_wnd->prev ) - { - wxWindowMGL *win = (wxWindowMGL*)m_wnd->prev->userData; - win->SetFocus(); + // activate next frame in Z-order: + if ( m_wnd->prev ) + { + wxWindowMGL *win = (wxWindowMGL*)m_wnd->prev->userData; + win->SetFocus(); + } + else if ( m_wnd->next ) + { + wxWindowMGL *win = (wxWindowMGL*)m_wnd->next->userData; + win->SetFocus(); + } + else + { + gs_activeFrame = NULL; } } @@ -789,7 +837,19 @@ bool wxWindowMGL::SetCursor(const wxCursor& cursor) void wxWindowMGL::WarpPointer(int x, int y) { + int w, h; + wxDisplaySize(&w, &h); + ClientToScreen(&x, &y); + if ( x < 0 ) + x = 0; + if ( y < 0 ) + y = 0; + if ( x >= w ) + x = w-1; + if ( y >= h ) + y = h-1; + EVT_setMousePos(x, y); } @@ -874,14 +934,21 @@ void wxWindowMGL::DragAcceptFiles(bool accept) // Get total size void wxWindowMGL::DoGetSize(int *x, int *y) const { + wxASSERT_MSG( m_wnd, wxT("invalid window") ); + if (x) *x = m_wnd->width; if (y) *y = m_wnd->height; } void wxWindowMGL::DoGetPosition(int *x, int *y) const { - if (x) *x = m_wnd->x; - if (y) *y = m_wnd->y; + wxASSERT_MSG( m_wnd, wxT("invalid window") ); + + int pX = 0, pY = 0; + AdjustForParentClientOrigin(pX, pY, 0); + + if (x) *x = m_wnd->x - pX; + if (y) *y = m_wnd->y - pY; } void wxWindowMGL::DoScreenToClient(int *x, int *y) const @@ -959,7 +1026,7 @@ void wxWindowMGL::DoSetSize(int x, int y, int width, int height, int sizeFlags) width = currentW; } } - + if ( height == -1 ) { if ( sizeFlags & wxSIZE_AUTO_HEIGHT ) @@ -978,6 +1045,16 @@ void wxWindowMGL::DoSetSize(int x, int y, int width, int height, int sizeFlags) height = currentH; } } + + int maxWidth = GetMaxWidth(), + minWidth = GetMinWidth(), + maxHeight = GetMaxHeight(), + minHeight = GetMinHeight(); + + if ( minWidth != -1 && width < minWidth ) width = minWidth; + if ( maxWidth != -1 && width > maxWidth ) width = maxWidth; + if ( minHeight != -1 && height < minHeight ) height = minHeight; + if ( maxHeight != -1 && height > maxHeight ) height = maxHeight; if ( m_wnd->x != x || m_wnd->y != y || (int)m_wnd->width != width || (int)m_wnd->height != height ) @@ -1126,10 +1203,17 @@ 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); +#ifdef __WXDEBUG__ + // FIXME_MGL -- debugging stuff, to be removed! + static int debugPaintEvents = -1; + if ( debugPaintEvents == -1 ) + debugPaintEvents = wxGetEnv(wxT("WXMGL_DEBUG_PAINT_EVENTS"), NULL); + if ( debugPaintEvents ) + { + dc->setColorRGB(255,0,255); + dc->fillRect(-1000,-1000,2000,2000); + wxUsleep(50); + } #endif MGLRegion clip; @@ -1183,3 +1267,13 @@ wxWindow* wxFindWindowAtPoint(const wxPoint& pt) window_t *wnd = MGL_wmGetWindowAtPosition(g_winMng, pt.x, pt.y); return (wxWindow*)wnd->userData; } + + +// --------------------------------------------------------------------------- +// idle events processing +// --------------------------------------------------------------------------- + +void wxWindowMGL::OnIdle(wxIdleEvent& WXUNUSED(event)) +{ + UpdateWindowUI(); +}