~ubuntu-branches/ubuntu/intrepid/plplot/intrepid

« back to all changes in this revision

Viewing changes to examples/c/plplotcanvas_animation.c

  • Committer: Bazaar Package Importer
  • Author(s): Rafael Laboissiere
  • Date: 2006-11-04 10:19:34 UTC
  • mfrom: (2.1.8 edgy)
  • Revision ID: james.westby@ubuntu.com-20061104101934-mlirvdg4gpwi6i5q
Tags: 5.6.1-10
* Orphaning the package
* debian/control: Changed the maintainer to the Debian QA Group

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * animation.c - Demonstrates the use of the plplot canvas widget with gtk.
 
3
 *
 
4
 *   Copyright (C) 2004, 2005 Thomas J. Duck
 
5
 *   All rights reserved.
 
6
 *
 
7
 *   Thomas J. Duck <tom.duck@dal.ca>
 
8
 *   Department of Physics and Atmospheric Science,
 
9
 *   Dalhousie University, Halifax, Nova Scotia, Canada, B3H 3J5
 
10
 *
 
11
 *   $Author: tomduck $
 
12
 *   $Revision: 1.6 $
 
13
 *   $Date: 2005/05/16 17:05:35 $
 
14
 *   $Name: cvs-tarball_2006-05-29-23-03-54 $
 
15
 *
 
16
 *
 
17
 * NOTICE
 
18
 *
 
19
 *   This program is free software; you can redistribute it and/or modify
 
20
 *   it under the terms of the GNU General Public License as published by
 
21
 *   the Free Software Foundation; either version 2 of the License, or
 
22
 *   (at your option) any later version.
 
23
 *
 
24
 *   This program is distributed in the hope that it will be useful,
 
25
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
26
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
27
 *   GNU General Public License for more details.
 
28
 *
 
29
 *   You should have received a copy of the GNU General Public License
 
30
 *   along with this program; if not, write to the Free Software
 
31
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
32
 *   MA  02110-1301  USA
 
33
 *
 
34
 *
 
35
 * DESCRIPTION
 
36
 * 
 
37
 *   This program demonstrates the use of the plplot canvas widget with gtk.
 
38
 *   Two graphs are draw in a window.  When the Execute button is pressed,
 
39
 *   two different waves progress through the graph in real time.  Plotting
 
40
 *   to the two graphs is handled in two different threads.
 
41
 * 
 
42
 */
 
43
 
 
44
#include <glib.h>
 
45
#include <gtk/gtk.h>
 
46
 
 
47
#include <plplotcanvas.h>
 
48
 
 
49
#include <math.h>
 
50
 
 
51
 
 
52
/* The number of time steps */
 
53
#define STEPS 300
 
54
 
 
55
/* The number of points and period for the first wave */
 
56
#define NPTS 100
 
57
#define PERIOD 30
 
58
 
 
59
/* The width and height for each plot widget */
 
60
#define WIDTH 800
 
61
#define HEIGHT 300
 
62
 
 
63
/* Run the plots in different threads */
 
64
GThread* thread0=NULL; 
 
65
GThread* thread1=NULL;
 
66
typedef struct {
 
67
  PlplotCanvas* canvas;
 
68
  char* title;
 
69
} ThreadData;
 
70
ThreadData data0,data1;
 
71
gint Nthreads = 0; /* Count the number of threads */
 
72
 
 
73
/* Create two different canvases */
 
74
PlplotCanvas *canvas0=NULL;
 
75
PlplotCanvas *canvas1=NULL;
 
76
 
 
77
/* Create the x and y array */
 
78
static PLFLT x[NPTS], y[NPTS];
 
79
 
 
80
/* Lock on the gtkstate so that we don't try to plot after gtk_main_quit */
 
81
#define GTKSTATE_CONTINUE (TRUE)
 
82
#define GTKSTATE_QUIT (FALSE)
 
83
G_LOCK_DEFINE_STATIC(gtkstate);
 
84
static volatile int gtkstate = GTKSTATE_CONTINUE;
 
85
 
 
86
/* setup_plot - preparation for plotting an animation to a canvas */
 
87
void setup_plot(PlplotCanvas *canvas, char* title)
 
88
{
 
89
  /* Set up the viewport and window */
 
90
  plplot_canvas_vsta(canvas);
 
91
  plplot_canvas_wind(canvas,x[0],x[NPTS-1],-2.,2.);
 
92
 
 
93
  /* Set the pen width */
 
94
  plplot_canvas_wid(canvas,2); 
 
95
 
 
96
  /* The axes should be persistent, so that they don't have to be 
 
97
   * replotted every time (which would slow down the animation)
 
98
   */
 
99
  plplot_canvas_use_persistence(canvas,TRUE);
 
100
 
 
101
  /* Draw the axes */
 
102
  plplot_canvas_col0(canvas,15);
 
103
  plplot_canvas_box(canvas,"bcnst",0.,0,"bcnstv",0.,0);
 
104
  plplot_canvas_lab(canvas,"(x)","(y)",title);
 
105
 
 
106
  /* Prepare for plotting */
 
107
  plplot_canvas_col0(canvas,plplot_canvas_get_stream_number(canvas)+8); 
 
108
 
 
109
  /* The animated data should not be persistent */
 
110
  plplot_canvas_use_persistence(canvas,FALSE);
 
111
}
 
112
 
 
113
/* plot - draws a plot on a canvas */
 
114
void plot(PlplotCanvas *canvas,gdouble offset,char* title)
 
115
{
 
116
  int i;
 
117
  guint Nstream;
 
118
  gdouble xmin,xmax,ymin,ymax;
 
119
 
 
120
  /* Get the stream number */
 
121
  Nstream = plplot_canvas_get_stream_number(canvas);
 
122
 
 
123
  /* Generate the sinusoid */
 
124
  for (i = 0; i < NPTS; i++)
 
125
    y[i] = sin(2.*3.14*(x[i]+offset*(Nstream+1))/PERIOD/(float)(Nstream+1));
 
126
 
 
127
  /* Draw the line */
 
128
  plplot_canvas_line(canvas,NPTS, x, y);
 
129
 
 
130
  /* Advance the page to finalize the plot */
 
131
  plplot_canvas_adv(canvas,0);   
 
132
}
 
133
 
 
134
/* Delete event callback */
 
135
gint delete_event( GtkWidget *widget,GdkEvent *event,gpointer data ) {
 
136
  return FALSE;
 
137
}
 
138
 
 
139
/* Destroy event calback */
 
140
void destroy(GtkWidget *widget,gpointer data) {
 
141
  G_LOCK(gtkstate);
 
142
  gtkstate=GTKSTATE_QUIT;
 
143
  G_UNLOCK(gtkstate);
 
144
 
 
145
  gtk_main_quit ();
 
146
}
 
147
 
 
148
GThreadFunc plot_thread(ThreadData* data) {
 
149
  int i;
 
150
 
 
151
  Nthreads++;
 
152
 
 
153
  /* Draw STEPS plots in succession */
 
154
  for(i=0;i<STEPS;i++) {
 
155
    gdk_threads_enter();
 
156
 
 
157
    /* Lock the current gtk state */
 
158
    G_LOCK(gtkstate);
 
159
  
 
160
    /* Check to make sure gtk hasn't quit */
 
161
    if(gtkstate == GTKSTATE_QUIT){
 
162
      G_UNLOCK(gtkstate);
 
163
      gdk_threads_leave();
 
164
      g_thread_exit(NULL);
 
165
    }
 
166
    
 
167
    /* Draw the plot */
 
168
    plot(data->canvas,i,data->title);
 
169
 
 
170
    /* Release the lock */
 
171
    G_UNLOCK(gtkstate);
 
172
    gdk_threads_leave();
 
173
  }
 
174
 
 
175
  Nthreads--;
 
176
  g_thread_exit(NULL);
 
177
}
 
178
 
 
179
/* Start threads callback from execute button */
 
180
void start_threads(GtkWidget *widget,gpointer data)
 
181
{
 
182
  GError **gerror;
 
183
 
 
184
  /* Ignore call if threads are currently active */
 
185
  if(Nthreads) return;
 
186
 
 
187
  /* Create the two plotting threads */
 
188
  data0.canvas = canvas0;
 
189
  data0.title = "A phase-progressing wave";
 
190
  if((thread0=g_thread_create((GThreadFunc)plot_thread,&data0,TRUE,gerror))\
 
191
     ==NULL) {
 
192
    fprintf(stderr,"Could not create thread");
 
193
    return;
 
194
  }
 
195
 
 
196
  data1.canvas = canvas1;
 
197
  data1.title = "Another phase-progressing wave";
 
198
  if((thread1=g_thread_create((GThreadFunc)plot_thread,&data1,TRUE,gerror))\
 
199
     ==NULL) {
 
200
    fprintf(stderr,"Could not create thread");
 
201
    return;
 
202
  }
 
203
}
 
204
 
 
205
int main(int argc,char *argv[] )
 
206
{
 
207
  int i;
 
208
 
 
209
  GtkWidget *window;
 
210
  GtkWidget *table;
 
211
 
 
212
  GtkFrame *canvas0frame;
 
213
  GtkFrame *canvas1frame;
 
214
 
 
215
  GtkButton* button;
 
216
  GtkBox* buttonbox;
 
217
 
 
218
  GtkBox* vbox;
 
219
 
 
220
  /* Parse the options */
 
221
  plparseopts(&argc, argv, PL_PARSE_FULL);
 
222
 
 
223
  /* Initialize */
 
224
  g_thread_init(NULL);
 
225
  gdk_threads_init();
 
226
  gtk_init(&argc, &argv);
 
227
  g_type_init();
 
228
 
 
229
  /* Initialize the x array */
 
230
  for(i=0;i<NPTS;i++) x[i] = (PLFLT)i;
 
231
 
 
232
  /* Create the first canvas, set its size, draw some axes on it, and
 
233
   *  place it in a frame
 
234
   */
 
235
  canvas0 = plplot_canvas_new(TRUE);
 
236
  plplot_canvas_set_size(canvas0,WIDTH,HEIGHT);
 
237
  plplot_canvas_adv(canvas0,0);
 
238
  setup_plot(canvas0,"A phase-progressing wave");
 
239
  plplot_canvas_adv(canvas0,0);   /* Advance the page to finalize the plot */
 
240
  canvas0frame = GTK_FRAME(gtk_frame_new(NULL));
 
241
  gtk_frame_set_shadow_type(canvas0frame,GTK_SHADOW_ETCHED_OUT);
 
242
  gtk_container_add(GTK_CONTAINER(canvas0frame),GTK_WIDGET(canvas0));
 
243
 
 
244
  /* Create the second canvas, set its size, draw some axes on it, and
 
245
   * place it in a frame
 
246
   */
 
247
  canvas1 = plplot_canvas_new(TRUE);
 
248
  plplot_canvas_set_size(canvas1,WIDTH,HEIGHT);
 
249
  plplot_canvas_adv(canvas1,0);
 
250
  setup_plot(canvas1,"Another phase-progressing wave");
 
251
  plplot_canvas_adv(canvas1,0);   /* Advance the page to finalize the plot */
 
252
  canvas1frame = GTK_FRAME(gtk_frame_new(NULL));
 
253
  gtk_frame_set_shadow_type(canvas1frame,GTK_SHADOW_ETCHED_OUT);
 
254
  gtk_container_add(GTK_CONTAINER(canvas1frame),GTK_WIDGET(canvas1));
 
255
 
 
256
  /* Create a button and put it in a box */
 
257
  button = GTK_BUTTON(gtk_button_new_from_stock(GTK_STOCK_EXECUTE));
 
258
  g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(start_threads),
 
259
                     NULL);
 
260
  gtk_container_set_border_width(GTK_CONTAINER(button),10);
 
261
  buttonbox = GTK_BOX(gtk_hbox_new(FALSE,0));
 
262
  gtk_box_pack_start(buttonbox,GTK_WIDGET(button),TRUE,FALSE,0);
 
263
 
 
264
  /* Create and fill the vbox with the widgets */
 
265
  vbox = GTK_BOX(gtk_vbox_new(FALSE,0));
 
266
  gtk_box_pack_start(vbox,GTK_WIDGET(canvas0frame),TRUE,FALSE,0);
 
267
  gtk_box_pack_start(vbox,GTK_WIDGET(canvas1frame),TRUE,FALSE,10);
 
268
  gtk_box_pack_start(vbox,GTK_WIDGET(buttonbox),TRUE,FALSE,0);
 
269
 
 
270
  /* Create a new window */
 
271
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
272
  
 
273
  /* Set the border width of the window */
 
274
  gtk_container_set_border_width(GTK_CONTAINER(window),10);
 
275
  
 
276
  /* Connect the signal handlers to the window decorations */
 
277
  g_signal_connect(G_OBJECT(window),"delete_event",
 
278
                   G_CALLBACK(delete_event),NULL);
 
279
  g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(destroy),NULL);
 
280
  
 
281
  /* Put the vbox into the window */
 
282
  gtk_container_add(GTK_CONTAINER(window),GTK_WIDGET(vbox));
 
283
  
 
284
  /* Display everything */
 
285
  gtk_widget_show_all(window);
 
286
    
 
287
  /* Start the gtk main loop */
 
288
  gdk_threads_enter();
 
289
  gtk_main ();
 
290
  gdk_threads_leave();
 
291
 
 
292
  return 0;
 
293
}