X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/19253261f5c6127f5448078295d4cbe1521d469f..74a8f67d96591cec101def2a7d47c64072aff7fd:/src/cocoa/window.mm diff --git a/src/cocoa/window.mm b/src/cocoa/window.mm index bb25bcc333..8fb822a76f 100644 --- a/src/cocoa/window.mm +++ b/src/cocoa/window.mm @@ -6,7 +6,7 @@ // Created: 2002/12/26 // RCS-ID: $Id$ // Copyright: (c) 2002 David Elliott -// Licence: wxWidgets licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #include "wx/wxprec.h" @@ -26,7 +26,7 @@ #include "wx/cocoa/string.h" #include "wx/cocoa/trackingrectmanager.h" #include "wx/cocoa/private/scrollview.h" -#include "wx/mac/corefoundation/cfref.h" +#include "wx/osx/core/cfref.h" #include "wx/cocoa/ObjcRef.h" #import @@ -152,7 +152,7 @@ namespace { // file namespace class wxCocoaPrivateScreenCoordinateTransformer { - DECLARE_NO_COPY_CLASS(wxCocoaPrivateScreenCoordinateTransformer) + wxDECLARE_NO_COPY_CLASS(wxCocoaPrivateScreenCoordinateTransformer); public: wxCocoaPrivateScreenCoordinateTransformer(); ~wxCocoaPrivateScreenCoordinateTransformer(); @@ -273,7 +273,7 @@ NSPoint wxWindowCocoa::OriginInCocoaScreenCoordinatesForRectInWxDisplayCoordinat // ======================================================================== class wxWindowCocoaHider: protected wxCocoaNSView { - DECLARE_NO_COPY_CLASS(wxWindowCocoaHider) + wxDECLARE_NO_COPY_CLASS(wxWindowCocoaHider); public: wxWindowCocoaHider(wxWindow *owner); virtual ~wxWindowCocoaHider(); @@ -309,6 +309,12 @@ WX_IMPLEMENT_GET_OBJC_CLASS(wxDummyNSView,NSView) // ======================================================================== // wxWindowCocoaHider +// NOTE: This class and method of hiding predates setHidden: support in +// the toolkit. The hack used here is to replace the view with a stand-in +// that will be subject to the usual Cocoa resizing rules. +// When possible (i.e. when running on 10.3 or higher) we make it hidden +// mostly as an optimization so Cocoa doesn't have to consider it when +// drawing or finding key views. // ======================================================================== wxWindowCocoaHider::wxWindowCocoaHider(wxWindow *owner) : m_owner(owner) @@ -319,6 +325,9 @@ wxWindowCocoaHider::wxWindowCocoaHider(wxWindow *owner) initWithFrame:[owner->GetNSViewForHiding() frame]]; [m_dummyNSView setAutoresizingMask: [owner->GetNSViewForHiding() autoresizingMask]]; AssociateNSView(m_dummyNSView); + + if([m_dummyNSView respondsToSelector:@selector(setHidden:)]) + [m_dummyNSView setHidden:YES]; } wxWindowCocoaHider::~wxWindowCocoaHider() @@ -348,9 +357,9 @@ bool wxWindowCocoaHider::Cocoa_drawRect(const NSRect& rect) /*! @class WXManualScrollView - @abstract An NSScrollView subclass which implements wx scroll behavior + @abstract An NSScrollView subclass which implements wx scroll behaviour @discussion - Overrides default behavior of NSScrollView such that this class receives + Overrides default behaviour of NSScrollView such that this class receives the scroller action messages and allows the wxCocoaScrollView to act on them accordingly. In particular, because the NSScrollView will not receive action messages from the scroller, it will not adjust the @@ -726,7 +735,7 @@ int wxWindowCocoaScrollView::GetScrollPos(wxOrientation orient) position is at range-thumbsize. The range of an NSScroller is 0.0 to 1.0. Much easier! NOTE: Apple doesn't really specify - but GNUStep docs do say that 0.0 is top/left and 1.0 is bottom/right. This is actualy + but GNUStep docs do say that 0.0 is top/left and 1.0 is bottom/right. This is actually in contrast to NSSlider which generally has 1.0 at the TOP when it's done vertically. */ CGFloat cocoaScrollPos = [cocoaScroller floatValue]; @@ -903,7 +912,14 @@ void wxWindowCocoaScrollView::Cocoa_FrameChanged(void) wxSizeEvent event(m_owner->GetSize(), m_owner->GetId()); event.SetEventObject(m_owner); m_owner->HandleWindowEvent(event); - UpdateSizes(); + + /* If the view is not a native one then it's being managed by wx. In this case the control + may decide to change its virtual size and we must update the document view's size to + match. For native views the virtual size will never have been set so we do not want + to use it at all. + */ + if(!m_isNativeView) + UpdateSizes(); } // ======================================================================== @@ -912,8 +928,6 @@ void wxWindowCocoaScrollView::Cocoa_FrameChanged(void) // normally the base classes aren't included, but wxWindow is special #ifdef __WXUNIVERSAL__ IMPLEMENT_ABSTRACT_CLASS(wxWindowCocoa, wxWindowBase) -#else -IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) #endif BEGIN_EVENT_TABLE(wxWindowCocoa, wxWindowBase) @@ -927,7 +941,6 @@ void wxWindowCocoa::Init() m_cocoaNSView = NULL; m_cocoaHider = NULL; m_wxCocoaScrollView = NULL; - m_isBeingDeleted = false; m_isInPaint = false; m_visibleTrackingRectManager = NULL; } @@ -1396,17 +1409,48 @@ bool wxWindow::Show(bool show) // If state isn't changing, return false if(!m_cocoaHider) return false; + + // Replace the stand-in view with the real one and destroy the dummy view CocoaReplaceView(m_cocoaHider->GetNSView(), cocoaView); wxASSERT(![m_cocoaHider->GetNSView() superview]); delete m_cocoaHider; m_cocoaHider = NULL; wxASSERT([cocoaView superview]); + + // Schedule an update of the key view loop (NOTE: 10.4+ only.. argh) + NSWindow *window = [cocoaView window]; + if(window != nil) + { + // Delay this until returning to the event loop for a couple of reasons: + // 1. If a lot of stuff is shown/hidden we avoid recalculating needlessly + // 2. NSWindow does not seem to see the newly shown views if we do it right now. + if([window respondsToSelector:@selector(recalculateKeyViewLoop)]) + [window performSelector:@selector(recalculateKeyViewLoop) withObject:nil afterDelay:0.0]; + } } else { // If state isn't changing, return false if(m_cocoaHider) return false; + + // Handle the first responder + NSWindow *window = [cocoaView window]; + if(window != nil) + { + NSResponder *firstResponder = [window firstResponder]; + if([firstResponder isKindOfClass:[NSView class]] && [(NSView*)firstResponder isDescendantOf:cocoaView]) + { + BOOL didResign = [window makeFirstResponder:nil]; + // If the current first responder (one of our subviews) refuses to give + // up its status, then fail now and don't hide this view + if(didResign == NO) + return false; + } + } + + // Create a new view to stand in for the real one (via wxWindowCocoaHider) and replace + // the real one with the stand in. m_cocoaHider = new wxWindowCocoaHider(this); // NOTE: replaceSubview:with will cause m_cocaNSView to be // (auto)released which balances out addSubview @@ -1667,7 +1711,7 @@ int wxWindow::GetCharWidth() const return 5; } -void wxWindow::GetTextExtent(const wxString& string, int *outX, int *outY, +void wxWindow::DoGetTextExtent(const wxString& string, int *outX, int *outY, int *outDescent, int *outExternalLeading, const wxFont *inFont) const { // FIXME: This obviously ignores the window's font (if any) along with any size @@ -1771,7 +1815,7 @@ static char const * const comparisonresultStrings[] = class CocoaWindowCompareContext { - DECLARE_NO_COPY_CLASS(CocoaWindowCompareContext) + wxDECLARE_NO_COPY_CLASS(CocoaWindowCompareContext); public: CocoaWindowCompareContext(); // Not implemented CocoaWindowCompareContext(NSView *target, NSArray *subviews) @@ -1962,7 +2006,7 @@ wxWindow* wxFindWindowAtPointer(wxPoint& pt) */ class wxCocoaMouseMovedEventSynthesizer { - DECLARE_NO_COPY_CLASS(wxCocoaMouseMovedEventSynthesizer) + wxDECLARE_NO_COPY_CLASS(wxCocoaMouseMovedEventSynthesizer); public: wxCocoaMouseMovedEventSynthesizer() { m_lastScreenMouseLocation = NSZeroPoint;