[xiph-commits] r12777 - trunk/sushivision
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Mon Mar 19 01:33:09 PDT 2007
Author: xiphmont
Date: 2007-03-19 01:33:06 -0700 (Mon, 19 Mar 2007)
New Revision: 12777
Modified:
trunk/sushivision/Makefile
trunk/sushivision/internal.h
trunk/sushivision/panel-1d.c
trunk/sushivision/panel-xy.c
trunk/sushivision/panel-xy.h
Log:
XY panels build, don't run yet
Modified: trunk/sushivision/Makefile
===================================================================
--- trunk/sushivision/Makefile 2007-03-18 14:46:07 UTC (rev 12776)
+++ trunk/sushivision/Makefile 2007-03-19 08:33:06 UTC (rev 12777)
@@ -25,14 +25,14 @@
SOLDFLAGS = -shared -nostdlib -Wl,-soname="lib$(NAME).so.$(MAJOR)"
SRC = main.c scale.c plot.c slider.c slice.c spinner.c panel.c panel-1d.c panel-2d.c \
- mapping.c dimension.c function.c objective.c undo.c gtksucks.c xml.c \
+ panel-xy.c mapping.c dimension.c function.c objective.c undo.c gtksucks.c xml.c \
example_fractal.c example_discrete.c example_chirp.c
INC = sushivision.h
MAN =
EXAMPLES = sushivision_fractal sushivision_discrete sushivision_chirp
EX_OBJ = example_fractal.o example_discrete.o example_chirp.o
OBJ = main.o scale.o plot.o slider.o slice.o spinner.c panel.o panel-1d.o panel-2d.o \
- mapping.o dimension.o function.o objective.o undo.o gtksucks.o xml.o
+ panel-xy.o mapping.o dimension.o function.o objective.o undo.o gtksucks.o xml.o
LIBS = -lpthread -ldl
CAIROVER = >= 1.4.1
GTKVER = >= 2.10.0
Modified: trunk/sushivision/internal.h
===================================================================
--- trunk/sushivision/internal.h 2007-03-18 14:46:07 UTC (rev 12776)
+++ trunk/sushivision/internal.h 2007-03-19 08:33:06 UTC (rev 12777)
@@ -53,7 +53,7 @@
#include "gtksucks.h"
union sushiv_panel_subtype {
- sushiv_panelxy_t *pxy;
+ sushiv_panelxy_t *xy;
sushiv_panel1d_t *p1;
sushiv_panel2d_t *p2;
};
@@ -84,6 +84,7 @@
typedef union {
_sushiv_bythread_cache_1d p1;
+ _sushiv_bythread_cache_xy xy;
_sushiv_bythread_cache_2d p2;
} _sushiv_bythread_cache;
Modified: trunk/sushivision/panel-1d.c
===================================================================
--- trunk/sushivision/panel-1d.c 2007-03-18 14:46:07 UTC (rev 12776)
+++ trunk/sushivision/panel-1d.c 2007-03-19 08:33:06 UTC (rev 12777)
@@ -501,7 +501,7 @@
// update colormap
int pos = gtk_combo_box_get_active(GTK_COMBO_BOX(w));
- p1->linetype[onum] = line_name[pos].value;
+ p1->linetype[onum] = line_name[pos]->value;
_sushiv_panel_dirty_map(p);
_sushiv_undo_resume(p->sushi);
@@ -518,7 +518,7 @@
// update colormap
int pos = gtk_combo_box_get_active(GTK_COMBO_BOX(w));
- p1->pointtype[onum] = point_name[pos].value;
+ p1->pointtype[onum] = point_name[pos]->value;
_sushiv_panel_dirty_map(p);
_sushiv_undo_resume(p->sushi);
Modified: trunk/sushivision/panel-xy.c
===================================================================
--- trunk/sushivision/panel-xy.c 2007-03-18 14:46:07 UTC (rev 12776)
+++ trunk/sushivision/panel-xy.c 2007-03-19 08:33:06 UTC (rev 12777)
@@ -54,6 +54,29 @@
NULL
};
+static void clear_xy_data(sushiv_panel_t *p){
+ sushiv_panelxy_t *xy = p->subtype->xy;
+ int i;
+
+ if(xy->x_vec){
+ for(i=0;i<p->objectives;i++){
+ if(xy->x_vec[i]){
+ free(xy->x_vec[i]);
+ xy->x_vec[i]=0;
+ }
+ }
+ }
+
+ if(xy->y_vec){
+ for(i=0;i<p->objectives;i++){
+ if(xy->y_vec[i]){
+ free(xy->y_vec[i]);
+ xy->y_vec[i]=0;
+ }
+ }
+ }
+}
+
static void render_checks(cairo_t *c, int w, int h){
/* default checked background */
/* 16x16 'mid-checks' */
@@ -78,7 +101,7 @@
// called internally, assumes we hold lock
// redraws the data, does not compute the data
static int _sushiv_panelxy_remap(sushiv_panel_t *p, cairo_t *c){
- sushiv_panelxy_t *xy = p->subtype->pxy;
+ sushiv_panelxy_t *xy = p->subtype->xy;
Plot *plot = PLOT(p->private->graph);
int plot_serialno = p->private->plot_serialno;
@@ -87,9 +110,9 @@
int pw = plot->x.pixels;
int ph = plot->y.pixels;
- scalespace sx = p1->x;
- scalespace sy = p1->y;
- scalespace data_v = p1->data_v;
+ scalespace sx = xy->x;
+ scalespace sy = xy->y;
+ scalespace data_v = xy->data_v;
scalespace px = plot->x;
scalespace py = plot->y;
@@ -126,13 +149,13 @@
if(plot_serialno != p->private->plot_serialno ||
map_serialno != p->private->map_serialno) return -1;
- if(xy->data_head){
+ if(xy->x_vec && xy->y_vec){
/* by objective */
for(j=0;j<p->objectives;j++){
if(xy->x_vec[j] && xy->y_vec[j] && !mapping_inactive_p(xy->mappings+j)){
- int dw = xy->data_v.pixels;
+ int dw = data_v.pixels;
double alpha = slider_get_value(xy->alpha_scale[j],0);
int linetype = xy->linetype[j];
int pointtype = xy->pointtype[j];
@@ -261,8 +284,6 @@
gdk_threads_enter();
if(plot_serialno != p->private->plot_serialno ||
map_serialno != p->private->map_serialno) return -1;
-
-
}
}
}
@@ -307,14 +328,14 @@
// if crosshairs are active, add them to the fun
if( plot->cross_active){
snprintf(buffer,320,"%s = %+.*f",
- xy->x_scale.name,
+ xy->x_scale->legend,
depth,
- xy->x_val);
+ plot->selx);
plot_legend_add(plot,buffer);
snprintf(buffer,320,"%s = %+.*f",
- xy->y_scale.name,
+ xy->y_scale->legend,
depth,
- xy->y_val);
+ plot->sely);
plot_legend_add(plot,buffer);
if(p->dimensions)
@@ -341,33 +362,33 @@
}
// call with lock
-static double _determine_rerender_metric(sushiv_panel_t *p, int half){
+static double _determine_rerender_metric(sushiv_panel_t *p, int off){
sushiv_panelxy_t *xy = p->subtype->xy;
int on = p->objectives;
double pw = p->private->graph->allocation.width;
double ph = p->private->graph->allocation.height;
int dw = xy->data_v.pixels;
- int off = (half?2;1);
// if this is a discrete data set, size/view changes cannot affect
// the data spacing; that's set by the discrete scale
- if(p->x_d->type != SUSHIV_DIM_CONTINUOUS) return -1;
+ if(xy->x_d->type != SUSHIV_DIM_CONTINUOUS) return -1;
double xscale = scalespace_pixel(&xy->x,1.) - scalespace_pixel(&xy->x,0.);
double yscale = scalespace_pixel(&xy->y,1.) - scalespace_pixel(&xy->y,0.);
// by plane, look at the spacing between visible x/y points
double max = -1;
+ int i,j;
for(i=0;i<on;i++){
if(xy->x_vec[j] && xy->y_vec[j] && !mapping_inactive_p(xy->mappings+i)){
double xacc = 0;
double yacc = 0;
double count = 0;
- double *x = p->x_vec[i];
- double *y = p->y_vec[i];
+ double *x = xy->x_vec[i];
+ double *y = xy->y_vec[i];
- for(j = off; j+off<=dw, j+=off){
+ for(j = off; j<dw; j++){
if(!isnan(x[i-off]) &&
!isnan(y[i-off]) &&
!isnan(x[i]) &&
@@ -383,7 +404,7 @@
}
}
- acc = sqrt(xacc*xscale*xscale + yacc*yscale*yscale);
+ double acc = sqrt(xacc*xscale*xscale + yacc*yscale*yscale);
if(count>0)
if(acc/count > max) max = acc/count;
@@ -395,38 +416,48 @@
}
// call while locked
-static int _mark_recompute_by_metric_change(sushiv_panel_t *p, int recursing){
+static int _mark_recompute_by_metric(sushiv_panel_t *p, int recursing){
+ sushiv_panelxy_t *xy = p->subtype->xy;
+
// discrete val dimensions are immune to rerender by metric changes
- if(p->x_d->type != SUSHIV_DIM_CONTINUOUS) return 0;
+ if(xy->x_d->type != SUSHIV_DIM_CONTINUOUS) return 0;
- sushiv_panelxy_t *xy = p->subtype->xy;
double target = (double) p->private->oversample_n / p->private->oversample_d;
- double full = _determine_rerender_metric(p, 0);
-
- if(!recursing) xy->request_scaling = 0;
+ double full = _determine_rerender_metric(p, 1);
if(full > target){
// we want to halve the sample spacing. But first make sure we're
// not looping due to uncertainties in the metric.
- if(xy->request_scaling != -1){
- xy->request_scaling = 1; // double pixels, halve spacing
- _sushiv_panel_dirty_plot(p); // trigger recompute
- return 1;
- }
+ if(recursing && xy->prev_zoom > xy->curr_zoom) return 0;
+
+ // also make sure our zoom level doesn't underflow
+ if(xy->data_v.massaged) return 0;
+
+ xy->prev_zoom = xy->curr_zoom;
+ xy->curr_zoom++;
+
+ _sushiv_panel_dirty_plot(p); // trigger recompute
+ return 1;
} else {
- double half = _determine_rerender_metric(p, 1);
+ double half = _determine_rerender_metric(p, 2);
if(half < target){
// we want to double the sample spacing. But first make sure we're
// not looping due to uncertainties in the metric.
- if(xy->request_scaling != 1){
- xy->request_scaling = -1; // halve pixels, double spacing
- _sushiv_panel_dirty_plot(p); // trigger recompute
- return 1;
- }
+ if(recursing && xy->prev_zoom < xy->curr_zoom) return 0;
+
+ // also make sure our zoom level doesn't overrflow
+ if(xy->curr_zoom == 0) return 0;
+
+ xy->prev_zoom = xy->curr_zoom;
+ xy->curr_zoom--;
+
+ _sushiv_panel_dirty_plot(p); // trigger recompute
+ return 1;
+
}
}
- xy->request_scaling = 0;
+ xy->prev_zoom = xy->curr_zoom;
return 0;
}
@@ -435,7 +466,8 @@
sushiv_panel_t *p = optr->p;
sushiv_panelxy_t *xy = p->subtype->xy;
int onum = optr - p->objective_list;
-
+ Plot *plot = PLOT(p->private->graph);
+
_sushiv_undo_push(p->sushi);
_sushiv_undo_suspend(p->sushi);
@@ -445,14 +477,21 @@
solid_set_func(&xy->mappings[onum],pos);
slider_set_gradient(xy->alpha_scale[onum], &xy->mappings[onum]);
+ // if the mapping has become inactive and the crosshairs point to
+ // this objective, inactivate the crosshairs.
+ if(xy->cross_objnum == onum)
+ plot->cross_active = 0;
+
// a map view size change may trigger a progressive up/down render,
// but will at least cause a remap
- if(!_mark_recompute_by_metric_change(p,0))
- _sushiv_panel_dirty_map(p);
+ _mark_recompute_by_metric(p,0);
+
+ _sushiv_panel_dirty_map(p);
_sushiv_panel_dirty_legend(p);
+
_sushiv_undo_resume(p->sushi);
}
-XXX
+
static void alpha_callback_xy(void * in, int buttonstate){
sushiv_objective_list_t *optr = (sushiv_objective_list_t *)in;
sushiv_panel_t *p = optr->p;
@@ -480,7 +519,7 @@
// update colormap
int pos = gtk_combo_box_get_active(GTK_COMBO_BOX(w));
- xy->linetype[onum] = line_name[pos].value;
+ xy->linetype[onum] = line_name[pos]->value;
_sushiv_panel_dirty_map(p);
_sushiv_undo_resume(p->sushi);
@@ -497,7 +536,7 @@
// update colormap
int pos = gtk_combo_box_get_active(GTK_COMBO_BOX(w));
- xy->pointtype[onum] = point_name[pos].value;
+ xy->pointtype[onum] = point_name[pos]->value;
_sushiv_panel_dirty_map(p);
_sushiv_undo_resume(p->sushi);
@@ -505,7 +544,7 @@
static void map_callback_xy(void *in,int buttonstate){
sushiv_panel_t *p = (sushiv_panel_t *)in;
- sushiv_panel1d_t *xy = p->subtype->xy;
+ sushiv_panelxy_t *xy = p->subtype->xy;
Plot *plot = PLOT(p->private->graph);
if(buttonstate == 0){
@@ -527,25 +566,25 @@
xy->y_bracket[0] = slider_get_value(xy->y_slider,0);
xy->y_bracket[1] = slider_get_value(xy->y_slider,1);
- xy->x = scalespace_linear(xy->x_bracket[1],
- xy->x_bracket[0],
- w,
- plot->scalespacing,
- xy->x_scale->legend);
- xy->y = scalespace_linear(xy->y_bracket[1],
- xy->y_bracket[0],
- h,
- plot->scalespacing,
- xy->y_scale->legend);
+
+ plot->x = xy->x = scalespace_linear(xy->x_bracket[1],
+ xy->x_bracket[0],
+ w,
+ plot->scalespacing,
+ xy->x_scale->legend);
+ plot->y = xy->y = scalespace_linear(xy->y_bracket[1],
+ xy->y_bracket[0],
+ h,
+ plot->scalespacing,
+ xy->y_scale->legend);
+ // a map view size change may trigger a progressive up/down render,
+ // but will at least cause a remap
+ _mark_recompute_by_metric(p,0);
+
+ _sushiv_panel_dirty_map(p);
+
}
-XXX
- // a map view size change may trigger a progressive up/down render,
- // but will at least cause a remap
- if(_determine_rerender_by_metric(p))
- _mark_recompute_xy(p);
- else
- _sushiv_panel_dirty_map(p);
if(buttonstate == 2)
_sushiv_undo_resume(p->sushi);
@@ -580,232 +619,147 @@
}
static void compute_xy(sushiv_panel_t *p,
+ int serialno,
int x_d,
scalespace sxi,
double *dim_vals,
+ char *prefilled,
double **x_vec,
double **y_vec,
- _sushiv_bythread_cache_1d *c){
- sushiv_panelxy_t *xy = p->subtype->xy;
+ _sushiv_bythread_cache_xy *c){
+
int i,j,fn=p->sushi->functions;
int w = sxi.pixels;
/* by x */
for(j=0;j<w;j++){
- dim_vals[x_d] = scalespace_value(&sxi,j);
-
- /* by function */
- for(i=0;i<fn;i++){
- if(c->call[i]){
- sushiv_function_t *f = p->sushi->function_list[i];
- double *fout = c->fout[i];
- c->call[i](dim_vals,fout);
+ if(!prefilled[j]){
+ dim_vals[x_d] = scalespace_value(&sxi,j);
+
+ /* by function */
+ for(i=0;i<fn;i++){
+ if(c->call[i]){
+ double *fout = c->fout[i];
+ c->call[i](dim_vals,fout);
+ }
}
+
+ /* process function output by objective */
+ /* xy panels currently only care about the XY output values; in the
+ future, Z and others may also be relevant */
+ for(i=0;i<p->objectives;i++){
+ sushiv_objective_t *o = p->objective_list[i].o;
+ int xoff = o->private->x_fout;
+ int yoff = o->private->y_fout;
+ sushiv_function_t *xf = o->private->x_func;
+ sushiv_function_t *yf = o->private->y_func;
+ x_vec[i][j] = c->fout[xf->number][xoff];
+ y_vec[i][j] = c->fout[yf->number][yoff];
+ }
}
- /* process function output by objective */
- /* xy panels currently only care about the XY output values; in the
- future, Z may also be relevant */
- for(i=0;i<p->objectives;i++){
- sushiv_objective_t *o = p->objective_list[i].o;
- int xoff = o->private->x_fout;
- int yoff = o->private->y_fout;
- sushiv_function_t *xf = o->private->x_func;
- sushiv_function_t *yf = o->private->y_func;
- x_vec[j] = c->fout[xf->number][xoff];
- y_vec[j] = c->fout[yf->number][yoff];
+ if(!(j&0x3f)){
+ gdk_threads_enter();
+
+ if(serialno != p->private->plot_serialno){
+ gdk_threads_leave();
+ return;
+ }
+
+ spinner_set_busy(p->private->spinner);
+ gdk_threads_leave();
}
}
}
-// call only from main gtk thread
+// call with lock
void _mark_recompute_xy(sushiv_panel_t *p){
if(!p->private->realized) return;
+
+ _sushiv_panel_dirty_plot(p);
+}
+
+static void recompute_callback_xy(void *ptr){
+ sushiv_panel_t *p = (sushiv_panel_t *)ptr;
sushiv_panelxy_t *xy = p->subtype->xy;
Plot *plot = PLOT(p->private->graph);
int w = plot->w.allocation.width;
int h = plot->w.allocation.height;
- int dw = w;
- int i,j;
-XXXX
- if(plot && GTK_WIDGET_REALIZED(GTK_WIDGET(plot))){
- dw = _sushiv_dimension_scales(p1->x_d,
- p1->x_d->bracket[0],
- p1->x_d->bracket[1],
- w,dw * p->private->oversample_n / p->private->oversample_d,
- plot->scalespacing,
- p1->x_d->name,
- &p1->x,
- &p1->x_v,
- &p1->x_i);
+ plot->x = xy->x = scalespace_linear(xy->x_bracket[0],
+ xy->x_bracket[1],
+ w,
+ plot->scalespacing,
+ xy->x_scale->legend);
+ plot->y = xy->y = scalespace_linear(xy->y_bracket[1],
+ xy->y_bracket[0],
+ h,
+ plot->scalespacing,
+ xy->y_scale->legend);
- p1->y = scalespace_linear(p1->range_bracket[1],
- p1->range_bracket[0],
- h,
- plot->scalespacing,
- p1->range_scale->legend);
- }
+ // always recompute, but also update zoom
+ if(!_mark_recompute_by_metric(p,0))
+ _mark_recompute_xy(p);
+}
- if(p1->data_size != dw){
- if(p1->data_vec){
+static void update_crosshair(sushiv_panel_t *p){
+ sushiv_panelxy_t *xy = p->subtype->xy;
+ Plot *plot = PLOT(p->private->graph);
- // make new vec
- int i;
- for(i=0;i<p->objectives;i++){
- double *new_vec = malloc(dw * sizeof(**p1->data_vec));
- free(p1->data_vec[i]);
- p1->data_vec[i] = new_vec;
- }
- }
- }
-
- p1->data_size = dw;
- p1->panel_w = w;
- p1->panel_h = h;
-
- if(!p1->data_vec){
- // allocate it
+ if(!p->private->realized)return;
- p1->data_vec = calloc(p->objectives,sizeof(*p1->data_vec));
- for(i=0;i<p->objectives;i++)
- p1->data_vec[i] = malloc(dw*sizeof(**p1->data_vec));
-
- }
+ // crosshairs snap to the x/y location of a point; however, with
+ // multiple objectives, there are probably multiple possible points.
+ // So, if we're currently pointing to a point for a given objective,
+ // update to a point on the same objective. Otherwise if crosshairs
+ // are inactive, do nothing.
- // blank it
- for(i=0;i<p->objectives;i++)
- for(j=0;j<dw;j++)
- p1->data_vec[i][j]=NAN;
+ if(!plot->cross_active)return;
+ if(xy->cross_objnum<0 || xy->cross_objnum >= p->objectives)return;
+ if(!xy->x_vec || !xy->y_vec)return;
+ if(!xy->x_vec[xy->cross_objnum] || !xy->y_vec[xy->cross_objnum])return;
- _sushiv_panel_dirty_plot(p);
- }
-}
+ // get bin number of dim value
+ int x_bin = 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];
-static void recompute_callback_1d(void *ptr){
- sushiv_panel_t *p = (sushiv_panel_t *)ptr;
- _mark_recompute_1d(p);
-}
-
-void _sushiv_panel1d_mark_recompute_linked(sushiv_panel_t *p){
- int i;
-
- /* look to see if any 1d panels link to passed in panel */
- sushiv_instance_t *s = p->sushi;
- for(i=0;i<s->panels;i++){
- sushiv_panel_t *q = s->panel_list[i];
- if(q != p && q->type == SUSHIV_PANEL_1D){
- sushiv_panel1d_t *q1 = q->subtype->p1;
- if(q1->link_x == p)
- _mark_recompute_1d(q);
- else{
- if(q1->link_y == p)
- _mark_recompute_1d(q);
- }
- }
- }
-}
-
-static void update_crosshair(sushiv_panel_t *p){
- sushiv_panel1d_t *p1 = p->subtype->p1;
- sushiv_panel_t *link=p1->link_x;
- Plot *plot = PLOT(p->private->graph);
- double x=0;
- int i;
-
- if(!p->private->realized)return;
+ plot_set_crosshairs(plot,x,y);
- if(p1->link_y)link=p1->link_y;
-
- if(link){
- for(i=0;i<link->dimensions;i++){
- sushiv_dimension_t *d = link->dimension_list[i].d;
- if(d == p1->x_d)
- x = link->dimension_list[i].d->val;
- }
- }else{
- for(i=0;i<p->dimensions;i++){
- sushiv_dimension_t *d = p->dimension_list[i].d;
- if(d == p1->x_d)
- x = p->dimension_list[i].d->val;
- }
- }
-
- if(p1->flip)
- plot_set_crosshairs(plot,0,x);
- else
- plot_set_crosshairs(plot,x,0);
-
- // in independent panels, crosshairs snap to a pixel position; the
- // cached dimension value should be accurate with respect to the
- // crosshairs. in linked panels, the crosshairs snap to a pixel
- // position in the master panel; that is handled in the master, not
- // here.
- for(i=0;i<p->dimensions;i++){
- sushiv_dimension_t *d = p->dimension_list[i].d;
- sushiv_panel1d_t *p1 = p->subtype->p1;
- if(d == p1->x_d){
- if(p1->flip)
- d->val = scalespace_value(&plot->x,plot_get_crosshair_ypixel(plot));
- else
- d->val = scalespace_value(&plot->x,plot_get_crosshair_xpixel(plot));
- }
- }
_sushiv_panel_dirty_legend(p);
}
-void _sushiv_panel1d_update_linked_crosshairs(sushiv_panel_t *p, int xflag, int yflag){
- int i;
-
- /* look to see if any 1d panels link to passed in panel */
- sushiv_instance_t *s = p->sushi;
- for(i=0;i<s->panels;i++){
- sushiv_panel_t *q = s->panel_list[i];
- if(q != p && q->type == SUSHIV_PANEL_1D){
- sushiv_panel1d_t *q1 = q->subtype->p1;
- if(q1->link_x == p){
- update_crosshair(q);
- if(yflag)
- q->private->request_compute(q);
- }else{
- if(q1->link_y == p){
- update_crosshair(q);
- if(xflag)
- q->private->request_compute(q);
- }
- }
- }
- }
-}
-
-static void center_callback_1d(sushiv_dimension_list_t *dptr){
+static void center_callback_xy(sushiv_dimension_list_t *dptr){
sushiv_dimension_t *d = dptr->d;
sushiv_panel_t *p = dptr->p;
- sushiv_panel1d_t *p1 = p->subtype->p1;
- int axisp = (d == p1->x_d);
+ sushiv_panelxy_t *xy = p->subtype->xy;
+ int axisp = (d == xy->x_d);
if(!axisp){
// mid slider of a non-axis dimension changed, rerender
- _mark_recompute_1d(p);
+ _mark_recompute_xy(p);
}else{
// mid slider of an axis dimension changed, move crosshairs
update_crosshair(p);
}
}
-static void bracket_callback_1d(sushiv_dimension_list_t *dptr){
+static void bracket_callback_xy(sushiv_dimension_list_t *dptr){
sushiv_dimension_t *d = dptr->d;
sushiv_panel_t *p = dptr->p;
- sushiv_panel1d_t *p1 = p->subtype->p1;
- int axisp = d == p1->x_d;
+ sushiv_panelxy_t *xy = p->subtype->xy;
+ int axisp = (d == xy->x_d);
+ // always need to recompute, amy also need to update zoom
+
if(axisp)
- _mark_recompute_1d(p);
-
+ if(!_mark_recompute_by_metric(p,0))
+ _mark_recompute_xy(p);
+
}
-static void dimchange_callback_1d(GtkWidget *button,gpointer in){
+static void dimchange_callback_xy(GtkWidget *button,gpointer in){
sushiv_panel_t *p = (sushiv_panel_t *)in;
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))){
@@ -813,66 +767,77 @@
_sushiv_undo_push(p->sushi);
_sushiv_undo_suspend(p->sushi);
- update_x_sel(p);
- update_crosshair(p);
+ update_dim_sel(p);
+
+ // clear data vectors so that none of the data is reused.
+ clear_xy_data(p);
+
+ update_crosshair(p); // which is to say, deactivate it
plot_unset_box(PLOT(p->private->graph));
- _mark_recompute_1d(p);
+ if(!_mark_recompute_by_metric(p,0))
+ _mark_recompute_xy(p);
+
_sushiv_undo_resume(p->sushi);
}
}
static void crosshair_callback(sushiv_panel_t *p){
- sushiv_panel1d_t *p1 = p->subtype->p1;
- sushiv_panel_t *link = p1->link_x;
+ sushiv_panelxy_t *xy = p->subtype->xy;
double x=PLOT(p->private->graph)->selx;
- int i;
+ double y=PLOT(p->private->graph)->sely;
+ int i,j;
- if(p1->flip)
- x=PLOT(p->private->graph)->sely;
- if(p1->link_y)
- link=p1->link_y;
+ _sushiv_undo_push(p->sushi);
+ _sushiv_undo_suspend(p->sushi);
- _sushiv_panel_dirty_legend(p);
+ // snap crosshairs to the closest plotted x/y point
+ int besto=-1;
+ int bestbin=-1;
+ double bestdist;
- if(p1->link_x){
- // make it the master panel's problem.
- plot_set_crosshairs_snap(PLOT(link->private->graph),
- x,
- PLOT(link->private->graph)->sely);
- link->private->crosshair_action(link);
- }else if (p1->link_y){
- // make it the master panel's problem.
- plot_set_crosshairs_snap(PLOT(link->private->graph),
- PLOT(link->private->graph)->selx,
- x);
- link->private->crosshair_action(link);
- }else{
+ for(i=0;i<p->objectives;i++){
+ if(xy->x_vec[i] && xy->y_vec[i] && !mapping_inactive_p(xy->mappings+i)){
+ for(j=0;j<xy->data_v.pixels;j++){
+ double xd = x - xy->x_vec[i][j];
+ double yd = y - xy->y_vec[i][j];
+ double dist = xd*xd + yd*yd;
+ if(besto==-1 || dist<bestdist){
+ besto = i;
+ bestbin = j;
+ bestdist = dist;
+ }
+ }
+ }
+ }
- _sushiv_undo_push(p->sushi);
- _sushiv_undo_suspend(p->sushi);
+ if(besto>-1){
+ x = xy->x_vec[besto][bestbin];
+ y = xy->y_vec[besto][bestbin];
- for(i=0;i<p->dimensions;i++){
- sushiv_dimension_t *d = p->dimension_list[i].d;
- sushiv_panel1d_t *p1 = p->subtype->p1;
- if(d == p1->x_d)
- _sushiv_dimension_set_value(p->private->dim_scales[i],1,x);
-
- p->private->oldbox_active = 0;
- }
- _sushiv_undo_resume(p->sushi);
+ PLOT(p->private->graph)->selx = x;
+ PLOT(p->private->graph)->sely = y;
+ xy->cross_objnum = besto;
+
+ double dimval = scalespace_value(&xy->data_v, bestbin);
+ sushiv_dimension_set_value(p->sushi,xy->x_d->number,1,dimval);
}
+
+ p->private->oldbox_active = 0;
+ _sushiv_undo_resume(p->sushi);
+ _sushiv_panel_dirty_legend(p);
+
}
static void box_callback(void *in, int state){
sushiv_panel_t *p = (sushiv_panel_t *)in;
- sushiv_panel1d_t *p1 = p->subtype->p1;
+ sushiv_panelxy_t *xy = p->subtype->xy;
Plot *plot = PLOT(p->private->graph);
switch(state){
case 0: // box set
_sushiv_undo_push(p->sushi);
- plot_box_vals(plot,p1->oldbox);
+ plot_box_vals(plot,xy->oldbox);
p->private->oldbox_active = plot->box_active;
break;
case 1: // box activate
@@ -880,9 +845,7 @@
_sushiv_undo_suspend(p->sushi);
crosshair_callback(p);
-
- _sushiv_dimension_set_value(p1->x_scale,0,p1->oldbox[0]);
- _sushiv_dimension_set_value(p1->x_scale,2,p1->oldbox[1]);
+ map_callback_xy(p,1);
p->private->oldbox_active = 0;
_sushiv_undo_resume(p->sushi);
break;
@@ -890,7 +853,7 @@
_sushiv_panel_update_menus(p);
}
-void _maintain_cache_1d(sushiv_panel_t *p, _sushiv_bythread_cache_1d *c, int w){
+void _maintain_cache_xy(sushiv_panel_t *p, _sushiv_bythread_cache_xy *c, int w){
/* toplevel initialization */
if(c->fout == 0){
@@ -905,17 +868,10 @@
c->call[o->function_map[j]]=
p->sushi->function_list[o->function_map[j]]->callback;
}
- }
- /* once to begin, as well as anytime the data width changes */
- if(c->storage_width < w){
- int i;
- c->storage_width = w;
-
for(i=0;i<p->sushi->functions;i++){
if(c->call[i]){
- if(c->fout[i])free(c->fout[i]);
- c->fout[i] = malloc(w * p->sushi->function_list[i]->outputs *
+ c->fout[i] = malloc(p->sushi->function_list[i]->outputs *
sizeof(**c->fout));
}
}
@@ -923,7 +879,7 @@
}
// subtype entry point for plot remaps; lock held
-int _sushiv_panel1d_map_redraw(sushiv_panel_t *p, _sushiv_bythread_cache *c){
+int _sushiv_panelxy_map_redraw(sushiv_panel_t *p, _sushiv_bythread_cache *c){
if(p->private->map_progress_count)return 0;
p->private->map_progress_count++;
@@ -935,7 +891,7 @@
cairo_image_surface_get_height(back));
cairo_t *ct = cairo_create(cs);
- if(_sushiv_panel1d_remap(p,ct) == -1){ // returns -1 on abort
+ if(_sushiv_panelxy_remap(p,ct) == -1){ // returns -1 on abort
cairo_destroy(ct);
cairo_surface_destroy(cs);
}else{
@@ -952,9 +908,9 @@
}
// subtype entry point for legend redraws; lock held
-int _sushiv_panel1d_legend_redraw(sushiv_panel_t *p){
+int _sushiv_panelxy_legend_redraw(sushiv_panel_t *p){
Plot *plot = PLOT(p->private->graph);
-
+
if(p->private->legend_progress_count)return 0;
p->private->legend_progress_count++;
update_legend(p);
@@ -968,57 +924,143 @@
return 1;
}
+// dim scales are autozoomed; we want the initial values to quantize
+// to the same grid regardless of zoom level or starting bracket as
+// well as only encompass the desired range
+static int _generate_dimscale_xy(sushiv_dimension_t *d, int zoom, scalespace *v, scalespace *i){
+ scalespace x;
+
+ if(d->type != SUSHIV_DIM_CONTINUOUS){
+ // non-continuous is unaffected by zoom
+ _sushiv_dimension_scales(d, d->bracket[0], d->bracket[1], 2, 2, 1, d->name, &x, v, i);
+ return 0;
+ }
+
+ // continuous dimensions are, in some ways, handled like a discrete dim.
+ double lo = d->scale->val_list[0];
+ double hi = d->scale->val_list[d->scale->vals-1];
+ _sushiv_dimension_scales(d, lo, hi, 2, 2, 1, NULL, &x, v, i);
+
+ // generate a new low that is quantized to our coarsest grid
+ lo = scalespace_value(v,0);
+
+ // choose a new resolution, make new scales
+
+ // this is iterative, not direct computation, so that at each level
+ // we have a small adjustment (as opposed to one huge adjustment at
+ // the end) as well as more resolution headroom at each level
+ int sofar = 0;
+ while (sofar<zoom){
+ int pixels = v->pixels << 1;
+
+ _sushiv_dimension_scales(d, lo, hi, pixels, pixels, 1, NULL, &x, v, i);
+ if(v->massaged)return 1;
+
+ // clip scales down the the desired part of the range
+ while(v->pixels>2 && scalespace_value(v,1) < d->bracket[0]){
+ v->first_pixel--;
+ i->first_pixel--;
+ v->pixels--;
+ i->pixels--;
+ }
+
+ while(v->pixels>2 && scalespace_value(v,v->pixels-1) > d->bracket[1]){
+ v->pixels--;
+ i->pixels--;
+ }
+ }
+
+ return 0;
+}
+
+static void _rescale_xy(scalespace *old, double **oldx, double **oldy,
+ scalespace *new, double **newx, double **newy,
+ char *prefilled, int objectives){
+
+ if(!oldx || !oldy)return;
+
+ int newi = 0;
+ int oldi = 0;
+ int j;
+
+ long num = scalespace_scalenum(new,old);
+ long den = scalespace_scalenum(new,old);
+ long oldpos = scalespace_scaleoff(new,old);
+ long newpos = 0;
+
+ while(newi < new->pixels && oldi < old->pixels){
+
+ if(oldpos == newpos &&
+ oldi >= 0){
+ prefilled[newi] = 1;
+ for(j=0;j<objectives;j++){
+ if(oldx[j])
+ newx[j][newi] = oldx[j][oldi];
+ if(oldy[j])
+ newy[j][newi] = oldy[j][oldi];
+ }
+ }
+
+ while(newi < new->pixels && newi < oldi ){
+ newpos += den;
+ newi++;
+ }
+ while(oldi < old->pixels && oldi < newi ){
+ oldpos += num;
+ oldi++;
+ }
+ }
+}
+
// subtype entry point for recomputation; lock held
-int _sushiv_panel1d_compute(sushiv_panel_t *p,
+int _sushiv_panelxy_compute(sushiv_panel_t *p,
_sushiv_bythread_cache *c){
- sushiv_panel1d_t *p1 = p->subtype->p1;
+ sushiv_panelxy_t *xy = p->subtype->xy;
Plot *plot;
int dw,w,h,i,d;
int serialno;
int x_d=-1;
- scalespace sy;
- scalespace sx;
- scalespace sxv;
- scalespace sxi;
+ scalespace sxv = xy->data_v;
+ plot = PLOT(p->private->graph);
- dw = p1->data_size;
- w = p1->panel_w;
- h = p1->panel_h;
+ dw = sxv.pixels;
+ w = plot->w.allocation.width;
+ h = plot->w.allocation.height;
- sy = p1->y;
-
- sx = p1->x;
- sxv = p1->x_v;
- sxi = p1->x_i;
-
+ // this computation is single-threaded for now
if(p->private->plot_progress_count)
return 0;
serialno = p->private->plot_serialno;
p->private->plot_progress_count++;
d = p->dimensions;
- plot = PLOT(p->private->graph);
/* render using local dimension array; several threads will be
computing objectives */
double dim_vals[p->sushi->dimensions];
/* get iterator bounds, use iterator scale */
- x_d = p1->x_d->number;
+ x_d = xy->x_d->number;
- if(p1->flip){
- plot->x = sy;
- plot->y = sx;
- plot->x_v = sy;
- plot->y_v = sxv;
- }else{
- plot->x = sx;
- plot->y = sy;
- plot->x_v = sxv;
- plot->y_v = sy;
+ /* generate a new data_v/data_i */
+ scalespace newv;
+ scalespace newi;
+ _generate_dimscale_xy(xy->x_d, xy->curr_zoom, &newv, &newi);
+ dw = newv.pixels;
+
+ /* compare new/old data scales; pre-fill the data vec with values
+ from old data vector if it can be reused */
+ double *new_x_vec[p->objectives];
+ double *new_y_vec[p->objectives];
+ char *prefilled = calloc(dw,sizeof(*prefilled));
+ for(i=0;i<p->objectives;i++){
+ new_x_vec[i] = calloc(dw,sizeof(**new_x_vec));
+ new_y_vec[i] = calloc(dw,sizeof(**new_y_vec));
}
+ _rescale_xy(&sxv,xy->x_vec,xy->y_vec,
+ &newv,new_x_vec,new_y_vec,prefilled, p->objectives);
// Initialize local dimension value array
for(i=0;i<p->sushi->dimensions;i++){
@@ -1026,84 +1068,121 @@
dim_vals[i]=dim->val;
}
- _maintain_cache_1d(p,&c->p1,dw);
+ _maintain_cache_xy(p,&c->xy,dw);
/* unlock for computation */
gdk_threads_leave ();
plot_draw_scales(plot);
- compute_1d(p, serialno, x_d, sxi, dw, dim_vals, &c->p1);
+ compute_xy(p, serialno, x_d, newi, dim_vals, prefilled, new_x_vec, new_y_vec, &c->xy);
gdk_threads_enter ();
if(serialno == p->private->plot_serialno){
+ // replace data vectors
+ p->private->plot_serialno++;
+ clear_xy_data(p);
+ if(!xy->x_vec)
+ xy->x_vec = calloc(p->objectives, sizeof(*xy->x_vec));
+ if(!xy->y_vec)
+ xy->y_vec = calloc(p->objectives, sizeof(*xy->y_vec));
+ for(i=0;i<p->objectives;i++){
+ xy->x_vec[i] = new_x_vec[i];
+ xy->y_vec[i] = new_y_vec[i];
+ }
+ free(prefilled);
+ // replace scales;
+ xy->data_v = newv;
+ xy->data_i = newi;
+
_sushiv_panel_dirty_map(p);
_sushiv_panel_dirty_legend(p);
_sushiv_panel_clean_plot(p);
+ }else{
+ for(i=0;i<p->objectives;i++){
+ free(new_x_vec[i]);
+ free(new_y_vec[i]);
+ }
+ free(prefilled);
}
+
return 1;
}
-static void panel1d_undo_log(sushiv_panel_undo_t *u, sushiv_panel_t *p){
- sushiv_panel1d_t *p1 = p->subtype->p1;
+static void panelxy_undo_log(sushiv_panel_undo_t *u, sushiv_panel_t *p){
+ sushiv_panelxy_t *xy = p->subtype->xy;
+ Plot *plot = PLOT(p->private->graph);
int i;
// alloc fields as necessary
if(!u->mappings)
u->mappings = calloc(p->objectives,sizeof(*u->mappings));
if(!u->scale_vals[0])
- u->scale_vals[0] = calloc(1,sizeof(**u->scale_vals));
+ u->scale_vals[0] = calloc(3,sizeof(**u->scale_vals));
if(!u->scale_vals[1])
- u->scale_vals[1] = calloc(1,sizeof(**u->scale_vals));
+ u->scale_vals[1] = calloc(3,sizeof(**u->scale_vals));
if(!u->scale_vals[2])
u->scale_vals[2] = calloc(p->objectives,sizeof(**u->scale_vals));
// populate undo
- u->scale_vals[0][0] = slider_get_value(p1->range_slider,0);
- u->scale_vals[1][0] = slider_get_value(p1->range_slider,1);
+ u->scale_vals[0][0] = slider_get_value(xy->x_slider,0);
+ u->scale_vals[1][0] = slider_get_value(xy->x_slider,1);
+ u->scale_vals[0][1] = plot->selx;
+ u->scale_vals[1][1] = plot->sely;
+ u->scale_vals[0][2] = slider_get_value(xy->y_slider,0);
+ u->scale_vals[1][2] = slider_get_value(xy->y_slider,1);
for(i=0;i<p->objectives;i++){
u->mappings[i] =
- (p1->mappings[i].mapnum<<24) |
- (p1->linetype[i]<<16) |
- (p1->pointtype[i]<<8);
- u->scale_vals[2][i] = slider_get_value(p1->alpha_scale[i],0);
+ (xy->mappings[i].mapnum<<24) |
+ (xy->linetype[i]<<16) |
+ (xy->pointtype[i]<<8);
+ u->scale_vals[2][i] = slider_get_value(xy->alpha_scale[i],0);
}
- u->x_d = p1->x_dnum;
- u->box[0] = p1->oldbox[0];
- u->box[1] = p1->oldbox[1];
+ u->x_d = xy->x_dnum;
+ u->box[0] = xy->oldbox[0];
+ u->box[1] = xy->oldbox[1];
+ u->box[2] = xy->oldbox[2];
+ u->box[3] = xy->oldbox[3];
u->box_active = p->private->oldbox_active;
}
-static void panel1d_undo_restore(sushiv_panel_undo_t *u, sushiv_panel_t *p){
- sushiv_panel1d_t *p1 = p->subtype->p1;
+static void panelxy_undo_restore(sushiv_panel_undo_t *u, sushiv_panel_t *p){
+ sushiv_panelxy_t *xy = p->subtype->xy;
Plot *plot = PLOT(p->private->graph);
int i;
// go in through widgets
- slider_set_value(p1->range_slider,0,u->scale_vals[0][0]);
- slider_set_value(p1->range_slider,1,u->scale_vals[1][0]);
+ slider_set_value(xy->x_slider,0,u->scale_vals[0][0]);
+ slider_set_value(xy->x_slider,1,u->scale_vals[1][0]);
+ plot->selx = u->scale_vals[0][1];
+ plot->sely = u->scale_vals[1][1];
+ slider_set_value(xy->y_slider,0,u->scale_vals[0][2]);
+ slider_set_value(xy->y_slider,1,u->scale_vals[1][2]);
for(i=0;i<p->objectives;i++){
- gtk_combo_box_set_active(GTK_COMBO_BOX(p1->map_pulldowns[i]), (u->mappings[i]>>24)&0xff );
- gtk_combo_box_set_active(GTK_COMBO_BOX(p1->line_pulldowns[i]), (u->mappings[i]>>16)&0xff );
- gtk_combo_box_set_active(GTK_COMBO_BOX(p1->point_pulldowns[i]), (u->mappings[i]>>8)&0xff );
- slider_set_value(p1->alpha_scale[i],0,u->scale_vals[2][i]);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(xy->map_pulldowns[i]), (u->mappings[i]>>24)&0xff );
+ gtk_combo_box_set_active(GTK_COMBO_BOX(xy->line_pulldowns[i]), (u->mappings[i]>>16)&0xff );
+ gtk_combo_box_set_active(GTK_COMBO_BOX(xy->point_pulldowns[i]), (u->mappings[i]>>8)&0xff );
+ slider_set_value(xy->alpha_scale[i],0,u->scale_vals[2][i]);
}
- if(p1->dim_xb && u->x_d<p->dimensions && p1->dim_xb[u->x_d])
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p1->dim_xb[u->x_d]),TRUE);
+ if(xy->dim_xb && u->x_d<p->dimensions && xy->dim_xb[u->x_d])
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(xy->dim_xb[u->x_d]),TRUE);
- update_x_sel(p);
+ update_dim_sel(p);
+ crosshair_callback(p);
if(u->box_active){
- p1->oldbox[0] = u->box[0];
- p1->oldbox[1] = u->box[1];
+ xy->oldbox[0] = u->box[0];
+ xy->oldbox[1] = u->box[1];
+ xy->oldbox[2] = u->box[2];
+ xy->oldbox[3] = u->box[3];
plot_box_set(plot,u->box);
p->private->oldbox_active = 1;
}else{
@@ -1112,8 +1191,8 @@
}
}
-void _sushiv_realize_panel1d(sushiv_panel_t *p){
- sushiv_panel1d_t *p1 = p->subtype->p1;
+void _sushiv_realize_panelxy(sushiv_panel_t *p){
+ sushiv_panelxy_t *xy = p->subtype->xy;
char buffer[160];
int i;
_sushiv_undo_suspend(p->sushi);
@@ -1140,75 +1219,81 @@
/* plotbox, graph */
{
- unsigned flags = 0;
- if(p1->flip)
- flags |= PLOT_NO_X_CROSS;
- else
- flags |= PLOT_NO_Y_CROSS;
-
- p1->graph_table = gtk_table_new(2,2,0);
- p->private->plotbox = p1->graph_table;
+ xy->graph_table = gtk_table_new(3,3,0);
+ p->private->plotbox = xy->graph_table;
gtk_box_pack_start(GTK_BOX(p->private->topbox), p->private->plotbox, 1,1,2);
- p->private->graph = GTK_WIDGET(plot_new(recompute_callback_1d,p,
+ p->private->graph = GTK_WIDGET(plot_new(recompute_callback_xy,p,
(void *)(void *)crosshair_callback,p,
- box_callback,p,flags));
- if(p1->flip){
- gtk_table_attach(GTK_TABLE(p1->graph_table),p->private->graph,0,2,0,1,
- GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,0,1);
- }else{
- gtk_table_attach(GTK_TABLE(p1->graph_table),p->private->graph,1,2,0,2,
- GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,0,1);
- }
+ box_callback,p,0));
+
+ gtk_table_attach(GTK_TABLE(xy->graph_table),p->private->graph,1,3,0,2,
+ GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,0,1);
}
- /* range slider, goes in the plotbox table */
- /* may be vertical to the left of the plot or along the bottom if the plot is flipped */
+ /* X range slider */
{
GtkWidget **sl = calloc(2,sizeof(*sl));
- int lo = p1->range_scale->val_list[0];
- int hi = p1->range_scale->val_list[p1->range_scale->vals-1];
+ int lo = xy->x_scale->val_list[0];
+ int hi = xy->x_scale->val_list[xy->x_scale->vals-1];
/* the range slices/slider */
- sl[0] = slice_new(map_callback_1d,p);
- sl[1] = slice_new(map_callback_1d,p);
+ sl[0] = slice_new(map_callback_xy,p);
+ sl[1] = slice_new(map_callback_xy,p);
- if(p1->flip){
- gtk_table_attach(GTK_TABLE(p1->graph_table),sl[0],0,1,1,2,
- GTK_EXPAND|GTK_FILL,0,0,0);
- gtk_table_attach(GTK_TABLE(p1->graph_table),sl[1],1,2,1,2,
- GTK_EXPAND|GTK_FILL,0,0,0);
- }else{
- gtk_table_attach(GTK_TABLE(p1->graph_table),sl[0],0,1,1,2,
- GTK_SHRINK,GTK_EXPAND|GTK_FILL,0,0);
- gtk_table_attach(GTK_TABLE(p1->graph_table),sl[1],0,1,0,1,
- GTK_SHRINK,GTK_EXPAND|GTK_FILL,0,0);
- gtk_table_set_col_spacing(GTK_TABLE(p1->graph_table),0,4);
- }
+ gtk_table_attach(GTK_TABLE(xy->graph_table),sl[0],1,2,2,3,
+ GTK_EXPAND|GTK_FILL,0,0,0);
+ gtk_table_attach(GTK_TABLE(xy->graph_table),sl[1],2,3,2,3,
+ GTK_EXPAND|GTK_FILL,0,0,0);
- p1->range_slider = slider_new((Slice **)sl,2,
- p1->range_scale->label_list,
- p1->range_scale->val_list,
- p1->range_scale->vals,
- (p1->flip?0:SLIDER_FLAG_VERTICAL));
+ xy->x_slider = slider_new((Slice **)sl,2,
+ xy->x_scale->label_list,
+ xy->x_scale->val_list,
+ xy->x_scale->vals,0);
+
+ slice_thumb_set((Slice *)sl[0],lo);
+ slice_thumb_set((Slice *)sl[1],hi);
+ }
+ /* Y range slider */
+ {
+ GtkWidget **sl = calloc(2,sizeof(*sl));
+ int lo = xy->y_scale->val_list[0];
+ int hi = xy->y_scale->val_list[xy->y_scale->vals-1];
+
+ /* the range slices/slider */
+ sl[0] = slice_new(map_callback_xy,p);
+ sl[1] = slice_new(map_callback_xy,p);
+
+ gtk_table_attach(GTK_TABLE(xy->graph_table),sl[0],0,1,1,2,
+ GTK_SHRINK,GTK_EXPAND|GTK_FILL,0,0);
+ gtk_table_attach(GTK_TABLE(xy->graph_table),sl[1],0,1,0,1,
+ GTK_SHRINK,GTK_EXPAND|GTK_FILL,0,0);
+ gtk_table_set_col_spacing(GTK_TABLE(xy->graph_table),0,4);
+
+ xy->y_slider = slider_new((Slice **)sl,2,
+ xy->y_scale->label_list,
+ xy->y_scale->val_list,
+ xy->y_scale->vals,
+ SLIDER_FLAG_VERTICAL);
+
slice_thumb_set((Slice *)sl[0],lo);
slice_thumb_set((Slice *)sl[1],hi);
}
/* obj box */
{
- p1->obj_table = gtk_table_new(p->objectives,5,0);
- gtk_box_pack_start(GTK_BOX(p->private->topbox), p1->obj_table, 0,0,1);
+ xy->obj_table = gtk_table_new(p->objectives,5,0);
+ gtk_box_pack_start(GTK_BOX(p->private->topbox), xy->obj_table, 0,0,1);
/* pulldowns */
- p1->pointtype = calloc(p->objectives,sizeof(*p1->pointtype));
- p1->linetype = calloc(p->objectives,sizeof(*p1->linetype));
- p1->mappings = calloc(p->objectives,sizeof(*p1->mappings));
- p1->map_pulldowns = calloc(p->objectives,sizeof(*p1->map_pulldowns));
- p1->line_pulldowns = calloc(p->objectives,sizeof(*p1->line_pulldowns));
- p1->point_pulldowns = calloc(p->objectives,sizeof(*p1->point_pulldowns));
- p1->alpha_scale = calloc(p->objectives,sizeof(*p1->alpha_scale));
+ xy->pointtype = calloc(p->objectives,sizeof(*xy->pointtype));
+ xy->linetype = calloc(p->objectives,sizeof(*xy->linetype));
+ xy->mappings = calloc(p->objectives,sizeof(*xy->mappings));
+ xy->map_pulldowns = calloc(p->objectives,sizeof(*xy->map_pulldowns));
+ xy->line_pulldowns = calloc(p->objectives,sizeof(*xy->line_pulldowns));
+ xy->point_pulldowns = calloc(p->objectives,sizeof(*xy->point_pulldowns));
+ xy->alpha_scale = calloc(p->objectives,sizeof(*xy->alpha_scale));
for(i=0;i<p->objectives;i++){
sushiv_objective_t *o = p->objective_list[i].o;
@@ -1216,7 +1301,7 @@
/* label */
GtkWidget *label = gtk_label_new(o->name);
gtk_misc_set_alignment(GTK_MISC(label),1.,.5);
- gtk_table_attach(GTK_TABLE(p1->obj_table),label,0,1,i,i+1,
+ gtk_table_attach(GTK_TABLE(xy->obj_table),label,0,1,i,i+1,
GTK_FILL,0,5,0);
/* mapping pulldown */
@@ -1233,11 +1318,11 @@
}
gtk_combo_box_set_active(GTK_COMBO_BOX(menu),0);
g_signal_connect (G_OBJECT (menu), "changed",
- G_CALLBACK (mapchange_callback_1d), p->objective_list+i);
- gtk_table_attach(GTK_TABLE(p1->obj_table),menu,1,2,i,i+1,
+ G_CALLBACK (mapchange_callback_xy), p->objective_list+i);
+ gtk_table_attach(GTK_TABLE(xy->obj_table),menu,1,2,i,i+1,
GTK_SHRINK,GTK_SHRINK,5,0);
- p1->map_pulldowns[i] = menu;
- solid_setup(&p1->mappings[i],0.,1.,0);
+ xy->map_pulldowns[i] = menu;
+ solid_setup(&xy->mappings[i],0.,1.,0);
}
/* line pulldown */
@@ -1248,10 +1333,10 @@
gtk_combo_box_append_text (GTK_COMBO_BOX (menu), line_name[j]->left);
gtk_combo_box_set_active(GTK_COMBO_BOX(menu),0);
g_signal_connect (G_OBJECT (menu), "changed",
- G_CALLBACK (linetype_callback_1d), p->objective_list+i);
- gtk_table_attach(GTK_TABLE(p1->obj_table),menu,2,3,i,i+1,
+ G_CALLBACK (linetype_callback_xy), p->objective_list+i);
+ gtk_table_attach(GTK_TABLE(xy->obj_table),menu,2,3,i,i+1,
GTK_SHRINK,GTK_SHRINK,5,0);
- p1->line_pulldowns[i] = menu;
+ xy->line_pulldowns[i] = menu;
}
/* point pulldown */
@@ -1262,26 +1347,26 @@
gtk_combo_box_append_text (GTK_COMBO_BOX (menu), point_name[j]->left);
gtk_combo_box_set_active(GTK_COMBO_BOX(menu),0);
g_signal_connect (G_OBJECT (menu), "changed",
- G_CALLBACK (pointtype_callback_1d), p->objective_list+i);
- gtk_table_attach(GTK_TABLE(p1->obj_table),menu,3,4,i,i+1,
+ G_CALLBACK (pointtype_callback_xy), p->objective_list+i);
+ gtk_table_attach(GTK_TABLE(xy->obj_table),menu,3,4,i,i+1,
GTK_SHRINK,GTK_SHRINK,5,0);
- p1->point_pulldowns[i] = menu;
+ xy->point_pulldowns[i] = menu;
}
/* alpha slider */
{
GtkWidget **sl = calloc(1, sizeof(*sl));
- sl[0] = slice_new(alpha_callback_1d,p->objective_list+i);
+ sl[0] = slice_new(alpha_callback_xy,p->objective_list+i);
- gtk_table_attach(GTK_TABLE(p1->obj_table),sl[0],4,5,i,i+1,
+ gtk_table_attach(GTK_TABLE(xy->obj_table),sl[0],4,5,i,i+1,
GTK_EXPAND|GTK_FILL,0,0,0);
- p1->alpha_scale[i] = slider_new((Slice **)sl,1,
+ xy->alpha_scale[i] = slider_new((Slice **)sl,1,
(char *[]){"transparent","solid"},
(double []){0.,1.},
2,0);
- slider_set_gradient(p1->alpha_scale[i], &p1->mappings[i]);
+ slider_set_gradient(xy->alpha_scale[i], &xy->mappings[i]);
slice_thumb_set((Slice *)sl[0],1.);
}
@@ -1290,11 +1375,11 @@
/* dim box */
if(p->dimensions){
- p1->dim_table = gtk_table_new(p->dimensions,3,0);
- gtk_box_pack_start(GTK_BOX(p->private->topbox), p1->dim_table, 0,0,4);
+ xy->dim_table = gtk_table_new(p->dimensions,3,0);
+ gtk_box_pack_start(GTK_BOX(p->private->topbox), xy->dim_table, 0,0,4);
p->private->dim_scales = calloc(p->dimensions,sizeof(*p->private->dim_scales));
- p1->dim_xb = calloc(p->dimensions,sizeof(*p1->dim_xb));
+ xy->dim_xb = calloc(p->dimensions,sizeof(*xy->dim_xb));
GtkWidget *first_x = NULL;
for(i=0;i<p->dimensions;i++){
@@ -1303,25 +1388,25 @@
/* label */
GtkWidget *label = gtk_label_new(d->name);
gtk_misc_set_alignment(GTK_MISC(label),1.,.5);
- gtk_table_attach(GTK_TABLE(p1->dim_table),label,0,1,i,i+1,
+ gtk_table_attach(GTK_TABLE(xy->dim_table),label,0,1,i,i+1,
GTK_FILL,0,5,0);
/* x radio buttons */
- if(!(d->flags & SUSHIV_DIM_NO_X) && !p1->link_x && !p1->link_y){
+ if(!(d->flags & SUSHIV_DIM_NO_X)){
if(first_x)
- p1->dim_xb[i] = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(first_x),"X");
+ xy->dim_xb[i] = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(first_x),"X");
else{
- first_x = p1->dim_xb[i] = gtk_radio_button_new_with_label(NULL,"X");
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p1->dim_xb[i]),TRUE);
+ first_x = xy->dim_xb[i] = gtk_radio_button_new_with_label(NULL,"X");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(xy->dim_xb[i]),TRUE);
}
- gtk_table_attach(GTK_TABLE(p1->dim_table),p1->dim_xb[i],1,2,i,i+1,
+ gtk_table_attach(GTK_TABLE(xy->dim_table),xy->dim_xb[i],1,2,i,i+1,
0,0,3,0);
}
p->private->dim_scales[i] =
- _sushiv_new_dimension_widget(p->dimension_list+i,center_callback_1d,bracket_callback_1d);
+ _sushiv_new_dimension_widget(p->dimension_list+i,center_callback_xy,bracket_callback_xy);
- gtk_table_attach(GTK_TABLE(p1->dim_table),
+ gtk_table_attach(GTK_TABLE(xy->dim_table),
GTK_WIDGET(p->private->dim_scales[i]->t),
2,3,i,i+1,
GTK_EXPAND|GTK_FILL,0,0,0);
@@ -1329,11 +1414,11 @@
}
for(i=0;i<p->dimensions;i++)
- if(p1->dim_xb[i])
- g_signal_connect (G_OBJECT (p1->dim_xb[i]), "toggled",
- G_CALLBACK (dimchange_callback_1d), p);
+ if(xy->dim_xb[i])
+ g_signal_connect (G_OBJECT (xy->dim_xb[i]), "toggled",
+ G_CALLBACK (dimchange_callback_xy), p);
- update_x_sel(p);
+ update_dim_sel(p);
}
gtk_widget_realize(p->private->toplevel);
@@ -1345,19 +1430,22 @@
}
-static int _save_panel1d(sushiv_panel_t *p, xmlNodePtr pn){
- sushiv_panel1d_t *p1 = p->subtype->p1;
+static int _save_panelxy(sushiv_panel_t *p, xmlNodePtr pn){
+ sushiv_panelxy_t *xy = p->subtype->xy;
+ Plot *plot = PLOT(p->private->graph);
int ret=0,i;
xmlNodePtr n;
- xmlNewProp(pn, (xmlChar *)"type", (xmlChar *)"1d");
+ xmlNewProp(pn, (xmlChar *)"type", (xmlChar *)"xy");
// box
if(p->private->oldbox_active){
xmlNodePtr boxn = xmlNewChild(pn, NULL, (xmlChar *) "box", NULL);
- xmlNewPropF(boxn, "x1", p1->oldbox[0]);
- xmlNewPropF(boxn, "x2", p1->oldbox[1]);
+ xmlNewPropF(boxn, "x1", xy->oldbox[0]);
+ xmlNewPropF(boxn, "x2", xy->oldbox[1]);
+ xmlNewPropF(boxn, "y1", xy->oldbox[2]);
+ xmlNewPropF(boxn, "y2", xy->oldbox[3]);
}
// objective map settings
@@ -1373,37 +1461,43 @@
// right now Y is the only type; the below is Y-specific
n = xmlNewChild(on, NULL, (xmlChar *) "y-map", NULL);
- xmlNewMapProp(n, "color", solid_map(), p1->mappings[i].mapnum);
- xmlNewMapProp(n, "line", line_name, p1->linetype[i]);
- xmlNewMapProp(n, "point", point_name, p1->pointtype[i]);
- xmlNewPropF(n, "alpha", slider_get_value(p1->alpha_scale[i],0));
+ xmlNewMapProp(n, "color", solid_map(), xy->mappings[i].mapnum);
+ xmlNewMapProp(n, "line", line_name, xy->linetype[i]);
+ xmlNewMapProp(n, "point", point_name, xy->pointtype[i]);
+ xmlNewPropF(n, "alpha", slider_get_value(xy->alpha_scale[i],0));
}
- // y scale
+ // x/y scale
n = xmlNewChild(pn, NULL, (xmlChar *) "range", NULL);
- xmlNewPropF(n, "low-bracket", slider_get_value(p1->range_slider,0));
- xmlNewPropF(n, "high-bracket", slider_get_value(p1->range_slider,1));
+ xmlNewPropF(n, "x-low-bracket", slider_get_value(xy->x_slider,0));
+ xmlNewPropF(n, "x-high-bracket", slider_get_value(xy->x_slider,1));
+ xmlNewPropF(n, "y-low-bracket", slider_get_value(xy->y_slider,0));
+ xmlNewPropF(n, "y-high-bracket", slider_get_value(xy->y_slider,1));
+ xmlNewPropF(n, "x-cross", plot->selx);
+ xmlNewPropF(n, "y-cross", plot->sely);
// x/y dim selection
n = xmlNewChild(pn, NULL, (xmlChar *) "axes", NULL);
- xmlNewPropI(n, "xpos", p1->x_dnum);
+ xmlNewPropI(n, "xpos", xy->x_dnum);
return ret;
}
-int _load_panel1d(sushiv_panel_t *p,
+int _load_panelxy(sushiv_panel_t *p,
sushiv_panel_undo_t *u,
xmlNodePtr pn,
int warn){
int i;
// check type
- xmlCheckPropS(pn,"type","1d", "Panel %d type mismatch in save file.",p->number,&warn);
+ xmlCheckPropS(pn,"type","xy", "Panel %d type mismatch in save file.",p->number,&warn);
// box
u->box_active = 0;
xmlGetChildPropFPreserve(pn, "box", "x1", &u->box[0]);
xmlGetChildPropFPreserve(pn, "box", "x2", &u->box[1]);
+ xmlGetChildPropFPreserve(pn, "box", "y1", &u->box[2]);
+ xmlGetChildPropFPreserve(pn, "box", "y2", &u->box[3]);
xmlNodePtr n = xmlGetChildS(pn, "box", NULL, NULL);
if(n){
@@ -1443,9 +1537,12 @@
}
}
- // y scale
- xmlGetChildPropFPreserve(pn, "range", "low-bracket", &u->scale_vals[0][0]);
- xmlGetChildPropF(pn, "range", "high-bracket", &u->scale_vals[1][0]);
+ xmlGetChildPropFPreserve(pn, "range", "x-low-bracket", &u->scale_vals[0][0]);
+ xmlGetChildPropFPreserve(pn, "range", "x-high-bracket", &u->scale_vals[1][0]);
+ xmlGetChildPropFPreserve(pn, "range", "y-low-bracket", &u->scale_vals[0][2]);
+ xmlGetChildPropFPreserve(pn, "range", "y-high-bracket", &u->scale_vals[1][2]);
+ xmlGetChildPropFPreserve(pn, "range", "x-cross", &u->scale_vals[0][1]);
+ xmlGetChildPropF(pn, "range", "y-cross", &u->scale_vals[1][1]);
// x/y dim selection
xmlGetChildPropI(pn, "axes", "xpos", &u->x_d);
@@ -1453,79 +1550,45 @@
return warn;
}
-int sushiv_new_panel_1d(sushiv_instance_t *s,
+int sushiv_new_panel_xy(sushiv_instance_t *s,
int number,
const char *name,
- sushiv_scale_t *scale,
+ sushiv_scale_t *xscale,
+ sushiv_scale_t *yscale,
int *objectives,
int *dimensions,
unsigned flags){
int ret = _sushiv_new_panel(s,number,name,objectives,dimensions,flags);
sushiv_panel_t *p;
- sushiv_panel1d_t *p1;
+ sushiv_panelxy_t *xy;
if(ret<0)return ret;
p = s->panel_list[number];
- p1 = calloc(1, sizeof(*p1));
+ xy = calloc(1, sizeof(*xy));
p->subtype = calloc(1, sizeof(*p->subtype));
- p->subtype->p1 = p1;
- p->type = SUSHIV_PANEL_1D;
- p1->range_scale = scale;
+ p->subtype->xy = xy;
+ p->type = SUSHIV_PANEL_XY;
+ xy->x_scale = xscale;
+ xy->y_scale = yscale;
p->private->bg_type = SUSHIV_BG_WHITE;
- if(p->flags && SUSHIV_PANEL_FLIP)
- p1->flip=1;
-
- p->private->realize = _sushiv_realize_panel1d;
- p->private->map_action = _sushiv_panel1d_map_redraw;
- p->private->legend_action = _sushiv_panel1d_legend_redraw;
- p->private->compute_action = _sushiv_panel1d_compute;
- p->private->request_compute = _mark_recompute_1d;
+ p->private->realize = _sushiv_realize_panelxy;
+ p->private->map_action = _sushiv_panelxy_map_redraw;
+ p->private->legend_action = _sushiv_panelxy_legend_redraw;
+ p->private->compute_action = _sushiv_panelxy_compute;
+ p->private->request_compute = _mark_recompute_xy;
p->private->crosshair_action = crosshair_callback;
- p->private->print_action = sushiv_panel1d_print;
- p->private->save_action = _save_panel1d;
- p->private->load_action = _load_panel1d;
+ p->private->print_action = sushiv_panelxy_print;
+ p->private->save_action = _save_panelxy;
+ p->private->load_action = _load_panelxy;
- p->private->undo_log = panel1d_undo_log;
- p->private->undo_restore = panel1d_undo_restore;
+ p->private->undo_log = panelxy_undo_log;
+ p->private->undo_restore = panelxy_undo_restore;
p->private->def_oversample_n = p->private->oversample_n = 1;
p->private->def_oversample_d = p->private->oversample_d = 8;
return 0;
}
-int sushiv_new_panel_1d_linked(sushiv_instance_t *s,
- int number,
- const char *name,
- sushiv_scale_t *scale,
- int *objectives,
- int link,
- unsigned flags){
-
- if(link < 0 ||
- link >= s->panels ||
- s->panel_list[link]==NULL ||
- s->panel_list[link]->type != SUSHIV_PANEL_2D){
- fprintf(stderr,"1d linked panel must be linked to preexisting 2d panel.\n");
- return -EINVAL;
- }
-
- int ret = sushiv_new_panel_1d(s,number,name,scale,objectives,(int []){-1},flags);
-
- sushiv_panel_t *p;
- sushiv_panel1d_t *p1;
- sushiv_panel_t *p2 = s->panel_list[link];
-
- if(ret<0)return ret;
- p = s->panel_list[number];
- p1 = p->subtype->p1;
-
- if(flags && SUSHIV_PANEL_LINK_Y)
- p1->link_y = p2;
- else
- p1->link_x = p2;
-
- return 0;
-}
Modified: trunk/sushivision/panel-xy.h
===================================================================
--- trunk/sushivision/panel-xy.h 2007-03-18 14:46:07 UTC (rev 12776)
+++ trunk/sushivision/panel-xy.h 2007-03-19 08:33:06 UTC (rev 12777)
@@ -31,20 +31,20 @@
scalespace x;
scalespace y;
double oldbox[4];
- sushiv_scale_t x_scale;
- sushiv_scale_t y_scale;
- Slider x_slider;
- Slider y_slider;
+ sushiv_scale_t *x_scale;
+ sushiv_scale_t *y_scale;
+ Slider *x_slider;
+ Slider *y_slider;
double x_bracket[2];
double y_bracket[2];
- double x_val;
- double y_val;
+ int cross_objnum;
scalespace data_v; // the x scale aligned to data vector's bins
scalespace data_i; // the 'counting' scale used to iterate for compute
double **x_vec;
double **y_vec;
- double scale_metric;
+ int curr_zoom;
+ int prev_zoom;
mapping *mappings;
int *linetype;
More information about the commits
mailing list