1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/generic/tipwin.cpp 
   3 // Purpose:     implementation of wxTipWindow 
   4 // Author:      Vadim Zeitlin 
   8 // Copyright:   (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> 
   9 // Licence:     wxWindows license 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  21     #pragma implementation "tipwin.h" 
  24 // For compilers that support precompilatixon, includes "wx/wx.h". 
  25 #include "wx/wxprec.h" 
  32     #include "wx/dcclient.h" 
  35 #include "wx/tipwin.h" 
  40 #include "wx/settings.h" 
  42 // ---------------------------------------------------------------------------- 
  44 // ---------------------------------------------------------------------------- 
  46 static const wxCoord TEXT_MARGIN_X 
= 3; 
  47 static const wxCoord TEXT_MARGIN_Y 
= 3; 
  49 // ---------------------------------------------------------------------------- 
  51 // ---------------------------------------------------------------------------- 
  53 // Viewer window to put in the frame 
  54 class WXDLLEXPORT wxTipWindowView 
: public wxWindow
 
  57     wxTipWindowView(wxWindow 
*parent
); 
  60     void OnPaint(wxPaintEvent
& event
); 
  61     void OnMouseClick(wxMouseEvent
& event
); 
  62     void OnMouseMove(wxMouseEvent
& event
); 
  65     void OnKillFocus(wxFocusEvent
& event
); 
  66 #endif // wxUSE_POPUPWIN 
  68     // calculate the client rect we need to display the text 
  69     void Adjust(const wxString
& text
, wxCoord maxLength
); 
  72     wxTipWindow
* m_parent
; 
  76 #endif // !wxUSE_POPUPWIN 
  81 // ============================================================================ 
  83 // ============================================================================ 
  85 // ---------------------------------------------------------------------------- 
  87 // ---------------------------------------------------------------------------- 
  89 BEGIN_EVENT_TABLE(wxTipWindow
, wxTipWindowBase
) 
  90     EVT_LEFT_DOWN(wxTipWindow::OnMouseClick
) 
  91     EVT_RIGHT_DOWN(wxTipWindow::OnMouseClick
) 
  92     EVT_MIDDLE_DOWN(wxTipWindow::OnMouseClick
) 
  95     EVT_KILL_FOCUS(wxTipWindow::OnKillFocus
) 
  96     EVT_ACTIVATE(wxTipWindow::OnActivate
) 
  97 #endif // !wxUSE_POPUPWIN 
 100 BEGIN_EVENT_TABLE(wxTipWindowView
, wxWindow
) 
 101     EVT_PAINT(wxTipWindowView::OnPaint
) 
 103     EVT_LEFT_DOWN(wxTipWindowView::OnMouseClick
) 
 104     EVT_RIGHT_DOWN(wxTipWindowView::OnMouseClick
) 
 105     EVT_MIDDLE_DOWN(wxTipWindowView::OnMouseClick
) 
 107     EVT_MOTION(wxTipWindowView::OnMouseMove
) 
 110     EVT_KILL_FOCUS(wxTipWindowView::OnKillFocus
) 
 111 #endif // !wxUSE_POPUPWIN 
 114 // ---------------------------------------------------------------------------- 
 116 // ---------------------------------------------------------------------------- 
 118 wxTipWindow::wxTipWindow(wxWindow 
*parent
, 
 119                          const wxString
& text
, 
 121                          wxTipWindow
** windowPtr
, 
 124            : wxPopupTransientWindow(parent
) 
 126            : wxFrame(parent
, -1, _T(""), 
 127                      wxDefaultPosition
, wxDefaultSize
, 
 128                      wxNO_BORDER 
| wxFRAME_NO_TASKBAR 
) 
 131     SetTipWindowPtr(windowPtr
); 
 134         SetBoundingRect(*rectBounds
); 
 139     // VZ: why don't we use wxSystemSettings for !MSW? (FIXME) 
 141     SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT
)); 
 142     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK
)); 
 144     SetForegroundColour(*wxBLACK
); 
 145     SetBackgroundColour(*wxWHITE
); 
 148     // set size, position and show it 
 149     m_view 
= new wxTipWindowView(this); 
 150     m_view
->Adjust(text
, maxLength
); 
 154     wxGetMousePosition(&x
, &y
); 
 156     // we want to show the tip below the mouse, not over it 
 158     // NB: the reason we use "/ 2" here is that we don't know where the current 
 159     //     cursors hot spot is... it would be nice if we could find this out 
 161     y 
+= wxSystemSettings::GetMetric(wxSYS_CURSOR_Y
) / 2; 
 164     Position(wxPoint(x
, y
), wxSize(0, 0)); 
 172 wxTipWindow::~wxTipWindow() 
 180 void wxTipWindow::OnMouseClick(wxMouseEvent
& WXUNUSED(event
)) 
 187 void wxTipWindow::OnDismiss() 
 192 #else // !wxUSE_POPUPWIN 
 194 void wxTipWindow::OnActivate(wxActivateEvent
& event
) 
 196     if (!event
.GetActive()) 
 200 void wxTipWindow::OnKillFocus(wxFocusEvent
& WXUNUSED(event
)) 
 202     // Under Windows at least, we will get this immediately 
 203     // because when the view window is focussed, the 
 204     // tip window goes out of focus. 
 210 #endif // wxUSE_POPUPWIN // !wxUSE_POPUPWIN 
 212 void wxTipWindow::SetBoundingRect(const wxRect
& rectBound
) 
 214     m_rectBound 
= rectBound
; 
 217 void wxTipWindow::Close() 
 233 // ---------------------------------------------------------------------------- 
 235 // ---------------------------------------------------------------------------- 
 237 wxTipWindowView::wxTipWindowView(wxWindow 
*parent
) 
 238                : wxWindow(parent
, -1, 
 239                           wxDefaultPosition
, wxDefaultSize
, 
 244     // VZ: why don't we use wxSystemSettings for !MSW? (FIXME) 
 246     SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT
)); 
 247     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK
)); 
 249     SetForegroundColour(*wxBLACK
); 
 250     SetBackgroundColour(*wxWHITE
); 
 254     m_creationTime 
= wxGetLocalTime(); 
 255 #endif // !wxUSE_POPUPWIN 
 257     m_parent 
= (wxTipWindow
*)parent
; 
 260 void wxTipWindowView::Adjust(const wxString
& text
, wxCoord maxLength
) 
 263     dc
.SetFont(GetFont()); 
 265     // calculate the length: we want each line be no longer than maxLength 
 266     // pixels and we only break lines at words boundary 
 268     wxCoord height
, width
, 
 270     m_parent
->m_heightLine 
= 0; 
 272     bool breakLine 
= FALSE
; 
 273     for ( const wxChar 
*p 
= text
.c_str(); ; p
++ ) 
 275         if ( *p 
== _T('\n') || *p 
== _T('\0') ) 
 277             dc
.GetTextExtent(current
, &width
, &height
); 
 278             if ( width 
> widthMax 
) 
 281             if ( height 
> m_parent
->m_heightLine 
) 
 282                 m_parent
->m_heightLine 
= height
; 
 284             m_parent
->m_textLines
.Add(current
); 
 295         else if ( breakLine 
&& (*p 
== _T(' ') || *p 
== _T('\t')) ) 
 297             // word boundary - break the line here 
 298             m_parent
->m_textLines
.Add(current
); 
 305             dc
.GetTextExtent(current
, &width
, &height
); 
 306             if ( width 
> maxLength 
) 
 309             if ( width 
> widthMax 
) 
 312             if ( height 
> m_parent
->m_heightLine 
) 
 313                 m_parent
->m_heightLine 
= height
; 
 317     // take into account the border size and the margins 
 318     width  
= 2*(TEXT_MARGIN_X 
+ 1) + widthMax
; 
 319     height 
= 2*(TEXT_MARGIN_Y 
+ 1) + m_parent
->m_textLines
.GetCount()*m_parent
->m_heightLine
; 
 320     m_parent
->SetClientSize(width
, height
); 
 321     SetSize(0, 0, width
, height
); 
 324 void wxTipWindowView::OnPaint(wxPaintEvent
& WXUNUSED(event
)) 
 329     wxSize size 
= GetClientSize(); 
 331     rect
.height 
= size
.y
; 
 333     // first filll the background 
 334     dc
.SetBrush(wxBrush(GetBackgroundColour(), wxSOLID
)); 
 335     dc
.SetPen( wxPen(GetForegroundColour(), 1, wxSOLID
) ); 
 336     dc
.DrawRectangle(rect
); 
 338     // and then draw the text line by line 
 339     dc
.SetTextBackground(GetBackgroundColour()); 
 340     dc
.SetTextForeground(GetForegroundColour()); 
 341     dc
.SetFont(GetFont()); 
 344     pt
.x 
= TEXT_MARGIN_X
; 
 345     pt
.y 
= TEXT_MARGIN_Y
; 
 346     size_t count 
= m_parent
->m_textLines
.GetCount(); 
 347     for ( size_t n 
= 0; n 
< count
; n
++ ) 
 349         dc
.DrawText(m_parent
->m_textLines
[n
], pt
); 
 351         pt
.y 
+= m_parent
->m_heightLine
; 
 355 void wxTipWindowView::OnMouseClick(wxMouseEvent
& WXUNUSED(event
)) 
 360 void wxTipWindowView::OnMouseMove(wxMouseEvent
& event
) 
 362     const wxRect
& rectBound 
= m_parent
->m_rectBound
; 
 364     if ( rectBound
.width 
&& 
 365             !rectBound
.Inside(ClientToScreen(event
.GetPosition())) ) 
 367         // mouse left the bounding rect, disappear 
 377 void wxTipWindowView::OnKillFocus(wxFocusEvent
& WXUNUSED(event
)) 
 379     // Workaround the kill focus event happening just after creation in wxGTK 
 380     if (wxGetLocalTime() > m_creationTime 
+ 1) 
 383 #endif // !wxUSE_POPUPWIN 
 385 #endif // wxUSE_TIPWINDOW