wxTipWindow added and is now used by wxSimpleHelpProvider
[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 END_EVENT_TABLE()
59
60 // ----------------------------------------------------------------------------
61 // wxTipWindow
62 // ----------------------------------------------------------------------------
63
64 wxTipWindow::wxTipWindow(wxWindow *parent,
65 const wxString& text,
66 wxCoord maxLength)
67 : wxFrame(parent, -1, _T(""),
68 wxDefaultPosition, wxDefaultSize,
69 wxNO_BORDER | wxFRAME_FLOAT_ON_PARENT)
70 {
71 // set colours
72 SetForegroundColour(*wxBLACK);
73 SetBackgroundColour(wxColour(0xc3ffff));
74
75 // set position and size
76 int x, y;
77 wxGetMousePosition(&x, &y);
78 Move(x, y + 20);
79
80 Adjust(text, maxLength);
81
82 // capture mouse as we want to dismiss the window when it is clicked
83 CaptureMouse();
84
85 Show(TRUE);
86 }
87
88 void wxTipWindow::Adjust(const wxString& text, wxCoord maxLength)
89 {
90 wxClientDC dc(this);
91 dc.SetFont(GetFont());
92
93 // calculate the length: we want each line be no longer than maxLength
94 // pixels and we only break lines at words boundary
95 wxString current;
96 wxCoord height, width,
97 widthMax = 0;
98 m_heightLine = 0;
99
100 bool breakLine = FALSE;
101 for ( const wxChar *p = text.c_str(); ; p++ )
102 {
103 if ( *p == _T('\n') || *p == _T('\0') )
104 {
105 dc.GetTextExtent(current, &width, &height);
106 if ( width > widthMax )
107 widthMax = width;
108
109 if ( height > m_heightLine )
110 m_heightLine = height;
111
112 m_textLines.Add(current);
113
114 if ( !*p )
115 {
116 // end of text
117 break;
118 }
119
120 current.clear();
121 breakLine = FALSE;
122 }
123 else if ( breakLine && (*p == _T(' ') || *p == _T('\t')) )
124 {
125 // word boundary - break the line here
126 m_textLines.Add(current);
127 current.clear();
128 breakLine = FALSE;
129 }
130 else // line goes on
131 {
132 current += *p;
133 dc.GetTextExtent(current, &width, &height);
134 if ( width > maxLength )
135 breakLine = TRUE;
136
137 if ( width > widthMax )
138 widthMax = width;
139
140 if ( height > m_heightLine )
141 m_heightLine = height;
142 }
143 }
144
145 // take into account the border size and the margins
146 SetClientSize(2*(TEXT_MARGIN_X + 1) + widthMax,
147 2*(TEXT_MARGIN_Y + 1) + m_textLines.GetCount()*m_heightLine);
148 }
149
150 void wxTipWindow::OnPaint(wxPaintEvent& event)
151 {
152 wxPaintDC dc(this);
153
154 wxRect rect;
155 wxSize size = GetClientSize();
156 rect.width = size.x;
157 rect.height = size.y;
158
159 // first filll the background
160 dc.SetBrush(wxBrush(GetBackgroundColour(), wxSOLID));
161 dc.SetPen(*wxBLACK_PEN);
162 dc.DrawRectangle(rect);
163
164 // and then draw the text line by line
165 dc.SetFont(GetFont());
166
167 wxPoint pt;
168 pt.x = TEXT_MARGIN_X;
169 pt.y = TEXT_MARGIN_Y;
170 size_t count = m_textLines.GetCount();
171 for ( size_t n = 0; n < count; n++ )
172 {
173 dc.DrawText(m_textLines[n], pt);
174
175 pt.y += m_heightLine;
176 }
177 }
178
179 void wxTipWindow::OnMouseClick(wxMouseEvent& event)
180 {
181 ReleaseMouse();
182
183 Close();
184 }