support wxWindowDisabler on osx_cocoa
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67129 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -15,6 +15,11 @@ class WXDLLIMPEXP_BASE wxGUIEventLoop : public wxCFEventLoop
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxGUIEventLoop();
|
wxGUIEventLoop();
|
||||||
|
~wxGUIEventLoop();
|
||||||
|
|
||||||
|
void BeginModalSession( wxWindow* modalWindow );
|
||||||
|
|
||||||
|
void EndModalSession();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int DoDispatchTimeout(unsigned long timeout);
|
virtual int DoDispatchTimeout(unsigned long timeout);
|
||||||
@@ -24,6 +29,9 @@ protected:
|
|||||||
virtual void DoStop();
|
virtual void DoStop();
|
||||||
|
|
||||||
virtual CFRunLoopRef CFGetCurrentRunLoop() const;
|
virtual CFRunLoopRef CFGetCurrentRunLoop() const;
|
||||||
|
|
||||||
|
void* m_modalSession;
|
||||||
|
WXWindow m_dummyWindow;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _WX_OSX_COCOA_EVTLOOP_H_
|
#endif // _WX_OSX_COCOA_EVTLOOP_H_
|
||||||
|
@@ -55,6 +55,7 @@ class WXDLLIMPEXP_FWD_BASE wxProcess;
|
|||||||
class WXDLLIMPEXP_FWD_CORE wxFrame;
|
class WXDLLIMPEXP_FWD_CORE wxFrame;
|
||||||
class WXDLLIMPEXP_FWD_CORE wxWindow;
|
class WXDLLIMPEXP_FWD_CORE wxWindow;
|
||||||
class WXDLLIMPEXP_FWD_CORE wxWindowList;
|
class WXDLLIMPEXP_FWD_CORE wxWindowList;
|
||||||
|
class WXDLLIMPEXP_FWD_CORE wxEventLoop;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Arithmetic functions
|
// Arithmetic functions
|
||||||
@@ -714,7 +715,9 @@ private:
|
|||||||
// disable all windows except the given one (used by both ctors)
|
// disable all windows except the given one (used by both ctors)
|
||||||
void DoDisable(wxWindow *winToSkip = NULL);
|
void DoDisable(wxWindow *winToSkip = NULL);
|
||||||
|
|
||||||
|
#if defined(__WXOSX__) && wxOSX_USE_COCOA
|
||||||
|
wxEventLoop* m_modalEventLoop;
|
||||||
|
#endif
|
||||||
wxWindowList *m_winDisabled;
|
wxWindowList *m_winDisabled;
|
||||||
bool m_disabled;
|
bool m_disabled;
|
||||||
|
|
||||||
|
@@ -1567,6 +1567,12 @@ void wxEnableTopLevelWindows(bool enable)
|
|||||||
node->GetData()->Enable(enable);
|
node->GetData()->Enable(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__WXOSX__) && wxOSX_USE_COCOA
|
||||||
|
|
||||||
|
// defined in evtloop.mm
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
wxWindowDisabler::wxWindowDisabler(bool disable)
|
wxWindowDisabler::wxWindowDisabler(bool disable)
|
||||||
{
|
{
|
||||||
m_disabled = disable;
|
m_disabled = disable;
|
||||||
@@ -1629,6 +1635,8 @@ wxWindowDisabler::~wxWindowDisabler()
|
|||||||
delete m_winDisabled;
|
delete m_winDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// Yield to other apps/messages and disable user input to all windows except
|
// Yield to other apps/messages and disable user input to all windows except
|
||||||
// the given one
|
// the given one
|
||||||
bool wxSafeYield(wxWindow *win, bool onlyIfNeeded)
|
bool wxSafeYield(wxWindow *win, bool onlyIfNeeded)
|
||||||
|
@@ -39,45 +39,76 @@
|
|||||||
// wxEventLoop implementation
|
// wxEventLoop implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
/*
|
|
||||||
static int CalculateNSEventMaskFromEventCategory(wxEventCategory cat)
|
static NSUInteger CalculateNSEventMaskFromEventCategory(wxEventCategory cat)
|
||||||
{
|
{
|
||||||
|
// the masking system doesn't really help, as only the lowlevel UI events
|
||||||
|
// are split in a useful way, all others are way to broad
|
||||||
|
|
||||||
|
if ( (cat | wxEVT_CATEGORY_USER_INPUT) && (cat | (~wxEVT_CATEGORY_USER_INPUT) ) )
|
||||||
|
return NSAnyEventMask;
|
||||||
|
|
||||||
|
NSUInteger mask = 0;
|
||||||
|
|
||||||
|
if ( cat | wxEVT_CATEGORY_USER_INPUT )
|
||||||
|
{
|
||||||
|
mask |=
|
||||||
NSLeftMouseDownMask |
|
NSLeftMouseDownMask |
|
||||||
NSLeftMouseUpMask |
|
NSLeftMouseUpMask |
|
||||||
NSRightMouseDownMask |
|
NSRightMouseDownMask |
|
||||||
NSRightMouseUpMask = 1 << NSRightMouseUp,
|
NSRightMouseUpMask |
|
||||||
NSMouseMovedMask = 1 << NSMouseMoved,
|
NSMouseMovedMask |
|
||||||
NSLeftMouseDraggedMask = 1 << NSLeftMouseDragged,
|
NSLeftMouseDraggedMask |
|
||||||
NSRightMouseDraggedMask = 1 << NSRightMouseDragged,
|
NSRightMouseDraggedMask |
|
||||||
NSMouseEnteredMask = 1 << NSMouseEntered,
|
NSMouseEnteredMask |
|
||||||
NSMouseExitedMask = 1 << NSMouseExited,
|
NSMouseExitedMask |
|
||||||
NSScrollWheelMask = 1 << NSScrollWheel,
|
NSScrollWheelMask |
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||||
NSTabletPointMask = 1 << NSTabletPoint,
|
NSTabletPointMask |
|
||||||
NSTabletProximityMask = 1 << NSTabletProximity,
|
NSTabletProximityMask |
|
||||||
#endif
|
#endif
|
||||||
NSOtherMouseDownMask = 1 << NSOtherMouseDown,
|
NSOtherMouseDownMask |
|
||||||
NSOtherMouseUpMask = 1 << NSOtherMouseUp,
|
NSOtherMouseUpMask |
|
||||||
NSOtherMouseDraggedMask = 1 << NSOtherMouseDragged,
|
NSOtherMouseDraggedMask |
|
||||||
|
|
||||||
|
NSKeyDownMask |
|
||||||
|
NSKeyUpMask |
|
||||||
NSKeyDownMask = 1 << NSKeyDown,
|
NSFlagsChangedMask |
|
||||||
NSKeyUpMask = 1 << NSKeyUp,
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||||
NSFlagsChangedMask = 1 << NSFlagsChanged,
|
NSEventMaskGesture |
|
||||||
|
NSEventMaskMagnify |
|
||||||
NSAppKitDefinedMask = 1 << NSAppKitDefined,
|
NSEventMaskSwipe |
|
||||||
NSSystemDefinedMask = 1 << NSSystemDefined,
|
NSEventMaskRotate |
|
||||||
NSApplicationDefinedMask = 1 << NSApplicationDefined,
|
NSEventMaskBeginGesture |
|
||||||
NSPeriodicMask = 1 << NSPeriodic,
|
NSEventMaskEndGesture |
|
||||||
NSCursorUpdateMask = 1 << NSCursorUpdate,
|
#endif
|
||||||
|
0;
|
||||||
NSAnyEventMask = 0xffffffffU
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
if ( cat | (~wxEVT_CATEGORY_USER_INPUT) )
|
||||||
|
{
|
||||||
|
mask |=
|
||||||
|
NSAppKitDefinedMask |
|
||||||
|
NSSystemDefinedMask |
|
||||||
|
NSApplicationDefinedMask |
|
||||||
|
NSPeriodicMask |
|
||||||
|
NSCursorUpdateMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
wxGUIEventLoop::wxGUIEventLoop()
|
wxGUIEventLoop::wxGUIEventLoop()
|
||||||
{
|
{
|
||||||
|
m_modalSession = nil;
|
||||||
|
m_dummyWindow = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxGUIEventLoop::~wxGUIEventLoop()
|
||||||
|
{
|
||||||
|
wxASSERT( m_modalSession == nil );
|
||||||
|
wxASSERT( m_dummyWindow == nil );
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -156,6 +187,35 @@ int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout)
|
|||||||
{
|
{
|
||||||
wxMacAutoreleasePool autoreleasepool;
|
wxMacAutoreleasePool autoreleasepool;
|
||||||
|
|
||||||
|
if ( m_modalSession )
|
||||||
|
{
|
||||||
|
NSInteger response = [NSApp runModalSession:(NSModalSession)m_modalSession];
|
||||||
|
|
||||||
|
switch (response)
|
||||||
|
{
|
||||||
|
case NSRunContinuesResponse:
|
||||||
|
{
|
||||||
|
if ( [[NSApplication sharedApplication]
|
||||||
|
nextEventMatchingMask: NSAnyEventMask
|
||||||
|
untilDate: nil
|
||||||
|
inMode: NSDefaultRunLoopMode
|
||||||
|
dequeue: NO] != nil )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NSRunStoppedResponse:
|
||||||
|
case NSRunAbortedResponse:
|
||||||
|
return -1;
|
||||||
|
default:
|
||||||
|
wxFAIL_MSG("unknown response code");
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
NSEvent *event = [NSApp
|
NSEvent *event = [NSApp
|
||||||
nextEventMatchingMask:NSAnyEventMask
|
nextEventMatchingMask:NSAnyEventMask
|
||||||
untilDate:[NSDate dateWithTimeIntervalSinceNow: timeout/1000]
|
untilDate:[NSDate dateWithTimeIntervalSinceNow: timeout/1000]
|
||||||
@@ -169,6 +229,7 @@ int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout)
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void wxGUIEventLoop::DoRun()
|
void wxGUIEventLoop::DoRun()
|
||||||
{
|
{
|
||||||
@@ -240,3 +301,112 @@ void wxModalEventLoop::DoStop()
|
|||||||
[NSApp stopModal];
|
[NSApp stopModal];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxGUIEventLoop::BeginModalSession( wxWindow* modalWindow )
|
||||||
|
{
|
||||||
|
WXWindow nsnow = nil;
|
||||||
|
|
||||||
|
if ( modalWindow )
|
||||||
|
{
|
||||||
|
wxNonOwnedWindow* now = dynamic_cast<wxNonOwnedWindow*> (modalWindow);
|
||||||
|
wxASSERT_MSG( now != NULL, "must pass in a toplevel window for modal event loop" );
|
||||||
|
nsnow = now ? now->GetWXWindow() : nil;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSRect r = NSMakeRect(10, 10, 0, 0);
|
||||||
|
nsnow = [NSPanel alloc];
|
||||||
|
[nsnow initWithContentRect:r
|
||||||
|
styleMask:NSBorderlessWindowMask
|
||||||
|
backing:NSBackingStoreBuffered
|
||||||
|
defer:YES
|
||||||
|
];
|
||||||
|
[nsnow orderOut:nil];
|
||||||
|
m_dummyWindow = nsnow;
|
||||||
|
}
|
||||||
|
m_modalSession = [NSApp beginModalSessionForWindow:nsnow];
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxGUIEventLoop::EndModalSession()
|
||||||
|
{
|
||||||
|
wxASSERT_MSG(m_modalSession != NULL, "no modal session active");
|
||||||
|
[NSApp endModalSession:(NSModalSession)m_modalSession];
|
||||||
|
m_modalSession = nil;
|
||||||
|
if ( m_dummyWindow )
|
||||||
|
{
|
||||||
|
[m_dummyWindow release];
|
||||||
|
m_dummyWindow = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
wxWindowDisabler::wxWindowDisabler(bool disable)
|
||||||
|
{
|
||||||
|
m_modalEventLoop = NULL;
|
||||||
|
m_disabled = disable;
|
||||||
|
if ( disable )
|
||||||
|
DoDisable();
|
||||||
|
}
|
||||||
|
|
||||||
|
wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip)
|
||||||
|
{
|
||||||
|
m_disabled = true;
|
||||||
|
DoDisable(winToSkip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxWindowDisabler::DoDisable(wxWindow *winToSkip)
|
||||||
|
{
|
||||||
|
// remember the top level windows which were already disabled, so that we
|
||||||
|
// don't reenable them later
|
||||||
|
m_winDisabled = NULL;
|
||||||
|
|
||||||
|
wxWindowList::compatibility_iterator node;
|
||||||
|
for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
|
||||||
|
{
|
||||||
|
wxWindow *winTop = node->GetData();
|
||||||
|
if ( winTop == winToSkip )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// we don't need to disable the hidden or already disabled windows
|
||||||
|
if ( winTop->IsEnabled() && winTop->IsShown() )
|
||||||
|
{
|
||||||
|
winTop->Disable();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( !m_winDisabled )
|
||||||
|
{
|
||||||
|
m_winDisabled = new wxWindowList;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_winDisabled->Append(winTop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_modalEventLoop = (wxEventLoop*)wxEventLoopBase::GetActive();
|
||||||
|
m_modalEventLoop->BeginModalSession(winToSkip);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxWindowDisabler::~wxWindowDisabler()
|
||||||
|
{
|
||||||
|
if ( !m_disabled )
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_modalEventLoop->EndModalSession();
|
||||||
|
|
||||||
|
wxWindowList::compatibility_iterator node;
|
||||||
|
for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
|
||||||
|
{
|
||||||
|
wxWindow *winTop = node->GetData();
|
||||||
|
if ( !m_winDisabled || !m_winDisabled->Find(winTop) )
|
||||||
|
{
|
||||||
|
winTop->Enable();
|
||||||
|
}
|
||||||
|
//else: had been already disabled, don't reenable
|
||||||
|
}
|
||||||
|
|
||||||
|
delete m_winDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user