Re: A simple GtkSpinner is very costly in CPU cycles
- From: cecashon aol com
- To: kian karas dev gmail com, ebassi gmail com
- Cc: gtk-app-devel-list gnome org
- Subject: Re: A simple GtkSpinner is very costly in CPU cycles
- Date: Thu, 22 Mar 2018 18:09:32 -0400
Hi Kian
For effeciency, use one of the default cursors.
https://developer.gnome.org/gdk3/stable/gdk3-Cursors.html
If you want, you can try creating your own cursor with animation and using that. I got this working on my
netbook which isn't a very high powered computer by todays standards and it works fine. I don't see it eating
up cpu cycles. Give it a try and see if it works.
Eric
//gcc -Wall cursor1.c -o cursor1 `pkg-config gtk+-3.0 --cflags --libs`
//Tested on Ubuntu16.04, GTK3.18.
#include<gtk/gtk.h>
static guint timeout_id=0;
static GdkCursor *cursors[4];
static void initialize_cursors(GtkWidget *window, GdkPixbuf *pixbufs[]);
static void start_cursor(GtkButton *button1, GtkWidget *da);
static void stop_cursor(GtkButton *button2, GtkWidget *da);
static gboolean update_cursor(GtkWidget *da);
static GdkPixbuf* draw_cursor(gint section);
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Cursors");
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
//Pixbufs for the different cursors.
GdkPixbuf *pixbuf1=draw_cursor(1);
GdkPixbuf *pixbuf2=draw_cursor(2);
GdkPixbuf *pixbuf3=draw_cursor(3);
GdkPixbuf *pixbuf4=draw_cursor(4);
GdkPixbuf *pixbufs[]={pixbuf1, pixbuf2, pixbuf3, pixbuf4};
g_signal_connect(window, "realize", G_CALLBACK(initialize_cursors), pixbufs);
GtkWidget *button1=gtk_button_new_with_label("Start Cursor");
gtk_widget_set_hexpand(button1, TRUE);
GtkWidget *button2=gtk_button_new_with_label("Stop Cursor");
gtk_widget_set_hexpand(button2, TRUE);
//Display the cursor in a drawing area.
GtkWidget *da=gtk_drawing_area_new();
gtk_widget_set_hexpand(da, TRUE);
gtk_widget_set_vexpand(da, TRUE);
g_signal_connect(button1, "clicked", G_CALLBACK(start_cursor), da);
g_signal_connect(button2, "clicked", G_CALLBACK(stop_cursor), da);
GtkWidget *grid=gtk_grid_new();
gtk_grid_attach(GTK_GRID(grid), button1, 0, 0, 1, 1);
gtk_grid_attach(GTK_GRID(grid), button2, 1, 0, 1, 1);
gtk_grid_attach(GTK_GRID(grid), da, 0, 1, 2, 1);
gtk_container_add(GTK_CONTAINER(window), grid);
gtk_widget_show_all(window);
gtk_main();
g_object_unref(pixbuf1);
g_object_unref(pixbuf2);
g_object_unref(pixbuf3);
g_object_unref(pixbuf4);
g_object_unref(cursors[0]);
g_object_unref(cursors[1]);
g_object_unref(cursors[2]);
g_object_unref(cursors[3]);
return 0;
}
static void initialize_cursors(GtkWidget *window, GdkPixbuf *pixbufs[])
{
GdkWindow *win=gtk_widget_get_window(window);
GdkDisplay *display=gdk_window_get_display(win);
GdkCursor *cursor1=gdk_cursor_new_from_pixbuf(display, pixbufs[0], 1, 32);
GdkCursor *cursor2=gdk_cursor_new_from_pixbuf(display, pixbufs[1], 1, 32);
GdkCursor *cursor3=gdk_cursor_new_from_pixbuf(display, pixbufs[2], 1, 32);
GdkCursor *cursor4=gdk_cursor_new_from_pixbuf(display, pixbufs[3], 1, 32);
cursors[0]=cursor1;
cursors[1]=cursor2;
cursors[2]=cursor3;
cursors[3]=cursor4;
}
static void start_cursor(GtkButton *button1, GtkWidget *da)
{
if(timeout_id==0)
{
timeout_id=g_timeout_add(300, (GSourceFunc)update_cursor, da);
}
}
static void stop_cursor(GtkButton *button2, GtkWidget *da)
{
if(timeout_id!=0)
{
g_source_remove(timeout_id);
timeout_id=0;
GdkWindow *win=gtk_widget_get_window(da);
gdk_window_set_cursor(win, NULL);
}
}
static gboolean update_cursor(GtkWidget *da)
{
static gint i=0;
GdkWindow *win=gtk_widget_get_window(da);
gdk_window_set_cursor(win, cursors[i]);
if(i>2) i=0;
else i++;
return TRUE;
}
static GdkPixbuf* draw_cursor(gint section)
{
//Create a surface to draw on.
cairo_surface_t *surface=cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 64, 64);
cairo_t *cr=cairo_create(surface);
//Paint the background transparent.
cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.0);
cairo_paint(cr);
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
cairo_rectangle(cr, 0.0, 0.0, 64.0, 64.0);
cairo_stroke(cr);
//Draw from center
cairo_translate(cr, 64.0/2.0, 64.0/2.0);
cairo_set_source_rgba(cr, 0.0, 1.0, 1.0, 1.0);
cairo_arc(cr, 0.0, 0.0, 20.0, 0.0, 2.0*G_PI);
cairo_fill(cr);
//Some pie wedges.
if(section==1)
{
cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
cairo_move_to(cr, 0.0, 0.0);
cairo_line_to(cr, 20.0, 0.0);
cairo_stroke_preserve(cr);
cairo_arc(cr, 0.0, 0.0, 20.0, 0.0, G_PI/2.0);
cairo_stroke_preserve(cr);
cairo_close_path(cr);
cairo_fill(cr);
}
else if(section==2)
{
cairo_set_source_rgb(cr, 0.0, 1.0, 0.0);
cairo_move_to(cr, 0.0, 0.0);
cairo_line_to(cr, 0.0, 20.0);
cairo_stroke_preserve(cr);
cairo_arc(cr, 0.0, 0.0, 20.0, G_PI/2.0, G_PI);
cairo_stroke_preserve(cr);
cairo_close_path(cr);
cairo_fill(cr);
}
else if(section==3)
{
cairo_set_source_rgb (cr, 0.0, 0.0, 1.0);
cairo_move_to(cr, 0.0, 0.0);
cairo_line_to(cr, -20.0, 0.0);
cairo_stroke_preserve(cr);
cairo_arc(cr, 0.0, 0.0, 20.0, G_PI, 3.0*G_PI/2.0);
cairo_stroke_preserve(cr);
cairo_close_path(cr);
cairo_fill(cr);
}
else
{
cairo_set_source_rgb (cr, 1.0, 0.0, 1.0);
cairo_move_to(cr, 0.0, 0.0);
cairo_line_to(cr, 0.0, -20.0);
cairo_stroke_preserve(cr);
cairo_arc(cr, 0.0, 0.0, 20.0, 3.0*G_PI/2.0, 2.0*G_PI);
cairo_stroke_preserve(cr);
cairo_close_path(cr);
cairo_fill(cr);
}
GdkPixbuf *cursor_drawing=gdk_pixbuf_get_from_surface(surface, 0, 0, 64, 64);
cairo_destroy(cr);
cairo_surface_destroy(surface);
return cursor_drawing;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]