#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 . */ #include #include #include namespace Gtk { /** Base class for widget style properties. * * This class manages the value type-agnostic bits of style properties. * * @newin{3,16} */ class GTKMM_API 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() noexcept; /** 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 StyleProperty : public StylePropertyBase { public: typedef T PropertyType; typedef Glib::Value 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 ****************************************/ template StyleProperty::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 StyleProperty::StyleProperty(Gtk::Widget& widget, const Glib::ustring& name, const typename StyleProperty::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 inline typename StyleProperty::PropertyType StyleProperty::get_value() const { PropertyType value; widget_->get_style_property(get_name(), value); return value; } template inline StyleProperty::operator PropertyType() const { return this->get_value(); } #endif /* DOXYGEN_SHOULD_SKIP_THIS */ } // namespace Gtk #endif /* _GTKMM_STYLEPROPERTY_H */