Logo Search packages:      
Sourcecode: calcoo version File versions  Download package

b_settings.c

/*
 * Calcoo: b_settings.c
 *
 * creates and operates the settings dialog
 *
 * Copyright (C) 2001, 2002, 2005 Alexei Kaminski
 *
 */

#include <stdio.h>
#include <stdlib.h>

#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>

#include "codes.h"
#include "b_headers.h"
#include "body.h"
#include "aux_headers.h"

#include "pixmaps/main.xpm"

#define INFO_SPACING 10
#define INFO_LINE_SPACING 5
#define BOX_BORDER_WIDTH 5
#define ENTRY_FIELD_LENGTH 2
#define TABLE_X_PADDING 8
#define TABLE_Y_PADDING 5
#define TABLE_BUTTON_Y_PADDING 10
#define WINDOW_PADDING 7

static int rpn_set, rpn_last,
      enter_set, enter_last,
      stack_set, stack_last,
      arc_set, arc_last,
      hyp_set, hyp_last,
      round_last, round_set,
      trunc_last, trunc_set;

static      GtkWidget *arc_check, *hyp_check;
static      GtkWidget *rpn_radio1, *rpn_radio2;
static      GtkWidget *enter_radio1, *enter_radio2;
static      GtkWidget *stack_radio1, *stack_radio2;
static  GtkWidget *round_spinbox, *round_check, *round_label1, *round_label2;
static  GtkWidget *trunc_check;

void apply_new_settings(void);


void toggled_rpn(void);
void toggled_enter_mode(void);
void toggled_stack_mode(void);

void toggled_arc(void);
void toggled_hyp(void);

void pressed_round(void);
void pressed_trunc_zeros(void);
void round_value_changed(void);

void activate_rpn_specific_options(int);
void activate_rounding_mode(int);

void create_two_option_box(GtkWidget **, GtkWidget **,
                     GtkWidget **, GtkWidget **,
                     char *, char *, char *,
                     int, int,
                     void (*)(void),
                     int (*)(void), int *, int *);
void create_checkbox(GtkWidget **, char *,
                void (*)(void),
                 int (*)(void), int *, int *);

void apply_new_settings(void)
{
      if (rpn_set != rpn_last) {
            set_rpn_mode(rpn_set);
            rpn_last = rpn_set;
      }

      if (enter_set != enter_last) {
            set_enter_mode(enter_set);
            enter_last = enter_set;
      }

      if (stack_set != stack_last) {
            set_stack_mode(stack_set);
            stack_last = stack_set;
      }

      if (arc_set != arc_last) {
            set_arc_autorelease(arc_set);
            arc_last = arc_set;
      }

      if (hyp_set != hyp_last) {
            set_hyp_autorelease(hyp_set);
            hyp_last = hyp_set;
      }

      if (round_set != round_last) {
            set_rounding_mode(round_set);
            round_last = round_set;
      }

      if (trunc_set != trunc_last) {
            set_trunc_zeros_mode(trunc_set);
            trunc_last = trunc_set;
      }

      save_settings();
}

void toggled_rpn(void)
{
      rpn_set = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rpn_radio1));
      activate_rpn_specific_options(rpn_set);
}

void activate_rpn_specific_options(int rpn_mode)
{
      gtk_widget_set_sensitive(enter_radio1, rpn_mode);
      gtk_widget_set_sensitive(enter_radio2, rpn_mode);
      gtk_widget_set_sensitive(stack_radio1, rpn_mode);
      gtk_widget_set_sensitive(stack_radio2, rpn_mode);
}

void activate_rounding_mode(int round_mode)
{
      gtk_widget_set_sensitive(round_spinbox, round_mode);
      gtk_widget_set_sensitive(round_label1, round_mode);
      gtk_widget_set_sensitive(round_label2, round_mode);
      gtk_widget_set_sensitive(trunc_check, round_mode);
}

/* Originally, I had functions connected to "clicked" events of the toggle 
 * buttons in the radio groups. It turned out that the signal "clicked" was
 * not sent when the button was clicked by the spacebar rather than by the 
 * mouse (GTK+ bug?). So I have to switch to using the "toggled" signal,
 * which does not have such problems */

void toggled_enter_mode(void)
{
      if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enter_radio1))) 
            enter_set = ENTER_MODE_TRADITIONAL;
      else
            enter_set = ENTER_MODE_HP28;
}

void toggled_stack_mode(void)
{
      if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stack_radio1))) 
            stack_set = STACK_MODE_INFINITE;
      else
            stack_set = STACK_MODE_XYZT;
}

void toggled_arc(void)
{
      arc_set = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(arc_check));
}

void toggled_hyp(void)
{
      hyp_set = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hyp_check));
}

void pressed_round(void)
{
      round_set = gtk_spin_button_get_value_as_int(
            GTK_SPIN_BUTTON(round_spinbox)
            );
      if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(round_check))) {
            activate_rounding_mode(TRUE); 
      } else {
            round_set = -round_set;
            activate_rounding_mode(FALSE);      
      }
}

void round_value_changed(void)
{
      round_set = gtk_spin_button_get_value_as_int(
            GTK_SPIN_BUTTON(round_spinbox)
            );
}

void pressed_trunc_zeros(void)
{
      trunc_set = gtk_toggle_button_get_active(
            GTK_TOGGLE_BUTTON(trunc_check)
            );
}


void create_two_option_box(GtkWidget **option1, GtkWidget **option2,
                     GtkWidget **box, GtkWidget **frame,
                     char *text1, char *text2, char *frame_text,
                     int value1, int value2,
                     void (*function1)(void),
                     int (*default_option1)(void), int *last, int *set
                     )
{
      *option1 = gtk_radio_button_new_with_label(NULL,text1);
      *option2 = gtk_radio_button_new_with_label_from_widget (
                       GTK_RADIO_BUTTON(*option1), text2);
      if ((*default_option1)() == value1) {
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(*option1), 
                                   TRUE);
            *last = value1;
            *set = value1;
      } else {
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(*option2), 
                                   TRUE);
            *last = value2;
            *set = value2;
      }
      g_signal_connect(G_OBJECT (*option1), "toggled",
                     GTK_SIGNAL_FUNC (function1), NULL);

      *box = gtk_vbox_new(TRUE, 0);
      gtk_box_pack_start (GTK_BOX (*box), *option1, TRUE, TRUE, 2);
      gtk_box_pack_start (GTK_BOX (*box), *option2, TRUE, TRUE, 2);
      gtk_container_set_border_width (GTK_CONTAINER(*box), BOX_BORDER_WIDTH);
      *frame = gtk_frame_new (frame_text);
      gtk_frame_set_shadow_type (GTK_FRAME(*frame), GTK_SHADOW_ETCHED_IN);
      gtk_container_add(GTK_CONTAINER(*frame), *box);
}


void create_checkbox(GtkWidget **checkbox, char *text,
                void (*function1)(void),
                int (*enabled)(void), int *last, int *set)
{
      *checkbox = gtk_check_button_new_with_label(text);
      if ((*enabled)()) 
      {
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(*checkbox), 
                                   TRUE);
            *last = TRUE;
            *set = TRUE;
      } else {
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(*checkbox), 
                                   FALSE);
            *last = FALSE;
            *set = FALSE;
      }
      g_signal_connect(G_OBJECT (*checkbox), "toggled",
                     GTK_SIGNAL_FUNC (function1), NULL);
}

void call_settings (void)
{
      static GtkWidget *settings_window = NULL;
      //GdkPixmap *main_pixmap;
      //GdkBitmap *main_mask;

      GtkWidget *close_button;

      GtkWidget *rpn_box, *rpn_frame;
      GtkWidget *enter_box, *enter_frame;
      GtkWidget *stack_box, *stack_frame;
      GtkWidget *archyp_box, *archyp_frame;
      GtkWidget *round_hbox, *round_box, *round_frame;
      GtkAdjustment *round_adjustment; 
      GtkWidget *apply_button;
      GtkWidget *settings_button_box;

      GtkWidget *table, *box1, *box2;

      GtkAccelGroup *settings_accel_group;

      if (settings_window)
            return;
      
/* Main settings window */
      settings_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
      gtk_window_set_title(GTK_WINDOW(settings_window), "Calcoo settings");
      gtk_window_set_resizable(GTK_WINDOW(settings_window),FALSE);
      gtk_container_set_border_width(GTK_CONTAINER(settings_window), 0);
      g_signal_connect(G_OBJECT(settings_window), "destroy",
                     GTK_SIGNAL_FUNC(gtk_widget_destroyed), 
                     &settings_window);

      gtk_widget_realize(settings_window);
      
/* Main settings window icon */
/*
      main_pixmap = gdk_pixmap_create_from_xpm_d ( 
            settings_window->window,
            &main_mask,
            &(body->style)->bg[GTK_STATE_NORMAL],
            (gchar **) main_xpm 
            );

      gdk_window_set_icon (settings_window->window, NULL,  
                       main_pixmap, main_mask);
*/
      gtk_window_set_icon (GTK_WINDOW(settings_window),  
                  gdk_pixbuf_new_from_xpm_data((const char **)main_xpm));

/* Settings */
      create_two_option_box(&rpn_radio1, &rpn_radio2,
                        &rpn_box, &rpn_frame,
                        "RPN", "Algebraic", "Mode",
                        TRUE, FALSE,
                        &toggled_rpn,
                        &get_rpn_mode, &rpn_last, &rpn_set);

      create_two_option_box(&enter_radio1, &enter_radio2,
                        &enter_box, &enter_frame,
                        "Traditional", "HP-28", "RPN Enter",
                        ENTER_MODE_TRADITIONAL, ENTER_MODE_HP28,
                        &toggled_enter_mode,
                        &get_enter_mode, &enter_last, &enter_set);

      create_two_option_box(&stack_radio1, &stack_radio2,
                        &stack_box, &stack_frame,
                        "Infinite", "XYZT", "RPN Stack",
                        STACK_MODE_INFINITE, STACK_MODE_XYZT,
                        &toggled_stack_mode,
                        &get_stack_mode, &stack_last, &stack_set);

/* arc & hyp */
      create_checkbox(&arc_check, "arc button", &toggled_arc,
                  &get_arc_autorelease, &arc_last, &arc_set);
      create_checkbox(&hyp_check, "hyp button", &toggled_hyp,
                  &get_hyp_autorelease, &hyp_last, &hyp_set);
      archyp_box = gtk_vbox_new(TRUE, 0);
      gtk_box_pack_start (GTK_BOX (archyp_box), arc_check, TRUE, TRUE, 2);
      gtk_box_pack_start (GTK_BOX (archyp_box), hyp_check, TRUE, TRUE, 2);
      gtk_container_set_border_width  (GTK_CONTAINER(archyp_box), 
                               BOX_BORDER_WIDTH);
      archyp_frame = gtk_frame_new ("Autorelease");
      gtk_frame_set_shadow_type (GTK_FRAME(archyp_frame), 
                           GTK_SHADOW_ETCHED_IN);
      gtk_container_add(GTK_CONTAINER(archyp_frame), archyp_box);

/* Rounding */
      round_check = gtk_check_button_new_with_label("Round output ");
      round_label1 = gtk_label_new("to ");
      round_last = round_set = get_rounding_mode();
      if (round_set > 0) 
      {
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(round_check), 
                                   TRUE);
      } else {
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(round_check), 
                                   FALSE);
      }
      g_signal_connect(G_OBJECT (round_check), "toggled",
                     GTK_SIGNAL_FUNC (pressed_round), NULL);

      round_adjustment = (GtkAdjustment *)gtk_adjustment_new(abs(round_last),
                                                 1, INPUT_LENGTH,
                                                 1, 1, 1);
      round_spinbox = gtk_spin_button_new (round_adjustment, 1, 0);
      g_signal_connect(G_OBJECT (round_adjustment), "value-changed",
                     GTK_SIGNAL_FUNC (round_value_changed), NULL);

      round_label2 = gtk_label_new("digits");

      round_hbox = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start (GTK_BOX (round_hbox), round_check, 
                      FALSE, FALSE, 0);
      gtk_box_pack_start (GTK_BOX (round_hbox), round_label1, 
                      FALSE, FALSE, 0);
      gtk_box_pack_start (GTK_BOX (round_hbox), round_spinbox, 
                      FALSE, FALSE, 0);
      gtk_box_pack_start (GTK_BOX (round_hbox), round_label2, 
                      FALSE, FALSE, 0);

      create_checkbox(&trunc_check, "Truncate trailing zeros", 
                  &pressed_trunc_zeros,
                  &get_trunc_zeros_mode, &trunc_last, &trunc_set);


      round_box = gtk_vbox_new(FALSE, 0);
      gtk_box_pack_start (GTK_BOX (round_box), round_hbox, 
                      FALSE, FALSE, 2);
      gtk_box_pack_start (GTK_BOX (round_box), trunc_check, 
                      FALSE, FALSE, 0);

      gtk_container_set_border_width  (GTK_CONTAINER(round_box), 
                               BOX_BORDER_WIDTH);
      round_frame = gtk_frame_new ("Rounding");
      gtk_frame_set_shadow_type (GTK_FRAME(round_frame), 
                           GTK_SHADOW_ETCHED_IN);
      gtk_container_add(GTK_CONTAINER(round_frame), round_box);
            

/* Buttons */
      apply_button = gtk_button_new_with_label("Apply");
      g_signal_connect(G_OBJECT (apply_button), "clicked",
                     GTK_SIGNAL_FUNC (apply_new_settings), NULL);

      close_button = gtk_button_new_with_label("Close");
      g_signal_connect_swapped(G_OBJECT(close_button), "clicked",
                          GTK_SIGNAL_FUNC(gtk_widget_destroy),
                          G_OBJECT(settings_window));

      settings_button_box = gtk_hbutton_box_new();
      gtk_button_box_set_layout(GTK_BUTTON_BOX(settings_button_box), 
                          GTK_BUTTONBOX_SPREAD);
      gtk_box_set_spacing(GTK_BOX(settings_button_box), 
                           INFO_SPACING);
      gtk_box_pack_start(GTK_BOX(settings_button_box), apply_button, 
                     FALSE, FALSE, 0);
      gtk_box_pack_start(GTK_BOX(settings_button_box), close_button, 
                     TRUE, TRUE, 0);

      settings_accel_group = gtk_accel_group_new();
      gtk_widget_add_accelerator(close_button, "clicked",
                           settings_accel_group,
                           GDK_Escape, 0, GTK_ACCEL_VISIBLE);
      gtk_window_add_accel_group(GTK_WINDOW(settings_window),
                           settings_accel_group);




/* Settings: packing all together */
      table = gtk_table_new(4/*rows*/, 2/*cols*/, FALSE);

      gtk_table_attach(GTK_TABLE(table), archyp_frame, 0, 1, 0, 1, 
                   GTK_FILL, GTK_FILL, TABLE_X_PADDING, TABLE_Y_PADDING);
      gtk_table_attach(GTK_TABLE(table), rpn_frame, 1, 2, 0, 1, 
                   GTK_FILL, GTK_FILL, TABLE_X_PADDING, TABLE_Y_PADDING);

      gtk_table_attach(GTK_TABLE(table), enter_frame, 0, 1, 1, 2, 
                   GTK_FILL, GTK_FILL, TABLE_X_PADDING, TABLE_Y_PADDING);
      gtk_table_attach(GTK_TABLE(table), stack_frame, 1, 2, 1, 2, 
                   GTK_FILL, GTK_FILL, TABLE_X_PADDING, TABLE_Y_PADDING);

      gtk_table_attach(GTK_TABLE(table), round_frame, 0, 2, 2, 3, 
                   GTK_FILL, GTK_FILL, TABLE_X_PADDING, TABLE_Y_PADDING);

      gtk_table_attach(GTK_TABLE(table), settings_button_box, 0, 2, 3, 4, 
                   GTK_FILL, GTK_FILL, 
                   TABLE_X_PADDING, TABLE_BUTTON_Y_PADDING);

      /* I do not know a better way to get some padding both on the
       * sides and on the top/bottom */
      box1 = gtk_vbox_new (FALSE, 0);
      gtk_box_pack_start(GTK_BOX(box1), table, 
                     FALSE, FALSE, WINDOW_PADDING);
      box2 = gtk_hbox_new (FALSE, 0);
      gtk_box_pack_start(GTK_BOX(box2), box1, 
                     FALSE, FALSE, WINDOW_PADDING);
      gtk_container_add(GTK_CONTAINER(settings_window), box2);

      gtk_widget_show_all(settings_window);
      activate_rpn_specific_options(rpn_set);
      activate_rounding_mode( (round_set > 0) );      
}


Generated by  Doxygen 1.6.0   Back to index