X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b2088388cc6fa895063cf1774cc552146cb9e6fe..683df83d51c0f080e2e5210dc8115be0cb30d1ad:/src/osx/window_osx.cpp diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index 6c3433c723..e8ce2cfc67 100644 --- a/src/osx/window_osx.cpp +++ b/src/osx/window_osx.cpp @@ -1,10 +1,10 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: src/osx/carbon/window.cpp +// Name: src/osx/window_osx.cpp // Purpose: wxWindowMac // Author: Stefan Csomor // Modified by: // Created: 1998-01-01 -// RCS-ID: $Id: window.cpp 54981 2008-08-05 17:52:02Z SC $ +// RCS-ID: $Id$ // Copyright: (c) Stefan Csomor // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -58,17 +58,15 @@ #endif #if wxUSE_DRAG_AND_DROP -#include "wx/dnd.h" + #include "wx/dnd.h" #endif #include "wx/graphics.h" #if wxOSX_USE_CARBON -#include "wx/osx/uma.h" + #include "wx/osx/uma.h" #else -#include "wx/osx/private.h" -// bring in themeing -#include + #include "wx/osx/private.h" #endif #define MAC_SCROLLBAR_SIZE 15 @@ -78,13 +76,9 @@ #ifdef __WXUNIVERSAL__ IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase) -#else - IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) #endif BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase) - EVT_NC_PAINT(wxWindowMac::OnNcPaint) - EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground) EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent) END_EVENT_TABLE() @@ -93,10 +87,100 @@ END_EVENT_TABLE() #define wxMAC_DEBUG_REDRAW 0 #endif +wxWidgetImplType* kOSXNoWidgetImpl = (wxWidgetImplType*) -1L; + +#if wxUSE_HOTKEY && wxOSX_USE_COCOA_OR_CARBON + +typedef struct { + EventHotKeyRef ref; + int keyId; + wxWindow* window; +} wxHotKeyRec; + +wxVector s_hotkeys; + +#endif + // =========================================================================== // implementation // =========================================================================== +// the grow box has to be implemented as an inactive window, so that nothing can direct +// the focus to it + +class WXDLLIMPEXP_CORE wxBlindPlateWindow : public wxWindow +{ +public: + wxBlindPlateWindow() { Init(); } + + // Old-style constructor (no default values for coordinates to avoid + // ambiguity with the new one) + wxBlindPlateWindow(wxWindow *parent, + int x, int y, int width, int height, + long style = wxTAB_TRAVERSAL | wxNO_BORDER, + const wxString& name = wxPanelNameStr) + { + Init(); + + Create(parent, wxID_ANY, wxPoint(x, y), wxSize(width, height), style, name); + } + + // Constructor + wxBlindPlateWindow(wxWindow *parent, + wxWindowID winid = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxTAB_TRAVERSAL | wxNO_BORDER, + const wxString& name = wxPanelNameStr) + { + Init(); + + Create(parent, winid, pos, size, style, name); + } + + // Pseudo ctor + bool Create(wxWindow *parent, + wxWindowID winid = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxTAB_TRAVERSAL | wxNO_BORDER, + const wxString& name = wxPanelNameStr) + { + if ( !wxWindow::Create(parent, winid, pos, size, style, name) ) + return false; + + // so that non-solid background renders correctly under GTK+: + SetThemeEnabled(true); + return true; + } + + virtual ~wxBlindPlateWindow(); + + virtual bool AcceptsFocus() const + { + return false; + } + +protected: + // common part of all ctors + void Init() + { + } + + DECLARE_DYNAMIC_CLASS_NO_COPY(wxBlindPlateWindow) + DECLARE_EVENT_TABLE() +}; + +wxBlindPlateWindow::~wxBlindPlateWindow() +{ +} + +IMPLEMENT_DYNAMIC_CLASS(wxBlindPlateWindow, wxWindow) + +BEGIN_EVENT_TABLE(wxBlindPlateWindow, wxWindow) +END_EVENT_TABLE() + + // ---------------------------------------------------------------------------- // constructors and such // ---------------------------------------------------------------------------- @@ -130,15 +214,31 @@ void wxWindowMac::Init() m_vScrollBar = NULL ; m_hScrollBarAlwaysShown = false; m_vScrollBarAlwaysShown = false; + m_growBox = NULL ; - m_macIsUserPane = true; m_clipChildren = false ; m_cachedClippedRectValid = false ; + m_isNativeWindowWrapper = false; } wxWindowMac::~wxWindowMac() { SendDestroyEvent(); + +#if wxUSE_HOTKEY && wxOSX_USE_COCOA_OR_CARBON + for ( int i = s_hotkeys.size()-1; i>=0; -- i ) + { + if ( s_hotkeys[i].window == this ) + { + EventHotKeyRef ref = s_hotkeys[i].ref; + s_hotkeys.erase(s_hotkeys.begin() + i); + if ( UnregisterEventHotKey(ref) != noErr ) + { + wxLogLastError(wxT("UnregisterHotKey")); + } + } + } +#endif MacInvalidateBorders() ; @@ -183,24 +283,102 @@ wxWindowMac::~wxWindowMac() // delete our drop target if we've got one #if wxUSE_DRAG_AND_DROP - if ( m_dropTarget != NULL ) - { - delete m_dropTarget; - m_dropTarget = NULL; - } + wxDELETE(m_dropTarget); #endif - delete m_peer ; + delete GetPeer() ; } WXWidget wxWindowMac::GetHandle() const { - return (WXWidget) m_peer->GetWXWidget() ; + if ( GetPeer() ) + return (WXWidget) GetPeer()->GetWXWidget() ; + return NULL; } -// -// TODO END move to window_osx.cpp -// +wxOSXWidgetImpl* wxWindowMac::GetPeer() const +{ + return m_peer == kOSXNoWidgetImpl ? NULL : m_peer ; +} + +bool wxWindowMac::ShouldCreatePeer() const +{ + return m_peer != kOSXNoWidgetImpl; +} + +void wxWindowMac::DontCreatePeer() +{ + m_peer = kOSXNoWidgetImpl; +} + +void wxWindowMac::SetWrappingPeer(wxOSXWidgetImpl* wrapper) +{ + wxOSXWidgetImpl* inner = GetPeer(); + wxASSERT_MSG( inner != NULL && inner->IsOk(), "missing or incomplete inner peer" ); + wxASSERT_MSG( wrapper != NULL && wrapper->IsOk(), "missing or incomplete wrapper" ); + + if ( !(inner != NULL && inner->IsOk() && wrapper != NULL && wrapper->IsOk()) ) + return; + + inner->RemoveFromParent(); + wrapper->InstallEventHandler(); + wrapper->Embed(inner); + m_peer = wrapper; +} + +void wxWindowMac::SetPeer(wxOSXWidgetImpl* peer) +{ + if ( GetPeer() ) + { + if ( !GetPeer()->IsRootControl() ) + GetPeer()->RemoveFromParent(); + wxDELETE(m_peer); + } + + m_peer = peer; + + if ( GetPeer() && !GetPeer()->IsRootControl()) + { + wxASSERT_MSG( GetPeer()->IsOk() , wxT("The native control must exist already") ) ; + + if (!GetParent()->GetChildren().Find((wxWindow*)this)) + GetParent()->AddChild( this ); + + GetPeer()->InstallEventHandler(); + GetPeer()->Embed(GetParent()->GetPeer()); + + GetParent()->MacChildAdded() ; + + // adjust font, controlsize etc + GetPeer()->SetControlSize( m_windowVariant ); + InheritAttributes(); + // in case nothing has been set, use the variant default fonts + if ( !m_hasFont ) + DoSetWindowVariant( m_windowVariant ); + + GetPeer()->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics), GetFont().GetEncoding() ) ; + + // for controls we want to use best size for wxDefaultSize params ) + if ( !GetPeer()->IsUserPane() ) + SetInitialSize(GetMinSize()); + + SetCursor( *wxSTANDARD_CURSOR ) ; + } +} + +#if WXWIN_COMPATIBILITY_2_8 + +bool wxWindowMac::MacIsUserPane() +{ + return GetPeer() == NULL || GetPeer()->IsUserPane(); +} + +#endif + +bool wxWindowMac::MacIsUserPane() const +{ + return GetPeer() == NULL || GetPeer()->IsUserPane(); +} // --------------------------------------------------------------------------- // Utility Routines to move between different coordinate systems @@ -209,7 +387,7 @@ WXWidget wxWindowMac::GetHandle() const /* * Right now we have the following setup : * a border that is not part of the native control is always outside the - * control's border (otherwise we loose all native intelligence, future ways + * control's border (otherwise we lose all native intelligence, future ways * may be to have a second embedding control responsible for drawing borders * and backgrounds eventually) * so all this border calculations have to be taken into account when calling @@ -238,15 +416,19 @@ bool wxWindowMac::Create(wxWindowMac *parent, m_windowVariant = parent->GetWindowVariant() ; - if ( m_macIsUserPane ) + if ( m_peer != kOSXNoWidgetImpl ) { - m_peer = wxWidgetImpl::CreateUserPane( this, parent, id, pos, size , style, GetExtraStyle() ); + SetPeer(wxWidgetImpl::CreateUserPane( this, parent, id, pos, size , style, GetExtraStyle() )); MacPostControlCreate(pos, size) ; } #ifndef __WXUNIVERSAL__ // Don't give scrollbars to wxControls unless they ask for them - if ( (! IsKindOf(CLASSINFO(wxControl)) && ! IsKindOf(CLASSINFO(wxStatusBar))) + if ( (! IsKindOf(CLASSINFO(wxControl)) +#if wxUSE_STATUSBAR + && ! IsKindOf(CLASSINFO(wxStatusBar)) +#endif + ) || (IsKindOf(CLASSINFO(wxControl)) && ((style & wxHSCROLL) || (style & wxVSCROLL)))) { MacCreateScrollBars( style ) ; @@ -261,116 +443,89 @@ bool wxWindowMac::Create(wxWindowMac *parent, void wxWindowMac::MacChildAdded() { +#if wxUSE_SCROLLBAR if ( m_vScrollBar ) m_vScrollBar->Raise() ; if ( m_hScrollBar ) m_hScrollBar->Raise() ; + if ( m_growBox ) + m_growBox->Raise() ; +#endif } -void wxWindowMac::MacPostControlCreate(const wxPoint& WXUNUSED(pos), const wxSize& size) +void wxWindowMac::MacPostControlCreate(const wxPoint& WXUNUSED(pos), + const wxSize& WXUNUSED(size)) { - wxASSERT_MSG( m_peer != NULL && m_peer->IsOk() , wxT("No valid mac control") ) ; + // todo remove if refactoring works correctly +#if 0 + wxASSERT_MSG( GetPeer() != NULL && GetPeer()->IsOk() , wxT("No valid mac control") ) ; - GetParent()->AddChild( this ); + if (!GetParent()->GetChildren().Find((wxWindow*)this)) + GetParent()->AddChild( this ); - m_peer->InstallEventHandler(); - m_peer->Embed(GetParent()->GetPeer()); + GetPeer()->InstallEventHandler(); + GetPeer()->Embed(GetParent()->GetPeer()); GetParent()->MacChildAdded() ; // adjust font, controlsize etc DoSetWindowVariant( m_windowVariant ) ; - m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics), GetFont().GetEncoding() ) ; + GetPeer()->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics), GetFont().GetEncoding() ) ; // for controls we want to use best size for wxDefaultSize params ) - if ( !m_macIsUserPane ) + if ( !GetPeer()->IsUserPane() ) SetInitialSize(size); SetCursor( *wxSTANDARD_CURSOR ) ; +#endif } void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant ) { // Don't assert, in case we set the window variant before // the window is created - // wxASSERT( m_peer->Ok() ) ; + // wxASSERT( GetPeer()->IsOk() ) ; m_windowVariant = variant ; - if (m_peer == NULL || !m_peer->IsOk()) + if (GetPeer() == NULL || !GetPeer()->IsOk()) return; - m_peer->SetControlSize( variant ); -#if wxOSX_USE_CARBON - ControlSize size ; - - // we will get that from the settings later - // and make this NORMAL later, but first - // we have a few calculations that we must fix - - switch ( variant ) - { - case wxWINDOW_VARIANT_NORMAL : - size = kControlSizeNormal; - break ; - - case wxWINDOW_VARIANT_SMALL : - size = kControlSizeSmall; - break ; - - case wxWINDOW_VARIANT_MINI : - // not always defined in the headers - size = 3 ; - break ; - - case wxWINDOW_VARIANT_LARGE : - size = kControlSizeLarge; - break ; - - default: - wxFAIL_MSG(_T("unexpected window variant")); - break ; - } - m_peer->SetData(kControlEntireControl, kControlSizeTag, &size ) ; -#endif - - wxFont font ; - - wxOSXSystemFont systemFont = wxOSX_SYSTEM_FONT_NORMAL ; + GetPeer()->SetControlSize( variant ); switch ( variant ) { case wxWINDOW_VARIANT_NORMAL : - systemFont = wxOSX_SYSTEM_FONT_NORMAL ; + static wxFont sysNormal(wxOSX_SYSTEM_FONT_NORMAL); + SetFont(sysNormal) ; break ; case wxWINDOW_VARIANT_SMALL : - systemFont = wxOSX_SYSTEM_FONT_SMALL ; + static wxFont sysSmall(wxOSX_SYSTEM_FONT_SMALL); + SetFont(sysSmall) ; break ; case wxWINDOW_VARIANT_MINI : - systemFont = wxOSX_SYSTEM_FONT_MINI ; + static wxFont sysMini(wxOSX_SYSTEM_FONT_MINI); + SetFont(sysMini) ; break ; case wxWINDOW_VARIANT_LARGE : - systemFont = wxOSX_SYSTEM_FONT_NORMAL ; + static wxFont sysLarge(wxOSX_SYSTEM_FONT_NORMAL); + SetFont(sysLarge) ; break ; default: - wxFAIL_MSG(_T("unexpected window variant")); + wxFAIL_MSG(wxT("unexpected window variant")); break ; } - - font.CreateSystemFont( systemFont ) ; - - SetFont( font ) ; } void wxWindowMac::MacUpdateControlFont() { - if ( m_peer ) - m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ; + if ( GetPeer() ) + GetPeer()->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ; // do not trigger refreshes upon invisible and possible partly created objects if ( IsShownOnScreen() ) @@ -396,33 +551,86 @@ bool wxWindowMac::SetForegroundColour(const wxColour& col ) return retval; } +bool wxWindowMac::SetBackgroundStyle(wxBackgroundStyle style) +{ + if ( !wxWindowBase::SetBackgroundStyle(style) ) + return false; + + if ( GetPeer() ) + GetPeer()->SetBackgroundStyle(style); + return true; +} + bool wxWindowMac::SetBackgroundColour(const wxColour& col ) { + if (m_growBox) + { + if ( m_backgroundColour.IsOk() ) + m_growBox->SetBackgroundColour(m_backgroundColour); + else + m_growBox->SetBackgroundColour(*wxWHITE); + } + if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol ) return false ; - if ( m_peer ) - m_peer->SetBackgroundColour( col ) ; + if ( GetPeer() ) + GetPeer()->SetBackgroundColour( col ) ; return true ; } +static bool wxIsWindowOrParentDisabled(wxWindow* w) +{ + while (w && !w->IsTopLevel()) + { + if (!w->IsEnabled()) + return true; + w = w->GetParent(); + } + return false; +} + void wxWindowMac::SetFocus() { if ( !AcceptsFocus() ) return ; + if (wxIsWindowOrParentDisabled((wxWindow*) this)) + return; + wxWindow* former = FindFocus() ; if ( former == this ) return ; - m_peer->SetFocus() ; + GetPeer()->SetFocus() ; +} + +void wxWindowMac::OSXSimulateFocusEvents() +{ + wxWindow* former = FindFocus() ; + if ( former != NULL && former != this ) + { + { + wxFocusEvent event( wxEVT_KILL_FOCUS, former->GetId()); + event.SetEventObject(former); + event.SetWindow(this); + former->HandleWindowEvent(event) ; + } + + { + wxFocusEvent event(wxEVT_SET_FOCUS, former->GetId()); + event.SetEventObject(former); + event.SetWindow(this); + former->HandleWindowEvent(event); + } + } } void wxWindowMac::DoCaptureMouse() { wxApp::s_captureWindow = (wxWindow*) this ; - m_peer->CaptureMouse() ; + GetPeer()->CaptureMouse() ; } wxWindow * wxWindowBase::GetCapture() @@ -434,7 +642,7 @@ void wxWindowMac::DoReleaseMouse() { wxApp::s_captureWindow = NULL ; - m_peer->ReleaseMouse() ; + GetPeer()->ReleaseMouse() ; } #if wxUSE_DRAG_AND_DROP @@ -444,10 +652,8 @@ void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget) delete m_dropTarget; m_dropTarget = pDropTarget; - if ( m_dropTarget != NULL ) - { - // TODO: - } + + GetPeer()->SetDropTarget(m_dropTarget) ; } #endif @@ -470,8 +676,8 @@ bool wxWindowMac::MacGetBoundsForControl( x = (int)pos.x; y = (int)pos.y; - w = WidthDefault( size.x ); - h = HeightDefault( size.y ); + w = WidthDefault( size.x ); + h = HeightDefault( size.y ); x += MacGetLeftBorderSize() ; y += MacGetTopBorderSize() ; @@ -495,7 +701,7 @@ bool wxWindowMac::MacGetBoundsForControl( void wxWindowMac::DoGetSize(int *x, int *y) const { int width, height; - m_peer->GetSize( width, height ); + GetPeer()->GetSize( width, height ); if (x) *x = width + MacGetLeftBorderSize() + MacGetRightBorderSize() ; @@ -507,8 +713,8 @@ void wxWindowMac::DoGetSize(int *x, int *y) const void wxWindowMac::DoGetPosition(int *x, int *y) const { int x1, y1; - - m_peer->GetPosition( x1, y1 ) ; + + GetPeer()->GetPosition( x1, y1 ) ; // get the wx window position from the native one x1 -= MacGetLeftBorderSize() ; @@ -593,7 +799,7 @@ void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const { pt.x -= MacGetLeftBorderSize() ; pt.y -= MacGetTopBorderSize() ; - wxWidgetImpl::Convert( &pt , m_peer , top->m_peer ) ; + wxWidgetImpl::Convert( &pt , GetPeer() , top->GetPeer() ) ; } } @@ -617,7 +823,7 @@ void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const wxNonOwnedWindow* top = MacGetTopLevelWindow(); if (top) { - wxWidgetImpl::Convert( &pt , top->m_peer , m_peer ) ; + wxWidgetImpl::Convert( &pt , top->GetPeer() , GetPeer() ) ; pt.x += MacGetLeftBorderSize() ; pt.y += MacGetTopBorderSize() ; } @@ -636,13 +842,13 @@ wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const int innerwidth, innerheight; int left, top; int outerwidth, outerheight; - - m_peer->GetContentArea( left, top, innerwidth, innerheight ); - m_peer->GetSize( outerwidth, outerheight ); - + + GetPeer()->GetContentArea( left, top, innerwidth, innerheight ); + GetPeer()->GetSize( outerwidth, outerheight ); + sizeTotal.x += outerwidth-innerwidth; sizeTotal.y += outerheight-innerheight; - + sizeTotal.x += MacGetLeftBorderSize() + MacGetRightBorderSize() ; sizeTotal.y += MacGetTopBorderSize() + MacGetBottomBorderSize() ; @@ -655,15 +861,16 @@ void wxWindowMac::DoGetClientSize( int *x, int *y ) const int ww, hh; int left, top; - - m_peer->GetContentArea( left, top, ww, hh ); + GetPeer()->GetContentArea( left, top, ww, hh ); +#if wxUSE_SCROLLBAR if (m_hScrollBar && m_hScrollBar->IsShown() ) hh -= m_hScrollBar->GetSize().y ; if (m_vScrollBar && m_vScrollBar->IsShown() ) ww -= m_vScrollBar->GetSize().x ; +#endif if (x) *x = ww; if (y) @@ -686,7 +893,7 @@ bool wxWindowMac::SetCursor(const wxCursor& cursor) return false ; } - wxASSERT_MSG( m_cursor.Ok(), + wxASSERT_MSG( m_cursor.IsOk(), wxT("cursor must be valid after call to the base version")); if ( GetPeer() != NULL ) @@ -699,7 +906,6 @@ bool wxWindowMac::SetCursor(const wxCursor& cursor) bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y) { #ifndef __WXUNIVERSAL__ - menu->SetInvokingWindow((wxWindow*)this); menu->UpdateUI(); if ( x == wxDefaultCoord && y == wxDefaultCoord ) @@ -713,7 +919,6 @@ bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y) ClientToScreen( &x , &y ) ; } menu->GetPeer()->PopUp(this, x, y); - menu->SetInvokingWindow( NULL ); return true; #else // actually this shouldn't be called, because universal is having its own implementation @@ -734,13 +939,16 @@ void wxWindowMac::DoSetToolTip(wxToolTip *tooltip) if ( m_tooltip ) m_tooltip->SetWindow(this); + + if (GetPeer()) + GetPeer()->SetToolTip(tooltip); } #endif void wxWindowMac::MacInvalidateBorders() { - if ( m_peer == NULL ) + if ( GetPeer() == NULL ) return ; bool vis = IsShownOnScreen() ; @@ -749,7 +957,7 @@ void wxWindowMac::MacInvalidateBorders() int outerBorder = MacGetLeftBorderSize() ; - if ( m_peer->NeedsFocusRect() ) + if ( GetPeer()->NeedsFocusRect() ) outerBorder += 4 ; if ( outerBorder == 0 ) @@ -758,20 +966,20 @@ void wxWindowMac::MacInvalidateBorders() // now we know that we have something to do at all int tx,ty,tw,th; - - m_peer->GetSize( tw, th ); - m_peer->GetPosition( tx, ty ); + + GetPeer()->GetSize( tw, th ); + GetPeer()->GetPosition( tx, ty ); wxRect leftupdate( tx-outerBorder,ty,outerBorder,th ); wxRect rightupdate( tx+tw, ty, outerBorder, th ); wxRect topupdate( tx-outerBorder, ty-outerBorder, tw + 2 * outerBorder, outerBorder ); wxRect bottomupdate( tx-outerBorder, ty + th, tw + 2 * outerBorder, outerBorder ); - + if (GetParent()) { - GetParent()->m_peer->SetNeedsDisplay(&leftupdate); - GetParent()->m_peer->SetNeedsDisplay(&rightupdate); - GetParent()->m_peer->SetNeedsDisplay(&topupdate); - GetParent()->m_peer->SetNeedsDisplay(&bottomupdate); + GetParent()->GetPeer()->SetNeedsDisplay(&leftupdate); + GetParent()->GetPeer()->SetNeedsDisplay(&rightupdate); + GetParent()->GetPeer()->SetNeedsDisplay(&topupdate); + GetParent()->GetPeer()->SetNeedsDisplay(&bottomupdate); } } @@ -797,6 +1005,8 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) int actualX = x; int actualY = y; +#if 0 + // min and max sizes are only for sizers, not for explicit size setting if ((m_minWidth != -1) && (actualWidth < m_minWidth)) actualWidth = m_minWidth; if ((m_minHeight != -1) && (actualHeight < m_minHeight)) @@ -805,6 +1015,7 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) actualWidth = m_maxWidth; if ((m_maxHeight != -1) && (actualHeight > m_maxHeight)) actualHeight = m_maxHeight; +#endif bool doMove = false, doResize = false ; @@ -830,8 +1041,8 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) MacInvalidateBorders() ; m_cachedClippedRectValid = false ; - - m_peer->Move( bounds.x, bounds.y, bounds.width, bounds.height); + + GetPeer()->Move( bounds.x, bounds.y, bounds.width, bounds.height); wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified @@ -849,25 +1060,22 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) if ( doResize ) { MacRepositionScrollBars() ; - wxSize size(actualWidth, actualHeight); - wxSizeEvent event(size, m_windowId); - event.SetEventObject(this); - HandleWindowEvent(event); + SendSizeEvent(); } } } wxSize wxWindowMac::DoGetBestSize() const { - if ( m_macIsUserPane || IsTopLevel() ) + if ( GetPeer() == NULL || GetPeer()->IsUserPane() || IsTopLevel() ) { return wxWindowBase::DoGetBestSize() ; } else { wxRect r ; - - m_peer->GetBestRect(&r); + + GetPeer()->GetBestRect(&r); if ( r.GetWidth() == 0 && r.GetHeight() == 0 ) { @@ -876,25 +1084,28 @@ wxSize wxWindowMac::DoGetBestSize() const r.width = r.height = 16 ; +#if wxUSE_SCROLLBAR if ( IsKindOf( CLASSINFO( wxScrollBar ) ) ) { r.height = 16 ; } - #if wxUSE_SPINBTN - else if ( IsKindOf( CLASSINFO( wxSpinButton ) ) ) + else +#endif +#if wxUSE_SPINBTN + if ( IsKindOf( CLASSINFO( wxSpinButton ) ) ) { r.height = 24 ; } - #endif else +#endif { // return wxWindowBase::DoGetBestSize() ; } } - int bestWidth = r.width + MacGetLeftBorderSize() + + int bestWidth = r.width + MacGetLeftBorderSize() + MacGetRightBorderSize(); - int bestHeight = r.height + MacGetTopBorderSize() + + int bestHeight = r.height + MacGetTopBorderSize() + MacGetBottomBorderSize(); if ( bestHeight < 10 ) bestHeight = 13 ; @@ -903,6 +1114,12 @@ wxSize wxWindowMac::DoGetBestSize() const } } +void wxWindowMac::SendSizeEvent(int flags) +{ + MacOnInternalSize(); + wxWindowBase::SendSizeEvent(flags); +} + // set the size of the window: if the dimensions are positive, just use them, // but if any of them is equal to -1, it means that we must find the value for // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in @@ -929,9 +1146,7 @@ void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags) if (sizeFlags & wxSIZE_FORCE_EVENT) { - wxSizeEvent event( wxSize(width,height), GetId() ); - event.SetEventObject( this ); - HandleWindowEvent( event ); + SendSizeEvent(); } return; @@ -985,7 +1200,7 @@ void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags) wxPoint wxWindowMac::GetClientAreaOrigin() const { int left,top,width,height; - m_peer->GetContentArea( left , top , width , height); + GetPeer()->GetContentArea( left , top , width , height); return wxPoint( left + MacGetLeftBorderSize() , top + MacGetTopBorderSize() ); } @@ -1004,12 +1219,22 @@ void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight) } } +double wxWindowMac::GetContentScaleFactor() const +{ + return GetPeer()->GetContentScaleFactor(); +} + void wxWindowMac::SetLabel(const wxString& title) { + if ( title == m_label ) + return; + m_label = title ; - if ( m_peer && m_peer->IsOk() && !(IsKindOf( CLASSINFO(wxButton) ) && GetId() == wxID_HELP) ) - m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics), GetFont().GetEncoding() ) ; + InvalidateBestSize(); + + if ( GetPeer() && GetPeer()->IsOk() ) + GetPeer()->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics), GetFont().GetEncoding() ) ; // do not trigger refreshes upon invisible and possible partly created objects if ( IsShownOnScreen() ) @@ -1023,18 +1248,47 @@ wxString wxWindowMac::GetLabel() const bool wxWindowMac::Show(bool show) { + if ( !show ) + MacInvalidateBorders(); + if ( !wxWindowBase::Show(show) ) return false; - if ( m_peer ) - m_peer->SetVisibility( show ) ; + if ( GetPeer() ) + GetPeer()->SetVisibility( show ) ; + + if ( show ) + MacInvalidateBorders(); + +#ifdef __WXOSX_IPHONE__ + // only when there's no native event support + if ( !IsTopLevel() ) +#endif + { + wxShowEvent eventShow(GetId(), show); + eventShow.SetEventObject(this); + + HandleWindowEvent(eventShow); + } + + return true; +} + +bool wxWindowMac::OSXShowWithEffect(bool show, + wxShowEffect effect, + unsigned timeout) +{ + if ( effect == wxSHOW_EFFECT_NONE || + !GetPeer() || !GetPeer()->ShowWithEffect(show, effect, timeout) ) + return Show(show); return true; } void wxWindowMac::DoEnable(bool enable) { - m_peer->Enable( enable ) ; + GetPeer()->Enable( enable ) ; + MacInvalidateBorders(); } // @@ -1051,7 +1305,6 @@ void wxWindowMac::MacHiliteChanged() void wxWindowMac::MacEnabledStateChanged() { - OnEnabled( m_peer->IsEnabled() ); } // @@ -1060,13 +1313,13 @@ void wxWindowMac::MacEnabledStateChanged() bool wxWindowMac::MacIsReallyEnabled() { - return m_peer->IsEnabled() ; + return GetPeer()->IsEnabled() ; } bool wxWindowMac::MacIsReallyHilited() { #if wxOSX_USE_CARBON - return m_peer->IsActive(); + return GetPeer()->IsActive(); #else return true; // TODO #endif @@ -1088,8 +1341,11 @@ int wxWindowMac::GetCharWidth() const return width; } -void wxWindowMac::GetTextExtent(const wxString& str, int *x, int *y, - int *descent, int *externalLeading, const wxFont *theFont ) const +void wxWindowMac::DoGetTextExtent(const wxString& str, + int *x, int *y, + int *descent, + int *externalLeading, + const wxFont *theFont) const { const wxFont *fontToUse = theFont; wxFont tempFont; @@ -1104,9 +1360,9 @@ void wxWindowMac::GetTextExtent(const wxString& str, int *x, int *y, wxDouble h , d , e , w; ctx->GetTextExtent( str, &w, &h, &d, &e ); - + delete ctx; - + if ( externalLeading ) *externalLeading = (wxCoord)(e+0.5); if ( descent ) @@ -1124,32 +1380,28 @@ void wxWindowMac::GetTextExtent(const wxString& str, int *x, int *y, void wxWindowMac::Refresh(bool WXUNUSED(eraseBack), const wxRect *rect) { - if ( m_peer == NULL ) + if ( GetPeer() == NULL ) return ; if ( !IsShownOnScreen() ) return ; - - m_peer->SetNeedsDisplay( rect ) ; + + if ( IsFrozen() ) + return; + + GetPeer()->SetNeedsDisplay( rect ) ; } void wxWindowMac::DoFreeze() { -#if wxOSX_USE_CARBON - if ( m_peer && m_peer->IsOk() ) - m_peer->SetDrawingEnabled( false ) ; -#endif + if ( GetPeer() && GetPeer()->IsOk() ) + GetPeer()->SetDrawingEnabled( false ) ; } void wxWindowMac::DoThaw() { -#if wxOSX_USE_CARBON - if ( m_peer && m_peer->IsOk() ) - { - m_peer->SetDrawingEnabled( true ) ; - m_peer->InvalidateWithChildren() ; - } -#endif + if ( GetPeer() && GetPeer()->IsOk() ) + GetPeer()->SetDrawingEnabled( true ) ; } wxWindow *wxGetActiveWindow() @@ -1159,46 +1411,37 @@ wxWindow *wxGetActiveWindow() } // Coordinates relative to the window -void wxWindowMac::WarpPointer(int WXUNUSED(x_pos), int WXUNUSED(y_pos)) -{ - // We really don't move the mouse programmatically under Mac. -} - -void wxWindowMac::OnEraseBackground(wxEraseEvent& event) +void wxWindowMac::WarpPointer(int x_pos, int y_pos) { - if ( MacGetTopLevelWindow() == NULL ) - return ; -/* -#if TARGET_API_MAC_OSX - if ( !m_backgroundColour.Ok() || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT ) - { - } - else +#if wxOSX_USE_COCOA_OR_CARBON + int x = x_pos; + int y = y_pos; + DoClientToScreen(&x, &y); + CGPoint cgpoint = CGPointMake( x, y ); + CGWarpMouseCursorPosition( cgpoint ); + + // At least GTK sends a mouse moved event after WarpMouse + wxMouseEvent event(wxEVT_MOTION); + event.m_x = x_pos; + event.m_y = y_pos; + wxMouseState mState = ::wxGetMouseState(); + + event.m_altDown = mState.AltDown(); + event.m_controlDown = mState.ControlDown(); + event.m_leftDown = mState.LeftIsDown(); + event.m_middleDown = mState.MiddleIsDown(); + event.m_rightDown = mState.RightIsDown(); + event.m_metaDown = mState.MetaDown(); + event.m_shiftDown = mState.ShiftDown(); + event.SetId(GetId()); + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(event); #endif -*/ - if ( GetBackgroundStyle() == wxBG_STYLE_COLOUR ) - { - event.GetDC()->Clear() ; - } - else if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM ) - { - // don't skip the event here, custom background means that the app - // is drawing it itself in its OnPaint(), so don't draw it at all - // now to avoid flicker - } - else - { - event.Skip() ; - } -} - -void wxWindowMac::OnNcPaint( wxNcPaintEvent& event ) -{ - event.Skip() ; } int wxWindowMac::GetScrollPos(int orient) const { +#if wxUSE_SCROLLBAR if ( orient == wxHORIZONTAL ) { if ( m_hScrollBar ) @@ -1209,7 +1452,7 @@ int wxWindowMac::GetScrollPos(int orient) const if ( m_vScrollBar ) return m_vScrollBar->GetThumbPosition() ; } - +#endif return 0; } @@ -1217,6 +1460,7 @@ int wxWindowMac::GetScrollPos(int orient) const // of positions that we can scroll. int wxWindowMac::GetScrollRange(int orient) const { +#if wxUSE_SCROLLBAR if ( orient == wxHORIZONTAL ) { if ( m_hScrollBar ) @@ -1227,12 +1471,13 @@ int wxWindowMac::GetScrollRange(int orient) const if ( m_vScrollBar ) return m_vScrollBar->GetRange() ; } - +#endif return 0; } int wxWindowMac::GetScrollThumb(int orient) const { +#if wxUSE_SCROLLBAR if ( orient == wxHORIZONTAL ) { if ( m_hScrollBar ) @@ -1243,12 +1488,13 @@ int wxWindowMac::GetScrollThumb(int orient) const if ( m_vScrollBar ) return m_vScrollBar->GetThumbSize() ; } - +#endif return 0; } void wxWindowMac::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh)) { +#if wxUSE_SCROLLBAR if ( orient == wxHORIZONTAL ) { if ( m_hScrollBar ) @@ -1259,6 +1505,7 @@ void wxWindowMac::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh)) if ( m_vScrollBar ) m_vScrollBar->SetThumbPosition( pos ) ; } +#endif } void @@ -1292,15 +1539,17 @@ void wxWindowMac::MacPaintGrowBox() if ( IsTopLevel() ) return ; +#if wxUSE_SCROLLBAR if ( MacHasScrollBarCorner() ) { +#if 0 CGContextRef cgContext = (CGContextRef) MacGetCGContextRef() ; wxASSERT( cgContext ) ; int tx,ty,tw,th; - - m_peer->GetSize( tw, th ); - m_peer->GetPosition( tx, ty ); + + GetPeer()->GetSize( tw, th ); + GetPeer()->GetPosition( tx, ty ); Rect rect = { ty,tx, ty+th, tx+tw }; @@ -1309,7 +1558,7 @@ void wxWindowMac::MacPaintGrowBox() CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ; CGContextSaveGState( cgContext ); - if ( m_backgroundColour.Ok() ) + if ( m_backgroundColour.IsOk() ) { CGContextSetFillColorWithColor( cgContext, m_backgroundColour.GetCGColor() ); } @@ -1319,7 +1568,18 @@ void wxWindowMac::MacPaintGrowBox() } CGContextFillRect( cgContext, cgrect ); CGContextRestoreGState( cgContext ); +#else + if (m_growBox) + { + if ( m_backgroundColour.IsOk() ) + m_growBox->SetBackgroundColour(m_backgroundColour); + else + m_growBox->SetBackgroundColour(*wxWHITE); + } +#endif } + +#endif } void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(rightOrigin) ) @@ -1327,28 +1587,24 @@ void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(right if ( IsTopLevel() ) return ; - bool hasFocus = m_peer->NeedsFocusRect() && m_peer->HasFocus() ; + bool hasFocus = GetPeer()->NeedsFocusRect() && HasFocus(); // back to the surrounding frame rectangle int tx,ty,tw,th; - - m_peer->GetSize( tw, th ); - m_peer->GetPosition( tx, ty ); - Rect rect = { ty,tx, ty+th, tx+tw }; + GetPeer()->GetSize( tw, th ); + GetPeer()->GetPosition( tx, ty ); #if wxOSX_USE_COCOA_OR_CARBON - InsetRect( &rect, -1 , -1 ) ; - { - CGRect cgrect = CGRectMake( rect.left , rect.top , rect.right - rect.left , - rect.bottom - rect.top ) ; + CGRect cgrect = CGRectMake( tx-1 , ty-1 , tw+2 , + th+2 ) ; CGContextRef cgContext = (CGContextRef) GetParent()->MacGetCGContextRef() ; wxASSERT( cgContext ) ; - if ( m_peer->NeedsFrame() ) + if ( GetPeer()->NeedsFrame() ) { HIThemeFrameDrawInfo info ; memset( &info, 0 , sizeof(info) ) ; @@ -1369,7 +1625,7 @@ void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(right HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ; } } - + if ( hasFocus ) { HIThemeDrawFocusRect( &cgrect , true , cgContext , kHIThemeOrientationNormal ) ; @@ -1380,16 +1636,20 @@ void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(right void wxWindowMac::RemoveChild( wxWindowBase *child ) { +#if wxUSE_SCROLLBAR if ( child == m_hScrollBar ) m_hScrollBar = NULL ; if ( child == m_vScrollBar ) m_vScrollBar = NULL ; - + if ( child == m_growBox ) + m_growBox = NULL ; +#endif wxWindowBase::RemoveChild( child ) ; } void wxWindowMac::DoUpdateScrollbarVisibility() { +#if wxUSE_SCROLLBAR bool triggerSizeEvent = false; if ( m_hScrollBar ) @@ -1417,22 +1677,29 @@ void wxWindowMac::DoUpdateScrollbarVisibility() MacRepositionScrollBars() ; if ( triggerSizeEvent ) { - wxSizeEvent event(GetSize(), m_windowId); - event.SetEventObject(this); - HandleWindowEvent(event); + SendSizeEvent(); } +#endif } // New function that will replace some of the above. void wxWindowMac::SetScrollbar(int orient, int pos, int thumb, int range, bool refresh) { +#if wxUSE_SCROLLBAR + // Updating scrollbars when window is being deleted is useless and + // currently results in asserts in client-to-screen coordinates conversion + // code which is used by DoUpdateScrollbarVisibility() so just skip it. + if ( m_isBeingDeleted ) + return; + if ( orient == wxHORIZONTAL && m_hScrollBar ) m_hScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh); else if ( orient == wxVERTICAL && m_vScrollBar ) m_vScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh); DoUpdateScrollbarVisibility(); +#endif } // Does a physical scroll @@ -1451,7 +1718,7 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) // as the native control might be not a 0/0 wx window coordinates, we have to offset scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ; - m_peer->ScrollRect( &scrollrect, dx, dy ); + GetPeer()->ScrollRect( &scrollrect, dx, dy ); } wxWindowMac *child; @@ -1461,13 +1728,13 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) child = node->GetData(); if (child == NULL) continue; - if (child == m_vScrollBar) - continue; - if (child == m_hScrollBar) - continue; + if (child->IsTopLevel()) continue; + if ( !IsClientAreaChild(child) ) + continue; + child->GetPosition( &x, &y ); child->GetSize( &w, &h ); if (rect) @@ -1485,6 +1752,7 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) void wxWindowMac::MacOnScroll( wxScrollEvent &event ) { +#if wxUSE_SCROLLBAR if ( event.GetEventObject() == m_vScrollBar || event.GetEventObject() == m_hScrollBar ) { wxScrollWinEvent wevent; @@ -1511,38 +1779,24 @@ void wxWindowMac::MacOnScroll( wxScrollEvent &event ) HandleWindowEvent(wevent); } -} - -// Get the window with the focus -wxWindow *wxWindowBase::DoFindFocus() -{ -#if wxOSX_USE_CARBON - ControlRef control ; - GetKeyboardFocus( GetUserFocusWindow() , &control ) ; - return wxFindWindowFromWXWidget( (WXWidget) control ) ; -#else - return NULL; #endif } -void wxWindowMac::OnInternalIdle() +wxWindow *wxWindowBase::DoFindFocus() { - // This calls the UI-update mechanism (querying windows for - // menu/toolbar/control state information) - if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen()) - UpdateWindowUI(wxUPDATE_UI_FROMIDLE); + return wxFindWindowFromWXWidget(wxWidgetImpl::FindFocus()); } // Raise the window to the top of the Z order void wxWindowMac::Raise() { - m_peer->Raise(); + GetPeer()->Raise(); } // Lower the window to the bottom of the Z order void wxWindowMac::Lower() { - m_peer->Lower(); + GetPeer()->Lower(); } // static wxWindow *gs_lastWhich = NULL; @@ -1557,6 +1811,8 @@ bool wxWindowMac::MacSetupCursor( const wxPoint& pt ) if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) ) { wxSetCursorEvent event( pt.x , pt.y ); + event.SetId(GetId()); + event.SetEventObject(this); bool processedEvtSetCursor = HandleWindowEvent(event); if ( processedEvtSetCursor && event.HasCursor() ) @@ -1569,18 +1825,18 @@ bool wxWindowMac::MacSetupCursor( const wxPoint& pt ) // if the user code caught EVT_SET_CURSOR() and returned nothing from // it - this is a way to say that our cursor shouldn't be used for this // point - if ( !processedEvtSetCursor && m_cursor.Ok() ) + if ( !processedEvtSetCursor && m_cursor.IsOk() ) cursor = m_cursor ; if ( !wxIsBusy() && !GetParent() ) cursor = *wxSTANDARD_CURSOR ; } - if ( cursor.Ok() ) + if ( cursor.IsOk() ) cursor.MacInstall() ; } - return cursor.Ok() ; + return cursor.IsOk() ; } wxString wxWindowMac::MacGetToolTipString( wxPoint &WXUNUSED(pt) ) @@ -1682,9 +1938,9 @@ void wxWindowMac::MacUpdateClippedRects() const Rect rIncludingOuterStructures ; int tx,ty,tw,th; - - m_peer->GetSize( tw, th ); - m_peer->GetPosition( tx, ty ); + + GetPeer()->GetSize( tw, th ); + GetPeer()->GetPosition( tx, ty ); Rect r = { ty,tx, ty+th, tx+tw }; @@ -1769,37 +2025,64 @@ void wxWindowMac::MacUpdateClippedRects() const bool wxWindowMac::MacDoRedraw( long time ) { bool handled = false ; - + wxRegion formerUpdateRgn = m_updateRegion; wxRegion clientUpdateRgn = formerUpdateRgn; - wxSize sz = GetClientSize() ; - wxPoint origin = GetClientAreaOrigin() ; - - clientUpdateRgn.Intersect(origin.x , origin.y , origin.x + sz.x , origin.y + sz.y); - + const wxRect clientRect = GetClientRect(); + + clientUpdateRgn.Intersect(clientRect); + // first send an erase event to the entire update area + const wxBackgroundStyle bgStyle = GetBackgroundStyle(); + switch ( bgStyle ) { - // for the toplevel window this really is the entire area - // for all the others only their client area, otherwise they - // might be drawing with full alpha and eg put blue into - // the grow-box area of a scrolled window (scroll sample) - wxDC* dc = new wxWindowDC(this); - if ( IsTopLevel() ) - dc->SetDeviceClippingRegion(formerUpdateRgn); - else - dc->SetDeviceClippingRegion(clientUpdateRgn); + case wxBG_STYLE_ERASE: + case wxBG_STYLE_SYSTEM: + case wxBG_STYLE_COLOUR: + { + // for the toplevel window this really is the entire area for + // all the others only their client area, otherwise they might + // be drawing with full alpha and eg put blue into the grow-box + // area of a scrolled window (scroll sample) + wxWindowDC dc(this); + if ( IsTopLevel() ) + dc.SetDeviceClippingRegion(formerUpdateRgn); + else + dc.SetDeviceClippingRegion(clientUpdateRgn); + + if ( bgStyle == wxBG_STYLE_ERASE ) + { + wxEraseEvent eevent( GetId(), &dc ); + eevent.SetEventObject( this ); + if ( ProcessWindowEvent( eevent ) ) + break; + } + + if ( UseBgCol() ) + { + dc.SetBackground(GetBackgroundColour()); + dc.Clear(); + } + } + break; - wxEraseEvent eevent( GetId(), dc ); - eevent.SetEventObject( this ); - HandleWindowEvent( eevent ); - delete dc ; + case wxBG_STYLE_PAINT: + case wxBG_STYLE_TRANSPARENT: + // nothing to do, user-defined EVT_PAINT handler will overwrite the + // entire window client area + break; + + default: + wxFAIL_MSG( "unsupported background style" ); } - MacPaintGrowBox(); + // as this is a full window, shouldn't be necessary anymore + // MacPaintGrowBox(); - // calculate a client-origin version of the update rgn and set m_updateRegion to that - clientUpdateRgn.Offset( -origin.x , -origin.y ); + // calculate a client-origin version of the update rgn and set + // m_updateRegion to that + clientUpdateRgn.Offset(-clientRect.GetPosition()); m_updateRegion = clientUpdateRgn ; if ( !m_updateRegion.Empty() ) @@ -1813,6 +2096,11 @@ bool wxWindowMac::MacDoRedraw( long time ) } m_updateRegion = formerUpdateRgn; + + wxNonOwnedWindow* top = MacGetTopLevelWindow(); + if (top) + top->WindowWasPainted() ; + return handled; } @@ -1831,10 +2119,14 @@ void wxWindowMac::MacPaintChildrenBorders() child = node->GetData(); if (child == NULL) continue; +#if wxUSE_SCROLLBAR if (child == m_vScrollBar) continue; if (child == m_hScrollBar) continue; + if (child == m_growBox) + continue; +#endif if (child->IsTopLevel()) continue; if (!child->IsShown()) @@ -1844,7 +2136,7 @@ void wxWindowMac::MacPaintChildrenBorders() child->GetPosition( &x, &y ); child->GetSize( &w, &h ); - + if ( m_updateRegion.Contains(clientOrigin.x+x-10, clientOrigin.y+y-10, w+20, h+20) ) { // paint custom borders @@ -1861,12 +2153,13 @@ void wxWindowMac::MacPaintChildrenBorders() WXWindow wxWindowMac::MacGetTopLevelWindowRef() const { - wxNonOwnedWindow* tlw = MacGetTopLevelWindow(); + wxNonOwnedWindow* tlw = MacGetTopLevelWindow(); return tlw ? tlw->GetWXWindow() : NULL ; } bool wxWindowMac::MacHasScrollBarCorner() const { +#if wxUSE_SCROLLBAR /* Returns whether the scroll bars in a wxScrolledWindow should be * shortened. Scroll bars should be shortened if either: * @@ -1895,7 +2188,8 @@ bool wxWindowMac::MacHasScrollBarCorner() const const wxFrame *frame = wxDynamicCast( win, wxFrame ) ; if ( frame ) { - if ( frame->GetWindowStyleFlag() & wxRESIZE_BORDER ) + // starting from 10.7 there are no resize indicators anymore + if ( (frame->GetWindowStyleFlag() & wxRESIZE_BORDER) && UMAGetSystemVersion() < 0x1070) { // Parent frame has resize handle wxPoint frameBottomRight = frame->GetScreenRect().GetBottomRight(); @@ -1927,10 +2221,14 @@ bool wxWindowMac::MacHasScrollBarCorner() const // No parent frame found return false ; } +#else + return false; +#endif } void wxWindowMac::MacCreateScrollBars( long style ) { +#if wxUSE_SCROLLBAR wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ; if ( style & ( wxVSCROLL | wxHSCROLL ) ) @@ -1962,22 +2260,32 @@ void wxWindowMac::MacCreateScrollBars( long style ) m_hScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, hPoint, hSize , wxHORIZONTAL); m_hScrollBar->SetMinSize( wxDefaultSize ); } + + wxPoint gPoint(width - scrlsize, height - scrlsize); + wxSize gSize(scrlsize, scrlsize); + m_growBox = new wxBlindPlateWindow((wxWindow *)this, wxID_ANY, gPoint, gSize, 0); } // because the create does not take into account the client area origin // we might have a real position shift MacRepositionScrollBars() ; +#endif } bool wxWindowMac::MacIsChildOfClientArea( const wxWindow* child ) const { - bool result = ((child == NULL) || ((child != m_hScrollBar) && (child != m_vScrollBar))); + bool result = ((child == NULL) +#if wxUSE_SCROLLBAR + || ((child != m_hScrollBar) && (child != m_vScrollBar) && (child != m_growBox)) +#endif + ); return result ; } void wxWindowMac::MacRepositionScrollBars() { +#if wxUSE_SCROLLBAR if ( !m_hScrollBar && !m_vScrollBar ) return ; @@ -2000,11 +2308,29 @@ void wxWindowMac::MacRepositionScrollBars() m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE ); if ( m_hScrollBar ) m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE ); + if ( m_growBox ) + { + if ( MacHasScrollBarCorner() ) + { + m_growBox->SetSize( width - scrlsize, height - scrlsize, wxDefaultCoord, wxDefaultCoord, wxSIZE_USE_EXISTING ); + if ( !m_growBox->IsShown() ) + m_growBox->Show(); + } + else + { + if ( m_growBox->IsShown() ) + m_growBox->Hide(); + } + } +#endif } bool wxWindowMac::AcceptsFocus() const { - return m_peer->CanFocus() && wxWindowBase::AcceptsFocus(); + if ( GetPeer() == NULL || GetPeer()->IsUserPane() ) + return wxWindowBase::AcceptsFocus(); + else + return GetPeer()->CanFocus(); } void wxWindowMac::MacSuperChangedPosition() @@ -2039,14 +2365,14 @@ void wxWindowMac::MacTopLevelWindowChangedPosition() } } -long wxWindowMac::MacGetLeftBorderSize() const +long wxWindowMac::MacGetWXBorderSize() const { if ( IsTopLevel() ) return 0 ; SInt32 border = 0 ; - if ( m_peer && m_peer->NeedsFrame() ) + if ( GetPeer() && GetPeer()->NeedsFrame() ) { if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER)) { @@ -2073,22 +2399,65 @@ long wxWindowMac::MacGetLeftBorderSize() const return border ; } +long wxWindowMac::MacGetLeftBorderSize() const +{ + // the wx borders are all symmetric in mac themes + long border = MacGetWXBorderSize() ; + + if ( GetPeer() ) + { + int left, top, right, bottom; + GetPeer()->GetLayoutInset( left, top, right, bottom ); + border -= left; + } + + return border; +} + + long wxWindowMac::MacGetRightBorderSize() const { - // they are all symmetric in mac themes - return MacGetLeftBorderSize() ; + // the wx borders are all symmetric in mac themes + long border = MacGetWXBorderSize() ; + + if ( GetPeer() ) + { + int left, top, right, bottom; + GetPeer()->GetLayoutInset( left, top, right, bottom ); + border -= right; + } + + return border; } long wxWindowMac::MacGetTopBorderSize() const { - // they are all symmetric in mac themes - return MacGetLeftBorderSize() ; + // the wx borders are all symmetric in mac themes + long border = MacGetWXBorderSize() ; + + if ( GetPeer() ) + { + int left, top, right, bottom; + GetPeer()->GetLayoutInset( left, top, right, bottom ); + border -= top; + } + + return border; } long wxWindowMac::MacGetBottomBorderSize() const { - // they are all symmetric in mac themes - return MacGetLeftBorderSize() ; + // the wx borders are all symmetric in mac themes + long border = MacGetWXBorderSize() ; + + if ( GetPeer() ) + { + int left, top, right, bottom; + GetPeer()->GetLayoutInset( left, top, right, bottom ); + border -= bottom; + } + + return border; } long wxWindowMac::MacRemoveBordersFromStyle( long style ) @@ -2151,12 +2520,12 @@ Rect wxMacGetBoundsForControl( wxWindowMac* window , const wxPoint& pos , const int x, y, w, h ; window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin ) ; - Rect bounds = { y, x, y + h, x + w }; + Rect bounds = { static_cast(y), static_cast(x), static_cast(y + h), static_cast(x + w) }; return bounds ; } -bool wxWindowMac::OSXHandleClicked( double timestampsec ) +bool wxWindowMac::OSXHandleClicked( double WXUNUSED(timestampsec) ) { return false; } @@ -2166,7 +2535,7 @@ wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENT #if wxOSX_USE_COCOA_OR_CARBON if ( OSXHandleClicked( GetEventTime((EventRef)event) ) ) return noErr; - + return eventNotHandledErr ; #else return 0; @@ -2179,8 +2548,10 @@ bool wxWindowMac::Reparent(wxWindowBase *newParentBase) if ( !wxWindowBase::Reparent(newParent) ) return false; - m_peer->RemoveFromParent(); - m_peer->Embed( GetParent()->GetPeer() ); + GetPeer()->RemoveFromParent(); + GetPeer()->Embed( GetParent()->GetPeer() ); + + MacChildAdded(); return true; } @@ -2209,9 +2580,9 @@ wxByte wxWindowMac::GetTransparent() const bool wxWindowMac::IsShownOnScreen() const { - if ( m_peer && m_peer->IsOk() ) + if ( GetPeer() && GetPeer()->IsOk() ) { - bool peerVis = m_peer->IsVisible(); + bool peerVis = GetPeer()->IsVisible(); bool wxVis = wxWindowBase::IsShownOnScreen(); if( peerVis != wxVis ) { @@ -2225,16 +2596,137 @@ bool wxWindowMac::IsShownOnScreen() const return wxVis; } - return m_peer->IsVisible(); + return GetPeer()->IsVisible(); } return wxWindowBase::IsShownOnScreen(); } +#if wxUSE_HOTKEY && wxOSX_USE_COCOA_OR_CARBON + +OSStatus +wxHotKeyHandler(EventHandlerCallRef WXUNUSED(nextHandler), + EventRef event, + void* WXUNUSED(userData)) +{ + EventHotKeyID hotKeyId; + + GetEventParameter( event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(hotKeyId), NULL, &hotKeyId); + + for ( unsigned i = 0; i < s_hotkeys.size(); ++i ) + { + if ( s_hotkeys[i].keyId == static_cast(hotKeyId.id) ) + { + unsigned char charCode ; + UInt32 keyCode ; + UInt32 modifiers ; + UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ; + + GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode ); + GetEventParameter( event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode ); + GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers ); + + UInt32 keymessage = (keyCode << 8) + charCode; + + wxKeyEvent wxevent(wxEVT_HOTKEY); + wxevent.SetId(hotKeyId.id); + wxTheApp->MacCreateKeyEvent( wxevent, s_hotkeys[i].window , keymessage , + modifiers , when , 0 ) ; + + s_hotkeys[i].window->HandleWindowEvent(wxevent); + } + } + + return noErr; +} + +bool wxWindowMac::RegisterHotKey(int hotkeyId, int modifiers, int keycode) +{ + for ( unsigned i = 0; i < s_hotkeys.size(); ++i ) + { + if ( s_hotkeys[i].keyId == hotkeyId ) + { + wxLogLastError(wxT("hotkeyId already registered")); + + return false; + } + } + + static bool installed = false; + if ( !installed ) + { + EventTypeSpec eventType; + eventType.eventClass=kEventClassKeyboard; + eventType.eventKind=kEventHotKeyPressed; + + InstallApplicationEventHandler(&wxHotKeyHandler, 1, &eventType, NULL, NULL); + installed = true; + } + + UInt32 mac_modifiers=0; + if ( modifiers & wxMOD_ALT ) + mac_modifiers |= optionKey; + if ( modifiers & wxMOD_SHIFT ) + mac_modifiers |= shiftKey; + if ( modifiers & wxMOD_RAW_CONTROL ) + mac_modifiers |= controlKey; + if ( modifiers & wxMOD_CONTROL ) + mac_modifiers |= cmdKey; + + EventHotKeyRef hotKeyRef; + EventHotKeyID hotKeyIDmac; + + hotKeyIDmac.signature = 'WXMC'; + hotKeyIDmac.id = hotkeyId; + + if ( RegisterEventHotKey(wxCharCodeWXToOSX((wxKeyCode)keycode), mac_modifiers, hotKeyIDmac, + GetApplicationEventTarget(), 0, &hotKeyRef) != noErr ) + { + wxLogLastError(wxT("RegisterHotKey")); + + return false; + } + else + { + wxHotKeyRec v; + v.ref = hotKeyRef; + v.keyId = hotkeyId; + v.window = this; + + s_hotkeys.push_back(v); + } + + return true; +} + +bool wxWindowMac::UnregisterHotKey(int hotkeyId) +{ + for ( int i = ((int)s_hotkeys.size())-1; i>=0; -- i ) + { + if ( s_hotkeys[i].keyId == hotkeyId ) + { + EventHotKeyRef ref = s_hotkeys[i].ref; + s_hotkeys.erase(s_hotkeys.begin() + i); + if ( UnregisterEventHotKey(ref) != noErr ) + { + wxLogLastError(wxT("UnregisterHotKey")); + + return false; + } + else + return true; + } + } + + return false; +} + +#endif // wxUSE_HOTKEY + bool wxWindowMac::OSXHandleKeyEvent( wxKeyEvent& event ) { - bool handled = HandleWindowEvent( event ) ; - if ( handled && event.GetSkipped() ) - handled = false ; + bool handled = false; + + // moved the ordinary key event sending AFTER the accel evaluation #if wxUSE_ACCEL if ( !handled && event.GetEventType() == wxEVT_KEY_DOWN) @@ -2247,13 +2739,13 @@ bool wxWindowMac::OSXHandleKeyEvent( wxKeyEvent& event ) { wxEvtHandler * const handler = ancestor->GetEventHandler(); - wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command ); + wxCommandEvent command_event( wxEVT_MENU, command ); handled = handler->ProcessEvent( command_event ); if ( !handled ) { // accelerators can also be used with buttons, try them too - command_event.SetEventType(wxEVT_COMMAND_BUTTON_CLICKED); + command_event.SetEventType(wxEVT_BUTTON); handled = handler->ProcessEvent( command_event ); } @@ -2267,14 +2759,25 @@ bool wxWindowMac::OSXHandleKeyEvent( wxKeyEvent& event ) } } #endif // wxUSE_ACCEL + + if ( !handled ) + { + handled = HandleWindowEvent( event ) ; + if ( handled && event.GetSkipped() ) + handled = false ; + } return handled ; } // -// wxWidgetImpl +// wxWidgetImpl // +// we are maintaining a n:1 map from native controls (ControlRef / NSView*) to their wxWidgetImpl +// n:1 because we might have an embedded view eg within a scrollview, both being part of the same impl +// the impl is calling Associate with its newly created native control(s), e.g. in InstallHandler + WX_DECLARE_HASH_MAP(WXWidget, wxWidgetImpl*, wxPointerHash, wxPointerEqual, MacControlMap); static MacControlMap wxWinMacControlList; @@ -2284,7 +2787,7 @@ wxWindowMac *wxFindWindowFromWXWidget(WXWidget inControl ) wxWidgetImpl* impl = wxWidgetImpl::FindFromWXWidget( inControl ); if ( impl ) return impl->GetWXPeer(); - + return NULL; } @@ -2329,11 +2832,13 @@ void wxWidgetImpl::RemoveAssociations(wxWidgetImpl* impl) IMPLEMENT_ABSTRACT_CLASS( wxWidgetImpl , wxObject ) -wxWidgetImpl::wxWidgetImpl( wxWindowMac* peer , bool isRootControl ) +wxWidgetImpl::wxWidgetImpl( wxWindowMac* peer , bool isRootControl, bool isUserPane ) { Init(); m_isRootControl = isRootControl; + m_isUserPane = isUserPane; m_wxPeer = peer; + m_shouldSendEvents = true; } wxWidgetImpl::wxWidgetImpl() @@ -2372,3 +2877,7 @@ bool wxWidgetImpl::NeedsFrame() const { return m_needsFrame; } + +void wxWidgetImpl::SetDrawingEnabled(bool WXUNUSED(enabled)) +{ +}