Add wxNativeWindow allowing to easily embed native widgets in wx.
Implement the class for wxMSW, wxGTK and wxOSX/Cocoa, show it in the widgets sample and add documentation for it.
This commit is contained in:
@@ -38,6 +38,45 @@
|
||||
// implementation
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxNativeWindow
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
wxNativeWindow::Create(wxWindow* parent,
|
||||
wxWindowID winid,
|
||||
wxNativeWindowHandle widget)
|
||||
{
|
||||
wxCHECK_MSG( widget, false, wxS("Invalid null GtkWidget") );
|
||||
|
||||
// Standard wxGTK controls use PreCreation() but we never have any size
|
||||
// specified at this stage, so don't bother with it.
|
||||
if ( !CreateBase(parent, winid) )
|
||||
return false;
|
||||
|
||||
// Add a reference to the widget to match g_object_unref() in wxWindow dtor
|
||||
// (and by using the "_sink" version we avoid memory leaks when we're
|
||||
// passed a newly allocated widget, as is typically the case).
|
||||
m_widget = widget;
|
||||
g_object_ref_sink(m_widget);
|
||||
|
||||
parent->DoAddChild(this);
|
||||
|
||||
PostCreation();
|
||||
|
||||
// Ensure that the best (and minimal) size is set to fully display the
|
||||
// widget.
|
||||
GtkRequisition req;
|
||||
gtk_widget_size_request(widget, &req);
|
||||
SetInitialSize(wxSize(req.width, req.height));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxNativeContainerWindow
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// TODO: we probably need equivalent code for other GDK platforms
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
|
||||
|
||||
@@ -32,6 +32,57 @@
|
||||
// implementation
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxNativeWindow
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
wxNativeWindow::Create(wxWindow* parent,
|
||||
wxWindowID winid,
|
||||
wxNativeWindowHandle hwnd)
|
||||
{
|
||||
wxCHECK_MSG( hwnd, false, wxS("Invalid null HWND") );
|
||||
wxCHECK_MSG( parent, false, wxS("Must have a valid parent") );
|
||||
wxASSERT_MSG( ::GetParent(hwnd) == GetHwndOf(parent),
|
||||
wxS("The native window has incorrect parent") );
|
||||
|
||||
const wxRect r = wxRectFromRECT(wxGetWindowRect(hwnd));
|
||||
|
||||
// Skip wxWindow::Create() which would try to create a new HWND, we don't
|
||||
// want this as we already have one.
|
||||
if ( !CreateBase(parent, winid,
|
||||
r.GetPosition(), r.GetSize(),
|
||||
0, wxDefaultValidator, wxS("nativewindow")) )
|
||||
return false;
|
||||
|
||||
parent->AddChild(this);
|
||||
|
||||
SubclassWin(hwnd);
|
||||
|
||||
if ( winid == wxID_ANY )
|
||||
{
|
||||
// We allocated a new ID to the control, use it at Windows level as
|
||||
// well because we assume that our and MSW IDs are the same in many
|
||||
// places and it seems prudent to avoid breaking this assumption.
|
||||
SetId(GetId());
|
||||
}
|
||||
else // We used a fixed ID.
|
||||
{
|
||||
// For the same reason as above, check that it's the same as the one
|
||||
// used by the native HWND.
|
||||
wxASSERT_MSG( ::GetWindowLong(hwnd, GWL_ID) == winid,
|
||||
wxS("Mismatch between wx and native IDs") );
|
||||
}
|
||||
|
||||
InheritAttributes();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxNativeContainerWindow
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxNativeContainerWindow::Create(wxNativeContainerWindowHandle hwnd)
|
||||
{
|
||||
if ( !::IsWindow(hwnd) )
|
||||
|
||||
68
src/osx/cocoa/nativewin.mm
Normal file
68
src/osx/cocoa/nativewin.mm
Normal file
@@ -0,0 +1,68 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: src/osx/cocoa/nativewin.mm
|
||||
// Purpose: wxNativeWindow implementation for wxOSX/Cocoa
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2015-08-01
|
||||
// Copyright: (c) 2015 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ============================================================================
|
||||
// declarations
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// for compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "wx/nativewin.h"
|
||||
|
||||
#include "wx/osx/private.h"
|
||||
|
||||
// ============================================================================
|
||||
// implementation
|
||||
// ============================================================================
|
||||
|
||||
bool
|
||||
wxNativeWindow::Create(wxWindow* parent,
|
||||
wxWindowID winid,
|
||||
wxNativeWindowHandle view)
|
||||
{
|
||||
wxCHECK_MSG( view, false, wxS("NULL NSView pointer") );
|
||||
|
||||
DontCreatePeer();
|
||||
|
||||
if ( !wxWindow::Create(parent, winid) )
|
||||
return false;
|
||||
|
||||
// We have to ensure that the internal label is synchronized with the label
|
||||
// at the native window, otherwise calling SetLabel() later might not work
|
||||
// and, even worse, the native label would be reset to match the (empty) wx
|
||||
// label by SetPeer().
|
||||
//
|
||||
// Notice that the selectors tested here are the same ones currently used
|
||||
// by wxWidgetCocoaImpl::SetLabel() and this code would need to be updated
|
||||
// if that method is.
|
||||
//
|
||||
// Also note the casts to "id" needed to suppress the "NSView may not
|
||||
// respond to selector" warnings: we do test that it responds to them, so
|
||||
// these warnings are not useful here.
|
||||
if ( [view respondsToSelector:@selector(title)] )
|
||||
m_label = wxCFStringRef::AsString([(id)view title]);
|
||||
else if ( [view respondsToSelector:@selector(stringValue)] )
|
||||
m_label = wxCFStringRef::AsString([(id)view stringValue]);
|
||||
|
||||
SetPeer(new wxWidgetCocoaImpl(this, view));
|
||||
|
||||
// It doesn't seem necessary to use MacPostControlCreate() here as we never
|
||||
// change the native control geometry here.
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user