X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/71908213057690d5452f72b2b9c8e62b53357170..0f243af310c9772628bbeeab8131a8c09bb94dbc:/src/univ/winuniv.cpp diff --git a/src/univ/winuniv.cpp b/src/univ/winuniv.cpp index ca2c7c4be5..be8a2ba4e3 100644 --- a/src/univ/winuniv.cpp +++ b/src/univ/winuniv.cpp @@ -18,7 +18,7 @@ // --------------------------------------------------------------------------- #ifdef __GNUG__ - #pragma implementation "window.h" + #pragma implementation "univwindow.h" #endif // For compilers that support precompilation, includes "wx.h". @@ -54,6 +54,10 @@ #undef WXDEBUG_REFRESH #endif +#if defined(WXDEBUG_REFRESH) && defined(__WXMSW__) && !defined(__WXMICROWIN__) +#include "wx/msw/private.h" +#endif + // ============================================================================ // implementation // ============================================================================ @@ -69,6 +73,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowGTK) #elif defined(__WXMGL__) IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowMGL) +#elif defined(__WXX11__) + IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowX11) +#elif defined(__WXPM__) + IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowOS2) #endif BEGIN_EVENT_TABLE(wxWindow, wxWindowNative) @@ -100,6 +108,9 @@ void wxWindow::Init() m_isCurrent = FALSE; m_renderer = wxTheme::Get()->GetRenderer(); + + m_oldSize.x = -1; + m_oldSize.y = -1; } bool wxWindow::Create(wxWindow *parent, @@ -109,12 +120,11 @@ bool wxWindow::Create(wxWindow *parent, long style, const wxString& name) { - // we add wxCLIP_CHILDREN and wxNO_FULL_REPAINT_ON_RESIZE because without - // these styles we can't get rid of flicker on wxMSW + // we add wxCLIP_CHILDREN to get the same ("natural") behaviour under MSW + // as under the other platforms if ( !wxWindowNative::Create(parent, id, pos, size, - style | - wxCLIP_CHILDREN | - wxNO_FULL_REPAINT_ON_RESIZE, name) ) + style | wxCLIP_CHILDREN, + name) ) { return FALSE; } @@ -122,19 +132,20 @@ bool wxWindow::Create(wxWindow *parent, // if we should always have the scrollbar, do show it if ( GetWindowStyle() & wxALWAYS_SHOW_SB ) { +#if wxUSE_TWO_WINDOWS + SetInsertIntoMain( TRUE ); +#endif m_scrollbarVert = new wxScrollBar(this, -1, wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL); +#if wxUSE_TWO_WINDOWS + SetInsertIntoMain( FALSE ); +#endif // and position it PositionScrollbars(); } - // the colours/fonts are default - m_hasBgCol = - m_hasFgCol = - m_hasFont = FALSE; - return TRUE; } @@ -178,7 +189,7 @@ void wxWindow::OnErase(wxEraseEvent& event) return; } - + DoDrawBackground(*event.GetDC()); // if we have both scrollbars, we also have a square in the corner between @@ -366,7 +377,7 @@ bool wxWindow::Enable(bool enable) return FALSE; // disabled window can't keep focus - if ( FindFocus() == this ) + if ( FindFocus() == this && GetParent() != NULL ) { GetParent()->SetFocus(); } @@ -444,12 +455,114 @@ int wxWindow::GetStateFlags() const void wxWindow::OnSize(wxSizeEvent& event) { + event.Skip(); + if ( m_scrollbarVert || m_scrollbarHorz ) { PositionScrollbars(); } - - event.Skip(); + +#if 0 // ndef __WXMSW__ + // Refresh the area (strip) previously occupied by the border + + if (HasFlag( wxNO_FULL_REPAINT_ON_RESIZE ) && IsShown()) + { + // This code assumes that wxSizeEvent.GetSize() returns + // the area of the entire window, not just the client + // area. + wxSize newSize = event.GetSize(); + + if (m_oldSize.x == -1 && m_oldSize.y == -1) + { + m_oldSize = newSize; + return; + } + + if (HasFlag( wxSIMPLE_BORDER )) + { + if (newSize.y > m_oldSize.y) + { + wxRect rect; + rect.x = 0; + rect.width = m_oldSize.x; + rect.y = m_oldSize.y-2; + rect.height = 1; + Refresh( TRUE, &rect ); + } + else if (newSize.y < m_oldSize.y) + { + wxRect rect; + rect.y = newSize.y; + rect.x = 0; + rect.height = 1; + rect.width = newSize.x; + wxWindowNative::Refresh( TRUE, &rect ); + } + + if (newSize.x > m_oldSize.x) + { + wxRect rect; + rect.y = 0; + rect.height = m_oldSize.y; + rect.x = m_oldSize.x-2; + rect.width = 1; + Refresh( TRUE, &rect ); + } + else if (newSize.x < m_oldSize.x) + { + wxRect rect; + rect.x = newSize.x; + rect.y = 0; + rect.width = 1; + rect.height = newSize.y; + wxWindowNative::Refresh( TRUE, &rect ); + } + } + else + if (HasFlag( wxSUNKEN_BORDER ) || HasFlag( wxRAISED_BORDER )) + { + if (newSize.y > m_oldSize.y) + { + wxRect rect; + rect.x = 0; + rect.width = m_oldSize.x; + rect.y = m_oldSize.y-4; + rect.height = 2; + Refresh( TRUE, &rect ); + } + else if (newSize.y < m_oldSize.y) + { + wxRect rect; + rect.y = newSize.y; + rect.x = 0; + rect.height = 2; + rect.width = newSize.x; + wxWindowNative::Refresh( TRUE, &rect ); + } + + if (newSize.x > m_oldSize.x) + { + wxRect rect; + rect.y = 0; + rect.height = m_oldSize.y; + rect.x = m_oldSize.x-4; + rect.width = 2; + Refresh( TRUE, &rect ); + } + else if (newSize.x < m_oldSize.x) + { + wxRect rect; + rect.x = newSize.x; + rect.y = 0; + rect.width = 2; + rect.height = newSize.y; + wxWindowNative::Refresh( TRUE, &rect ); + } + } + + m_oldSize = newSize; + } +#endif } wxSize wxWindow::DoGetBestSize() const @@ -474,8 +587,11 @@ wxPoint wxWindow::GetClientAreaOrigin() const { wxPoint pt = wxWindowBase::GetClientAreaOrigin(); +#if wxUSE_TWO_WINDOWS +#else if ( m_renderer ) pt += m_renderer->GetBorderDimensions(GetBorder()).GetPosition(); +#endif return pt; } @@ -654,17 +770,26 @@ void wxWindow::SetScrollbar(int orient, int range, bool refresh) { + wxASSERT_MSG( pageSize <= range, + _T("page size can't be greater than range") ); + bool hasClientSizeChanged = FALSE; wxScrollBar *scrollbar = GetScrollbar(orient); - if ( range ) + if ( range && (pageSize < range) ) { if ( !scrollbar ) { // create it +#if wxUSE_TWO_WINDOWS + SetInsertIntoMain( TRUE ); +#endif scrollbar = new wxScrollBar(this, -1, wxDefaultPosition, wxDefaultSize, orient & wxVERTICAL ? wxSB_VERTICAL : wxSB_HORIZONTAL); +#if wxUSE_TWO_WINDOWS + SetInsertIntoMain( FALSE ); +#endif if ( orient & wxVERTICAL ) m_scrollbarVert = scrollbar; else @@ -729,8 +854,13 @@ void wxWindow::SetScrollPos(int orient, int pos, bool refresh) wxCHECK_RET( scrollbar, _T("no scrollbar to set position for") ); scrollbar->SetThumbPosition(pos); + + // VZ: I think we can safely ignore this as we always refresh it + // automatically whenever the value chanegs +#if 0 if ( refresh ) Refresh(); +#endif } int wxWindow::GetScrollPos(int orient) const @@ -753,6 +883,14 @@ int wxWindow::GetScrollRange(int orient) const void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) { + // use native scrolling when available and do it in generic way + // otherwise: +#ifdef __WXX11__ + + wxWindowNative::ScrollWindow(dx, dy, rect); + +#else + // before scrolling it, ensure that we don't have any unpainted areas Update(); @@ -769,6 +907,45 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) r = ScrollNoRefresh(0, dy, rect); Refresh(TRUE /* erase bkgnd */, &r); } + + // scroll children accordingly: + wxPoint offset(dx, dy); + + for (wxWindowList::Node *node = GetChildren().GetFirst(); + node; node = node->GetNext()) + { + wxWindow *child = node->GetData(); + if ( child == m_scrollbarVert || child == m_scrollbarHorz ) + continue; + + // VS: Scrolling children has non-trivial semantics. If rect=NULL then + // it is easy: we scroll all children. Otherwise it gets + // complicated: + // 1. if scrolling in one direction only, scroll only + // those children that intersect shaft defined by the rectangle + // and scrolling direction + // 2. if scrolling in both axes, scroll all children + + if ( rect && (dx * dy == 0 /* moving in only one of x, y axis */) ) + { + wxRect childRect = child->GetRect(); + if ( dx == 0 && (childRect.GetLeft() <= rect->GetRight() || + childRect.GetRight() >= rect->GetLeft()) ) + { + child->Move(child->GetPosition() + offset); + } + else if ( dy == 0 && (childRect.GetTop() <= rect->GetBottom() || + childRect.GetBottom() >= rect->GetTop()) ) + { + child->Move(child->GetPosition() + offset); + } + } + else + { + child->Move(child->GetPosition() + offset); + } + } +#endif } wxRect wxWindow::ScrollNoRefresh(int dx, int dy, const wxRect *rectTotal) @@ -852,7 +1029,7 @@ wxRect wxWindow::ScrollNoRefresh(int dx, int dy, const wxRect *rectTotal) dcMem.SelectObject(bmp); dcMem.Blit(wxPoint(0, 0), size, &dc, ptSource -#if defined(__WXGTK__) && !defined(__WX_DC_BLIT_FIXED__) +#if defined(__WXGTK__) && !defined(wxHAS_WORKING_GTK_DC_BLIT) + GetClientAreaOrigin() #endif // broken wxGTK wxDC::Blit ); @@ -925,81 +1102,6 @@ wxRect wxWindow::ScrollNoRefresh(int dx, int dy, const wxRect *rectTotal) return rect; } -// ---------------------------------------------------------------------------- -// colours/fonts -// ---------------------------------------------------------------------------- - -bool wxWindow::SetBackgroundColour(const wxColour& colour) -{ - if ( !wxWindowNative::SetBackgroundColour(colour) ) - return FALSE; - - m_hasBgCol = TRUE; - - return TRUE; -} - -bool wxWindow::SetForegroundColour(const wxColour& colour) -{ - if ( !wxWindowNative::SetForegroundColour(colour) ) - return FALSE; - - m_hasFgCol = TRUE; - - return TRUE; -} - -bool wxWindow::SetFont(const wxFont& font) -{ - if ( !wxWindowNative::SetFont(font) ) - return FALSE; - - m_hasFont = TRUE; - - return TRUE; -} - -// ---------------------------------------------------------------------------- -// mouse capture -// ---------------------------------------------------------------------------- - -struct WXDLLEXPORT wxWindowNext -{ - wxWindow *win; - wxWindowNext *next; -} *wxWindow::ms_winCaptureNext = NULL; - -void wxWindow::CaptureMouse() -{ - wxWindow *winOld = GetCapture(); - if ( winOld ) - { - // save it on stack - wxWindowNext *item = new wxWindowNext; - item->win = winOld; - item->next = ms_winCaptureNext; - ms_winCaptureNext = item; - } - //else: no mouse capture to save - - wxWindowNative::CaptureMouse(); -} - -void wxWindow::ReleaseMouse() -{ - wxWindowNative::ReleaseMouse(); - - if ( ms_winCaptureNext ) - { - ms_winCaptureNext->win->CaptureMouse(); - - wxWindowNext *item = ms_winCaptureNext; - ms_winCaptureNext = item->next; - delete item; - } - //else: stack is empty, no previous capture -} - // ---------------------------------------------------------------------------- // accelerators and menu hot keys // ---------------------------------------------------------------------------- @@ -1056,6 +1158,22 @@ void wxWindow::OnKeyDown(wxKeyEvent& event) } #endif // wxUSE_MENUS + // if it wasn't in a menu, try to find a button + if ( command != -1 ) + { + wxWindow* child = win->FindWindow(command); + if ( child && wxDynamicCast(child, wxButton) ) + { + wxCommandEvent eventCmd(wxEVT_COMMAND_BUTTON_CLICKED, command); + eventCmd.SetEventObject(child); + if ( child->GetEventHandler()->ProcessEvent(eventCmd) ) + { + // skip "event.Skip()" below + return; + } + } + } + // don't propagate accels from the child frame to the parent one break; } @@ -1141,3 +1259,29 @@ void wxWindow::OnKeyUp(wxKeyEvent& event) #endif // wxUSE_MENUS +// ---------------------------------------------------------------------------- +// MSW-specific section +// ---------------------------------------------------------------------------- + +#ifdef __WXMSW__ + +#include "wx/msw/private.h" + +long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) +{ + if ( message == WM_NCHITTEST ) + { + // the windows which contain the other windows should let the mouse + // events through, otherwise a window inside a static box would + // never get any events at all + if ( IsStaticBox() ) + { + return HTTRANSPARENT; + } + } + + return wxWindowNative::MSWWindowProc(message, wParam, lParam); +} + +#endif // __WXMSW__ +