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



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);
    }
  }
};
```


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