/* Core Wars. * Copyright (C) 1999, 2000 Walter Hofmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include "config.h" #include "main.h" #include "main-gui.h" #include "parser-cw.h" #include "program.h" #include "select.h" #include "execute.h" #include "execute-cw.h" #include "execute-rc.h" #include "statistic.h" #include "pstatistic.h" #include "options.h" #include "tournament.h" #include "dirbrowser.h" #include "preferences.h" GtkWidget *menu_file_start; GtkWidget *menu_file_pause; GtkWidget *menu_file_continue; GtkWidget *menu_file_step; GtkWidget *menu_file_stop; GtkWidget *menu_view_gstatistic; GtkWidget *menu_view_pstatistic; GtkWidget *menu_tournament_start; GtkWidget *menu_tournament_stop; GtkWidget *main_window; GtkWidget *main_vbox; GtkWidget *main_drawing_area; GdkDrawable *main_map; GtkWidget *about_window = NULL; char *itos (int i) { static char s[32]; sprintf (s, "%d", i); return s; } void menu_start_update () { struct program *p; int proceed = FALSE; p = program_list_root; while (p) { if (!p->error && p->load_count && p->language==LANGUAGE) proceed = TRUE; p = p->next; } gtk_widget_set (GTK_WIDGET (menu_file_start), "sensitive", proceed, NULL); gtk_widget_set (GTK_WIDGET (menu_tournament_start), "sensitive", proceed, NULL); } static gint main_configure (GtkWidget *widget, GdkEventConfigure *event) { main_map = widget->window; execute_init (); return FALSE; } static gint main_expose (GtkWidget *widget, GdkEventExpose *event) { int x1,y1,x2,y2; int i; x1 = (event->area.x-1) / 6; y1 = (event->area.y-1) / 6; x2 = (event->area.x+event->area.width-1) / 6; y2 = (event->area.y+event->area.height-1) / 6; for (i=0; iwindow); } /* Start Programs */ static void file_start (GtkWidget *w, gpointer data) { execute_start (); } /* Pause Programs */ static void file_pause (GtkWidget *w, gpointer data) { execute_pause (); } /* Continue Programs */ static void file_continue (GtkWidget *w, gpointer data) { execute_continue (); } /* Single Step Programs */ static void file_step (GtkWidget *w, gpointer data) { if (LANGUAGE==LANGUAGE_CW) cw_execute_step (); else rc_execute_step (); statistic_update (FALSE); } /* Stop Programs */ static void file_stop (GtkWidget *w, gpointer data) { execute_stop (); } /* Game statistic */ static void game_statistic (GtkWidget *w, gpointer data) { statistic_view (); } /* Program statistic */ static void program_statistic (GtkWidget *w, gpointer data) { pstatistic_view (); } /* About */ static void help_about (GtkWidget *w, gpointer data) { GtkWidget *table; GtkWidget *label; GtkWidget *okbutton; if (!about_window) { about_window = gtk_dialog_new (); gtk_signal_connect (GTK_OBJECT (about_window), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroyed), &about_window); gtk_window_set_title (GTK_WINDOW (about_window), "About Core Wars"); table = gtk_table_new (5, 3, FALSE); gtk_table_set_row_spacings (GTK_TABLE (table), 10); gtk_table_set_col_spacings (GTK_TABLE (table), 10); label = gtk_label_new ("Core Wars"); gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 1, 2); gtk_widget_show (label); label = gtk_label_new ("Version " VERSION); gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 2, 3); gtk_widget_show (label); label = gtk_label_new ("Copyright 1999, 2000 Walter Hofmann "); gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 3, 4); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->vbox), table, TRUE, TRUE, 0); gtk_widget_show (table); okbutton = gtk_button_new_with_label( "Ok" ); gtk_signal_connect_object (GTK_OBJECT (okbutton), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (about_window)); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->action_area), okbutton, TRUE, TRUE, 0); gtk_widget_show (okbutton); gtk_window_set_position (GTK_WINDOW (about_window), GTK_WIN_POS_CENTER); gtk_widget_show (about_window); } else gdk_window_raise (about_window->window); } static gint handle_button_press (GtkWidget *widget, GdkEventButton *event) { if (event->button == 1) statistic_select (event->x, event->y); return TRUE; } static gint handle_motion_notify (GtkWidget *widget, GdkEventMotion *event) { int x, y; GdkModifierType state; if (event->is_hint) gdk_window_get_pointer (event->window, &x, &y, &state); else { x = event->x; y = event->y; state = event->state; } if (state & GDK_BUTTON1_MASK) statistic_select (x, y); return TRUE; } void create_drawing_area () { main_drawing_area = gtk_drawing_area_new (); gtk_signal_connect (GTK_OBJECT (main_drawing_area), "expose_event", (GtkSignalFunc) main_expose, NULL); gtk_signal_connect (GTK_OBJECT(main_drawing_area),"configure_event", (GtkSignalFunc) main_configure, NULL); gtk_drawing_area_size (GTK_DRAWING_AREA (main_drawing_area), 6*DIMENSIONX+1, 6*DIMENSIONY+1); gtk_box_pack_start (GTK_BOX (main_vbox), main_drawing_area, FALSE, FALSE, 0); gtk_signal_connect (GTK_OBJECT (main_drawing_area), "motion_notify_event", (GtkSignalFunc) handle_motion_notify, NULL); gtk_signal_connect (GTK_OBJECT (main_drawing_area), "button_press_event", (GtkSignalFunc) handle_button_press, NULL); gtk_widget_set_events (main_drawing_area, GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK); gtk_widget_show (main_drawing_area); } /* This is the GtkItemFactoryEntry structure used to generate new menus. Item 1: The menu path. The letter after the underscore indicates an accelerator key once the menu is open. Item 2: The accelerator key for the entry Item 3: The callback function. Item 4: The callback action. This changes the parameters with which the function is called. The default is 0. Item 5: The item type, used to define what kind of an item it is. Here are the possible values: NULL -> "" "" -> "" "" -> create a title item "<Item>" -> create a simple item "<CheckItem>" -> create a check item "<ToggleItem>" -> create a toggle item "<RadioItem>" -> create a radio item <path> -> path of a radio item to link against "<Separator>" -> create a separator "<Branch>" -> create an item to hold sub items (optional) "<LastBranch>" -> create a right justified branch */ static GtkItemFactoryEntry menu_items[] = { { "/_File", NULL, NULL, 0, "<Branch>" }, { "/File/Load _Directory...", "<control>D", file_loaddirectory, 0, NULL }, { "/File/Select Progra_ms...", "<control>M", file_selectprograms, 0, NULL }, { "/File/_Start", "<control>S", file_start, 0, NULL }, { "/File/_Pause", "<control>A", file_pause, 0, NULL }, { "/File/_Continue", "<control>C", file_continue, 0, NULL }, { "/File/Si_ngle Step", "<control>N", file_step, 0, NULL }, { "/File/Sto_p", "<control>P", file_stop, 0, NULL }, { "/File/sep2", NULL, NULL, 0, "<Separator>" }, { "/File/_Quit", "<control>Q", gtk_main_quit, 0, NULL }, { "/_View", NULL, NULL, 0, "<Branch>" }, { "/View/_Game Statistic...", "<control>G", game_statistic, 0, NULL }, { "/View/_Program Statistic...", "<control>R", program_statistic, 0, NULL }, { "/View/_Options...", "<control>O", view_options, 0, NULL }, { "/_Tournament", NULL, NULL, 0, "<Branch>" }, { "/Tournament/_Start...", "<control>T", tournament_start, 0, NULL }, { "/Tournament/Sto_p", "<control>H", tournament_stop, 0, NULL }, { "/_Help", NULL, NULL, 0, "<LastBranch>" }, { "/Help/_About...", "<control>B", help_about, 0, NULL }, }; void get_main_menu( GtkWidget *window, GtkWidget **menubar ) { GtkItemFactory *item_factory; GtkAccelGroup *accel_group; gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]); accel_group = gtk_accel_group_new (); /* This function initializes the item factory. Param 1: The type of menu - can be GTK_TYPE_MENU_BAR, GTK_TYPE_MENU, or GTK_TYPE_OPTION_MENU. Param 2: The path of the menu. Param 3: A pointer to a gtk_accel_group. The item factory sets up the accelerator table while generating menus. */ item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group); /* This function generates the menu items. Pass the item factory, the number of items in the array, the array itself, and any callback data for the the menu items. */ gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL); /* Attach the new accelerator group to the window. */ gtk_accel_group_attach (accel_group, GTK_OBJECT (window)); menu_file_start = gtk_item_factory_get_widget (item_factory, "/File/Start"); menu_file_pause = gtk_item_factory_get_widget (item_factory, "/File/Pause"); menu_file_continue = gtk_item_factory_get_widget (item_factory, "/File/Continue"); menu_file_step = gtk_item_factory_get_widget (item_factory, "/File/Single Step"); menu_file_stop = gtk_item_factory_get_widget (item_factory, "/File/Stop"); menu_view_gstatistic = gtk_item_factory_get_widget (item_factory, "/View/Game Statistic"); menu_view_pstatistic = gtk_item_factory_get_widget (item_factory, "/View/Program Statistic"); menu_tournament_start = gtk_item_factory_get_widget (item_factory, "/Tournament/Start..."); menu_tournament_stop = gtk_item_factory_get_widget (item_factory, "/Tournament/Stop"); if (menubar) /* Finally, return the actual menu bar created by the item factory. */ *menubar = gtk_item_factory_get_widget (item_factory, "<main>"); } int main(int argc,char *argv[]) { GtkWidget *menubar; preferences_load (); DIMENSIONX = (int) sqrt (SIZE); DIMENSIONY = (SIZE+DIMENSIONX-1)/DIMENSIONX; add_program_directory (DATADIR); add_program_directory ("."); gtk_init (&argc, &argv); main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_signal_connect (GTK_OBJECT (main_window), "destroy", GTK_SIGNAL_FUNC (gtk_main_quit), "WM destroy"); gtk_window_set_title (GTK_WINDOW (main_window), "Core Wars"); gtk_window_set_policy (GTK_WINDOW (main_window), FALSE, FALSE, FALSE); main_vbox = gtk_vbox_new (FALSE, 1); gtk_container_border_width (GTK_CONTAINER (main_vbox), 1); gtk_container_add (GTK_CONTAINER (main_window), main_vbox); gtk_widget_show (main_vbox); get_main_menu (main_window, &menubar); gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, TRUE, 0); gtk_widget_set (GTK_WIDGET (menu_file_start), "sensitive", FALSE, NULL); gtk_widget_set (GTK_WIDGET (menu_file_pause), "sensitive", FALSE, NULL); gtk_widget_set (GTK_WIDGET (menu_file_continue), "sensitive", FALSE, NULL); gtk_widget_set (GTK_WIDGET (menu_file_step), "sensitive", FALSE, NULL); gtk_widget_set (GTK_WIDGET (menu_file_stop), "sensitive", FALSE, NULL); gtk_widget_set (GTK_WIDGET (menu_tournament_start), "sensitive", FALSE, NULL); gtk_widget_set (GTK_WIDGET (menu_tournament_stop), "sensitive", FALSE, NULL); gtk_widget_show (menubar); create_drawing_area (); gtk_widget_show (main_window); gtk_main (); preferences_save (); return 0; }