]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/tooltip.cpp
The Great wxRegion Refactoring:
[wxWidgets.git] / src / mac / carbon / tooltip.cpp
index 45877f9a1c3098cc472a71a79e22aa9c77159219..122c76b623d0c5574b8aaf8f80ad7a8dee97d872 100644 (file)
@@ -1,71 +1,81 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        tooltip.cpp
+// Name:        src/mac/carbon/tooltip.cpp
 // Purpose:     wxToolTip implementation
-// Author:      Robert Roebling
+// Author:      Stefan Csomor
 // Id:          $Id$
-// Copyright:   (c) 1998 Robert Roebling
+// Copyright:   (c) Stefan Csomor
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-    #pragma implementation "tooltip.h"
-#endif
-
-#include "wx/setup.h"
+#include "wx/wxprec.h"
 
 #if wxUSE_TOOLTIPS
 
-#include "wx/app.h"
-#include "wx/dc.h"
-#include "wx/window.h"
 #include "wx/tooltip.h"
-#include "wx/timer.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/app.h"
+    #include "wx/window.h"
+    #include "wx/dc.h"
+    #include "wx/timer.h"
+#endif // WX_PRECOMP
+
 #include "wx/geometry.h"
-#include "wx/mac/aga.h"
 #include "wx/mac/uma.h"
 
 //-----------------------------------------------------------------------------
 // global data
 //-----------------------------------------------------------------------------
 
+class wxMacToolTipTimer ;
+
 class wxMacToolTip
 {
-       public :
-               wxMacToolTip( ) ;
-               ~wxMacToolTip() ;
-               
-               void                    Setup( WindowRef window  , wxString text , wxPoint localPosition ) ;
-               long                    GetMark() { return m_mark ; }
-               void                    Draw() ;
-               void                    Clear() ;
-               bool                    IsShown() { return m_shown  ; }
-       private :
-               
-               wxString        m_label ;
-               wxPoint m_position ;
-               Rect                    m_rect ;
-               WindowRef       m_window ;      
-               PicHandle       m_backpict ;
-               bool            m_shown ;
-               long            m_mark ;
+public :
+    wxMacToolTip() ;
+    ~wxMacToolTip() ;
+
+    void Setup( WindowRef window , const wxString& text , const wxPoint& localPosition ) ;
+    void Draw() ;
+    void Clear() ;
+
+    long GetMark()
+    { return m_mark ; }
+
+    bool IsShown()
+    { return m_shown ; }
+
+private :
+    wxString    m_label ;
+    wxPoint m_position ;
+    Rect            m_rect ;
+    WindowRef    m_window ;
+    PicHandle    m_backpict ;
+    bool        m_shown ;
+    long        m_mark ;
+    wxMacToolTipTimer* m_timer ;
+
+#if TARGET_CARBON
+    wxMacCFStringHolder m_helpTextRef ;
+#endif
 } ;
 
-class wxMacToolTipTimer : wxTimer
+class wxMacToolTipTimer : public wxTimer
 {
 public:
-       wxMacToolTipTimer(wxMacToolTip* tip, int iMilliseconds) ;
+    wxMacToolTipTimer(wxMacToolTip* tip, int iMilliseconds) ;
+    wxMacToolTipTimer() {} ;
+    virtual ~wxMacToolTipTimer() {} ;
 
-       void Notify()
-       {
-               if ( m_mark == m_tip->GetMark() )
-                       m_tip->Draw() ;
+    void Notify()
+    {
+        if ( m_mark == m_tip->GetMark() )
+            m_tip->Draw() ;
+    }
 
-               delete this;
-       }
-       
 protected:
-       wxMacToolTip*   m_tip;
-       long                    m_mark ;
+    wxMacToolTip*     m_tip;
+    long        m_mark ;
 };
 
 //-----------------------------------------------------------------------------
@@ -77,6 +87,10 @@ static wxMacToolTip s_ToolTip ;
 static wxWindow* s_LastWindowEntered = NULL ;
 static wxRect2DInt s_ToolTipArea ;
 static WindowRef s_ToolTipWindowRef = NULL ;
+
+IMPLEMENT_ABSTRACT_CLASS(wxToolTip, wxObject)
+
+
 wxToolTip::wxToolTip( const wxString &tip )
 {
     m_text = tip;
@@ -89,114 +103,128 @@ wxToolTip::~wxToolTip()
 
 void wxToolTip::SetTip( const wxString &tip )
 {
-     m_text = tip;
+    m_text = tip;
 
     if ( m_window )
     {
-       /*
-        // update it immediately
-        wxToolInfo ti(GetHwndOf(m_window));
-        ti.lpszText = (wxChar *)m_text.c_str();
+#if 0
+    // update it immediately
+    wxToolInfo ti(GetHwndOf(m_window));
+    ti.lpszText = (wxChar *)m_text.c_str();
 
-        (void)SendTooltipMessage(GetToolTipCtrl(), TTM_UPDATETIPTEXT, 0, &ti);
-        */
+    (void)SendTooltipMessage(GetToolTipCtrl(), TTM_UPDATETIPTEXT, 0, &ti);
+#endif
     }
 }
 
 void wxToolTip::SetWindow( wxWindow *win )
 {
-    m_window = win;
+    m_window = win ;
 }
 
 void wxToolTip::Enable( bool flag )
 {
-       if ( s_ShowToolTips != flag )
-       {
-               s_ShowToolTips = flag ;
-               if ( s_ShowToolTips )
-               {
-               }
-               else
-               {
-                       s_ToolTip.Clear() ;
-               }
-       }
+    if ( s_ShowToolTips != flag )
+    {
+        s_ShowToolTips = flag ;
+
+        if ( s_ShowToolTips )
+        {
+        }
+        else
+        {
+            s_ToolTip.Clear() ;
+        }
+    }
 }
 
 void wxToolTip::SetDelay( long msecs )
 {
-       s_ToolTipDelay = msecs ;
+    s_ToolTipDelay = msecs ;
 }
 
 void wxToolTip::RelayEvent( wxWindow *win , wxMouseEvent &event )
 {
-       if ( s_ShowToolTips )
-       {
-               if ( event.GetEventType() == wxEVT_LEAVE_WINDOW )
-               {
-                       s_ToolTip.Clear() ;
-               }
-               else if (event.GetEventType() == wxEVT_ENTER_WINDOW || event.GetEventType() == wxEVT_MOTION )
-               {
-                       wxPoint2DInt where( event.m_x , event.m_y ) ;
-                       if ( s_LastWindowEntered == win && s_ToolTipArea.Contains( where ) )
-                       {
-                       }
-                       else
-                       {
-                               s_ToolTip.Clear() ;
-                               s_ToolTipArea = wxRect2DInt( event.m_x - 2 , event.m_y - 2 , 4 , 4 ) ;
-                               s_LastWindowEntered = win ;
-                               
-                               WindowRef window = win->MacGetRootWindow() ;
-                               int x = event.m_x ;
-                               int y = event.m_y ;
-                               wxPoint local( x , y ) ;
-                               win->MacClientToRootWindow( &x, &y ) ;
-                               wxPoint windowlocal( x , y ) ;
-                               s_ToolTip.Setup( window , win->MacGetToolTipString( local ) , windowlocal ) ;
-                       }
-               }
-       }
+    if ( s_ShowToolTips )
+    {
+        if ( event.GetEventType() == wxEVT_LEAVE_WINDOW )
+        {
+            s_ToolTip.Clear() ;
+        }
+        else if (event.GetEventType() == wxEVT_ENTER_WINDOW || event.GetEventType() == wxEVT_MOTION )
+        {
+            wxPoint2DInt where( event.m_x , event.m_y ) ;
+            if ( s_LastWindowEntered == win && s_ToolTipArea.Contains( where ) )
+            {
+            }
+            else
+            {
+                s_ToolTip.Clear() ;
+                s_ToolTipArea = wxRect2DInt( event.m_x - 2 , event.m_y - 2 , 4 , 4 ) ;
+                s_LastWindowEntered = win ;
+
+                WindowRef window = MAC_WXHWND( win->MacGetTopLevelWindowRef() ) ;
+                int x = event.m_x ;
+                int y = event.m_y ;
+                wxPoint local( x , y ) ;
+                win->MacClientToRootWindow( &x, &y ) ;
+                wxPoint windowlocal( x , y ) ;
+                s_ToolTip.Setup( window , win->MacGetToolTipString( local ) , windowlocal ) ;
+            }
+        }
+    }
 }
 
 void wxToolTip::RemoveToolTips()
 {
-       s_ToolTip.Clear() ;
+    s_ToolTip.Clear() ;
 }
+
 // --- mac specific
 
 wxMacToolTipTimer::wxMacToolTipTimer( wxMacToolTip *tip , int msec )
 {
-       m_tip = tip;
-       m_mark = tip->GetMark() ;
-       Start(msec, true);
+    m_tip = tip;
+    m_mark = tip->GetMark() ;
+    Start(msec, true);
 }
 
 wxMacToolTip::wxMacToolTip()
 {
-       m_window = NULL ;
-       m_backpict = NULL ;
-       m_mark = 0 ;
-       m_shown = false ;
+    m_window = NULL ;
+    m_backpict = NULL ;
+    m_timer = NULL ;
+    m_mark = 0 ;
+    m_shown = false ;
 }
 
-void wxMacToolTip::Setup( WindowRef window  , wxString text , wxPoint localPosition ) 
+void wxMacToolTip::Setup( WindowRef win  , const wxString& text , const wxPoint& localPosition )
 {
-       m_mark++ ;
-       Clear() ;
-       m_position = localPosition ; 
-       m_label = wxMacMakeMacStringFromPC( text ) ;
-       m_window = window ;
-       s_ToolTipWindowRef = window ;
-       m_backpict = NULL ;
-       new wxMacToolTipTimer( this , s_ToolTipDelay ) ;
+    m_mark++ ;
+
+    Clear() ;
+    m_position = localPosition ;
+    m_label = text ;
+    m_window =win;
+    s_ToolTipWindowRef = m_window ;
+    m_backpict = NULL ;
+
+    if ( m_timer )
+        delete m_timer ;
+
+    m_timer = new wxMacToolTipTimer( this , s_ToolTipDelay ) ;
 }
 
-wxMacToolTip::~wxMacToolTip() 
+wxMacToolTip::~wxMacToolTip()
 {
-       if ( m_backpict ) 
-               Clear() ;
+    if ( m_timer )
+    {
+        delete m_timer ;
+        m_timer = NULL;
+    }
+
+    if ( m_backpict )
+        Clear() ;
 }
 
 const short kTipBorder = 2 ;
@@ -204,141 +232,197 @@ const short kTipOffset = 5 ;
 
 void wxMacToolTip::Draw()
 {
-       if ( m_label.Length() == 0 )
-               return ;
-               
-       if ( m_window == s_ToolTipWindowRef )
-       {
+    if ( m_label.empty() )
+        return ;
+
+    if ( m_window == s_ToolTipWindowRef )
+    {
+        m_shown = true ;
+
 #if TARGET_CARBON
-/*
-         if ( HMDisplayTag != (void*) kUnresolvedCFragSymbolAddress )
-         {
-           HMDisplayTag( 
-         }
-         else
-*/
+        HMHelpContentRec tag ;
+        tag.version = kMacHelpVersion;
+        SetRect( &tag.absHotRect , m_position.x - 2 , m_position.y - 2 , m_position.x + 2 , m_position.y + 2 ) ;
+
+        QDLocalToGlobalRect( GetWindowPort( m_window ) , &tag.absHotRect ) ;
+
+        m_helpTextRef.Assign( m_label , wxFONTENCODING_DEFAULT ) ;
+        tag.content[kHMMinimumContentIndex].contentType = kHMCFStringContent ;
+        tag.content[kHMMinimumContentIndex].u.tagCFString = m_helpTextRef ;
+        tag.content[kHMMaximumContentIndex].contentType = kHMCFStringContent ;
+        tag.content[kHMMaximumContentIndex].u.tagCFString = m_helpTextRef ;
+        tag.tagSide = kHMDefaultSide;
+        HMDisplayTag( &tag );
+#else
+        wxMacPortStateHelper help( (GrafPtr)GetWindowPort( m_window ) );
+        FontFamilyID fontId ;
+        Str255 fontName ;
+        SInt16 fontSize ;
+        Style fontStyle ;
+        GetThemeFont( kThemeSmallSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;
+        GetFNum( fontName, &fontId );
+
+        TextFont( fontId ) ;
+        TextSize( fontSize ) ;
+        TextFace( fontStyle ) ;
+        FontInfo fontInfo;
+        ::GetFontInfo(&fontInfo);
+        short lineh = fontInfo.ascent + fontInfo.descent + fontInfo.leading;
+        short height = 0 ;
+
+        int i = 0 ;
+        int length = m_label.length() ;
+        int width = 0 ;
+        int thiswidth = 0 ;
+        int laststop = 0 ;
+        wxCharBuffer text = m_label.mb_str( wxConvLocal ) ;
+
+        while ( i < length )
+        {
+            if ( text[i] == 13 || text[i] == 10)
+            {
+                thiswidth = ::TextWidth( text , laststop , i - laststop ) ;
+                if ( thiswidth > width )
+                    width = thiswidth ;
+
+                height += lineh ;
+                laststop = i + 1 ;
+            }
+
+            i++ ;
+        }
+
+        if ( i - laststop > 0 )
+        {
+            thiswidth = ::TextWidth( text , laststop , i - laststop ) ;
+            if ( thiswidth > width )
+                width = thiswidth ;
+            height += lineh ;
+        }
+
+        m_rect.left = m_position.x + kTipOffset;
+        m_rect.top = m_position.y + kTipOffset;
+        m_rect.right = m_rect.left + width + 2 * kTipBorder;
+
+        m_rect.bottom = m_rect.top + height + 2 * kTipBorder;
+        Rect r ;
+
+        GetPortBounds( GetWindowPort( m_window ) , &r ) ;
+        if ( m_rect.top < 0 )
+        {
+            m_rect.bottom += -m_rect.top ;
+            m_rect.top = 0 ;
+        }
+        if ( m_rect.left < 0 )
+        {
+            m_rect.right += -m_rect.left ;
+            m_rect.left = 0 ;
+        }
+        if ( m_rect.right > r.right )
+        {
+            m_rect.left -= (m_rect.right - r.right ) ;
+            m_rect.right = r.right ;
+        }
+        if ( m_rect.bottom > r.bottom )
+        {
+            m_rect.top -= (m_rect.bottom - r.bottom) ;
+            m_rect.bottom = r.bottom ;
+        }
+
+        GWorldPtr port ;
+        CGrafPtr  origPort ;
+        GDHandle  origDevice ;
+
+        ClipRect( &m_rect ) ;
+        BackColor( whiteColor ) ;
+        ForeColor(blackColor ) ;
+        NewGWorld( &port , wxDisplayDepth() , &m_rect , NULL , NULL , 0 ) ;
+
+        GetGWorld( &origPort , &origDevice ) ;
+        SetGWorld( port , NULL ) ;
+
+        m_backpict = OpenPicture(&m_rect);
+
+        CopyBits(GetPortBitMapForCopyBits(GetWindowPort(m_window)),
+            GetPortBitMapForCopyBits(port),
+            &m_rect,
+            &m_rect,
+            srcCopy,
+            NULL);
+        ClosePicture();
+        SetGWorld( origPort , origDevice ) ;
+        DisposeGWorld( port ) ;
+        PenNormal() ;
+
+        RGBColor tooltipbackground = { 0xFFFF , 0xFFFF , 0xC000 } ;
+        BackColor( whiteColor ) ;
+        RGBForeColor( &tooltipbackground ) ;
+
+        PaintRect( &m_rect ) ;
+        ForeColor(blackColor ) ;
+        FrameRect( &m_rect ) ;
+        SetThemeTextColor(kThemeTextColorNotification,wxDisplayDepth(),true) ;
+        ::MoveTo( m_rect.left + kTipBorder , m_rect.top + fontInfo.ascent + kTipBorder);
+
+        i = 0 ;
+        laststop = 0 ;
+        height = 0 ;
+
+        while ( i < length )
+        {
+            if ( text[i] == 13 || text[i] == 10)
+            {
+                ::DrawText( text , laststop , i - laststop ) ;
+                height += lineh ;
+                ::MoveTo( m_rect.left + kTipBorder , m_rect.top + fontInfo.ascent + kTipBorder + height );
+                laststop = i+1 ;
+            }
+
+            i++ ;
+        }
+
+        ::DrawText( text , laststop , i - laststop ) ;
+        ::TextMode( srcOr ) ;
 #endif
-         {
-               #if TARGET_CARBON
-               AGAPortHelper help( GetWindowPort( m_window ) );
-               #else
-               AGAPortHelper help( ( m_window ) );
-               #endif
-               m_shown = true ;
-
-               TextFont( kFontIDGeneva ) ;
-               TextSize( 10 ) ;
-               TextFace( 0 ) ;
-               FontInfo fontInfo;
-               ::GetFontInfo(&fontInfo);
-               short lineh = fontInfo.ascent + fontInfo.descent + fontInfo.leading;
-               short height = 0 ;
-       //      short width = TextWidth( m_label , 0 ,m_label.Length() ) ;
-               
-               int i = 0 ;
-               int length = m_label.Length() ;
-               int width = 0 ;
-               int thiswidth = 0 ;
-               int laststop = 0 ;
-               const char *text = m_label ;
-               while( i < length )
-               {
-                       if( text[i] == 13 || text[i] == 10)
-                       {
-                               thiswidth = ::TextWidth( text , laststop , i - laststop ) ;
-                               if ( thiswidth > width )
-                                       width = thiswidth ;
-                                       
-                               height += lineh ;
-                               laststop = i+1 ;
-                       }
-                       i++ ;
-               }
-               if ( i - laststop > 0 )
-               {
-                       thiswidth = ::TextWidth( text , laststop , i - laststop ) ;
-                       if ( thiswidth > width )
-                               width = thiswidth ;
-                       height += lineh ;
-               }
-
-
-               m_rect.left = m_position.x + kTipOffset;
-               m_rect.top = m_position.y + kTipOffset;
-               m_rect.right = m_rect.left + width + 2 * kTipBorder;
-               m_rect.bottom = m_rect.top + height + 2 * kTipBorder;
-               ClipRect( &m_rect ) ;
-               BackColor( whiteColor ) ;
-               ForeColor(blackColor ) ;
-               m_backpict = OpenPicture(&m_rect);
-
-               CopyBits(GetPortBitMapForCopyBits(GetWindowPort(m_window)), 
-                                  GetPortBitMapForCopyBits(GetWindowPort(m_window)), 
-                                  &m_rect, 
-                                  &m_rect, 
-                                  srcCopy, 
-                                  NULL);
-
-               ClosePicture();
-      PenNormal() ;
-               SetThemeBackground(kThemeBrushNotificationWindowBackground,32,true) ;
-               SetThemeTextColor(kThemeTextColorNotification,32,true) ;
-               EraseRect( &m_rect ) ;
-               FrameRect( &m_rect ) ;
-               ::MoveTo( m_rect.left + kTipBorder , m_rect.top + fontInfo.ascent + kTipBorder);
-
-               i = 0 ;
-               laststop = 0 ;
-               height = 0 ;
-               while( i < length )
-               {
-                       if( text[i] == 13 || text[i] == 10)
-                       {
-                               ::DrawText( text , laststop , i - laststop ) ;
-                               height += lineh ;
-                               ::MoveTo( m_rect.left + kTipBorder , m_rect.top + fontInfo.ascent + kTipBorder + height );
-                               laststop = i+1 ;
-                       }
-                       i++ ;
-               }
-                                       
-               ::DrawText( text , laststop , i - laststop ) ;
-               ::TextMode( srcOr ) ;           
-       //      DrawText( m_label , 0 , m_label.Length() ) ;
-       }
-       }
+    }
 }
 
-void wxToolTip::NotifyWindowDelete( WindowRef win ) 
+void wxToolTip::NotifyWindowDelete( WXHWND win )
 {
-       if ( win == s_ToolTipWindowRef )
-       {
-               s_ToolTipWindowRef = NULL ;
-       }
+    if ( win == s_ToolTipWindowRef )
+        s_ToolTipWindowRef = NULL ;
 }
 
 void wxMacToolTip::Clear()
 {
-       m_mark++ ;
-       if ( !m_shown )
-               return ;
-                
-       if ( m_window == s_ToolTipWindowRef && m_backpict )
-       {
-               #if TARGET_CARBON
-               AGAPortHelper help( GetWindowPort(m_window) ) ;
-               #else
-               AGAPortHelper help( (m_window) ) ;
-               #endif
-               m_shown = false ;
-
-               BackColor( whiteColor ) ;
-               ForeColor(blackColor ) ;
-               DrawPicture(m_backpict, &m_rect);
-               KillPicture(m_backpict);
-               m_backpict = NULL ;
-       }
-}
+    m_mark++ ;
 
+    if ( m_timer )
+    {
+        delete m_timer ;
+        m_timer = NULL ;
+    }
+
+    if ( !m_shown )
+        return ;
+
+#if TARGET_CARBON
+    HMHideTag() ;
+    m_helpTextRef.Release() ;
+#else
+    if ( m_window == s_ToolTipWindowRef && m_backpict )
+    {
+        wxMacPortStateHelper help( (GrafPtr)GetWindowPort( m_window ) ) ;
+
+        m_shown = false ;
+
+        BackColor( whiteColor ) ;
+        ForeColor( blackColor ) ;
+        DrawPicture( m_backpict, &m_rect );
+        KillPicture( m_backpict );
+        m_backpict = NULL ;
+    }
 #endif
+}
 
+#endif // wxUSE_TOOLTIPS