mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-14 14:20:21 +00:00
gtk4-demo: Add widgetbowl demo
Same as fishbowl, but with widgets
This commit is contained in:
parent
4b0da8682d
commit
a0444b9c42
@ -28,6 +28,7 @@ demos_base = \
|
|||||||
expander.c \
|
expander.c \
|
||||||
filtermodel.c \
|
filtermodel.c \
|
||||||
fishbowl.c \
|
fishbowl.c \
|
||||||
|
widgetbowl.c \
|
||||||
foreigndrawing.c \
|
foreigndrawing.c \
|
||||||
gestures.c \
|
gestures.c \
|
||||||
glarea.c \
|
glarea.c \
|
||||||
|
@ -156,6 +156,7 @@
|
|||||||
<file>expander.c</file>
|
<file>expander.c</file>
|
||||||
<file>filtermodel.c</file>
|
<file>filtermodel.c</file>
|
||||||
<file>fishbowl.c</file>
|
<file>fishbowl.c</file>
|
||||||
|
<file>widgetbowl.c</file>
|
||||||
<file>flowbox.c</file>
|
<file>flowbox.c</file>
|
||||||
<file>foreigndrawing.c</file>
|
<file>foreigndrawing.c</file>
|
||||||
<file>font_features.c</file>
|
<file>font_features.c</file>
|
||||||
|
@ -157,6 +157,7 @@ do_fishbowl (GtkWidget *do_widget)
|
|||||||
gtk_builder_connect_signals (builder, NULL);
|
gtk_builder_connect_signals (builder, NULL);
|
||||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||||
bowl = GTK_WIDGET (gtk_builder_get_object (builder, "bowl"));
|
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"));
|
info_label = GTK_WIDGET (gtk_builder_get_object (builder, "info_label"));
|
||||||
allow_changes = GTK_WIDGET (gtk_builder_get_object (builder, "changes_allow"));
|
allow_changes = GTK_WIDGET (gtk_builder_get_object (builder, "changes_allow"));
|
||||||
gtk_window_set_screen (GTK_WINDOW (window),
|
gtk_window_set_screen (GTK_WINDOW (window),
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="info_label">
|
<object class="GtkLabel" id="info_label">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label">icons - 0 fps</property>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="pack_type">end</property>
|
<property name="pack_type">end</property>
|
||||||
|
@ -29,6 +29,8 @@ struct _GtkFishbowlPrivate
|
|||||||
|
|
||||||
gint64 last_frame_time;
|
gint64 last_frame_time;
|
||||||
guint tick_id;
|
guint tick_id;
|
||||||
|
|
||||||
|
guint use_icons: 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GtkFishbowlChild
|
struct _GtkFishbowlChild
|
||||||
@ -70,6 +72,15 @@ gtk_fishbowl_new (void)
|
|||||||
return g_object_new (GTK_TYPE_FISHBOWL, NULL);
|
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
|
static void
|
||||||
gtk_fishbowl_measure (GtkWidget *widget,
|
gtk_fishbowl_measure (GtkWidget *widget,
|
||||||
GtkOrientation orientation,
|
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
|
static void
|
||||||
gtk_fishbowl_dispose (GObject *object)
|
gtk_fishbowl_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
@ -311,7 +301,6 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
|
|||||||
|
|
||||||
widget_class->measure = gtk_fishbowl_measure;
|
widget_class->measure = gtk_fishbowl_measure;
|
||||||
widget_class->size_allocate = gtk_fishbowl_size_allocate;
|
widget_class->size_allocate = gtk_fishbowl_size_allocate;
|
||||||
widget_class->snapshot = gtk_fishbowl_snapshot;
|
|
||||||
|
|
||||||
container_class->add = gtk_fishbowl_add;
|
container_class->add = gtk_fishbowl_add;
|
||||||
container_class->remove = gtk_fishbowl_remove;
|
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)];
|
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
|
void
|
||||||
gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
|
gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
|
||||||
guint count)
|
guint count)
|
||||||
@ -399,10 +407,13 @@ gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
|
|||||||
while (priv->count < count)
|
while (priv->count < count)
|
||||||
{
|
{
|
||||||
GtkWidget *new_widget;
|
GtkWidget *new_widget;
|
||||||
|
|
||||||
new_widget = gtk_image_new_from_icon_name (get_random_icon_name (gtk_icon_theme_get_default ()),
|
if (priv->use_icons)
|
||||||
GTK_ICON_SIZE_DIALOG);
|
new_widget = gtk_image_new_from_icon_name (get_random_icon_name (gtk_icon_theme_get_default ()),
|
||||||
gtk_widget_show (new_widget);
|
GTK_ICON_SIZE_DIALOG);
|
||||||
|
else
|
||||||
|
new_widget = g_object_new (get_random_widget_type (), NULL);
|
||||||
|
|
||||||
gtk_container_add (GTK_CONTAINER (fishbowl), new_widget);
|
gtk_container_add (GTK_CONTAINER (fishbowl), new_widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,9 @@ GType gtk_fishbowl_get_type (void) G_GNUC_CONST;
|
|||||||
|
|
||||||
GtkWidget* gtk_fishbowl_new (void);
|
GtkWidget* gtk_fishbowl_new (void);
|
||||||
|
|
||||||
|
void gtk_fishbowl_set_use_icons (GtkFishbowl *fishbowl,
|
||||||
|
gboolean use_icons);
|
||||||
|
|
||||||
guint gtk_fishbowl_get_count (GtkFishbowl *fishbowl);
|
guint gtk_fishbowl_get_count (GtkFishbowl *fishbowl);
|
||||||
void gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
|
void gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
|
||||||
guint count);
|
guint count);
|
||||||
|
@ -25,6 +25,7 @@ demos = files([
|
|||||||
'expander.c',
|
'expander.c',
|
||||||
'filtermodel.c',
|
'filtermodel.c',
|
||||||
'fishbowl.c',
|
'fishbowl.c',
|
||||||
|
'widgetbowl.c',
|
||||||
'foreigndrawing.c',
|
'foreigndrawing.c',
|
||||||
'gestures.c',
|
'gestures.c',
|
||||||
'glarea.c',
|
'glarea.c',
|
||||||
|
179
demos/gtk-demo/widgetbowl.c
Normal file
179
demos/gtk-demo/widgetbowl.c
Normal file
@ -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 ("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,
|
||||||
|
!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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user