From 0c530e5a6790a1789d8f857eb0c1d49b743833cd Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Thu, 15 Jan 2009 11:31:02 +0000 Subject: [PATCH] fixing controls with content areas, correcting radiobox layout git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58113 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/osx/cocoa/private.h | 39 +++++++++++-- src/osx/cocoa/statbox.mm | 2 +- src/osx/cocoa/textctrl.mm | 1 + src/osx/cocoa/window.mm | 100 +++++++++++++++++++++++++-------- src/osx/radiobox_osx.cpp | 22 +++++--- src/osx/window_osx.cpp | 4 +- 6 files changed, 130 insertions(+), 38 deletions(-) diff --git a/include/wx/osx/cocoa/private.h b/include/wx/osx/cocoa/private.h index de4b72ae46..d998d8950f 100644 --- a/include/wx/osx/cocoa/private.h +++ b/include/wx/osx/cocoa/private.h @@ -119,6 +119,7 @@ public : virtual bool DoHandleMouseEvent(NSEvent *event); virtual bool DoHandleKeyEvent(NSEvent *event); + virtual void DoNotifyFocusEvent(bool receivedFocus); protected: WXWidget m_osxView; @@ -199,7 +200,7 @@ protected : // common code snippets for cocoa implementations // later to be done using injection in method table - #define WXCOCOAIMPL_COMMON_MOUSE_INTERFACE -(void)mouseDown:(NSEvent *)event ;\ + #define WXCOCOAIMPL_COMMON_EVENTS_INTERFACE -(void)mouseDown:(NSEvent *)event ;\ -(void)rightMouseDown:(NSEvent *)event ;\ -(void)otherMouseDown:(NSEvent *)event ;\ -(void)mouseUp:(NSEvent *)event ;\ @@ -208,8 +209,10 @@ protected : - (void)keyDown:(NSEvent *)event;\ - (void)keyUp:(NSEvent *)event;\ - (void)flagsChanged:(NSEvent *)event;\ + - (BOOL) becomeFirstResponder;\ + - (BOOL) resignFirstResponder; - #define WXCOCOAIMPL_COMMON_MOUSE_IMPLEMENTATION -(void)mouseDown:(NSEvent *)event \ + #define WXCOCOAIMPL_COMMON_EVENTS_IMPLEMENTATION -(void)mouseDown:(NSEvent *)event \ {\ if ( !impl->DoHandleMouseEvent(event) )\ [super mouseDown:event];\ @@ -253,6 +256,20 @@ protected : {\ if ( !impl->DoHandleKeyEvent(event) )\ [super flagsChanged:event];\ + }\ + - (BOOL) becomeFirstResponder\ + {\ + BOOL r = [super becomeFirstResponder];\ + if ( r )\ + impl->DoNotifyFocusEvent( true );\ + return r;\ + }\ + - (BOOL) resignFirstResponder\ + {\ + BOOL r = [super resignFirstResponder];\ + if ( r )\ + impl->DoNotifyFocusEvent( false );\ + return r;\ } #define WXCOCOAIMPL_COMMON_MEMBERS wxWidgetCocoaImpl* impl; @@ -261,9 +278,9 @@ protected : - (void)setImplementation: (wxWidgetCocoaImpl *) theImplementation;\ - (wxWidgetCocoaImpl*) implementation;\ - (BOOL) isFlipped;\ - WXCOCOAIMPL_COMMON_MOUSE_INTERFACE + WXCOCOAIMPL_COMMON_EVENTS_INTERFACE - #define WXCOCOAIMPL_COMMON_IMPLEMENTATION WXCOCOAIMPL_COMMON_MOUSE_IMPLEMENTATION \ + #define WXCOCOAIMPL_COMMON_IMPLEMENTATION WXCOCOAIMPL_COMMON_EVENTS_IMPLEMENTATION \ - (void)setImplementation: (wxWidgetCocoaImpl *) theImplementation\ {\ impl = theImplementation;\ @@ -277,6 +294,20 @@ protected : return YES;\ }\ + #define WXCOCOAIMPL_COMMON_IMPLEMENTATION_NOT_FLIPPED WXCOCOAIMPL_COMMON_EVENTS_IMPLEMENTATION \ + - (void)setImplementation: (wxWidgetCocoaImpl *) theImplementation\ + {\ + impl = theImplementation;\ + }\ + - (wxWidgetCocoaImpl*) implementation\ + {\ + return impl;\ + }\ + - (BOOL) isFlipped\ + {\ + return NO;\ + }\ + // used for many wxControls @interface wxNSButton : NSButton diff --git a/src/osx/cocoa/statbox.mm b/src/osx/cocoa/statbox.mm index c05dc97365..34c2f27246 100644 --- a/src/osx/cocoa/statbox.mm +++ b/src/osx/cocoa/statbox.mm @@ -18,7 +18,7 @@ @implementation wxNSBox -WXCOCOAIMPL_COMMON_IMPLEMENTATION +WXCOCOAIMPL_COMMON_IMPLEMENTATION_NOT_FLIPPED @end diff --git a/src/osx/cocoa/textctrl.mm b/src/osx/cocoa/textctrl.mm index 61b8506db8..3e5b8d87e7 100644 --- a/src/osx/cocoa/textctrl.mm +++ b/src/osx/cocoa/textctrl.mm @@ -149,6 +149,7 @@ bool wxNSTextFieldControl::CanPaste() const void wxNSTextFieldControl::SetEditable(bool editable) { + [(wxNSTextField*) m_osxView setEditable:editable]; } void wxNSTextFieldControl::GetSelection( long* from, long* to) const diff --git a/src/osx/cocoa/window.mm b/src/osx/cocoa/window.mm index c50baa63a0..a21626cdb2 100644 --- a/src/osx/cocoa/window.mm +++ b/src/osx/cocoa/window.mm @@ -19,6 +19,10 @@ #include "wx/osx/private.h" #endif +#if wxUSE_CARET + #include "wx/caret.h" +#endif + NSRect wxOSXGetFrameForControl( wxWindowMac* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin ) { int x, y, w, h ; @@ -39,8 +43,6 @@ NSRect wxOSXGetFrameForControl( wxWindowMac* window , const wxPoint& pos , const WXCOCOAIMPL_COMMON_INTERFACE -- (BOOL) becomeFirstResponder; -- (BOOL) resignFirstResponder; - (BOOL) canBecomeKeyView; @end // wxNSView @@ -63,6 +65,8 @@ WXCOCOAIMPL_COMMON_INTERFACE - (void)setImage:(NSImage *)image; - (void)setControlSize:(NSControlSize)size; + +- (id)contentView; @end long wxOSXTranslateCocoaKey(unsigned short code, int unichar ) @@ -356,24 +360,6 @@ void SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEvent ) WXCOCOAIMPL_COMMON_IMPLEMENTATION -- (BOOL) becomeFirstResponder -{ - BOOL r = [super becomeFirstResponder]; - if ( r ) - { - } - return r; -} - -- (BOOL) resignFirstResponder -{ - BOOL r = [super resignFirstResponder]; - if ( r ) - { - } - return r; -} - - (BOOL) canBecomeKeyView { return YES; @@ -434,6 +420,15 @@ void wxWidgetCocoaImpl::ScrollRect( const wxRect *rect, int dx, int dy ) void wxWidgetCocoaImpl::Move(int x, int y, int width, int height) { + wxWindowMac* parent = GetWXPeer()->GetParent(); + // under Cocoa we might have a contentView in the wxParent to which we have to + // adjust the coordinates + if (parent) + { + wxPoint pt(parent->GetClientAreaOrigin()); + x -= pt.x; + y -= pt.y; + } NSRect r = wxToNSRect( [m_osxView superview], wxRect(x,y,width, height) ); [m_osxView setFrame:r]; } @@ -454,8 +449,27 @@ void wxWidgetCocoaImpl::GetSize( int &width, int &height ) const void wxWidgetCocoaImpl::GetContentArea( int&left, int &top, int &width, int &height ) const { - left = top = 0; - GetSize( width, height ); + if ( [m_osxView respondsToSelector:@selector(contentView) ] ) + { + NSView* cv = [m_osxView contentView]; + + NSRect bounds = [m_osxView bounds]; + NSRect rect = [cv frame]; + + int y = rect.origin.y; + int x = rect.origin.x; + if ( ![ m_osxView isFlipped ] ) + y = bounds.size.height - (rect.origin.y + rect.size.height); + left = x; + top = y; + width = rect.size.width; + height = rect.size.height; + } + else + { + left = top = 0; + GetSize( width, height ); + } } void wxWidgetCocoaImpl::SetNeedsDisplay( const wxRect* where ) @@ -670,6 +684,48 @@ bool wxWidgetCocoaImpl::DoHandleMouseEvent(NSEvent *event) return GetWXPeer()->HandleWindowEvent(wxevent); } +void wxWidgetCocoaImpl::DoNotifyFocusEvent(bool receivedFocus) +{ + wxWindow* thisWindow = GetWXPeer(); + if ( thisWindow->MacGetTopLevelWindow() && NeedsFocusRect() ) + { + thisWindow->MacInvalidateBorders(); + } + + if ( receivedFocus ) + { + wxLogTrace(_T("Focus"), _T("focus set(%p)"), static_cast(thisWindow)); + wxChildFocusEvent eventFocus((wxWindow*)thisWindow); + thisWindow->HandleWindowEvent(eventFocus); + +#if wxUSE_CARET + if ( thisWindow->GetCaret() ) + thisWindow->GetCaret()->OnSetFocus(); +#endif + + wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId()); + event.SetEventObject(thisWindow); + // TODO how to find out the targetFocusWindow ? + // event.SetWindow(targetFocusWindow); + thisWindow->HandleWindowEvent(event) ; + } + else // !receivedFocuss + { +#if wxUSE_CARET + if ( thisWindow->GetCaret() ) + thisWindow->GetCaret()->OnKillFocus(); +#endif + + wxLogTrace(_T("Focus"), _T("focus lost(%p)"), static_cast(thisWindow)); + + wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId()); + event.SetEventObject(thisWindow); + // TODO how to find out the targetFocusWindow ? + // event.SetWindow(targetFocusWindow); + thisWindow->HandleWindowEvent(event) ; + } +} + // // Factory methods diff --git a/src/osx/radiobox_osx.cpp b/src/osx/radiobox_osx.cpp index 6ad4a138f9..dec4feb9a1 100644 --- a/src/osx/radiobox_osx.cpp +++ b/src/osx/radiobox_osx.cpp @@ -399,7 +399,7 @@ void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags) { GetTextExtent(GetString(i), &eachWidth[i], &eachHeight[i] ); eachWidth[i] = (int)(eachWidth[i] + RADIO_SIZE); - eachHeight[i] = (int)((3 * eachHeight[i]) / 2); + eachHeight[i] = (int) eachHeight[i]; if (maxWidth < eachWidth[i]) maxWidth = eachWidth[i]; @@ -407,11 +407,11 @@ void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags) maxHeight = eachHeight[i]; } - totHeight = GetRowCount() * maxHeight; + totHeight = GetRowCount() * maxHeight + (GetRowCount() - 1) * maxHeight / 2; totWidth = GetColumnCount() * (maxWidth + charWidth); wxSize sz = DoGetSizeFromClientSize( wxSize( totWidth, totHeight ) ) ; - + // change the width / height only when specified if ( width == wxDefaultCoord ) { @@ -434,8 +434,8 @@ void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags) // arrange radio buttons int x_start, y_start; - x_start = 0; - y_start = 0; + x_start = ( width - sz.x ) / 2; + y_start = ( height - sz.y ) / 2; x_offset = x_start; y_offset = y_start; @@ -454,7 +454,7 @@ void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags) else { x_offset = x_start; - y_offset += maxHeight ; //+ charHeight / 2 + y_offset += 3 * maxHeight / 2 ; //+ charHeight / 2 } } @@ -462,7 +462,7 @@ void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags) current = current->NextInCycle(); if (m_windowStyle & wxRA_SPECIFY_ROWS) - y_offset += maxHeight ; // + charHeight / 2 + y_offset += 3 * maxHeight / 2 ; // + charHeight / 2 else x_offset += maxWidth + charWidth; } @@ -489,19 +489,23 @@ wxSize wxRadioBox::DoGetBestSize() const { GetTextExtent(GetString(i), &eachWidth, &eachHeight, NULL, NULL, &font ); eachWidth = (int)(eachWidth + RADIO_SIZE); - eachHeight = (int)((3 * eachHeight) / 2); + eachHeight = (int)eachHeight; if (maxWidth < eachWidth) maxWidth = eachWidth; if (maxHeight < eachHeight) maxHeight = eachHeight; } - totHeight = GetRowCount() * maxHeight; + totHeight = GetRowCount() * maxHeight + (GetRowCount() - 1) * maxHeight / 2; totWidth = GetColumnCount() * (maxWidth + charWidth); wxSize sz = DoGetSizeFromClientSize( wxSize( totWidth, totHeight ) ); totWidth = sz.x; totHeight = sz.y; + + // optimum size is an additional 5 pt border to all sides + totWidth += 10; + totHeight += 10; // handle radio box title as well GetTextExtent( GetLabel(), &eachWidth, NULL ); diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index 9c41ef1189..ac75853aa4 100644 --- a/src/osx/window_osx.cpp +++ b/src/osx/window_osx.cpp @@ -674,8 +674,8 @@ wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const m_peer->GetContentArea( left, top, innerwidth, innerheight ); m_peer->GetSize( outerwidth, outerheight ); - sizeTotal.x += left + (outerwidth-innerwidth); - sizeTotal.y += top + (outerheight-innerheight); + sizeTotal.x += outerwidth-innerwidth; + sizeTotal.y += outerheight-innerheight; sizeTotal.x += MacGetLeftBorderSize() + MacGetRightBorderSize() ; sizeTotal.y += MacGetTopBorderSize() + MacGetBottomBorderSize() ; -- 2.45.2