2016-11-05 02:31:10 +00:00
/* Benchmark/Fishbowl
*
* 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>
2017-01-07 00:59:23 +00:00
# include "gtkfishbowl.h"
2018-04-24 19:32:36 +00:00
# include "gtkgears.h"
2020-09-29 07:36:10 +00:00
# include "gskshaderpaintable.h"
2018-04-24 19:32:36 +00:00
2022-04-08 17:10:43 +00:00
# include "nodewidget.h"
# include "graphwidget.h"
2018-04-24 19:32:36 +00:00
const char * const css =
" .blurred-button { "
" box-shadow: 0px 0px 5px 10px rgba(0, 0, 0, 0.5); "
" } "
" " ;
2016-11-05 02:31:10 +00:00
2018-04-24 18:32:57 +00:00
char * * icon_names = NULL ;
gsize n_icon_names = 0 ;
static void
init_icon_names ( GtkIconTheme * theme )
{
if ( icon_names )
return ;
2020-02-18 05:56:37 +00:00
icon_names = gtk_icon_theme_get_icon_names ( theme ) ;
n_icon_names = g_strv_length ( icon_names ) ;
2018-04-24 18:32:57 +00:00
}
static const char *
get_random_icon_name ( GtkIconTheme * theme )
{
init_icon_names ( theme ) ;
return icon_names [ g_random_int_range ( 0 , n_icon_names ) ] ;
}
2020-03-07 14:01:21 +00:00
/* Can't be static because it's also used in iconscroll.c */
2018-04-24 18:32:57 +00:00
GtkWidget *
create_icon ( void )
{
GtkWidget * image ;
2020-02-01 22:38:49 +00:00
image = gtk_image_new ( ) ;
2018-04-24 18:32:57 +00:00
gtk_image_set_icon_size ( GTK_IMAGE ( image ) , GTK_ICON_SIZE_LARGE ) ;
2020-02-01 22:38:49 +00:00
gtk_image_set_from_icon_name ( GTK_IMAGE ( image ) ,
get_random_icon_name ( gtk_icon_theme_get_for_display ( gtk_widget_get_display ( image ) ) ) ) ;
2018-04-24 18:32:57 +00:00
return image ;
}
2018-04-24 19:32:36 +00:00
static GtkWidget *
create_button ( void )
{
return gtk_button_new_with_label ( " Button " ) ;
}
static GtkWidget *
create_blurred_button ( void )
{
GtkWidget * w = gtk_button_new ( ) ;
2020-04-10 16:08:16 +00:00
gtk_widget_add_css_class ( w , " blurred-button " ) ;
2018-04-24 19:32:36 +00:00
return w ;
}
static GtkWidget *
create_font_button ( void )
{
2023-09-23 11:47:09 +00:00
return gtk_font_dialog_button_new ( gtk_font_dialog_new ( ) ) ;
2018-04-24 19:32:36 +00:00
}
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. " ) ;
2019-08-22 10:41:39 +00:00
gtk_label_set_wrap ( GTK_LABEL ( w ) , TRUE ) ;
2018-04-24 19:32:36 +00:00
gtk_label_set_max_width_chars ( GTK_LABEL ( w ) , 100 ) ;
return w ;
}
static GtkWidget *
create_video ( void )
{
2021-01-04 23:26:29 +00:00
GtkWidget * w = gtk_video_new ( ) ;
2018-08-19 07:25:38 +00:00
gtk_widget_set_size_request ( w , 64 , 64 ) ;
2021-01-04 23:26:29 +00:00
gtk_video_set_loop ( GTK_VIDEO ( w ) , TRUE ) ;
gtk_video_set_autoplay ( GTK_VIDEO ( w ) , TRUE ) ;
gtk_video_set_resource ( GTK_VIDEO ( w ) , " /images/gtk-logo.webm " ) ;
2018-04-24 19:32:36 +00:00
return w ;
}
static GtkWidget *
create_gears ( void )
{
GtkWidget * w = gtk_gears_new ( ) ;
gtk_widget_set_size_request ( w , 100 , 100 ) ;
return w ;
}
static GtkWidget *
create_switch ( void )
{
GtkWidget * w = gtk_switch_new ( ) ;
gtk_switch_set_state ( GTK_SWITCH ( w ) , TRUE ) ;
return w ;
}
2020-09-29 07:36:10 +00:00
static gboolean
update_paintable ( GtkWidget * widget ,
GdkFrameClock * frame_clock ,
gpointer user_data )
{
GskShaderPaintable * paintable ;
gint64 frame_time ;
paintable = GSK_SHADER_PAINTABLE ( gtk_picture_get_paintable ( GTK_PICTURE ( widget ) ) ) ;
frame_time = gdk_frame_clock_get_frame_time ( frame_clock ) ;
gsk_shader_paintable_update_time ( paintable , 0 , frame_time ) ;
return G_SOURCE_CONTINUE ;
}
static GtkWidget *
create_cogs ( void )
{
GtkWidget * picture ;
static GskGLShader * cog_shader = NULL ;
GdkPaintable * paintable ;
if ( cog_shader = = NULL )
cog_shader = gsk_gl_shader_new_from_resource ( " /gltransition/cogs2.glsl " ) ;
paintable = gsk_shader_paintable_new ( g_object_ref ( cog_shader ) , NULL ) ;
picture = gtk_picture_new_for_paintable ( paintable ) ;
gtk_widget_set_size_request ( picture , 150 , 75 ) ;
gtk_widget_add_tick_callback ( picture , update_paintable , NULL , NULL ) ;
return picture ;
}
2024-03-14 00:45:30 +00:00
static gboolean
check_cogs ( GtkFishbowl * fb )
{
return GSK_IS_GL_RENDERER ( gtk_native_get_renderer ( gtk_widget_get_native ( GTK_WIDGET ( fb ) ) ) ) ;
}
2019-05-24 01:54:55 +00:00
static void
mapped ( GtkWidget * w )
{
gtk_menu_button_popup ( GTK_MENU_BUTTON ( w ) ) ;
}
2019-05-24 00:31:07 +00:00
static GtkWidget *
create_menu_button ( void )
{
GtkWidget * w = gtk_menu_button_new ( ) ;
2020-02-24 12:21:46 +00:00
GtkWidget * popover = gtk_popover_new ( ) ;
2019-05-24 00:31:07 +00:00
2020-05-02 02:22:20 +00:00
gtk_popover_set_child ( GTK_POPOVER ( popover ) , gtk_button_new_with_label ( " Hey! " ) ) ;
2019-05-24 01:54:55 +00:00
gtk_popover_set_autohide ( GTK_POPOVER ( popover ) , FALSE ) ;
2019-05-24 00:31:07 +00:00
gtk_menu_button_set_popover ( GTK_MENU_BUTTON ( w ) , popover ) ;
2019-05-24 01:54:55 +00:00
g_signal_connect ( w , " map " , G_CALLBACK ( mapped ) , NULL ) ;
2019-05-24 00:31:07 +00:00
return w ;
}
2022-04-08 17:10:43 +00:00
static GtkWidget *
create_tiger ( void )
{
return node_widget_new ( " /fishbowl/tiger.node " ) ;
}
static GtkWidget *
create_graph ( void )
{
return graph_widget_new ( ) ;
}
2018-04-24 19:32:36 +00:00
static const struct {
const char * name ;
2024-03-14 00:45:30 +00:00
GtkWidget * ( * create_func ) ( void ) ;
gboolean ( * check ) ( GtkFishbowl * fb ) ;
2018-04-24 19:32:36 +00:00
} widget_types [ ] = {
2024-03-14 00:45:30 +00:00
{ " Icon " , create_icon , NULL } ,
{ " Button " , create_button , NULL } ,
{ " Blurbutton " , create_blurred_button , NULL } ,
{ " Fontbutton " , create_font_button , NULL } ,
{ " Levelbar " , create_level_bar , NULL } ,
{ " Label " , create_label , NULL } ,
{ " Spinner " , create_spinner , NULL } ,
{ " Spinbutton " , create_spinbutton , NULL } ,
{ " Video " , create_video , NULL } ,
{ " Gears " , create_gears , NULL } ,
{ " Switch " , create_switch , NULL } ,
{ " Menubutton " , create_menu_button , NULL } ,
{ " Shader " , create_cogs , check_cogs } ,
{ " Tiger " , create_tiger , NULL } ,
{ " Graph " , create_graph , NULL } ,
2018-04-24 19:32:36 +00:00
} ;
static int selected_widget_type = - 1 ;
static const int N_WIDGET_TYPES = G_N_ELEMENTS ( widget_types ) ;
2024-03-14 00:45:30 +00:00
static gboolean
2018-04-24 19:32:36 +00:00
set_widget_type ( GtkFishbowl * fishbowl ,
int widget_type_index )
{
2020-04-30 23:04:08 +00:00
GtkWidget * window ;
2018-04-24 19:32:36 +00:00
if ( widget_type_index = = selected_widget_type )
2024-03-14 00:45:30 +00:00
return TRUE ;
if ( widget_types [ widget_type_index ] . check ! = NULL & &
! widget_types [ widget_type_index ] . check ( fishbowl ) )
return FALSE ;
2018-04-24 19:32:36 +00:00
selected_widget_type = widget_type_index ;
gtk_fishbowl_set_creation_func ( fishbowl ,
widget_types [ selected_widget_type ] . create_func ) ;
2019-05-20 04:47:50 +00:00
window = GTK_WIDGET ( gtk_widget_get_root ( GTK_WIDGET ( fishbowl ) ) ) ;
2020-04-30 23:04:08 +00:00
gtk_window_set_title ( GTK_WINDOW ( window ) ,
widget_types [ selected_widget_type ] . name ) ;
2024-03-14 00:45:30 +00:00
return TRUE ;
2018-04-24 19:32:36 +00:00
}
2020-07-27 09:02:00 +00:00
G_MODULE_EXPORT void
2019-11-29 07:48:48 +00:00
fishbowl_next_button_clicked_cb ( GtkButton * source ,
gpointer user_data )
2018-04-24 19:32:36 +00:00
{
GtkFishbowl * fishbowl = user_data ;
2024-03-14 00:45:30 +00:00
int new_index = selected_widget_type ;
2018-04-24 19:32:36 +00:00
2024-03-14 00:45:30 +00:00
do
{
if ( new_index + 1 > = N_WIDGET_TYPES )
new_index = 0 ;
else
new_index = new_index + 1 ;
2018-04-24 19:32:36 +00:00
2024-03-14 00:45:30 +00:00
}
while ( ! set_widget_type ( fishbowl , new_index ) ) ;
2018-04-24 19:32:36 +00:00
}
2020-07-27 09:02:00 +00:00
G_MODULE_EXPORT void
2019-11-29 07:48:48 +00:00
fishbowl_prev_button_clicked_cb ( GtkButton * source ,
gpointer user_data )
2018-04-24 19:32:36 +00:00
{
GtkFishbowl * fishbowl = user_data ;
2024-03-14 00:45:30 +00:00
int new_index = selected_widget_type ;
2018-04-24 19:32:36 +00:00
2024-03-14 00:45:30 +00:00
do
{
if ( new_index - 1 < 0 )
new_index = N_WIDGET_TYPES - 1 ;
else
new_index = new_index - 1 ;
}
2018-04-24 19:32:36 +00:00
2024-03-14 00:45:30 +00:00
while ( ! set_widget_type ( fishbowl , new_index ) ) ;
2018-04-24 19:32:36 +00:00
}
2020-07-27 09:02:00 +00:00
G_MODULE_EXPORT void
2019-11-29 07:48:48 +00:00
fishbowl_changes_toggled_cb ( GtkToggleButton * button ,
gpointer user_data )
2019-05-24 00:11:23 +00:00
{
if ( gtk_toggle_button_get_active ( button ) )
gtk_button_set_icon_name ( GTK_BUTTON ( button ) , " changes-prevent " ) ;
else
gtk_button_set_icon_name ( GTK_BUTTON ( button ) , " changes-allow " ) ;
}
2018-04-24 19:32:36 +00:00
2020-07-27 09:02:00 +00:00
G_MODULE_EXPORT char *
2019-11-25 06:28:19 +00:00
format_header_cb ( GObject * object ,
guint count ,
double fps )
{
return g_strdup_printf ( " %u Icons, %.2f fps " , count , fps ) ;
}
2016-11-05 02:31:10 +00:00
GtkWidget *
do_fishbowl ( GtkWidget * do_widget )
{
static GtkWidget * window = NULL ;
2018-04-24 19:32:36 +00:00
static GtkCssProvider * provider = NULL ;
if ( provider = = NULL )
{
provider = gtk_css_provider_new ( ) ;
2023-05-13 23:44:42 +00:00
gtk_css_provider_load_from_string ( provider , css ) ;
2018-04-24 19:32:36 +00:00
gtk_style_context_add_provider_for_display ( gdk_display_get_default ( ) ,
GTK_STYLE_PROVIDER ( provider ) ,
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION ) ;
}
2016-11-05 02:31:10 +00:00
if ( ! window )
{
GtkBuilder * builder ;
2023-08-02 19:32:45 +00:00
GtkBuilderScope * scope ;
2018-03-30 14:47:52 +00:00
GtkWidget * bowl ;
2016-11-05 02:31:10 +00:00
2017-01-07 00:59:23 +00:00
g_type_ensure ( GTK_TYPE_FISHBOWL ) ;
2023-08-02 19:32:45 +00:00
scope = gtk_builder_cscope_new ( ) ;
gtk_builder_cscope_add_callback ( GTK_BUILDER_CSCOPE ( scope ) , fishbowl_prev_button_clicked_cb ) ;
gtk_builder_cscope_add_callback ( GTK_BUILDER_CSCOPE ( scope ) , fishbowl_next_button_clicked_cb ) ;
gtk_builder_cscope_add_callback ( GTK_BUILDER_CSCOPE ( scope ) , fishbowl_changes_toggled_cb ) ;
gtk_builder_cscope_add_callback ( GTK_BUILDER_CSCOPE ( scope ) , format_header_cb ) ;
builder = gtk_builder_new ( ) ;
gtk_builder_set_scope ( builder , scope ) ;
gtk_builder_add_from_resource ( builder , " /fishbowl/fishbowl.ui " , NULL ) ;
2016-11-05 02:31:10 +00:00
window = GTK_WIDGET ( gtk_builder_get_object ( builder , " window " ) ) ;
2020-05-09 16:03:11 +00:00
g_object_add_weak_pointer ( G_OBJECT ( window ) , ( gpointer * ) & window ) ;
2016-11-05 02:31:10 +00:00
bowl = GTK_WIDGET ( gtk_builder_get_object ( builder , " bowl " ) ) ;
2019-02-11 13:24:06 +00:00
selected_widget_type = - 1 ;
2018-04-24 19:32:36 +00:00
set_widget_type ( GTK_FISHBOWL ( bowl ) , 0 ) ;
2017-10-31 06:41:15 +00:00
gtk_window_set_display ( GTK_WINDOW ( window ) ,
gtk_widget_get_display ( do_widget ) ) ;
2016-11-05 02:31:10 +00:00
gtk_widget_realize ( window ) ;
2019-07-13 08:10:17 +00:00
g_object_unref ( builder ) ;
2023-08-02 19:32:45 +00:00
g_object_unref ( scope ) ;
2016-11-05 02:31:10 +00:00
}
if ( ! gtk_widget_get_visible ( window ) )
2022-11-28 04:03:14 +00:00
gtk_widget_set_visible ( window , TRUE ) ;
2016-11-05 02:31:10 +00:00
else
2020-05-09 14:26:22 +00:00
gtk_window_destroy ( GTK_WINDOW ( window ) ) ;
2016-11-05 02:31:10 +00:00
return window ;
}