/////////////////////////////////////////////////////////////////////////////
-// Name: src/osx/carbon/window.cpp
+// Name: src/osx/window_osx.cpp
// Purpose: wxWindowMac
// Author: Stefan Csomor
// Modified by:
#endif
#if wxUSE_DRAG_AND_DROP
-#include "wx/dnd.h"
+ #include "wx/dnd.h"
#endif
#include "wx/graphics.h"
#if wxOSX_USE_CARBON
-#include "wx/osx/uma.h"
+ #include "wx/osx/uma.h"
#else
-#include "wx/osx/private.h"
+ #include "wx/osx/private.h"
#endif
#define MAC_SCROLLBAR_SIZE 15
wxWidgetImplType* kOSXNoWidgetImpl = (wxWidgetImplType*) -1L;
+#if wxUSE_HOTKEY && wxOSX_USE_COCOA_OR_CARBON
+
+typedef struct {
+ EventHotKeyRef ref;
+ int keyId;
+ wxWindow* window;
+} wxHotKeyRec;
+
+wxVector<wxHotKeyRec> s_hotkeys;
+
+#endif
+
// ===========================================================================
// implementation
// ===========================================================================
wxWindowMac::~wxWindowMac()
{
SendDestroyEvent();
+
+#if wxUSE_HOTKEY && wxOSX_USE_COCOA_OR_CARBON
+ for ( int i = s_hotkeys.size()-1; i>=0; -- i )
+ {
+ if ( s_hotkeys[i].window == this )
+ {
+ EventHotKeyRef ref = s_hotkeys[i].ref;
+ s_hotkeys.erase(s_hotkeys.begin() + i);
+ if ( UnregisterEventHotKey(ref) != noErr )
+ {
+ wxLogLastError(wxT("UnregisterHotKey"));
+ }
+ }
+ }
+#endif
MacInvalidateBorders() ;
return m_peer == kOSXNoWidgetImpl ? NULL : m_peer ;
}
+bool wxWindowMac::ShouldCreatePeer() const
+{
+ return m_peer != kOSXNoWidgetImpl;
+}
+
void wxWindowMac::DontCreatePeer()
{
m_peer = kOSXNoWidgetImpl;
{
if ( GetPeer() )
{
- GetPeer()->RemoveFromParent();
+ if ( !GetPeer()->IsRootControl() )
+ GetPeer()->RemoveFromParent();
wxDELETE(m_peer);
}
GetParent()->MacChildAdded() ;
// adjust font, controlsize etc
- DoSetWindowVariant( m_windowVariant ) ;
+ GetPeer()->SetControlSize( m_windowVariant );
+ InheritAttributes();
+ // in case nothing has been set, use the variant default fonts
+ if ( !m_hasFont )
+ DoSetWindowVariant( m_windowVariant );
GetPeer()->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics), GetFont().GetEncoding() ) ;
/*
* Right now we have the following setup :
* a border that is not part of the native control is always outside the
- * control's border (otherwise we loose all native intelligence, future ways
+ * control's border (otherwise we lose all native intelligence, future ways
* may be to have a second embedding control responsible for drawing borders
* and backgrounds eventually)
* so all this border calculations have to be taken into account when calling
#endif
}
-void wxWindowMac::MacPostControlCreate(const wxPoint& WXUNUSED(pos), const wxSize& size)
+void wxWindowMac::MacPostControlCreate(const wxPoint& WXUNUSED(pos),
+ const wxSize& WXUNUSED(size))
{
// todo remove if refactoring works correctly
#if 0
{
// Don't assert, in case we set the window variant before
// the window is created
- // wxASSERT( GetPeer()->Ok() ) ;
+ // wxASSERT( GetPeer()->IsOk() ) ;
m_windowVariant = variant ;
return;
GetPeer()->SetControlSize( variant );
-#if wxOSX_USE_CARBON
- ControlSize size ;
-
- // we will get that from the settings later
- // and make this NORMAL later, but first
- // we have a few calculations that we must fix
-
- switch ( variant )
- {
- case wxWINDOW_VARIANT_NORMAL :
- size = kControlSizeNormal;
- break ;
-
- case wxWINDOW_VARIANT_SMALL :
- size = kControlSizeSmall;
- break ;
-
- case wxWINDOW_VARIANT_MINI :
- // not always defined in the headers
- size = 3 ;
- break ;
-
- case wxWINDOW_VARIANT_LARGE :
- size = kControlSizeLarge;
- break ;
-
- default:
- wxFAIL_MSG(wxT("unexpected window variant"));
- break ;
- }
- GetPeer()->SetData<ControlSize>(kControlEntireControl, kControlSizeTag, &size ) ;
-#endif
-
switch ( variant )
{
{
if (m_growBox)
{
- if ( m_backgroundColour.Ok() )
+ if ( m_backgroundColour.IsOk() )
m_growBox->SetBackgroundColour(m_backgroundColour);
else
m_growBox->SetBackgroundColour(*wxWHITE);
GetPeer()->SetFocus() ;
}
+void wxWindowMac::OSXSimulateFocusEvents()
+{
+ wxWindow* former = FindFocus() ;
+ if ( former != NULL && former != this )
+ {
+ {
+ wxFocusEvent event( wxEVT_KILL_FOCUS, former->GetId());
+ event.SetEventObject(former);
+ event.SetWindow(this);
+ former->HandleWindowEvent(event) ;
+ }
+
+ {
+ wxFocusEvent event(wxEVT_SET_FOCUS, former->GetId());
+ event.SetEventObject(former);
+ event.SetWindow(this);
+ former->HandleWindowEvent(event);
+ }
+ }
+}
+
void wxWindowMac::DoCaptureMouse()
{
wxApp::s_captureWindow = (wxWindow*) this ;
delete m_dropTarget;
m_dropTarget = pDropTarget;
- if ( m_dropTarget != NULL )
- {
- // TODO:
- }
+
+ GetPeer()->SetDropTarget(m_dropTarget) ;
}
#endif
return false ;
}
- wxASSERT_MSG( m_cursor.Ok(),
+ wxASSERT_MSG( m_cursor.IsOk(),
wxT("cursor must be valid after call to the base version"));
if ( GetPeer() != NULL )
if ( doResize )
{
MacRepositionScrollBars() ;
- wxSize size(actualWidth, actualHeight);
- wxSizeEvent event(size, m_windowId);
- event.SetEventObject(this);
- HandleWindowEvent(event);
+ SendSizeEvent();
}
}
}
}
}
+void wxWindowMac::SendSizeEvent(int flags)
+{
+ MacOnInternalSize();
+ wxWindowBase::SendSizeEvent(flags);
+}
+
// set the size of the window: if the dimensions are positive, just use them,
// but if any of them is equal to -1, it means that we must find the value for
// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
if (sizeFlags & wxSIZE_FORCE_EVENT)
{
- wxSizeEvent event( wxSize(width,height), GetId() );
- event.SetEventObject( this );
- HandleWindowEvent( event );
+ SendSizeEvent();
}
return;
}
}
-float wxWindowMac::GetContentScaleFactor() const
+double wxWindowMac::GetContentScaleFactor() const
{
return GetPeer()->GetContentScaleFactor();
}
bool wxWindowMac::Show(bool show)
{
+ if ( !show )
+ MacInvalidateBorders();
+
if ( !wxWindowBase::Show(show) )
return false;
if ( GetPeer() )
GetPeer()->SetVisibility( show ) ;
+ if ( show )
+ MacInvalidateBorders();
+
#ifdef __WXOSX_IPHONE__
// only when there's no native event support
if ( !IsTopLevel() )
void wxWindowMac::MacEnabledStateChanged()
{
- OnEnabled( GetPeer()->IsEnabled() );
}
//
if ( !IsShownOnScreen() )
return ;
+
+ if ( IsFrozen() )
+ return;
GetPeer()->SetNeedsDisplay( rect ) ;
}
void wxWindowMac::DoFreeze()
{
-#if wxOSX_USE_CARBON
if ( GetPeer() && GetPeer()->IsOk() )
GetPeer()->SetDrawingEnabled( false ) ;
-#endif
}
void wxWindowMac::DoThaw()
{
-#if wxOSX_USE_CARBON
if ( GetPeer() && GetPeer()->IsOk() )
- {
GetPeer()->SetDrawingEnabled( true ) ;
- GetPeer()->InvalidateWithChildren() ;
- }
-#endif
}
wxWindow *wxGetActiveWindow()
CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
CGContextSaveGState( cgContext );
- if ( m_backgroundColour.Ok() )
+ if ( m_backgroundColour.IsOk() )
{
CGContextSetFillColorWithColor( cgContext, m_backgroundColour.GetCGColor() );
}
#else
if (m_growBox)
{
- if ( m_backgroundColour.Ok() )
+ if ( m_backgroundColour.IsOk() )
m_growBox->SetBackgroundColour(m_backgroundColour);
else
m_growBox->SetBackgroundColour(*wxWHITE);
GetPeer()->GetSize( tw, th );
GetPeer()->GetPosition( tx, ty );
- Rect rect = { ty,tx, ty+th, tx+tw };
-
#if wxOSX_USE_COCOA_OR_CARBON
- InsetRect( &rect, -1 , -1 ) ;
-
{
- CGRect cgrect = CGRectMake( rect.left , rect.top , rect.right - rect.left ,
- rect.bottom - rect.top ) ;
+ CGRect cgrect = CGRectMake( tx-1 , ty-1 , tw+2 ,
+ th+2 ) ;
CGContextRef cgContext = (CGContextRef) GetParent()->MacGetCGContextRef() ;
wxASSERT( cgContext ) ;
MacRepositionScrollBars() ;
if ( triggerSizeEvent )
{
- wxSizeEvent event(GetSize(), m_windowId);
- event.SetEventObject(this);
- HandleWindowEvent(event);
+ SendSizeEvent();
}
#endif
}
if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) )
{
wxSetCursorEvent event( pt.x , pt.y );
+ event.SetId(GetId());
+ event.SetEventObject(this);
bool processedEvtSetCursor = HandleWindowEvent(event);
if ( processedEvtSetCursor && event.HasCursor() )
// if the user code caught EVT_SET_CURSOR() and returned nothing from
// it - this is a way to say that our cursor shouldn't be used for this
// point
- if ( !processedEvtSetCursor && m_cursor.Ok() )
+ if ( !processedEvtSetCursor && m_cursor.IsOk() )
cursor = m_cursor ;
if ( !wxIsBusy() && !GetParent() )
cursor = *wxSTANDARD_CURSOR ;
}
- if ( cursor.Ok() )
+ if ( cursor.IsOk() )
cursor.MacInstall() ;
}
- return cursor.Ok() ;
+ return cursor.IsOk() ;
}
wxString wxWindowMac::MacGetToolTipString( wxPoint &WXUNUSED(pt) )
}
m_updateRegion = formerUpdateRgn;
+
+ wxNonOwnedWindow* top = MacGetTopLevelWindow();
+ if (top)
+ top->WindowWasPainted() ;
+
return handled;
}
const wxFrame *frame = wxDynamicCast( win, wxFrame ) ;
if ( frame )
{
- if ( frame->GetWindowStyleFlag() & wxRESIZE_BORDER )
+ // starting from 10.7 there are no resize indicators anymore
+ if ( (frame->GetWindowStyleFlag() & wxRESIZE_BORDER) && UMAGetSystemVersion() < 0x1070)
{
// Parent frame has resize handle
wxPoint frameBottomRight = frame->GetScreenRect().GetBottomRight();
int x, y, w, h ;
window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin ) ;
- Rect bounds = { y, x, y + h, x + w };
+ Rect bounds = { static_cast<short>(y), static_cast<short>(x), static_cast<short>(y + h), static_cast<short>(x + w) };
return bounds ;
}
return wxWindowBase::IsShownOnScreen();
}
+#if wxUSE_HOTKEY && wxOSX_USE_COCOA_OR_CARBON
+
+OSStatus
+wxHotKeyHandler(EventHandlerCallRef WXUNUSED(nextHandler),
+ EventRef event,
+ void* WXUNUSED(userData))
+{
+ EventHotKeyID hotKeyId;
+
+ GetEventParameter( event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(hotKeyId), NULL, &hotKeyId);
+
+ for ( unsigned i = 0; i < s_hotkeys.size(); ++i )
+ {
+ if ( s_hotkeys[i].keyId == static_cast<int>(hotKeyId.id) )
+ {
+ unsigned char charCode ;
+ UInt32 keyCode ;
+ UInt32 modifiers ;
+ UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
+
+ GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode );
+ GetEventParameter( event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
+ GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers );
+
+ UInt32 keymessage = (keyCode << 8) + charCode;
+
+ wxKeyEvent wxevent(wxEVT_HOTKEY);
+ wxevent.SetId(hotKeyId.id);
+ wxTheApp->MacCreateKeyEvent( wxevent, s_hotkeys[i].window , keymessage ,
+ modifiers , when , 0 ) ;
+
+ s_hotkeys[i].window->HandleWindowEvent(wxevent);
+ }
+ }
+
+ return noErr;
+}
+
+bool wxWindowMac::RegisterHotKey(int hotkeyId, int modifiers, int keycode)
+{
+ for ( unsigned i = 0; i < s_hotkeys.size(); ++i )
+ {
+ if ( s_hotkeys[i].keyId == hotkeyId )
+ {
+ wxLogLastError(wxT("hotkeyId already registered"));
+
+ return false;
+ }
+ }
+
+ static bool installed = false;
+ if ( !installed )
+ {
+ EventTypeSpec eventType;
+ eventType.eventClass=kEventClassKeyboard;
+ eventType.eventKind=kEventHotKeyPressed;
+
+ InstallApplicationEventHandler(&wxHotKeyHandler, 1, &eventType, NULL, NULL);
+ installed = true;
+ }
+
+ UInt32 mac_modifiers=0;
+ if ( modifiers & wxMOD_ALT )
+ mac_modifiers |= optionKey;
+ if ( modifiers & wxMOD_SHIFT )
+ mac_modifiers |= shiftKey;
+ if ( modifiers & wxMOD_RAW_CONTROL )
+ mac_modifiers |= controlKey;
+ if ( modifiers & wxMOD_CONTROL )
+ mac_modifiers |= cmdKey;
+
+ EventHotKeyRef hotKeyRef;
+ EventHotKeyID hotKeyIDmac;
+
+ hotKeyIDmac.signature = 'WXMC';
+ hotKeyIDmac.id = hotkeyId;
+
+ if ( RegisterEventHotKey(wxCharCodeWXToOSX((wxKeyCode)keycode), mac_modifiers, hotKeyIDmac,
+ GetApplicationEventTarget(), 0, &hotKeyRef) != noErr )
+ {
+ wxLogLastError(wxT("RegisterHotKey"));
+
+ return false;
+ }
+ else
+ {
+ wxHotKeyRec v;
+ v.ref = hotKeyRef;
+ v.keyId = hotkeyId;
+ v.window = this;
+
+ s_hotkeys.push_back(v);
+ }
+
+ return true;
+}
+
+bool wxWindowMac::UnregisterHotKey(int hotkeyId)
+{
+ for ( int i = ((int)s_hotkeys.size())-1; i>=0; -- i )
+ {
+ if ( s_hotkeys[i].keyId == hotkeyId )
+ {
+ EventHotKeyRef ref = s_hotkeys[i].ref;
+ s_hotkeys.erase(s_hotkeys.begin() + i);
+ if ( UnregisterEventHotKey(ref) != noErr )
+ {
+ wxLogLastError(wxT("UnregisterHotKey"));
+
+ return false;
+ }
+ else
+ return true;
+ }
+ }
+
+ return false;
+}
+
+#endif // wxUSE_HOTKEY
+
bool wxWindowMac::OSXHandleKeyEvent( wxKeyEvent& event )
{
bool handled = false;
{
wxEvtHandler * const handler = ancestor->GetEventHandler();
- wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
+ wxCommandEvent command_event( wxEVT_MENU, command );
handled = handler->ProcessEvent( command_event );
if ( !handled )
{
// accelerators can also be used with buttons, try them too
- command_event.SetEventType(wxEVT_COMMAND_BUTTON_CLICKED);
+ command_event.SetEventType(wxEVT_BUTTON);
handled = handler->ProcessEvent( command_event );
}
// wxWidgetImpl
//
+// we are maintaining a n:1 map from native controls (ControlRef / NSView*) to their wxWidgetImpl
+// n:1 because we might have an embedded view eg within a scrollview, both being part of the same impl
+// the impl is calling Associate with its newly created native control(s), e.g. in InstallHandler
+
WX_DECLARE_HASH_MAP(WXWidget, wxWidgetImpl*, wxPointerHash, wxPointerEqual, MacControlMap);
static MacControlMap wxWinMacControlList;
{
return m_needsFrame;
}
+
+void wxWidgetImpl::SetDrawingEnabled(bool WXUNUSED(enabled))
+{
+}