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
7
// Copyright: (c) 2005 David Norris
8
// Licence: wxWindows licence
9
/////////////////////////////////////////////////////////////////////////////
11
// ============================================================================
13
// ============================================================================
15
//---------------------------------------------------------------------------
16
// Pre-compiled header stuff
17
//---------------------------------------------------------------------------
19
// For compilers that support precompilation, includes "wx.h".
20
#include "wx/wxprec.h"
26
#if wxUSE_HYPERLINKCTRL
28
//---------------------------------------------------------------------------
30
//---------------------------------------------------------------------------
32
#include "wx/hyperlink.h"
35
#include "wx/utils.h" // for wxLaunchDefaultBrowser
36
#include "wx/dcclient.h"
39
#include "wx/dataobj.h"
42
#include "wx/clipbrd.h"
43
#include "wx/renderer.h"
45
// ============================================================================
47
// ============================================================================
49
// reserved for internal use only
50
#define wxHYPERLINK_POPUP_COPY_ID 16384
52
// ----------------------------------------------------------------------------
53
// wxGenericHyperlinkCtrl
54
// ----------------------------------------------------------------------------
56
bool wxGenericHyperlinkCtrl::Create(wxWindow *parent, wxWindowID id,
57
const wxString& label, const wxString& url, const wxPoint& pos,
58
const wxSize& size, long style, const wxString& name)
60
// do validation checks:
61
CheckParams(label, url, style);
63
if ((style & wxHL_ALIGN_LEFT) == 0)
64
style |= wxFULL_REPAINT_ON_RESIZE;
66
if (!wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name))
69
// set to non empty strings both the url and the label
70
SetURL(url.empty() ? label : url);
71
SetLabel(label.empty() ? url : label);
74
SetForegroundColour(m_normalColour);
76
// by default the font of an hyperlink control is underlined
78
f.SetUnderlined(true);
84
// connect our event handlers:
85
// NOTE: since this class is the base class of the GTK+'s native implementation
86
// of wxHyperlinkCtrl, we cannot use the static macros in BEGIN/END_EVENT_TABLE
87
// blocks, otherwise the GTK+'s native impl of wxHyperlinkCtrl would not
88
// behave correctly (as we intercept events doing things which interfere
89
// with GTK+'s native handling):
91
Connect( wxEVT_PAINT, wxPaintEventHandler(wxGenericHyperlinkCtrl::OnPaint) );
92
Connect( wxEVT_SET_FOCUS, wxFocusEventHandler(wxGenericHyperlinkCtrl::OnFocus) );
93
Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler(wxGenericHyperlinkCtrl::OnFocus) );
94
Connect( wxEVT_CHAR, wxKeyEventHandler(wxGenericHyperlinkCtrl::OnChar) );
95
Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler(wxGenericHyperlinkCtrl::OnLeaveWindow) );
97
Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler(wxGenericHyperlinkCtrl::OnLeftDown) );
98
Connect( wxEVT_LEFT_UP, wxMouseEventHandler(wxGenericHyperlinkCtrl::OnLeftUp) );
99
Connect( wxEVT_MOTION, wxMouseEventHandler(wxGenericHyperlinkCtrl::OnMotion) );
101
ConnectMenuHandlers();
106
void wxGenericHyperlinkCtrl::Init()
113
m_normalColour = *wxBLUE;
114
m_hoverColour = *wxRED;
115
m_visitedColour = wxColour("#551a8b");
118
void wxGenericHyperlinkCtrl::ConnectMenuHandlers()
120
// Connect the event handlers for the context menu.
121
Connect( wxEVT_RIGHT_UP, wxMouseEventHandler(wxGenericHyperlinkCtrl::OnRightUp) );
122
Connect( wxHYPERLINK_POPUP_COPY_ID, wxEVT_MENU,
123
wxCommandEventHandler(wxGenericHyperlinkCtrl::OnPopUpCopy) );
126
wxSize wxGenericHyperlinkCtrl::DoGetBestClientSize() const
128
wxClientDC dc((wxWindow *)this);
129
return dc.GetTextExtent(GetLabel());
133
void wxGenericHyperlinkCtrl::SetNormalColour(const wxColour &colour)
135
m_normalColour = colour;
138
SetForegroundColour(m_normalColour);
143
void wxGenericHyperlinkCtrl::SetVisitedColour(const wxColour &colour)
145
m_visitedColour = colour;
148
SetForegroundColour(m_visitedColour);
153
void wxGenericHyperlinkCtrl::DoContextMenu(const wxPoint &pos)
155
wxMenu *menuPopUp = new wxMenu(wxEmptyString, wxMENU_TEAROFF);
156
menuPopUp->Append(wxHYPERLINK_POPUP_COPY_ID, _("&Copy URL"));
157
PopupMenu( menuPopUp, pos );
161
wxRect wxGenericHyperlinkCtrl::GetLabelRect() const
163
// our best size is always the size of the label without borders
164
wxSize c(GetClientSize()), b(GetBestSize());
167
// the label is always centered vertically
168
offset.y = (c.GetHeight()-b.GetHeight())/2;
170
if (HasFlag(wxHL_ALIGN_CENTRE))
171
offset.x = (c.GetWidth()-b.GetWidth())/2;
172
else if (HasFlag(wxHL_ALIGN_RIGHT))
173
offset.x = c.GetWidth()-b.GetWidth();
174
else if (HasFlag(wxHL_ALIGN_LEFT))
176
return wxRect(offset, b);
181
// ----------------------------------------------------------------------------
182
// wxGenericHyperlinkCtrl - event handlers
183
// ----------------------------------------------------------------------------
185
void wxGenericHyperlinkCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
188
dc.SetFont(GetFont());
189
dc.SetTextForeground(GetForegroundColour());
190
dc.SetTextBackground(GetBackgroundColour());
192
dc.DrawText(GetLabel(), GetLabelRect().GetTopLeft());
195
wxRendererNative::Get().DrawFocusRect(this, dc, GetClientRect(), wxCONTROL_SELECTED);
199
void wxGenericHyperlinkCtrl::OnFocus(wxFocusEvent& event)
205
void wxGenericHyperlinkCtrl::OnChar(wxKeyEvent& event)
207
switch (event.m_keyCode)
213
case WXK_NUMPAD_SPACE:
214
SetForegroundColour(m_visitedColour);
221
void wxGenericHyperlinkCtrl::OnLeftDown(wxMouseEvent& event)
223
// the left click must start from the hyperlink rect
224
m_clicking = GetLabelRect().Contains(event.GetPosition());
227
void wxGenericHyperlinkCtrl::OnLeftUp(wxMouseEvent& event)
229
// the click must be started and ended in the hyperlink rect
230
if (!m_clicking || !GetLabelRect().Contains(event.GetPosition()))
233
SetForegroundColour(m_visitedColour);
241
void wxGenericHyperlinkCtrl::OnRightUp(wxMouseEvent& event)
243
if( GetWindowStyle() & wxHL_CONTEXTMENU )
244
if ( GetLabelRect().Contains(event.GetPosition()) )
245
DoContextMenu(wxPoint(event.m_x, event.m_y));
248
void wxGenericHyperlinkCtrl::OnMotion(wxMouseEvent& event)
250
wxRect textrc = GetLabelRect();
252
if (textrc.Contains(event.GetPosition()))
254
SetCursor(wxCursor(wxCURSOR_HAND));
255
SetForegroundColour(m_hoverColour);
261
SetCursor(*wxSTANDARD_CURSOR);
262
SetForegroundColour(!m_visited ? m_normalColour : m_visitedColour);
268
void wxGenericHyperlinkCtrl::OnLeaveWindow(wxMouseEvent& WXUNUSED(event) )
270
// NB: when the label rect and the client size rect have the same
271
// height this function is indispensable to remove the "rollover"
272
// effect as the OnMotion() event handler could not be called
273
// in that case moving the mouse out of the label vertically...
277
SetCursor(*wxSTANDARD_CURSOR);
278
SetForegroundColour(!m_visited ? m_normalColour : m_visitedColour);
284
void wxGenericHyperlinkCtrl::OnPopUpCopy( wxCommandEvent& WXUNUSED(event) )
287
if (!wxTheClipboard->Open())
290
wxTextDataObject *data = new wxTextDataObject( m_url );
291
wxTheClipboard->SetData( data );
292
wxTheClipboard->Close();
293
#endif // wxUSE_CLIPBOARD
296
#endif // wxUSE_HYPERLINKCTRL