[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