[gtk+/wip/baedert/drawing: 100/102] gtk4-demo: Add widgetbowl demo
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/baedert/drawing: 100/102] gtk4-demo: Add widgetbowl demo
- Date: Thu, 29 Jun 2017 15:46:26 +0000 (UTC)
commit 848a5083b13ba1c8f1b2d209d913f5cf19dce1e2
Author: Timm Bäder <mail baedert org>
Date: Thu Jun 29 12:18:40 2017 +0200
gtk4-demo: Add widgetbowl demo
Same as fishbowl, but with widgets
demos/gtk-demo/Makefile.am | 1 +
demos/gtk-demo/fishbowl.c | 1 +
demos/gtk-demo/gtkfishbowl.c | 63 +++++++++------
demos/gtk-demo/gtkfishbowl.h | 3 +
demos/gtk-demo/widgetbowl.c | 179 ++++++++++++++++++++++++++++++++++++++++++
5 files changed, 221 insertions(+), 26 deletions(-)
---
diff --git a/demos/gtk-demo/Makefile.am b/demos/gtk-demo/Makefile.am
index b3bcd7d..ea20c49 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/fishbowl.c b/demos/gtk-demo/fishbowl.c
index db49822..4d87655 100644
--- a/demos/gtk-demo/fishbowl.c
+++ b/demos/gtk-demo/fishbowl.c
@@ -157,6 +157,7 @@ do_fishbowl (GtkWidget *do_widget)
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
bowl = GTK_WIDGET (gtk_builder_get_object (builder, "bowl"));
+ gtk_fishbowl_set_use_icons (GTK_FISHBOWL (bowl), TRUE);
info_label = GTK_WIDGET (gtk_builder_get_object (builder, "info_label"));
allow_changes = GTK_WIDGET (gtk_builder_get_object (builder, "changes_allow"));
gtk_window_set_screen (GTK_WINDOW (window),
diff --git a/demos/gtk-demo/gtkfishbowl.c b/demos/gtk-demo/gtkfishbowl.c
index 447610c..d3343eb 100644
--- a/demos/gtk-demo/gtkfishbowl.c
+++ b/demos/gtk-demo/gtkfishbowl.c
@@ -29,6 +29,8 @@ struct _GtkFishbowlPrivate
gint64 last_frame_time;
guint tick_id;
+
+ guint use_icons: 1;
};
struct _GtkFishbowlChild
@@ -70,6 +72,15 @@ gtk_fishbowl_new (void)
return g_object_new (GTK_TYPE_FISHBOWL, NULL);
}
+void
+gtk_fishbowl_set_use_icons (GtkFishbowl *fishbowl,
+ gboolean use_icons)
+{
+ GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
+
+ priv->use_icons = use_icons;
+}
+
static void
gtk_fishbowl_measure (GtkWidget *widget,
GtkOrientation orientation,
@@ -218,27 +229,6 @@ gtk_fishbowl_forall (GtkContainer *container,
}
}
-static void
-gtk_fishbowl_snapshot (GtkWidget *widget,
- GtkSnapshot *snapshot)
-{
- GtkFishbowl *fishbowl = GTK_FISHBOWL (widget);
- GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
- GtkFishbowlChild *child;
- GList *list;
-
- for (list = priv->children;
- list;
- list = list->next)
- {
- child = list->data;
-
- gtk_widget_snapshot_child (widget,
- child->widget,
- snapshot);
- }
-}
-
static void
gtk_fishbowl_dispose (GObject *object)
{
@@ -311,7 +301,6 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
widget_class->measure = gtk_fishbowl_measure;
widget_class->size_allocate = gtk_fishbowl_size_allocate;
- widget_class->snapshot = gtk_fishbowl_snapshot;
container_class->add = gtk_fishbowl_add;
container_class->remove = gtk_fishbowl_remove;
@@ -382,6 +371,25 @@ get_random_icon_name (GtkIconTheme *theme)
return icon_names[g_random_int_range(0, n_icon_names)];
}
+static GType
+get_random_widget_type ()
+{
+ GType types[] = {
+ GTK_TYPE_SWITCH,
+ GTK_TYPE_BUTTON,
+ GTK_TYPE_ENTRY,
+ GTK_TYPE_SPIN_BUTTON,
+ GTK_TYPE_FONT_BUTTON,
+ GTK_TYPE_SCROLLBAR,
+ GTK_TYPE_SCALE,
+ GTK_TYPE_LEVEL_BAR,
+ GTK_TYPE_PROGRESS_BAR,
+ GTK_TYPE_RADIO_BUTTON,
+ GTK_TYPE_CHECK_BUTTON
+ };
+ return types[g_random_int_range (0, G_N_ELEMENTS (types))];
+}
+
void
gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
guint count)
@@ -399,10 +407,13 @@ gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
while (priv->count < count)
{
GtkWidget *new_widget;
-
- new_widget = gtk_image_new_from_icon_name (get_random_icon_name (gtk_icon_theme_get_default ()),
- GTK_ICON_SIZE_DIALOG);
- gtk_widget_show (new_widget);
+
+ if (priv->use_icons)
+ new_widget = gtk_image_new_from_icon_name (get_random_icon_name (gtk_icon_theme_get_default ()),
+ GTK_ICON_SIZE_DIALOG);
+ else
+ new_widget = g_object_new (get_random_widget_type (), NULL);
+
gtk_container_add (GTK_CONTAINER (fishbowl), new_widget);
}
diff --git a/demos/gtk-demo/gtkfishbowl.h b/demos/gtk-demo/gtkfishbowl.h
index 2ac1ad1..b1559d0 100644
--- a/demos/gtk-demo/gtkfishbowl.h
+++ b/demos/gtk-demo/gtkfishbowl.h
@@ -46,6 +46,9 @@ GType gtk_fishbowl_get_type (void) G_GNUC_CONST;
GtkWidget* gtk_fishbowl_new (void);
+void gtk_fishbowl_set_use_icons (GtkFishbowl *fishbowl,
+ gboolean use_icons);
+
guint gtk_fishbowl_get_count (GtkFishbowl *fishbowl);
void gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
guint count);
diff --git a/demos/gtk-demo/widgetbowl.c b/demos/gtk-demo/widgetbowl.c
new file mode 100644
index 0000000..b64d2c4
--- /dev/null
+++ b/demos/gtk-demo/widgetbowl.c
@@ -0,0 +1,179 @@
+/* Benchmark/Widgetbowl
+ *
+ * This demo models the fishbowl demos seen on the web in a GTK way.
+ * It's also a neat little tool to see how fast your computer (or
+ * your GTK version) is.
+ */
+
+#include <gtk/gtk.h>
+
+#include "gtkfishbowl.h"
+
+GtkWidget *allow_changes;
+
+#define N_STATS 5
+
+#define STATS_UPDATE_TIME G_USEC_PER_SEC
+
+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 ("icons - %.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,
+ !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (allow_changes)) ? &suggested_change : NULL);
+
+ gtk_fishbowl_set_count (GTK_FISHBOWL (bowl),
+ gtk_fishbowl_get_count (GTK_FISHBOWL (bowl)) + suggested_change);
+ stats_update (bowl);
+
+ return G_SOURCE_CONTINUE;
+}
+
+GtkWidget *
+do_widgetbowl (GtkWidget *do_widget)
+{
+ static GtkWidget *window = NULL;
+
+ if (!window)
+ {
+ GtkBuilder *builder;
+ GtkWidget *bowl, *info_label;
+
+ g_type_ensure (GTK_TYPE_FISHBOWL);
+
+ builder = gtk_builder_new_from_resource ("/fishbowl/fishbowl.ui");
+ gtk_builder_connect_signals (builder, NULL);
+ window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
+ bowl = GTK_WIDGET (gtk_builder_get_object (builder, "bowl"));
+ gtk_fishbowl_set_use_icons (GTK_FISHBOWL (bowl), FALSE);
+ info_label = GTK_WIDGET (gtk_builder_get_object (builder, "info_label"));
+ allow_changes = GTK_WIDGET (gtk_builder_get_object (builder, "changes_allow"));
+ gtk_window_set_screen (GTK_WINDOW (window),
+ gtk_widget_get_screen (do_widget));
+ g_signal_connect (window, "destroy",
+ G_CALLBACK (gtk_widget_destroyed), &window);
+
+ gtk_widget_realize (window);
+ gtk_widget_add_tick_callback (bowl, move_fish, info_label, NULL);
+ }
+
+ if (!gtk_widget_get_visible (window))
+ gtk_widget_show (window);
+ else
+ gtk_widget_destroy (window);
+
+
+ return window;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]