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

gamgi_gtk_direction_modify.c

/*********************************************************
 *
 * $GAMGI/src/gtk/direction/gamgi_gtk_direction_modify.c
 *
 * Copyright (C) 2006 Carlos Pereira
 *
 * Distributed under the terms of the GNU
 * General Public License: $GAMGI/LICENSE
 *
 */

#include "gamgi_engine.h"
#include "gamgi_gtk.h"
#include "gamgi_mesa.h"
#include "gamgi_math.h"
#include "gamgi_chem.h"
#include "gamgi_phys.h"
#include "gamgi_io.h"
#include "gamgi_global.h"

#include "gamgi_engine_create.h"
#include "gamgi_engine_start.h"
#include "gamgi_engine_remove.h"
#include "gamgi_engine_find.h"
#include "gamgi_engine_list.h"
#include "gamgi_engine_dlist.h"
#include "gamgi_engine_link.h"
#include "gamgi_engine_unlink.h"
#include "gamgi_engine_reparent.h"
#include "gamgi_gtk_dialog.h"
#include "gamgi_gtk_object.h"
#include "gamgi_gtk_history.h"
#include "gamgi_gtk_object.h"
#include "gamgi_gtk_cell_symmetry.h"
#include "gamgi_gtk_direction_modify.h"
#include "gamgi_gtk_direction_range.h"
#include "gamgi_mesa_select.h"
#include "gamgi_math_vector.h"
#include "gamgi_math_matrix.h"
#include "gamgi_math_euler.h"
#include "gamgi_math_node.h"
#include "gamgi_math_position.h"
#include "gamgi_phys_projection.h"
#include "gamgi_phys_direction.h"
#include "gamgi_io_token.h"

static gamgi_bool static_scan (gamgi_direction *direction, gamgi_dlist *start,
double *position, gamgi_atom **atom_reference)
{
gamgi_atom *atom;
gamgi_dlist *dlist;
double x, y, z;

for (dlist = start; dlist != NULL; dlist = dlist->next)
  {
  atom = GAMGI_CAST_ATOM dlist->data;
  x = atom->position[0] - position[0];
  y = atom->position[1] - position[1];
  z = atom->position[2] - position[2];
  if (x*x + y*y +z*z < GAMGI_MATH_TOLERANCE_LENGTH * GAMGI_MATH_TOLERANCE_LENGTH)
    { *atom_reference = atom; return TRUE; }
  }

return FALSE;
}

static gamgi_bool static_find (gamgi_direction *direction,
gamgi_atom **atom1, gamgi_atom **atom2)
{
gamgi_dlist *dlist;
double matrix[9], inverse[9];
double position[3], translate[3];
double euler[3];

/*************************************************
 * get list of atoms not linked to directions or *
 * directions, including the current direction   *
 *************************************************/

dlist = gamgi_engine_dlist_atom_object (direction->object.object, NULL);
dlist = gamgi_phys_direction_filter (dlist);

/*****************************************************
 * get rotation and translation to transform atoms   *
 * back to where they would be if direction rotation *
 * and translation were (0, 0, 0) and (0, 0, 0)      *
 *****************************************************/

gamgi_math_position_direction_rotation_get (direction, euler);
gamgi_math_euler_to_matrix (euler, matrix);
gamgi_math_matrix_inverse (matrix, inverse);

gamgi_math_matrix_vector (inverse, direction->origin, translate);
gamgi_math_position_translation (direction->object.object, position);
gamgi_math_vector_sub (position, translate, translate);

/******************************************************************
 * try to find the original atoms of the reference atoms, where   *
 * direction rotation and translation are (0, 0, 0) and (0, 0, 0) *
 ******************************************************************/

gamgi_math_matrix_vector (inverse, (*atom1)->position, position);
gamgi_math_vector_add (position, translate, position);
if (static_scan (direction, dlist, position, atom1) == FALSE) return FALSE;

gamgi_math_matrix_vector (inverse, (*atom2)->position, position);
gamgi_math_vector_add (position, translate, position);
if (static_scan (direction, dlist, position, atom2) == FALSE) return FALSE;

return TRUE;
}

static void static_remove (gamgi_direction *direction)
{
gamgi_dlist *dlist;

dlist = direction->atom_start;
while (dlist != NULL)
  { gamgi_engine_remove_atom (GAMGI_CAST_ATOM dlist->data);
    dlist = gamgi_engine_dlist_remove_start (dlist); }
direction->atom_start = NULL;
direction->atom_end = NULL;

dlist = direction->orbital_start;
while (dlist != NULL)
  { gamgi_engine_remove_orbital (GAMGI_CAST_ORBITAL dlist->data);
    dlist = gamgi_engine_dlist_remove_start (dlist); }
direction->orbital_start = NULL;
direction->orbital_end = NULL;

dlist = direction->text_start;
while (dlist != NULL)
  { gamgi_engine_remove_text (GAMGI_CAST_TEXT dlist->data);
    dlist = gamgi_engine_dlist_remove_start (dlist); }
direction->text_start = NULL;
direction->text_end = NULL;
}

static GtkWidget *static_atom (GtkWidget *dialog)
{
GtkWidget *entry;
const char *name;

/**********
 * atom 1 *
 **********/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_atom1");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == FALSE) return entry;

/**********
 * atom 2 *
 **********/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_atom2");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == FALSE) return entry;

return NULL;
}

static void static_end_atom (GtkWidget *dialog)
{
GtkWidget *entry;

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_atom1");
gtk_entry_set_text (GTK_ENTRY (entry), "");
entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_atom2");
gtk_entry_set_text (GTK_ENTRY (entry), "");
}

static gamgi_enum static_class (gamgi_window *window)
{
GtkWidget *dialog = window->dialog0;
GtkWidget *entry;
GtkWidget *button;
GtkWidget *combo;
const char *name;
int row;

button = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "button_global");
entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_direction");
name = gtk_entry_get_text (GTK_ENTRY (entry));

/**************************************
 * when the direction entry is active *
 * and empty, look for a direction    *
 **************************************/

if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) == FALSE &&
gamgi_io_token_check (name) == FALSE) return GAMGI_ENGINE_DIRECTION;

/*********************************
 * select which object to select *
 *********************************/

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_reference");
row = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));

if (row == GAMGI_GTK_CELL - 1) return GAMGI_ENGINE_CELL;
if (row == GAMGI_GTK_ATOMS - 1) return GAMGI_ENGINE_ATOM;

/*********************************************
 * this case can only occur when the Global  *
 * button is selected and Reference is Local *
 *********************************************/

return FALSE;
}

static void static_start_cell (gamgi_window *window)
{
GtkWidget *dialog = window->dialog0;
GtkWidget *entry;
GtkWidget *combo;
 
entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_cell");
gtk_entry_set_text (GTK_ENTRY (entry), "");
 
entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_u");
gtk_entry_set_text (GTK_ENTRY (entry), "");
entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_v");
gtk_entry_set_text (GTK_ENTRY (entry), "");
entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_w");
gtk_entry_set_text (GTK_ENTRY (entry), "");

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_vectors");
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), GAMGI_PHYS_CONVENTIONAL - 1);
}

static void static_start_atom (gamgi_window *window)
{
GtkWidget *dialog = window->dialog0;
GtkWidget *entry;

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_atom1");
gtk_entry_set_text (GTK_ENTRY (entry), "");
entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_atom2");
gtk_entry_set_text (GTK_ENTRY (entry), "");
}

static void static_instance (GtkWidget *widget, void *data)
{
gamgi_window *window = GAMGI_CAST_WINDOW data;
GtkWidget *dialog = window->dialog0;
GtkWidget *combo;
GtkWidget *hbox;
GtkWidget *entry;
GtkWidget *label;
int row;

/************************************************************
 * initialize node combo box to Local (before desabling it) *
 ************************************************************/

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_o4");
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 7);

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_o1");
gtk_entry_set_text (GTK_ENTRY (entry), "");
entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_o2");
gtk_entry_set_text (GTK_ENTRY (entry), "");
entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_o3");
gtk_entry_set_text (GTK_ENTRY (entry), "");

/*************************************
 * disable node data in atomic plane *
 *************************************/

label = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "label_node");
hbox = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "hbox_node");

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_reference");
row = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));

if (row == GAMGI_GTK_ATOMS - 1)
  {
  gtk_widget_set_sensitive (label, FALSE);
  gtk_widget_set_sensitive (hbox, FALSE);
  }
else
  {
  gtk_widget_set_sensitive (label, TRUE);
  gtk_widget_set_sensitive (hbox, TRUE);
  }
}

static void static_start_position (gamgi_window *window)
{ 
GtkWidget *dialog = window->dialog0;
GtkWidget *entry;
char token[GAMGI_ENGINE_TOKEN];
  
/***********************
 * start Position page *
 ***********************/
    
entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_x");
sprintf (token, "%.*f", gamgi->gamgi->length, GAMGI_PHYS_CELL_X);
gtk_entry_set_text (GTK_ENTRY (entry), token);
    
entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_y");
sprintf (token, "%.*f", gamgi->gamgi->length, GAMGI_PHYS_CELL_Y);
gtk_entry_set_text (GTK_ENTRY (entry), token);

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_z");
sprintf (token, "%.*f", gamgi->gamgi->length, GAMGI_PHYS_CELL_Z);
gtk_entry_set_text (GTK_ENTRY (entry), token);

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_e1");
sprintf (token, "%.*f", gamgi->gamgi->angle, GAMGI_PHYS_CELL_E1);
gtk_entry_set_text (GTK_ENTRY (entry), token);

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_e2");
sprintf (token, "%.*f", gamgi->gamgi->angle, GAMGI_PHYS_CELL_E2);
gtk_entry_set_text (GTK_ENTRY (entry), token);

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_e3");
sprintf (token, "%.*f", gamgi->gamgi->angle, GAMGI_PHYS_CELL_E3);
gtk_entry_set_text (GTK_ENTRY (entry), token);
}

static void static_autonomy (GtkWidget *widget, void *data)
{
gamgi_window *window = GAMGI_CAST_WINDOW data;
GtkWidget *dialog = window->dialog0;
GtkWidget *vbox;
GtkWidget *entry;
GtkWidget *label;
GtkWidget *combo;
char token[GAMGI_ENGINE_TOKEN];
int row_reference, row_autonomy;

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_reference");
row_reference = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_autonomy");
row_autonomy = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));

/************************
 * enable/disable scale *
 ************************/

vbox = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "vbox_position");

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_scale");
label = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "label_scale");

if (row_autonomy != GAMGI_GTK_ALL - 1 && row_autonomy != GAMGI_GTK_PARTIAL - 1)
  {
  gtk_widget_hide (vbox);

  gtk_entry_set_text (GTK_ENTRY (entry), "");
  if (row_autonomy == GAMGI_GTK_NONE - 1)
    {
    gtk_widget_set_sensitive (entry, FALSE);
    gtk_widget_set_sensitive (label, FALSE);
    }
  else
    {
    gtk_widget_set_sensitive (entry, TRUE);
    gtk_widget_set_sensitive (label, TRUE);
    }
  }
else
  {
   if (GTK_WIDGET_VISIBLE (vbox) == FALSE)
     static_start_position (window);
  gtk_widget_show (vbox);

  gtk_widget_set_sensitive (entry, TRUE);
  gtk_widget_set_sensitive (label, TRUE);
  sprintf (token, "%.*f", GAMGI_MATH_DECIMAL_SCALE, GAMGI_MESA_SCALE);
  gtk_entry_set_text (GTK_ENTRY (entry), token);
  }

/**********************************
 * enable/disable thickness entry *
 **********************************/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_thickness");
label = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "label_thickness");

if (row_autonomy == GAMGI_GTK_ALL - 1 || row_autonomy == GAMGI_GTK_PARTIAL - 1 ||
(row_reference == GAMGI_GTK_ATOMS - 1 && row_autonomy ==  GAMGI_GTK_NONE - 1))
  {
  gtk_widget_set_sensitive (entry, TRUE);
  gtk_widget_set_sensitive (label, TRUE);
  sprintf (token, "%.*f", GAMGI_MATH_DECIMAL_LENGTH,
  GAMGI_CHEM_DIRECTION_THICKNESS);
  gtk_entry_set_text (GTK_ENTRY (entry), token);
  }
else
  {
  gtk_entry_set_text (GTK_ENTRY (entry), "");
  if (row_reference == GAMGI_GTK_CELL - 1 && row_autonomy == GAMGI_GTK_NONE - 1)
    {
    gtk_widget_set_sensitive (entry, FALSE);
    gtk_widget_set_sensitive (label, FALSE);
    }
  else
    {
    gtk_widget_set_sensitive (entry, TRUE);
    gtk_widget_set_sensitive (label, TRUE);
    }
  }

}

static void static_reference (GtkWidget *widget, void *data)
{
gamgi_window *window = GAMGI_CAST_WINDOW data;
GtkWidget *dialog = window->dialog0;
GtkWidget *vbox_cell, *vbox_atom;
GtkWidget *combo;
int row;

vbox_cell = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "vbox_cell");
vbox_atom = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "vbox_atom");

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_reference");
row = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));

if (row == GAMGI_GTK_ATOMS - 1)
  {
  gtk_widget_hide (vbox_cell);
  gtk_widget_show (vbox_atom);
  static_start_atom (window);
  }
else
  {
  gtk_widget_hide (vbox_atom);
  gtk_widget_show (vbox_cell);
  static_start_cell (window);
  }

/**************************
 * Set combo box to Local *
 **************************/

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_autonomy");
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 3);
static_autonomy (NULL, window);

static_instance (NULL, window);
}

static void static_start_line (gamgi_window *window)
{
GtkWidget *dialog = window->dialog0;
GtkWidget *entry_o1, *entry_o2, *entry_o3;
GtkWidget *combo;
char token[GAMGI_ENGINE_TOKEN];

/************************************************************
 * when the previous cell was a projection, initialize with *
 * the same defaults used in gamgi_gtk_direction_create     *
 ************************************************************/

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_autonomy");
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), GAMGI_GTK_NONE - 1);
static_autonomy (NULL, window);

static_instance (NULL, window);

entry_o1 = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_o1");
entry_o2 = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_o2");
entry_o3 = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_o3");
sprintf (token, "%d", GAMGI_PHYS_DIRECTION_NODE_O1);
gtk_entry_set_text (GTK_ENTRY (entry_o1), token);
sprintf (token, "%d", GAMGI_PHYS_DIRECTION_NODE_O2);
gtk_entry_set_text (GTK_ENTRY (entry_o2), token);
sprintf (token, "%d", GAMGI_PHYS_DIRECTION_NODE_O3);
gtk_entry_set_text (GTK_ENTRY (entry_o3), token);

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_o4");
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), FALSE);
}

static void static_start_projection (gamgi_window *window)
{
GtkWidget *dialog = window->dialog0;
GtkWidget *entry;
GtkWidget *label;
GtkWidget *combo;

/******************************************************
 * default for projection and type combo boxes: Local *
 ******************************************************/

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_projection");
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 2);

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_type");
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 2);

/*****************
 * disable scale *
 *****************/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_scale");
label = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "label_scale");

gtk_widget_set_sensitive (entry, FALSE);
gtk_widget_set_sensitive (label, FALSE);

/********************
 * disable autonomy *
 ********************/

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_autonomy");
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), GAMGI_GTK_NONE - 1);
}

static void static_nodes (gamgi_cell *cell, gamgi_window *window)
{
GtkWidget *dialog = window->dialog0;
GtkWidget *combo;
int lattice, vectors;
int row;

/********************
 * get cell lattice *
 ********************/

if (cell == NULL) lattice = 0;
else lattice = cell->lattice;

/********************
 * get cell vectors *
 ********************/

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_vectors");
row = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));

if (row == GAMGI_PHYS_PRIMITIVE - 1) vectors = GAMGI_PHYS_PRIMITIVE;
else vectors = GAMGI_PHYS_CONVENTIONAL;

/****************
 * handle nodes *
 ****************/

gamgi_gtk_cell_symmetry_nodes (lattice, vectors, dialog);
}

static void static_cell (GtkWidget *widget, void *data)
{
gamgi_window *window = GAMGI_CAST_WINDOW data;
gamgi_cell *cell;
GtkWidget *dialog = window->dialog0;
GtkWidget *vbox_line, *vbox_projection;

vbox_line = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "vbox_line");
vbox_projection = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "vbox_projection");

cell = GAMGI_CAST_CELL gamgi_gtk_object_name_number (dialog,
"entry_cell", GAMGI_ENGINE_CELL, window);
if (cell != NULL && cell->type == GAMGI_PHYS_PROJECTION)
  {
  if (GTK_WIDGET_VISIBLE (vbox_projection) == FALSE)
    static_start_projection (window);
  gtk_widget_hide (vbox_line);
  gtk_widget_show (vbox_projection);
  }
else
  {
  if (GTK_WIDGET_VISIBLE (vbox_line) == FALSE)
    static_start_line (window);
  gtk_widget_hide (vbox_projection);
  gtk_widget_show (vbox_line);
  }

static_nodes (cell, window);
}

static void static_vectors (GtkWidget *widget, void *data)
{
gamgi_window *window = GAMGI_CAST_WINDOW data;
gamgi_cell *cell;
GtkWidget *dialog = window->dialog0;

cell = GAMGI_CAST_CELL gamgi_gtk_object_name_number (dialog,
"entry_cell", GAMGI_ENGINE_CELL, window);
if (cell != NULL && cell->type != GAMGI_PHYS_PROJECTION)
  static_nodes (cell, window);
}

static void static_reset (gamgi_window *window)
{
GtkWidget *dialog = window->dialog0;
GtkWidget *combo;
GtkWidget *entry;

/************************
 * clean direction name *
 ************************/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_direction");
gtk_entry_set_text (GTK_ENTRY (entry), "");

/************************
 * reset direction data *
 ************************/

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_reference");
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 2);
static_reference (NULL, window);

/****************
 * reset colors *
 ****************/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_red");
gtk_entry_set_text (GTK_ENTRY (entry), "");
entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_green");
gtk_entry_set_text (GTK_ENTRY (entry), "");
entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_blue");
gtk_entry_set_text (GTK_ENTRY (entry), "");
}

/**************** internal function ************
 *                                             *
 *                   STATIC_GLOBAL             *
 *                                             *
 * Makes the direction entry sensitive when    *
 * the local button is pressed and insensitive *
 * when the global button is pressed.          *
 *                                             *
 ***********************************************/

static void static_global (GtkWidget *widget, void *data)
{
gamgi_window *window = GAMGI_CAST_WINDOW data;
GtkWidget *dialog = window->dialog0;
GtkWidget *hbox, *button;

hbox = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "hbox_direction");
button = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "button_global");

if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) == FALSE)
  {
  /*****************************
   * Choose the Plane directly *
   *****************************/

  gtk_widget_set_sensitive (hbox, TRUE);
  }
else
  {
  /********************************************
   * Choose the Cell List previously selected *
   ********************************************/

  gtk_widget_set_sensitive (hbox, FALSE);
  static_reset (window);
  }
}

static gamgi_bool static_ok_cell (gamgi_cell **cell, 
int *uvw, gamgi_enum *vectors, gamgi_window *window)
{
GtkWidget *dialog = window->dialog0;
GtkWidget *entry;
GtkWidget *combo;
const char *name;
int row;

/**********************
 * get reference cell *
 **********************/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_cell");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE)
  *cell = GAMGI_CAST_CELL gamgi_gtk_object_name_number (dialog,
  "entry_cell", GAMGI_ENGINE_CELL, window);
if (*cell == NULL)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid plane cell", window);
  return FALSE;
  }

/*************************
 * Get direction indices *
 *************************/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_u");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_int_scan (name, &uvw[0], -INT_MAX, INT_MAX) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid direction indices", window);
  return FALSE;
  }

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_v");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_int_scan (name, &uvw[1], -INT_MAX, INT_MAX) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid direction indices", window);
  return FALSE;
  }

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_w");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_int_scan (name, &uvw[2], -INT_MAX, INT_MAX) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid direction indices", window);
  return FALSE;
  }

if (gamgi_phys_direction_zero (uvw) == TRUE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid direction indices", window);
  return FALSE;
  }

/*************************
 * get direction vectors *
 *************************/

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_vectors");
row = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));

if (row == GAMGI_PHYS_CONVENTIONAL - 1) *vectors = GAMGI_PHYS_CONVENTIONAL;
if (row == GAMGI_PHYS_PRIMITIVE - 1) *vectors = GAMGI_PHYS_PRIMITIVE;

if (*vectors == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid direction vectors", window);
  return FALSE;
  }

return TRUE;
}

static gamgi_bool static_ok_atoms (gamgi_direction *direction,
gamgi_atom **atom1, gamgi_atom **atom2, gamgi_enum *inside, gamgi_window *window)
{
GtkWidget *dialog = window->dialog0;
GtkWidget *entry;
const char *name;
gamgi_bool inside1, inside2;

/************************
 * get reference atom 1 *
 ************************/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_atom1");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE)
  *atom1 = GAMGI_CAST_ATOM gamgi_gtk_object_name_number (dialog,
  "entry_atom1", GAMGI_ENGINE_ATOM, window);
if (*atom1 == NULL)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid reference atom", window);
  return FALSE;
  }

/************************
 * get reference atom 2 *
 ************************/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_atom2");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE)
  *atom2 = GAMGI_CAST_ATOM gamgi_gtk_object_name_number (dialog,
  "entry_atom2", GAMGI_ENGINE_ATOM, window);
if (*atom2 == NULL)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid reference atom", window);
  return FALSE;
  }

/**************************************************
 * check if atoms already belong to the direction *
 **************************************************/

inside1 = FALSE;
if ((*atom1)->object.object == GAMGI_CAST_OBJECT direction) inside1 = TRUE;
inside2 = FALSE;
if ((*atom2)->object.object == GAMGI_CAST_OBJECT direction) inside2 = TRUE;

*inside = GAMGI_GTK_PARTIAL;
if (inside1 == TRUE && inside2 == TRUE) *inside = GAMGI_GTK_ALL;
if (inside1 == FALSE && inside2 == FALSE) *inside = GAMGI_GTK_NONE;

/*********************************************
 * a direction cannot be modified with atoms *
 * inside and outside, to avoid conflicts    *
 *********************************************/

if (*inside == GAMGI_GTK_PARTIAL)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid atom parents", window);
  return FALSE;
  }

/*************************************************************
 * atoms already belonging to planes, directions cannot be   *
 * used to define new planes, directions, to avoid conflicts *
 *************************************************************/

if (*inside == GAMGI_GTK_NONE &&
gamgi_phys_direction_compatible (*atom1, *atom2) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid atom parents", window);
  return FALSE;
  }

/**************************************
 * atoms must be far enough from each *
 * other to define a proper line      *
 **************************************/

if (gamgi_phys_direction_line (*atom1, *atom2) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid atom parents", window);
  return FALSE;
  }

return TRUE;
}

static gamgi_bool static_ok_line (gamgi_cell *cell, int *uvw, 
gamgi_enum vectors, gamgi_enum *type, gamgi_projection *projection,
gamgi_enum *autonomy, double *thickness, int *node, gamgi_window *window)
{
GtkWidget *dialog = window->dialog0;
GtkWidget *entry;
GtkWidget *combo;
const char *name;
int row;

/****************************
 * this is a line direction *
 ****************************/

*type = GAMGI_PHYS_LINE;

/***********************************************
 * only pole,traces have a projection function *
 ***********************************************/

*projection = NULL;

/*********************
 * get link autonomy *
 *********************/

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_autonomy");
row = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));

if (row == GAMGI_GTK_ALL - 1) *autonomy = GAMGI_GTK_ALL;
if (row == GAMGI_GTK_PARTIAL - 1) *autonomy = GAMGI_GTK_PARTIAL;
if (row == GAMGI_GTK_NONE - 1) *autonomy = GAMGI_GTK_NONE;

/**************************
 * get scanning thickness *
 **************************/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_thickness");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_double_scan (name, thickness,
GAMGI_CHEM_PLANE_THICKNESS, DBL_MAX) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid direction thickness", window);
  return FALSE;
  }

/********************************************
 * return control for atomic directions,    *
 * continue for crystallographic directions *
 ********************************************/

if (cell == NULL) return TRUE;

/**************************************
 * get o1,o2,o3 node coordinates      *
 * (for crystallographic planes only) *
 **************************************/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_o1");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_int_scan (name, &node[0], -INT_MAX, INT_MAX) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid node coordinates", window);
  return FALSE;
  }

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_o2");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_int_scan (name, &node[1], -INT_MAX, INT_MAX) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid node coordinates", window);
  return FALSE;
  }

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_o3");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_int_scan (name, &node[2], -INT_MAX, INT_MAX) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid node coordinates", window);
  return FALSE;
  }

/*******************************************************************
 * if o4 is not Local, get o4 node coordinate (unless the lattice  *
 * is centered and the vectors are conventional, o4 is always 000) *
 *******************************************************************/

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_o4");
row = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
if (row != 7) node[3] = row;

if (gamgi_math_node_check (cell->lattice, node[3]) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid node coordinates", window);
  return FALSE;
  }

return TRUE;
}

static gamgi_bool static_ok_projection (gamgi_projection *projection,
gamgi_enum *type, gamgi_enum *autonomy, gamgi_window *window)
{
GtkWidget *dialog = window->dialog0;
GtkWidget *combo;
int row;

/**********************************************
 * direction cannot move away from projection *
 **********************************************/

*autonomy = GAMGI_GTK_ALL;

/************************************
 * get projection: Wulff or Schmidt *
 ************************************/

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_projection");
row = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));

if (row == GAMGI_PHYS_WULFF - 1) *projection = gamgi_phys_projection_wulff;
if (row == GAMGI_PHYS_SCHMIDT - 1) *projection = gamgi_phys_projection_schmidt;

if (*projection == NULL) *projection = GAMGI_PHYS_CELL_PROJECTION;

/*********************************************
 * get direction representation: pole, trace *
 *********************************************/

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_type");
row = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));

if (row == GAMGI_PHYS_POLE - 1) *type = GAMGI_PHYS_POLE;
if (row == GAMGI_PHYS_TRACE - 1) *type = GAMGI_PHYS_TRACE;

if (*type != GAMGI_PHYS_POLE && *type != GAMGI_PHYS_TRACE)
  *type = GAMGI_PHYS_POLE;

return TRUE;
}

static gamgi_bool static_ok_position (gamgi_enum autonomy,
double *euler, double *origin, gamgi_window *window)
{
GtkWidget *dialog = window->dialog0;
GtkWidget *entry;
const char *name;

if (autonomy == GAMGI_GTK_NONE)
  {
  gamgi_math_vector_zero (origin);
  gamgi_math_vector_zero (euler);
  return TRUE;
  }

/****************************
 * origin x,y,z coordinates *
 ****************************/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_x");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_double_scan (name, &origin[0], -DBL_MAX, DBL_MAX) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid position data", window);
  return FALSE;
  }

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_y");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_double_scan (name, &origin[1], -DBL_MAX, DBL_MAX) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid position data", window);
  return FALSE;
  }

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_z");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_double_scan (name, &origin[2], -DBL_MAX, DBL_MAX) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid position data", window);
  return FALSE;
  }

/*************************
 * e1,e2,e3 euler angles *
 *************************/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_e1");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_double_scan (name, &euler[0], 0.0, 180.0) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid angle data", window);
  return FALSE;
  }

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_e2");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_double_scan (name, &euler[1], 0.0, 360.0) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid angle data", window);
  return FALSE;
  }

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_e3");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_double_scan (name, &euler[2], 0.0, 360.0) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid angle data", window);
  return FALSE;
  }

return TRUE;
}

static gamgi_bool static_ok_view (float *red, float *green,
float *blue, double *scale, gamgi_window *window)
{
GtkWidget *dialog = window->dialog0;
GtkWidget *entry;
const char *name;

/*******
 * red *
 *******/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_red");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_float_scan (name, red, 0.0, 1.0) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid plane color", window);
  return FALSE;
  }

/*********
 * green *
 *********/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_green");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_float_scan (name, green, 0.0, 1.0) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid plane color", window);
  return FALSE;
  }

/********
 * blue *
 ********/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_blue");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_float_scan (name, blue, 0.0, 1.0) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid plane color", window);
  return FALSE;
  }

/*************
 * Get scale *
 *************/

entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_scale");
name = gtk_entry_get_text (GTK_ENTRY (entry));
if (gamgi_io_token_check (name) == TRUE &&
gamgi_io_token_double_scan (name, scale, 
GAMGI_MESA_SCALE_LOWER, GAMGI_MESA_SCALE_UPPER) == FALSE)
  {
  gamgi_gtk_dialog_message_create ("Error", "Invalid direction scale", window);
  return FALSE;
  }

return TRUE;
}

/*************** internal function *****************
 *                                                 *
 *                    STATIC_OK                    *
 *                                                 *
 * This is the function that actually creates      *
 * new directions. It is triggered when the user   *
 * presses Ok or when she/he cliks on the screen,  *
 * to indicate the position of the new directions. *
 *                                                 *
 ***************************************************/

static void static_ok (GtkWidget *widget, void *data)
{
gamgi_window *window = GAMGI_CAST_WINDOW data;
GtkWidget *dialog = window->dialog0;
gamgi_cell *cell;
gamgi_direction *direction;
gamgi_atom *atom1, *atom2;
gamgi_object *parent;
gamgi_dlist *dlist;
gamgi_projection projection;
gamgi_enum vectors;
gamgi_enum reference, autonomy, type;
GtkWidget *button;
GtkWidget *combo;
int hkl1[3], hkl2[3];
int start1, end1;
int start2, end2;
gamgi_enum pole, trace, inside;
gamgi_bool copy;
gamgi_bool valid;
char token[GAMGI_ENGINE_TOKEN];
double euler[3], origin[3], zero[3];
double thickness, scale;
float red, green, blue;
int node[4];
int uvw[3];
int row;

button = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "button_global");
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) == FALSE)
  {
  /****************
   * Local method *
   ****************/

  /**************************************
   * Get name (possibly new) and number *
   **************************************/

  direction = GAMGI_CAST_DIRECTION gamgi_gtk_object_number (dialog,
  "entry_direction", GAMGI_ENGINE_DIRECTION, window, token);
  if (direction == NULL)
    {
    gamgi_gtk_dialog_message_create ("Error", "Invalid direction name", window);
    return;
    }

  /**************************
   * get initial parameters *
   **************************/

  reference = direction->reference;
  uvw[0] = direction->uvw[0];
  uvw[1] = direction->uvw[1];
  uvw[2] = direction->uvw[2];
  vectors = direction->vectors;

  type = direction->type;
  projection = direction->projection;
  autonomy = direction->autonomy;
  thickness = direction->thickness;
  node[0] = direction->node[0];
  node[1] = direction->node[1];
  node[2] = direction->node[2];
  node[3] = direction->node[3];

  red = direction->red;
  green = direction->green;
  blue = direction->blue;
  scale = direction->object.scale;

  /***********************************
   * this unneeded initialization    *
   * avoids a O3 compilation warning *
   ***********************************/

  atom1 = atom2 = NULL; cell = NULL;
  pole = FALSE; trace = FALSE;
  inside = FALSE;

  /********************************
   * get reference: cell or atoms *
   ********************************/

  combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_reference");
  row = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));

  if (row == GAMGI_GTK_CELL - 1) reference = GAMGI_ENGINE_CELL;
  if (row == GAMGI_GTK_ATOMS - 1) reference = GAMGI_ENGINE_ATOM;

  if (reference == GAMGI_ENGINE_CELL)
    {
    /****************************************
     * this is a crystallographic direction *
     ****************************************/

    cell = NULL;
    parent = direction->object.object;
    if (parent->class == GAMGI_ENGINE_CELL)
      cell = GAMGI_CAST_CELL parent;

    valid = static_ok_cell (&cell, uvw, &vectors, window);
    if (valid == FALSE) return;

    if (cell->type == GAMGI_PHYS_PROJECTION)
      {
      valid = static_ok_projection (&projection, &type, &autonomy, window);
      if (valid == FALSE) return;

      if (type == GAMGI_PHYS_POLE) pole = TRUE;
      if (type == GAMGI_PHYS_TRACE) trace = TRUE;
      }
    else
      {
      valid = static_ok_line (cell, uvw, vectors,
      &type, &projection, &autonomy, &thickness, node, window);
      if (valid == FALSE) return;
      }

    }
  else
    {
    /*******************************
     * this is an atomic direction *
     *******************************/
 
    gamgi_phys_direction_reference (direction, &atom1, &atom2);
    valid = static_ok_atoms (direction, &atom1, &atom2, &inside, window);
    if (valid == FALSE) return;

    valid = static_ok_line (NULL, NULL, 0,
    &type, &projection, &autonomy, &thickness, NULL, window);
    if (valid == FALSE) return;
    }

  valid = static_ok_position (autonomy, euler, origin, window);
  if (valid == FALSE) return;

  valid = static_ok_view (&red, &green, &blue, &scale, window);
  if (valid == FALSE) return;

  /***************************************************************************
   * atomic directions with autonomy all can be modified to autonomy partial *
   * or none, as long as reference atoms in the original positions can       *
   * replace those entered by the user, later removed with the direction     *
   ***************************************************************************/

  if (direction->reference == GAMGI_ENGINE_ATOM && reference == GAMGI_ENGINE_ATOM && 
  direction->autonomy == GAMGI_GTK_ALL && autonomy != GAMGI_GTK_ALL && 
  inside == GAMGI_GTK_ALL && static_find (direction, &atom1, &atom2) == FALSE)
    {
    gamgi_gtk_dialog_message_create ("Error", "Invalid atom parents", window);
    return;
    }

  /***************************************
   * Save current layer as undo buffer   *
   * layer so it can be recovered later. *
   ***************************************/

  gamgi_gtk_history_update (window->layer, window->layer->undo, GAMGI_ENGINE_UNDO);

  /*******************
   * reset direction *
   *******************/

  gamgi_math_vector_zero (zero);
  gamgi_math_position_direction_rotation_set (direction, zero);
  gamgi_math_position_direction_translation_set (direction, zero);

  free (direction->points);
  free (direction->loops);
  direction->points = NULL;
  direction->loops = NULL;
  direction->n_points = 0;
  direction->n_loops = 0;

  if (direction->autonomy == GAMGI_GTK_PARTIAL ||
  (direction->autonomy == GAMGI_GTK_NONE &&
  direction->reference == GAMGI_ENGINE_ATOM))
    gamgi_engine_reparent_atom (direction->atom_start, direction->object.object);

  parent = direction->object.object;

  /*****************************************************************
   * Remove the plane initially with autonomy all except when the  *
     same plane is modified. When reference atoms and autonomy ALL *
     are maintained, copy is FALSE because the plane is maintained *
   *****************************************************************/

  copy = (direction->reference != GAMGI_ENGINE_ATOM ||
  reference != GAMGI_ENGINE_ATOM || direction->autonomy != GAMGI_GTK_ALL ||
  autonomy != GAMGI_GTK_ALL || inside != GAMGI_GTK_ALL);

  if (direction->autonomy == GAMGI_GTK_ALL && copy == TRUE)
    {
    /************************************************
     * Before removing the direction, check if the  *
     * current object is afected. In this case, the *
     * current layer becomes the new current object *
     ************************************************/

    if (gamgi_engine_find_object (window->focus,
    GAMGI_CAST_OBJECT direction) == TRUE)
      gamgi_gtk_object_focus_local (GAMGI_CAST_OBJECT window->layer, window);

    static_remove (direction);
    }

  gamgi_engine_unlink_direction (direction);

  /****************************
   * set direction parameters *
   ****************************/

  strcpy (direction->object.name, token);
  direction->reference = reference;
  direction->uvw[0] = uvw[0];
  direction->uvw[1] = uvw[1];
  direction->uvw[2] = uvw[2];
  direction->vectors = vectors;

  direction->type = type;
  direction->projection = projection;
  direction->autonomy = autonomy;
  direction->thickness = thickness;
  direction->node[0] = node[0];
  direction->node[1] = node[1];
  direction->node[2] = node[2];
  direction->node[3] = node[3];

  direction->red = red;
  direction->green = green;
  direction->blue = blue;
  direction->object.scale = scale;

  /*****************************
   * create and link direction *
   *****************************/

  if (direction->reference == GAMGI_ENGINE_CELL)
    {
    /****************************************
     * this is a crystallographic direction *
     ****************************************/

    if (cell->type == GAMGI_PHYS_PROJECTION)
      gamgi_phys_direction_projection (direction, cell, pole, trace);
    else
      {
      if (gamgi_gtk_direction_range_get (cell->lattice, direction->vectors, 
      hkl1, hkl2, &start1, &end1, &start2, &end2) == TRUE)
        gamgi_phys_direction_range (direction, cell, 
        hkl1, start1, end1, hkl2, start2, end2);
      else
        gamgi_phys_direction_node (direction, cell);
      }
    }

  if (direction->reference == GAMGI_ENGINE_ATOM)
    {
    if (copy == TRUE)
      {
      /************************************************************
       * this is an atomic direction: get list of atoms in parent *
       *                                                          *
       *  filter atoms linked to other plane or direction         *
       *                                                          *
       * reorder list so the two defining atoms come first        *
       ************************************************************/

      parent = gamgi_phys_direction_parent (atom1, atom2, window);
      dlist = gamgi_engine_dlist_atom_object (parent, NULL);
      dlist = gamgi_phys_direction_filter (dlist);
      }
    else
      {
      /**********************************************
       * get list of atoms already in the direction *
       **********************************************/

      dlist = gamgi_engine_dlist_atom_direction (direction, NULL);
      }

    /**********************************************************
     * reset and build direction line AFTER linking to parent *
     **********************************************************/

    dlist = gamgi_phys_direction_reorder (dlist, atom1, atom2);
    gamgi_engine_link_object_object (GAMGI_CAST_OBJECT direction, parent);

    gamgi_math_vector_zero (zero);
    gamgi_math_position_direction_rotation_set (direction, zero);
    gamgi_math_position_direction_translation_set (direction, zero);

    gamgi_phys_direction_atoms (direction, atom1, atom2, dlist, copy);
    }

  gamgi_math_position_direction_rotation_set (direction, euler);
  gamgi_math_position_direction_translation_set (direction, origin);
  }

/************************   
 * Redraw gl_area image *
 ************************/
 
gtk_widget_queue_draw (window->area);
static_reset (window);
}

static void static_init (gamgi_window *window)
{
GtkWidget *dialog = window->dialog0;
GtkWidget *notebook;
GtkRequisition size;
GtkWidget *combo;

/***************************************************
 * Set notebook current size as its minimum size:  *
 * this is needed because pages are shown/hidden,  *
 * changing the currently needed size for dialog.  *
 * Fixing the dialog size only partly solves the   *
 * problem because the page size can still change. *
 ***************************************************/

notebook = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "notebook");
gtk_widget_size_request (GTK_WIDGET (notebook), &size);
gtk_widget_set_size_request (notebook, size.width, size.height);

combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_reference");
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 2);
static_reference (NULL, window);

static_cell (NULL, window);
}

static void static_press (gamgi_object *object, void *data)
{
gamgi_window *window = GAMGI_CAST_WINDOW data;
gamgi_cell *cell;
gamgi_direction *direction;
gamgi_atom *atom;
gamgi_dlist *dlist;
GtkWidget *dialog = window->dialog0;
GtkWidget *entry;
GtkWidget *combo;
char string[2 * GAMGI_ENGINE_TOKEN];
double origin[3], euler[3];
gamgi_enum class;

class = static_class (window);
if (class == GAMGI_ENGINE_DIRECTION)
  {
  /********************************
   * set Direction identification *
   ********************************/

  entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_direction");
  sprintf (string, "%s %d", object->name, object->number);
  gtk_entry_set_text (GTK_ENTRY (entry), string);

  direction = GAMGI_CAST_DIRECTION object;

  combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_reference");
  if (direction->reference == GAMGI_ENGINE_CELL)
    {
    /****************************************
     * This is a crystallographic direction *
     ****************************************/

    gtk_combo_box_set_active (GTK_COMBO_BOX (combo), GAMGI_GTK_CELL - 1);
    static_reference (NULL, window);

    /***************************
     * set Cell identification *
     ***************************/

    cell = GAMGI_CAST_CELL direction->object.object;

    entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_cell");
    sprintf (string, "%s %d", cell->object.name, cell->object.number);
    gtk_entry_set_text (GTK_ENTRY (entry), string);

    /***************************
     * Direction u,v,w indices *
     ***************************/

    entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_u");
    sprintf (string, "%d", direction->uvw[0]);
    gtk_entry_set_text (GTK_ENTRY (entry), string);

    entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_v");
    sprintf (string, "%d", direction->uvw[1]);
    gtk_entry_set_text (GTK_ENTRY (entry), string);

    entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_w");
    sprintf (string, "%d", direction->uvw[2]);
    gtk_entry_set_text (GTK_ENTRY (entry), string);
  
    /*********************
     * Direction vectors *
     *********************/

    combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_vectors");
    gtk_combo_box_set_active (GTK_COMBO_BOX (combo), direction->vectors - 1);

    if (cell->type == GAMGI_PHYS_PROJECTION)
      {
      combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_type");
      if (direction->type == GAMGI_PHYS_POLE)
        gtk_combo_box_set_active (GTK_COMBO_BOX (combo), GAMGI_PHYS_POLE - 1);
      if (direction->type == GAMGI_PHYS_TRACE)
        gtk_combo_box_set_active (GTK_COMBO_BOX (combo), GAMGI_PHYS_TRACE - 1);

      combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_projection");
      if (direction->projection == gamgi_phys_projection_wulff)
        gtk_combo_box_set_active (GTK_COMBO_BOX (combo), GAMGI_PHYS_WULFF - 1);
      if (direction->projection == gamgi_phys_projection_schmidt)
        gtk_combo_box_set_active (GTK_COMBO_BOX (combo), GAMGI_PHYS_SCHMIDT - 1);
      }
    else
      {
      /*************************************
       * set Direction autonomy, thickness *
       *************************************/

      combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_autonomy");
      gtk_combo_box_set_active (GTK_COMBO_BOX (combo), direction->autonomy - 1);
      static_autonomy (NULL, window);

      entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_thickness");
      if (GTK_WIDGET_SENSITIVE (entry) == TRUE)
        {
        sprintf (string, "%.*f", gamgi->gamgi->length, direction->thickness);
        gtk_entry_set_text (GTK_ENTRY (entry), string);
        }

      /*************************************
       * set Direction origin: o1,o2,o3,o4 *
       *************************************/

      entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_o1");
      sprintf (string, "%d", direction->node[0]);
      gtk_entry_set_text (GTK_ENTRY (entry), string);

      entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_o2");
      sprintf (string, "%d", direction->node[1]);
      gtk_entry_set_text (GTK_ENTRY (entry), string);

      entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_o3");
      sprintf (string, "%d", direction->node[2]);
      gtk_entry_set_text (GTK_ENTRY (entry), string);

      combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_o4");
      gtk_combo_box_set_active (GTK_COMBO_BOX (combo), direction->node[3]);
      }
    }
  else if (direction->reference == GAMGI_ENGINE_ATOM)
    {
    /***************************
     * This is an atomic plane *
     ***************************/

    gtk_combo_box_set_active (GTK_COMBO_BOX (combo), GAMGI_GTK_ATOMS - 1);
    static_reference (NULL, window);

    /******************************************
     * set Atoms identification (dlist should *
     * never be NULL: defensive programming)  *
     ******************************************/

    dlist = direction->atom_start;
    if (dlist == NULL) return;
    atom = GAMGI_CAST_ATOM dlist->data;
    entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_atom1");
    sprintf (string, "%s %d", atom->object.name, atom->object.number);
    gtk_entry_set_text (GTK_ENTRY (entry), string);

    dlist = dlist->next;
    if (dlist == NULL) return;
    atom = GAMGI_CAST_ATOM dlist->data;
    entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_atom2");
    sprintf (string, "%s %d", atom->object.name, atom->object.number);
    gtk_entry_set_text (GTK_ENTRY (entry), string);

    /*************************************
     * set Direction autonomy, thickness *
     *************************************/

    combo = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "combo_autonomy");
    gtk_combo_box_set_active (GTK_COMBO_BOX (combo), direction->autonomy - 1);
    static_autonomy (NULL, window);

    entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_thickness");
    sprintf (string, "%f", direction->thickness);
    gtk_entry_set_text (GTK_ENTRY (entry), string);
    }

  /***************************************
   * set Direction orientation, position *
   ***************************************/

  if (direction->autonomy != GAMGI_GTK_NONE)
    {
    gamgi_math_position_direction_translation_get (direction, origin);

    entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_x");
    sprintf (string, "%f", origin[0]);
    gtk_entry_set_text (GTK_ENTRY (entry), string);

    entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_y");
    sprintf (string, "%f", origin[1]);
    gtk_entry_set_text (GTK_ENTRY (entry), string);

    entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_z");
    sprintf (string, "%f", origin[2]);
    gtk_entry_set_text (GTK_ENTRY (entry), string);

    gamgi_math_position_direction_rotation_get (direction, euler);

    entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_e1");
    sprintf (string, "%f", euler[0]);
    gtk_entry_set_text (GTK_ENTRY (entry), string);

    entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_e2");
    sprintf (string, "%f", euler[1]);
    gtk_entry_set_text (GTK_ENTRY (entry), string);

    entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_e3");
    sprintf (string, "%f", euler[2]);
    gtk_entry_set_text (GTK_ENTRY (entry), string);
    }

  /******************************
   * set Direction color, scale *
   ******************************/

  entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_red");
  sprintf (string, "%.*f", GAMGI_MATH_DECIMAL_COLOR, direction->red);
  gtk_entry_set_text (GTK_ENTRY (entry), string);

  entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_green");
  sprintf (string, "%.*f", GAMGI_MATH_DECIMAL_COLOR, direction->green);
  gtk_entry_set_text (GTK_ENTRY (entry), string);

  entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_blue");
  sprintf (string, "%.*f", GAMGI_MATH_DECIMAL_COLOR, direction->blue);
  gtk_entry_set_text (GTK_ENTRY (entry), string);

  entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_scale");
  if (GTK_WIDGET_SENSITIVE (entry) == TRUE)
    {
    sprintf (string, "%.*f", GAMGI_MATH_DECIMAL_SCALE, direction->object.scale);
    gtk_entry_set_text (GTK_ENTRY (entry), string);
    }
  }
else if (class == GAMGI_ENGINE_CELL)
  {
  entry = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "entry_cell");
  sprintf (string, "%s %d", object->name, object->number);
  gtk_entry_set_text (GTK_ENTRY (entry), string);
  }
else if (class == GAMGI_ENGINE_ATOM)
  {
  /***********************
   * get next atom entry *
   ***********************/

  entry = static_atom (dialog);
  if (entry == NULL)
    { static_end_atom (dialog); entry = static_atom (dialog); }
  sprintf (string, "%s %d", object->name, object->number);
  gtk_entry_set_text (GTK_ENTRY (entry), string);
  }
else return;

}

void gamgi_gtk_direction_modify_press (gamgi_window *window_mouse,
int x, int y, gamgi_window *window_dialog)
{
GtkWidget *dialog = window_dialog->dialog0;
GtkWidget *button;

/******************************
 * local mouse selection only *
 ******************************/

button = (GtkWidget *) g_object_get_data (G_OBJECT (dialog), "button_global");
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) == TRUE ||
window_dialog != window_mouse) return;

gamgi_mesa_select_object (window_mouse, x, y,
static_class (window_dialog), TRUE, static_press);
}

/******************** external function *****************
 *                                                      *
 *              GAMGI_GTK_DIRECTION_MODIFY              *
 *                                                      *
 * Creates the dialog window used to modify directions. *
 *                                                      *
 ********************************************************/

void gamgi_gtk_direction_modify (GtkWidget *widget, void *data)
{
gamgi_window *window = GAMGI_CAST_WINDOW data;
GtkWidget *dialog;
GtkWidget *notebook;
GtkWidget *frame;
GtkWidget *table;
GtkWidget *hbox_center, *hbox_left, *hbox_left_left;
GtkWidget *vbox_dialog, *vbox_page, *vbox_frame, *vbox_top, *vbox_top_top;
GtkWidget *entry;
GtkWidget *label;
GtkWidget *button;
GtkWidget *combo;
GtkListStore *store;
GtkCellRenderer *renderer;
GtkTreeIter iter;
gamgi_bool *sensitive;

/******************
 * dialog level 0 *
 ******************/

dialog = gamgi_gtk_dialog_task0_create ("Direction Modify", window);
window->action = GAMGI_GTK_DIRECTION_MODIFY;
gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);

/********************
 * global container *
 ********************/

vbox_dialog = gtk_vbox_new (FALSE, 5);
gtk_container_add (GTK_CONTAINER (dialog), vbox_dialog);
gtk_widget_show (vbox_dialog);

/*********************
 * Direction objects *
 *********************/

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_dialog), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

hbox_left = gtk_hbox_new (FALSE, 10);
gtk_box_pack_start (GTK_BOX (hbox_center), hbox_left, FALSE, FALSE, 0);
gtk_widget_show (hbox_left);

/*********
 * Local *
 *********/

hbox_left_left = gtk_hbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (hbox_left), hbox_left_left, FALSE, FALSE, 0);
g_object_set_data (G_OBJECT (dialog), "hbox_direction", hbox_left_left);
gtk_widget_show (hbox_left_left);

label = gtk_label_new ("Direction");
gtk_box_pack_start (GTK_BOX (hbox_left_left), label, FALSE, FALSE, 0);
gtk_widget_show (label);

entry = gtk_entry_new ();
gtk_box_pack_start (GTK_BOX (hbox_left_left), entry, FALSE, FALSE, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_20);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_20);
g_signal_connect (GTK_OBJECT (entry), "changed",
G_CALLBACK (static_cell), window);
g_object_set_data (G_OBJECT (dialog), "entry_direction", entry);
gtk_widget_show (entry);

/**********
 * Global *
 **********/

button = gtk_toggle_button_new_with_label ("Global");
gtk_box_pack_start (GTK_BOX (hbox_left), button, FALSE, FALSE, 0);
g_signal_connect (GTK_OBJECT (button), "toggled",
G_CALLBACK (static_global), window);
g_object_set_data (G_OBJECT (dialog), "button_global", button);
gtk_widget_show (button);

/************
 * notebook *
 ************/

notebook = gtk_notebook_new ();
gtk_box_pack_start (GTK_BOX (vbox_dialog), notebook, FALSE, FALSE, 0);
gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
g_object_set_data (G_OBJECT (dialog), "notebook", notebook);
gtk_widget_show (notebook);

/*************
 * Type page *
 *************/

vbox_page = gtk_vbox_new (FALSE, 5);
label = gtk_label_new (" Type ");
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox_page, label);
gtk_container_set_border_width (GTK_CONTAINER (vbox_page), 5);
gtk_widget_show (vbox_page);

frame = gtk_frame_new (NULL);
gtk_box_pack_start (GTK_BOX (vbox_page), frame, TRUE, TRUE, 0);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_widget_show (frame);

/********************************************************
 * vbox_frame is not centered, to avoid small shifts    *
 * in the reference position when frame contents change *
 ********************************************************/

vbox_frame = gtk_vbox_new (TRUE, 0);
gtk_container_add (GTK_CONTAINER (frame), vbox_frame);
gtk_container_set_border_width (GTK_CONTAINER (vbox_frame), 5);
gtk_widget_show (vbox_frame);

vbox_top = gtk_vbox_new (FALSE, 10);
gtk_box_pack_start (GTK_BOX (vbox_frame), vbox_top, FALSE, FALSE, 0);
gtk_widget_show (vbox_top);

/********
 * Type *
 ********/

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

hbox_left = gtk_hbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (hbox_center), hbox_left, FALSE, FALSE, 0);
gtk_widget_show (hbox_left);

label = gtk_label_new ("Reference");
gtk_box_pack_start (GTK_BOX (hbox_left), label, FALSE, FALSE, 0);
gtk_widget_show (label);

combo = gtk_combo_box_new ();
gtk_box_pack_start (GTK_BOX (hbox_left), combo, FALSE, FALSE, 0);
g_signal_connect (GTK_OBJECT (combo), "changed",
G_CALLBACK (static_reference), window);
g_object_set_data (G_OBJECT (dialog), "combo_reference", combo);
gtk_widget_show (combo);

store = gtk_list_store_new (1, G_TYPE_STRING);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "Cell", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "Atoms", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "Local", -1);
gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (store));
g_object_unref (store);

renderer = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", 0, NULL);

/********
 * Cell *
 ********/

vbox_top_top = gtk_vbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (vbox_top), vbox_top_top, FALSE, FALSE, 0);
g_object_set_data (G_OBJECT (dialog), "vbox_cell", vbox_top_top);
gtk_widget_show (vbox_top_top);

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top_top), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

table = gtk_table_new (1, 2, FALSE);
gtk_box_pack_start (GTK_BOX (hbox_center), table, FALSE, FALSE, 10);
gtk_widget_show (table);

label = gtk_label_new ("Cell");
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_widget_show (label);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_20);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_20);
g_signal_connect (GTK_OBJECT (entry), "changed",
G_CALLBACK (static_cell), window);
g_object_set_data (G_OBJECT (dialog), "entry_cell", entry);
gtk_widget_show (entry);

/*********************
 * Direction indices *
 *********************/

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top_top), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

hbox_left = gtk_hbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (hbox_center), hbox_left, FALSE, FALSE, 0);
gtk_widget_show (hbox_left);

label = gtk_label_new ("Indices");
gtk_box_pack_start (GTK_BOX (hbox_left), label, FALSE, FALSE, 0);
gtk_widget_show (label);

table = gtk_table_new (1, 6, FALSE);
gtk_box_pack_start (GTK_BOX (hbox_left), table, FALSE, FALSE, 0);
gtk_widget_show (table);

label = gtk_label_new ("U");
gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1, GTK_EXPAND, GTK_FILL, 5, 0);
gtk_widget_show (label);

label = gtk_label_new ("V");
gtk_table_attach (GTK_TABLE (table), label, 4, 5, 0, 1, GTK_EXPAND, GTK_FILL, 5, 0);
gtk_widget_show (label);

label = gtk_label_new ("W");
gtk_table_attach (GTK_TABLE (table), label, 6, 7, 0, 1, GTK_EXPAND, GTK_FILL, 5, 0);
gtk_widget_show (label);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1, GTK_EXPAND, GTK_FILL, 0, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
g_object_set_data (G_OBJECT (dialog), "entry_u", entry);
gtk_widget_show (entry);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 0, 1, GTK_EXPAND, GTK_FILL, 0, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
g_object_set_data (G_OBJECT (dialog), "entry_v", entry);
gtk_widget_show (entry);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 5, 6, 0, 1, GTK_EXPAND, GTK_FILL, 0, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
g_object_set_data (G_OBJECT (dialog), "entry_w", entry);
gtk_widget_show (entry);

/*********************
 * Vectors combo box *
 *********************/

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top_top), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

hbox_left = gtk_hbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (hbox_center), hbox_left, FALSE, FALSE, 0);
gtk_widget_show (hbox_left);

label = gtk_label_new ("Vectors");
gtk_box_pack_start (GTK_BOX (hbox_left), label, FALSE, FALSE, 0);
gtk_widget_show (label);

combo = gtk_combo_box_new ();
gtk_box_pack_start (GTK_BOX (hbox_left), combo, FALSE, FALSE, 0);
g_signal_connect (GTK_OBJECT (combo), "changed",
G_CALLBACK (static_vectors), window);
g_object_set_data (G_OBJECT (dialog), "combo_vectors", combo);
gtk_widget_show (combo);

store = gtk_list_store_new (1, G_TYPE_STRING);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "Conventional", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "Primitive", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "Local", -1);
gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (store));
g_object_unref (store);

renderer = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", 0, NULL);

/*********************
 * Atom-based method *
 *********************/

vbox_top_top = gtk_vbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (vbox_top), vbox_top_top, FALSE, FALSE, 0);
g_object_set_data (G_OBJECT (dialog), "vbox_atom", vbox_top_top);

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top_top), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

table = gtk_table_new (2, 2, FALSE);
gtk_box_pack_start (GTK_BOX (hbox_center), table, FALSE, FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (table), 5);
gtk_widget_show (table);

label = gtk_label_new ("Atom");
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_widget_show (label);

label = gtk_label_new ("Atom");
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 0);
gtk_widget_show (label);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_20);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_20);
g_object_set_data (G_OBJECT (dialog), "entry_atom1", entry);
gtk_widget_show (entry);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 5);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_20);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_20);
g_object_set_data (G_OBJECT (dialog), "entry_atom2", entry);
gtk_widget_show (entry);

/*******************
 * Projection page *
 *******************/

vbox_page = gtk_vbox_new (FALSE, 5);
label = gtk_label_new ("Projection");
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox_page, label);
gtk_container_set_border_width (GTK_CONTAINER (vbox_page), 5);
g_object_set_data (G_OBJECT (dialog), "vbox_projection", vbox_page);
gtk_widget_show (vbox_page);

frame = gtk_frame_new (NULL);
gtk_box_pack_start (GTK_BOX (vbox_page), frame, TRUE, TRUE, 0);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_widget_show (frame);

vbox_frame = gtk_vbox_new (TRUE, 0);
gtk_container_add (GTK_CONTAINER (frame), vbox_frame);
gtk_container_set_border_width (GTK_CONTAINER (vbox_frame), 5);
gtk_widget_show (vbox_frame);

vbox_top = gtk_vbox_new (FALSE, 10);
gtk_box_pack_start (GTK_BOX (vbox_frame), vbox_top, FALSE, FALSE, 0);
gtk_widget_show (vbox_top);

/**************
 * Projection *
 **************/

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

hbox_left = gtk_hbox_new (FALSE, 40);
gtk_box_pack_start (GTK_BOX (hbox_center), hbox_left, FALSE, FALSE, 0);
gtk_widget_show (hbox_left);

/*****************************
 * wulff, schmidt, combo box *
 *****************************/

vbox_top_top = gtk_vbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (hbox_left), vbox_top_top, FALSE, FALSE, 0);
gtk_widget_show (vbox_top_top);

label = gtk_label_new ("Net");
gtk_box_pack_start (GTK_BOX (vbox_top_top), label, FALSE, FALSE, 0);
gtk_widget_show (label);

combo = gtk_combo_box_new ();
gtk_box_pack_start (GTK_BOX (vbox_top_top), combo, FALSE, FALSE, 0);
g_object_set_data (G_OBJECT (dialog), "combo_projection", combo);
gtk_widget_show (combo);

store = gtk_list_store_new (1, G_TYPE_STRING);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "Wulff", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "Schmidt", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "Local", -1);
gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (store));
g_object_unref (store);

renderer = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", 0, NULL);

/**************************
 * pole, trace, combo box *
 **************************/

vbox_top_top = gtk_vbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (hbox_left), vbox_top_top, FALSE, FALSE, 0);
gtk_widget_show (vbox_top_top);

label = gtk_label_new ("Model");
gtk_box_pack_start (GTK_BOX (vbox_top_top), label, FALSE, FALSE, 0);
gtk_widget_show (label);

combo = gtk_combo_box_new ();
gtk_box_pack_start (GTK_BOX (vbox_top_top), combo, FALSE, FALSE, 0);
g_object_set_data (G_OBJECT (dialog), "combo_type", combo);
gtk_widget_show (combo);

store = gtk_list_store_new (1, G_TYPE_STRING);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "Pole", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "Trace", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "Local", -1);
gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (store));
g_object_unref (store);

renderer = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", 0, NULL);

/*************
 * Line page *
 *************/

vbox_page = gtk_vbox_new (FALSE, 5);
label = gtk_label_new (" Line ");
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox_page, label);
gtk_container_set_border_width (GTK_CONTAINER (vbox_page), 5);
g_object_set_data (G_OBJECT (dialog), "vbox_line", vbox_page);
gtk_widget_show (vbox_page);

frame = gtk_frame_new (NULL);
gtk_box_pack_start (GTK_BOX (vbox_page), frame, TRUE, TRUE, 0);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_widget_show (frame);

vbox_frame = gtk_vbox_new (TRUE, 0);
gtk_container_add (GTK_CONTAINER (frame), vbox_frame);
gtk_container_set_border_width (GTK_CONTAINER (vbox_frame), 5);
gtk_widget_show (vbox_frame);

vbox_top = gtk_vbox_new (FALSE, 10);
gtk_box_pack_start (GTK_BOX (vbox_frame), vbox_top, FALSE, FALSE, 0);
gtk_widget_show (vbox_top);

/********
 * Link *
 ********/

vbox_top_top = gtk_vbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (vbox_top), vbox_top_top, FALSE, FALSE, 0);
gtk_widget_show (vbox_top_top);

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top_top), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

hbox_left = gtk_hbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (hbox_center), hbox_left, FALSE, FALSE, 0);
gtk_widget_show (hbox_left);

label = gtk_label_new ("Autonomy");
gtk_box_pack_start (GTK_BOX (hbox_left), label, FALSE, FALSE, 0);
gtk_widget_show (label);

combo = gtk_combo_box_new ();
gtk_box_pack_start (GTK_BOX (hbox_left), combo, FALSE, FALSE, 0);
g_signal_connect (GTK_OBJECT (combo), "changed",
G_CALLBACK (static_autonomy), window);
g_object_set_data (G_OBJECT (dialog), "combo_autonomy", combo);
gtk_widget_show (combo);

store = gtk_list_store_new (1, G_TYPE_STRING);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "All", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "Partial", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "None", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "Local", -1);
gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (store));
g_object_unref (store);

renderer = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", 0, NULL);

/*************
 * Thickness *
 *************/

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top_top), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

hbox_left = gtk_hbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (hbox_center), hbox_left, FALSE, FALSE, 0);
gtk_widget_show (hbox_left);

label = gtk_label_new ("Thickness");
gtk_box_pack_start (GTK_BOX (hbox_left), label, FALSE, FALSE, 0);
g_object_set_data (G_OBJECT (dialog), "label_thickness", label);
gtk_widget_show (label);

entry = gtk_entry_new ();
gtk_box_pack_start (GTK_BOX (hbox_left), entry, FALSE, FALSE, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_7);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_7);
g_object_set_data (G_OBJECT (dialog), "entry_thickness", entry);
gtk_widget_show (entry);

/********
 * Node *
 ********/

vbox_top_top = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top), vbox_top_top, FALSE, FALSE, 0);
gtk_widget_show (vbox_top_top);

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top_top), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

label = gtk_label_new ("Node");
gtk_box_pack_start (GTK_BOX (vbox_top_top), label, FALSE, FALSE, 0);
g_object_set_data (G_OBJECT (dialog), "label_node", label);
gtk_widget_show (label);

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top_top), hbox_center, FALSE, FALSE, 0);
g_object_set_data (G_OBJECT (dialog), "hbox_node", hbox_center);
gtk_widget_show (hbox_center);

table = gtk_table_new (1, 8, FALSE);
gtk_box_pack_start (GTK_BOX (hbox_center), table, FALSE, FALSE, 0);
gtk_widget_show (table);

label = gtk_label_new ("O1");
gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
g_object_set_data (G_OBJECT (dialog), "label_o1", label);
gtk_widget_show (label);

label = gtk_label_new ("O2");
gtk_table_attach (GTK_TABLE (table), label, 3, 4, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
g_object_set_data (G_OBJECT (dialog), "label_o2", label);
gtk_widget_show (label);

label = gtk_label_new ("O3");
gtk_table_attach (GTK_TABLE (table), label, 5, 6, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
g_object_set_data (G_OBJECT (dialog), "label_o3", label);
gtk_widget_show (label);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
g_object_set_data (G_OBJECT (dialog), "entry_o1", entry);
gtk_widget_show (entry);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 2, 3, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
g_object_set_data (G_OBJECT (dialog), "entry_o2", entry);
gtk_widget_show (entry);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 4, 5, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
g_object_set_data (G_OBJECT (dialog), "entry_o3", entry);
gtk_widget_show (entry);

/********************************************************
 * o4 combo box, with code to change sensitive property *
 ********************************************************/

combo = gtk_combo_box_new ();
gtk_table_attach (GTK_TABLE (table), combo, 6, 7, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
g_object_set_data (G_OBJECT (dialog), "combo_o4", combo);
gtk_widget_show (combo);

store = gtk_list_store_new (1, G_TYPE_STRING);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "000", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "011", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "101", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "110", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "111", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "122", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "211", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "Local", -1);
gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (store));
g_object_unref (store);

renderer = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", 0, NULL);

sensitive = gamgi_gtk_dialog_sensitive_create (8);
g_object_set_data (G_OBJECT (dialog), "sensitive_o4", sensitive);
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo),
renderer, gamgi_gtk_dialog_sensitive_scan, sensitive, free);

label = gtk_label_new ("O4");
gtk_table_attach (GTK_TABLE (table), label, 8, 9, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
g_object_set_data (G_OBJECT (dialog), "label_o4", label);
gtk_widget_show (label);

/*****************
 * Position page *
 *****************/

vbox_page = gtk_vbox_new (FALSE, 5);
label = gtk_label_new ("Position");
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox_page, label);
gtk_container_set_border_width (GTK_CONTAINER (vbox_page), 5);
g_object_set_data (G_OBJECT (dialog), "vbox_position", vbox_page);
gtk_widget_show (vbox_page);

frame = gtk_frame_new (NULL);
gtk_box_pack_start (GTK_BOX (vbox_page), frame, TRUE, TRUE, 0);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_widget_show (frame);

vbox_frame = gtk_vbox_new (TRUE, 10);
gtk_container_add (GTK_CONTAINER (frame), vbox_frame);
gtk_container_set_border_width (GTK_CONTAINER (vbox_frame), 5);
gtk_widget_show (vbox_frame);

/**********
 * Origin *
 **********/

vbox_top = gtk_vbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (vbox_frame), vbox_top, FALSE, FALSE, 0);
gtk_widget_show (vbox_top);

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

label = gtk_label_new ("Translation");
gtk_box_pack_start (GTK_BOX (hbox_center), label, FALSE, FALSE, 0);
gtk_widget_show (label);

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

table = gtk_table_new (1, 6, FALSE);
gtk_box_pack_start (GTK_BOX (hbox_center), table, FALSE, FALSE, 5);
gtk_widget_show (table);

label = gtk_label_new ("X");
gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_widget_show (label);

label = gtk_label_new ("Y");
gtk_table_attach (GTK_TABLE (table), label, 3, 4, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_widget_show (label);

label = gtk_label_new ("Z");
gtk_table_attach (GTK_TABLE (table), label, 5, 6, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_widget_show (label);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_7);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_7);
g_object_set_data (G_OBJECT (dialog), "entry_x", entry);
gtk_widget_show (entry);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 2, 3, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_7);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_7);
g_object_set_data (G_OBJECT (dialog), "entry_y", entry);
gtk_widget_show (entry);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 4, 5, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_7);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_7);
g_object_set_data (G_OBJECT (dialog), "entry_z", entry);
gtk_widget_show (entry);

/*********
 * Angle *
 *********/

vbox_top = gtk_vbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (vbox_frame), vbox_top, FALSE, FALSE, 0);
gtk_widget_show (vbox_top);

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

label = gtk_label_new ("Rotation");
gtk_box_pack_start (GTK_BOX (hbox_center), label, FALSE, FALSE, 0);
gtk_widget_show (label);

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

table = gtk_table_new (1, 6, FALSE);
gtk_box_pack_start (GTK_BOX (hbox_center), table, FALSE, FALSE, 5);
gtk_widget_show (table);

label = gtk_label_new ("E1");
gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_widget_show (label);

label = gtk_label_new ("E2");
gtk_table_attach (GTK_TABLE (table), label, 3, 4, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_widget_show (label);

label = gtk_label_new ("E3");
gtk_table_attach (GTK_TABLE (table), label, 5, 6, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_widget_show (label);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_7);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_7);
g_object_set_data (G_OBJECT (dialog), "entry_e1", entry);
gtk_widget_show (entry);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 2, 3, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_7);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_7);
g_object_set_data (G_OBJECT (dialog), "entry_e2", entry);
gtk_widget_show (entry);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 4, 5, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_7);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_7);
g_object_set_data (G_OBJECT (dialog), "entry_e3", entry);
gtk_widget_show (entry);

/*************
 * View page *
 *************/

vbox_page = gtk_vbox_new (FALSE, 5);
label = gtk_label_new (" View ");
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox_page, label);
gtk_container_set_border_width (GTK_CONTAINER (vbox_page), 5);
gtk_widget_show (vbox_page);

frame = gtk_frame_new (NULL);
gtk_box_pack_start (GTK_BOX (vbox_page), frame, TRUE, TRUE, 0);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_widget_show (frame);

vbox_frame = gtk_vbox_new (TRUE, 0);
gtk_container_add (GTK_CONTAINER (frame), vbox_frame);
gtk_container_set_border_width (GTK_CONTAINER (vbox_frame), 5);
gtk_widget_show (vbox_frame);

vbox_top = gtk_vbox_new (FALSE, 20);
gtk_box_pack_start (GTK_BOX (vbox_frame), vbox_top, FALSE, FALSE, 0);
gtk_widget_show (vbox_top);

/*********
 * Color *
 *********/

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

table = gtk_table_new (1, 7, FALSE);
gtk_box_pack_start (GTK_BOX (hbox_center), table, FALSE, FALSE, 0);
gtk_widget_show (table);

label = gtk_label_new ("Color");
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_SHRINK, GTK_FILL, 5, 0);
gtk_widget_show (label);

label = gtk_label_new ("R");
gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1, GTK_EXPAND, GTK_FILL, 5, 0);
gtk_widget_show (label);

label = gtk_label_new ("G");
gtk_table_attach (GTK_TABLE (table), label, 4, 5, 0, 1, GTK_EXPAND, GTK_FILL, 5, 0);
gtk_widget_show (label);

label = gtk_label_new ("B");
gtk_table_attach (GTK_TABLE (table), label, 6, 7, 0, 1, GTK_EXPAND, GTK_FILL, 5, 0);
gtk_widget_show (label);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1, GTK_EXPAND, GTK_FILL, 5, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
g_object_set_data (G_OBJECT (dialog), "entry_red", entry);
gtk_widget_show (entry);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 3, 4, 0, 1, GTK_EXPAND, GTK_FILL, 5, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
g_object_set_data (G_OBJECT (dialog), "entry_green", entry);
gtk_widget_show (entry);

entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 5, 6, 0, 1, GTK_EXPAND, GTK_FILL, 5, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
g_object_set_data (G_OBJECT (dialog), "entry_blue", entry);
gtk_widget_show (entry);

/*********
 * Scale *
 *********/

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_top), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

hbox_left = gtk_hbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (hbox_center), hbox_left, FALSE, FALSE, 0);
gtk_widget_show (hbox_left);

label = gtk_label_new ("Scale");
gtk_box_pack_start (GTK_BOX (hbox_left), label, FALSE, FALSE, 0);
g_object_set_data (G_OBJECT (dialog), "label_scale", label);
gtk_widget_show (label);

entry = gtk_entry_new ();
gtk_box_pack_start (GTK_BOX (hbox_left), entry, FALSE, FALSE, 0);
gtk_entry_set_width_chars (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
gtk_entry_set_max_length (GTK_ENTRY (entry), GAMGI_GTK_CHAR_5);
g_object_set_data (G_OBJECT (dialog), "entry_scale", entry);
gtk_widget_show (entry);

/*********************
 * Ok/Cancel buttons *
 *********************/

hbox_center = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox_dialog), hbox_center, FALSE, FALSE, 0);
gtk_widget_show (hbox_center);

button = gamgi_gtk_dialog_button_create ("Ok", NULL);
gtk_widget_set_size_request (button, GAMGI_GTK_BUTTON_WIDTH, -1);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_box_pack_start (GTK_BOX (hbox_center), button, FALSE, FALSE, 0);
g_signal_connect (GTK_OBJECT (button), "clicked",
G_CALLBACK (static_ok), window);
gtk_widget_show (button);

button = gamgi_gtk_dialog_button_create ("Cancel", "red");
gtk_widget_set_size_request (button, GAMGI_GTK_BUTTON_WIDTH, -1);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_box_pack_start (GTK_BOX (hbox_center), button, FALSE, FALSE, 0);
gtk_widget_grab_focus (button);
g_signal_connect (GTK_OBJECT (button), "clicked",
G_CALLBACK (gamgi_gtk_dialog_task0_remove), window);
gtk_widget_show (button);

static_init (window);
gtk_widget_show (dialog);
}

Generated by  Doxygen 1.6.0   Back to index