helpers.c
来自「Gnome的一个单人纸牌游戏。」· C语言 代码 · 共 1,053 行 · 第 1/2 页
C
1,053 行
#include <config.h>#include <gdk-pixbuf/gdk-pixbuf.h>#include <gdk-pixbuf/gnome-canvas-pixbuf.h>#include "typedefs.h"#include "helpers.h"#include "callbacks.h"#include "property.h"#include "game.h"#include <sys/types.h>#include <sys/stat.h>#include <dirent.h>/** * make_menus: * @app: the application struct * * function description: for internal use only( goal_init_and_create() ), creates the main menu(bar) * * return values: nothing */voidmake_menus(GoalApp *app){ gboolean dummy; GnomeUIInfo game_type_subtree [] = { GNOMEUIINFO_ITEM_DATA(N_("Cross"), N_("create cross board"), set_game_type_to_cross_cb, app, NULL), GNOMEUIINFO_ITEM_DATA(N_("Plus"), N_("create plus board"), set_game_type_to_plus_cb, app, NULL), GNOMEUIINFO_ITEM_DATA(N_("Chimney"), N_("create chimney board"), set_game_type_to_chimney_cb, app, NULL), GNOMEUIINFO_ITEM_DATA(N_("Pyramid"), N_("create pyramid board"), set_game_type_to_pyramid_cb, app, NULL), GNOMEUIINFO_ITEM_DATA(N_("Arrow"), N_("create arrow board"), set_game_type_to_arrow_cb, app, NULL), GNOMEUIINFO_ITEM_DATA(N_("Rubin"), N_("create rubin board"), set_game_type_to_rubin_cb, app, NULL), GNOMEUIINFO_ITEM_DATA(N_("Diamond"), N_("create diamond board"), set_game_type_to_diamond_cb, app, NULL), GNOMEUIINFO_ITEM_DATA(N_("Solitaire"), N_("create solitaire board"), set_game_type_to_solitaire_cb, app, NULL), GNOMEUIINFO_END }; GnomeUIInfo menubar_game_menu[] = { GNOMEUIINFO_MENU_NEW_GAME_ITEM(new_game_cb, app), GNOMEUIINFO_MENU_GAME_TREE(game_type_subtree), GNOMEUIINFO_TOGGLEITEM_DATA(N_("Hints"), N_("Show board hints"), toggle_show_board_hints_cb, app, NULL), GNOMEUIINFO_SEPARATOR, GNOMEUIINFO_MENU_EXIT_ITEM(menubar_game_menu_exit_item_cb, app), GNOMEUIINFO_END }; GnomeUIInfo menubar_edit_menu[] = { GNOMEUIINFO_MENU_PROPERTIES_ITEM(menubar_help_menu_properties_item_cb, app), GNOMEUIINFO_END }; GnomeUIInfo menubar_help_menu[] = { GNOMEUIINFO_MENU_ABOUT_ITEM(menubar_help_menu_about_item_cb, app), GNOMEUIINFO_END }; GnomeUIInfo menubar[] = { GNOMEUIINFO_MENU_GAME_TREE(menubar_game_menu), GNOMEUIINFO_MENU_EDIT_TREE(menubar_edit_menu), GNOMEUIINFO_MENU_HELP_TREE(menubar_help_menu), GNOMEUIINFO_END }; /* install the menus+hints for the application */ gnome_app_create_menus(GNOME_APP(app->gui.MainWindow), menubar); gnome_app_install_menu_hints(GNOME_APP(app->gui.MainWindow), menubar); /* FIXME: gtk_check_menu_item_set_active call toggle_show_board_hints_cb if state is changed */ /* set menupoint "hints" */ dummy = app->game.ShowBoardHints; gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menubar_game_menu[2].widget), app->game.ShowBoardHints); app->game.ShowBoardHints = dummy; }/** * load_pixmaps: * @app: the GoalApp struct, holds the game information * * function description: load the pixmaps into a temp variables (pixbuf) * * return values: 0 no error happends, NOT 0 error code */gintload_pixmaps(GoalApp *app){ gint PNoH, PNoW, PEH, PEW, PMH, PMW, PTH, PTW, PNeH, PNeW, PEPH, PEPW, PENH, PENW, x, y; GdkPixbuf *buff; GoalTheme *theme; /* get the given theme (the list ist counting from 0, but we count from 1 thats why -1)*/ theme = (GoalTheme *) g_list_nth_data(app->ThemeList, app->game.DefaultThemeNumber - 1); if(theme == NULL) { g_warning(":: PACKAGE: %s :: FILE: %s :: LINE: %i :: error getting theme from list\n" , PACKAGE, __FILE__, __LINE__); return 2; } /* ---===---===--- load pixmaps into canvas ---===---===--- */ /* --- Wallpaper --- */ if((buff = gdk_pixbuf_new_from_file(/*app->*/theme->PathToPixmapWallpaper)) == NULL) { return 1; }; /* get height and width, with this info we set the main windows heigth and width */ app->gui.WallpaperHeight = gdk_pixbuf_get_height(buff); app->gui.WallpaperWidth = gdk_pixbuf_get_width(buff); if(app->gui.Wallpaper) gtk_object_destroy(GTK_OBJECT(app->gui.Wallpaper)); app->gui.Wallpaper = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(app->gui.Canvas)), gnome_canvas_pixbuf_get_type(), "pixbuf", buff, "x",0.0, "y",0.0, NULL); /* connect to signal */ gtk_signal_connect(GTK_OBJECT(app->gui.Wallpaper), "event", (GtkSignalFunc)board_event_cb, app); gdk_pixbuf_unref(buff); /* --- Piece --- */ if((buff = gdk_pixbuf_new_from_file(/*app->*/theme->PathToPixmapPieceNormal)) == NULL) { return 2; } app->gui.PieceHeight = gdk_pixbuf_get_height(buff); app->gui.PieceWidth = gdk_pixbuf_get_width(buff); for(x = 0; x < NUMBER_CELLS; x++) for(y = 0; y < NUMBER_CELLS; y++) if(app->game.CellStatus[x][y] != UNKOWN) { /* destroy canvas item if exists */ if(app->gui.PieceNormal[x][y]) gtk_object_destroy(GTK_OBJECT(app->gui.PieceNormal[x][y])); /* create new canvas item*/ app->gui.PieceNormal[x][y] = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(app->gui.Canvas)), gnome_canvas_pixbuf_get_type(), "pixbuf", buff, "x",(double)(x * app->gui.PieceWidth), "y",(double)(y * app->gui.PieceHeight), NULL); /* connect canvas item to signal */ gtk_signal_connect(GTK_OBJECT(app->gui.PieceNormal[x][y]), "event", (GtkSignalFunc)board_event_cb, app); } PNoH = app->gui.PieceHeight; PNoW = app->gui.PieceWidth; gdk_pixbuf_unref(buff); /* --- Piece (empty) --- */ if((buff = gdk_pixbuf_new_from_file(theme->PathToPixmapPieceEmpty)) == NULL) { return 3; } if(app->gui.PieceEmpty) gtk_object_destroy(GTK_OBJECT(app->gui.PieceEmpty)); app->gui.PieceEmpty = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(app->gui.Canvas)), gnome_canvas_pixbuf_get_type(), "pixbuf", buff, "x", 0.0, "y", 0.0, NULL); /* connect canvas item to signal */ gtk_signal_connect(GTK_OBJECT(app->gui.PieceEmpty), "event", (GtkSignalFunc)board_event_cb, app); gnome_canvas_item_hide(app->gui.PieceEmpty); PEH = gdk_pixbuf_get_height(buff); PEW = gdk_pixbuf_get_width(buff); gdk_pixbuf_unref(buff); /* --- Piece (marked) --- */ if((buff = gdk_pixbuf_new_from_file(/*app->*/theme->PathToPixmapPieceMarked)) == NULL) { return 3; } if(app->gui.PieceMarked) gtk_object_destroy(GTK_OBJECT(app->gui.PieceMarked)); app->gui.PieceMarked = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(app->gui.Canvas)), gnome_canvas_pixbuf_get_type(), "pixbuf", buff, "x", 0.0, "y", 0.0, NULL); /* connect canvas item to signal */ gtk_signal_connect(GTK_OBJECT(app->gui.PieceMarked), "event", (GtkSignalFunc)board_event_cb, app); gnome_canvas_item_hide(app->gui.PieceMarked); PMH = gdk_pixbuf_get_height(buff); PMW = gdk_pixbuf_get_width(buff); gdk_pixbuf_unref(buff); /* --- Piece (touched) --- */ if((buff = gdk_pixbuf_new_from_file(/*app->*/theme->PathToPixmapPieceTouched)) == NULL) { return 4; } if(app->gui.PieceTouched) gtk_object_destroy(GTK_OBJECT(app->gui.PieceTouched)); app->gui.PieceTouched = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(app->gui.Canvas)), gnome_canvas_pixbuf_get_type(), "pixbuf", buff, "x", 0.0, "y", 0.0, NULL); /* connect canvas item to signal */ gtk_signal_connect(GTK_OBJECT(app->gui.PieceTouched), "event", (GtkSignalFunc)board_event_cb, app); gnome_canvas_item_hide(app->gui.PieceTouched); PTH = gdk_pixbuf_get_height(buff); PTW = gdk_pixbuf_get_width(buff); gdk_pixbuf_unref(buff); /* --- Piece (negativ) --- */ if((buff = gdk_pixbuf_new_from_file(/*app->*/theme->PathToPixmapPieceNegativ)) == NULL) { return 5; } if(app->gui.PieceNegativ) gtk_object_destroy(GTK_OBJECT(app->gui.PieceNegativ)); app->gui.PieceNegativ = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(app->gui.Canvas)), gnome_canvas_pixbuf_get_type(), "pixbuf", buff, "x", 0.0, "y", 0.0, NULL); /* connect canvas item to signal */ gtk_signal_connect(GTK_OBJECT(app->gui.PieceNegativ), "event", (GtkSignalFunc)board_event_cb, app); gnome_canvas_item_hide(app->gui.PieceNegativ); PNeH = gdk_pixbuf_get_height(buff); PNeW = gdk_pixbuf_get_width(buff); gdk_pixbuf_unref(buff); /* --- Piece (positiv) --- */ if((buff = gdk_pixbuf_new_from_file(/*app->*/theme->PathToPixmapPieceEmptyPositiv)) == NULL) { return 6; } if(app->gui.PieceEmptyPositiv) gtk_object_destroy(GTK_OBJECT(app->gui.PieceEmptyPositiv)); app->gui.PieceEmptyPositiv = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(app->gui.Canvas)), gnome_canvas_pixbuf_get_type(), "pixbuf", buff, "x", 0.0, "y", 0.0, NULL); /* connect canvas item to signal */ gtk_signal_connect(GTK_OBJECT(app->gui.PieceEmptyPositiv), "event", (GtkSignalFunc)board_event_cb, app); gnome_canvas_item_hide(app->gui.PieceEmptyPositiv); PEPH = gdk_pixbuf_get_height(buff); PEPW = gdk_pixbuf_get_width(buff); gdk_pixbuf_unref(buff); /* --- */ if((buff = gdk_pixbuf_new_from_file(/*app->*/theme->PathToPixmapPieceEmptyNegativ)) == NULL) { return 7; } if(app->gui.PieceEmptyNegativ) gtk_object_destroy(GTK_OBJECT(app->gui.PieceEmptyNegativ)); app->gui.PieceEmptyNegativ = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(app->gui.Canvas)), gnome_canvas_pixbuf_get_type(), "pixbuf", buff, "x", 0.0, "y", 0.0, NULL); /* connect canvas item to signal */ gtk_signal_connect(GTK_OBJECT(app->gui.PieceEmptyNegativ), "event", (GtkSignalFunc)board_event_cb, app); gnome_canvas_item_hide(app->gui.PieceEmptyNegativ); PENH = gdk_pixbuf_get_height(buff); PENW = gdk_pixbuf_get_width(buff); gdk_pixbuf_unref(buff); /* check some important things and give an warning message */ /* have the other pieces the same width and height like the "normal" piece ?? */ if((PNoW != PMW) || (PNoW != PTW) || (PNoW != PEW) || (PNoW != PNeW) || (PNoW != PEPW) || (PNoW != PENW)) g_warning(":: PACKAGE: %s :: FILE: %s :: LINE: %i :: pieces have not the same width\n" , PACKAGE, __FILE__, __LINE__); if((PNoH != PMH) || (PNoH != PTH) || (PNoH != PEH) || (PNoH != PNeH) || (PNoH != PEPH) || (PNoH != PENH)) g_warning(":: PACKAGE: %s :: FILE: %s :: LINE: %i :: pieces have not the same height\n" , PACKAGE, __FILE__, __LINE__); /* check relations */ if(app->gui.WallpaperWidth != (NUMBER_CELLS * PNoW)) g_warning(":: PACKAGE: %s :: FILE: %s :: LINE: %i :: wrong relation between wallpaper width and piece width\n" , PACKAGE, __FILE__, __LINE__); if(app->gui.WallpaperHeight != (NUMBER_CELLS * PNoH)) g_warning(":: PACKAGE: %s :: FILE: %s :: LINE: %i :: wrong relation between wallpaper height and piece height\n" , PACKAGE, __FILE__, __LINE__); gnome_canvas_set_scroll_region(GNOME_CANVAS(app->gui.Canvas), 0.0, 0.0, app->gui.WallpaperWidth, app->gui.WallpaperHeight);/* FIXME: deprecated (change to gtk_widget_set_size_request) */ gtk_widget_set_usize(app->gui.Canvas, app->gui.WallpaperWidth, app->gui.WallpaperHeight);/* FIXME: change gtk_window_set_policy to gtk_window_set_resizable() */ gtk_widget_realize(app->gui.MainWindow); /* great, no error happends */ return 0;}/** * goal_init_and_create: * @argc: like in the main function * @argv: like in the main function * * function description: create the main window, init some important stuff * * return values: the created app, holding in GoalApp struct */GoalApp*goal_init_and_create(gint argc, gchar **argv){ GoalApp *app; gint ret; /* request memory for app */ app = g_malloc(sizeof(GoalApp)); /* initialize the empty list. */ app->ThemeList = NULL; /* init gnome */ if(gnome_init(PACKAGE, VERSION, argc, argv) != 0) g_error(":: PACKAGE: %s :: FILE: %s :: LINE: %i :: could not init gnome\n" , PACKAGE, __FILE__, __LINE__); /* load the settings */ load_settings(app); /* create the main window and concect it to signals */ if((app->gui.MainWindow = gnome_app_new(PACKAGE, "Goal")) == NULL) g_error(":: PACKAGE: %s :: FILE: %s :: LINE: %i :: could not create main window\n" , PACKAGE, __FILE__, __LINE__); gtk_signal_connect(GTK_OBJECT(app->gui.MainWindow), "delete_event", GTK_SIGNAL_FUNC(mainwindow_delete_event_cb), app); gtk_signal_connect(GTK_OBJECT(app->gui.MainWindow), "destroy", GTK_SIGNAL_FUNC(mainwindow_destroy_cb), app); /* install the appbar */ if((app->gui.Appbar = gnome_appbar_new(FALSE, TRUE, GNOME_PREFERENCES_USER)) == NULL) g_error(":: PACKAGE: %s :: FILE: %s :: LINE: %i :: could not create appbar\n" , PACKAGE, __FILE__, __LINE__); gnome_app_set_statusbar(GNOME_APP(app->gui.MainWindow), app->gui.Appbar); gtk_widget_show(app->gui.MainWindow); /* init the board */ clear_board(app); /* create the canvas and put it into the main window */ gtk_widget_push_visual(gdk_rgb_get_visual()); gtk_widget_push_colormap(gdk_rgb_get_cmap()); if((app->gui.Canvas = gnome_canvas_new()) == NULL) g_error(":: PACKAGE: %s :: FILE: %s :: LINE: %i :: could not create canvas\n" , PACKAGE, __FILE__, __LINE__); gtk_widget_pop_colormap(); gtk_widget_pop_visual(); gnome_app_set_contents(GNOME_APP(app->gui.MainWindow), app->gui.Canvas); gtk_widget_show(app->gui.Canvas); gtk_window_set_policy(GTK_WINDOW(app->gui.MainWindow), FALSE, FALSE, TRUE); /* create the main menu */ make_menus(app); /* --- load the pixmaps and put they into the gnomecanvas --- */ /* first lad theme list */ if((ret = create_theme_list(app)) != 0) g_error(":: PACKAGE: %s :: FILE: %s :: LINE: %i :: error loading theme (ERROR:%i)\n" , PACKAGE, __FILE__, __LINE__, ret); /* check the default theme number, if is lesser than 1 or greater than our number of themes then set it to 1 */ if((app->game.DefaultThemeNumber > app->NumberOfThemes) || (app->game.DefaultThemeNumber < 1)) { g_warning(":: PACKAGE: %s :: FILE: %s :: LINE: %i :: wrong theme number, set theme number to 1\n" , PACKAGE, __FILE__, __LINE__); app->game.DefaultThemeNumber = 1; } if((ret = load_pixmaps(app)) != 0) g_error(":: PACKAGE: %s :: FILE: %s :: LINE: %i :: error loading pixmaps (ERROR:%i)\n" , PACKAGE, __FILE__, __LINE__, ret); delete_theme_list(app); /* appbar hint */ gnome_appbar_set_status(GNOME_APPBAR(app->gui.Appbar), _("Welcome to Goal")); /* update the gui but don't start a new one */ init_new_game(app); /* init the game status to not running */ app->game.GameIsRunning = FALSE; app->game.JumpStarted = FALSE; app->game.FirstPieceRemoved = FALSE; return app; }/** * load_settings: * @app: the application struct * * function description: load the settings * * return values: void */voidload_settings(GoalApp *app){ gchar *tmp1; /* default theme name */ tmp1 = g_malloc(sizeof(gint) + sizeof("/goal/setting/defaultthemenumber=")); sprintf(tmp1, "/goal/setting/defaultthemenumber=%i", 1); app->game.DefaultThemeNumber = gnome_config_get_int(tmp1); g_free(tmp1); /* gametype */ tmp1 = g_malloc(sizeof(gint) + sizeof("/goal/setting/gametype=")); sprintf(tmp1,"/goal/setting/gametype=%i", SOLITAIRE); app->game.GameType = gnome_config_get_int(tmp1); g_free(tmp1); /* board hints */ tmp1 = g_malloc(sizeof(gint) + sizeof("/goal/setting/showboardhints=")); sprintf(tmp1,"/goal/setting/showboardhints=%i", FALSE); app->game.ShowBoardHints = gnome_config_get_bool(tmp1); g_free(tmp1); /* g_print("Goal :: load_seetings\n"); g_print("DefaultTheme: %i\n", app->game.DefaultThemeNumber); g_print("GameType: %i\n", app->game.GameType); g_print("ShowBoardHints: %i\n", app->game.ShowBoardHints); */ }/** * save_settings: * @app: the application struct * * function description: load the settings * * return values: void */voidsave_settings(GoalApp *app){ gnome_config_set_int("/goal/setting/defaultthemenumber", app->game.DefaultThemeNumber); gnome_config_set_int("/goal/setting/gametype", app->game.GameType); gnome_config_set_int("/goal/setting/showboardhints", app->game.ShowBoardHints); /* write to disk */ gnome_config_sync(); /* g_print("Goal :: save_seetings\n"); g_print("DefaultTheme: %i\n", app->game.DefaultThemeNumber); g_print("GameType: %i\n", app->game.GameType); g_print("ShowBoardHints: %i\n", app->game.ShowBoardHints);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?