[gtkmm] Gtk::Widget: Add new vfuncs. Don't wrap signal_draw().
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtkmm] Gtk::Widget: Add new vfuncs. Don't wrap signal_draw().
- Date: Sun, 22 Jan 2017 18:05:08 +0000 (UTC)
commit d3c714b0d46521c0e9e9b52c10a8bed3591e261d
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date: Sun Jan 22 19:00:01 2017 +0100
Gtk::Widget: Add new vfuncs. Don't wrap signal_draw().
gtk/src/gtk_vfuncs.defs: Add new vfuncs.
gtk/src/widget.[ccg|hg]: Add compute_expand_vfunc(), queue_draw_region_vfunc(),
queue_draw_child_vfunc(). Add comments saying that signal_draw() and
snapshot_vfunc() shall not be wrapped in Gtk::Widget.
gtk/src/gtk_vfuncs.defs | 49 +++++++++++++++++++++++++++++-------
gtk/src/widget.ccg | 62 +++++++++++++++++++++++++++++++++++++++++++++++
gtk/src/widget.hg | 35 ++++++++++++++++++--------
3 files changed, 125 insertions(+), 21 deletions(-)
---
diff --git a/gtk/src/gtk_vfuncs.defs b/gtk/src/gtk_vfuncs.defs
index 8c8a543..ca3d8f9 100644
--- a/gtk/src/gtk_vfuncs.defs
+++ b/gtk/src/gtk_vfuncs.defs
@@ -689,16 +689,6 @@
)
)
-(define-vfunc show_all
- (of-object "GtkWidget")
- (return-type "none")
-)
-
-(define-vfunc get_accessible
- (of-object "GtkWidget")
- (return-type "AtkObject*")
-)
-
(define-vfunc get_request_mode
(of-object "GtkWidget")
(return-type "GtkSizeRequestMode")
@@ -717,6 +707,45 @@
)
)
+(define-vfunc get_accessible
+ (of-object "GtkWidget")
+ (return-type "AtkObject*")
+)
+
+(define-vfunc compute_expand
+ (of-object "GtkWidget")
+ (return-type "void")
+ (parameters
+ '("gboolean*" "hexpand_p")
+ '("gboolean*" "vexpand_p")
+ )
+)
+
+(define-vfunc queue_draw_region
+ (of-object "GtkWidget")
+ (return-type "void")
+ (parameters
+ '("const-cairo_region_t*" "region")
+ )
+)
+
+(define-vfunc queue_draw_child
+ (of-object "GtkWidget")
+ (return-type "void")
+ (parameters
+ '("GtkWidget*" "child")
+ '("const-cairo_region_t*" "region")
+ )
+)
+
+(define-vfunc snapshot
+ (of-object "GtkWidget")
+ (return-type "void")
+ (parameters
+ '("GtkSnapshot*" "snapshot")
+ )
+)
+
; GtkRecentChooser
(define-vfunc set_current_uri
diff --git a/gtk/src/widget.ccg b/gtk/src/widget.ccg
index d32c2ed..0501b4c 100644
--- a/gtk/src/widget.ccg
+++ b/gtk/src/widget.ccg
@@ -274,6 +274,68 @@ void Widget_Class::measure_vfunc_callback(GtkWidget* self, GtkOrientation orient
(*base->measure)(self, orientation, for_size, minimum, natural, minimum_baseline, natural_baseline);
}
+// This vfunc callback and the corresponding vfunc are custom implemented because we want
+// the output arguments of the C++ vfunc to be bool& (not gboolean* or gboolean&).
+void Widget_Class::compute_expand_vfunc_callback(GtkWidget* self, gboolean* hexpand_p, gboolean* vexpand_p)
+{
+ const auto obj_base = static_cast<Glib::ObjectBase*>(
+ Glib::ObjectBase::_get_current_wrapper((GObject*)self));
+
+ // Non-gtkmmproc-generated custom classes implicitly call the default
+ // Glib::ObjectBase constructor, which sets is_derived_. But gtkmmproc-
+ // generated classes can use this optimisation, which avoids the unnecessary
+ // parameter conversions if there is no possibility of the virtual function
+ // being overridden:
+ if(obj_base && obj_base->is_derived_())
+ {
+ const auto obj = dynamic_cast<CppObjectType* const>(obj_base);
+ if(obj) // This can be NULL during destruction.
+ {
+ try // Trap C++ exceptions which would normally be lost because this is a C callback.
+ {
+ // Call the virtual member method, which derived classes might override.
+ bool hexpand_pcxx = hexpand_p ? *hexpand_p : false;
+ bool vexpand_pcxx = vexpand_p ? *vexpand_p : false;
+ obj->compute_expand_vfunc(hexpand_pcxx, vexpand_pcxx);
+ if (hexpand_p)
+ *hexpand_p = hexpand_pcxx;
+ if (vexpand_p)
+ *vexpand_p = vexpand_pcxx;
+ return;
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+ }
+ }
+
+ BaseClassType *const base = static_cast<BaseClassType*>(
+ g_type_class_peek_parent(G_OBJECT_GET_CLASS(self)) // Get the parent class of the object class (The
original underlying C class).
+ );
+
+ // Call the original underlying C function:
+ if(base && base->compute_expand)
+ (*base->compute_expand)(self, hexpand_p, vexpand_p);
+}
+
+void Gtk::Widget::compute_expand_vfunc(bool& hexpand_p, bool& vexpand_p)
+{
+ const auto base = static_cast<BaseClassType*>(
+ g_type_class_peek_parent(G_OBJECT_GET_CLASS(gobject_)) // Get the parent class of the object class
(The original underlying C class).
+ );
+
+ if(base && base->compute_expand)
+ {
+ gboolean hexpand_pc = hexpand_p;
+ gboolean vexpand_pc = vexpand_p;
+ (*base->compute_expand)(gobj(), &hexpand_pc, &vexpand_pc);
+ hexpand_p = hexpand_pc;
+ vexpand_p = vexpand_pc;
+ }
+}
+
+
Widget::~Widget() noexcept
{}
diff --git a/gtk/src/widget.hg b/gtk/src/widget.hg
index 6f10920..ed387b4 100644
--- a/gtk/src/widget.hg
+++ b/gtk/src/widget.hg
@@ -598,15 +598,14 @@ dnl
_POP()
#m4end
-#m4 _CONVERSION(`cairo_t*',`const ::Cairo::RefPtr< ::Cairo::Context>&',`::Cairo::make_refptr_for_instance<
::Cairo::Context>(new ::Cairo::Context($3, false /* has_reference */))')
- //TODO: no_default_handler is a temporary fix (rather workaround) for the
- // problem with get_render_mode() in gtk+.
- // Most widgets will be correctly drawn, even Gtk::DrawingArea since it now
- // uses a draw function instead of signal_draw().
- // Custom widgets won't be drawn correctly with this workaround.
+ // The draw signal must not be wrapped here. It would interfere with the way
+ // gtk+ selects either the snapshot vfunc or the draw signal for rendering widgets.
+ // Custom widgets that need the draw signal must use a custom rendering widget
+ // that wraps the draw signal.
// https://bugzilla.gnome.org/show_bug.cgi?id=774778
- _WRAP_SIGNAL(bool draw(const ::Cairo::RefPtr< ::Cairo::Context>& cr), "draw", no_default_handler)
+//#m4 _CONVERSION(`cairo_t*',`const ::Cairo::RefPtr< ::Cairo::Context>&',`::Cairo::make_refptr_for_instance<
::Cairo::Context>(new ::Cairo::Context($3, false /* has_reference */))')
//_WRAP_SIGNAL(bool draw(const ::Cairo::RefPtr< ::Cairo::Context>& cr), "draw")
+ _IGNORE_SIGNAL(draw)
/// Event triggered by a key press will widget has focus.
_WRAP_SIGNAL(bool key_press_event(GdkEventKey* key_event), "key_press_event")
@@ -713,12 +712,26 @@ protected:
//comment in GTK+ header: "seldomly overidden"
_WRAP_VFUNC(void dispatch_child_properties_changed(guint, GParamSpec**),
"dispatch_child_properties_changed")
- _WRAP_VFUNC(Glib::RefPtr<Atk::Object> get_accessible(), "get_accessible", refreturn, ifdef
GTKMM_ATKMM_ENABLED)
-
_WRAP_VFUNC(SizeRequestMode get_request_mode() const, get_request_mode)
_WRAP_VFUNC(void measure(Orientation orientation, int for_size, int& minimum, int& natural,
int& minimum_baseline, int& natural_baseline) const, measure, custom_vfunc_callback)
- //TODO: Wrap all the new vfuncs when we can break ABI.
+ _WRAP_VFUNC(Glib::RefPtr<Atk::Object> get_accessible(), "get_accessible", refreturn, ifdef
GTKMM_ATKMM_ENABLED)
+
+ _WRAP_VFUNC(void compute_expand(bool& hexpand_p, bool& vexpand_p), compute_expand,
+ custom_vfunc_callback, custom_vfunc)
+
+#m4 _CONVERSION(`const cairo_region_t*',`const ::Cairo::RefPtr<const
::Cairo::Region>&',`::Cairo::make_refptr_for_instance<const ::Cairo::Region>(new
::Cairo::Region(const_cast<cairo_region_t*>($3), false /* has_reference */))')
+ _WRAP_VFUNC(void queue_draw_region(const ::Cairo::RefPtr<const ::Cairo::Region>& region),
queue_draw_region)
+ _WRAP_VFUNC(void queue_draw_child(Widget& child, const ::Cairo::RefPtr<const ::Cairo::Region>& region),
queue_draw_child)
+
+ // The snapshot vfunc must not be wrapped here. It would interfere with the way
+ // gtk+ selects either the snapshot vfunc or the draw signal for rendering widgets.
+ // Custom widgets that need the snapshot vfunc must use a custom rendering widget
+ // that wraps the snapshot vfunc.
+ // https://bugzilla.gnome.org/show_bug.cgi?id=774778
+//#m4 _CONVERSION(`Snapshot&',`GtkSnapshot*',`($3).gobj()')
+//#m4 _CONVERSION(`GtkSnapshot*',`Snapshot&',`*Glib::wrap($3)')
+ //_WRAP_VFUNC(void snapshot(Snapshot& snapshot), snapshot)
protected:
_CTOR_DEFAULT()
@@ -784,7 +797,7 @@ dnl
#m4end
#m4begin
-dnl// Hook in custom hierarchy_changed callback.
+dnl// Hook in custom parent_set callback.
dnl// It will use the generated callback.
dnl
_PUSH(SECTION_PCC_CLASS_INIT_DEFAULT_SIGNAL_HANDLERS)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]