From 66d340ae150a391a8fdda455d1c3481e58007e7e Mon Sep 17 00:00:00 2001 From: New Pagodi Date: Thu, 14 Mar 2019 20:00:35 -0500 Subject: [PATCH] Define the wxSTCPopupBase for wxCocoa With the cocoa port, wxSTCPopupBase is defined by creating a floating window using the cocoa api and then wrapping that window in a wxNonOwnedWindow for use with wxWidgets. --- src/stc/PlatWX.cpp | 59 ++++++++++++++++++ src/stc/PlatWX.h | 13 ++++ src/stc/PlatWXcocoa.h | 28 +++++++++ src/stc/PlatWXcocoa.mm | 132 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 232 insertions(+) create mode 100644 src/stc/PlatWXcocoa.h create mode 100644 src/stc/PlatWXcocoa.mm diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index a907e4b955..b78b8445b5 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -60,6 +60,8 @@ #include "wx/gtk/private/wrapgtk.h" #elif defined(__WXMSW__) #include "wx/msw/wrapwin.h" +#elif defined(__WXOSX_COCOA__) + #include "PlatWXcocoa.h" #endif Point Point::FromLong(long lpoint) { @@ -1998,10 +2000,67 @@ PRectangle Window::GetMonitorRect(Point pt) { wxSTCPopupBase::wxSTCPopupBase(wxWindow* parent):wxNonOwnedWindow() { + m_nativeWin = CreateFloatingWindow(this); + wxNonOwnedWindow::Create(parent, m_nativeWin); + m_stc = wxDynamicCast(parent, wxStyledTextCtrl); + m_isShown = false; + + Bind(wxEVT_ENTER_WINDOW, &wxSTCPopupBase::OnMouseEnter, this); + Bind(wxEVT_LEAVE_WINDOW, &wxSTCPopupBase::OnMouseLeave, this); } wxSTCPopupBase::~wxSTCPopupBase() { + UnsubclassWin(); + CloseFloatingWindow(m_nativeWin); + + SetSTCCursor(wxSTC_CURSORNORMAL); + } + + bool wxSTCPopupBase::Show(bool show) + { + if ( !wxWindowBase::Show(show) ) + return false; + + if ( show ) + { + ShowFloatingWindow(m_nativeWin); + + if ( GetRect().Contains(::wxMouseState().GetPosition()) ) + SetSTCCursor(wxSTC_CURSORARROW); + } + else + { + HideFloatingWindow(m_nativeWin); + SetSTCCursor(wxSTC_CURSORNORMAL); + } + + return true; + } + + void wxSTCPopupBase::DoSetSize(int x, int y, int width, int ht, int flags) + { + wxSize oldSize = GetSize(); + wxNonOwnedWindow::DoSetSize(x, y, width, ht, flags); + + if ( oldSize != GetSize() ) + SendSizeEvent(); + } + + void wxSTCPopupBase::SetSTCCursor(int cursor) + { + if ( m_stc ) + m_stc->SetSTCCursor(cursor); + } + + void wxSTCPopupBase::OnMouseEnter(wxMouseEvent& WXUNUSED(event)) + { + SetSTCCursor(wxSTC_CURSORARROW); + } + + void wxSTCPopupBase::OnMouseLeave(wxMouseEvent& WXUNUSED(event)) + { + SetSTCCursor(wxSTC_CURSORNORMAL); } #elif wxUSE_POPUPWIN diff --git a/src/stc/PlatWX.h b/src/stc/PlatWX.h index 93dc33f380..edb5493161 100644 --- a/src/stc/PlatWX.h +++ b/src/stc/PlatWX.h @@ -8,6 +8,8 @@ #include "wx/imaglist.h" #include "Platform.h" +class wxStyledTextCtrl; + @@ -75,6 +77,17 @@ public: public: wxSTCPopupBase(wxWindow*); virtual ~wxSTCPopupBase(); + virtual bool Show(bool show=true) wxOVERRIDE; + + protected: + virtual void DoSetSize(int, int, int, int, int) wxOVERRIDE; + void SetSTCCursor(int); + void OnMouseEnter(wxMouseEvent&); + void OnMouseLeave(wxMouseEvent&); + + private: + WX_NSWindow m_nativeWin; + wxStyledTextCtrl* m_stc; }; #elif wxUSE_POPUPWIN diff --git a/src/stc/PlatWXcocoa.h b/src/stc/PlatWXcocoa.h new file mode 100644 index 0000000000..74c7f4856c --- /dev/null +++ b/src/stc/PlatWXcocoa.h @@ -0,0 +1,28 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: src/stc/PlatWXcocoa.h +// Purpose: Declaration of utility functions for wxSTC with cocoa +// Author: New Pagodi +// Created: 2019-03-10 +// Copyright: (c) 2019 wxWidgets development team +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _SRC_STC_PLATWXCOCOA_H_ +#define _SRC_STC_PLATWXCOCOA_H_ + +#include "wx/defs.h" + +#if wxUSE_STC + +// Functions used to create and manage popup windows. +WX_NSWindow CreateFloatingWindow(wxWindow*); +void CloseFloatingWindow(WX_NSWindow win); +void ShowFloatingWindow(WX_NSWindow win); +void HideFloatingWindow(WX_NSWindow win); + +// Function needed for list control colours. +wxColour GetListHighlightColour(); + +#endif // wxUSE_STC + +#endif // _SRC_STC_PLATWXCOCOA_H_ diff --git a/src/stc/PlatWXcocoa.mm b/src/stc/PlatWXcocoa.mm new file mode 100644 index 0000000000..0c8ce5ccd3 --- /dev/null +++ b/src/stc/PlatWXcocoa.mm @@ -0,0 +1,132 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: src/stc/PlatWXcocoa.mm +// Purpose: Implementation of utility functions for wxSTC with cocoa +// Author: New Pagodi +// Created: 2019-03-10 +// Copyright: (c) 2019 wxWidgets development team +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#include "wx/wxprec.h" + +#if wxUSE_STC + +#include "wx/osx/private.h" +#include "PlatWXcocoa.h" + +// A simple view used for popup windows. + +@interface wxSTCPopupBaseView : NSView +{ +@private + NSTrackingArea * m_trackingArea; + wxWindow* m_wxWin; +} + +- (id)initWithwxWin:(wxWindow*) wxwin; + +@end + +@implementation wxSTCPopupBaseView + +- (id)initWithwxWin:(wxWindow*) wxWin +{ + m_trackingArea = nil; + + self = [super init]; + if ( self ) + m_wxWin = wxWin; + + return self; +} + +- (void)updateTrackingAreas +{ + if( m_trackingArea != nil ) + { + [self removeTrackingArea:m_trackingArea]; + [m_trackingArea release]; + } + + int options = NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways; + m_trackingArea = [[NSTrackingArea alloc] initWithRect: [self bounds] + options: options + owner: self + userInfo: nil]; + [self addTrackingArea:m_trackingArea]; +} + +- (void)mouseEntered:(NSEvent *)evt +{ + wxMouseEvent wxevent(wxEVT_ENTER_WINDOW); + wxevent.SetEventObject(m_wxWin); + m_wxWin->ProcessWindowEvent(wxevent); +} + +- (void)mouseExited:(NSEvent *)evt +{ + wxMouseEvent wxevent(wxEVT_LEAVE_WINDOW); + wxevent.SetEventObject(m_wxWin); + m_wxWin->ProcessWindowEvent(wxevent); +} + +- (void)mouseDown:(NSEvent *)evt +{ + NSRect locationInWindow = NSZeroRect; + locationInWindow.origin = [evt locationInWindow]; + NSPoint locationInView = [self convertPoint: locationInWindow.origin + fromView: nil]; + wxPoint locationInViewWX = wxFromNSPoint(self, locationInView); + + wxMouseEvent wxevent(wxEVT_LEFT_DOWN); + wxevent.SetEventObject(m_wxWin); + wxevent.SetX(locationInViewWX.x); + wxevent.SetY(locationInViewWX.y); + m_wxWin->ProcessWindowEvent(wxevent); +} + +- (void)drawRect:(NSRect)dirtyRect +{ + static_cast(m_wxWin->GetPeer())-> + drawRect(&dirtyRect, self, NULL); +} + +@end + + +// Utility functions. + +WX_NSWindow CreateFloatingWindow(wxWindow* wxWin) +{ + NSWindow* w = [[NSWindow alloc] initWithContentRect: NSZeroRect + styleMask: NSBorderlessWindowMask + backing: NSBackingStoreBuffered + defer: NO]; + [w setLevel:NSFloatingWindowLevel]; + [w setHasShadow:YES]; + [w setContentView:[[wxSTCPopupBaseView alloc] initWithwxWin:wxWin]]; + + return w; +} + +void CloseFloatingWindow(WX_NSWindow nsWin) +{ + [nsWin close]; +} + +void ShowFloatingWindow(WX_NSWindow nsWin) +{ + [nsWin orderFront:NSApp]; +} + +void HideFloatingWindow(WX_NSWindow nsWin) +{ + [nsWin orderOut:NSApp]; +} + +wxColour GetListHighlightColour() +{ + return wxColour([NSColor alternateSelectedControlColor]); +} + +#endif // wxUSE_STC