[gtkmm] Gtk::DrawingArea: Replace the draw signal with a draw function
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtkmm] Gtk::DrawingArea: Replace the draw signal with a draw function
- Date: Thu, 24 Nov 2016 07:58:41 +0000 (UTC)
commit b65429f67f17d639d5b6e4b240a7cf5f7fd4891b
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date: Thu Nov 24 08:55:34 2016 +0100
Gtk::DrawingArea: Replace the draw signal with a draw function
Add set_draw_func() and other new methods and properties.
signal_draw() shall not be used with DrawingArea in gtk+4/gtkmm4.
gtk/src/drawingarea.ccg | 36 ++++++++++++++
gtk/src/drawingarea.hg | 124 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 158 insertions(+), 2 deletions(-)
---
diff --git a/gtk/src/drawingarea.ccg b/gtk/src/drawingarea.ccg
index 031daaa..c80dfa3 100644
--- a/gtk/src/drawingarea.ccg
+++ b/gtk/src/drawingarea.ccg
@@ -18,3 +18,39 @@
#include <gtk/gtk.h>
+namespace
+{
+
+void SignalProxy_Draw_gtk_callback(GtkDrawingArea* /* drawing_area */, cairo_t* cr,
+ int width, int height, void* user_data)
+{
+ auto the_slot = static_cast<Gtk::DrawingArea::SlotDraw*>(user_data);
+ auto cr2 = ::Cairo::RefPtr< ::Cairo::Context>(new ::Cairo::Context(cr, false /* has_reference */));
+
+ try
+ {
+ (*the_slot)(cr2, width, height);
+ }
+ catch (...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+}
+
+} // anonymous namespace
+
+namespace Gtk
+{
+void DrawingArea::set_draw_func(const SlotDraw& 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<SlotDraw> is called.
+ auto slot_copy = new SlotDraw(slot);
+
+ gtk_drawing_area_set_draw_func(gobj(),
+ &SignalProxy_Draw_gtk_callback, slot_copy,
+ &Glib::destroy_notify_delete<SlotDraw>);
+}
+
+} //namespace Gtk
diff --git a/gtk/src/drawingarea.hg b/gtk/src/drawingarea.hg
index 3a78347..4d89620 100644
--- a/gtk/src/drawingarea.hg
+++ b/gtk/src/drawingarea.hg
@@ -26,16 +26,136 @@ namespace Gtk
/** A widget for custom user interface elements.
*
+ * The %DrawingArea widget is used for creating custom user interface
+ * elements. It’s essentially a blank widget; you can draw on it. After
+ * creating a drawing area, the application may want to connect to:
+ *
+ * - Mouse and button press signals to respond to input from
+ * the user. (Use Gtk::Widget::add_events() to enable events
+ * you wish to receive.)
+ *
+ * - Gtk::Widget::signal_realize() to take any necessary actions
+ * when the widget is instantiated on a particular display.
+ * (Create GDK resources in response to this signal.)
+ *
+ * - Gtk::Widget::signal_size_allocate() to take any necessary
+ * actions when the widget changes size.
+ *
+ * - Call set_draw_func() to handle redrawing the contents of the widget.
+ *
+ * The following code portion demonstrates using a drawing
+ * area to display a circle in the normal widget foreground color.
+ *
+ * Note that GDK automatically clears the exposed area before causing a
+ * redraw, and that drawing is implicitly clipped to the exposed
+ * area. If you want to have a theme-provided background, you need
+ * to call Gtk::StyleContext::render_background() in your draw function.
+ *
+ * Simple %DrawingArea usage:
+ * @code
+ * class MyDrawingArea : public Gtk::DrawingArea
+ * {
+ * public:
+ * MyDrawingArea()
+ * {
+ * set_draw_func(sigc::mem_fun(*this, &MyDrawingArea::on_draw));
+ * }
+ *
+ * void on_draw(const Cairo::RefPtr<Cairo::Context>& cr, int width, int height)
+ * {
+ * auto style_context = get_style_context();
+ *
+ * style_context->render_background(cr, 0, 0, width, height);
+ *
+ * cr->arc(width / 2.0, height / 2.0, std::min(width, height) / 2.0, 0, 2 * M_PI);
+ *
+ * auto color = style_context->get_color();
+ * Gdk::Cairo::set_source_rgba(cr, color);
+ *
+ * cr->fill();
+ * }
+ * //...
+ * }; // end MyDrawingArea
+ *
+ * //...
+ * auto area = Gtk::manage(new MyDrawingArea)
+ * area->set_content_width(100);
+ * area->set_content_height(100);
+ * @endcode
+ *
+ * The draw function is normally called when a drawing area first comes
+ * onscreen, or when it’s covered by another window and then uncovered.
+ * You can also force a redraw by adding to the “damage region” of the
+ * drawing area’s window using Gtk::Widget::queue_draw_region(),
+ * Gtk::Widget::queue_draw_area() or Gtk::Widget::queue_draw().
+ * This will cause the drawing area to call the draw function again.
+ *
+ * To receive mouse events on a drawing area, you will need to enable
+ * them with Gtk::Widget::add_events(). To receive keyboard events, you
+ * will need to set the “can-focus” property on the drawing area, and you
+ * should probably draw some user-visible indication that the drawing
+ * area is focused. Use Gtk::Widget::has_focus() in your draw function
+ * to decide whether to draw the focus indicator. See
+ * Gtk::StyleContext::render_focus() for one way to draw focus.
+ *
* @ingroup Widgets
*/
class DrawingArea : public Widget
{
_CLASS_GTKOBJECT(DrawingArea,GtkDrawingArea,GTK_DRAWING_AREA,Gtk::Widget,GtkWidget)
-public:
+public:
_CTOR_DEFAULT
+/** Whenever the drawing area needs to redraw, this slot will be called.
+ *
+ * For instance:
+ * @code
+ * void on_draw(const Cairo::RefPtr<Cairo::Context>& cr, int width, int height);
+ * @endcode
+ *
+ * This slot should exclusively redraw the contents of the drawing area
+ * and must not call any widget functions that cause changes.
+ *
+ * @param cr The context to draw to.
+ * @param width The actual width of the contents. This value will be at least
+ * as wide as property_content_width().
+ * @param height The actual height of the contents. This value will be at least
+ * as high as property_content_height().
+ *
+ * @newin{3,90}
+ */
+ using SlotDraw = sigc::slot<void(const ::Cairo::RefPtr< ::Cairo::Context>&, int, int)>;
+
+ _WRAP_METHOD(void set_content_width(int width), gtk_drawing_area_set_content_width)
+ _WRAP_METHOD(int get_content_width() const, gtk_drawing_area_get_content_width)
+ _WRAP_METHOD(void set_content_height(int width), gtk_drawing_area_set_content_height)
+ _WRAP_METHOD(int get_content_height() const, gtk_drawing_area_get_content_height)
+
+ /** Sets a draw function.
+ *
+ * Setting a draw function is the main thing you want to do when using a drawing
+ * area. It is called whenever GTK needs to draw the contents of the drawing area
+ * to the screen.
+ *
+ * The draw function will be called during the drawing stage of GTK. In the
+ * drawing stage it is not allowed to change properties of any GTK widgets or call
+ * any functions that would cause any properties to be changed.
+ * You should restrict yourself exclusively to drawing your contents in the draw
+ * function.
+ *
+ * If what you are drawing does change, call Gtk::Widget::queue_draw() on the
+ * drawing area. This will call a redraw and will call @a slot again.
+ *
+ * @newin{3,90}
+ *
+ * @param slot Callback that lets you draw the drawing area's contents.
+ */
+ void set_draw_func(const SlotDraw& slot);
+ _IGNORE(gtk_drawing_area_set_draw_func)
+
+ _WRAP_PROPERTY("content-width", int)
+ _WRAP_PROPERTY("content-height", int)
};
} //namespace Gtk
-
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]