[gtkmm] Add Gtk::StyleProperty



commit 20728720ea5930147c0b24b9b6fde87d526fa14e
Author: Mark Vender <markv743 yahoo co uk>
Date:   Thu Nov 13 15:31:37 2014 +0100

    Add Gtk::StyleProperty
    
    * gtk/gtkmm.h: Add styleproperty.h.
    * gtk/gtkmm/filelist.am: Add styleproperty.[h|cc].
    * gtk/gtkmm/styleproperty[h|cc]: New files. Bug #673317.

 gtk/gtkmm.h                |    1 +
 gtk/gtkmm/filelist.am      |    2 +
 gtk/gtkmm/styleproperty.cc |   77 +++++++++++++++++++
 gtk/gtkmm/styleproperty.h  |  182 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 262 insertions(+), 0 deletions(-)
---
diff --git a/gtk/gtkmm.h b/gtk/gtkmm.h
index 886d8ca..8fed08b 100644
--- a/gtk/gtkmm.h
+++ b/gtk/gtkmm.h
@@ -266,6 +266,7 @@ extern const int gtkmm_micro_version;
 #include <gtkmm/stock.h>
 #include <gtkmm/stockitem.h>
 #include <gtkmm/stylecontext.h>
+#include <gtkmm/styleproperty.h>
 #include <gtkmm/switch.h>
 #include <gtkmm/table.h>
 #include <gtkmm/tearoffmenuitem.h>
diff --git a/gtk/gtkmm/filelist.am b/gtk/gtkmm/filelist.am
index 337d6b2..6fa9358 100644
--- a/gtk/gtkmm/filelist.am
+++ b/gtk/gtkmm/filelist.am
@@ -14,6 +14,7 @@ gtkmm_files_extra_any_cc =            \
        object.cc \
        radiobuttongroup.cc             \
        selectiondata_private.cc        \
+       styleproperty.cc \
        targetentry.cc                  \
        treemodelcolumn.cc              \
        treeview_private.cc
@@ -34,6 +35,7 @@ gtkmm_files_extra_any_h =                     \
        object.h \
        radiobuttongroup.h              \
        selectiondata_private.h         \
+       styleproperty.h \
        targetentry.h                   \
        treemodelcolumn.h               \
        treeview_private.h              \
diff --git a/gtk/gtkmm/styleproperty.cc b/gtk/gtkmm/styleproperty.cc
new file mode 100644
index 0000000..92de478
--- /dev/null
+++ b/gtk/gtkmm/styleproperty.cc
@@ -0,0 +1,77 @@
+/* Copyright (C) 2014 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtkmm/styleproperty.h>
+
+#include <gtk/gtk.h>
+
+namespace Gtk
+{
+
+/**** Gtk::StylePropertyBase ***************************************/
+
+StylePropertyBase::StylePropertyBase(Gtk::Widget& widget, GType value_type)
+:
+  widget_     (&widget),
+  value_type_ (value_type),
+  param_spec_ (0)
+{
+}
+
+StylePropertyBase::~StylePropertyBase()
+{
+  if (param_spec_)
+    g_param_spec_unref(param_spec_);
+}
+
+bool StylePropertyBase::lookup_style_property(const Glib::ustring& name)
+{
+  g_assert(param_spec_ == 0);
+
+  param_spec_ = gtk_widget_class_find_style_property(GTK_WIDGET_GET_CLASS(widget_->gobj()), name.c_str());
+
+  if (param_spec_)
+  {
+    g_assert(G_PARAM_SPEC_VALUE_TYPE(param_spec_) == value_type_);
+    g_param_spec_ref(param_spec_);
+  }
+
+  return param_spec_ != 0;
+}
+
+void StylePropertyBase::install_style_property(GParamSpec* param_spec)
+{
+  g_return_if_fail(param_spec != 0);
+
+  gtk_widget_class_install_style_property(GTK_WIDGET_GET_CLASS(widget_->gobj()), param_spec);
+
+  param_spec_ = param_spec;
+  g_param_spec_ref(param_spec_);
+}
+
+const char* StylePropertyBase::get_name_internal() const
+{
+  const char* const name = g_param_spec_get_name(param_spec_);
+  g_return_val_if_fail(name != 0, "");
+  return name;
+}
+
+Glib::ustring StylePropertyBase::get_name() const
+{
+  return Glib::ustring(get_name_internal());
+}
+
+} // namespace Gtk
diff --git a/gtk/gtkmm/styleproperty.h b/gtk/gtkmm/styleproperty.h
new file mode 100644
index 0000000..c03c62c
--- /dev/null
+++ b/gtk/gtkmm/styleproperty.h
@@ -0,0 +1,182 @@
+#ifndef _GTKMM_STYLEPROPERTY_H
+#define _GTKMM_STYLEPROPERTY_H
+
+/* Copyright (C) 2014 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtkmm/widget.h>
+#include <glibmm/ustring.h>
+#include <glibmm/value.h>
+
+namespace Gtk
+{
+
+/** Base class for widget style properties.
+ *
+ * This class manages the value type-agnostic bits of style properties.
+ *
+ * @newin{3,16}
+ */
+class StylePropertyBase
+{
+public:
+
+  /** Returns the name of the style property.
+   */
+  Glib::ustring get_name() const;
+
+protected:
+  Gtk::Widget*    widget_;
+  GType           value_type_;
+  GParamSpec*     param_spec_;
+
+  /** Constructs a style property of type @a value_type for @a widget.
+   * The property is not registered in Gtk, call install_style_property()
+   * in order to do that. The properties are usually installed on the
+   * initialization of the first instance of a widget.
+   */
+  StylePropertyBase(Gtk::Widget& widget, GType value_type);
+  ~StylePropertyBase();
+
+  /** Checks if the style property has already been installed.
+   */
+  bool lookup_style_property(const Glib::ustring& name);
+
+  /** Installs the style property specified by the given @a param_spec.
+   */
+  void install_style_property(GParamSpec* param_spec);
+
+  /** Returns the name of the style property.
+   */
+  const char* get_name_internal() const;
+
+private:
+  // noncopyable
+  StylePropertyBase(const StylePropertyBase&);
+  StylePropertyBase& operator=(const StylePropertyBase&);
+};
+
+/** Represents a widget style property.
+ *
+ * This class maps one to one to a style property of a widget in Gtk. A style
+ * property is similar to object properties (Glib::Property), but its value is
+ * stored in the style object associated with the widget. The style property,
+ * similarly to the object properties, has some global data for each property.
+ * The global data includes the following information about the style property:
+ *  * unique name, used to identify the style property
+ *  * human-readable nickname
+ *  * short description
+ *  * default value, minimum and maximum bounds (applicable depending on the
+ *      type of the style property)
+ *  * flags, defining, among other things, whether the property can be read or
+ *      written
+ *
+ * The StyleProperty class currently supports only the name and default value.
+ * The minimum and maximum bounds are set to the full range of the value. The
+ * nickname and the description are set to empty. The flags are set to indicate that
+ * the property is read-only (this doesn't disallow a style provider to set the
+ * value of the property).
+ *
+ * The global information must be installed into the widget once per property.
+ * This is handled automatically. A reference to the widget must be passed on
+ * the construction of the style property.
+ *
+ * @newin{3,16}
+ */
+template <class T>
+class StyleProperty : public StylePropertyBase
+{
+public:
+  typedef T PropertyType;
+  typedef Glib::Value<T> ValueType;
+
+  /** Constructs a style property for @a widget with @a name. For each instance
+   * of the widget, the same property must be constructed with the same name.
+   */
+  StyleProperty(Gtk::Widget& widget, const Glib::ustring& name);
+
+  /** Constructs a style property for @a widget with @a name and @a default_value.
+   * For each instance of the widget, the same property must be constructed with
+   * the same name and default value.
+   */
+  StyleProperty(Gtk::Widget& widget, const Glib::ustring& name, const PropertyType& default_value);
+
+  /** Returns the value of the style property. Equivalent to
+   * Gtk::Widget::get_style_property(get_name(), PropertyType& value).
+   */
+  inline PropertyType get_value() const;
+
+  /** Returns the value of the style property. Equivalent to
+   * Gtk::Widget::get_style_property(get_name(), PropertyType& value).
+   */
+  inline operator PropertyType() const;
+};
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+/**** Gtk::StyleProperty<T> ****************************************/
+
+template <class T>
+StyleProperty<T>::StyleProperty(Gtk::Widget& widget, const Glib::ustring& name)
+:
+  StylePropertyBase(widget, ValueType::value_type())
+{
+  if (!lookup_style_property(name))
+  {
+    ValueType value;
+    value.init(value_type_);
+    GParamSpec* param_spec = value.create_param_spec(name);
+    param_spec->flags = (GParamFlags)(param_spec->flags & ~G_PARAM_WRITABLE); // value.create_param_spec() 
sets read-write flags
+    install_style_property(param_spec);
+  }
+}
+
+template <class T>
+StyleProperty<T>::StyleProperty(Gtk::Widget& widget, const Glib::ustring& name,
+                      const typename StyleProperty<T>::PropertyType& default_value)
+:
+  StylePropertyBase(widget, ValueType::value_type())
+{
+  if (!lookup_style_property(name))
+  {
+    ValueType value;
+    value.init(value_type_);
+    value.set(default_value);
+    GParamSpec* param_spec = value.create_param_spec(name);
+    param_spec->flags = (GParamFlags)(param_spec->flags & ~G_PARAM_WRITABLE); // value.create_param_spec() 
sets read-write flags
+    install_style_property(param_spec);
+  }
+}
+
+template <class T> inline
+typename StyleProperty<T>::PropertyType StyleProperty<T>::get_value() const
+{
+  PropertyType value;
+  widget_->get_style_property(get_name(), value);
+  return value;
+}
+
+template <class T> inline
+StyleProperty<T>::operator PropertyType() const
+{
+  return this->get_value();
+}
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+} // namespace Gtk
+
+#endif /* _GTKMM_STYLEPROPERTY_H */


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