X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/17e2694c5957fa82f3da9b338cd0937a98106005..08670ea85abf4b4946a9ce64971b591d7b1ee30b:/src/osx/window_osx.cpp diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index 04e3a9e127..012deb900d 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,15 +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" + #include "wx/osx/private.h" #endif #define MAC_SCROLLBAR_SIZE 15 @@ -76,8 +76,6 @@ #ifdef __WXUNIVERSAL__ IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase) -#else - IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) #endif BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase) @@ -89,6 +87,20 @@ 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 // =========================================================================== @@ -100,7 +112,7 @@ 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, @@ -109,10 +121,10 @@ public: 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, @@ -122,10 +134,10 @@ public: const wxString& name = wxPanelNameStr) { Init(); - + Create(parent, winid, pos, size, style, name); } - + // Pseudo ctor bool Create(wxWindow *parent, wxWindowID winid = wxID_ANY, @@ -136,24 +148,25 @@ public: { 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() }; @@ -203,7 +216,6 @@ void wxWindowMac::Init() m_vScrollBarAlwaysShown = false; m_growBox = NULL ; - m_macIsUserPane = true; m_clipChildren = false ; m_cachedClippedRectValid = false ; m_isNativeWindowWrapper = false; @@ -212,6 +224,21 @@ void wxWindowMac::Init() 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() ; @@ -256,23 +283,94 @@ 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 { - if ( m_peer ) - return (WXWidget) m_peer->GetWXWidget() ; + if ( GetPeer() ) + return (WXWidget) GetPeer()->GetWXWidget() ; return NULL; } +wxOSXWidgetImpl* wxWindowMac::GetPeer() const +{ + return m_peer == kOSXNoWidgetImpl ? NULL : m_peer ; +} + +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 + 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 // --------------------------------------------------------------------------- @@ -309,9 +407,9 @@ 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) ; } @@ -346,41 +444,46 @@ void wxWindowMac::MacChildAdded() #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 ); + GetPeer()->SetControlSize( variant ); #if wxOSX_USE_CARBON ControlSize size ; @@ -411,10 +514,10 @@ void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant ) wxFAIL_MSG(wxT("unexpected window variant")); break ; } - m_peer->SetData(kControlEntireControl, kControlSizeTag, &size ) ; + GetPeer()->SetData(kControlEntireControl, kControlSizeTag, &size ) ; #endif - + switch ( variant ) { case wxWINDOW_VARIANT_NORMAL : @@ -445,8 +548,8 @@ void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant ) 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() ) @@ -472,11 +575,21 @@ 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.Ok() ) + if ( m_backgroundColour.IsOk() ) m_growBox->SetBackgroundColour(m_backgroundColour); else m_growBox->SetBackgroundColour(*wxWHITE); @@ -485,8 +598,8 @@ bool wxWindowMac::SetBackgroundColour(const wxColour& col ) if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol ) return false ; - if ( m_peer ) - m_peer->SetBackgroundColour( col ) ; + if ( GetPeer() ) + GetPeer()->SetBackgroundColour( col ) ; return true ; } @@ -514,13 +627,13 @@ void wxWindowMac::SetFocus() if ( former == this ) return ; - m_peer->SetFocus() ; + GetPeer()->SetFocus() ; } void wxWindowMac::DoCaptureMouse() { wxApp::s_captureWindow = (wxWindow*) this ; - m_peer->CaptureMouse() ; + GetPeer()->CaptureMouse() ; } wxWindow * wxWindowBase::GetCapture() @@ -532,7 +645,7 @@ void wxWindowMac::DoReleaseMouse() { wxApp::s_captureWindow = NULL ; - m_peer->ReleaseMouse() ; + GetPeer()->ReleaseMouse() ; } #if wxUSE_DRAG_AND_DROP @@ -593,7 +706,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() ; @@ -606,7 +719,7 @@ 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() ; @@ -691,7 +804,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() ) ; } } @@ -715,7 +828,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() ; } @@ -735,8 +848,8 @@ wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const 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; @@ -754,7 +867,7 @@ void wxWindowMac::DoGetClientSize( int *x, int *y ) const 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 ; @@ -785,7 +898,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 ) @@ -798,7 +911,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 ) @@ -812,7 +924,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 @@ -833,16 +944,16 @@ void wxWindowMac::DoSetToolTip(wxToolTip *tooltip) if ( m_tooltip ) m_tooltip->SetWindow(this); - - if (m_peer) - m_peer->SetToolTip(tooltip); + + if (GetPeer()) + GetPeer()->SetToolTip(tooltip); } #endif void wxWindowMac::MacInvalidateBorders() { - if ( m_peer == NULL ) + if ( GetPeer() == NULL ) return ; bool vis = IsShownOnScreen() ; @@ -851,7 +962,7 @@ void wxWindowMac::MacInvalidateBorders() int outerBorder = MacGetLeftBorderSize() ; - if ( m_peer->NeedsFocusRect() ) + if ( GetPeer()->NeedsFocusRect() ) outerBorder += 4 ; if ( outerBorder == 0 ) @@ -861,8 +972,8 @@ void wxWindowMac::MacInvalidateBorders() 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 ); @@ -870,10 +981,10 @@ void wxWindowMac::MacInvalidateBorders() 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); } } @@ -936,7 +1047,7 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) 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 @@ -964,7 +1075,7 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) wxSize wxWindowMac::DoGetBestSize() const { - if ( m_macIsUserPane || IsTopLevel() ) + if ( GetPeer() == NULL || GetPeer()->IsUserPane() || IsTopLevel() ) { return wxWindowBase::DoGetBestSize() ; } @@ -972,7 +1083,7 @@ wxSize wxWindowMac::DoGetBestSize() const { wxRect r ; - m_peer->GetBestRect(&r); + GetPeer()->GetBestRect(&r); if ( r.GetWidth() == 0 && r.GetHeight() == 0 ) { @@ -1093,7 +1204,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() ); } @@ -1112,6 +1223,11 @@ void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight) } } +float wxWindowMac::GetContentScaleFactor() const +{ + return GetPeer()->GetContentScaleFactor(); +} + void wxWindowMac::SetLabel(const wxString& title) { if ( title == m_label ) @@ -1121,8 +1237,8 @@ void wxWindowMac::SetLabel(const wxString& title) InvalidateBestSize(); - if ( m_peer && m_peer->IsOk() ) - m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics), GetFont().GetEncoding() ) ; + 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() ) @@ -1139,20 +1255,20 @@ bool wxWindowMac::Show(bool show) if ( !wxWindowBase::Show(show) ) return false; - if ( m_peer ) - m_peer->SetVisibility( show ) ; + if ( GetPeer() ) + GetPeer()->SetVisibility( show ) ; #ifdef __WXOSX_IPHONE__ - // only when there's no native event support + // only when there's no native event support if ( !IsTopLevel() ) #endif { wxShowEvent eventShow(GetId(), show); eventShow.SetEventObject(this); - + HandleWindowEvent(eventShow); } - + return true; } @@ -1161,7 +1277,7 @@ bool wxWindowMac::OSXShowWithEffect(bool show, unsigned timeout) { if ( effect == wxSHOW_EFFECT_NONE || - !m_peer || !m_peer->ShowWithEffect(show, effect, timeout) ) + !GetPeer() || !GetPeer()->ShowWithEffect(show, effect, timeout) ) return Show(show); return true; @@ -1169,7 +1285,7 @@ bool wxWindowMac::OSXShowWithEffect(bool show, void wxWindowMac::DoEnable(bool enable) { - m_peer->Enable( enable ) ; + GetPeer()->Enable( enable ) ; MacInvalidateBorders(); } @@ -1187,7 +1303,7 @@ void wxWindowMac::MacHiliteChanged() void wxWindowMac::MacEnabledStateChanged() { - OnEnabled( m_peer->IsEnabled() ); + OnEnabled( GetPeer()->IsEnabled() ); } // @@ -1196,13 +1312,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 @@ -1263,30 +1379,30 @@ void wxWindowMac::DoGetTextExtent(const wxString& str, void wxWindowMac::Refresh(bool WXUNUSED(eraseBack), const wxRect *rect) { - if ( m_peer == NULL ) + if ( GetPeer() == NULL ) return ; if ( !IsShownOnScreen() ) return ; - m_peer->SetNeedsDisplay( rect ) ; + GetPeer()->SetNeedsDisplay( rect ) ; } void wxWindowMac::DoFreeze() { #if wxOSX_USE_CARBON - if ( m_peer && m_peer->IsOk() ) - m_peer->SetDrawingEnabled( false ) ; + if ( GetPeer() && GetPeer()->IsOk() ) + GetPeer()->SetDrawingEnabled( false ) ; #endif } void wxWindowMac::DoThaw() { #if wxOSX_USE_CARBON - if ( m_peer && m_peer->IsOk() ) + if ( GetPeer() && GetPeer()->IsOk() ) { - m_peer->SetDrawingEnabled( true ) ; - m_peer->InvalidateWithChildren() ; + GetPeer()->SetDrawingEnabled( true ) ; + GetPeer()->InvalidateWithChildren() ; } #endif } @@ -1435,8 +1551,8 @@ void wxWindowMac::MacPaintGrowBox() 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 }; @@ -1445,7 +1561,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() ); } @@ -1458,7 +1574,7 @@ void wxWindowMac::MacPaintGrowBox() #else if (m_growBox) { - if ( m_backgroundColour.Ok() ) + if ( m_backgroundColour.IsOk() ) m_growBox->SetBackgroundColour(m_backgroundColour); else m_growBox->SetBackgroundColour(*wxWHITE); @@ -1474,28 +1590,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) ) ; @@ -1580,6 +1692,12 @@ 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 ) @@ -1605,7 +1723,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; @@ -1618,7 +1736,7 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) if (child->IsTopLevel()) continue; - + if ( !IsClientAreaChild(child) ) continue; @@ -1674,24 +1792,16 @@ wxWindow *wxWindowBase::DoFindFocus() return wxFindWindowFromWXWidget(wxWidgetImpl::FindFocus()); } -void wxWindowMac::OnInternalIdle() -{ - // This calls the UI-update mechanism (querying windows for - // menu/toolbar/control state information) - if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen()) - UpdateWindowUI(wxUPDATE_UI_FROMIDLE); -} - // 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; @@ -1718,18 +1828,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) ) @@ -1832,8 +1942,8 @@ void wxWindowMac::MacUpdateClippedRects() const 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 }; @@ -2214,10 +2324,10 @@ void wxWindowMac::MacRepositionScrollBars() bool wxWindowMac::AcceptsFocus() const { - if ( MacIsUserPane() ) + if ( GetPeer() == NULL || GetPeer()->IsUserPane() ) return wxWindowBase::AcceptsFocus(); else - return m_peer->CanFocus(); + return GetPeer()->CanFocus(); } void wxWindowMac::MacSuperChangedPosition() @@ -2252,14 +2362,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)) { @@ -2286,22 +2396,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 ) @@ -2392,8 +2545,8 @@ 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; @@ -2424,9 +2577,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 ) { @@ -2440,16 +2593,139 @@ 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 ; + Point where ; + UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ; + + GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode ); + GetEventParameter( event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode ); + GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers ); + GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &where ); + + UInt32 keymessage = (keyCode << 8) + charCode; + + wxKeyEvent wxevent(wxEVT_HOTKEY); + wxevent.SetId(hotKeyId.id); + wxTheApp->MacCreateKeyEvent( wxevent, s_hotkeys[i].window , keymessage , + modifiers , when , where.h , where.v , 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 ( unsigned i = 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) @@ -2482,6 +2758,13 @@ bool wxWindowMac::OSXHandleKeyEvent( wxKeyEvent& event ) } } #endif // wxUSE_ACCEL + + if ( !handled ) + { + handled = HandleWindowEvent( event ) ; + if ( handled && event.GetSkipped() ) + handled = false ; + } return handled ; } @@ -2544,10 +2827,11 @@ 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; }