[xiph-commits] r12784 - trunk/sushivision

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Tue Mar 20 11:42:15 PDT 2007


Author: xiphmont
Date: 2007-03-20 11:42:11 -0700 (Tue, 20 Mar 2007)
New Revision: 12784

Added:
   trunk/sushivision/example_spirograph.c
Modified:
   trunk/sushivision/dimension.c
   trunk/sushivision/dimension.h
   trunk/sushivision/panel-1d.c
   trunk/sushivision/panel-xy.c
   trunk/sushivision/panel.c
   trunk/sushivision/slider.c
Log:
First cut of working XY panel and a demo to go with.



Modified: trunk/sushivision/dimension.c
===================================================================
--- trunk/sushivision/dimension.c	2007-03-20 15:48:53 UTC (rev 12783)
+++ trunk/sushivision/dimension.c	2007-03-20 18:42:11 UTC (rev 12784)
@@ -224,51 +224,47 @@
 
   sushiv_dim_widget_t *dw = (sushiv_dim_widget_t *)data;
 
-  if(!dw->center_updating){
-    sushiv_dimension_t *d = dw->dl->d;
-    sushiv_panel_t *p = dw->dl->p;
-    double val = slider_get_value(dw->scale,1);
-      char buffer[80];
-
-    val = discrete_quantize_val(d,val);
-    dw->center_updating = 1;
+  sushiv_dimension_t *d = dw->dl->d;
+  sushiv_panel_t *p = dw->dl->p;
+  double val = slider_get_value(dw->scale,1);
+  char buffer[80];
+  
+  val = discrete_quantize_val(d,val);
+  
+  if(buttonstate == 0){
+    _sushiv_undo_push(p->sushi);
+    _sushiv_undo_suspend(p->sushi);
+  }
+  
+  if(d->val != val){
+    int i;
     
-    if(buttonstate == 0){
-      _sushiv_undo_push(p->sushi);
-      _sushiv_undo_suspend(p->sushi);
-    }
+    d->val = val;
     
-    if(d->val != val){
-      int i;
-      
-      d->val = val;
-            
-      /* dims can be shared amongst multiple widgets; all must be updated */
-      for(i=0;i<d->private->widgets;i++){
-	sushiv_dim_widget_t *w = d->private->widget_list[i];
-	if(w->scale) // all shared widgets had better have scales, but bulletproof in case
-	  slider_set_value(w->scale,1,val);
-      }
-
-      /* dims can be shared amongst multiple widgets; all must get callbacks */
-      for(i=0;i<d->private->widgets;i++){
-	sushiv_dim_widget_t *w = d->private->widget_list[i];
-	w->center_callback(dw->dl);
-      }
+    /* dims can be shared amongst multiple widgets; all must be updated */
+    for(i=0;i<d->private->widgets;i++){
+      sushiv_dim_widget_t *w = d->private->widget_list[i];
+      if(w->scale) // all shared widgets had better have scales, but bulletproof in case
+	slider_set_value(w->scale,1,val);
     }
     
-    if(buttonstate == 2)
-      _sushiv_undo_resume(p->sushi);
-
-    snprintf(buffer,80,"%.10g",d->bracket[0]);
-    gtk_entry_set_text(GTK_ENTRY(dw->entry[0]),buffer);
-    snprintf(buffer,80,"%.10g",d->val);
-    gtk_entry_set_text(GTK_ENTRY(dw->entry[1]),buffer);
-    snprintf(buffer,80,"%.10g",d->bracket[1]);
-    gtk_entry_set_text(GTK_ENTRY(dw->entry[2]),buffer);
-    
-    dw->center_updating = 0;
+    /* dims can be shared amongst multiple widgets; all must get callbacks */
+    for(i=0;i<d->private->widgets;i++){
+      sushiv_dim_widget_t *w = d->private->widget_list[i];
+      w->center_callback(dw->dl);
+    }
   }
+  
+  if(buttonstate == 2)
+    _sushiv_undo_resume(p->sushi);
+  
+  snprintf(buffer,80,"%.10g",d->bracket[0]);
+  gtk_entry_set_text(GTK_ENTRY(dw->entry[0]),buffer);
+  snprintf(buffer,80,"%.10g",d->val);
+  gtk_entry_set_text(GTK_ENTRY(dw->entry[1]),buffer);
+  snprintf(buffer,80,"%.10g",d->bracket[1]);
+  gtk_entry_set_text(GTK_ENTRY(dw->entry[2]),buffer);
+  
   gdk_threads_leave();
 }
 
@@ -277,57 +273,52 @@
 
   sushiv_dim_widget_t *dw = (sushiv_dim_widget_t *)data;
 
-  if(!dw->bracket_updating){
-    sushiv_dimension_t *d = dw->dl->d;
-    sushiv_panel_t *p = dw->dl->p;
-    double lo = slider_get_value(dw->scale,0);
-    double hi = slider_get_value(dw->scale,2);
-    char buffer[80];
-
-    hi = discrete_quantize_val(d,hi);
-    lo = discrete_quantize_val(d,lo);
-
-    dw->bracket_updating = 1;
+  sushiv_dimension_t *d = dw->dl->d;
+  sushiv_panel_t *p = dw->dl->p;
+  double lo = slider_get_value(dw->scale,0);
+  double hi = slider_get_value(dw->scale,2);
+  char buffer[80];
+  
+  hi = discrete_quantize_val(d,hi);
+  lo = discrete_quantize_val(d,lo);
+  
+  if(buttonstate == 0){
+    _sushiv_undo_push(p->sushi);
+    _sushiv_undo_suspend(p->sushi);
+  }
+  
+  if(d->bracket[0] != lo || d->bracket[1] != hi){
+    int i;
     
-    if(buttonstate == 0){
-      _sushiv_undo_push(p->sushi);
-      _sushiv_undo_suspend(p->sushi);
-    }
-
-    if(d->bracket[0] != lo || d->bracket[1] != hi){
-      int i;
-
-      d->bracket[0] = lo;
-      d->bracket[1] = hi;
-
-      /* dims can be shared amongst multiple widgets; all must be updated */
-      for(i=0;i<d->private->widgets;i++){
-	sushiv_dim_widget_t *w = d->private->widget_list[i];
-	if(w->scale){ // all shared widgets had better have scales, but bulletproof in case
-	  slider_set_value(w->scale,0,lo);
-	  slider_set_value(w->scale,2,hi);
-	}
+    d->bracket[0] = lo;
+    d->bracket[1] = hi;
+    
+    /* dims can be shared amongst multiple widgets; all must be updated */
+    for(i=0;i<d->private->widgets;i++){
+      sushiv_dim_widget_t *w = d->private->widget_list[i];
+      if(w->scale){ // all shared widgets had better have scales, but bulletproof in case
+	slider_set_value(w->scale,0,lo);
+	slider_set_value(w->scale,2,hi);
       }
-
-      /* dims can be shared amongst multiple widgets; all must get callbacks */
-      for(i=0;i<d->private->widgets;i++){
-	sushiv_dim_widget_t *w = d->private->widget_list[i];
-	w->bracket_callback(dw->dl);
-      }
     }
     
-    if(buttonstate == 2)
-      _sushiv_undo_resume(p->sushi);
-    
-    snprintf(buffer,80,"%.10g",d->bracket[0]);
-    gtk_entry_set_text(GTK_ENTRY(dw->entry[0]),buffer);
-    snprintf(buffer,80,"%.10g",d->val);
-    gtk_entry_set_text(GTK_ENTRY(dw->entry[1]),buffer);
-    snprintf(buffer,80,"%.10g",d->bracket[1]);
-    gtk_entry_set_text(GTK_ENTRY(dw->entry[2]),buffer);
-    
-    dw->bracket_updating = 0;
+    /* dims can be shared amongst multiple widgets; all must get callbacks */
+    for(i=0;i<d->private->widgets;i++){
+      sushiv_dim_widget_t *w = d->private->widget_list[i];
+      w->bracket_callback(dw->dl);
+    }
   }
+  
+  if(buttonstate == 2)
+    _sushiv_undo_resume(p->sushi);
+  
+  snprintf(buffer,80,"%.10g",d->bracket[0]);
+  gtk_entry_set_text(GTK_ENTRY(dw->entry[0]),buffer);
+  snprintf(buffer,80,"%.10g",d->val);
+  gtk_entry_set_text(GTK_ENTRY(dw->entry[1]),buffer);
+  snprintf(buffer,80,"%.10g",d->bracket[1]);
+  gtk_entry_set_text(GTK_ENTRY(dw->entry[2]),buffer);
+  
   gdk_threads_leave();
 }
 
@@ -336,41 +327,36 @@
 
   sushiv_dim_widget_t *dw = (sushiv_dim_widget_t *)data;
 
-  if(!dw->center_updating){
-    sushiv_dimension_t *d = dw->dl->d;
-    sushiv_panel_t *p = dw->dl->p;
-    int bin = gtk_combo_box_get_active(GTK_COMBO_BOX(dw->menu));
-    double val = d->scale->val_list[bin];
- 
-    dw->center_updating = 1;
+  sushiv_dimension_t *d = dw->dl->d;
+  sushiv_panel_t *p = dw->dl->p;
+  int bin = gtk_combo_box_get_active(GTK_COMBO_BOX(dw->menu));
+  double val = d->scale->val_list[bin];
     
-    _sushiv_undo_push(p->sushi);
-    _sushiv_undo_suspend(p->sushi);
+  _sushiv_undo_push(p->sushi);
+  _sushiv_undo_suspend(p->sushi);
     
-    if(d->val != val){
-      int i;
-
-      d->val = val;
-      d->bracket[0] = val;
-      d->bracket[1] = val;
-
-      /* dims can be shared amongst multiple widgets; all must be updated */
-      for(i=0;i<d->private->widgets;i++){
-	sushiv_dim_widget_t *w = d->private->widget_list[i];
-	if(w->menu) // all shared widgets had better have scales, but bulletproof in case
-	  gtk_combo_box_set_active(GTK_COMBO_BOX(w->menu),bin);
-      }
-
-      /* dims can be shared amongst multiple widgets; all must get callbacks */
-      for(i=0;i<d->private->widgets;i++){
-	sushiv_dim_widget_t *w = d->private->widget_list[i];
-	w->center_callback(dw->dl);
-      }
+  if(d->val != val){
+    int i;
+    
+    d->val = val;
+    d->bracket[0] = val;
+    d->bracket[1] = val;
+    
+    /* dims can be shared amongst multiple widgets; all must be updated */
+    for(i=0;i<d->private->widgets;i++){
+      sushiv_dim_widget_t *w = d->private->widget_list[i];
+      if(w->menu) // all shared widgets had better have scales, but bulletproof in case
+	gtk_combo_box_set_active(GTK_COMBO_BOX(w->menu),bin);
     }
-    _sushiv_undo_resume(p->sushi);
     
-    dw->center_updating = 0;
+    /* dims can be shared amongst multiple widgets; all must get callbacks */
+    for(i=0;i<d->private->widgets;i++){
+      sushiv_dim_widget_t *w = d->private->widget_list[i];
+      w->center_callback(dw->dl);
+    }
   }
+  _sushiv_undo_resume(p->sushi);
+  
   gdk_threads_leave();
 }
 

Modified: trunk/sushivision/dimension.h
===================================================================
--- trunk/sushivision/dimension.h	2007-03-20 15:48:53 UTC (rev 12783)
+++ trunk/sushivision/dimension.h	2007-03-20 18:42:11 UTC (rev 12784)
@@ -29,11 +29,6 @@
   GtkWidget *menu;
   GtkWidget *entry[3];
 
-  /* don't rely on intuited state; that could be fragile. If we don't
-     want updates to recurse, be explicit about it! */
-  int center_updating;
-  int bracket_updating;
-
   /* calls with the callback data and a state flag:
      0: begin set
      1: continue set

Added: trunk/sushivision/example_spirograph.c
===================================================================
--- trunk/sushivision/example_spirograph.c	2007-03-20 15:48:53 UTC (rev 12783)
+++ trunk/sushivision/example_spirograph.c	2007-03-20 18:42:11 UTC (rev 12784)
@@ -0,0 +1,117 @@
+/*
+ *
+ *     sushivision copyright (C) 2006-2007 Monty <monty at xiph.org>
+ *
+ *  sushivision is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  sushivision is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with sushivision; see the file COPYING.  If not, write to the
+ *  Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * 
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <math.h>
+#include "sushivision.h"
+
+#define MAX_TEETH 100
+
+sushiv_instance_t *s;
+int mult[MAX_TEETH+1][MAX_TEETH+1];
+
+static void inner(double *d, double *ret){
+  double R = d[0];
+  double r = d[1];
+  double p = d[2];
+  double t = d[3]*M_PI*2.*mult[(int)R][(int)r];
+  
+  ret[0] = (R-r) * cos(t) + p * cos((R-r)*t/r);
+  ret[1] = (R-r) * sin(t) - p * sin((R-r)*t/r);
+}
+
+static void outer(double *d, double *ret){
+  double R = d[0];
+  double r = d[1];
+  double p = d[2];
+  double t = d[3]*M_PI*2.*mult[(int)R][(int)r];
+
+  ret[0] = (R+r) * cos(t) - p * cos((R+r)*t/r);
+  ret[1] = (R+r) * sin(t) + p * sin((R+r)*t/r);
+}
+
+int factored_mult(int x, int y){
+  int d = 2;
+  while(d<x){
+    if((x / d * d) == x &&
+       (y / d * d) == y){
+      x/=d;
+      y/=d;
+    }else{
+      d++;
+    }
+  }
+  return y;
+}
+
+int sushiv_submain(int argc, char *argv[]){
+  int i,j;
+  for(i=0;i<=MAX_TEETH;i++)
+    for(j=0;j<=MAX_TEETH;j++)
+      mult[i][j] = factored_mult(i,j);
+
+  s=sushiv_new_instance(0,"spirograph");
+
+  sushiv_new_dimension_discrete(s,0,"ring teeth",
+				2,(double []){11,MAX_TEETH},
+				NULL,1,1,0);
+  sushiv_new_dimension_discrete(s,1,"wheel teeth",
+				2,(double []){7,MAX_TEETH},
+				NULL,1,1,0);
+  sushiv_new_dimension(s,2,"wheel pen",
+		       2,(double []){0,MAX_TEETH},
+		       NULL,0);
+  sushiv_new_dimension(s,3,"trace",
+		       2,(double []){0,1},
+		       NULL,0);
+
+  scale_set_scalelabels(s->dimension_list[3]->scale,(char *[]){"start","end"});
+
+  sushiv_new_function(s, 0, 2, inner, 0);
+  sushiv_new_function(s, 1, 2, outer, 0);
+
+  sushiv_new_objective(s,0,"inner",
+		       0,NULL,
+		       (int []){0,0},
+		       (int []){0,1},
+		       "XY", 0);
+
+  sushiv_new_objective(s,1,"outer",
+		       0,NULL,
+		       (int []){1,1},
+		       (int []){0,1},
+		       "XY", 0);
+
+  sushiv_scale_t *axis = scale_new(3,(double []){-MAX_TEETH*3,0,MAX_TEETH*3},NULL);
+
+  sushiv_new_panel_xy(s,2,"spirograph (TM)",
+		      axis,axis,
+		      (int []){0,1,-1},
+		      (int []){3,0,1,2,-1},
+		      0);
+
+  sushiv_dimension_set_value(s,0,1,100);
+  sushiv_dimension_set_value(s,1,1,70);
+  sushiv_dimension_set_value(s,2,1,50);
+
+  return 0;
+}

Modified: trunk/sushivision/panel-1d.c
===================================================================
--- trunk/sushivision/panel-1d.c	2007-03-20 15:48:53 UTC (rev 12783)
+++ trunk/sushivision/panel-1d.c	2007-03-20 18:42:11 UTC (rev 12784)
@@ -409,7 +409,7 @@
       
       // add each dimension to the legend
       // display decimal precision relative to display scales
-      if(3-p1->x_v.decimal_exponent > depth) depth = 3-p1->x_v.decimal_exponent;
+      
       snprintf(buffer,320,"%s = %+.*f",
 	       d->name,
 	       depth,

Modified: trunk/sushivision/panel-xy.c
===================================================================
--- trunk/sushivision/panel-xy.c	2007-03-20 15:48:53 UTC (rev 12783)
+++ trunk/sushivision/panel-xy.c	2007-03-20 18:42:11 UTC (rev 12784)
@@ -327,19 +327,23 @@
     char buffer[320];
     plot_legend_clear(plot);
 
-    if(3-xy->data_v.decimal_exponent > depth) depth = 3-xy->data_v.decimal_exponent;
     if(3-xy->x.decimal_exponent > depth) depth = 3-xy->x.decimal_exponent;
     if(3-xy->y.decimal_exponent > depth) depth = 3-xy->y.decimal_exponent;
 
     // if crosshairs are active, add them to the fun
     if( plot->cross_active){
+      char *legend = xy->x_scale->legend;
+      if(!strcmp(legend,""))legend = "X";
       snprintf(buffer,320,"%s = %+.*f",
-	       xy->x_scale->legend,
+	       legend,
 	       depth,
 	       plot->selx);
       plot_legend_add(plot,buffer);
+
+      legend = xy->y_scale->legend;
+      if(!strcmp(legend,""))legend = "Y";
       snprintf(buffer,320,"%s = %+.*f",
-	       xy->y_scale->legend,
+	       legend,
 	       depth,
 	       plot->sely);
       plot_legend_add(plot,buffer);
@@ -349,6 +353,7 @@
     }
 
     // add each dimension to the legend
+    if(-xy->data_v.decimal_exponent > depth) depth = -xy->data_v.decimal_exponent;
     for(i=0;i<p->dimensions;i++){
       sushiv_dimension_t *d = p->dimension_list[i].d;
 
@@ -728,12 +733,13 @@
   if(!xy->x_vec[xy->cross_objnum] || !xy->y_vec[xy->cross_objnum])return;
 
   // get bin number of dim value
-  int x_bin = scalespace_pixel(&xy->data_v, xy->x_d->val);
+  int x_bin = rint(scalespace_pixel(&xy->data_v, xy->x_d->val));
   double x = xy->x_vec[xy->cross_objnum][x_bin];
   double y = xy->y_vec[xy->cross_objnum][x_bin];
 
   plot_set_crosshairs(plot,x,y);
-  
+  sushiv_dimension_set_value(p->sushi,xy->x_d->number,1,scalespace_value(&xy->data_v, x_bin));
+
   _sushiv_panel_dirty_legend(p);
 }
 
@@ -769,6 +775,7 @@
 
 static void dimchange_callback_xy(GtkWidget *button,gpointer in){
   sushiv_panel_t *p = (sushiv_panel_t *)in;
+  sushiv_panelxy_t *xy = p->subtype->xy;
 
   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))){
 
@@ -783,8 +790,8 @@
     update_crosshair(p); // which is to say, deactivate it
     plot_unset_box(PLOT(p->private->graph));
 
-    if(!_mark_recompute_by_metric(p,0))
-      _mark_recompute_xy(p);
+    xy->curr_zoom = xy->prev_zoom = xy->req_zoom = 0;
+    _mark_recompute_xy(p);
 
     _sushiv_undo_resume(p->sushi);
   }
@@ -853,7 +860,12 @@
     _sushiv_undo_suspend(p->sushi);
 
     crosshair_callback(p);
-    map_callback_xy(p,1);
+
+    slider_set_value(xy->x_slider,0,xy->oldbox[0]);
+    slider_set_value(xy->x_slider,1,xy->oldbox[1]);
+    slider_set_value(xy->y_slider,0,xy->oldbox[2]);
+    slider_set_value(xy->y_slider,1,xy->oldbox[3]);
+
     p->private->oldbox_active = 0;
     _sushiv_undo_resume(p->sushi);
     break;

Modified: trunk/sushivision/panel.c
===================================================================
--- trunk/sushivision/panel.c	2007-03-20 15:48:53 UTC (rev 12783)
+++ trunk/sushivision/panel.c	2007-03-20 18:42:11 UTC (rev 12784)
@@ -848,6 +848,12 @@
   p->objectives = i;
   p->objective_list = malloc(i*sizeof(*p->objective_list));
   for(i=0;i<p->objectives;i++){
+    if(objectives[i]<0 || objectives[i]>=s->objectives ||
+       s->objective_list[objectives[i]] == NULL){
+      fprintf(stderr,"Panel %d: Objective number %d does not exist\n",number, objectives[i]);
+      return -EINVAL;
+    }
+
     sushiv_objective_t *o = s->objective_list[objectives[i]];
     p->objective_list[i].o = o;
     p->objective_list[i].p = p;
@@ -858,6 +864,12 @@
   p->dimensions = i;
   p->dimension_list = malloc(i*sizeof(*p->dimension_list));
   for(i=0;i<p->dimensions;i++){
+    if(dimensions[i]<0 || dimensions[i]>=s->dimensions ||
+       s->dimension_list[dimensions[i]] == NULL){
+      fprintf(stderr,"Panel %d: Objective number %d does not exist\n",number, objectives[i]);
+      return -EINVAL;
+    }
+
     sushiv_dimension_t *d = s->dimension_list[dimensions[i]];
     p->dimension_list[i].d = d;
     p->dimension_list[i].p = p;

Modified: trunk/sushivision/slider.c
===================================================================
--- trunk/sushivision/slider.c	2007-03-20 15:48:53 UTC (rev 12783)
+++ trunk/sushivision/slider.c	2007-03-20 18:42:11 UTC (rev 12784)
@@ -625,7 +625,7 @@
     Slice *sl = SLICE(s->slices[i]);
     Slice *sl2 = SLICE(s->slices[i2]);
     if((sl->thumb_val>sl2->thumb_val)^flip)
-      sl->thumb_val=sl2->thumb_val;
+      slice_thumb_set(sl,sl2->thumb_val);
   }
   
   for(i=slicenum+1; i<s->num_slices;i++){
@@ -637,7 +637,8 @@
     Slice *sl = SLICE(s->slices[i]);
     Slice *sl2 = SLICE(s->slices[i2]);
     if((sl->thumb_val<sl2->thumb_val)^flip)
-      sl->thumb_val=sl2->thumb_val;
+      slice_thumb_set(sl,sl2->thumb_val);
+
   }
 }
 
@@ -811,7 +812,9 @@
   switch(event->keyval){
   case GDK_Left:
     {
-      double x = val_to_pixel(s,sl->thumb_val)-1;
+      double x = val_to_pixel(s,sl->thumb_val);
+      while(sl->thumb_val > s->label_vals[0] &&
+	    sl->thumb_val == slider_pixel_to_val(s,x))x--;
       if(shift)
 	x-=9;
       sl->thumb_val=slider_pixel_to_val(s,x);
@@ -832,7 +835,9 @@
 
   case GDK_Right:
     {
-      double x = val_to_pixel(s,sl->thumb_val)+1;
+      double x = val_to_pixel(s,sl->thumb_val);
+      while(sl->thumb_val < s->label_vals[s->labels-1] &&
+	    sl->thumb_val == slider_pixel_to_val(s,x))x++;
       if(shift)
 	x+=9;
       sl->thumb_val=slider_pixel_to_val(s,x);



More information about the commits mailing list