Logo Search packages:      
Sourcecode: paul version File versions  Download package

animate.c

/*****************************************************************************
 *                                                                           *
 * Program:   paul                                                           *
 *            (P)rogramm zur (A)uswertung und (U)mformung von                *
 *            (L)aserbildern                                                 *
 * Uses:      GTK                                                     *
 * Modul:     animate.c                                                      *
 *            animation related functions for paul                           *
 * Author:    Andreas Tille                                                  *
 * Date:      03.09.1998                                                     *
 * Copyright: Andreas Tille, 1999; Gnu Public License                        *
 *                                                                           *
 *****************************************************************************/

#include <stdlib.h>
#include "paul.h"
#include "callback.h"
#include "names.h"

int        ANIMATION_SPEED = SINGLE;
static int TIMEOUT_TAG = 0,
           ANIFLAG = 0,
           DIRECTION = 0;

static int BackwardAnimation(PAUL *p)
/* timeout-function for backward animation
 * --- parameter: ---
 * PAUL *p         : animation structure containing window and picture ring-list
 * --- return:    ---
 * int  Animation(): 0 in case of error
 */
{
  if ( ANIFLAG ) return 1;  /* avoid displaying if timout is faster than display */
   
  ANIFLAG  = 1;
  p->activ = (p->activ)->prev;
  ApplyPicture((p->show)->window, BILD(p->activ));
  ANIFLAG  = 0;

  return 1;
}

static int ForewardAnimation(PAUL *p)
/* timeout-function for foreward animation
 * --- parameter: ---
 * PAUL *p         : animation structure containing window and picture ring-list
 * --- return:    ---
 * int  Animation(): 0 in case of error
 */
{
  if ( ANIFLAG ) return 1;  /* avoid displaying if timout is faster than display */
   
  ANIFLAG  = 1;
  p->activ = (p->activ)->next;
  ApplyPicture((p->show)->window, BILD(p->activ));
  ANIFLAG  = 0;

  return 1;
}

static int InstallTimeout(PAUL *p)
{
  register long       wait;

  g_return_val_if_fail ( IS_PAUL(p), RET_ERR );
  g_return_val_if_fail ( DIRECTION != 0, RET_ERR ) ;
  
  if ( p->opt->sek < 0.01 ) wait = 0; /* about 0.01 seconds needs calculation */
  else                      wait = 1000*(p->opt->sek) - 10; 

  /* add some integer to wait to enable keyboard input in image window */
  if ( DIRECTION < 0 ) 
    TIMEOUT_TAG = gtk_timeout_add(wait, (GtkFunction)BackwardAnimation, p);
  else
    TIMEOUT_TAG = gtk_timeout_add(wait, (GtkFunction)ForewardAnimation, p);
   
  if ( wait > FAST_TIME ) ANIMATION_SPEED = SLOW_ANIMATION;
  else {
    ANIMATION_SPEED = FAST_ANIMATION;
    SHOW_SLOW       = 0;
    gdk_window_set_title((p->show)->window, "Paul animation");
  }
   
  gtk_widget_set_sensitive(p->w, FALSE);
  return TIMEOUT_TAG;
}

static void AnimationTimeChanged(GtkWidget *widget, PAUL *p)
/* called when parameter of animation time was changed in menu
 * --- Parameter: ---
 * GtkButton *button: OK-Button of menu window for animation time
 *                    PAUL *p connected
 * gpointer   data  : spin button which holds new value
 */
{
  if ( TIMEOUT_TAG ) {
    gtk_timeout_remove(TIMEOUT_TAG);
    InstallTimeout(p);
  }
}

void AnimationTimeParameterCallback(PAUL *p)
{
  ITEM      *para;
  GtkWidget *table;
  int        np = 1;
   
  para           = g_new0(ITEM, np+1);
  para->name     = _("Delay time [s]:");
  para->typ      = P_DOUBLE;
  if ( p->opt->sek <= 0 ) p->opt->sek = 0.0;
  para->val      = &(p->opt->sek);
  para->upper    = 10000.0;
  para->lower    = 0.0;
  para->valchg   = NULL;
  para->adj      = NULL;
  para->userdata = NULL;
   
  if ( (table = BuildParameterTable(para, np)) )
    BuildParameterInput(table, Animation_p, Animation_d, para, 
                        GTK_SIGNAL_FUNC(_ParameterChanged), table, 
                        GTK_SIGNAL_FUNC(AnimationTimeChanged), p);
}

static GList *SortList(GList *list, GList *reflist)
/* sort a given GList *list according to the sequence of Data in GList *reflist
 * Each element of reflist in ascending order is checked, if it is contained in
 * list.  Then it goes into the newly created sorted list.
 * --- Parameter: ---
 * GList *list       : list to sort
 * GList *reflist    : reference list
 * --- return: ---
 * GList *SortList() : sorted list
 */
{
  register gpointer data;
  register GList   *rl, *ll, *new = NULL;
  int               i;
   
  if ( !reflist || !list ) return NULL;
  for ( rl = reflist; rl; rl = rl->next ) {
    if ( !(data = rl->data) ) continue;
    for ( ll = list; ll; ll = ll->next ) 
      if ( ll->data == data ) break;
    if ( !ll ) continue;
    new = g_list_append(new, data);
  }
  if (  ( i = g_list_length(list) - g_list_length(new) ) )
    g_warning(_("%i elements lost in new list"), i);
      
  G_LIST_FREE(list);
  return new;
}

int PictureAnimate(GtkWidget *button, PAUL *p)
/* prepares animation
 * --- Parameter: ---
 * GtkWidget *button   : button at bottom line (can be ignored)
 * PAUL      *p        : PAUL structure
 * --- Return: ---
 * int PictureAnimate(): RET_ERR or RET_OK
 */
{
  register GList *pl = NULL, *sellist;
  int             x = -1, y = -1;
  GtkWidget      *bb, *bs, *bf;

  g_return_val_if_fail ( IS_PAUL(p), RET_ERR ) ;
  g_return_val_if_fail ( GTK_IS_CLIST(p->filelist), RET_ERR ) ;
  g_return_val_if_fail ( p->ctrl, RET_ERR ) ;
  g_return_val_if_fail ( GTK_IS_NOTEBOOK(p->ctrl), RET_ERR ) ;
  g_return_val_if_fail ( (bb = gtk_object_get_user_data(GTK_OBJECT(p->ctrl))), RET_ERR ) ;
  g_return_val_if_fail ( GTK_IS_BUTTON(bb), RET_ERR ) ;
  g_return_val_if_fail ( (bs = gtk_object_get_user_data(GTK_OBJECT(bb))), RET_ERR ) ;
  g_return_val_if_fail ( GTK_IS_BUTTON(bs), RET_ERR ) ;
  g_return_val_if_fail ( (bf = gtk_object_get_user_data(GTK_OBJECT(bs))), RET_ERR ) ;
  g_return_val_if_fail ( GTK_IS_BUTTON(bf), RET_ERR ) ;
  g_return_val_if_fail ( bb == gtk_object_get_user_data(GTK_OBJECT(bf)), RET_ERR ) ;
  if ( !button ) button = bf ;  /* initial state if -w command line option */
  else           g_return_val_if_fail ( bb == button || bf == button, RET_ERR ) ;
   
  sellist = GetListFromSelection(p->piclist);
  if ( !sellist || !(sellist->next) ) {
    g_warning(_("Please select at least two images to animate."));
    return RET_ERR;
  }

  g_return_val_if_fail ( BILD(p->activ), RET_ERR ) ;
   
  while (sellist) {
    register  PICTURE *bild;
      
    g_return_val_if_fail ( (bild = BILD(sellist)), RET_ERR );
    if ( p->opt->sek < FAST_TIME  ) {
      if ( x == -1 ) {
        x = bild->W;
        y = bild->H;
      } else {
        if ( x != bild->W || y != bild->H ) {
          g_warning(_("Please make sure that all images have the same size.\nThis is neccessary for animation speed under %gs."), (double)FAST_TIME);
          G_LIST_FREE(pl);
          return RET_ERR;
      }
      }
    }
    pl      = g_list_append(pl, bild);
    sellist = sellist->next;
  }

  sellist = pl;
  sellist = SortList(sellist, p->piclist);

  (pl = g_list_last(sellist))->next = sellist; /* ringlist !! */
  sellist->prev = pl;
  p->activ = g_list_find(sellist, (p->activ)->data);

  gtk_widget_set_sensitive(bb, FALSE);
  gtk_widget_set_sensitive(bs, TRUE);
  gtk_widget_set_sensitive(bf, FALSE);
  gtk_widget_show_all(p->ctrl);

  if ( button == bb ) {
    DIRECTION = -1;
    InstallTimeout(p);
  } else {
    DIRECTION = +1;
    InstallTimeout(p);
  }
  
  return RET_OK;
}

int StopPictureAnimate(GtkWidget *button, PAUL *p)
/* stopps animation
 * --- Parameter: ---
 * GtkWidget *button: animation button
 * PAUL      *p
 */
{
  register GList *pl;
  GtkWidget      *bb, *bs, *bf;

  g_return_val_if_fail ( DIRECTION , RET_ERR ) ;
  g_return_val_if_fail ( IS_PAUL(p), RET_ERR ) ;
  g_return_val_if_fail ( p->ctrl, RET_ERR ) ;
  g_return_val_if_fail ( GTK_IS_NOTEBOOK(p->ctrl), RET_ERR ) ;
  g_return_val_if_fail ( (bb = gtk_object_get_user_data(GTK_OBJECT(p->ctrl))), RET_ERR );
  g_return_val_if_fail ( GTK_IS_BUTTON(bb), RET_ERR ) ;
  g_return_val_if_fail ( (bs = gtk_object_get_user_data(GTK_OBJECT(bb))), RET_ERR );
  g_return_val_if_fail ( GTK_IS_BUTTON(bs), RET_ERR ) ;
  g_return_val_if_fail ( (bf = gtk_object_get_user_data(GTK_OBJECT(bs))), RET_ERR );
  g_return_val_if_fail ( GTK_IS_BUTTON(bf), RET_ERR ) ;
  g_return_val_if_fail ( bb == gtk_object_get_user_data(GTK_OBJECT(bf)), RET_ERR );

  gtk_timeout_remove(TIMEOUT_TAG);
  TIMEOUT_TAG = 0;
  DIRECTION   = 0;
   
  pl = g_list_find(p->piclist, (p->activ)->data);

  ((p->activ)->prev)->next = NULL;  /* open ring!! */
  G_LIST_FREE(p->activ);
  p->activ = pl;
  if ( ANIMATION_SPEED == FAST_ANIMATION ) {
    gdk_window_set_title((p->show)->window, (BILD(pl))->file);
    gdk_window_show((p->show)->window);
    SHOW_SLOW = 1;
  }
  ANIMATION_SPEED = SINGLE;
  gtk_widget_set_sensitive(p->w, TRUE);

  gtk_widget_set_sensitive(bb, TRUE);
  gtk_widget_set_sensitive(bs, FALSE);
  gtk_widget_set_sensitive(bf, TRUE);
  SelectAndUpdateInfo(p);
  
  return RET_OK;
}



Generated by  Doxygen 1.6.0   Back to index