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

Widget animation




Hello,

I am writing a GTK+ app which uses animated widgets-- specifically, clists
and scrollbars which are rapidly manipulated via their adjustments (using
gtk_adjustment_set_value( ), or emitting "changed" signals manually). 

This is done in an idle loop, with a value keyed off the system clock. In
theory, this should allow the widget to scroll/move in a fairly smooth,
CPU-speed-independent manner. 

But alas, not so. The adjustment gets updated too frequently, with the
result that the clist/scrollbar widget lurches around in a half-drawn
manner, slowing down the rest of the program along with itself. 


*** Further down is a small sample program, implementing an animated clist,
which displays exactly this behavior. Notice how the clist remains
completely blank, except for brief moments at the top and bottom ***


The solution, I believe, is to check with GTK+, to see if the widget is
busy drawing itself, or if it's in steady state (ready for another
"value_changed" signal), in a test along the following lines (this part is
highlighted in the sample program):

	if (!some_test_function( ))
		gtk_adjustment_set_value( vadj, value );

I've tried gtk_events_pending( ), gdk_events_pending( ), and even
g_main_pending( ) as the test in the above conditional, and none do what is
necessary to yield a smooth animation. That is, the adjustment still gets
its value reset even as the associated widget is drawing itself, resulting
in a backlog of widget redraws.


So, my question is: What test can be made (or what widget flag can be
checked, etc.) to see if a widget is completely, totally drawn/updated?
i.e. what will make smooth widget animation /work?/


Any help will be greatly appreciated


--Straker



-------- begin animx.c --------
#include <stdio.h>
#include <math.h>
#include <sys/time.h>
#include <gtk/gtk.h>

#define PI 3.14159265358979323846

GtkWidget *window_w;
GtkWidget *scrollwin_w;
GtkWidget *clist_w;
GtkAdjustment *vadj;

double
current_time( void )
{
	struct timeval tv;
	double t;

	gettimeofday( &tv, NULL );
	t = (double)tv.tv_sec + (double)tv.tv_usec / 1.0e6;

	return t;
}

void
idle_loop( void )
{
	double k, value;

	k = 0.5 * (1.0 - cos( 0.5 * PI * current_time( ) ));
	value = vadj->lower +
	    k * (vadj->upper - vadj->lower - vadj->page_size);

	/**** AREA OF INTEREST ****/

	if (!gtk_events_pending( ))
		gtk_adjustment_set_value( vadj, value );

	/**************************/
}

int
main( int argc, char **argv )
{
	int i;
	char *clist_row[] = { "I have no strings on me!" };

	gtk_init( &argc, &argv );

	window_w = gtk_window_new( GTK_WINDOW_TOPLEVEL );
	gtk_widget_set_usize( window_w, 400, 300 );
	gtk_signal_connect( GTK_OBJECT(window_w), "delete_event",
	    GTK_SIGNAL_FUNC(gtk_main_quit), NULL );

	scrollwin_w = gtk_scrolled_window_new( NULL, NULL );
	gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(scrollwin_w),
	    GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS );
	gtk_container_add( GTK_CONTAINER(window_w), scrollwin_w );
	gtk_widget_show( scrollwin_w );

	clist_w = gtk_clist_new( 1 );
	gtk_scrolled_window_add_with_viewport(
	    GTK_SCROLLED_WINDOW(scrollwin_w), clist_w );
	gtk_widget_show( clist_w );

	for (i = 0; i < 100; i++)
		gtk_clist_append( GTK_CLIST(clist_w), clist_row );

	gtk_widget_show( window_w );

	vadj = gtk_scrolled_window_get_vadjustment(
	    GTK_SCROLLED_WINDOW(scrollwin_w) );

	gtk_idle_add_priority( G_PRIORITY_LOW, (GtkFunction)idle_loop, NULL );

	gtk_main( );

	return 0;
}
-------- end animx.c --------

                       //,,    //,,
//=================// //////  ////// //==================================\\
 Straker Skunk     / //////  ////// /      Skunks are such wonderful
 <skunk@mit.edu>  / //////  ////// /     creatures... soft, and cuddly,
 -- -- -- -- -- --\ \\\\\\  \\\\\\ \      and if you annoy them they
 Daniel Richard G. \ \\\\\\  \\\\\\ \      make you stink like hell
 ========--====--==-\ \\\\\\  \\\\\\ \---------------=--==--====--========
 //mit.edu/straker  / //////  ////// / Furry|Course VI-3|MIT Class of 2001
 //skunk.mit.edu   / //////  ////// / 80% Beaver 90% Penguin 100% SKUNK!!!
\\===============// //////  ////// //====================================//
                     ''//    ''//



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