/* * gtk-symmetry.c * * A simple widget to select a symmetry group * * (c) 2006-2007 Thomas White * * synth2d - Two-Dimensional Crystallographic Fourier Synthesis * */ #include #include "gtk-symmetry.h" static GtkObjectClass *parent_class = NULL; static void gtk_symmetry_destroy(GtkObject *gtk_symmetry) { parent_class->destroy(gtk_symmetry); } static gint gtk_symmetry_changed(GtkWidget *selection, GtkSymmetry *gtk_symmetry) { g_signal_emit_by_name(G_OBJECT(gtk_symmetry), "changed"); return 0; } static gint gtk_symmetry_do_packing(GtkWidget *widget, GtkObject *old_parent, GtkSymmetry *gtk_symmetry) { if ( gtk_symmetry->has_friedel ) { if ( gtk_symmetry->friedel_pos == GTK_POS_RIGHT ) { gtk_symmetry->table = gtk_table_new(1, 3, FALSE); } else { gtk_symmetry->table = gtk_table_new(2, 2, FALSE); } } else { gtk_symmetry->table = gtk_table_new(1, 2, FALSE); } gtk_table_set_row_spacings(GTK_TABLE(gtk_symmetry->table), 5); gtk_table_set_col_spacings(GTK_TABLE(gtk_symmetry->table), 5); gtk_symmetry->label = gtk_label_new("Planegroup:"); gtk_misc_set_alignment(GTK_MISC(gtk_symmetry->label), 1, 0.5); gtk_table_attach_defaults(GTK_TABLE(gtk_symmetry->table), GTK_WIDGET(gtk_symmetry->label), 1, 2, 1, 2); gtk_symmetry->selection = gtk_combo_box_new_text(); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "p1"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "p2"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "pm (m // x)"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "pm (m // y)"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "pg (g // x)"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "pg (g // y)"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "cm (m // x)"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "cm (m // y)"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "p2mm"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "p2mg (m // x)"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "p2mg (m // y)"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "p2gg"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "c2mm"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "p4"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "p4mm"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "p4gm"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "p3"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "p3m1"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "p31m"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "p6"); gtk_combo_box_append_text(GTK_COMBO_BOX(gtk_symmetry->selection), "p6mm"); gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_symmetry->selection), 0); gtk_table_attach_defaults(GTK_TABLE(gtk_symmetry->table), GTK_WIDGET(gtk_symmetry->selection), 2, 3, 1, 2); g_signal_connect(G_OBJECT(gtk_symmetry->selection), "changed", G_CALLBACK(gtk_symmetry_changed), gtk_symmetry); gtk_symmetry->friedel = gtk_check_button_new_with_label("Friedel"); if ( gtk_symmetry->has_friedel ) { if ( gtk_symmetry->friedel_pos == GTK_POS_RIGHT ) { gtk_table_attach_defaults(GTK_TABLE(gtk_symmetry->table), gtk_symmetry->friedel, 3, 4, 1, 2); } else { gtk_table_attach_defaults(GTK_TABLE(gtk_symmetry->table), gtk_symmetry->friedel, 2, 3, 2, 3); } } g_signal_connect(G_OBJECT(gtk_symmetry->friedel), "toggled", G_CALLBACK(gtk_symmetry_changed), gtk_symmetry); gtk_box_pack_start(GTK_BOX(gtk_symmetry), GTK_WIDGET(gtk_symmetry->table), TRUE, TRUE, 5); return 0; } GtkWidget *gtk_symmetry_new(unsigned int dimensions, unsigned int trans_dimensions, gboolean has_friedel) { GtkSymmetry *gtk_symmetry; g_return_val_if_fail(dimensions >= trans_dimensions, NULL); g_return_val_if_fail(dimensions < 4, NULL); g_return_val_if_fail(dimensions < 4, NULL); gtk_symmetry = GTK_SYMMETRY(gtk_type_new(gtk_symmetry_get_type())); gtk_symmetry->dimensions = dimensions; gtk_symmetry->trans_dimensions = trans_dimensions; gtk_symmetry->has_friedel = has_friedel; gtk_symmetry->friedel_pos = GTK_POS_BOTTOM; g_signal_connect(G_OBJECT(gtk_symmetry), "parent-set", G_CALLBACK(gtk_symmetry_do_packing), gtk_symmetry); return GTK_WIDGET(gtk_symmetry); } static GObject *gtk_symmetry_constructor(GType type, guint n_construct_properties, GObjectConstructParam *construct_properties) { GtkSymmetryClass *class; GObjectClass *p_class; GObject *obj; class = GTK_SYMMETRY_CLASS(g_type_class_peek(gtk_symmetry_get_type())); p_class = G_OBJECT_CLASS(g_type_class_peek_parent(class)); obj = p_class->constructor(type, n_construct_properties, construct_properties); return obj; } static void gtk_symmetry_class_init(GtkSymmetryClass *class) { GtkObjectClass *object_class; GObjectClass *g_object_class; object_class = (GtkObjectClass *) class; g_object_class = G_OBJECT_CLASS(class); object_class->destroy = gtk_symmetry_destroy; g_object_class->constructor = gtk_symmetry_constructor; parent_class = gtk_type_class(gtk_hbox_get_type()); g_signal_new("changed", gtk_symmetry_get_type(), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, G_STRUCT_OFFSET(GtkSymmetryClass, changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } Symmetry gtk_symmetry_get_symmetry(GtkSymmetry *gtk_symmetry) { Symmetry symmetry = PLANEGROUP_P1; g_return_val_if_fail(GTK_IS_SYMMETRY(gtk_symmetry), symmetry); switch ( gtk_combo_box_get_active(GTK_COMBO_BOX(GTK_SYMMETRY(gtk_symmetry)->selection)) ) { case 0 : symmetry = PLANEGROUP_P1; break; case 1 : symmetry = PLANEGROUP_P2; break; case 2 : symmetry = PLANEGROUP_PM_X; break; case 3 : symmetry = PLANEGROUP_PM_Y; break; case 4 : symmetry = PLANEGROUP_PG_X; break; case 5 : symmetry = PLANEGROUP_PG_Y; break; case 6 : symmetry = PLANEGROUP_CM_X; break; case 7 : symmetry = PLANEGROUP_CM_Y; break; case 8 : symmetry = PLANEGROUP_P2MM; break; case 9 : symmetry = PLANEGROUP_P2MG_X; break; case 10 : symmetry = PLANEGROUP_P2MG_Y; break; case 11 : symmetry = PLANEGROUP_P2GG; break; case 12 : symmetry = PLANEGROUP_C2MM; break; case 13 : symmetry = PLANEGROUP_P4; break; case 14 : symmetry = PLANEGROUP_P4MM; break; case 15 : symmetry = PLANEGROUP_P4GM; break; case 16 : symmetry = PLANEGROUP_P3; break; case 17 : symmetry = PLANEGROUP_P3M1; break; case 18 : symmetry = PLANEGROUP_P31M; break; case 19 : symmetry = PLANEGROUP_P6; break; case 20 : symmetry = PLANEGROUP_P6MM; break; } if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(GTK_SYMMETRY(gtk_symmetry)->friedel)) ) { symmetry = symmetry | SYMMETRY_FRIEDEL; } return symmetry; } Symmetry gtk_symmetry_set_symmetry(GtkSymmetry *symmetry, Symmetry new_sym) { Symmetry old_sym; gint idx = 0; old_sym = gtk_symmetry_get_symmetry(symmetry); if ( new_sym == PLANEGROUP_P1 ) idx = 0; if ( new_sym == PLANEGROUP_P2 ) idx = 1; if ( new_sym == PLANEGROUP_PM_X ) idx = 2; if ( new_sym == PLANEGROUP_PM_Y ) idx = 3; if ( new_sym == PLANEGROUP_PG_X ) idx = 4; if ( new_sym == PLANEGROUP_PG_Y ) idx = 5; if ( new_sym == PLANEGROUP_CM_X ) idx = 6; if ( new_sym == PLANEGROUP_CM_Y ) idx = 7; if ( new_sym == PLANEGROUP_P2MM ) idx = 8; if ( new_sym == PLANEGROUP_P2MG_X ) idx = 9; if ( new_sym == PLANEGROUP_P2MG_Y ) idx = 10; if ( new_sym == PLANEGROUP_P2GG ) idx = 11; if ( new_sym == PLANEGROUP_C2MM ) idx = 12; if ( new_sym == PLANEGROUP_P4 ) idx = 13; if ( new_sym == PLANEGROUP_P4MM ) idx = 14; if ( new_sym == PLANEGROUP_P4GM ) idx = 15; if ( new_sym == PLANEGROUP_P3 ) idx = 16; if ( new_sym == PLANEGROUP_P3M1 ) idx = 17; if ( new_sym == PLANEGROUP_P31M ) idx = 18; if ( new_sym == PLANEGROUP_P6 ) idx = 19; if ( new_sym ==PLANEGROUP_P6MM ) idx = 20; gtk_combo_box_set_active(GTK_COMBO_BOX(GTK_SYMMETRY(symmetry)->selection), idx); return old_sym; } static void gtk_symmetry_init(GtkSymmetry *gtk_symmetry) { } guint gtk_symmetry_get_type(void) { static guint gtk_symmetry_type = 0; if ( !gtk_symmetry_type ) { GtkTypeInfo gtk_symmetry_info = { "GtkSymmetry", sizeof(GtkSymmetry), sizeof(GtkSymmetryClass), (GtkClassInitFunc) gtk_symmetry_class_init, (GtkObjectInitFunc) gtk_symmetry_init, NULL, NULL, (GtkClassInitFunc) NULL, }; gtk_symmetry_type = gtk_type_unique(gtk_hbox_get_type(), >k_symmetry_info); } return gtk_symmetry_type; }