]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/generic/hyperlinkg.cpp
Border corrections
[wxWidgets.git] / src / generic / hyperlinkg.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/generic/hyperlinkg.cpp
3// Purpose: Hyperlink control
4// Author: David Norris <danorris@gmail.com>, Otto Wyss
5// Modified by: Ryan Norton, Francesco Montorsi
6// Created: 04/02/2005
7// RCS-ID: $Id$
8// Copyright: (c) 2005 David Norris
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16//---------------------------------------------------------------------------
17// Pre-compiled header stuff
18//---------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#if wxUSE_HYPERLINKCTRL
28
29//---------------------------------------------------------------------------
30// Includes
31//---------------------------------------------------------------------------
32
33#include "wx/hyperlink.h"
34
35#ifndef WX_PRECOMP
36 #include "wx/utils.h" // for wxLaunchDefaultBrowser
37 #include "wx/dcclient.h"
38 #include "wx/menu.h"
39 #include "wx/log.h"
40 #include "wx/dataobj.h"
41#endif
42
43#include "wx/clipbrd.h"
44
45// ============================================================================
46// implementation
47// ============================================================================
48
49IMPLEMENT_DYNAMIC_CLASS(wxGenericHyperlinkCtrl, wxControl)
50
51// reserved for internal use only
52#define wxHYPERLINK_POPUP_COPY_ID 16384
53
54// ----------------------------------------------------------------------------
55// wxGenericHyperlinkCtrl
56// ----------------------------------------------------------------------------
57
58bool wxGenericHyperlinkCtrl::Create(wxWindow *parent, wxWindowID id,
59 const wxString& label, const wxString& url, const wxPoint& pos,
60 const wxSize& size, long style, const wxString& name)
61{
62 // do validation checks:
63 CheckParams(label, url, style);
64
65 if ((style & wxHL_ALIGN_LEFT) == 0)
66 style |= wxFULL_REPAINT_ON_RESIZE;
67
68 if (!wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name))
69 return false;
70
71 // set to non empty strings both the url and the label
72 SetURL(url.empty() ? label : url);
73 SetLabel(label.empty() ? url : label);
74
75 m_rollover = false;
76 m_clicking = false;
77 m_visited = false;
78
79 // colours
80 m_normalColour = *wxBLUE;
81 m_hoverColour = *wxRED;
82 SetForegroundColour(m_normalColour);
83
84 // by default the font of an hyperlink control is underlined
85 wxFont f = GetFont();
86 f.SetUnderlined(true);
87 SetFont(f);
88
89 SetInitialSize(size);
90
91
92 // connect our event handlers:
93 // NOTE: since this class is the base class of the GTK+'s native implementation
94 // of wxHyperlinkCtrl, we cannot use the static macros in BEGIN/END_EVENT_TABLE
95 // blocks, otherwise the GTK+'s native impl of wxHyperlinkCtrl would not
96 // behave correctly (as we intercept events doing things which interfere
97 // with GTK+'s native handling):
98
99 Connect( wxEVT_PAINT, wxPaintEventHandler(wxGenericHyperlinkCtrl::OnPaint) );
100 Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler(wxGenericHyperlinkCtrl::OnLeaveWindow) );
101
102 Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler(wxGenericHyperlinkCtrl::OnLeftDown) );
103 Connect( wxEVT_LEFT_UP, wxMouseEventHandler(wxGenericHyperlinkCtrl::OnLeftUp) );
104 Connect( wxEVT_RIGHT_UP, wxMouseEventHandler(wxGenericHyperlinkCtrl::OnRightUp) );
105 Connect( wxEVT_MOTION, wxMouseEventHandler(wxGenericHyperlinkCtrl::OnMotion) );
106
107 Connect( wxHYPERLINK_POPUP_COPY_ID, wxEVT_COMMAND_MENU_SELECTED,
108 wxCommandEventHandler(wxGenericHyperlinkCtrl::OnPopUpCopy) );
109
110 return true;
111}
112
113wxSize wxGenericHyperlinkCtrl::DoGetBestSize() const
114{
115 int w, h;
116
117 wxClientDC dc((wxWindow *)this);
118 dc.SetFont(GetFont());
119 dc.GetTextExtent(GetLabel(), &w, &h);
120
121 wxSize best(w, h);
122 CacheBestSize(best);
123 return best;
124}
125
126
127void wxGenericHyperlinkCtrl::SetNormalColour(const wxColour &colour)
128{
129 m_normalColour = colour;
130 if (!m_visited)
131 {
132 SetForegroundColour(m_normalColour);
133 Refresh();
134 }
135}
136
137void wxGenericHyperlinkCtrl::SetVisitedColour(const wxColour &colour)
138{
139 m_visitedColour = colour;
140 if (m_visited)
141 {
142 SetForegroundColour(m_visitedColour);
143 Refresh();
144 }
145}
146
147void wxGenericHyperlinkCtrl::DoContextMenu(const wxPoint &pos)
148{
149 wxMenu *menuPopUp = new wxMenu(wxEmptyString, wxMENU_TEAROFF);
150 menuPopUp->Append(wxHYPERLINK_POPUP_COPY_ID, wxT("Copy URL"));
151 PopupMenu( menuPopUp, pos );
152 delete menuPopUp;
153}
154
155wxRect wxGenericHyperlinkCtrl::GetLabelRect() const
156{
157 // our best size is always the size of the label without borders
158 wxSize c(GetClientSize()), b(GetBestSize());
159 wxPoint offset;
160
161 // the label is always centered vertically
162 offset.y = (c.GetHeight()-b.GetHeight())/2;
163
164 if (HasFlag(wxHL_ALIGN_CENTRE))
165 offset.x = (c.GetWidth()-b.GetWidth())/2;
166 else if (HasFlag(wxHL_ALIGN_RIGHT))
167 offset.x = c.GetWidth()-b.GetWidth();
168 else if (HasFlag(wxHL_ALIGN_LEFT))
169 offset.x = 0;
170 return wxRect(offset, b);
171}
172
173
174
175// ----------------------------------------------------------------------------
176// wxGenericHyperlinkCtrl - event handlers
177// ----------------------------------------------------------------------------
178
179void wxGenericHyperlinkCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
180{
181 wxPaintDC dc(this);
182 dc.SetFont(GetFont());
183 dc.SetTextForeground(GetForegroundColour());
184 dc.SetTextBackground(GetBackgroundColour());
185
186 dc.DrawText(GetLabel(), GetLabelRect().GetTopLeft());
187}
188
189void wxGenericHyperlinkCtrl::OnLeftDown(wxMouseEvent& event)
190{
191 // the left click must start from the hyperlink rect
192 m_clicking = GetLabelRect().Contains(event.GetPosition());
193}
194
195void wxGenericHyperlinkCtrl::OnLeftUp(wxMouseEvent& event)
196{
197 // the click must be started and ended in the hyperlink rect
198 if (!m_clicking || !GetLabelRect().Contains(event.GetPosition()))
199 return;
200
201 SetForegroundColour(m_visitedColour);
202 m_visited = true;
203 m_clicking = false;
204
205 // send the event
206 SendEvent();
207}
208
209void wxGenericHyperlinkCtrl::OnRightUp(wxMouseEvent& event)
210{
211 if( GetWindowStyle() & wxHL_CONTEXTMENU )
212 if ( GetLabelRect().Contains(event.GetPosition()) )
213 DoContextMenu(wxPoint(event.m_x, event.m_y));
214}
215
216void wxGenericHyperlinkCtrl::OnMotion(wxMouseEvent& event)
217{
218 wxRect textrc = GetLabelRect();
219
220 if (textrc.Contains(event.GetPosition()))
221 {
222 SetCursor(wxCursor(wxCURSOR_HAND));
223 SetForegroundColour(m_hoverColour);
224 m_rollover = true;
225 Refresh();
226 }
227 else if (m_rollover)
228 {
229 SetCursor(*wxSTANDARD_CURSOR);
230 SetForegroundColour(!m_visited ? m_normalColour : m_visitedColour);
231 m_rollover = false;
232 Refresh();
233 }
234}
235
236void wxGenericHyperlinkCtrl::OnLeaveWindow(wxMouseEvent& WXUNUSED(event) )
237{
238 // NB: when the label rect and the client size rect have the same
239 // height this function is indispensable to remove the "rollover"
240 // effect as the OnMotion() event handler could not be called
241 // in that case moving the mouse out of the label vertically...
242
243 if (m_rollover)
244 {
245 SetCursor(*wxSTANDARD_CURSOR);
246 SetForegroundColour(!m_visited ? m_normalColour : m_visitedColour);
247 m_rollover = false;
248 Refresh();
249 }
250}
251
252void wxGenericHyperlinkCtrl::OnPopUpCopy( wxCommandEvent& WXUNUSED(event) )
253{
254#if wxUSE_CLIPBOARD
255 if (!wxTheClipboard->Open())
256 return;
257
258 wxTextDataObject *data = new wxTextDataObject( m_url );
259 wxTheClipboard->SetData( data );
260 wxTheClipboard->Close();
261#endif // wxUSE_CLIPBOARD
262}
263
264#endif // wxUSE_HYPERLINKCTRL