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