]> git.saurik.com Git - wxWidgets.git/blob - src/generic/tipwin.cpp
use UNIX wxDir if available
[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 #if wxUSE_TIPWINDOW
38
39 #include "wx/timer.h"
40 #include "wx/settings.h"
41
42 // ----------------------------------------------------------------------------
43 // constants
44 // ----------------------------------------------------------------------------
45
46 static const wxCoord TEXT_MARGIN_X = 3;
47 static const wxCoord TEXT_MARGIN_Y = 3;
48
49 // ============================================================================
50 // implementation
51 // ============================================================================
52
53 // ----------------------------------------------------------------------------
54 // event tables
55 // ----------------------------------------------------------------------------
56
57 #if wxUSE_POPUPWIN
58 BEGIN_EVENT_TABLE(wxTipWindow, wxPopupTransientWindow)
59 #else
60 BEGIN_EVENT_TABLE(wxTipWindow, wxFrame)
61 #endif
62 EVT_LEFT_DOWN(wxTipWindow::OnMouseClick)
63 EVT_RIGHT_DOWN(wxTipWindow::OnMouseClick)
64 EVT_MIDDLE_DOWN(wxTipWindow::OnMouseClick)
65 #if !wxUSE_POPUPWIN
66 EVT_KILL_FOCUS(wxTipWindow::OnKillFocus)
67 EVT_ACTIVATE(wxTipWindow::OnActivate)
68 #endif
69 END_EVENT_TABLE()
70
71
72 // Viewer window to put in the frame
73 class wxTipWindowView: public wxWindow
74 {
75 public:
76 wxTipWindowView(wxWindow *parent);
77
78 // event handlers
79 void OnPaint(wxPaintEvent& event);
80 void OnMouseClick(wxMouseEvent& event);
81 #if !wxUSE_POPUPWIN
82 void OnKillFocus(wxFocusEvent& event);
83 #endif
84 // calculate the client rect we need to display the text
85 void Adjust(const wxString& text, wxCoord maxLength);
86
87 private:
88 long m_creationTime;
89 wxTipWindow* m_parent;
90
91 DECLARE_EVENT_TABLE()
92 };
93
94 BEGIN_EVENT_TABLE(wxTipWindowView, wxWindow)
95 EVT_PAINT(wxTipWindowView::OnPaint)
96 EVT_LEFT_DOWN(wxTipWindowView::OnMouseClick)
97 EVT_RIGHT_DOWN(wxTipWindowView::OnMouseClick)
98 EVT_MIDDLE_DOWN(wxTipWindowView::OnMouseClick)
99 #if !wxUSE_POPUPWIN
100 EVT_KILL_FOCUS(wxTipWindowView::OnKillFocus)
101 #endif
102 END_EVENT_TABLE()
103
104 // ----------------------------------------------------------------------------
105 // wxTipWindow
106 // ----------------------------------------------------------------------------
107
108 wxTipWindow::wxTipWindow(wxWindow *parent,
109 const wxString& text,
110 wxCoord maxLength, wxTipWindow** windowPtr)
111 #if wxUSE_POPUPWIN
112 : wxPopupTransientWindow(parent)
113 #else
114 : wxFrame(parent, -1, _T(""),
115 wxDefaultPosition, wxDefaultSize,
116 wxNO_BORDER | wxFRAME_NO_TASKBAR )
117 #endif
118 {
119 m_windowPtr = windowPtr;
120
121 // set colours
122 SetForegroundColour(*wxBLACK);
123
124 #ifdef __WXMSW__
125 wxColour bkCol(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_INFOBK));
126 #else
127 wxColour bkCol(wxColour(255, 255, 225));
128 #endif
129 SetBackgroundColour(bkCol);
130
131 // set size, position and show it
132 wxTipWindowView* tipWindowView = new wxTipWindowView(this);
133 tipWindowView->Adjust(text, maxLength);
134 tipWindowView->SetFocus();
135 int x, y;
136 wxGetMousePosition(&x, &y);
137 #if wxUSE_POPUPWIN
138 Position(wxPoint(x, y+10), wxSize(0,0));
139 Popup(tipWindowView);
140 #else
141 Move(x, y + 10);
142 Show(TRUE);
143 #endif
144 }
145
146 wxTipWindow::~wxTipWindow()
147 {
148 if (m_windowPtr)
149 {
150 *m_windowPtr = NULL;
151 }
152 }
153
154 void wxTipWindow::OnMouseClick(wxMouseEvent& WXUNUSED(event))
155 {
156 Close();
157 }
158
159 #if !wxUSE_POPUPWIN
160 void wxTipWindow::OnActivate(wxActivateEvent& event)
161 {
162 if (!event.GetActive())
163 Close();
164 }
165
166 void wxTipWindow::OnKillFocus(wxFocusEvent& WXUNUSED(event))
167 {
168 // Under Windows at least, we will get this immediately
169 // because when the view window is focussed, the
170 // tip window goes out of focus.
171 #ifdef __WXGTK__
172 Close();
173 #endif
174 }
175 #endif
176
177
178 void wxTipWindow::Close()
179 {
180 #if wxUSE_POPUPWIN
181 Show(FALSE);
182 Destroy();
183 #else
184 wxFrame::Close();
185 #endif
186 }
187
188 // ----------------------------------------------------------------------------
189 // wxTipWindowView
190 // ----------------------------------------------------------------------------
191
192 wxTipWindowView::wxTipWindowView(wxWindow *parent)
193 : wxWindow(parent, -1,
194 wxDefaultPosition, wxDefaultSize,
195 wxNO_BORDER)
196 {
197 // set colours
198 SetForegroundColour(*wxBLACK);
199 #ifdef __WXMSW__
200 wxColour bkCol(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_INFOBK));
201 #else
202 wxColour bkCol(wxColour(255, 255, 225));
203 #endif
204 SetBackgroundColour(bkCol);
205 m_creationTime = wxGetLocalTime();
206 m_parent = (wxTipWindow*)parent;
207 }
208
209 void wxTipWindowView::Adjust(const wxString& text, wxCoord maxLength)
210 {
211 wxClientDC dc(this);
212 dc.SetFont(GetFont());
213
214 // calculate the length: we want each line be no longer than maxLength
215 // pixels and we only break lines at words boundary
216 wxString current;
217 wxCoord height, width,
218 widthMax = 0;
219 m_parent->m_heightLine = 0;
220
221 bool breakLine = FALSE;
222 for ( const wxChar *p = text.c_str(); ; p++ )
223 {
224 if ( *p == _T('\n') || *p == _T('\0') )
225 {
226 dc.GetTextExtent(current, &width, &height);
227 if ( width > widthMax )
228 widthMax = width;
229
230 if ( height > m_parent->m_heightLine )
231 m_parent->m_heightLine = height;
232
233 m_parent->m_textLines.Add(current);
234
235 if ( !*p )
236 {
237 // end of text
238 break;
239 }
240
241 current.clear();
242 breakLine = FALSE;
243 }
244 else if ( breakLine && (*p == _T(' ') || *p == _T('\t')) )
245 {
246 // word boundary - break the line here
247 m_parent->m_textLines.Add(current);
248 current.clear();
249 breakLine = FALSE;
250 }
251 else // line goes on
252 {
253 current += *p;
254 dc.GetTextExtent(current, &width, &height);
255 if ( width > maxLength )
256 breakLine = TRUE;
257
258 if ( width > widthMax )
259 widthMax = width;
260
261 if ( height > m_parent->m_heightLine )
262 m_parent->m_heightLine = height;
263 }
264 }
265
266 // take into account the border size and the margins
267 width = 2*(TEXT_MARGIN_X + 1) + widthMax;
268 height = 2*(TEXT_MARGIN_Y + 1) + m_parent->m_textLines.GetCount()*m_parent->m_heightLine;
269 m_parent->SetClientSize(width, height);
270 SetSize(0, 0, width, height);
271 }
272
273 void wxTipWindowView::OnPaint(wxPaintEvent& WXUNUSED(event))
274 {
275 wxPaintDC dc(this);
276
277 wxRect rect;
278 wxSize size = GetClientSize();
279 rect.width = size.x;
280 rect.height = size.y;
281
282 // first filll the background
283 dc.SetBrush(wxBrush(GetBackgroundColour(), wxSOLID));
284 dc.SetPen( wxPen(GetForegroundColour(), 1, wxSOLID) );
285 dc.DrawRectangle(rect);
286
287 // and then draw the text line by line
288 dc.SetTextBackground(GetBackgroundColour());
289 dc.SetTextForeground(GetForegroundColour());
290 dc.SetFont(GetFont());
291
292 wxPoint pt;
293 pt.x = TEXT_MARGIN_X;
294 pt.y = TEXT_MARGIN_Y;
295 size_t count = m_parent->m_textLines.GetCount();
296 for ( size_t n = 0; n < count; n++ )
297 {
298 dc.DrawText(m_parent->m_textLines[n], pt);
299
300 pt.y += m_parent->m_heightLine;
301 }
302 }
303
304 void wxTipWindowView::OnMouseClick(wxMouseEvent& WXUNUSED(event))
305 {
306 m_parent->Close();
307 }
308
309 #if !wxUSE_POPUPWIN
310 void wxTipWindowView::OnKillFocus(wxFocusEvent& WXUNUSED(event))
311 {
312 // Workaround the kill focus event happening just after creation in wxGTK
313 if (wxGetLocalTime() > m_creationTime + 1)
314 m_parent->Close();
315 }
316 #endif
317
318 #endif