Commit 7294fa2d authored by Karuna Grewal's avatar Karuna Grewal Committed by Robert Roth

Split five-or-more.c The current code existing in five-or-more.c has been split into:

* five-or-more-app.c : Here all  the callbacks to the application are connected,
  followed by the general setting related to the application like background
  color etc. are moved to this file

* game-area.c: Drawing area related code ,say, binding signals to callbacks,
  or rendering the graphics, controlling the animation are handled here.

* balls-preview.c: This has the necessary functions for previewing.

Getters are used to access the static variables used across the appliaction
which weren't currently required since all the code was mash-up into
a single file.

https://bugzilla.gnome.org/show_bug.cgi?id=794273
parent 2c9624cd
......@@ -9,3 +9,6 @@ data/org.gnome.five-or-more.gschema.xml
data/translatable_themes.h
src/five-or-more.c
src/games-scores-dialog.c
src/five-or-more-app.c
src/game-area.c
src/balls-preview.c
......@@ -2,7 +2,6 @@ bin_PROGRAMS = five-or-more
five_or_more_SOURCES = \
five-or-more.c \
five-or-more.h \
games-file-list.c \
games-file-list.h \
games-gridframe.c \
......@@ -16,7 +15,13 @@ five_or_more_SOURCES = \
games-scores-dialog.c \
games-scores-dialog.h \
games-scores-backend.c \
games-scores-backend.h
games-scores-backend.h \
five-or-more-app.h \
five-or-more-app.c \
balls-preview.c \
balls-preview.h \
game-area.h \
game-area.c
five_or_more_CPPFLAGS = \
-I$(top_srcdir) \
......
/* -*- mode:C; indent-tabs-mode:t; tab-width:8; c-basic-offset:8; -*- */
/*
* Color lines for GNOME
* Copyright © 1999 Free Software Foundation
* Authors: Robert Szokovacs <szo@appaloosacorp.hu>
* Szabolcs Ban <shooby@gnome.hu>
* Karuna Grewal <karunagrewal98@gmail.com>
* Copyright © 2007 Christian Persch
*
* This game 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, 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, see <https://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdlib.h>
#include <locale.h>
#include <math.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdkkeysyms.h>
#include "games-preimage.h"
#include "balls-preview.h"
#include "game-area.h"
#define MAXNPIECES 10
#define PREVIEW_IMAGE_WIDTH 20
#define PREVIEW_IMAGE_HEIGHT 20
static GtkImage* preview_images[MAXNPIECES];
static GdkPixbuf* preview_pixbufs[MAXNPIECES];
static int preview[MAXNPIECES];
void
init_preview (void)
{
int i;
gint npieces = get_npieces();
for (i = 0; i < npieces; i++) {
preview[i] = g_rand_int_range (*get_rgen(), 1, get_ncolors() + 1);
}
}
void
draw_preview (void)
{
guint i;
gint npieces = get_npieces();
/* This function can be called before the images are initialized */
if (!GTK_IS_IMAGE (preview_images[0]))
return;
for (i = 0; i < MAXNPIECES; i++) {
if (i < npieces)
gtk_image_set_from_pixbuf (preview_images[i], preview_pixbufs[preview[i] - 1]);
else
gtk_image_clear (preview_images[i]);
}
}
void
refresh_preview_surfaces (void)
{
guint i;
GdkPixbuf *scaled = NULL;
GtkWidget *widget = GTK_WIDGET (preview_images[0]);
GtkStyleContext *context;
GdkRGBA bg;
cairo_t *cr;
GdkRectangle preview_rect;
cairo_surface_t *blank_preview_surface = NULL;
/* The balls rendered to a size appropriate for the preview. */
cairo_surface_t *preview_surface = NULL;
context = gtk_widget_get_style_context (widget);
gtk_style_context_get_background_color (context, gtk_style_context_get_state (context), &bg);
/* Like the refresh_pixmaps() function, we may be called before
* the window is ready. */
if (PREVIEW_IMAGE_HEIGHT == 0)
return;
preview_rect.x = 0;
preview_rect.y = 0;
preview_rect.width = PREVIEW_IMAGE_WIDTH;
preview_rect.height = PREVIEW_IMAGE_HEIGHT;
/* We create pixmaps for each of the ball colours and then
* set them as the background for each widget in the preview array.
* This code assumes that each preview window is identical. */
GamesPreimage *ball_preimage = get_ball_preimage();
if (ball_preimage)
scaled = games_preimage_render (ball_preimage, 4 * PREVIEW_IMAGE_WIDTH,
7 * PREVIEW_IMAGE_HEIGHT);
if (!scaled) {
scaled = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
4 * PREVIEW_IMAGE_WIDTH, 7 * PREVIEW_IMAGE_HEIGHT);
gdk_pixbuf_fill (scaled, 0x00000000);
}
for (i = 0; i < 7; i++) {
preview_surface = gdk_window_create_similar_image_surface (gtk_widget_get_window (widget),
CAIRO_FORMAT_ARGB32,
PREVIEW_IMAGE_WIDTH, PREVIEW_IMAGE_HEIGHT, 1);
cr = cairo_create (preview_surface);
gdk_cairo_set_source_rgba (cr, &bg);
gdk_cairo_rectangle (cr, &preview_rect);
cairo_fill (cr);
gdk_cairo_set_source_pixbuf (cr, scaled, 0, -1.0 * PREVIEW_IMAGE_HEIGHT * i);
cairo_mask (cr, cairo_get_source (cr));
if (preview_pixbufs[i])
g_object_unref (preview_pixbufs[i]);
preview_pixbufs[i] = gdk_pixbuf_get_from_surface (preview_surface, 0, 0,
PREVIEW_IMAGE_WIDTH, PREVIEW_IMAGE_HEIGHT);
cairo_destroy (cr);
cairo_surface_destroy (preview_surface);
}
blank_preview_surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
CAIRO_CONTENT_COLOR_ALPHA,
PREVIEW_IMAGE_WIDTH, PREVIEW_IMAGE_HEIGHT);
cr = cairo_create (blank_preview_surface);
gdk_cairo_set_source_rgba (cr, &bg);
gdk_cairo_rectangle (cr, &preview_rect);
cairo_fill (cr);
cairo_surface_destroy (blank_preview_surface);
cairo_destroy (cr);
g_object_unref (scaled);
}
GtkImage **
get_preview_images()
{
return preview_images;
}
int *
get_preview()
{
return preview;
}
GdkPixbuf **
get_preview_pixbufs()
{
return preview_pixbufs;
}
\ No newline at end of file
/*
* Color lines for GNOME
* Copyright © 1999 Free Software Foundation
* Authors: Robert Szokovacs <szo@appaloosacorp.hu>
* Szabolcs Ban <shooby@gnome.hu>
* Karuna Grewal <karunagrewal98@gmail.com>
* Copyright © 2007 Christian Persch
*
* This game 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, 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, see <https://www.gnu.org/licenses/>.
*/
#ifndef BALLS_PREVIEW_H
#define BALLS_PREVIEW_H
#include <gtk/gtk.h>
void init_preview (void);
void draw_preview (void);
void refresh_preview_surfaces (void);
GtkImage **get_preview_images ();
int * get_preview ();
GdkPixbuf **get_preview_pixbufs ();
#endif
\ No newline at end of file
/* -*- mode:C; indent-tabs-mode:t; tab-width:8; c-basic-offset:8; -*- */
/*
* Color lines for GNOME
* Copyright © 1999 Free Software Foundation
* Authors: Robert Szokovacs <szo@appaloosacorp.hu>
* Szabolcs Ban <shooby@gnome.hu>
* Karuna Grewal <karunagrewal98@gmail.com>
* Copyright © 2007 Christian Persch
*
* This game 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, 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, see <https://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdlib.h>
#include <locale.h>
#include <math.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdkkeysyms.h>
#include "games-file-list.h"
#include "games-preimage.h"
#include "games-gridframe.h"
#include "games-scores.h"
#include "games-scores-dialog.h"
#include "game-area.h"
#include "five-or-more-app.h"
#include "balls-preview.h"
#define DEFAULT_GAME_SIZE MEDIUM
#define KEY_SIZE "size"
#define MAXNPIECES 10
#define KEY_MOVE_TIMEOUT "move-timeout"
#define KEY_BACKGROUND_COLOR "background-color"
#define KEY_BALL_THEME "ball-theme"
static const GamesScoresCategory scorecats[] = {
{ "Small", NC_("board size", "Small") },
{ "Medium", NC_("board size", "Medium") },
{ "Large", NC_("board size", "Large") }
};
enum {
UNSET = 0,
SMALL = 1,
MEDIUM,
LARGE,
MAX_SIZE,
};
static background backgnd = { { 0, 0, 0, 0}, NULL, 0 };
static GtkWidget *gridframe;
static GtkWidget *app, *headerbar, *restart_game_dialog, *pref_dialog;
static char *ball_filename;
static gint game_size = UNSET;
static gboolean pref_dialog_done = FALSE;
static GamesFileList *theme_file_list = NULL;
static GtkWidget *size_radio_s, *size_radio_m, *size_radio_l;
static int move_timeout = 100;
static gboolean window_is_fullscreen = FALSE, window_is_maximized = FALSE;
static gint window_width = 0, window_height = 0;
static GamesScores *highscores;
static GSettings *settings;
static GtkBuilder *builder;
static GtkBuilder *builder_preferences;
static guint score = 0;
static GtkWidget *scorelabel;
/*getter funcs*/
GSettings **
get_settings ()
{
return &settings;
}
const GamesScoresCategory *
get_scorecats ()
{
return scorecats;
}
gint *
get_game_size ()
{
return &game_size;
}
GtkWidget *
get_gridframe ()
{
return gridframe;
}
char *
get_ball_filename ()
{
return ball_filename;
}
background
get_backgnd ()
{
return backgnd;
}
int
get_move_timeout ()
{
return move_timeout;
}
GamesScores *
get_highscores()
{
return highscores;
}
void
update_score (guint value)
{
char string[20];
if(value)
score += value;
else
score = value;
g_snprintf (string, 19, "%d", score);
gtk_label_set_text (GTK_LABEL (scorelabel), string);
}
void
set_status_message (gchar * message)
{
gtk_header_bar_set_subtitle (GTK_HEADER_BAR (headerbar), message);
}
static void
set_backgnd_color (const gchar * str)
{
if (!str)
str = g_strdup ("#000000");
if (str != backgnd.name) {
g_free (backgnd.name);
backgnd.name = g_strdup (str);
}
if (!gdk_rgba_parse (&backgnd.color, backgnd.name)) {
gdk_rgba_parse (&backgnd.color, "#000000");
}
}
static void
show_scores (gint pos)
{
static GtkWidget *dialog;
if (dialog == NULL) {
dialog = games_scores_dialog_new (GTK_WINDOW (app), highscores, _("Five or More Scores"));
games_scores_dialog_set_category_description (GAMES_SCORES_DIALOG
(dialog), _("_Board size:"));
}
if (pos > 0) {
games_scores_dialog_set_hilight (GAMES_SCORES_DIALOG (dialog), pos);
}
gtk_window_present (GTK_WINDOW (dialog));
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_hide (dialog);
}
static void
load_properties (void)
{
gchar *buf;
ball_filename = g_settings_get_string (settings, KEY_BALL_THEME);
move_timeout = g_settings_get_int (settings, KEY_MOVE_TIMEOUT);
if (move_timeout <= 0)
move_timeout = 100;
buf = g_settings_get_string (settings, KEY_BACKGROUND_COLOR); /* FIXMEchpe? */
set_backgnd_color (buf);
g_free (buf);
load_theme ();
}
void
game_over (void)
{
int pos;
set_status_message (_("Game Over!"));
if (score > 0)
pos = games_scores_add_plain_score (highscores, score);
show_scores (pos);
}
static void
start_game (void)
{
set_status_message (_("Match five objects of the same type in a row to score!"));
refresh_screen ();
update_score(0);
set_inmove (0);
}
static void
conf_value_changed_cb (GSettings *settings, gchar *key)
{
if (strcmp (key, KEY_BACKGROUND_COLOR) == 0) {
gchar *color;
color = g_settings_get_string (settings, KEY_BACKGROUND_COLOR);
if (color != NULL) {
set_backgnd_color (color);
g_free (color);
}
} else if (strcmp (key, KEY_BALL_THEME) == 0) {
gchar *theme_tmp = NULL;
theme_tmp = g_settings_get_string (settings, KEY_BALL_THEME);
if (theme_tmp) {
if (strcmp (theme_tmp, ball_filename) != 0) {
g_free (ball_filename);
ball_filename = theme_tmp;
load_theme ();
refresh_screen ();
} else
g_free (theme_tmp);
}
/* FIXME apply in the prefs dialog GUI */
} else if (strcmp (key, KEY_MOVE_TIMEOUT) == 0) {
gint timeout_tmp;
timeout_tmp = g_settings_get_int (settings, KEY_MOVE_TIMEOUT);
timeout_tmp = CLAMP (timeout_tmp, 1, 1000);
if (timeout_tmp != move_timeout)
move_timeout = timeout_tmp;
} else if (strcmp (key, KEY_SIZE) == 0) {
gint size_tmp;
size_tmp = g_settings_get_int (settings, KEY_SIZE);
if (size_tmp != game_size) {
set_sizes (size_tmp);
reset_game ();
start_game ();
}
}
}
static void
init_config (void)
{
g_signal_connect (settings, "changed",
G_CALLBACK (conf_value_changed_cb), NULL);
game_size = g_settings_get_int (settings, KEY_SIZE);
if (game_size == UNSET)
game_size = DEFAULT_GAME_SIZE;
game_size = CLAMP (game_size, SMALL, MAX_SIZE - 1);
set_sizes (game_size);
}
static gboolean
window_size_allocate_cb (GtkWidget *widget, GdkRectangle *allocation)
{
if (!window_is_maximized && !window_is_fullscreen)
gtk_window_get_size (GTK_WINDOW (widget), &window_width, &window_height);
return FALSE;
}
static gboolean
window_state_event_cb (GtkWidget *widget, GdkEventWindowState *event)
{
if ((event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) != 0)
window_is_maximized = (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
if ((event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) != 0)
window_is_fullscreen = (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) != 0;
return FALSE;
}
void
game_new_callback (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
reset_game ();
start_game ();
}
void
game_top_ten_callback (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
show_scores (0);
}
static void
set_selection (GtkWidget * widget, char *data)
{
const gchar *entry;
entry = games_file_list_get_nth (theme_file_list,
gtk_combo_box_get_active (GTK_COMBO_BOX
(widget)));
g_settings_set_string (settings, KEY_BALL_THEME, entry);
}
void
pref_dialog_response (GtkDialog * dialog, gint response, gpointer data)
{
gtk_widget_hide (GTK_WIDGET (dialog));
}
static void
bg_color_callback (GtkWidget * widget, gpointer data)
{
GdkRGBA c;
char str[64];
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (widget), &c);
g_snprintf (str, sizeof (str), "#%04x%04x%04x", (int) (c.red * 65535 + 0.5), (int) (c.green * 65535 + 0.5), (int) (c.blue * 65535 + 0.5));
g_settings_set_string (settings, KEY_BACKGROUND_COLOR, str);
//area,h
load_theme ();
//area.h
refresh_screen ();
}
static void
size_callback (GtkWidget * widget, gpointer data)
{
GtkWidget *size_radio, *content_area, *label;
game_size = g_settings_get_int (settings, KEY_SIZE);
if (pref_dialog_done && game_size != GPOINTER_TO_INT (data) && !restart_game_dialog) {
GtkDialogFlags flags = GTK_DIALOG_DESTROY_WITH_PARENT;
restart_game_dialog = gtk_message_dialog_new (GTK_WINDOW (pref_dialog),
GTK_MESSAGE_WARNING,
flags,
GTK_BUTTONS_NONE,
_("Are you sure you want to restart the game?"));
gtk_dialog_add_buttons (GTK_DIALOG (restart_game_dialog),
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Restart"), GTK_RESPONSE_OK,
NULL);
gint result = gtk_dialog_run (GTK_DIALOG (restart_game_dialog));
gtk_widget_destroy (restart_game_dialog);
switch (result) {
case GTK_RESPONSE_OK:
g_settings_set_int (settings, KEY_SIZE, GPOINTER_TO_INT (data));
break;
case GTK_RESPONSE_CANCEL:
switch (game_size) {
case SMALL:
size_radio = size_radio_s;
break;
case MEDIUM:
size_radio = size_radio_m;
break;
case LARGE: