]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/hyperlink.cpp
native wxHyperlinkCtrl implementation for GTK+ 2.10+ (patch 1661851)
[wxWidgets.git] / src / gtk / hyperlink.cpp
diff --git a/src/gtk/hyperlink.cpp b/src/gtk/hyperlink.cpp
new file mode 100644 (file)
index 0000000..4093de2
--- /dev/null
@@ -0,0 +1,248 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        src/gtk/hyperlink.cpp
+// Purpose:     Hyperlink control
+// Author:      Francesco Montorsi
+// Created:     14/2/2007
+// RCS-ID:      $Id$
+// Copyright:   (c) 2007 Francesco Montorsi
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// --------------------------------------------------------------------------
+// headers
+// --------------------------------------------------------------------------
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#if wxUSE_HYPERLINKCTRL && defined(__WXGTK210__)
+
+#include "wx/hyperlink.h"
+
+#ifndef WX_PRECOMP
+#endif
+
+#include <gtk/gtk.h>
+#include "wx/gtk/private.h"
+
+// ----------------------------------------------------------------------------
+// local functions
+// ----------------------------------------------------------------------------
+
+inline bool UseNative()
+{
+    // native gtk_link_button widget is only available in GTK+ 2.10 and later
+    return !gtk_check_version(2, 10, 0);
+}
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+IMPLEMENT_DYNAMIC_CLASS(wxHyperlinkCtrl, wxGenericHyperlinkCtrl)
+
+
+// ----------------------------------------------------------------------------
+// "clicked"
+// ----------------------------------------------------------------------------
+
+extern "C" {
+static void gtk_hyperlink_clicked_callback( GtkWidget *WXUNUSED(widget),
+                                            wxHyperlinkCtrl *linkCtrl )
+{
+    // send the event
+    linkCtrl->SendEvent();
+}
+}
+
+// ----------------------------------------------------------------------------
+// wxHyperlinkCtrl
+// ----------------------------------------------------------------------------
+
+bool wxHyperlinkCtrl::Create(wxWindow *parent, wxWindowID id,
+    const wxString& label, const wxString& url, const wxPoint& pos,
+    const wxSize& size, long style, const wxString& name)
+{
+    if ( UseNative() )
+    {
+        // do validation checks:
+        CheckParams(label, url, style);
+
+        m_needParent = true;
+        m_acceptsFocus = true;
+
+        if (!PreCreation( parent, pos, size ) ||
+            !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
+        {
+            wxFAIL_MSG( wxT("wxHyperlinkCtrl creation failed") );
+            return false;
+        }
+
+        m_widget = gtk_link_button_new("asdfsaf asdfdsaf asdfdsa");
+        gtk_widget_show( GTK_WIDGET(m_widget) );
+
+        // alignment
+        float x_alignment = 0.5;
+        if (HasFlag(wxHL_ALIGN_LEFT))
+            x_alignment = 0.0;
+        else if (HasFlag(wxHL_ALIGN_RIGHT))
+            x_alignment = 1.0;
+        gtk_button_set_alignment(GTK_BUTTON(m_widget), x_alignment, 0.5);
+
+        // set to non empty strings both the url and the label
+        SetURL(url.empty() ? label : url);
+        SetLabel(label.empty() ? url : label);
+
+        // our signal handlers:
+        g_signal_connect_after (m_widget, "clicked",
+                                G_CALLBACK (gtk_hyperlink_clicked_callback),
+                                this);
+
+        m_parent->DoAddChild( this );
+
+        PostCreation(size);
+        SetInitialSize(size);
+
+        // wxWindowGTK will connect to the enter_notify and leave_notify GTK+ signals
+        // thus overriding GTK+'s internal signal handlers which set the cursor of
+        // the widget - thus we need to manually set it here: 
+        SetCursor(wxCursor(wxCURSOR_HAND));
+    }
+    else
+        return wxGenericHyperlinkCtrl::Create(parent, id, label, url, pos, size, style, name);
+
+    return true;
+}
+
+wxSize wxHyperlinkCtrl::DoGetBestSize() const
+{
+    if ( UseNative() )
+        return wxControl::DoGetBestSize();
+    return wxGenericHyperlinkCtrl::DoGetBestSize();
+}
+
+void wxHyperlinkCtrl::SetLabel(const wxString &label)
+{
+    if ( UseNative() )
+    {
+        wxControl::SetLabel(label);
+        const wxString labelGTK = GTKConvertMnemonics(label);
+        gtk_button_set_label(GTK_BUTTON(m_widget), wxGTK_CONV(labelGTK));
+    }
+    else
+        wxGenericHyperlinkCtrl::SetLabel(label);
+}
+
+void wxHyperlinkCtrl::SetURL(const wxString &uri)
+{
+    if ( UseNative() )
+        gtk_link_button_set_uri(GTK_LINK_BUTTON(m_widget), uri.c_str());
+    else
+        wxGenericHyperlinkCtrl::SetURL(uri);
+}
+
+wxString wxHyperlinkCtrl::GetURL() const
+{
+    if ( UseNative() )
+    {
+        const gchar *str = gtk_link_button_get_uri(GTK_LINK_BUTTON(m_widget));
+        return wxConvFileName->cMB2WX(str);
+    }
+
+    return wxGenericHyperlinkCtrl::GetURL();
+}
+
+void wxHyperlinkCtrl::SetNormalColour(const wxColour &colour)
+{
+    if ( UseNative() )
+    {
+        // simply do nothing: GTK+ does not allow us to change it :(
+    }
+    else
+        wxGenericHyperlinkCtrl::SetNormalColour(colour);
+}
+
+wxColour wxHyperlinkCtrl::GetNormalColour() const
+{
+    if ( UseNative() )
+    {
+        GdkColor *link_color = NULL;
+        wxColour ret = wxNullColour;
+
+        // convert GdkColor in wxColour
+        gtk_widget_style_get(m_widget, "link-color", &link_color, NULL);
+        if (link_color)
+            ret.Set(link_color->red, link_color->green, link_color->blue);
+        gdk_color_free (link_color);
+
+        return ret;
+    }
+    else
+        return wxGenericHyperlinkCtrl::GetNormalColour();
+}
+
+void wxHyperlinkCtrl::SetVisitedColour(const wxColour &colour)
+{
+    if ( UseNative() )
+    {
+        // simply do nothing: GTK+ does not allow us to change it :(
+    }
+    else
+        wxGenericHyperlinkCtrl::SetVisitedColour(colour);
+}
+
+wxColour wxHyperlinkCtrl::GetVisitedColour() const
+{
+    if ( UseNative() )
+    {
+        GdkColor *link_color = NULL;
+        wxColour ret = wxNullColour;
+
+        // convert GdkColor in wxColour
+        gtk_widget_style_get(m_widget, "visited-link-color", &link_color, NULL);
+        if (link_color)
+            ret.Set(link_color->red, link_color->green, link_color->blue);
+        gdk_color_free (link_color);
+
+        return ret;
+    }
+    else
+        return wxGenericHyperlinkCtrl::GetVisitedColour();
+}
+
+void wxHyperlinkCtrl::SetHoverColour(const wxColour &colour)
+{
+    if ( UseNative() )
+    {
+        // simply do nothing: GTK+ does not allow us to change it :(
+    }
+    else
+        wxGenericHyperlinkCtrl::SetHoverColour(colour);
+}
+
+wxColour wxHyperlinkCtrl::GetHoverColour() const
+{
+    if ( UseNative() )
+    {
+        // hover colour == normal colour for native GTK+ widget
+        return GetNormalColour();
+    }
+
+    return wxGenericHyperlinkCtrl::GetHoverColour();
+}
+
+GdkWindow *wxHyperlinkCtrl::GTKGetWindow(wxArrayGdkWindows& windows) const
+{
+    return UseNative() ? GTK_BUTTON(m_widget)->event_window
+                       : wxGenericHyperlinkCtrl::GTKGetWindow(windows);
+}
+
+#endif // wxUSE_HYPERLINKCTRL && GTK+ 2.10+