[gtkmm-documentation/gtkmm-3-24] custom_widget example: Use Glib::ExtraClassInit



commit f12fe14fbf54a457ddf49cbe3c8851131bceb2f1
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date:   Tue Mar 19 18:18:40 2019 +0100

    custom_widget example: Use Glib::ExtraClassInit
    
    Add MyExtraInit that calls gtk_widget_class_set_css_name() in the class init
    function and calls gtk_widget_set_has_window() in the instance init function.
    See glibmm#33

 examples/Makefile.am                              |  2 +
 examples/book/custom/custom_widget/custom_gtk.css |  6 ++-
 examples/book/custom/custom_widget/myextrainit.cc | 55 +++++++++++++++++++++++
 examples/book/custom/custom_widget/myextrainit.h  | 42 +++++++++++++++++
 examples/book/custom/custom_widget/mywidget.cc    | 25 ++++++-----
 examples/book/custom/custom_widget/mywidget.h     |  5 +++
 6 files changed, 124 insertions(+), 11 deletions(-)
---
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 74142f0..465d3bc 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -292,6 +292,8 @@ book_custom_custom_widget_example_SOURCES =         \
        book/custom/custom_widget/examplewindow.cc      \
        book/custom/custom_widget/examplewindow.h       \
        book/custom/custom_widget/main.cc               \
+       book/custom/custom_widget/myextrainit.cc \
+       book/custom/custom_widget/myextrainit.h \
        book/custom/custom_widget/mywidget.cc           \
        book/custom/custom_widget/mywidget.h
 
diff --git a/examples/book/custom/custom_widget/custom_gtk.css 
b/examples/book/custom/custom_widget/custom_gtk.css
index dbdd7f7..7e59d8f 100644
--- a/examples/book/custom/custom_widget/custom_gtk.css
+++ b/examples/book/custom/custom_widget/custom_gtk.css
@@ -9,8 +9,12 @@
   -gtkmm__CustomObject_mywidget-example-scale: 920;
 }
 
-#my-widget {
+my-widget-class {
   background-color: rgb(255,0,0);
   color:            rgb(0,0,255);
 }
+#my-widget-instance {
+  background-color: rgb(255,128,0);
+  color:            rgb(0,0,255);
+}
 
diff --git a/examples/book/custom/custom_widget/myextrainit.cc 
b/examples/book/custom/custom_widget/myextrainit.cc
new file mode 100644
index 0000000..fc2d7ae
--- /dev/null
+++ b/examples/book/custom/custom_widget/myextrainit.cc
@@ -0,0 +1,55 @@
+/* gtkmm example Copyright (C) 2017 gtkmm development team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "myextrainit.h"
+#include <gtkmm/widget.h>
+#include <gtk/gtk.h>
+
+#if HAS_EXTRA_CLASS_INIT
+
+namespace
+{
+using BaseObjectType = GtkWidget;
+using BaseClassType = GtkWidgetClass;
+
+// Extra class init function.
+void class_init_function(void* g_class, void* class_data)
+{
+  g_return_if_fail(GTK_IS_WIDGET_CLASS(g_class));
+
+  const auto klass = static_cast<BaseClassType*>(g_class);
+  const auto css_name = static_cast<Glib::ustring*>(class_data);
+
+  gtk_widget_class_set_css_name(klass, css_name->c_str());
+}
+
+// Extra instance init function.
+void instance_init_function(GTypeInstance* instance, void* /* g_class */)
+{
+  g_return_if_fail(GTK_IS_WIDGET(instance));
+
+  gtk_widget_set_has_window(GTK_WIDGET(instance), true);
+}
+
+} // anonymous namespace
+
+MyExtraInit::MyExtraInit(const Glib::ustring& css_name)
+:
+Glib::ExtraClassInit(class_init_function, &m_css_name, instance_init_function),
+m_css_name(css_name)
+{
+}
+
+#endif // HAS_EXTRA_CLASS_INIT
diff --git a/examples/book/custom/custom_widget/myextrainit.h 
b/examples/book/custom/custom_widget/myextrainit.h
new file mode 100644
index 0000000..74c21c7
--- /dev/null
+++ b/examples/book/custom/custom_widget/myextrainit.h
@@ -0,0 +1,42 @@
+/* gtkmm example Copyright (C) 2017 gtkmm development team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GTKMM_CUSTOM_WIDGET_MYEXTRAINIT_H
+#define GTKMM_CUSTOM_WIDGET_MYEXTRAINIT_H
+
+#include <glibmmconfig.h>
+
+#define HAS_EXTRA_CLASS_INIT (GLIBMM_MAJOR_VERSION > 2 || \
+  (GLIBMM_MAJOR_VERSION == 2 && GLIBMM_MINOR_VERSION >= 60))
+
+#if HAS_EXTRA_CLASS_INIT
+
+#include <glibmm/extraclassinit.h>
+#include <glibmm/ustring.h>
+
+// Calls gtk_widget_class_set_css_name() in the class init function
+// and gtk_set_has_window() in the instance init function.
+class MyExtraInit : public Glib::ExtraClassInit
+{
+public:
+  MyExtraInit(const Glib::ustring& css_name);
+
+private:
+  Glib::ustring m_css_name;
+};
+
+#endif // HAS_EXTRA_CLASS_INIT
+
+#endif //GTKMM_CUSTOM_WIDGET_MYEXTRAINIT_H
diff --git a/examples/book/custom/custom_widget/mywidget.cc b/examples/book/custom/custom_widget/mywidget.cc
index b64021f..7843cc5 100644
--- a/examples/book/custom/custom_widget/mywidget.cc
+++ b/examples/book/custom/custom_widget/mywidget.cc
@@ -22,18 +22,25 @@
 
 // The MyWidget class uses API which was added in gtkmm 3.15.3 (Gtk::CssProviderError,
 // Gtk::CssProvider::signal_parsing_error() and Gtk::CssSection) and in gtkmm 3.15.2
-// (Gtk::StyleProperty).
+// (Gtk::StyleProperty) and in glibmm 2.60.0 (Glib::ExtraClassInit).
 
 MyWidget::MyWidget() :
   //The GType name will actually be gtkmm__CustomObject_mywidget
   Glib::ObjectBase("mywidget"),
+#if HAS_EXTRA_CLASS_INIT
+  MyExtraInit("my-widget-class"), // CSS node name, which must be used in the CSS file.
+#endif
   Gtk::Widget(),
   //Install a style property so that an aspect of this widget may be themed
   //via a CSS style sheet file:
   m_scale_prop(*this, "example_scale", 500),
   m_scale(1000)
 {
+#if HAS_EXTRA_CLASS_INIT == 0
   set_has_window(true);
+  // Set the widget name to use in the CSS file.
+  set_name("my-widget-instance");
+#endif
 
   //This shows the GType name, which must be used in the CSS file.
   std::cout << "GType name: " << G_OBJECT_TYPE_NAME(gobj()) << std::endl;
@@ -41,15 +48,13 @@ MyWidget::MyWidget() :
   //This shows that the GType still derives from GtkWidget:
   //std::cout << "Gtype is a GtkWidget?:" << GTK_IS_WIDGET(gobj()) << std::endl;
 
-  // Set the widget name to use in the CSS file.
-  set_name("my-widget");
-
-  // If you make a custom widget in C code, based on gtk+'s GtkWidget, there is
-  // an alternative to gtk_widget_set_name(): Set a CSS name for your custom
-  // class (instead of the widget instance) with gtk_widget_class_set_css_name()
-  // (new in gtk+ 3.19.1). That's not possible for custom widgets defined in gtkmm.
-  // gtk_widget_class_set_css_name() must be called in the class init function,
-  // which can't be customized, when the widget is based on gtkmm's Gtk::Widget.
+  // The CSS name can be set either
+  // - for a GType (in this case for your custom class) with gtk_widget_class_set_css_name(), or
+  // - for a widget instance with gtk_widget_set_name() (Gtk::Widget::set_name()).
+  //
+  // gtk_widget_class_set_css_name() (new in gtk+ 3.19.1), if used, must be called
+  // in the class init function. It has not been wrapped in a C++ function.
+  // Gtk::Widget::set_name() can be called in a C++ constructor.
   //
   // Another alternative: The custom widget inherits the CSS name "widget" from
   // GtkWidget. That name can be used in the CSS file. This is not a very good
diff --git a/examples/book/custom/custom_widget/mywidget.h b/examples/book/custom/custom_widget/mywidget.h
index 6fd6d1a..87d0183 100644
--- a/examples/book/custom/custom_widget/mywidget.h
+++ b/examples/book/custom/custom_widget/mywidget.h
@@ -20,8 +20,13 @@
 #include <gtkmm/widget.h>
 #include <gtkmm/cssprovider.h>
 #include <gtkmm/styleproperty.h>
+#include "myextrainit.h"
 
+#if HAS_EXTRA_CLASS_INIT
+class MyWidget : public MyExtraInit, public Gtk::Widget
+#else
 class MyWidget : public Gtk::Widget
+#endif
 {
 public:
   MyWidget();


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]