550 lines
16 KiB
C
550 lines
16 KiB
C
/*
|
|
* gawzoom.c - Analog waveform viewer
|
|
* zoom stuff
|
|
*/
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include <gtk/gtk.h>
|
|
#include <string.h>
|
|
// #include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
#include <gaw.h>
|
|
|
|
#ifdef TRACE_MEM
|
|
#include <tracemem.h>
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
* reset the x zoom scale of all panels
|
|
*/
|
|
gint az_cmd_zoom_absolute(UserData *ud, double start, double end )
|
|
{
|
|
double scroll_start, scroll_end;
|
|
GawLabels *lbx = ud->xLabels;
|
|
|
|
msg_dbg("start %f end %f", start, end);
|
|
/* set starting drawn x-value */
|
|
if (start > end) {
|
|
int val = start;
|
|
start = end;
|
|
end = val;
|
|
}
|
|
if (start < lbx->min_val) {
|
|
start = lbx->min_val;
|
|
}
|
|
if (end > lbx->max_val) {
|
|
end = lbx->max_val;
|
|
}
|
|
|
|
/*
|
|
* Needs tp update_vals for the end of this function
|
|
*/
|
|
al_label_update_vals( lbx, start, end );
|
|
/*
|
|
* Scroll bar always goes from zero to one.
|
|
* Perform an appropriate transform based on lin/log
|
|
*/
|
|
if ( lbx->logAxis && lbx->logAble ) {
|
|
scroll_start = (lbx->max_Lval > lbx->min_Lval) ?
|
|
( lbx->start_Lval - lbx->min_Lval ) /
|
|
( lbx->max_Lval - lbx->min_Lval ) :
|
|
0.0;
|
|
scroll_end = (lbx->max_Lval > lbx->min_Lval) ?
|
|
( lbx->end_Lval - lbx->min_Lval ) /
|
|
( lbx->max_Lval - lbx->min_Lval ) :
|
|
0.0;
|
|
} else {
|
|
scroll_start = ( lbx->start_val - lbx->min_val ) /
|
|
( lbx->max_val - lbx->min_val );
|
|
scroll_end = ( lbx->end_val - lbx->min_val ) /
|
|
( lbx->max_val - lbx->min_val );
|
|
}
|
|
if ( ud->xadj == NULL || lbx->wh == 0 ) {
|
|
return 0;
|
|
}
|
|
gdouble page_size;
|
|
|
|
page_size = fabs( scroll_end - scroll_start );
|
|
gtk_adjustment_set_page_size (ud->xadj, page_size);
|
|
msg_dbg("scroll_start %f scroll_end %f", scroll_start, scroll_end);
|
|
|
|
gtk_adjustment_set_page_increment(ud->xadj, page_size / 2);
|
|
gtk_adjustment_set_step_increment(ud->xadj, page_size / 100);
|
|
gtk_adjustment_set_value(ud->xadj, scroll_start);
|
|
gtk_adjustment_set_lower(ud->xadj, 0.0);
|
|
gtk_adjustment_set_upper(ud->xadj, 1.0);
|
|
|
|
gtk_adjustment_value_changed (ud->xadj);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void az_zoom_in_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
UserData *ud = (UserData *) user_data;
|
|
double start;
|
|
double end;
|
|
GawLabels *lbx = ud->xLabels;
|
|
|
|
if ( lbx->logAxis && lbx->logAble ) {
|
|
start = pow( 10, lbx->start_Lval + ( lbx->end_Lval - lbx->start_Lval ) / 4 );
|
|
end = pow( 10, lbx->end_Lval - ( lbx->end_Lval - lbx->start_Lval ) / 4 );
|
|
} else {
|
|
start = lbx->start_val + ( lbx->end_val - lbx->start_val) / 4;
|
|
end = lbx->end_val - ( lbx->end_val - lbx->start_val) / 4;
|
|
}
|
|
|
|
az_cmd_zoom_absolute(ud, start, end );
|
|
}
|
|
|
|
void
|
|
az_pop_zoom_in_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
WavePanel *wp = (WavePanel *) user_data;
|
|
az_zoom_in_gaction (action, param, wp->ud);
|
|
}
|
|
|
|
void
|
|
az_zoom_out_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
UserData *ud = (UserData *) user_data;
|
|
double start;
|
|
double end;
|
|
GawLabels *lbx = ud->xLabels;
|
|
|
|
if ( lbx->logAxis && lbx->logAble ) {
|
|
start = pow( 10, lbx->start_Lval - ( lbx->end_Lval - lbx->start_Lval ) / 2 );
|
|
end = pow( 10, lbx->end_Lval + ( lbx->end_Lval - lbx->start_Lval ) / 2 );
|
|
} else {
|
|
start = lbx->start_val - ( lbx->end_val - lbx->start_val) / 2;
|
|
end = lbx->end_val + ( lbx->end_val - lbx->start_val) / 2;
|
|
}
|
|
|
|
az_cmd_zoom_absolute(ud, start, end );
|
|
}
|
|
|
|
void az_pop_zoom_out_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
WavePanel *wp = (WavePanel *) user_data;
|
|
az_zoom_out_gaction (action, param, wp->ud);
|
|
}
|
|
|
|
void az_zoom_cursor0_centered_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
UserData *ud = (UserData *) user_data;
|
|
double start;
|
|
double end;
|
|
GawLabels *lbx = ud->xLabels;
|
|
AWCursor *csp = ud->cursors[0];
|
|
|
|
msg_dbg("cursors[0] shown %d 0x%x", csp->shown, (unsigned long) csp );
|
|
if ( csp->shown ) {
|
|
double xval = csp->xval;
|
|
double Lxval = 0;
|
|
|
|
if ( lbx->logAxis && lbx->logAble ) {
|
|
Lxval = log10(xval);
|
|
start = pow( 10, lbx->start_Lval + (( Lxval - lbx->start_Lval ) / 4) );
|
|
end = pow( 10, lbx->end_Lval + (( Lxval - lbx->end_Lval ) / 4) );
|
|
} else {
|
|
start = lbx->start_val + ( xval - lbx->start_val ) / 4;
|
|
end = lbx->end_val + ( xval - lbx->end_val ) / 4;
|
|
}
|
|
msg_dbg("xval %f Lxval %f start %f end %f", xval, Lxval, start, end);
|
|
|
|
az_cmd_zoom_absolute(ud, start, end );
|
|
|
|
} else {
|
|
msg_info(_( "\n\nThis function will zoom centered on cursor 0\n"
|
|
"But you need first set the cursor 0 by left click in DrawingArea\n") );
|
|
}
|
|
}
|
|
|
|
void az_zoom_cursors_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
UserData *ud = (UserData *) user_data;
|
|
double start;
|
|
double end;
|
|
|
|
if ( ud->cursors[0]->shown && ud->cursors[1]->shown ) {
|
|
if( ud->cursors[0]->xval < ud->cursors[1]->xval) {
|
|
start = ud->cursors[0]->xval;
|
|
end = ud->cursors[1]->xval;
|
|
} else {
|
|
start = ud->cursors[1]->xval;
|
|
end = ud->cursors[0]->xval;
|
|
}
|
|
az_cmd_zoom_absolute(ud, start, end );
|
|
// cu_clear_cursors(ud);
|
|
} else {
|
|
msg_info(_("\n\nThis function will zoom between the 2 cursors\n"
|
|
"But you need first set the cursor 0 by left click in DrawingArea\n"
|
|
"and the cursor 1 by middle click in DrawingArea\n") );
|
|
}
|
|
}
|
|
|
|
void
|
|
az_pop_zoom_cursors_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
WavePanel *wp = (WavePanel *) user_data;
|
|
az_zoom_cursors_gaction (action, param, wp->ud);
|
|
}
|
|
|
|
|
|
void az_zoom_x_full_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
UserData *ud = (UserData *) user_data;
|
|
double start;
|
|
double end;
|
|
GawLabels *lbx = ud->xLabels;
|
|
|
|
start = lbx->min_val;
|
|
end = lbx->max_val;
|
|
|
|
if (lbx->start_val == lbx->min_val && lbx->end_val == lbx->max_val) {
|
|
msg_info (_("\n\nNo Zoom X to cancel\n"));
|
|
}
|
|
|
|
az_cmd_zoom_absolute(ud, start, end );
|
|
}
|
|
|
|
void az_pop_zoom_x_full_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
WavePanel *wp = (WavePanel *) user_data;
|
|
az_zoom_x_full_gaction (action, param, wp->ud );
|
|
}
|
|
|
|
void az_pop_zoom_y_full_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
WavePanel *wp = (WavePanel *) user_data;
|
|
if ( ! wp ) {
|
|
return;
|
|
}
|
|
GawLabels *lby = wp->yLabels;
|
|
|
|
wp->man_yzoom = 0;
|
|
pa_panel_set_yvals( wp, lby->min_val, lby->max_val);
|
|
pa_panel_full_redraw(wp);
|
|
}
|
|
|
|
void az_zoom_y_full_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
UserData *ud = (UserData *) user_data;
|
|
WavePanel *wp = ud->selected_panel;
|
|
|
|
if ( ! wp) {
|
|
msg_info (aw_panel_not_selected_msg);
|
|
ap_all_redraw(ud);
|
|
return;
|
|
}
|
|
az_pop_zoom_y_full_gaction (action, param, wp);
|
|
}
|
|
|
|
void az_zoom_x_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
UserData *ud = (UserData *) user_data;
|
|
ud->srange->type = SR_X;
|
|
ud->mouseState = M_SELRANGE_ARMED;
|
|
|
|
/* set gdk cursor in all panels */
|
|
g_list_foreach(ud->panelList, (GFunc) pa_panel_drawing_set_gdk_cursor,
|
|
GINT_TO_POINTER (GDK_RIGHT_SIDE) );
|
|
}
|
|
|
|
void az_pop_zoom_x_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
WavePanel *wp = (WavePanel *) user_data;
|
|
az_zoom_x_gaction (action, param, wp->ud);
|
|
}
|
|
|
|
void
|
|
az_zoom_y_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
UserData *ud = (UserData *) user_data;
|
|
ud->srange->type = SR_Y;
|
|
ud->mouseState = M_SELRANGE_ARMED;
|
|
/* set gdk cursor in all panels */
|
|
g_list_foreach(ud->panelList, (GFunc) pa_panel_drawing_set_gdk_cursor,
|
|
GINT_TO_POINTER (GDK_TOP_SIDE) );
|
|
}
|
|
|
|
void
|
|
az_pop_zoom_y_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
WavePanel *wp = (WavePanel *) user_data;
|
|
az_zoom_y_gaction (action, param, wp->ud);
|
|
}
|
|
|
|
void
|
|
az_zoom_xy_area_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
UserData *ud = (UserData *) user_data;
|
|
ud->srange->type = SR_XY;
|
|
ud->mouseState = M_SELRANGE_ARMED;
|
|
/* set gdk cursor in all panels */
|
|
g_list_foreach(ud->panelList, (GFunc) pa_panel_drawing_set_gdk_cursor,
|
|
GINT_TO_POINTER (GDK_TOP_LEFT_CORNER) );
|
|
}
|
|
|
|
void az_pop_zoom_xy_area_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
WavePanel *wp = (WavePanel *) user_data;
|
|
az_zoom_xy_area_gaction (action, param, wp->ud);
|
|
}
|
|
|
|
typedef struct _ToggledData {
|
|
WavePanel *wp;
|
|
GtkWidget *entry_ys;
|
|
GtkWidget *entry_ye;
|
|
} ToggledData;
|
|
|
|
|
|
static void
|
|
az_button_toggled_cb (GtkWidget *widget, ToggledData *pdata)
|
|
{
|
|
pdata->wp->man_yzoom = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
|
|
if ( pdata->entry_ys ){
|
|
gtk_widget_set_sensitive (pdata->entry_ys, pdata->wp->man_yzoom);
|
|
}
|
|
if ( pdata->entry_ye ){
|
|
gtk_widget_set_sensitive (pdata->entry_ye, pdata->wp->man_yzoom);
|
|
}
|
|
}
|
|
|
|
static void
|
|
az_entry_changed_cb (GtkWidget *widget, gpointer pdata)
|
|
{
|
|
const gchar *text;
|
|
double *val = ( double *) pdata;
|
|
|
|
text = gtk_entry_get_text (GTK_ENTRY (widget));
|
|
*val = str2val((char *) text);
|
|
}
|
|
|
|
void az_pop_zoom_dialog_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
WavePanel *wp = (WavePanel *) user_data;
|
|
if ( ! wp ) {
|
|
return ;
|
|
}
|
|
UserData *ud = wp->ud;
|
|
GtkWidget *dialog;
|
|
GtkWidget *vbox;
|
|
gint response;
|
|
static ToggledData *toggledData = NULL;
|
|
GtkWidget *frame;
|
|
GtkWidget *x_table;
|
|
GtkWidget *y_table;
|
|
GtkWidget *label;
|
|
GtkWidget *entry;
|
|
GtkWidget *button;
|
|
gchar *str;
|
|
GawLabels *lbx = ud->xLabels;
|
|
GawLabels *lby = wp->yLabels;
|
|
|
|
if (! toggledData) {
|
|
toggledData = g_new0 (ToggledData, 1);
|
|
}
|
|
toggledData->wp = wp;
|
|
|
|
dialog = gtk_dialog_new_with_buttons (_("Gaw axis settings"),
|
|
GTK_WINDOW (ud->window),
|
|
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
|
_("_Cancel"),
|
|
GTK_RESPONSE_REJECT,
|
|
_("_OK"),
|
|
GTK_RESPONSE_ACCEPT,
|
|
NULL);
|
|
vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
|
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
|
|
|
|
/* frame Global X Axis */
|
|
frame = gtk_frame_new ( _("Global X Axis"));
|
|
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
|
|
x_table = gtk_grid_new ();
|
|
gtk_grid_set_column_spacing( GTK_GRID(x_table), 5);
|
|
gtk_grid_set_row_spacing( GTK_GRID (x_table), 2);
|
|
gtk_container_add (GTK_CONTAINER (frame), x_table);
|
|
|
|
/* frame Panel Y Axis */
|
|
frame = gtk_frame_new (_("Panel Y Axis"));
|
|
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
|
|
y_table = gtk_grid_new ();
|
|
gtk_grid_set_column_spacing( GTK_GRID(y_table), 5);
|
|
gtk_grid_set_row_spacing( GTK_GRID (y_table), 2);
|
|
gtk_container_add (GTK_CONTAINER (frame), y_table);
|
|
|
|
str = _("min");
|
|
label = gtk_label_new( str );
|
|
gtk_grid_attach(GTK_GRID(x_table), label,
|
|
/* left, top, width, height */
|
|
1, 0, 1, 1 );
|
|
label = gtk_label_new( str );
|
|
gtk_grid_attach(GTK_GRID(y_table), label,
|
|
/* left, top, width, height */
|
|
1, 0, 1, 1 );
|
|
|
|
str = _("max");
|
|
label = gtk_label_new( str );
|
|
gtk_grid_attach(GTK_GRID(x_table), label,
|
|
/* left, top, width, height */
|
|
2, 0, 1, 1 );
|
|
label = gtk_label_new( str );
|
|
gtk_grid_attach(GTK_GRID(y_table), label,
|
|
/* left, top, width, height */
|
|
2, 0, 1, 1 );
|
|
|
|
str = _("Current");
|
|
label = gtk_label_new( str );
|
|
gtk_grid_attach(GTK_GRID(x_table), label,
|
|
/* left, top, width, height */
|
|
0, 2, 1, 1 );
|
|
label = gtk_label_new( str );
|
|
gtk_grid_attach(GTK_GRID(y_table), label,
|
|
/* left, top, width, height */
|
|
0, 2, 1, 1 );
|
|
|
|
str = _("New:");
|
|
label = gtk_label_new( str );
|
|
gtk_grid_attach(GTK_GRID(x_table), label,
|
|
/* left, top, width, height */
|
|
0, 3, 1, 1 );
|
|
label = gtk_label_new( str );
|
|
gtk_grid_attach(GTK_GRID(y_table), label,
|
|
/* left, top, width, height */
|
|
0, 3, 1, 1 );
|
|
|
|
/* X values */
|
|
str = val2str(lbx->min_val, ud->up->scientific);
|
|
label = gtk_label_new( str );
|
|
gtk_grid_attach(GTK_GRID(x_table), label,
|
|
/* left, top, width, height */
|
|
1, 1, 1, 1 );
|
|
str = val2str(lbx->max_val, ud->up->scientific);
|
|
label = gtk_label_new( str );
|
|
gtk_grid_attach(GTK_GRID(x_table), label,
|
|
/* left, top, width, height */
|
|
2, 1, 1, 1 );
|
|
|
|
str = val2str(lbx->start_val, ud->up->scientific);
|
|
label = gtk_label_new( str );
|
|
gtk_grid_attach(GTK_GRID(x_table), label,
|
|
/* left, top, width, height */
|
|
1, 2, 1, 1 );
|
|
str = val2str(lbx->end_val, ud->up->scientific);
|
|
label = gtk_label_new( str );
|
|
gtk_grid_attach(GTK_GRID(x_table), label,
|
|
/* left, top, width, height */
|
|
2, 2, 1, 1 );
|
|
|
|
/* Y values */
|
|
str = val2str(lby->min_val, ud->up->scientific);
|
|
label = gtk_label_new( str );
|
|
gtk_grid_attach(GTK_GRID(y_table), label,
|
|
/* left, top, width, height */
|
|
1, 1, 1, 1 );
|
|
str = val2str(lby->max_val, ud->up->scientific);
|
|
label = gtk_label_new( str );
|
|
gtk_grid_attach(GTK_GRID(y_table), label,
|
|
/* left, top, width, height */
|
|
2, 1, 1, 1 );
|
|
|
|
str = val2str(lby->start_val, ud->up->scientific);
|
|
label = gtk_label_new( str );
|
|
gtk_grid_attach(GTK_GRID(y_table), label,
|
|
/* left, top, width, height */
|
|
1, 2, 1, 1 );
|
|
str = val2str(lby->end_val, ud->up->scientific);
|
|
label = gtk_label_new( str );
|
|
gtk_grid_attach(GTK_GRID(y_table), label,
|
|
/* left, top, width, height */
|
|
2, 2, 1, 1 );
|
|
|
|
/* new X values in entry */
|
|
str = val2str(lbx->start_val, ud->up->scientific);
|
|
entry = gtk_entry_new() ;
|
|
gtk_entry_set_text (GTK_ENTRY (entry), str);
|
|
g_signal_connect (entry, "changed",
|
|
G_CALLBACK (az_entry_changed_cb),
|
|
( gpointer) &lbx->start_val);
|
|
gtk_grid_attach(GTK_GRID(x_table), entry,
|
|
/* left, top, width, height */
|
|
1, 3, 1, 1 );
|
|
str = val2str(lbx->end_val, ud->up->scientific);
|
|
entry = gtk_entry_new() ;
|
|
gtk_entry_set_text (GTK_ENTRY (entry), str);
|
|
g_signal_connect (entry, "changed",
|
|
G_CALLBACK (az_entry_changed_cb),
|
|
( gpointer) &lbx->end_val);
|
|
gtk_grid_attach(GTK_GRID(x_table), entry,
|
|
/* left, top, width, height */
|
|
2, 3, 1, 1 );
|
|
|
|
/* new Y values in entry */
|
|
str = val2str(lby->start_val, ud->up->scientific);
|
|
entry = gtk_entry_new() ;
|
|
toggledData->entry_ys = entry;
|
|
gtk_entry_set_text (GTK_ENTRY (entry), str);
|
|
g_signal_connect (entry, "changed",
|
|
G_CALLBACK (az_entry_changed_cb),
|
|
( gpointer) &lby->start_val);
|
|
gtk_grid_attach(GTK_GRID(y_table), entry,
|
|
/* left, top, width, height */
|
|
1, 3, 1, 1 );
|
|
gtk_widget_set_sensitive (entry, wp->man_yzoom);
|
|
str = val2str(lby->end_val, ud->up->scientific);
|
|
entry = gtk_entry_new() ;
|
|
toggledData->entry_ye = entry;
|
|
gtk_entry_set_text (GTK_ENTRY (entry), str);
|
|
g_signal_connect (entry, "changed",
|
|
G_CALLBACK (az_entry_changed_cb),
|
|
( gpointer) &lby->end_val);
|
|
gtk_grid_attach(GTK_GRID(y_table), entry,
|
|
/* left, top, width, height */
|
|
2, 3, 1, 1 );
|
|
gtk_widget_set_sensitive (entry, wp->man_yzoom);
|
|
|
|
/* Full Scale button */
|
|
str = _("Zoom to");
|
|
button = gtk_toggle_button_new_with_label (str) ;
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button), wp->man_yzoom);
|
|
g_signal_connect (button, "toggled",
|
|
G_CALLBACK (az_button_toggled_cb),
|
|
( gpointer) toggledData );
|
|
gtk_grid_attach(GTK_GRID(y_table), button,
|
|
/* left, top, width, height */
|
|
0, 0, 1, 1 );
|
|
|
|
gtk_widget_show_all (vbox);
|
|
response = gtk_dialog_run (GTK_DIALOG (dialog));
|
|
|
|
if (response == GTK_RESPONSE_ACCEPT) {
|
|
msg_dbg(_("dialog OK"));
|
|
az_cmd_zoom_absolute(ud, lbx->start_val, lbx->end_val );
|
|
ap_all_redraw(ud);
|
|
} else {
|
|
pa_panel_set_yvals( wp, lby->min_val, lby->max_val);
|
|
wp->man_yzoom = 0;
|
|
}
|
|
|
|
gtk_widget_destroy (dialog);
|
|
}
|
|
|
|
void az_zoom_dialog_gaction (GSimpleAction *action, GVariant *param, gpointer user_data )
|
|
{
|
|
UserData *ud = (UserData *) user_data;
|
|
if ( ud->selected_panel == NULL) {
|
|
msg_info (aw_panel_not_selected_msg);
|
|
return ;
|
|
}
|
|
WavePanel *wp = ud->selected_panel ;
|
|
|
|
az_pop_zoom_dialog_gaction ( action, param, wp);
|
|
}
|