[gtkmm] Gdk::Window, Gtk::StyleContext, Widget: Add FrameClock API



commit e79382f6811b3fcec775e9f960a15ac60828c09a
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date:   Wed Jan 31 13:33:04 2018 +0100

    Gdk::Window, Gtk::StyleContext, Widget: Add FrameClock API
    
    * gdk/src/window.[ccg|hg]: Add get_frame_clock().
    * gtk/src/stylecontext.[ccg|hg]: Add set/get_frame_clock() and
    property_paint_clock().
    * gtk/src/widget.[ccg|hg]: Add get_frame_clock(), add_tick_callback() and
    remove_tick_callback().

 gdk/src/window.ccg       |    1 +
 gdk/src/window.hg        |    4 +++
 gtk/src/stylecontext.ccg |    1 +
 gtk/src/stylecontext.hg  |    9 +++++++
 gtk/src/widget.ccg       |   30 +++++++++++++++++++++++++
 gtk/src/widget.hg        |   54 +++++++++++++++++++++++++++++++++++++++++++--
 6 files changed, 96 insertions(+), 3 deletions(-)
---
diff --git a/gdk/src/window.ccg b/gdk/src/window.ccg
index a640953..a8fc02b 100644
--- a/gdk/src/window.ccg
+++ b/gdk/src/window.ccg
@@ -24,6 +24,7 @@
 #include <gdkmm/glcontext.h>
 #include <gdkmm/drawcontext.h>
 #include <gdkmm/drawingcontext.h>
+#include <gdkmm/frameclock.h>
 
 using Type = Gdk::Window::Type;
 using State = Gdk::Window::State;
diff --git a/gdk/src/window.hg b/gdk/src/window.hg
index 90b2eca..27ed706 100644
--- a/gdk/src/window.hg
+++ b/gdk/src/window.hg
@@ -49,6 +49,7 @@ class Cursor;
 class GLContext;
 class DrawContext;
 class DrawingContext;
+class FrameClock;
 
 /** A Gdk::Window is a rectangular region on the screen. It's a low-level object, used to implement 
high-level objects such
  * as Gtk::Widget and Gtk::Window on the GTK+ level. A Gtk::Window is a toplevel window, the thing a user 
might think of as
@@ -296,6 +297,9 @@ public:
   _WRAP_METHOD(void set_support_multidevice(bool support_multidevice = true), 
gdk_window_set_support_multidevice)
   _WRAP_METHOD(bool get_support_multidevice(), gdk_window_get_support_multidevice)
 
+  _WRAP_METHOD(Glib::RefPtr<FrameClock> get_frame_clock(), gdk_window_get_frame_clock, refreturn, newin 
"3,94")
+  _WRAP_METHOD(Glib::RefPtr<const FrameClock> get_frame_clock() const, gdk_window_get_frame_clock, 
refreturn, constversion, newin "3,94")
+
   //This is const because it returns a copy (though that is not very clear from the C documentation)
   _WRAP_METHOD(::Cairo::RefPtr< ::Cairo::Region> get_clip_region() const, gdk_window_get_clip_region)
 
diff --git a/gtk/src/stylecontext.ccg b/gtk/src/stylecontext.ccg
index 5e3fb20..22c1896 100644
--- a/gtk/src/stylecontext.ccg
+++ b/gtk/src/stylecontext.ccg
@@ -15,6 +15,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <gdkmm/frameclock.h>
 #include <gtkmm/widget.h>
 #include <gtk/gtk.h>
 
diff --git a/gtk/src/stylecontext.hg b/gtk/src/stylecontext.hg
index a95b3c4..d76a48b 100644
--- a/gtk/src/stylecontext.hg
+++ b/gtk/src/stylecontext.hg
@@ -32,6 +32,10 @@ _PINCLUDE(gtk/gtk.h)
 #include <pangomm/layout.h>
 #include <gtkmmconfig.h>
 
+namespace Gdk
+{
+class FrameClock;
+}
 
 namespace Gtk
 {
@@ -152,6 +156,10 @@ public:
   _WRAP_METHOD(Glib::RefPtr<Gdk::Display> get_display(), gtk_style_context_get_display, refreturn)
   _WRAP_METHOD(Glib::RefPtr<const Gdk::Display> get_display() const, gtk_style_context_get_display, 
refreturn, constversion)
 
+  _WRAP_METHOD(void set_frame_clock(const Glib::RefPtr<Gdk::FrameClock>& frame_clock), 
gtk_style_context_set_frame_clock, newin "3,94")
+  _WRAP_METHOD(Glib::RefPtr<Gdk::FrameClock> get_frame_clock(), gtk_style_context_get_frame_clock, 
refreturn, newin "3,94")
+  _WRAP_METHOD(Glib::RefPtr<const Gdk::FrameClock> get_frame_clock() const, 
gtk_style_context_get_frame_clock, refreturn, constversion, newin "3,94")
+
   _WRAP_METHOD(bool lookup_color(const Glib::ustring& color_name, Gdk::RGBA& color), 
gtk_style_context_lookup_color)
 
   /** Gets the foreground color for a given state.
@@ -201,6 +209,7 @@ public:
 
   _WRAP_SIGNAL(void changed(), "changed")
   _WRAP_PROPERTY("display", Glib::RefPtr<Gdk::Display>)
+  _WRAP_PROPERTY("paint-clock", Glib::RefPtr<Gdk::FrameClock>, newin "3,94")
   _WRAP_PROPERTY("parent", Glib::RefPtr<StyleContext>)
 };
 
diff --git a/gtk/src/widget.ccg b/gtk/src/widget.ccg
index ada65b6..ebddab4 100644
--- a/gtk/src/widget.ccg
+++ b/gtk/src/widget.ccg
@@ -18,6 +18,7 @@
 #include <glibmm/vectorutils.h>
 
 #include <gdkmm/contentformats.h>
+#include <gdkmm/frameclock.h>
 #include <gtkmm/adjustment.h>
 #include <gtkmm/window.h>
 #include <gtkmm/accelgroup.h>
@@ -82,6 +83,24 @@ static void Widget_signal_drag_data_get_callback(GtkWidget* self, GdkDragContext
   }
 }
 
+gboolean SlotTick_gtk_callback(GtkWidget* self, GdkFrameClock* frame_clock, void* data)
+{
+  // Do not try to call a signal on a disassociated wrapper.
+  if (Glib::ObjectBase::_get_current_wrapper((GObject*)self))
+  {
+    auto the_slot = static_cast<Gtk::Widget::SlotTick*>(data);
+    try
+    {
+      return (*the_slot)(Glib::wrap(frame_clock, true));
+    }
+    catch (...)
+    {
+      Glib::exception_handlers_invoke();
+    }
+  }
+  return false;
+}
+
 } //anonymous
 
 namespace Gtk
@@ -513,4 +532,15 @@ void Widget::set_margin(int margin)
   property_margin() = margin;
 }
 
+guint Widget::add_tick_callback(const SlotTick& slot)
+{
+  // Create a copy of the slot object. A pointer to this will be passed
+  // through the callback's data parameter. It will be deleted
+  // when Glib::destroy_notify_delete<SlotTick>() is called.
+  auto slot_copy = new SlotTick(slot);
+
+  return gtk_widget_add_tick_callback(gobj(), &SlotTick_gtk_callback, slot_copy,
+    &Glib::destroy_notify_delete<SlotTick>);
+}
+
 } // namespace Gtk
diff --git a/gtk/src/widget.hg b/gtk/src/widget.hg
index 5662822..3a7c117 100644
--- a/gtk/src/widget.hg
+++ b/gtk/src/widget.hg
@@ -48,6 +48,7 @@ _PINCLUDE(gtkmm/private/object_p.h)
 namespace Gdk
 {
 class ContentFormats;
+class FrameClock;
 }
 
 namespace Gtk
@@ -464,7 +465,9 @@ public:
   void drag_set_as_icon(const Glib::RefPtr<Gdk::DragContext>& context, int hot_x, int hot_y);
 
   _WRAP_METHOD(void queue_resize_no_redraw(), gtk_widget_queue_resize_no_redraw)
-  //TODO: _WRAP_METHOD(GdkFrameClock* get_frame_clock(), gtk_widget_get_frame_clock)
+
+  _WRAP_METHOD(Glib::RefPtr<Gdk::FrameClock> get_frame_clock(), gtk_widget_get_frame_clock, refreturn, newin 
"3,94")
+  _WRAP_METHOD(Glib::RefPtr<const Gdk::FrameClock> get_frame_clock()const, gtk_widget_get_frame_clock, 
refreturn, constversion, newin "3,94")
 
   //Used when implementing containers:
   _WRAP_METHOD(void set_parent(Widget& parent), gtk_widget_set_parent)
@@ -493,8 +496,53 @@ public:
 
   _WRAP_METHOD(Gdk::ModifierType get_modifier_mask(Gdk::ModifierIntent intent), gtk_widget_get_modifier_mask)
 
-//TODO: guint gtk_widget_add_tick_callback (GtkWidget *widget,  GtkTickCallback callback, gpointer 
user_data, GDestroyNotify   notify);
-//TODO: void gtk_widget_remove_tick_callback (GtkWidget *widget,  guint id);
+  /** Callback type for adding a function to update animations. See add_tick_callback().
+   *
+   * For instance:
+   * @code
+   * bool on_tick(const Glib::RefPtr<Gdk::FrameClock>& frame_clock);
+   * @endcode
+   *
+   * @param frame_clock The frame clock for the widget (same as calling get_frame_clock()).
+   * @return <tt>true</tt> if the tick callback should continue to be called,
+   *         <tt>false</tt> if the tick callback should be removed.
+   *
+   * @newin{3,94}
+   */
+  using SlotTick = sigc::slot<bool(const Glib::RefPtr<Gdk::FrameClock>&)>;
+
+  /** Queues an animation frame update and adds a callback to be called
+   * before each frame.
+   *
+   * Until the tick callback is removed, it will be
+   * called frequently (usually at the frame rate of the output device
+   * or as quickly as the application can be repainted, whichever is
+   * slower). For this reason, is most suitable for handling graphics
+   * that change every frame or every few frames. The tick callback does
+   * not automatically imply a relayout or repaint. If you want a
+   * repaint or relayout, and aren’t changing widget properties that
+   * would trigger that (for example, changing the text of a Gtk::Label),
+   * then you will have to call queue_resize() or queue_draw_area() yourself.
+   *
+   * Gdk::FrameClock::get_frame_time() should generally be used for timing
+   * continuous animations and
+   * Gdk::FrameTimings::get_predicted_presentation_time() if you are
+   * trying to display isolated frames at particular times.
+   *
+   * This is a more convenient alternative to connecting directly to the
+   * Gdk::FrameClock::signal_update() signal of Gdk::FrameClock, since you don't
+   * have to worry about when a Gdk::FrameClock is assigned to a widget.
+   *
+   * @newin{3,94}
+   *
+   * @param slot Slot to call for updating animations.
+   * @return An id for the connection of this callback. Remove the callback
+   *         by passing it to remove_tick_callback().
+   */
+  guint add_tick_callback(const SlotTick& slot);
+  _IGNORE(gtk_widget_add_tick_callback)
+
+  _WRAP_METHOD(void remove_tick_callback(guint id), gtk_widget_remove_tick_callback, newin "3,94")
 
   //This is mostly only needed by the class itself, so it could be protected,
   //but it is sometimes helpful to call it from outside:


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