/* LIBPIKA - The PIKA Library * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball * * pikalabelintwidget.c * Copyright (C) 2020 Jehan * * 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 3 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 * Library 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 "config.h" #include #include #include "libpikacolor/pikacolor.h" #include "libpikamath/pikamath.h" #include "libpikabase/pikabase.h" #include "pikalabelintwidget.h" /** * SECTION: pikalabelintwidget * @title: PikaLabelIntWidget * @short_description: Widget containing a label and a widget with an * integer "value" property. * * This widget is a subclass of #PikaLabeled. **/ enum { VALUE_CHANGED, LAST_SIGNAL }; enum { PROP_0, PROP_VALUE, PROP_WIDGET, }; typedef struct _PikaLabelIntWidgetPrivate { PikaLabeled parent_instance; GtkWidget *widget; gint value; } PikaLabelIntWidgetPrivate; static void pika_label_int_widget_constructed (GObject *object); static void pika_label_int_widget_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void pika_label_int_widget_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static GtkWidget * pika_label_int_widget_populate (PikaLabeled *widget, gint *x, gint *y, gint *width, gint *height); G_DEFINE_TYPE_WITH_PRIVATE (PikaLabelIntWidget, pika_label_int_widget, PIKA_TYPE_LABELED) #define parent_class pika_label_int_widget_parent_class static guint pika_label_int_widget_signals[LAST_SIGNAL] = { 0 }; static void pika_label_int_widget_class_init (PikaLabelIntWidgetClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); PikaLabeledClass *labeled_class = PIKA_LABELED_CLASS (klass); pika_label_int_widget_signals[VALUE_CHANGED] = g_signal_new ("value-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (PikaLabelIntWidgetClass, value_changed), NULL, NULL, NULL, G_TYPE_NONE, 0); object_class->constructed = pika_label_int_widget_constructed; object_class->set_property = pika_label_int_widget_set_property; object_class->get_property = pika_label_int_widget_get_property; labeled_class->populate = pika_label_int_widget_populate; /** * PikaLabelIntWidget:value: * * The currently set value. * * Since: 3.0 **/ g_object_class_install_property (object_class, PROP_VALUE, g_param_spec_int ("value", NULL, "Current value", G_MININT, G_MAXINT, 0, PIKA_PARAM_READWRITE)); /** * PikaLabelIntWidget:widget: * * The widget holding an integer value. * * Since: 3.0 **/ g_object_class_install_property (object_class, PROP_WIDGET, g_param_spec_object ("widget", NULL, "Integer widget", GTK_TYPE_WIDGET, PIKA_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } static void pika_label_int_widget_init (PikaLabelIntWidget *widget) { } static void pika_label_int_widget_constructed (GObject *object) { PikaLabelIntWidget *widget = PIKA_LABEL_INT_WIDGET (object); PikaLabelIntWidgetPrivate *priv = pika_label_int_widget_get_instance_private (widget); G_OBJECT_CLASS (parent_class)->constructed (object); gtk_grid_set_column_spacing (GTK_GRID (widget), 6); gtk_grid_set_row_spacing (GTK_GRID (widget), 6); /* This is important to make this object into a property widget. It * will allow config object to bind the "value" property of this * widget, and therefore be updated automatically. */ g_object_bind_property (G_OBJECT (priv->widget), "value", object, "value", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); } static void pika_label_int_widget_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { PikaLabelIntWidget *widget = PIKA_LABEL_INT_WIDGET (object); PikaLabelIntWidgetPrivate *priv = pika_label_int_widget_get_instance_private (widget); switch (property_id) { case PROP_VALUE: priv->value = g_value_get_int (value); g_signal_emit (object, pika_label_int_widget_signals[VALUE_CHANGED], 0); break; case PROP_WIDGET: priv->widget = g_value_get_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void pika_label_int_widget_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { PikaLabelIntWidget *widget = PIKA_LABEL_INT_WIDGET (object); PikaLabelIntWidgetPrivate *priv = pika_label_int_widget_get_instance_private (widget); switch (property_id) { case PROP_VALUE: g_value_set_int (value, priv->value); break; case PROP_WIDGET: g_value_set_object (value, priv->widget); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static GtkWidget * pika_label_int_widget_populate (PikaLabeled *labeled, gint *x, gint *y, gint *width, gint *height) { PikaLabelIntWidget *widget = PIKA_LABEL_INT_WIDGET (labeled); PikaLabelIntWidgetPrivate *priv = pika_label_int_widget_get_instance_private (widget); gtk_grid_attach (GTK_GRID (widget), priv->widget, 1, 0, 1, 1); gtk_widget_show (priv->widget); return priv->widget; } /* Public Functions */ /** * pika_label_int_widget_new: * @text: The text for the #GtkLabel. * @widget: (transfer full): The #GtkWidget to use. * * Creates a new #PikaLabelIntWidget whose "value" property is bound to * that of @widget (which must therefore have such an integer property). * * Returns: (transfer full): The new #PikaLabelIntWidget widget. **/ GtkWidget * pika_label_int_widget_new (const gchar *text, GtkWidget *widget) { GtkWidget *int_widget; GParamSpec *pspec; g_return_val_if_fail ((pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (widget), "value")) && G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_INT, NULL); int_widget = g_object_new (PIKA_TYPE_LABEL_INT_WIDGET, "label", text, "widget", widget, NULL); return int_widget; } /** * pika_label_int_widget_get_widget: * @widget: the #PikaLabelIntWidget. * * Returns: (transfer none): The new #GtkWidget packed next to the label. **/ GtkWidget * pika_label_int_widget_get_widget (PikaLabelIntWidget *widget) { PikaLabelIntWidgetPrivate *priv; g_return_val_if_fail (PIKA_IS_LABEL_INT_WIDGET (widget), NULL); priv = pika_label_int_widget_get_instance_private (widget); return priv->widget; }