[gtk+] widget-factory: Improve the flow box example



commit 79f4d5d61032b330484fca67f103a5a72340818a
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Aug 12 22:14:21 2014 -0400

    widget-factory: Improve the flow box example
    
    Make the selection actually do something. This is also an opportunity
    to test the new draw-layer vfunc in GtkTextView.

 demos/widget-factory/widget-factory.c  |  143 ++++++++++++++++++++++++++++++-
 demos/widget-factory/widget-factory.ui |   23 ++----
 2 files changed, 146 insertions(+), 20 deletions(-)
---
diff --git a/demos/widget-factory/widget-factory.c b/demos/widget-factory/widget-factory.c
index 58cd5e5..2a868d2 100644
--- a/demos/widget-factory/widget-factory.c
+++ b/demos/widget-factory/widget-factory.c
@@ -531,12 +531,17 @@ populate_colors (GtkWidget *widget)
   gtk_list_box_invalidate_headers (GTK_LIST_BOX (widget));
 }
 
+typedef struct {
+  GtkWidget *flowbox;
+  gchar *filename;
+} BackgroundData;
+
 static void
 background_loaded_cb (GObject      *source,
                       GAsyncResult *res,
                       gpointer      data)
 {
-  GtkWidget *flowbox = data;
+  BackgroundData *bd = data;
   GtkWidget *child;
   GdkPixbuf *pixbuf;
   GError *error = NULL;
@@ -551,7 +556,10 @@ background_loaded_cb (GObject      *source,
 
   child = gtk_image_new_from_pixbuf (pixbuf);
   gtk_widget_show (child);
-  gtk_flow_box_insert (GTK_FLOW_BOX (flowbox), child, -1);
+  gtk_flow_box_insert (GTK_FLOW_BOX (bd->flowbox), child, -1);
+  child = gtk_widget_get_parent (child);
+  g_object_set_data_full (G_OBJECT (child), "filename", bd->filename, g_free);
+  g_free (bd);
 }
 
 static void
@@ -564,9 +572,18 @@ populate_flowbox (GtkWidget *button, GtkWidget *flowbox)
   gchar *filename;
   GFile *file;
   GInputStream *stream;
+  BackgroundData *bd;
+  GdkPixbuf *pixbuf;
+  GtkWidget *child;
 
   g_signal_handlers_disconnect_by_func (button, populate_flowbox, flowbox);
 
+  pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 110, 70);
+  gdk_pixbuf_fill (pixbuf, 0xffffffff);
+  child = gtk_image_new_from_pixbuf (pixbuf);
+  gtk_widget_show (child);
+  gtk_flow_box_insert (GTK_FLOW_BOX (flowbox), child, -1);
+
   location = "/usr/share/backgrounds/gnome";
   dir = g_dir_open (location, 0, &error);
   if (error)
@@ -585,16 +602,19 @@ populate_flowbox (GtkWidget *button, GtkWidget *flowbox)
         {
           g_warning ("%s", error->message);
           g_clear_error (&error);
+          g_free (filename); 
         }
       else
         {
+          bd = g_new (BackgroundData, 1);
+          bd->flowbox = flowbox;
+          bd->filename = filename;
           gdk_pixbuf_new_from_stream_at_scale_async (stream, 110, 110, TRUE, NULL, 
-                                                     background_loaded_cb, flowbox);
+                                                     background_loaded_cb, bd);
         }
 
       g_object_unref (file);
       g_object_unref (stream);
-      g_free (filename); 
     }
 
   g_dir_close (dir);
@@ -643,6 +663,116 @@ set_accel (GtkApplication *app, GtkWidget *widget)
   g_strfreev (accels);
 }
 
+typedef struct
+{
+  GtkTextView tv;
+  cairo_surface_t *surface;
+} MyTextView;
+
+typedef GtkTextViewClass MyTextViewClass;
+
+G_DEFINE_TYPE (MyTextView, my_text_view, GTK_TYPE_TEXT_VIEW)
+
+static void
+my_text_view_init (MyTextView *tv)
+{
+}
+
+static void
+my_tv_draw_layer (GtkWidget *widget, GtkTextViewLayer layer, cairo_t *cr)
+{
+  MyTextView *tv = (MyTextView *)widget;
+
+  if (layer == GTK_TEXT_VIEW_LAYER_BELOW && tv->surface)
+    {
+      cairo_save (cr);
+      cairo_set_source_surface (cr, tv->surface, 0.0, 0.0);
+      cairo_paint_with_alpha (cr, 0.333);
+      cairo_restore (cr);
+    }
+}
+
+static void
+my_tv_finalize (GObject *object)
+{
+  MyTextView *tv = (MyTextView *)object;
+
+  if (tv->surface)
+    cairo_surface_destroy (tv->surface);
+
+  G_OBJECT_CLASS (my_text_view_parent_class)->finalize (object);
+}
+
+static void
+my_text_view_class_init (MyTextViewClass *class)
+{
+  GtkTextViewClass *tv_class = GTK_TEXT_VIEW_CLASS (class);
+  GObjectClass *o_class = G_OBJECT_CLASS (class);
+
+  o_class->finalize = my_tv_finalize;
+  tv_class->draw_layer = my_tv_draw_layer;
+}
+
+static void
+my_text_view_set_background (MyTextView *tv, const gchar *filename)
+{
+  GdkPixbuf *pixbuf;
+  GError *error = NULL;
+
+  if (tv->surface)
+    cairo_surface_destroy (tv->surface);
+
+  tv->surface = NULL;
+
+  if (filename == NULL)
+    return;
+
+  pixbuf = gdk_pixbuf_new_from_file (filename, &error);
+  if (error)
+    {
+      g_warning ("%s", error->message);
+      g_error_free (error);
+      return;
+    }
+
+  tv->surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 1, NULL);
+
+  g_object_unref (pixbuf);
+
+  gtk_widget_queue_draw (GTK_WIDGET (tv));
+}
+
+static void
+close_selection_dialog (GtkWidget *dialog, gint response, GtkWidget *tv)
+{
+  GtkWidget *box;
+  GtkWidget *child;
+  GList *children;
+  const gchar *filename;
+
+  gtk_widget_hide (dialog);
+
+  if (response == GTK_RESPONSE_CANCEL)
+    return;
+
+  box = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+  children = gtk_container_get_children (GTK_CONTAINER (box));
+  box = children->data;
+  g_list_free (children);
+  g_assert (GTK_IS_FLOW_BOX (box));
+  children = gtk_flow_box_get_selected_children (GTK_FLOW_BOX (box));
+
+  if (!children)
+    return;
+
+  child = children->data;
+  filename = (const gchar *)g_object_get_data (G_OBJECT (child), "filename");
+
+  g_list_free (children);
+
+  my_text_view_set_background ((MyTextView *)tv, filename);
+}
+
 static void
 activate (GApplication *app)
 {
@@ -670,6 +800,8 @@ activate (GApplication *app)
   };
   gint i;
 
+  g_type_ensure (my_text_view_get_type ());
+
   builder = gtk_builder_new_from_resource ("/org/gtk/WidgetFactory/widget-factory.ui");
   gtk_builder_add_callback_symbol (builder, "on_entry_icon_release", (GCallback)on_entry_icon_release);
   gtk_builder_connect_signals (builder, NULL);
@@ -756,7 +888,8 @@ activate (GApplication *app)
   g_signal_connect (widget, "clicked", G_CALLBACK (show_dialog), dialog);
 
   dialog = (GtkWidget *)gtk_builder_get_object (builder, "selection_dialog");
-  g_signal_connect (dialog, "response", G_CALLBACK (close_dialog), NULL);
+  widget = (GtkWidget *)gtk_builder_get_object (builder, "text3");
+  g_signal_connect (dialog, "response", G_CALLBACK (close_selection_dialog), widget);
   widget = (GtkWidget *)gtk_builder_get_object (builder, "selection_dialog_button");
   g_signal_connect (widget, "clicked", G_CALLBACK (show_dialog), dialog);
 
diff --git a/demos/widget-factory/widget-factory.ui b/demos/widget-factory/widget-factory.ui
index 97e0563..b3c21cd 100644
--- a/demos/widget-factory/widget-factory.ui
+++ b/demos/widget-factory/widget-factory.ui
@@ -2787,7 +2787,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus. </property>
                                     <property name="shadow_type">in</property>
                                     <property name="vexpand">True</property>
                                     <child>
-                                      <object class="GtkTextView">
+                                      <object class="MyTextView" id="text3">
                                         <property name="visible">True</property>
                                         <property name="can_focus">True</property>
                                         <property name="buffer">textbuffer1</property>
@@ -3339,21 +3339,14 @@ bad things might happen.</property>
     <child internal-child="vbox">
       <object class="GtkBox">
         <child>
-          <object class="GtkScrolledWindow">
+          <object class="GtkFlowBox" id="selection_flowbox">
             <property name="visible">True</property>
-            <property name="hscrollbar-policy">never</property>
-            <property name="vscrollbar-policy">never</property>
-            <child>
-              <object class="GtkFlowBox" id="selection_flowbox">
-                <property name="visible">True</property>
-                <property name="selection-mode">single</property>
-                <property name="row-spacing">10</property>
-                <property name="column-spacing">10</property>
-                <property name="margin">10</property>
-                <property name="min-children-per-line">3</property>
-                <property name="max-children-per-line">9</property>
-              </object>
-            </child>
+            <property name="selection-mode">single</property>
+            <property name="row-spacing">10</property>
+            <property name="column-spacing">10</property>
+            <property name="margin">10</property>
+            <property name="min-children-per-line">3</property>
+            <property name="max-children-per-line">9</property>
           </object>
         </child>
       </object>


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