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
8 // Copyright: (c) 2005 David Norris
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 //---------------------------------------------------------------------------
17 // Pre-compiled header stuff
18 //---------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
27 #if wxUSE_HYPERLINKCTRL
29 //---------------------------------------------------------------------------
31 //---------------------------------------------------------------------------
33 #include "wx/hyperlink.h"
36 #include "wx/utils.h" // for wxLaunchDefaultBrowser
37 #include "wx/dcclient.h"
40 #include "wx/dataobj.h"
43 #include "wx/clipbrd.h"
45 // ============================================================================
47 // ============================================================================
49 IMPLEMENT_DYNAMIC_CLASS(wxGenericHyperlinkCtrl
, wxControl
)
51 // reserved for internal use only
52 #define wxHYPERLINK_POPUP_COPY_ID 16384
54 // ----------------------------------------------------------------------------
55 // wxGenericHyperlinkCtrl
56 // ----------------------------------------------------------------------------
58 bool 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
)
62 // do validation checks:
63 CheckParams(label
, url
, style
);
65 if (!wxControl::Create(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
68 // set to non empty strings both the url and the label
69 SetURL(url
.empty() ? label
: url
);
70 SetLabel(label
.empty() ? url
: label
);
77 m_normalColour
= *wxBLUE
;
78 m_hoverColour
= *wxRED
;
79 SetForegroundColour(m_normalColour
);
81 // by default the font of an hyperlink control is underlined
83 f
.SetUnderlined(true);
89 // connect our event handlers:
90 // NOTE: since this class is the base class of the GTK+'s native implementation
91 // of wxHyperlinkCtrl, we cannot use the static macros in BEGIN/END_EVENT_TABLE
92 // blocks, otherwise the GTK+'s native impl of wxHyperlinkCtrl would not
93 // behave correctly (as we intercept events doing things which interfere
94 // with GTK+'s native handling):
96 Connect( wxEVT_PAINT
, wxPaintEventHandler(wxGenericHyperlinkCtrl::OnPaint
) );
97 Connect( wxEVT_SIZE
, wxSizeEventHandler(wxGenericHyperlinkCtrl::OnSize
) );
98 Connect( wxEVT_LEAVE_WINDOW
, wxMouseEventHandler(wxGenericHyperlinkCtrl::OnLeaveWindow
) );
100 Connect( wxEVT_LEFT_DOWN
, wxMouseEventHandler(wxGenericHyperlinkCtrl::OnLeftDown
) );
101 Connect( wxEVT_LEFT_UP
, wxMouseEventHandler(wxGenericHyperlinkCtrl::OnLeftUp
) );
102 Connect( wxEVT_RIGHT_UP
, wxMouseEventHandler(wxGenericHyperlinkCtrl::OnRightUp
) );
103 Connect( wxEVT_MOTION
, wxMouseEventHandler(wxGenericHyperlinkCtrl::OnMotion
) );
105 Connect( wxHYPERLINK_POPUP_COPY_ID
, wxEVT_COMMAND_MENU_SELECTED
,
106 wxCommandEventHandler(wxGenericHyperlinkCtrl::OnPopUpCopy
) );
111 wxSize
wxGenericHyperlinkCtrl::DoGetBestSize() const
115 wxClientDC
dc((wxWindow
*)this);
116 dc
.SetFont(GetFont());
117 dc
.GetTextExtent(GetLabel(), &w
, &h
);
125 void wxGenericHyperlinkCtrl::SetNormalColour(const wxColour
&colour
)
127 m_normalColour
= colour
;
130 SetForegroundColour(m_normalColour
);
135 void wxGenericHyperlinkCtrl::SetVisitedColour(const wxColour
&colour
)
137 m_visitedColour
= colour
;
140 SetForegroundColour(m_visitedColour
);
145 void wxGenericHyperlinkCtrl::DoContextMenu(const wxPoint
&pos
)
147 wxMenu
*menuPopUp
= new wxMenu(wxEmptyString
, wxMENU_TEAROFF
);
148 menuPopUp
->Append(wxHYPERLINK_POPUP_COPY_ID
, wxT("Copy URL"));
149 PopupMenu( menuPopUp
, pos
);
153 wxRect
wxGenericHyperlinkCtrl::GetLabelRect() const
155 // our best size is always the size of the label without borders
156 wxSize
c(GetClientSize()), b(GetBestSize());
159 // the label is always centered vertically
160 offset
.y
= (c
.GetHeight()-b
.GetHeight())/2;
162 if (HasFlag(wxHL_ALIGN_CENTRE
))
163 offset
.x
= (c
.GetWidth()-b
.GetWidth())/2;
164 else if (HasFlag(wxHL_ALIGN_RIGHT
))
165 offset
.x
= c
.GetWidth()-b
.GetWidth();
166 else if (HasFlag(wxHL_ALIGN_LEFT
))
168 return wxRect(offset
, b
);
173 // ----------------------------------------------------------------------------
174 // wxGenericHyperlinkCtrl - event handlers
175 // ----------------------------------------------------------------------------
177 void wxGenericHyperlinkCtrl::OnPaint(wxPaintEvent
& WXUNUSED(event
))
180 dc
.SetFont(GetFont());
181 dc
.SetTextForeground(GetForegroundColour());
182 dc
.SetTextBackground(GetBackgroundColour());
184 dc
.DrawText(GetLabel(), GetLabelRect().GetTopLeft());
187 void wxGenericHyperlinkCtrl::OnLeftDown(wxMouseEvent
& event
)
189 // the left click must start from the hyperlink rect
190 m_clicking
= GetLabelRect().Contains(event
.GetPosition());
193 void wxGenericHyperlinkCtrl::OnLeftUp(wxMouseEvent
& event
)
195 // the click must be started and ended in the hyperlink rect
196 if (!m_clicking
|| !GetLabelRect().Contains(event
.GetPosition()))
199 SetForegroundColour(m_visitedColour
);
207 void wxGenericHyperlinkCtrl::OnRightUp(wxMouseEvent
& event
)
209 if( GetWindowStyle() & wxHL_CONTEXTMENU
)
210 if ( GetLabelRect().Contains(event
.GetPosition()) )
211 DoContextMenu(wxPoint(event
.m_x
, event
.m_y
));
214 void wxGenericHyperlinkCtrl::OnMotion(wxMouseEvent
& event
)
216 wxRect textrc
= GetLabelRect();
218 if (textrc
.Contains(event
.GetPosition()))
220 SetCursor(wxCursor(wxCURSOR_HAND
));
221 SetForegroundColour(m_hoverColour
);
227 SetCursor(*wxSTANDARD_CURSOR
);
228 SetForegroundColour(!m_visited
? m_normalColour
: m_visitedColour
);
234 void wxGenericHyperlinkCtrl::OnLeaveWindow(wxMouseEvent
& WXUNUSED(event
) )
236 // NB: when the label rect and the client size rect have the same
237 // height this function is indispensable to remove the "rollover"
238 // effect as the OnMotion() event handler could not be called
239 // in that case moving the mouse out of the label vertically...
243 SetCursor(*wxSTANDARD_CURSOR
);
244 SetForegroundColour(!m_visited
? m_normalColour
: m_visitedColour
);
250 void wxGenericHyperlinkCtrl::OnPopUpCopy( wxCommandEvent
& WXUNUSED(event
) )
253 if (!wxTheClipboard
->Open())
256 wxTextDataObject
*data
= new wxTextDataObject( m_url
);
257 wxTheClipboard
->SetData( data
);
258 wxTheClipboard
->Close();
259 #endif // wxUSE_CLIPBOARD
262 void wxGenericHyperlinkCtrl::OnSize(wxSizeEvent
& WXUNUSED(event
))
264 // update the position of the label in the screen respecting
265 // the selected align flag
269 #endif // wxUSE_HYPERLINKCTRL