3 * sushivision copyright (C) 2006-2007 Monty <monty@xiph.org>
5 * sushivision is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * sushivision is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with sushivision; see the file COPYING. If not, write to the
17 * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
30 #include <sys/types.h>
36 static _sv_propmap_t
*line_name
[LINETYPES
+1] = {
37 &(_sv_propmap_t
){"line", 0, NULL
,NULL
,NULL
},
38 &(_sv_propmap_t
){"fat line", 1, NULL
,NULL
,NULL
},
39 &(_sv_propmap_t
){"fill above", 2, NULL
,NULL
,NULL
},
40 &(_sv_propmap_t
){"fill below", 3, NULL
,NULL
,NULL
},
41 &(_sv_propmap_t
){"fill to zero", 4, NULL
,NULL
,NULL
},
42 &(_sv_propmap_t
){"no line", 5, NULL
,NULL
,NULL
},
47 static _sv_propmap_t
*point_name
[POINTTYPES
+1] = {
48 &(_sv_propmap_t
){"dot", 0, NULL
,NULL
,NULL
},
49 &(_sv_propmap_t
){"cross", 1, NULL
,NULL
,NULL
},
50 &(_sv_propmap_t
){"plus", 2, NULL
,NULL
,NULL
},
51 &(_sv_propmap_t
){"open circle", 3, NULL
,NULL
,NULL
},
52 &(_sv_propmap_t
){"open square", 4, NULL
,NULL
,NULL
},
53 &(_sv_propmap_t
){"open triangle", 5, NULL
,NULL
,NULL
},
54 &(_sv_propmap_t
){"solid circle", 6, NULL
,NULL
,NULL
},
55 &(_sv_propmap_t
){"solid square", 7, NULL
,NULL
,NULL
},
56 &(_sv_propmap_t
){"solid triangle", 8, NULL
,NULL
,NULL
},
60 static void render_checks(cairo_t
*c
, int w
, int h
){
61 /* default checked background */
62 /* 16x16 'mid-checks' */
65 cairo_set_source_rgb (c
, .5,.5,.5);
67 cairo_set_source_rgb (c
, .314,.314,.314);
73 cairo_rectangle(c
,x
,y
,16.,16.);
81 // called internally, assumes we hold lock
82 // redraws the data, does not compute the data
83 static int _sv_panel1d_remap(sv_panel_t
*p
, cairo_t
*c
){
84 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
85 _sv_plot_t
*plot
= PLOT(p
->private->graph
);
87 int plot_serialno
= p
->private->plot_serialno
;
88 int map_serialno
= p
->private->map_serialno
;
90 int pw
= plot
->x
.pixels
;
91 int ph
= plot
->y
.pixels
;
92 int dw
= p1
->data_size
;
93 double r
= (p1
->flip
?p1
->panel_w
:p1
->panel_h
);
95 _sv_scalespace_t rx
= (p1
->flip
?p1
->y
:p1
->x
);
96 _sv_scalespace_t ry
= (p1
->flip
?p1
->x
:p1
->y
);
97 _sv_scalespace_t sx
= p1
->x
;
98 _sv_scalespace_t sy
= p1
->y
;
99 _sv_scalespace_t sx_v
= p1
->x_v
;
100 _sv_scalespace_t px
= plot
->x
;
101 _sv_scalespace_t py
= plot
->y
;
103 /* do the panel and plot scales match? If not, redraw the plot
106 if(memcmp(&rx
,&px
,sizeof(rx
)) ||
107 memcmp(&ry
,&py
,sizeof(ry
))){
113 _sv_plot_draw_scales(plot
);
117 /* blank frame to selected bg */
118 switch(p
->private->bg_type
){
120 cairo_set_source_rgb (c
, 1.,1.,1.);
124 cairo_set_source_rgb (c
, 0,0,0);
128 render_checks(c
,pw
,ph
);
133 if(plot_serialno
!= p
->private->plot_serialno
||
134 map_serialno
!= p
->private->map_serialno
) return -1;
139 for(j
=0;j
<p
->objectives
;j
++){
140 if(p1
->data_vec
[j
] && !_sv_mapping_inactive_p(p1
->mappings
+j
)){
142 double alpha
= _sv_slider_get_value(p1
->alpha_scale
[j
],0);
143 int linetype
= p1
->linetype
[j
];
144 int pointtype
= p1
->pointtype
[j
];
145 u_int32_t color
= _sv_mapping_calc(p1
->mappings
+j
,1.,0);
147 double *xv
= calloc(dw
,sizeof(*xv
));
148 double *yv
= calloc(dw
,sizeof(*yv
));
149 double *data_vec
= calloc(dw
,sizeof(*data_vec
));
151 memcpy(data_vec
,p1
->data_vec
[j
],sizeof(*data_vec
)*dw
);
155 for(xi
=0;xi
<dw
;xi
++){
156 double val
= data_vec
[xi
];
160 /* map data vector bin to x pixel location in the plot */
161 xpixel
= _sv_scalespace_pixel(&sx
,_sv_scalespace_value(&sx_v
,xpixel
))+.5;
163 /* map/render result */
165 ypixel
= _sv_scalespace_pixel(&sy
,val
)+.5;
171 /* draw areas, if any */
172 if(linetype
>1 && linetype
< 5){
174 if(linetype
== 2) /* fill above */
176 if(linetype
== 3) /* fill below */
177 yA
= (p1
->flip
?-1:r
);
178 if(linetype
== 4) /* fill to zero */
179 yA
= _sv_scalespace_pixel(&sy
,0.)+.5;
181 cairo_set_source_rgba(c
,
182 ((color
>>16)&0xff)/255.,
183 ((color
>>8)&0xff)/255.,
189 cairo_move_to(c
,yA
,xv
[0]+.5);
190 cairo_line_to(c
,yv
[0],xv
[0]+.5);
192 cairo_move_to(c
,xv
[0]-.5,yA
);
193 cairo_line_to(c
,xv
[0]-.5,yv
[0]);
201 /* close off the area */
203 cairo_line_to(c
,yv
[i
-1],xv
[i
-1]-.5);
204 cairo_line_to(c
,yA
,xv
[i
-1]-.5);
206 cairo_line_to(c
,xv
[i
-1]+.5,yv
[i
-1]);
207 cairo_line_to(c
,xv
[i
-1]+.5,yA
);
214 cairo_move_to(c
,yA
,xv
[i
]+.5);
215 cairo_line_to(c
,yv
[i
],xv
[i
]+.5);
217 cairo_move_to(c
,xv
[i
]-.5,yA
);
218 cairo_line_to(c
,xv
[i
]-.5,yv
[i
]);
222 cairo_line_to(c
,yv
[i
],xv
[i
]);
224 cairo_line_to(c
,xv
[i
],yv
[i
]);
231 /* close off the area */
233 cairo_line_to(c
,yv
[i
-1],xv
[i
-1]-.5);
234 cairo_line_to(c
,yA
,xv
[i
-1]-.5);
236 cairo_line_to(c
,xv
[i
-1]+.5,yv
[i
-1]);
237 cairo_line_to(c
,xv
[i
-1]+.5,yA
);
245 /* now draw the lines */
247 cairo_set_source_rgba(c
,
248 ((color
>>16)&0xff)/255.,
249 ((color
>>8)&0xff)/255.,
253 cairo_set_line_width(c
,2.);
255 cairo_set_line_width(c
,1.);
259 if(!isnan(yv
[i
-1]) && !isnan(yv
[i
])){
262 cairo_move_to(c
,yv
[i
-1],xv
[i
-1]);
263 cairo_line_to(c
,yv
[i
],xv
[i
]);
265 cairo_move_to(c
,xv
[i
-1],yv
[i
-1]);
266 cairo_line_to(c
,xv
[i
],yv
[i
]);
273 /* now draw the points */
274 if(pointtype
> 0 || linetype
== 5){
275 cairo_set_line_width(c
,1.);
288 cairo_set_source_rgba(c
,
289 ((color
>>16)&0xff)/255.,
290 ((color
>>8)&0xff)/255.,
295 case 0: /* pixeldots */
296 cairo_rectangle(c
, xx
-.5,yy
-.5,1,1);
300 cairo_move_to(c
,xx
-4,yy
-4);
301 cairo_line_to(c
,xx
+4,yy
+4);
302 cairo_move_to(c
,xx
+4,yy
-4);
303 cairo_line_to(c
,xx
-4,yy
+4);
306 cairo_move_to(c
,xx
-4,yy
);
307 cairo_line_to(c
,xx
+4,yy
);
308 cairo_move_to(c
,xx
,yy
-4);
309 cairo_line_to(c
,xx
,yy
+4);
311 case 3: case 6: /* circle */
312 cairo_arc(c
,xx
,yy
,4,0,2.*M_PI
);
314 case 4: case 7: /* square */
315 cairo_rectangle(c
,xx
-4,yy
-4,8,8);
317 case 5: case 8: /* triangle */
318 cairo_move_to(c
,xx
,yy
-5);
319 cairo_line_to(c
,xx
-4,yy
+3);
320 cairo_line_to(c
,xx
+4,yy
+3);
326 cairo_fill_preserve(c
);
330 if(p
->private->bg_type
== SV_BG_WHITE
)
331 cairo_set_source_rgba(c
,0.,0.,0.,alpha
);
333 cairo_set_source_rgba(c
,1.,1.,1.,alpha
);
345 if(plot_serialno
!= p
->private->plot_serialno
||
346 map_serialno
!= p
->private->map_serialno
) return -1;
356 static void _sv_panel1d_print(sv_panel_t
*p
, cairo_t
*c
, int w
, int h
){
357 _sv_plot_t
*plot
= PLOT(p
->private->graph
);
358 double pw
= p
->private->graph
->allocation
.width
;
359 double ph
= p
->private->graph
->allocation
.height
;
368 cairo_get_matrix(c
,&m
);
369 cairo_matrix_scale(&m
,scale
,scale
);
370 cairo_set_matrix(c
,&m
);
372 _sv_plot_print(plot
, c
, ph
*scale
, (void(*)(void *, cairo_t
*))_sv_panel1d_remap
, p
);
375 static void _sv_panel1d_update_legend(sv_panel_t
*p
){
376 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
377 _sv_plot_t
*plot
= PLOT(p
->private->graph
);
379 gdk_threads_enter ();
384 _sv_plot_legend_clear(plot
);
386 if(3-_sv_scalespace_decimal_exponent(&p1
->x_v
) > depth
)
387 depth
= 3-_sv_scalespace_decimal_exponent(&p1
->x_v
);
389 // add each dimension to the legend
390 for(i
=0;i
<p
->dimensions
;i
++){
391 sv_dim_t
*d
= p
->dimension_list
[i
].d
;
392 // display decimal precision relative to bracket
393 //int depth = del_depth(p->dimension_list[i].d->bracket[0],
394 // p->dimension_list[i].d->bracket[1]) + offset;
395 if( d
!=p
->private->x_d
||
398 snprintf(buffer
,320,"%s = %+.*f",
399 p
->dimension_list
[i
].d
->name
,
401 p
->dimension_list
[i
].d
->val
);
402 _sv_plot_legend_add(plot
,buffer
);
407 _sv_plot_legend_add(plot
,NULL
);
409 // add each active objective to the legend
410 // choose the value under the crosshairs
411 if(plot
->cross_active
){
412 double val
= (p1
->flip
?plot
->sely
:plot
->selx
);
413 int bin
= rint(_sv_scalespace_pixel(&p1
->x_v
, val
));
415 for(i
=0;i
<p
->objectives
;i
++){
416 if(!_sv_mapping_inactive_p(p1
->mappings
+i
)){
417 u_int32_t color
= _sv_mapping_calc(p1
->mappings
+i
,1.,0);
419 snprintf(buffer
,320,"%s",
420 p
->objective_list
[i
].o
->name
);
422 if(bin
>=0 && bin
<p1
->data_size
){
424 float val
= p1
->data_vec
[i
][bin
];
427 snprintf(buffer
,320,"%s = %f",
428 p
->objective_list
[i
].o
->name
,
433 _sv_plot_legend_add_with_color(plot
,buffer
,color
| 0xff000000);
437 gdk_threads_leave ();
441 static void _sv_panel1d_mapchange_callback(GtkWidget
*w
,gpointer in
){
442 sv_obj_list_t
*optr
= (sv_obj_list_t
*)in
;
443 sv_panel_t
*p
= optr
->p
;
444 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
445 int onum
= optr
- p
->objective_list
;
452 _sv_solid_set_func(&p1
->mappings
[onum
],
453 gtk_combo_box_get_active(GTK_COMBO_BOX(w
)));
454 _sv_slider_set_gradient(p1
->alpha_scale
[onum
], &p1
->mappings
[onum
]);
456 _sv_panel_dirty_map(p
);
457 _sv_panel_dirty_legend(p
);
461 static void _sv_panel1d_alpha_callback(void * in
, int buttonstate
){
462 sv_obj_list_t
*optr
= (sv_obj_list_t
*)in
;
463 sv_panel_t
*p
= optr
->p
;
464 // _sv_panel1d_t *p1 = p->subtype->p1;
465 // int onum = optr - p->objective_list;
467 if(buttonstate
== 0){
472 _sv_panel_dirty_map(p
);
473 _sv_panel_dirty_legend(p
);
479 static void _sv_panel1d_linetype_callback(GtkWidget
*w
,gpointer in
){
480 sv_obj_list_t
*optr
= (sv_obj_list_t
*)in
;
481 sv_panel_t
*p
= optr
->p
;
482 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
483 int onum
= optr
- p
->objective_list
;
489 int pos
= gtk_combo_box_get_active(GTK_COMBO_BOX(w
));
490 p1
->linetype
[onum
] = line_name
[pos
]->value
;
492 _sv_panel_dirty_map(p
);
496 static void _sv_panel1d_pointtype_callback(GtkWidget
*w
,gpointer in
){
497 sv_obj_list_t
*optr
= (sv_obj_list_t
*)in
;
498 sv_panel_t
*p
= optr
->p
;
499 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
500 int onum
= optr
- p
->objective_list
;
506 int pos
= gtk_combo_box_get_active(GTK_COMBO_BOX(w
));
507 p1
->pointtype
[onum
] = point_name
[pos
]->value
;
509 _sv_panel_dirty_map(p
);
513 static void _sv_panel1d_map_callback(void *in
,int buttonstate
){
514 sv_panel_t
*p
= (sv_panel_t
*)in
;
515 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
516 _sv_plot_t
*plot
= PLOT(p
->private->graph
);
518 if(buttonstate
== 0){
523 // has new bracketing changed the plot range scale?
524 if(p1
->range_bracket
[0] != _sv_slider_get_value(p1
->range_slider
,0) ||
525 p1
->range_bracket
[1] != _sv_slider_get_value(p1
->range_slider
,1)){
527 int w
= plot
->w
.allocation
.width
;
528 int h
= plot
->w
.allocation
.height
;
530 p1
->range_bracket
[0] = _sv_slider_get_value(p1
->range_slider
,0);
531 p1
->range_bracket
[1] = _sv_slider_get_value(p1
->range_slider
,1);
534 p1
->y
= _sv_scalespace_linear(p1
->range_bracket
[0],
535 p1
->range_bracket
[1],
538 p1
->range_scale
->legend
);
541 p1
->y
= _sv_scalespace_linear(p1
->range_bracket
[1],
542 p1
->range_bracket
[0],
545 p1
->range_scale
->legend
);
550 _sv_panel_dirty_map(p
);
555 static void _sv_panel1d_update_xsel(sv_panel_t
*p
){
556 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
559 // enable/disable dimension slider thumbs
560 // enable/disable objective 'point' dropdowns
561 for(i
=0;i
<p
->dimensions
;i
++){
564 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p1
->dim_xb
[i
]))){
566 // set the x dim flag
567 p
->private->x_d
= p
->dimension_list
[i
].d
;
568 p1
->x_scale
= p
->private->dim_scales
[i
];
572 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p1
->dim_xb
[i
]))){
573 // make all thumbs visible
574 _sv_dim_widget_set_thumb_active(p
->private->dim_scales
[i
],0,1);
575 _sv_dim_widget_set_thumb_active(p
->private->dim_scales
[i
],2,1);
577 // make bracket thumbs invisible */
578 _sv_dim_widget_set_thumb_active(p
->private->dim_scales
[i
],0,0);
579 _sv_dim_widget_set_thumb_active(p
->private->dim_scales
[i
],2,0);
584 static void _sv_panel1d_compute_line(sv_panel_t
*p
,
587 _sv_scalespace_t sxi
,
590 _sv_bythread_cache_1d_t
*c
){
591 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
593 int i
,j
,fn
=_sv_functions
;
598 sv_func_t
*f
= _sv_function_list
[i
];
599 int step
= f
->outputs
;
600 double *fout
= c
->fout
[i
];
604 dim_vals
[x_d
] = _sv_scalespace_value(&sxi
,j
);
605 c
->call
[i
](dim_vals
,fout
);
611 /* process function output by objective */
612 /* 1d panels currently only care about the Y output value; in the
613 future, Z may also be relevant */
614 for(i
=0;i
<p
->objectives
;i
++){
615 sv_obj_t
*o
= p
->objective_list
[i
].o
;
616 int offset
= o
->private->y_fout
;
617 sv_func_t
*f
= o
->private->y_func
;
619 int step
= f
->outputs
;
620 double *fout
= c
->fout
[f
->number
]+offset
;
622 /* map result from function output to objective output */
628 gdk_threads_enter (); // misuse me as a global mutex
629 if(p
->private->plot_serialno
== serialno
){
630 /* store result in panel */
631 memcpy(p1
->data_vec
[i
],work
,w
*sizeof(*work
));
632 gdk_threads_leave (); // misuse me as a global mutex
634 gdk_threads_leave (); // misuse me as a global mutex
641 // subtype entry point for plot remaps; lock held
642 int _sv_panel1d_map_redraw(sv_panel_t
*p
, _sv_bythread_cache_t
*c
){
643 if(p
->private->map_progress_count
)return 0;
644 p
->private->map_progress_count
++;
646 // render to a temp surface so that we can release the lock occasionally
647 _sv_plot_t
*plot
= PLOT(p
->private->graph
);
648 cairo_surface_t
*back
= plot
->back
;
649 cairo_surface_t
*cs
= cairo_surface_create_similar(back
,CAIRO_CONTENT_COLOR
,
650 cairo_image_surface_get_width(back
),
651 cairo_image_surface_get_height(back
));
652 cairo_t
*ct
= cairo_create(cs
);
654 if(_sv_panel1d_remap(p
,ct
) == -1){ // returns -1 on abort
656 cairo_surface_destroy(cs
);
659 cairo_surface_destroy(plot
->back
);
663 _sv_panel_clean_map(p
);
664 _sv_plot_expose_request(plot
);
670 // call only from main gtk thread
671 void _sv_panel1d_mark_recompute(sv_panel_t
*p
){
672 if(!p
->private->realized
) return;
673 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
674 _sv_plot_t
*plot
= PLOT(p
->private->graph
);
675 int w
= plot
->w
.allocation
.width
;
676 int h
= plot
->w
.allocation
.height
;
680 if(plot
&& GTK_WIDGET_REALIZED(GTK_WIDGET(plot
))){
682 dw
= _sv_dim_scales(p
->private->x_d
,
683 p
->private->x_d
->bracket
[1],
684 p
->private->x_d
->bracket
[0],
685 h
,dw
* p
->private->oversample_n
/ p
->private->oversample_d
,
687 p
->private->x_d
->name
,
692 p1
->y
= _sv_scalespace_linear(p1
->range_bracket
[0],
693 p1
->range_bracket
[1],
696 p1
->range_scale
->legend
);
699 dw
= _sv_dim_scales(p
->private->x_d
,
700 p
->private->x_d
->bracket
[0],
701 p
->private->x_d
->bracket
[1],
702 w
,dw
* p
->private->oversample_n
/ p
->private->oversample_d
,
704 p
->private->x_d
->name
,
709 p1
->y
= _sv_scalespace_linear(p1
->range_bracket
[1],
710 p1
->range_bracket
[0],
713 p1
->range_scale
->legend
);
716 if(p1
->data_size
!= dw
){
721 for(i
=0;i
<p
->objectives
;i
++){
722 double *new_vec
= malloc(dw
* sizeof(**p1
->data_vec
));
724 free(p1
->data_vec
[i
]);
725 p1
->data_vec
[i
] = new_vec
;
735 p1
->data_vec
= calloc(p
->objectives
,sizeof(*p1
->data_vec
));
736 for(i
=0;i
<p
->objectives
;i
++)
737 p1
->data_vec
[i
] = malloc(dw
*sizeof(**p1
->data_vec
));
742 for(i
=0;i
<p
->objectives
;i
++)
744 p1
->data_vec
[i
][j
]=NAN
;
746 if(p1
->panel_w
!= w
|| p1
->panel_h
!= h
){
747 p
->private->map_progress_count
=0;
748 _sv_panel1d_map_redraw(p
, NULL
);
754 _sv_panel_dirty_plot(p
);
758 static void _sv_panel1d_recompute_callback(void *ptr
){
759 sv_panel_t
*p
= (sv_panel_t
*)ptr
;
760 _sv_panel1d_mark_recompute(p
);
763 static void _sv_panel1d_update_crosshair(sv_panel_t
*p
){
764 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
765 _sv_plot_t
*plot
= PLOT(p
->private->graph
);
769 if(!p
->private->realized
)return;
771 for(i
=0;i
<p
->dimensions
;i
++){
772 sv_dim_t
*d
= p
->dimension_list
[i
].d
;
773 if(d
== p
->private->x_d
)
774 x
= p
->dimension_list
[i
].d
->val
;
778 _sv_plot_set_crosshairs(plot
,0,x
);
780 _sv_plot_set_crosshairs(plot
,x
,0);
782 // crosshairs snap to a pixel position; the
783 // cached dimension value should be accurate with respect to the
785 for(i
=0;i
<p
->dimensions
;i
++){
786 sv_dim_t
*d
= p
->dimension_list
[i
].d
;
787 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
788 if(d
== p
->private->x_d
){
790 d
->val
= _sv_scalespace_value(&plot
->x
,_sv_plot_get_crosshair_ypixel(plot
));
792 d
->val
= _sv_scalespace_value(&plot
->x
,_sv_plot_get_crosshair_xpixel(plot
));
795 _sv_panel_dirty_legend(p
);
798 static void _sv_panel1d_center_callback(sv_dim_list_t
*dptr
){
799 sv_dim_t
*d
= dptr
->d
;
800 sv_panel_t
*p
= dptr
->p
;
801 int axisp
= (d
== p
->private->x_d
);
804 // mid slider of a non-axis dimension changed, rerender
805 _sv_panel1d_mark_recompute(p
);
807 // mid slider of an axis dimension changed, move crosshairs
808 _sv_panel1d_update_crosshair(p
);
812 static void _sv_panel1d_bracket_callback(sv_dim_list_t
*dptr
){
813 sv_dim_t
*d
= dptr
->d
;
814 sv_panel_t
*p
= dptr
->p
;
815 int axisp
= d
== p
->private->x_d
;
818 _sv_panel1d_mark_recompute(p
);
822 static void _sv_panel1d_dimchange_callback(GtkWidget
*button
,gpointer in
){
823 sv_panel_t
*p
= (sv_panel_t
*)in
;
825 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button
))){
830 _sv_panel1d_update_xsel(p
);
831 _sv_panel1d_update_crosshair(p
);
832 _sv_plot_unset_box(PLOT(p
->private->graph
));
833 _sv_panel1d_mark_recompute(p
);
839 static void _sv_panel1d_crosshair_callback(sv_panel_t
*p
){
840 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
841 double x
=PLOT(p
->private->graph
)->selx
;
845 x
=PLOT(p
->private->graph
)->sely
;
847 _sv_panel_dirty_legend(p
);
852 for(i
=0;i
<p
->dimensions
;i
++){
853 sv_dim_t
*d
= p
->dimension_list
[i
].d
;
854 if(d
== p
->private->x_d
)
855 _sv_dim_widget_set_thumb(p
->private->dim_scales
[i
],1,x
);
857 p
->private->oldbox_active
= 0;
861 static void _sv_panel1d_box_callback(void *in
, int state
){
862 sv_panel_t
*p
= (sv_panel_t
*)in
;
863 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
864 _sv_plot_t
*plot
= PLOT(p
->private->graph
);
869 _sv_plot_box_vals(plot
,p1
->oldbox
);
870 p
->private->oldbox_active
= plot
->box_active
;
872 case 1: // box activate
876 _sv_panel1d_crosshair_callback(p
);
878 _sv_dim_widget_set_thumb(p1
->x_scale
,0,p1
->oldbox
[0]);
879 _sv_dim_widget_set_thumb(p1
->x_scale
,2,p1
->oldbox
[1]);
880 p
->private->oldbox_active
= 0;
884 _sv_panel_update_menus(p
);
887 void _sv_panel1d_maintain_cache(sv_panel_t
*p
, _sv_bythread_cache_1d_t
*c
, int w
){
889 /* toplevel initialization */
893 /* determine which functions are actually needed */
894 c
->call
= calloc(_sv_functions
,sizeof(*c
->call
));
895 c
->fout
= calloc(_sv_functions
,sizeof(*c
->fout
));
896 for(i
=0;i
<p
->objectives
;i
++){
897 sv_obj_t
*o
= p
->objective_list
[i
].o
;
898 for(j
=0;j
<o
->outputs
;j
++)
899 c
->call
[o
->function_map
[j
]]=
900 _sv_function_list
[o
->function_map
[j
]]->callback
;
904 /* once to begin, as well as anytime the data width changes */
905 if(c
->storage_width
< w
){
907 c
->storage_width
= w
;
909 for(i
=0;i
<_sv_functions
;i
++){
911 if(c
->fout
[i
])free(c
->fout
[i
]);
912 c
->fout
[i
] = malloc(w
* _sv_function_list
[i
]->outputs
*
919 // subtype entry point for legend redraws; lock held
920 int _sv_panel1d_legend_redraw(sv_panel_t
*p
){
921 _sv_plot_t
*plot
= PLOT(p
->private->graph
);
923 if(p
->private->legend_progress_count
)return 0;
924 p
->private->legend_progress_count
++;
925 _sv_panel1d_update_legend(p
);
926 _sv_panel_clean_legend(p
);
929 _sv_plot_draw_scales(plot
);
932 _sv_plot_expose_request(plot
);
936 // subtype entry point for recomputation; lock held
937 int _sv_panel1d_compute(sv_panel_t
*p
,
938 _sv_bythread_cache_t
*c
){
939 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
948 _sv_scalespace_t sxv
;
949 _sv_scalespace_t sxi
;
961 if(p
->private->plot_progress_count
)
964 serialno
= p
->private->plot_serialno
;
965 p
->private->plot_progress_count
++;
967 plot
= PLOT(p
->private->graph
);
969 /* render using local dimension array; several threads will be
970 computing objectives */
971 double dim_vals
[_sv_dimensions
];
973 /* get iterator bounds, use iterator scale */
974 x_d
= p
->private->x_d
->number
;
988 // Initialize local dimension value array
989 for(i
=0;i
<_sv_dimensions
;i
++){
990 sv_dim_t
*dim
= _sv_dimension_list
[i
];
991 dim_vals
[i
]=dim
->val
;
994 _sv_panel1d_maintain_cache(p
,&c
->p1
,dw
);
996 /* unlock for computation */
997 gdk_threads_leave ();
999 _sv_panel1d_compute_line(p
, serialno
, x_d
, sxi
, dw
, dim_vals
, &c
->p1
);
1001 gdk_threads_enter ();
1003 if(serialno
== p
->private->plot_serialno
){
1004 _sv_panel_dirty_map(p
);
1005 _sv_panel_dirty_legend(p
);
1006 _sv_panel_clean_plot(p
);
1011 static void _sv_panel1d_undo_log(_sv_panel_undo_t
*u
, sv_panel_t
*p
){
1012 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
1015 // alloc fields as necessary
1017 u
->mappings
= calloc(p
->objectives
,sizeof(*u
->mappings
));
1018 if(!u
->scale_vals
[0])
1019 u
->scale_vals
[0] = calloc(1,sizeof(**u
->scale_vals
));
1020 if(!u
->scale_vals
[1])
1021 u
->scale_vals
[1] = calloc(1,sizeof(**u
->scale_vals
));
1022 if(!u
->scale_vals
[2])
1023 u
->scale_vals
[2] = calloc(p
->objectives
,sizeof(**u
->scale_vals
));
1026 u
->scale_vals
[0][0] = _sv_slider_get_value(p1
->range_slider
,0);
1027 u
->scale_vals
[1][0] = _sv_slider_get_value(p1
->range_slider
,1);
1029 for(i
=0;i
<p
->objectives
;i
++){
1031 (p1
->mappings
[i
].mapnum
<<24) |
1032 (p1
->linetype
[i
]<<16) |
1033 (p1
->pointtype
[i
]<<8);
1034 u
->scale_vals
[2][i
] = _sv_slider_get_value(p1
->alpha_scale
[i
],0);
1037 u
->x_d
= p1
->x_dnum
;
1038 u
->box
[0] = p1
->oldbox
[0];
1039 u
->box
[1] = p1
->oldbox
[1];
1041 u
->box_active
= p
->private->oldbox_active
;
1045 static void _sv_panel1d_undo_restore(_sv_panel_undo_t
*u
, sv_panel_t
*p
){
1046 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
1047 _sv_plot_t
*plot
= PLOT(p
->private->graph
);
1051 // go in through widgets
1053 _sv_slider_set_value(p1
->range_slider
,0,u
->scale_vals
[0][0]);
1054 _sv_slider_set_value(p1
->range_slider
,1,u
->scale_vals
[1][0]);
1056 for(i
=0;i
<p
->objectives
;i
++){
1057 gtk_combo_box_set_active(GTK_COMBO_BOX(p1
->map_pulldowns
[i
]), (u
->mappings
[i
]>>24)&0xff );
1058 gtk_combo_box_set_active(GTK_COMBO_BOX(p1
->line_pulldowns
[i
]), (u
->mappings
[i
]>>16)&0xff );
1059 gtk_combo_box_set_active(GTK_COMBO_BOX(p1
->point_pulldowns
[i
]), (u
->mappings
[i
]>>8)&0xff );
1060 _sv_slider_set_value(p1
->alpha_scale
[i
],0,u
->scale_vals
[2][i
]);
1063 if(p1
->dim_xb
&& u
->x_d
<p
->dimensions
&& p1
->dim_xb
[u
->x_d
])
1064 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p1
->dim_xb
[u
->x_d
]),TRUE
);
1066 _sv_panel1d_update_xsel(p
);
1069 p1
->oldbox
[0] = u
->box
[0];
1070 p1
->oldbox
[1] = u
->box
[1];
1071 _sv_plot_box_set(plot
,u
->box
);
1072 p
->private->oldbox_active
= 1;
1074 _sv_plot_unset_box(plot
);
1075 p
->private->oldbox_active
= 0;
1079 void _sv_panel1d_realize(sv_panel_t
*p
){
1080 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
1085 p
->private->toplevel
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
1086 g_signal_connect_swapped (G_OBJECT (p
->private->toplevel
), "delete-event",
1087 G_CALLBACK (_sv_clean_exit
), (void *)SIGINT
);
1089 // add border to sides with hbox/padding
1090 GtkWidget
*borderbox
= gtk_hbox_new(0,0);
1091 gtk_container_add (GTK_CONTAINER (p
->private->toplevel
), borderbox
);
1094 p
->private->topbox
= gtk_vbox_new(0,0);
1095 gtk_box_pack_start(GTK_BOX(borderbox
), p
->private->topbox
, 1,1,4);
1096 gtk_container_set_border_width (GTK_CONTAINER (p
->private->toplevel
), 1);
1098 /* spinner, top bar */
1100 GtkWidget
*hbox
= gtk_hbox_new(0,0);
1101 gtk_box_pack_start(GTK_BOX(p
->private->topbox
), hbox
, 0,0,0);
1102 gtk_box_pack_end(GTK_BOX(hbox
),GTK_WIDGET(p
->private->spinner
),0,0,0);
1105 /* plotbox, graph */
1109 flags
|= _SV_PLOT_NO_X_CROSS
;
1111 flags
|= _SV_PLOT_NO_Y_CROSS
;
1113 p1
->graph_table
= gtk_table_new(2,2,0);
1114 p
->private->plotbox
= p1
->graph_table
;
1115 gtk_box_pack_start(GTK_BOX(p
->private->topbox
), p
->private->plotbox
, 1,1,2);
1117 p
->private->graph
= GTK_WIDGET(_sv_plot_new(_sv_panel1d_recompute_callback
,p
,
1118 (void *)(void *)_sv_panel1d_crosshair_callback
,p
,
1119 _sv_panel1d_box_callback
,p
,flags
));
1121 gtk_table_attach(GTK_TABLE(p1
->graph_table
),p
->private->graph
,0,2,0,1,
1122 GTK_EXPAND
|GTK_FILL
,GTK_EXPAND
|GTK_FILL
,0,1);
1124 gtk_table_attach(GTK_TABLE(p1
->graph_table
),p
->private->graph
,1,2,0,2,
1125 GTK_EXPAND
|GTK_FILL
,GTK_EXPAND
|GTK_FILL
,0,1);
1129 /* range slider, goes in the plotbox table */
1130 /* may be vertical to the left of the plot or along the bottom if the plot is flipped */
1132 GtkWidget
**sl
= calloc(2,sizeof(*sl
));
1133 int lo
= p1
->range_scale
->val_list
[0];
1134 int hi
= p1
->range_scale
->val_list
[p1
->range_scale
->vals
-1];
1136 /* the range slices/slider */
1137 sl
[0] = _sv_slice_new(_sv_panel1d_map_callback
,p
);
1138 sl
[1] = _sv_slice_new(_sv_panel1d_map_callback
,p
);
1141 gtk_table_attach(GTK_TABLE(p1
->graph_table
),sl
[0],0,1,1,2,
1142 GTK_EXPAND
|GTK_FILL
,0,0,0);
1143 gtk_table_attach(GTK_TABLE(p1
->graph_table
),sl
[1],1,2,1,2,
1144 GTK_EXPAND
|GTK_FILL
,0,0,0);
1146 gtk_table_attach(GTK_TABLE(p1
->graph_table
),sl
[0],0,1,1,2,
1147 GTK_SHRINK
,GTK_EXPAND
|GTK_FILL
,0,0);
1148 gtk_table_attach(GTK_TABLE(p1
->graph_table
),sl
[1],0,1,0,1,
1149 GTK_SHRINK
,GTK_EXPAND
|GTK_FILL
,0,0);
1150 gtk_table_set_col_spacing(GTK_TABLE(p1
->graph_table
),0,4);
1153 p1
->range_slider
= _sv_slider_new((_sv_slice_t
**)sl
,2,
1154 p1
->range_scale
->label_list
,
1155 p1
->range_scale
->val_list
,
1156 p1
->range_scale
->vals
,
1157 (p1
->flip
?0:_SV_SLIDER_FLAG_VERTICAL
));
1159 _sv_slice_thumb_set((_sv_slice_t
*)sl
[0],lo
);
1160 _sv_slice_thumb_set((_sv_slice_t
*)sl
[1],hi
);
1165 p1
->obj_table
= gtk_table_new(p
->objectives
,5,0);
1166 gtk_box_pack_start(GTK_BOX(p
->private->topbox
), p1
->obj_table
, 0,0,1);
1169 p1
->pointtype
= calloc(p
->objectives
,sizeof(*p1
->pointtype
));
1170 p1
->linetype
= calloc(p
->objectives
,sizeof(*p1
->linetype
));
1171 p1
->mappings
= calloc(p
->objectives
,sizeof(*p1
->mappings
));
1172 p1
->map_pulldowns
= calloc(p
->objectives
,sizeof(*p1
->map_pulldowns
));
1173 p1
->line_pulldowns
= calloc(p
->objectives
,sizeof(*p1
->line_pulldowns
));
1174 p1
->point_pulldowns
= calloc(p
->objectives
,sizeof(*p1
->point_pulldowns
));
1175 p1
->alpha_scale
= calloc(p
->objectives
,sizeof(*p1
->alpha_scale
));
1177 for(i
=0;i
<p
->objectives
;i
++){
1178 sv_obj_t
*o
= p
->objective_list
[i
].o
;
1181 GtkWidget
*label
= gtk_label_new(o
->name
);
1182 gtk_misc_set_alignment(GTK_MISC(label
),1.,.5);
1183 gtk_table_attach(GTK_TABLE(p1
->obj_table
),label
,0,1,i
,i
+1,
1186 /* mapping pulldown */
1188 GtkWidget
*menu
=_gtk_combo_box_new_markup();
1190 for(j
=0;j
<_sv_solid_names();j
++){
1191 if(strcmp(_sv_solid_name(j
),"inactive"))
1192 snprintf(buffer
,sizeof(buffer
),"<span foreground=\"%s\">%s</span>",
1193 _sv_solid_name(j
),_sv_solid_name(j
));
1195 snprintf(buffer
,sizeof(buffer
),"%s",_sv_solid_name(j
));
1197 gtk_combo_box_append_text (GTK_COMBO_BOX (menu
), buffer
);
1199 gtk_combo_box_set_active(GTK_COMBO_BOX(menu
),0);
1200 g_signal_connect (G_OBJECT (menu
), "changed",
1201 G_CALLBACK (_sv_panel1d_mapchange_callback
), p
->objective_list
+i
);
1202 gtk_table_attach(GTK_TABLE(p1
->obj_table
),menu
,1,2,i
,i
+1,
1203 GTK_SHRINK
,GTK_SHRINK
,5,0);
1204 p1
->map_pulldowns
[i
] = menu
;
1205 _sv_solid_setup(&p1
->mappings
[i
],0.,1.,0);
1210 GtkWidget
*menu
=gtk_combo_box_new_text();
1212 for(j
=0;j
<LINETYPES
;j
++)
1213 gtk_combo_box_append_text (GTK_COMBO_BOX (menu
), line_name
[j
]->left
);
1214 gtk_combo_box_set_active(GTK_COMBO_BOX(menu
),0);
1215 g_signal_connect (G_OBJECT (menu
), "changed",
1216 G_CALLBACK (_sv_panel1d_linetype_callback
), p
->objective_list
+i
);
1217 gtk_table_attach(GTK_TABLE(p1
->obj_table
),menu
,2,3,i
,i
+1,
1218 GTK_SHRINK
,GTK_SHRINK
,5,0);
1219 p1
->line_pulldowns
[i
] = menu
;
1222 /* point pulldown */
1224 GtkWidget
*menu
=gtk_combo_box_new_text();
1226 for(j
=0;j
<POINTTYPES
;j
++)
1227 gtk_combo_box_append_text (GTK_COMBO_BOX (menu
), point_name
[j
]->left
);
1228 gtk_combo_box_set_active(GTK_COMBO_BOX(menu
),0);
1229 g_signal_connect (G_OBJECT (menu
), "changed",
1230 G_CALLBACK (_sv_panel1d_pointtype_callback
), p
->objective_list
+i
);
1231 gtk_table_attach(GTK_TABLE(p1
->obj_table
),menu
,3,4,i
,i
+1,
1232 GTK_SHRINK
,GTK_SHRINK
,5,0);
1233 p1
->point_pulldowns
[i
] = menu
;
1238 GtkWidget
**sl
= calloc(1, sizeof(*sl
));
1239 sl
[0] = _sv_slice_new(_sv_panel1d_alpha_callback
,p
->objective_list
+i
);
1241 gtk_table_attach(GTK_TABLE(p1
->obj_table
),sl
[0],4,5,i
,i
+1,
1242 GTK_EXPAND
|GTK_FILL
,0,0,0);
1244 p1
->alpha_scale
[i
] = _sv_slider_new((_sv_slice_t
**)sl
,1,
1245 (char *[]){"transparent","solid"},
1249 _sv_slider_set_gradient(p1
->alpha_scale
[i
], &p1
->mappings
[i
]);
1250 _sv_slice_thumb_set((_sv_slice_t
*)sl
[0],1.);
1258 p1
->dim_table
= gtk_table_new(p
->dimensions
,3,0);
1259 gtk_box_pack_start(GTK_BOX(p
->private->topbox
), p1
->dim_table
, 0,0,4);
1261 p
->private->dim_scales
= calloc(p
->dimensions
,sizeof(*p
->private->dim_scales
));
1262 p1
->dim_xb
= calloc(p
->dimensions
,sizeof(*p1
->dim_xb
));
1263 GtkWidget
*first_x
= NULL
;
1265 for(i
=0;i
<p
->dimensions
;i
++){
1266 sv_dim_t
*d
= p
->dimension_list
[i
].d
;
1269 GtkWidget
*label
= gtk_label_new(d
->name
);
1270 gtk_misc_set_alignment(GTK_MISC(label
),1.,.5);
1271 gtk_table_attach(GTK_TABLE(p1
->dim_table
),label
,0,1,i
,i
+1,
1274 /* x radio buttons */
1275 if(!(d
->flags
& SV_DIM_NO_X
)){
1277 p1
->dim_xb
[i
] = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(first_x
),"X");
1279 first_x
= p1
->dim_xb
[i
] = gtk_radio_button_new_with_label(NULL
,"X");
1280 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p1
->dim_xb
[i
]),TRUE
);
1282 gtk_table_attach(GTK_TABLE(p1
->dim_table
),p1
->dim_xb
[i
],1,2,i
,i
+1,
1286 p
->private->dim_scales
[i
] =
1287 _sv_dim_widget_new(p
->dimension_list
+i
,_sv_panel1d_center_callback
,_sv_panel1d_bracket_callback
);
1289 gtk_table_attach(GTK_TABLE(p1
->dim_table
),
1290 GTK_WIDGET(p
->private->dim_scales
[i
]->t
),
1292 GTK_EXPAND
|GTK_FILL
,0,0,0);
1296 for(i
=0;i
<p
->dimensions
;i
++)
1298 g_signal_connect (G_OBJECT (p1
->dim_xb
[i
]), "toggled",
1299 G_CALLBACK (_sv_panel1d_dimchange_callback
), p
);
1301 _sv_panel1d_update_xsel(p
);
1304 gtk_widget_realize(p
->private->toplevel
);
1305 gtk_widget_realize(p
->private->graph
);
1306 gtk_widget_realize(GTK_WIDGET(p
->private->spinner
));
1307 gtk_widget_show_all(p
->private->toplevel
);
1313 static int _sv_panel1d_save(sv_panel_t
*p
, xmlNodePtr pn
){
1314 _sv_panel1d_t
*p1
= p
->subtype
->p1
;
1319 xmlNewProp(pn
, (xmlChar
*)"type", (xmlChar
*)"1d");
1322 if(p
->private->oldbox_active
){
1323 xmlNodePtr boxn
= xmlNewChild(pn
, NULL
, (xmlChar
*) "box", NULL
);
1324 _xmlNewPropF(boxn
, "x1", p1
->oldbox
[0]);
1325 _xmlNewPropF(boxn
, "x2", p1
->oldbox
[1]);
1328 // objective map settings
1329 for(i
=0;i
<p
->objectives
;i
++){
1330 sv_obj_t
*o
= p
->objective_list
[i
].o
;
1332 xmlNodePtr on
= xmlNewChild(pn
, NULL
, (xmlChar
*) "objective", NULL
);
1333 _xmlNewPropI(on
, "position", i
);
1334 _xmlNewPropI(on
, "number", o
->number
);
1335 _xmlNewPropS(on
, "name", o
->name
);
1336 _xmlNewPropS(on
, "type", o
->output_types
);
1338 // right now Y is the only type; the below is Y-specific
1340 n
= xmlNewChild(on
, NULL
, (xmlChar
*) "y-map", NULL
);
1341 _xmlNewMapProp(n
, "color", _sv_solid_map(), p1
->mappings
[i
].mapnum
);
1342 _xmlNewMapProp(n
, "line", line_name
, p1
->linetype
[i
]);
1343 _xmlNewMapProp(n
, "point", point_name
, p1
->pointtype
[i
]);
1344 _xmlNewPropF(n
, "alpha", _sv_slider_get_value(p1
->alpha_scale
[i
],0));
1348 n
= xmlNewChild(pn
, NULL
, (xmlChar
*) "range", NULL
);
1349 _xmlNewPropF(n
, "low-bracket", _sv_slider_get_value(p1
->range_slider
,0));
1350 _xmlNewPropF(n
, "high-bracket", _sv_slider_get_value(p1
->range_slider
,1));
1352 // x/y dim selection
1353 n
= xmlNewChild(pn
, NULL
, (xmlChar
*) "axes", NULL
);
1354 _xmlNewPropI(n
, "xpos", p1
->x_dnum
);
1359 int _sv_panel1d_load(sv_panel_t
*p
,
1360 _sv_panel_undo_t
*u
,
1366 _xmlCheckPropS(pn
,"type","1d", "Panel %d type mismatch in save file.",p
->number
,&warn
);
1370 _xmlGetChildPropFPreserve(pn
, "box", "x1", &u
->box
[0]);
1371 _xmlGetChildPropFPreserve(pn
, "box", "x2", &u
->box
[1]);
1373 xmlNodePtr n
= _xmlGetChildS(pn
, "box", NULL
, NULL
);
1379 // objective map settings
1380 for(i
=0;i
<p
->objectives
;i
++){
1381 sv_obj_t
*o
= p
->objective_list
[i
].o
;
1382 xmlNodePtr on
= _xmlGetChildI(pn
, "objective", "position", i
);
1384 _sv_first_load_warning(&warn
);
1385 fprintf(stderr
,"No save data found for panel %d objective \"%s\".\n",p
->number
, o
->name
);
1388 _xmlCheckPropS(on
,"name",o
->name
, "Objectve position %d name mismatch in save file.",i
,&warn
);
1389 _xmlCheckPropS(on
,"type",o
->output_types
, "Objectve position %d type mismatch in save file.",i
,&warn
);
1391 // right now Y is the only type; the below is Y-specific
1392 // load maptype, values
1393 int color
= (u
->mappings
[i
]>>24)&0xff;
1394 int line
= (u
->mappings
[i
]>>16)&0xff;
1395 int point
= (u
->mappings
[i
]>>8)&0xff;
1397 _xmlGetChildMapPreserve(on
, "y-map", "color", _sv_solid_map(), &color
,
1398 "Panel %d objective unknown mapping setting", p
->number
, &warn
);
1399 _xmlGetChildMapPreserve(on
, "y-map", "line", line_name
, &line
,
1400 "Panel %d objective unknown mapping setting", p
->number
, &warn
);
1401 _xmlGetChildMapPreserve(on
, "y-map", "point", point_name
, &point
,
1402 "Panel %d objective unknown mapping setting", p
->number
, &warn
);
1403 _xmlGetChildPropF(on
, "y-map", "alpha", &u
->scale_vals
[2][i
]);
1405 u
->mappings
[i
] = (color
<<24) | (line
<<16) | (point
<<8);
1412 _xmlGetChildPropFPreserve(pn
, "range", "low-bracket", &u
->scale_vals
[0][0]);
1413 _xmlGetChildPropF(pn
, "range", "high-bracket", &u
->scale_vals
[1][0]);
1415 // x/y dim selection
1416 _xmlGetChildPropI(pn
, "axes", "xpos", &u
->x_d
);
1421 sv_panel_t
*sv_panel_new_1d(int number
,
1424 char *objectivelist
,
1425 char *dimensionlist
,
1428 sv_panel_t
*p
= _sv_panel_new(number
,name
,objectivelist
,dimensionlist
,flags
);
1432 p1
= calloc(1, sizeof(*p1
));
1433 p
->subtype
= calloc(1, sizeof(*p
->subtype
));
1435 p
->subtype
->p1
= p1
;
1436 p
->type
= SV_PANEL_1D
;
1437 p1
->range_scale
= (sv_scale_t
*)scale
;
1438 p
->private->bg_type
= SV_BG_WHITE
;
1440 if(p
->flags
&& SV_PANEL_FLIP
)
1443 p
->private->realize
= _sv_panel1d_realize
;
1444 p
->private->map_action
= _sv_panel1d_map_redraw
;
1445 p
->private->legend_action
= _sv_panel1d_legend_redraw
;
1446 p
->private->compute_action
= _sv_panel1d_compute
;
1447 p
->private->request_compute
= _sv_panel1d_mark_recompute
;
1448 p
->private->crosshair_action
= _sv_panel1d_crosshair_callback
;
1449 p
->private->print_action
= _sv_panel1d_print
;
1450 p
->private->save_action
= _sv_panel1d_save
;
1451 p
->private->load_action
= _sv_panel1d_load
;
1453 p
->private->undo_log
= _sv_panel1d_undo_log
;
1454 p
->private->undo_restore
= _sv_panel1d_undo_restore
;
1455 p
->private->def_oversample_n
= p
->private->oversample_n
= 1;
1456 p
->private->def_oversample_d
= p
->private->oversample_d
= 8;