Further implementation of native overlay on Cocoa

Should work for Caret,  still has a problem with the transformation matrix otherwise, too many things have changed there for me to find a quick solutions.
This commit is contained in:
Stefan Csomor
2017-09-09 11:44:43 +02:00
parent 4d8c1fc890
commit 8ad0039b71
2 changed files with 41 additions and 52 deletions

View File

@@ -38,7 +38,7 @@ public:
void Clear( wxDC* dc); void Clear( wxDC* dc);
private: private:
void CreateOverlayWindow(); void CreateOverlayWindow( wxDC* dc );
WXWindow m_overlayWindow; WXWindow m_overlayWindow;
WXWindow m_overlayParentWindow; WXWindow m_overlayParentWindow;

View File

@@ -56,47 +56,45 @@ bool wxOverlayImpl::IsOk()
return m_overlayWindow != NULL ; return m_overlayWindow != NULL ;
} }
void wxOverlayImpl::CreateOverlayWindow() void wxOverlayImpl::CreateOverlayWindow( wxDC* dc )
{ {
if ( m_window ) if (m_window)
{ {
m_overlayParentWindow = m_window->MacGetTopLevelWindowRef(); m_overlayParentWindow = m_window->MacGetTopLevelWindowRef();
[m_overlayParentWindow makeKeyAndOrderFront:nil]; [m_overlayParentWindow makeKeyAndOrderFront:nil];
NSView* view = m_window->GetHandle(); wxPoint origin(m_x, m_y);
if (!dc->IsKindOf(CLASSINFO(wxClientDC)))
origin -= m_window->GetClientAreaOrigin();
NSPoint viewOriginBase, viewOriginScreen; origin = m_window->ClientToScreen(origin);
viewOriginBase = [view convertPoint:NSMakePoint(0, 0) toView:nil];
viewOriginScreen = [m_overlayParentWindow convertBaseToScreen:viewOriginBase];
NSSize viewSize = [view frame].size; wxSize size(m_width, m_height);
if ( [view isFlipped] ) NSRect overlayRect = wxToNSRect(NULL, wxRect(origin, size));
viewOriginScreen.y -= viewSize.height; overlayRect = [NSWindow contentRectForFrameRect:overlayRect styleMask:NSBorderlessWindowMask];
m_overlayWindow=[[NSWindow alloc] initWithContentRect:NSMakeRect(viewOriginScreen.x,viewOriginScreen.y,
viewSize.width,
viewSize.height)
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:YES];
m_overlayWindow = [[NSWindow alloc] initWithContentRect:overlayRect
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:YES];
[m_overlayParentWindow addChildWindow:m_overlayWindow ordered:NSWindowAbove]; [m_overlayParentWindow addChildWindow:m_overlayWindow ordered:NSWindowAbove];
} }
else else
{ {
m_overlayParentWindow = NULL ; m_overlayParentWindow = NULL;
CGRect cgbounds ; CGRect cgbounds;
cgbounds = CGDisplayBounds(CGMainDisplayID()); cgbounds = CGDisplayBounds(CGMainDisplayID());
m_overlayWindow=[[NSWindow alloc] initWithContentRect:NSMakeRect(cgbounds.origin.x,cgbounds.origin.y, m_overlayWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(cgbounds.origin.x, cgbounds.origin.y,
cgbounds.size.width, cgbounds.size.width,
cgbounds.size.height) cgbounds.size.height)
styleMask:NSBorderlessWindowMask styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered backing:NSBackingStoreBuffered
defer:YES]; defer:YES];
} }
[m_overlayWindow setOpaque:NO]; [m_overlayWindow setOpaque:NO];
[m_overlayWindow setIgnoresMouseEvents:YES]; [m_overlayWindow setIgnoresMouseEvents:YES];
[m_overlayWindow setBackgroundColor:[NSColor clearColor]];
[m_overlayWindow setAlphaValue:1.0]; [m_overlayWindow setAlphaValue:1.0];
[m_overlayWindow orderFront:nil]; [m_overlayWindow orderFront:nil];
@@ -109,39 +107,28 @@ void wxOverlayImpl::Init( wxDC* dc, int x , int y , int width , int height )
m_window = dc->GetWindow(); m_window = dc->GetWindow();
m_x = x ; m_x = x ;
m_y = y ; m_y = y ;
if ( dc->IsKindOf( CLASSINFO( wxClientDC ) ))
{
wxPoint origin = m_window->GetClientAreaOrigin();
m_x += origin.x;
m_y += origin.y;
}
m_width = width ; m_width = width ;
m_height = height ; m_height = height ;
CreateOverlayWindow(); CreateOverlayWindow(dc);
wxASSERT_MSG( m_overlayWindow != NULL , _("Couldn't create the overlay window") ); wxASSERT_MSG(m_overlayWindow != NULL, _("Couldn't create the overlay window"));
m_overlayContext = (CGContextRef) [[m_overlayWindow graphicsContext] graphicsPort]; m_overlayContext = (CGContextRef) [[m_overlayWindow graphicsContext] graphicsPort];
wxASSERT_MSG( m_overlayContext != NULL , _("Couldn't init the context on the overlay window") ); wxASSERT_MSG( m_overlayContext != NULL , _("Couldn't init the context on the overlay window") );
int ySize = 0; int ySize = 0;
if ( m_window ) if ( m_window )
{ {
NSView* view = m_window->GetHandle(); ySize = m_height;
NSSize viewSize = [view frame].size;
ySize = viewSize.height;
} }
else else
{ {
CGRect cgbounds ; CGRect cgbounds ;
cgbounds = CGDisplayBounds(CGMainDisplayID()); cgbounds = CGDisplayBounds(CGMainDisplayID());
ySize = cgbounds.size.height; ySize = cgbounds.size.height;
} }
CGContextTranslateCTM( m_overlayContext, 0, ySize );
CGContextScaleCTM( m_overlayContext, 1, -1 ); CGContextTranslateCTM(m_overlayContext, 0, ySize);
CGContextTranslateCTM( m_overlayContext, -m_x , -m_y ); CGContextScaleCTM(m_overlayContext, 1, -1);
} }
void wxOverlayImpl::BeginDrawing( wxDC* dc) void wxOverlayImpl::BeginDrawing( wxDC* dc)
@@ -151,7 +138,9 @@ void wxOverlayImpl::BeginDrawing( wxDC* dc)
if (win_impl) if (win_impl)
{ {
win_impl->SetGraphicsContext( wxGraphicsContext::CreateFromNative( m_overlayContext ) ); win_impl->SetGraphicsContext( wxGraphicsContext::CreateFromNative( m_overlayContext ) );
dc->SetClippingRegion( m_x , m_y , m_width , m_height ) ; if (m_window)
dc->SetDeviceOrigin(dc->LogicalToDeviceX(-m_x), dc->LogicalToDeviceY(-m_y));
dc->SetClippingRegion(m_x, m_y, m_width, m_height);
} }
} }
@@ -165,11 +154,11 @@ void wxOverlayImpl::EndDrawing( wxDC* dc)
CGContextFlush( m_overlayContext ); CGContextFlush( m_overlayContext );
} }
void wxOverlayImpl::Clear(wxDC* WXUNUSED(dc)) void wxOverlayImpl::Clear(wxDC* dc)
{ {
wxASSERT_MSG( IsOk() , _("You cannot Clear an overlay that is not inited") ); wxASSERT_MSG( IsOk() , _("You cannot Clear an overlay that is not inited") );
CGRect box = CGRectMake( m_x - 1, m_y - 1 , m_width + 2 , m_height + 2 );
CGContextClearRect( m_overlayContext, box ); dc->GetGraphicsContext()->ClearRectangle(m_x - 1, m_y - 1, m_width + 2, m_height + 2);
} }
void wxOverlayImpl::Reset() void wxOverlayImpl::Reset()