]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/window.cpp
Add the unified style on OS X 10.4, and default to using it.
[wxWidgets.git] / src / mac / carbon / window.cpp
index e6a954fa299aaa4b68d9fc6489c0827a03469884..56d06a2612a666cc42619e312ebcbe1ca1f4623c 100644 (file)
     #include "wx/layout.h"
     #include "wx/statusbr.h"
     #include "wx/menuitem.h"
     #include "wx/layout.h"
     #include "wx/statusbr.h"
     #include "wx/menuitem.h"
+    #include "wx/treectrl.h"
+    #include "wx/listctrl.h"
 #endif
 
 #include "wx/tooltip.h"
 #include "wx/spinctrl.h"
 #include "wx/geometry.h"
 
 #endif
 
 #include "wx/tooltip.h"
 #include "wx/spinctrl.h"
 #include "wx/geometry.h"
 
+#if wxUSE_LISTCTRL
+    #include "wx/listctrl.h"
+#endif
+
+#if wxUSE_TREECTRL
+    #include "wx/treectrl.h"
+#endif
+
 #if wxUSE_CARET
     #include "wx/caret.h"
 #endif
 #if wxUSE_CARET
     #include "wx/caret.h"
 #endif
@@ -156,6 +166,7 @@ static const EventTypeSpec eventList[] =
     { kEventClassCommand, kEventProcessCommand } ,
     { kEventClassCommand, kEventCommandUpdateStatus } ,
 
     { kEventClassCommand, kEventProcessCommand } ,
     { kEventClassCommand, kEventCommandUpdateStatus } ,
 
+    { kEventClassControl , kEventControlGetClickActivation } ,
     { kEventClassControl , kEventControlHit } ,
 
     { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } ,
     { kEventClassControl , kEventControlHit } ,
 
     { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } ,
@@ -166,6 +177,9 @@ static const EventTypeSpec eventList[] =
     { kEventClassControl , kEventControlVisibilityChanged } ,
     { kEventClassControl , kEventControlEnabledStateChanged } ,
     { kEventClassControl , kEventControlHiliteChanged } ,
     { kEventClassControl , kEventControlVisibilityChanged } ,
     { kEventClassControl , kEventControlEnabledStateChanged } ,
     { kEventClassControl , kEventControlHiliteChanged } ,
+
+    { kEventClassControl , kEventControlActivate } ,
+    { kEventClassControl , kEventControlDeactivate } ,
 #endif
     { kEventClassControl , kEventControlSetFocusPart } ,
 
 #endif
     { kEventClassControl , kEventControlSetFocusPart } ,
 
@@ -293,7 +307,20 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl
         case kEventControlHiliteChanged :
             thisWindow->MacHiliteChanged() ;
             break ;
         case kEventControlHiliteChanged :
             thisWindow->MacHiliteChanged() ;
             break ;
+            
+        case kEventControlActivate :
+        case kEventControlDeactivate :
+            // FIXME: we should have a virtual function for this!
+#if wxUSE_TREECTRL
+            if ( thisWindow->IsKindOf( CLASSINFO( wxTreeCtrl ) ) )
+                thisWindow->Refresh();
+#endif
+#if wxUSE_LISTCTRL
+            if ( thisWindow->IsKindOf( CLASSINFO( wxListCtrl ) ) )
+                thisWindow->Refresh();
 #endif
 #endif
+            break ;
+#endif // TARGET_API_MAC_OSX
 
         // we emulate this event under Carbon CFM
         case kEventControlSetFocusPart :
 
         // we emulate this event under Carbon CFM
         case kEventControlSetFocusPart :
@@ -307,6 +334,9 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl
                 }
 #endif
 
                 }
 #endif
 
+                if ( thisWindow->MacIsUserPane() )
+                    result = noErr ;
+
                 if ( controlPart == kControlFocusNoPart )
                 {
 #if wxUSE_CARET
                 if ( controlPart == kControlFocusNoPart )
                 {
 #if wxUSE_CARET
@@ -340,9 +370,6 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl
                     event.SetEventObject(thisWindow);
                     thisWindow->GetEventHandler()->ProcessEvent(event) ;
                 }
                     event.SetEventObject(thisWindow);
                     thisWindow->GetEventHandler()->ProcessEvent(event) ;
                 }
-
-                if ( thisWindow->MacIsUserPane() )
-                    result = noErr ;
             }
             break ;
 
             }
             break ;
 
@@ -350,6 +377,18 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl
             result = thisWindow->MacControlHit( handler , event ) ;
             break ;
 
             result = thisWindow->MacControlHit( handler , event ) ;
             break ;
 
+        case kEventControlGetClickActivation :
+            {
+               // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
+                WindowRef owner = cEvent.GetParameter<WindowRef>(kEventParamWindowRef);
+                if ( !IsWindowActive(owner) )
+                {
+                    cEvent.SetParameter(kEventParamClickActivation,(UInt32) kActivateAndIgnoreClick) ;
+                    result = noErr ;
+                }
+            }
+            break ;
+
         default :
             break ;
     }
         default :
             break ;
     }
@@ -472,7 +511,7 @@ pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , Even
         charBuf[ numChars - 1 ] = 0;
 #if SIZEOF_WCHAR_T == 2
         uniChars = (wchar_t*) charBuf ;
         charBuf[ numChars - 1 ] = 0;
 #if SIZEOF_WCHAR_T == 2
         uniChars = (wchar_t*) charBuf ;
-        memcpy( uniChars , charBuf , numChars * 2 ) ;
+/*        memcpy( uniChars , charBuf , numChars * 2 ) ;*/      // is there any point in copying charBuf over itself? (in fact, memcpy isn't even guaranteed to work correctly if the source and destination ranges overlap...)
 #else
         // the resulting string will never have more chars than the utf16 version, so this is safe
         wxMBConvUTF16 converter ;
 #else
         // the resulting string will never have more chars than the utf16 version, so this is safe
         wxMBConvUTF16 converter ;
@@ -492,7 +531,32 @@ pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , Even
                     WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
                     wxTheApp->MacSetCurrentEvent( event , handler ) ;
 
                     WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
                     wxTheApp->MacSetCurrentEvent( event , handler ) ;
 
+                    UInt32 message = uniChars[pos] < 128 ? (char)uniChars[pos] : '?';
+/*
+       NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
+       multiple times to update the active range during inline input, so this handler will often receive
+       uncommited text, which should usually not trigger side effects. It might be a good idea to check the
+       kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
+       On the other hand, it can be useful for some applications to react to uncommitted text (for example,
+       to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
+       should add new event types to support advanced text input. For now, I would keep things as they are.
+       
+       However, the code that was being used caused additional problems:
                     UInt32 message = (0  << 8) + ((char)uniChars[pos] );
                     UInt32 message = (0  << 8) + ((char)uniChars[pos] );
+       Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
+       input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
+       for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
+       (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
+       (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
+       Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
+       overlap with Unicode within the (7-bit) ASCII range.
+       But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
+       for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
+       characters as they are and replaces the rest with '?', ensuring that update events are triggered.
+       It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
+       I don't have time to look into that right now.
+               -- CL
+*/
                     if ( wxTheApp->MacSendCharEvent(
                                                     focus , message , 0 , when , 0 , 0 , uniChars[pos] ) )
                     {
                     if ( wxTheApp->MacSendCharEvent(
                                                     focus , message , 0 , when , 0 , 0 , uniChars[pos] ) )
                     {
@@ -898,10 +962,6 @@ void wxWindowMac::Init()
     m_frozenness = 0 ;
     m_macAlpha = 255 ;
 
     m_frozenness = 0 ;
     m_macAlpha = 255 ;
 
-#if WXWIN_COMPATIBILITY_2_4
-    m_backgroundTransparent = false;
-#endif
-
 #if wxMAC_USE_CORE_GRAPHICS
     m_cgContextRef = NULL ;
 #endif
 #if wxMAC_USE_CORE_GRAPHICS
     m_cgContextRef = NULL ;
 #endif
@@ -1095,7 +1155,7 @@ void wxWindowMac::MacPostControlCreate(const wxPoint& pos, const wxSize& size)
     m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ;
 
     if (!m_macIsUserPane)
     m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ;
 
     if (!m_macIsUserPane)
-        SetInitialBestSize(size);
+        SetInitialSize(size);
 
     SetCursor( *wxSTANDARD_CURSOR ) ;
 }
 
     SetCursor( *wxSTANDARD_CURSOR ) ;
 }
@@ -1661,10 +1721,10 @@ void wxWindowMac::DoGetClientSize( int *x, int *y ) const
 
 bool wxWindowMac::SetCursor(const wxCursor& cursor)
 {
 
 bool wxWindowMac::SetCursor(const wxCursor& cursor)
 {
-    if (m_cursor == cursor)
+    if (m_cursor.IsSameAs(cursor))
         return false;
 
         return false;
 
-    if (wxNullCursor == cursor)
+    if (!cursor.IsOk())
     {
         if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) )
             return false ;
     {
         if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) )
             return false ;
@@ -2079,19 +2139,9 @@ bool wxWindowMac::Show(bool show)
     return true;
 }
 
     return true;
 }
 
-bool wxWindowMac::Enable(bool enable)
+void wxWindowMac::DoEnable(bool enable)
 {
 {
-    wxASSERT( m_peer->Ok() ) ;
-    bool former = MacIsReallyEnabled() ;
-    if ( !wxWindowBase::Enable(enable) )
-        return false;
-
     m_peer->Enable( enable ) ;
     m_peer->Enable( enable ) ;
-
-    if ( former != MacIsReallyEnabled() )
-        MacPropagateEnabledStateChanged() ;
-
-    return true;
 }
 
 //
 }
 
 //
@@ -2116,21 +2166,10 @@ void wxWindowMac::MacPropagateVisibilityChanged()
 #endif
 }
 
 #endif
 }
 
-void wxWindowMac::MacPropagateEnabledStateChanged()
+void wxWindowMac::OnEnabled(bool enabled)
 {
 #if !TARGET_API_MAC_OSX
     MacEnabledStateChanged() ;
 {
 #if !TARGET_API_MAC_OSX
     MacEnabledStateChanged() ;
-
-    wxWindowMac *child;
-    wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
-    while ( node )
-    {
-        child = node->GetData();
-        if ( child->IsEnabled() )
-            child->MacPropagateEnabledStateChanged() ;
-
-        node = node->GetNext();
-    }
 #endif
 }
 
 #endif
 }
 
@@ -2236,7 +2275,7 @@ void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y,
         fontToUse = &m_font;
 
     wxClientDC dc( (wxWindowMac*) this ) ;
         fontToUse = &m_font;
 
     wxClientDC dc( (wxWindowMac*) this ) ;
-    long lx,ly,ld,le ;
+    wxCoord lx,ly,ld,le ;
     dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ;
     if ( externalLeading )
         *externalLeading = le ;
     dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ;
     if ( externalLeading )
         *externalLeading = le ;
@@ -2301,6 +2340,11 @@ void wxWindowMac::Thaw()
 #endif
 }
 
 #endif
 }
 
+bool wxWindowMac::IsFrozen() const
+{
+    return m_frozenness != 0;
+}
+
 wxWindowMac *wxGetActiveWindow()
 {
     // actually this is a windows-only concept
 wxWindowMac *wxGetActiveWindow()
 {
     // actually this is a windows-only concept
@@ -2566,6 +2610,7 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
         if ( m_peer->GetNeedsDisplay() )
         {
             // because HIViewScrollRect does not scroll the already invalidated area we have two options:
         if ( m_peer->GetNeedsDisplay() )
         {
             // because HIViewScrollRect does not scroll the already invalidated area we have two options:
+            // in case there is already a pending redraw on that area
             // either immediate redraw or full invalidate
 #if 1
             // is the better overall solution, as it does not slow down scrolling
             // either immediate redraw or full invalidate
 #if 1
             // is the better overall solution, as it does not slow down scrolling
@@ -2586,14 +2631,8 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
         scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
         m_peer->ScrollRect( &scrollrect , dx , dy ) ;
 
         scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
         m_peer->ScrollRect( &scrollrect , dx , dy ) ;
 
-        // becuase HIViewScrollRect does not scroll the already invalidated area we have two options
-        // either immediate redraw or full invalidate
 #if 0
 #if 0
-        // is the better overall solution, as it does not slow down scrolling
-        m_peer->SetNeedsDisplay() ;
-#else
         // this would be the preferred version for fast drawing controls
         // this would be the preferred version for fast drawing controls
-
         HIViewRender(m_peer->GetControlRef()) ;
 #endif
     }
         HIViewRender(m_peer->GetControlRef()) ;
 #endif
     }
@@ -2618,11 +2657,11 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
         {
             wxRect rc( x, y, w, h );
             if (rect->Intersects( rc ))
         {
             wxRect rc( x, y, w, h );
             if (rect->Intersects( rc ))
-                child->SetSize( x + dx, y + dy, w, h );
+                child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE );
         }
         else
         {
         }
         else
         {
-            child->SetSize( x + dx, y + dy, w, h );
+            child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE );
         }
     }
 }
         }
     }
 }
@@ -2687,7 +2726,7 @@ void wxWindowMac::OnSetFocus( wxFocusEvent& event )
         Rect rect ;
 
         m_peer->GetRect( &rect ) ;
         Rect rect ;
 
         m_peer->GetRect( &rect ) ;
-        // auf den umgebenden Rahmen zur\9fck
+        // auf den umgebenden Rahmen zur\81Â\9fck
         InsetRect( &rect, -1 , -1 ) ;
 
         wxTopLevelWindowMac* top = MacGetTopLevelWindow();
         InsetRect( &rect, -1 , -1 ) ;
 
         wxTopLevelWindowMac* top = MacGetTopLevelWindow();