[gtk/gtk-3-22] demo: Add widgetbowl demo



commit 5d27915aa4c404bd99a0c8aef51cccc24bead4d2
Author: Timm Bäder <mail baedert org>
Date:   Thu Mar 15 21:04:45 2018 +0100

    demo: Add widgetbowl demo
    
    Backported from gtk4.

 demos/gtk-demo/Makefile.am        |   1 +
 demos/gtk-demo/demo.gresource.xml |   1 +
 demos/gtk-demo/widgetbowl.c       | 365 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 367 insertions(+)
---
diff --git a/demos/gtk-demo/Makefile.am b/demos/gtk-demo/Makefile.am
index 261d555ae5..decba7d0e2 100644
--- a/demos/gtk-demo/Makefile.am
+++ b/demos/gtk-demo/Makefile.am
@@ -28,6 +28,7 @@ demos_base =                                  \
        expander.c                              \
         filtermodel.c                          \
        fishbowl.c                              \
+       widgetbowl.c                            \
        foreigndrawing.c                        \
        gestures.c                              \
        glarea.c                                \
diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml
index a02c4843f9..7ab207c692 100644
--- a/demos/gtk-demo/demo.gresource.xml
+++ b/demos/gtk-demo/demo.gresource.xml
@@ -156,6 +156,7 @@
     <file>expander.c</file>
     <file>filtermodel.c</file>
     <file>fishbowl.c</file>
+    <file>widgetbowl.c</file>
     <file>flowbox.c</file>
     <file>foreigndrawing.c</file>
     <file>font_features.c</file>
diff --git a/demos/gtk-demo/widgetbowl.c b/demos/gtk-demo/widgetbowl.c
new file mode 100644
index 0000000000..0b7e5a0ab7
--- /dev/null
+++ b/demos/gtk-demo/widgetbowl.c
@@ -0,0 +1,365 @@
+/* Benchmark/Widgetbowl
+ *
+ * This is a version of the Fishbowl demo that instead shows different
+ * kinds of widgets, which is useful for comparing the rendering performance
+ * of theme specifics.
+ */
+
+#include <gtk/gtk.h>
+
+#include "gtkfishbowl.h"
+
+const char *const css =
+".blurred-button {"
+"  box-shadow: 0px 0px 5px 10px rgba(0, 0, 0, 0.5);"
+"}"
+"";
+
+GtkWidget *fishbowl;
+
+static GtkWidget *
+create_button (void)
+{
+  return gtk_button_new_with_label ("Button");
+}
+static GtkWidget *
+create_blurred_button (void)
+{
+  GtkWidget *w = gtk_button_new ();
+
+  gtk_style_context_add_class (gtk_widget_get_style_context (w), "blurred-button");
+
+  return w;
+}
+
+static GtkWidget *
+create_font_button (void)
+{
+  return gtk_font_button_new ();
+}
+
+static GtkWidget *
+create_level_bar (void)
+{
+  GtkWidget *w = gtk_level_bar_new_for_interval (0, 100);
+
+  gtk_level_bar_set_value (GTK_LEVEL_BAR (w), 50);
+
+  /* Force them to be a bit larger */
+  gtk_widget_set_size_request (w, 200, -1);
+
+  return w;
+}
+
+static GtkWidget *
+create_spinner (void)
+{
+  GtkWidget *w = gtk_spinner_new ();
+
+  gtk_spinner_start (GTK_SPINNER (w));
+
+  return w;
+}
+
+static GtkWidget *
+create_spinbutton (void)
+{
+  GtkWidget *w = gtk_spin_button_new_with_range (0, 10, 1);
+
+  return w;
+}
+
+static GtkWidget *
+create_label (void)
+{
+  GtkWidget *w = gtk_label_new ("pLorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy 
eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.");
+
+  gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
+  gtk_label_set_max_width_chars (GTK_LABEL (w), 100);
+
+  return w;
+}
+
+static const struct {
+  const char *name;
+  GtkWidget * (*create_func) (void);
+} widget_types[] = {
+  { "Button",     create_button         },
+  { "Blurbutton", create_blurred_button },
+  { "Fontbutton", create_font_button    },
+  { "Levelbar"  , create_level_bar      },
+  { "Label"     , create_label          },
+  { "Spinner"   , create_spinner        },
+  { "Spinbutton", create_spinbutton     },
+};
+
+static int selected_widget_type = -1;
+static const int N_WIDGET_TYPES = G_N_ELEMENTS (widget_types);
+
+#define N_STATS 5
+
+#define STATS_UPDATE_TIME G_USEC_PER_SEC
+
+static void
+set_widget_type (GtkWidget *headerbar,
+                 int        widget_type_index)
+{
+  if (widget_type_index == selected_widget_type)
+    return;
+
+  /* Remove everything */
+  gtk_fishbowl_set_count (GTK_FISHBOWL (fishbowl), 0);
+
+  selected_widget_type = widget_type_index;
+
+  gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar),
+                            widget_types[selected_widget_type].name);
+}
+
+
+typedef struct _Stats Stats;
+struct _Stats {
+  gint64 last_stats;
+  gint64 last_frame;
+  gint last_suggestion;
+  guint frame_counter_max;
+
+  guint stats_index;
+  guint frame_counter[N_STATS];
+  guint item_counter[N_STATS];
+};
+
+static Stats *
+get_stats (GtkWidget *widget)
+{
+  static GQuark stats_quark = 0;
+  Stats *stats;
+
+  if (G_UNLIKELY (stats_quark == 0))
+    stats_quark = g_quark_from_static_string ("stats");
+
+  stats = g_object_get_qdata (G_OBJECT (widget), stats_quark);
+  if (stats == NULL)
+    {
+      stats = g_new0 (Stats, 1);
+      g_object_set_qdata_full (G_OBJECT (widget), stats_quark, stats, g_free);
+      stats->last_frame = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
+      stats->last_stats = stats->last_frame;
+    }
+
+  return stats;
+}
+
+static void
+do_stats (GtkWidget *widget,
+          GtkWidget *info_label,
+          gint      *suggested_change)
+{
+  Stats *stats;
+  gint64 frame_time;
+
+  stats = get_stats (widget);
+  frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
+
+  if (stats->last_stats + STATS_UPDATE_TIME < frame_time)
+    {
+      char *new_label;
+      guint i, n_frames;
+
+      n_frames = 0;
+      for (i = 0; i < N_STATS; i++)
+        {
+          n_frames += stats->frame_counter[i];
+        }
+
+      new_label = g_strdup_printf ("widgets - %.1f fps",
+                                   (double) G_USEC_PER_SEC * n_frames
+                                       / (N_STATS * STATS_UPDATE_TIME));
+      gtk_label_set_label (GTK_LABEL (info_label), new_label);
+      g_free (new_label);
+
+      if (stats->frame_counter[stats->stats_index] >= 19 * stats->frame_counter_max / 20)
+        {
+          if (stats->last_suggestion > 0)
+            stats->last_suggestion *= 2;
+          else
+            stats->last_suggestion = 1;
+        }
+      else
+        {
+          if (stats->last_suggestion < 0)
+            stats->last_suggestion--;
+          else
+            stats->last_suggestion = -1;
+          stats->last_suggestion = MAX (stats->last_suggestion, 1 - (int) 
stats->item_counter[stats->stats_index]);
+        }
+
+      stats->stats_index = (stats->stats_index + 1) % N_STATS;
+      stats->frame_counter[stats->stats_index] = 0;
+      stats->item_counter[stats->stats_index] = stats->item_counter[(stats->stats_index + N_STATS - 1) % 
N_STATS];
+      stats->last_stats = frame_time;
+
+      if (suggested_change)
+        *suggested_change = stats->last_suggestion;
+      else
+        stats->last_suggestion = 0;
+    }
+  else
+    {
+      if (suggested_change)
+        *suggested_change = 0;
+    }
+
+  stats->last_frame = frame_time;
+  stats->frame_counter[stats->stats_index]++;
+  stats->frame_counter_max = MAX (stats->frame_counter_max, stats->frame_counter[stats->stats_index]);
+}
+
+static void
+stats_update (GtkWidget *widget)
+{
+  Stats *stats;
+
+  stats = get_stats (widget);
+
+  stats->item_counter[stats->stats_index] = gtk_fishbowl_get_count (GTK_FISHBOWL (widget));
+}
+
+static gboolean
+move_fish (GtkWidget     *bowl,
+           GdkFrameClock *frame_clock,
+           gpointer       info_label)
+{
+  gint suggested_change = 0;
+
+  do_stats (bowl, info_label, &suggested_change);
+
+  if (suggested_change > 0)
+    {
+      int i;
+
+      for (i = 0; i < suggested_change; i ++)
+        {
+          GtkWidget *new_widget = widget_types[selected_widget_type].create_func ();
+
+          gtk_widget_show (new_widget);
+
+          gtk_container_add (GTK_CONTAINER (fishbowl), new_widget);
+
+        }
+    }
+  else if (suggested_change < 0)
+    {
+      gtk_fishbowl_set_count (GTK_FISHBOWL (fishbowl),
+                              gtk_fishbowl_get_count (GTK_FISHBOWL (fishbowl)) + suggested_change);
+    }
+
+  stats_update (bowl);
+
+  return G_SOURCE_CONTINUE;
+}
+
+static void
+next_button_clicked_cb (GtkButton *source,
+                        gpointer   user_data)
+{
+  GtkWidget *headerbar = user_data;
+  int new_index;
+
+  if (selected_widget_type + 1 >= N_WIDGET_TYPES)
+    new_index = 0;
+  else
+    new_index = selected_widget_type + 1;
+
+  set_widget_type (headerbar, new_index);
+}
+
+static void
+prev_button_clicked_cb (GtkButton *source,
+                        gpointer   user_data)
+{
+  GtkWidget *headerbar = user_data;
+  int new_index;
+
+  if (selected_widget_type - 1 < 0)
+    new_index = N_WIDGET_TYPES - 1;
+  else
+    new_index = selected_widget_type - 1;
+
+  set_widget_type (headerbar, new_index);
+}
+
+GtkWidget *
+do_widgetbowl (GtkWidget *do_widget)
+{
+  static GtkWidget *window = NULL;
+  static GtkCssProvider *provider = NULL;
+
+  if (provider == NULL)
+    {
+      provider = gtk_css_provider_new ();
+      gtk_css_provider_load_from_data (provider, css, -1, NULL);
+      gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
+                                                 GTK_STYLE_PROVIDER (provider),
+                                                 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+    }
+
+  if (!window)
+    {
+      GtkWidget *info_label;
+      GtkWidget *count_label;
+      GtkWidget *titlebar;
+      GtkWidget *title_box;
+      GtkWidget *left_box;
+      GtkWidget *next_button;
+      GtkWidget *prev_button;
+
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+      titlebar = gtk_header_bar_new ();
+      gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (titlebar), TRUE);
+      info_label = gtk_label_new ("widget - 00.0 fps");
+      count_label = gtk_label_new ("0");
+      fishbowl = gtk_fishbowl_new ();
+      title_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+      prev_button = gtk_button_new_from_icon_name ("pan-start-symbolic", GTK_ICON_SIZE_BUTTON);
+      next_button = gtk_button_new_from_icon_name ("pan-end-symbolic", GTK_ICON_SIZE_BUTTON);
+      left_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+
+      g_object_bind_property (fishbowl, "count", count_label, "label", 0);
+      g_signal_connect (next_button, "clicked", G_CALLBACK (next_button_clicked_cb), titlebar);
+      g_signal_connect (prev_button, "clicked", G_CALLBACK (prev_button_clicked_cb), titlebar);
+
+      gtk_fishbowl_set_animating (GTK_FISHBOWL (fishbowl), TRUE);
+
+      gtk_widget_set_hexpand (title_box, TRUE);
+      gtk_widget_set_halign (title_box, GTK_ALIGN_END);
+
+      gtk_window_set_titlebar (GTK_WINDOW (window), titlebar);
+      gtk_container_add (GTK_CONTAINER (title_box), count_label);
+      gtk_container_add (GTK_CONTAINER (title_box), info_label);
+      gtk_header_bar_pack_end (GTK_HEADER_BAR (titlebar), title_box);
+      gtk_container_add (GTK_CONTAINER (window), fishbowl);
+
+
+      gtk_style_context_add_class (gtk_widget_get_style_context (left_box), "linked");
+      gtk_container_add (GTK_CONTAINER (left_box), prev_button);
+      gtk_container_add (GTK_CONTAINER (left_box), next_button);
+      gtk_header_bar_pack_start (GTK_HEADER_BAR (titlebar), left_box);
+
+      g_signal_connect (window, "destroy",
+                        G_CALLBACK (gtk_widget_destroyed), &window);
+
+      gtk_widget_realize (window);
+      gtk_widget_add_tick_callback (fishbowl, move_fish, info_label, NULL);
+
+      set_widget_type (titlebar, 0);
+    }
+
+  if (!gtk_widget_get_visible (window))
+    gtk_widget_show_all (window);
+  else
+    gtk_widget_destroy (window);
+
+
+  return window;
+}


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