Re: Setting custom Glib::Property values in Gtk::Builder .ui XML

Daniel Boles via gtkmm-list <[email protected]>
Newsgroups gmane.comp.gnome.gtkmm
Message-ID <CAKChMKPkt_w0-0r3mNvN1jgWVTiR96wj2EOS-2PAAxStvR8jJA@mail.gmail.com>
So far the only thing I've managed to get working is to use ExtraClassInit
to do all the property installation and get/set handling in C... looking a
bit like this, assuming a derived GtkButton called Button2, with a new
property called :style-class.

I think the crux of the problem is 2fold:
 * We can't handle such properties in C++ because they need to work with C
layers like GtkBuilder, which will never run a C++ constructor or signal or
etc.
 * We need to handle them using the good old C [gs]et_property vfuncs,
otherwise the base G_OBJECT_WARN_INVALID_PROPERTY_ID() gets hit.

with the result being that I think the best we can currently do is some
hybrid of C/C++, where the properties must be implemented in C and then
just wrapped later in C++ for easier consumption.

This is arguably still a bit nicer than doing the whole lot in C, but it
remains to be seen whether it's sustainable enough to be worthwhile, i.e.
whether the benefit of being able to shift programmatic ui generation into
Builder definitions outweights having to add the layer of C boilerplate to
every class.

Of course, I might still be missing something obvious - so I'd definitely
welcome corrections or proof-of-concepts contrary to what I've said/shown
so far!


```c
class ExtraClassInit_Button2: public Glib::ExtraClassInit {
public:
  ExtraClassInit_Button2()
  : Glib::ExtraClassInit(class_init, nullptr, instance_init)
  {}

private:
  enum { PROP_0, PROP_STYLE_CLASS, PROP_COUNT };

  static GParamSpec* s_paramSpecs[PROP_COUNT];

  static void
  class_init(void* const g_class, void* const class_data)
  {
    s_paramSpecs[PROP_STYLE_CLASS] = g_param_spec_string(
      "style-class", "Style Class", "a CSS style class",
      "", G_PARAM_READWRITE);

    auto gObjectClass = G_OBJECT_CLASS(g_class);
    gObjectClass->set_property = &set_property;
    gObjectClass->get_property = &get_property;
    g_object_class_install_properties(gObjectClass, PROP_COUNT,
s_paramSpecs);
  }

  static void
  set_property(GObject* const object, unsigned const property_id,
               const GValue* const value, GParamSpec* const pspec)
  {
    switch (property_id) {
      case PROP_STYLE_CLASS: {
        auto const str = g_value_get_string(value);
        set_style_class(GTK_WIDGET(object), str);
        break;
      }

      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
    }
  }

  static void
  set_style_class(GtkWidget* const widget, char const* const str)
  {
    if (!str) {
      return;
    }

    auto const styleContext = gtk_widget_get_style_context(widget);
    gtk_style_context_add_class (styleContext, str);
  }

  static void
  get_property(GObject* const object, unsigned const property_id,
               GValue* const value, GParamSpec* const pspec)
  {
    switch (property_id) {
      case PROP_STYLE_CLASS:
        g_value_set_string(value, "oops not implemented yet");
        break;

      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
    }
  }
};
```

_______________________________________________
gtkmm-list mailing list
[email protected]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.