Provide native wxHyperlinkCtrl implementation for wxMSW.
[wxWidgets.git] / src / gtk / hyperlink.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/hyperlink.cpp
3 // Purpose: Hyperlink control
4 // Author: Francesco Montorsi
5 // Created: 14/2/2007
6 // RCS-ID: $Id$
7 // Copyright: (c) 2007 Francesco Montorsi
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // --------------------------------------------------------------------------
16 // headers
17 // --------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #if wxUSE_HYPERLINKCTRL && defined(__WXGTK210__) && !defined(__WXUNIVERSAL__)
27
28 #include "wx/hyperlink.h"
29
30 #ifndef WX_PRECOMP
31 #endif
32
33 #include <gtk/gtk.h>
34 #include "wx/gtk/private.h"
35
36 // ----------------------------------------------------------------------------
37 // local functions
38 // ----------------------------------------------------------------------------
39
40 static inline bool UseNative()
41 {
42 // native gtk_link_button widget is only available in GTK+ 2.10 and later
43 return !gtk_check_version(2, 10, 0);
44 }
45
46 // ============================================================================
47 // implementation
48 // ============================================================================
49
50 // ----------------------------------------------------------------------------
51 // "clicked"
52 // ----------------------------------------------------------------------------
53
54 extern "C" {
55 static void gtk_hyperlink_clicked_callback( GtkWidget *WXUNUSED(widget),
56 wxHyperlinkCtrl *linkCtrl )
57 {
58 // send the event
59 linkCtrl->SendEvent();
60 }
61 }
62
63 // ----------------------------------------------------------------------------
64 // wxHyperlinkCtrl
65 // ----------------------------------------------------------------------------
66
67 bool wxHyperlinkCtrl::Create(wxWindow *parent, wxWindowID id,
68 const wxString& label, const wxString& url, const wxPoint& pos,
69 const wxSize& size, long style, const wxString& name)
70 {
71 if ( UseNative() )
72 {
73 // do validation checks:
74 CheckParams(label, url, style);
75
76 if (!PreCreation( parent, pos, size ) ||
77 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
78 {
79 wxFAIL_MSG( wxT("wxHyperlinkCtrl creation failed") );
80 return false;
81 }
82
83 m_widget = gtk_link_button_new("asdfsaf asdfdsaf asdfdsa");
84 g_object_ref(m_widget);
85 gtk_widget_show(m_widget);
86
87 // alignment
88 float x_alignment = 0.5;
89 if (HasFlag(wxHL_ALIGN_LEFT))
90 x_alignment = 0.0;
91 else if (HasFlag(wxHL_ALIGN_RIGHT))
92 x_alignment = 1.0;
93 gtk_button_set_alignment(GTK_BUTTON(m_widget), x_alignment, 0.5);
94
95 // set to non empty strings both the url and the label
96 SetURL(url.empty() ? label : url);
97 SetLabel(label.empty() ? url : label);
98
99 // our signal handlers:
100 g_signal_connect_after (m_widget, "clicked",
101 G_CALLBACK (gtk_hyperlink_clicked_callback),
102 this);
103
104 m_parent->DoAddChild( this );
105
106 PostCreation(size);
107
108 // wxWindowGTK will connect to the enter_notify and leave_notify GTK+ signals
109 // thus overriding GTK+'s internal signal handlers which set the cursor of
110 // the widget - thus we need to manually set it here:
111 SetCursor(wxCursor(wxCURSOR_HAND));
112 }
113 else
114 return wxGenericHyperlinkCtrl::Create(parent, id, label, url, pos, size, style, name);
115
116 return true;
117 }
118
119 wxSize wxHyperlinkCtrl::DoGetBestSize() const
120 {
121 if ( UseNative() )
122 return wxControl::DoGetBestSize();
123 return wxGenericHyperlinkCtrl::DoGetBestSize();
124 }
125
126 void wxHyperlinkCtrl::SetLabel(const wxString &label)
127 {
128 if ( UseNative() )
129 {
130 wxControl::SetLabel(label);
131 const wxString labelGTK = GTKConvertMnemonics(label);
132 gtk_button_set_label(GTK_BUTTON(m_widget), wxGTK_CONV(labelGTK));
133 }
134 else
135 wxGenericHyperlinkCtrl::SetLabel(label);
136 }
137
138 void wxHyperlinkCtrl::SetURL(const wxString &uri)
139 {
140 if ( UseNative() )
141 gtk_link_button_set_uri(GTK_LINK_BUTTON(m_widget), wxGTK_CONV(uri));
142 else
143 wxGenericHyperlinkCtrl::SetURL(uri);
144 }
145
146 wxString wxHyperlinkCtrl::GetURL() const
147 {
148 if ( UseNative() )
149 {
150 const gchar *str = gtk_link_button_get_uri(GTK_LINK_BUTTON(m_widget));
151 return wxString::FromUTF8(str);
152 }
153
154 return wxGenericHyperlinkCtrl::GetURL();
155 }
156
157 void wxHyperlinkCtrl::SetNormalColour(const wxColour &colour)
158 {
159 if ( UseNative() )
160 {
161 // simply do nothing: GTK+ does not allow us to change it :(
162 }
163 else
164 wxGenericHyperlinkCtrl::SetNormalColour(colour);
165 }
166
167 wxColour wxHyperlinkCtrl::GetNormalColour() const
168 {
169 wxColour ret;
170 if ( UseNative() )
171 {
172 GdkColor *link_color = NULL;
173
174 // convert GdkColor in wxColour
175 gtk_widget_style_get(m_widget, "link-color", &link_color, NULL);
176 if (link_color)
177 ret = wxColour(*link_color);
178 gdk_color_free (link_color);
179 }
180 else
181 ret = wxGenericHyperlinkCtrl::GetNormalColour();
182
183 return ret;
184 }
185
186 void wxHyperlinkCtrl::SetVisitedColour(const wxColour &colour)
187 {
188 if ( UseNative() )
189 {
190 // simply do nothing: GTK+ does not allow us to change it :(
191 }
192 else
193 wxGenericHyperlinkCtrl::SetVisitedColour(colour);
194 }
195
196 wxColour wxHyperlinkCtrl::GetVisitedColour() const
197 {
198 wxColour ret;
199 if ( UseNative() )
200 {
201 GdkColor *link_color = NULL;
202
203 // convert GdkColor in wxColour
204 gtk_widget_style_get(m_widget, "visited-link-color", &link_color, NULL);
205 if (link_color)
206 ret = wxColour(*link_color);
207 gdk_color_free (link_color);
208 }
209 else
210 return wxGenericHyperlinkCtrl::GetVisitedColour();
211
212 return ret;
213 }
214
215 void wxHyperlinkCtrl::SetHoverColour(const wxColour &colour)
216 {
217 if ( UseNative() )
218 {
219 // simply do nothing: GTK+ does not allow us to change it :(
220 }
221 else
222 wxGenericHyperlinkCtrl::SetHoverColour(colour);
223 }
224
225 wxColour wxHyperlinkCtrl::GetHoverColour() const
226 {
227 if ( UseNative() )
228 {
229 // hover colour == normal colour for native GTK+ widget
230 return GetNormalColour();
231 }
232
233 return wxGenericHyperlinkCtrl::GetHoverColour();
234 }
235
236 GdkWindow *wxHyperlinkCtrl::GTKGetWindow(wxArrayGdkWindows& windows) const
237 {
238 return UseNative() ? GTK_BUTTON(m_widget)->event_window
239 : wxGenericHyperlinkCtrl::GTKGetWindow(windows);
240 }
241
242 #endif // wxUSE_HYPERLINKCTRL && GTK+ 2.10+