/* * GSetGame - ui.c * Copyright 2007 Kirill Gorelov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include "gsetgame.h" #include "gettext.h" #include "debug.h" #include "cfg.h" #include "bgrnd.h" #include "ui.h" #include "records.h" UserInterface ui; #define ALIGN_CENTER 0x01 #define ALIGN_HCENTER 0x02 #define ALIGN_RIGHT 0x04 #define DRAW_BAR 0x08 static void gset_draw_bar(gint x1, gint y1, gint x2, gint y2) { cairo_t *cr; /* get a cairo_t */ cr = gdk_cairo_create (ui.backbuffer); if (!cr) return; cairo_set_source_rgba (cr, 0.6, 0.8, 0.6, 0.6); cairo_rectangle (cr, x1, y1, x2, y2); cairo_fill (cr); cairo_destroy (cr); } static void gset_pango_msg(gchar *msg, gint fontsize, gint x, gint y, int flags) { gint width, height; gint x1,y1; PangoLayout *layout = NULL; PangoFontDescription *fontdesc = NULL; char fontname[NAME_MAX]; GtkWidget *drawarea = glade_xml_get_widget(ui.xml, "gsetdrawing"); snprintf(fontname, NAME_MAX, "Sans Bold %d", fontsize); fontname[NAME_MAX-1] = 0; layout = gtk_widget_create_pango_layout (drawarea, msg); pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); /* PANGO_ALIGN_LEFT, PANGO_ALIGN_CENTER, PANGO_ALIGN_RIGHT */ fontdesc = pango_font_description_from_string (fontname); pango_layout_set_font_description (layout, fontdesc); pango_layout_get_pixel_size (layout, &width, &height); DBG(UI_DEBUG, "Pango msg=%s\n", msg); DBG(UI_DEBUG, "Pango layout width=%d height=%d\n", width, height); DBG(UI_DEBUG, "Pango scale=%d\n", PANGO_SCALE); if (flags & ALIGN_CENTER) { x1 = x - width/2; y1 = y - height/2; } else if (flags & ALIGN_HCENTER) { x1 = x - width/2; y1 = y; } else if (flags & ALIGN_RIGHT) { x1 = x - width; y1 = y; } else { x1 = x; y1 = y; } if (flags & DRAW_BAR) { gset_draw_bar(x1 - 2, y1 - 2, width + 4, height + 4); } gdk_draw_layout (ui.backbuffer, ui.backbuffer_gc, x1, y1, layout); pango_font_description_free (fontdesc); g_object_unref (layout); } void hide_toolbar(void) { gtk_widget_hide(glade_xml_get_widget(ui.xml, "gsettoolbar")); } /* Load the ui global in all it's glory */ void ui_load(void) { /* Load the glade UI file */ glade_gnome_init(); ui.xml = glade_xml_new(PACKAGE_DATA_DIR"/gsetgame/gsetgame.glade", NULL, NULL); // ui.xml = glade_xml_new("./gsetgame.glade", NULL, NULL); ui.window = glade_xml_get_widget(ui.xml, "gsetgame"); /* Load cards */ /*ui.cards_image = cards_image_from_file(PACKAGE_DATA_DIR"/pixmaps/gsetgame/cards/cards.svg");*/ ui.cards_image = cards_image_from_file(PACKAGE_DATA_DIR"/pixmaps/gsetgame/cards/cards.png"); if (ui.cards_image == NULL) { printf("Error loading cards image file\n"); } else { DBG(UI_DEBUG, "Cards image loaded successfully\n"); } #ifdef MAEMO_CHANGES hide_toolbar(); #endif /* Turn off double buffering. We do this ourselves */ gtk_widget_set_double_buffered(glade_xml_get_widget(ui.xml, "gsetdrawing"), FALSE); } /* Start the user interface */ void ui_start(void) { glade_xml_signal_autoconnect(ui.xml); } /* Set configuration options from the cfg global */ void ui_set_config(void) { if (cfg.nosets_auto) { gtk_widget_hide(glade_xml_get_widget(ui.xml, "toolbtn_nosets")); } else { gtk_widget_show(glade_xml_get_widget(ui.xml, "toolbtn_nosets")); } } void ui_draw_records_table(GtkWidget *gsetdrawing) { gchar result[128]; gint i; gset_draw_bar(40, 100, gsetdrawing->allocation.width-80, gsetdrawing->allocation.height-110); gset_pango_msg(_("Records Table"), 18, gsetdrawing->allocation.width/2, 120, ALIGN_CENTER); for (i=0; i < records_table_size(gset_current_records_handle()); i++) { time_t t; int nsets; gchar *name = NULL; if (records_table_get(gset_current_records_handle(), i, &t, &nsets, &name)) { if (!name) name = g_strdup(""); snprintf(result, 127, "%2d) %02d:%02d - " "%s (%d sets found)", i+1, (int)(t/60), (int)(t%60), name, nsets); gset_pango_msg(result, 12, gsetdrawing->allocation.width/2, 150 + i*22, ALIGN_CENTER); g_free(name); } } } /* draw the playing area */ void ui_draw_playcanvas(void) { GtkWidget *gsetdrawing; gchar str[PATH_MAX]; struct gsetgame_stats *gst; gsetdrawing = glade_xml_get_widget(ui.xml, "gsetdrawing"); if (gsetdrawing == NULL) return; /* Fill the buffer with the background image */ bgrnd_draw(ui.backbuffer, 0, 0, gsetdrawing->allocation.width, gsetdrawing->allocation.height); switch (gset_game_state()) { case GAME_PLAYING: /* Draw the pack of cards */ cards_pack_render_to_pixmap(&card_pack, ui.cards_image, ui.backbuffer, ui.backbuffer_gc); /* Draw game statistics */ gset_draw_bar(0, 0, gsetdrawing->allocation.width, 23); gst = gset_game_get_stats(); /* Draw time elapsed */ snprintf(str, PATH_MAX-1, "TIME: %02d:%02d", (int)(gst->time/60), (int)(gst->time%60)); gset_pango_msg(str, 14, gsetdrawing->allocation.width, 0, ALIGN_RIGHT); /* Draw the number of sets found */ snprintf(str, PATH_MAX-1, "SETS: %02d", (int)(gst->num_sets)); gset_pango_msg(str, 14, gsetdrawing->allocation.width/2, 0, ALIGN_HCENTER); /* Draw the number of cards left in the deck */ snprintf(str, PATH_MAX-1, "CARDS: %02d", (int)(card_deck.ncards)); /* XXX P1: what a dirty hack :( */ gset_pango_msg(str, 14, 0, 0, 0); break; case GAME_PAUSED: gset_pango_msg(_("PAUSED"), 72, gsetdrawing->allocation.width/2, gsetdrawing->allocation.height/2, ALIGN_CENTER); break; case GAME_ABANDONED: gset_pango_msg(_("GAME OVER"), 72, gsetdrawing->allocation.width/2, 50, ALIGN_CENTER); ui_draw_records_table(gsetdrawing); break; case GAME_COMPLETED: { gchar result[128]; snprintf(result, 127, "%02d:%02d", (int)(game_stats.time/60), (int)(game_stats.time%60)); gset_draw_bar(20, 10, gsetdrawing->allocation.width-40, 80); gset_pango_msg(_("The Game's finished"), 20, gsetdrawing->allocation.width/2, 25, ALIGN_CENTER); gset_pango_msg(_("in"), 16, gsetdrawing->allocation.width/2, 50, ALIGN_CENTER); gset_pango_msg(result, 20, gsetdrawing->allocation.width/2, 75, ALIGN_CENTER); /* Now, draw the records table */ ui_draw_records_table(gsetdrawing); } break; default: break; } /* update the screen */ gtk_widget_queue_draw_area(gsetdrawing, 0, 0, gsetdrawing->allocation.width, gsetdrawing->allocation.height); } void ui_resize_cards() { GtkWidget *gsetdrawing=NULL; gsetdrawing = glade_xml_get_widget(ui.xml, "gsetdrawing"); cards_pack_resize_cards(&card_pack, ui.cards_image, gsetdrawing->allocation.width, gsetdrawing->allocation.height); } const gchar* ui_ask_player_name() { GtkWidget *dialog, *pl_name_entry; gint result; const gchar *name; dialog = glade_xml_get_widget(ui.xml, "player_name_dialog"); pl_name_entry = glade_xml_get_widget(ui.xml, "pl_name"); name = gtk_entry_get_text(GTK_ENTRY(pl_name_entry)); if (!g_strv_length((gchar**)name)) // XXX P1: weird thing... If I pass gchar** it doen't work, passing gchar* works fine. gtk_entry_set_text(GTK_ENTRY(pl_name_entry), getenv("USER")); gtk_widget_show(dialog); result = gtk_dialog_run (GTK_DIALOG (dialog)); switch (result) { case GTK_RESPONSE_OK: name = gtk_entry_get_text(GTK_ENTRY(pl_name_entry)); break; default: name = NULL; break; } gtk_widget_hide (dialog); return name; } gint gset_msg(gchar *msg) { GtkWidget *dlg; gint result=0; dlg = gtk_message_dialog_new( (GtkWindow*)ui.window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "%s", msg); gtk_window_set_resizable(GTK_WINDOW(dlg), FALSE); result = gtk_dialog_run(GTK_DIALOG(dlg)); gtk_widget_destroy(dlg); return result; } /* Free the UI */ void ui_free(void) { cards_image_free(ui.cards_image); g_object_unref(ui.backbuffer_gc); g_object_unref(ui.backbuffer); g_object_unref(ui.xml); }