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:
parent
dc90b8d411
commit
902ddbfd3e
@ -15,6 +15,11 @@ class WXDLLIMPEXP_BASE wxGUIEventLoop : public wxCFEventLoop
|
||||
{
|
||||
public:
|
||||
wxGUIEventLoop();
|
||||
~wxGUIEventLoop();
|
||||
|
||||
void BeginModalSession( wxWindow* modalWindow );
|
||||
|
||||
void EndModalSession();
|
||||
|
||||
protected:
|
||||
virtual int DoDispatchTimeout(unsigned long timeout);
|
||||
@ -24,6 +29,9 @@ protected:
|
||||
virtual void DoStop();
|
||||
|
||||
virtual CFRunLoopRef CFGetCurrentRunLoop() const;
|
||||
|
||||
void* m_modalSession;
|
||||
WXWindow m_dummyWindow;
|
||||
};
|
||||
|
||||
#endif // _WX_OSX_COCOA_EVTLOOP_H_
|
||||
|
@ -55,6 +55,7 @@ class WXDLLIMPEXP_FWD_BASE wxProcess;
|
||||
class WXDLLIMPEXP_FWD_CORE wxFrame;
|
||||
class WXDLLIMPEXP_FWD_CORE wxWindow;
|
||||
class WXDLLIMPEXP_FWD_CORE wxWindowList;
|
||||
class WXDLLIMPEXP_FWD_CORE wxEventLoop;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Arithmetic functions
|
||||
@ -714,7 +715,9 @@ private:
|
||||
// disable all windows except the given one (used by both ctors)
|
||||
void DoDisable(wxWindow *winToSkip = NULL);
|
||||
|
||||
|
||||
#if defined(__WXOSX__) && wxOSX_USE_COCOA
|
||||
wxEventLoop* m_modalEventLoop;
|
||||
#endif
|
||||
wxWindowList *m_winDisabled;
|
||||
bool m_disabled;
|
||||
|
||||
|
@ -1567,6 +1567,12 @@ void wxEnableTopLevelWindows(bool enable)
|
||||
node->GetData()->Enable(enable);
|
||||
}
|
||||
|
||||
#if defined(__WXOSX__) && wxOSX_USE_COCOA
|
||||
|
||||
// defined in evtloop.mm
|
||||
|
||||
#else
|
||||
|
||||
wxWindowDisabler::wxWindowDisabler(bool disable)
|
||||
{
|
||||
m_disabled = disable;
|
||||
@ -1629,6 +1635,8 @@ wxWindowDisabler::~wxWindowDisabler()
|
||||
delete m_winDisabled;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Yield to other apps/messages and disable user input to all windows except
|
||||
// the given one
|
||||
bool wxSafeYield(wxWindow *win, bool onlyIfNeeded)
|
||||
|
@ -39,45 +39,76 @@
|
||||
// wxEventLoop implementation
|
||||
// ============================================================================
|
||||
|
||||
/*
|
||||
static int CalculateNSEventMaskFromEventCategory(wxEventCategory cat)
|
||||
|
||||
static NSUInteger CalculateNSEventMaskFromEventCategory(wxEventCategory cat)
|
||||
{
|
||||
NSLeftMouseDownMask |
|
||||
NSLeftMouseUpMask |
|
||||
NSRightMouseDownMask |
|
||||
NSRightMouseUpMask = 1 << NSRightMouseUp,
|
||||
NSMouseMovedMask = 1 << NSMouseMoved,
|
||||
NSLeftMouseDraggedMask = 1 << NSLeftMouseDragged,
|
||||
NSRightMouseDraggedMask = 1 << NSRightMouseDragged,
|
||||
NSMouseEnteredMask = 1 << NSMouseEntered,
|
||||
NSMouseExitedMask = 1 << NSMouseExited,
|
||||
NSScrollWheelMask = 1 << NSScrollWheel,
|
||||
// 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 |
|
||||
NSLeftMouseUpMask |
|
||||
NSRightMouseDownMask |
|
||||
NSRightMouseUpMask |
|
||||
NSMouseMovedMask |
|
||||
NSLeftMouseDraggedMask |
|
||||
NSRightMouseDraggedMask |
|
||||
NSMouseEnteredMask |
|
||||
NSMouseExitedMask |
|
||||
NSScrollWheelMask |
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||
NSTabletPointMask = 1 << NSTabletPoint,
|
||||
NSTabletProximityMask = 1 << NSTabletProximity,
|
||||
NSTabletPointMask |
|
||||
NSTabletProximityMask |
|
||||
#endif
|
||||
NSOtherMouseDownMask = 1 << NSOtherMouseDown,
|
||||
NSOtherMouseUpMask = 1 << NSOtherMouseUp,
|
||||
NSOtherMouseDraggedMask = 1 << NSOtherMouseDragged,
|
||||
NSOtherMouseDownMask |
|
||||
NSOtherMouseUpMask |
|
||||
NSOtherMouseDraggedMask |
|
||||
|
||||
|
||||
|
||||
NSKeyDownMask = 1 << NSKeyDown,
|
||||
NSKeyUpMask = 1 << NSKeyUp,
|
||||
NSFlagsChangedMask = 1 << NSFlagsChanged,
|
||||
|
||||
NSAppKitDefinedMask = 1 << NSAppKitDefined,
|
||||
NSSystemDefinedMask = 1 << NSSystemDefined,
|
||||
NSApplicationDefinedMask = 1 << NSApplicationDefined,
|
||||
NSPeriodicMask = 1 << NSPeriodic,
|
||||
NSCursorUpdateMask = 1 << NSCursorUpdate,
|
||||
|
||||
NSAnyEventMask = 0xffffffffU
|
||||
NSKeyDownMask |
|
||||
NSKeyUpMask |
|
||||
NSFlagsChangedMask |
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||
NSEventMaskGesture |
|
||||
NSEventMaskMagnify |
|
||||
NSEventMaskSwipe |
|
||||
NSEventMaskRotate |
|
||||
NSEventMaskBeginGesture |
|
||||
NSEventMaskEndGesture |
|
||||
#endif
|
||||
0;
|
||||
}
|
||||
|
||||
if ( cat | (~wxEVT_CATEGORY_USER_INPUT) )
|
||||
{
|
||||
mask |=
|
||||
NSAppKitDefinedMask |
|
||||
NSSystemDefinedMask |
|
||||
NSApplicationDefinedMask |
|
||||
NSPeriodicMask |
|
||||
NSCursorUpdateMask;
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
wxGUIEventLoop::wxGUIEventLoop()
|
||||
{
|
||||
m_modalSession = nil;
|
||||
m_dummyWindow = nil;
|
||||
}
|
||||
|
||||
wxGUIEventLoop::~wxGUIEventLoop()
|
||||
{
|
||||
wxASSERT( m_modalSession == nil );
|
||||
wxASSERT( m_dummyWindow == nil );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -156,18 +187,48 @@ int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout)
|
||||
{
|
||||
wxMacAutoreleasePool autoreleasepool;
|
||||
|
||||
NSEvent *event = [NSApp
|
||||
nextEventMatchingMask:NSAnyEventMask
|
||||
untilDate:[NSDate dateWithTimeIntervalSinceNow: timeout/1000]
|
||||
inMode:NSDefaultRunLoopMode
|
||||
dequeue: YES];
|
||||
|
||||
if ( event == nil )
|
||||
return -1;
|
||||
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
|
||||
nextEventMatchingMask:NSAnyEventMask
|
||||
untilDate:[NSDate dateWithTimeIntervalSinceNow: timeout/1000]
|
||||
inMode:NSDefaultRunLoopMode
|
||||
dequeue: YES];
|
||||
|
||||
if ( event == nil )
|
||||
return -1;
|
||||
|
||||
[NSApp sendEvent: event];
|
||||
[NSApp sendEvent: event];
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void wxGUIEventLoop::DoRun()
|
||||
@ -240,3 +301,112 @@ void wxModalEventLoop::DoStop()
|
||||
[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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user