wxHelpProvider now cleans itself up. wxTipWindow doesn't
[wxWidgets.git] / src / generic / tipwin.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/tipwin.cpp
3 // Purpose: implementation of wxTipWindow
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 10.09.00
7 // RCS-ID: $Id$
8 // Copyright: (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "tipwin.h"
22 #endif
23
24 // For compilers that support precompilatixon, includes "wx/wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/dcclient.h"
33 #endif // WX_PRECOMP
34
35 #include "wx/tipwin.h"
36
37 // ----------------------------------------------------------------------------
38 // constants
39 // ----------------------------------------------------------------------------
40
41 static const wxCoord TEXT_MARGIN_X = 3;
42 static const wxCoord TEXT_MARGIN_Y = 3;
43
44 // ============================================================================
45 // implementation
46 // ============================================================================
47
48 // ----------------------------------------------------------------------------
49 // event tables
50 // ----------------------------------------------------------------------------
51
52 BEGIN_EVENT_TABLE(wxTipWindow, wxFrame)
53 EVT_PAINT(wxTipWindow::OnPaint)
54
55 EVT_LEFT_DOWN(wxTipWindow::OnMouseClick)
56 EVT_RIGHT_DOWN(wxTipWindow::OnMouseClick)
57 EVT_MIDDLE_DOWN(wxTipWindow::OnMouseClick)
58 EVT_KILL_FOCUS(wxTipWindow::OnKillFocus)
59 EVT_ACTIVATE(wxTipWindow::OnActivate)
60 END_EVENT_TABLE()
61
62 // ----------------------------------------------------------------------------
63 // wxTipWindow
64 // ----------------------------------------------------------------------------
65
66 wxTipWindow::wxTipWindow(wxWindow *parent,
67 const wxString& text,
68 wxCoord maxLength)
69 : wxFrame(parent, -1, _T(""),
70 wxDefaultPosition, wxDefaultSize,
71 wxNO_BORDER | wxFRAME_FLOAT_ON_PARENT)
72 {
73 // set colours
74 SetForegroundColour(*wxBLACK);
75 SetBackgroundColour(wxColour(0xc3ffff));
76
77 // set position and size
78 int x, y;
79 wxGetMousePosition(&x, &y);
80 Move(x, y + 20);
81
82 Adjust(text, maxLength);
83
84 SetFocus();
85
86 Show(TRUE);
87 }
88
89 void wxTipWindow::Adjust(const wxString& text, wxCoord maxLength)
90 {
91 wxClientDC dc(this);
92 dc.SetFont(GetFont());
93
94 // calculate the length: we want each line be no longer than maxLength
95 // pixels and we only break lines at words boundary
96 wxString current;
97 wxCoord height, width,
98 widthMax = 0;
99 m_heightLine = 0;
100
101 bool breakLine = FALSE;
102 for ( const wxChar *p = text.c_str(); ; p++ )
103 {
104 if ( *p == _T('\n') || *p == _T('\0') )
105 {
106 dc.GetTextExtent(current, &width, &height);
107 if ( width > widthMax )
108 widthMax = width;
109
110 if ( height > m_heightLine )
111 m_heightLine = height;
112
113 m_textLines.Add(current);
114
115 if ( !*p )
116 {
117 // end of text
118 break;
119 }
120
121 current.clear();
122 breakLine = FALSE;
123 }
124 else if ( breakLine && (*p == _T(' ') || *p == _T('\t')) )
125 {
126 // word boundary - break the line here
127 m_textLines.Add(current);
128 current.clear();
129 breakLine = FALSE;
130 }
131 else // line goes on
132 {
133 current += *p;
134 dc.GetTextExtent(current, &width, &height);
135 if ( width > maxLength )
136 breakLine = TRUE;
137
138 if ( width > widthMax )
139 widthMax = width;
140
141 if ( height > m_heightLine )
142 m_heightLine = height;
143 }
144 }
145
146 // take into account the border size and the margins
147 SetClientSize(2*(TEXT_MARGIN_X + 1) + widthMax,
148 2*(TEXT_MARGIN_Y + 1) + m_textLines.GetCount()*m_heightLine);
149 }
150
151 void wxTipWindow::OnPaint(wxPaintEvent& event)
152 {
153 wxPaintDC dc(this);
154
155 wxRect rect;
156 wxSize size = GetClientSize();
157 rect.width = size.x;
158 rect.height = size.y;
159
160 // first filll the background
161 dc.SetBrush(wxBrush(GetBackgroundColour(), wxSOLID));
162
163 // Under Windows, you apparently get a thin black border whether you like it or not :-(
164 #ifdef __WXMSW__
165 dc.SetPen( * wxTRANSPARENT_PEN );
166 #else
167 dc.SetPen( * wxBLACK_PEND );
168 #endif
169 dc.DrawRectangle(rect);
170
171 // and then draw the text line by line
172 dc.SetFont(GetFont());
173
174 wxPoint pt;
175 pt.x = TEXT_MARGIN_X;
176 pt.y = TEXT_MARGIN_Y;
177 size_t count = m_textLines.GetCount();
178 for ( size_t n = 0; n < count; n++ )
179 {
180 dc.DrawText(m_textLines[n], pt);
181
182 pt.y += m_heightLine;
183 }
184 }
185
186 void wxTipWindow::OnMouseClick(wxMouseEvent& event)
187 {
188 Close();
189 }
190
191 void wxTipWindow::OnActivate(wxActivateEvent& event)
192 {
193 if (!event.GetActive())
194 Close();
195 }
196
197 void wxTipWindow::OnKillFocus(wxFocusEvent& event)
198 {
199 Close();
200 }