/* gcompris - help.c
*
* Copyright (C) 2000, 2008 Bruno Coudoin
*
* 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 3 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, see .
*/
/**
* The bar button common to each games
*
*/
#include
#include "gcompris.h"
#include "gc_core.h"
#define SOUNDLISTFILE PACKAGE
#define GAP_TO_BUTTON -20
static gint item_event_help(GnomeCanvasItem *item, GdkEvent *event, gpointer data);
static int event_disable_right_click_popup(GtkWidget *w, GdkEvent *event, gpointer data);
static void select_item(GnomeCanvasItem *item, GnomeCanvasItem *item_text);
static void set_content(char *text);
static gboolean help_displayed = FALSE;
static GnomeCanvasItem *rootitem = NULL;
static gchar *prerequisite = NULL;
static gchar *goal = NULL;
static gchar *manual = NULL;
static gchar *credit = NULL;
static GnomeCanvasItem *item_prerequisite = NULL;
static GnomeCanvasItem *item_goal = NULL;
static GnomeCanvasItem *item_manual = NULL;
static GnomeCanvasItem *item_credit = NULL;
static GnomeCanvasItem *item_prerequisite_text = NULL;
static GnomeCanvasItem *item_goal_text = NULL;
static GnomeCanvasItem *item_manual_text = NULL;
static GnomeCanvasItem *item_credit_text = NULL;
static GnomeCanvasItem *item_selected = NULL;
static GnomeCanvasItem *item_selected_text = NULL;
static GtkTextBuffer *buffer_content;
/*
* Main entry point
* ----------------
*
*/
/**
* Return true wether the given board has at least one help field defined
*
*/
gboolean gc_help_has_board (GcomprisBoard *gcomprisBoard)
{
if(!gcomprisBoard)
return FALSE;
prerequisite = gcomprisBoard->prerequisite;
goal = gcomprisBoard->goal;
manual = gcomprisBoard->manual;
credit = gcomprisBoard->credit;
return(prerequisite!=NULL || goal!=NULL || manual!=NULL || credit!=NULL);
}
/*
* Do all the help display and register the events
*/
void gc_help_start (GcomprisBoard *gcomprisBoard)
{
GdkPixbuf *pixmap = NULL;
GnomeCanvasItem *item, *item2;
gint y = 0;
gint y_start = 0;
gint x_start = 0;
gchar *name = NULL;
gchar *text_to_display = NULL;
if(rootitem)
return;
gc_board_pause(TRUE);
item_selected = NULL;
item_selected_text = NULL;
name = gcomprisBoard->title;
gc_help_has_board(gcomprisBoard);
rootitem = \
gnome_canvas_item_new (gnome_canvas_root(gc_get_canvas()),
gnome_canvas_group_get_type (),
"x", (double)0,
"y", (double)0,
NULL);
pixmap = gc_skin_pixmap_load("help_bg.png");
y_start = (BOARDHEIGHT - gdk_pixbuf_get_height(pixmap))/2;
x_start = (BOARDWIDTH - gdk_pixbuf_get_width(pixmap))/2;
item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_pixbuf_get_type (),
"pixbuf", pixmap,
"x", (double) x_start,
"y", (double) y_start,
NULL);
y = BOARDHEIGHT - (BOARDHEIGHT - gdk_pixbuf_get_height(pixmap))/2;
gdk_pixbuf_unref(pixmap);
y_start += 14;
if(gcomprisBoard->section && gcomprisBoard->name) {
text_to_display = g_strdup_printf("%s/%s", gcomprisBoard->section, gcomprisBoard->name);
gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_text_get_type (),
"text", text_to_display,
"font", gc_skin_font_board_tiny,
"x", (double) BOARDWIDTH*0.10 + 1.0,
"y", (double) y_start + 1.0,
"anchor", GTK_ANCHOR_NW,
"fill_color_rgba", gc_skin_color_shadow,
NULL);
gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_text_get_type (),
"text", text_to_display,
"font", gc_skin_font_board_tiny,
"x", (double) BOARDWIDTH*0.10,
"y", (double) y_start,
"anchor", GTK_ANCHOR_NW,
"fill_color_rgba", gc_skin_color_title,
NULL);
g_free(text_to_display);
}
y_start += 35;
gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_text_get_type (),
"text", name,
"font", gc_skin_font_title,
"x", (double) BOARDWIDTH/2 + 1.0,
"y", (double) y_start + 1.0,
"anchor", GTK_ANCHOR_CENTER,
"fill_color_rgba", gc_skin_color_shadow,
"weight", PANGO_WEIGHT_HEAVY,
NULL);
gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_text_get_type (),
"text", name,
"font", gc_skin_font_title,
"x", (double) BOARDWIDTH/2,
"y", (double) y_start,
"anchor", GTK_ANCHOR_CENTER,
"fill_color_rgba", gc_skin_color_title,
"weight", PANGO_WEIGHT_HEAVY,
NULL);
y_start += 120;
pixmap = gc_skin_pixmap_load("button_up.png");
// Prerequisite Button
if(prerequisite)
{
item_prerequisite = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_pixbuf_get_type (),
"pixbuf", pixmap,
"x", (double) (BOARDWIDTH*0.2) - gdk_pixbuf_get_width(pixmap)/2,
"y", (double) y_start - gdk_pixbuf_get_height(pixmap) - 10,
NULL);
gtk_signal_connect(GTK_OBJECT(item_prerequisite), "event",
(GtkSignalFunc) item_event_help,
"prerequisite");
item_prerequisite_text = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_text_get_type (),
"text", _("Prerequisite"),
"font", gc_skin_font_content,
"x", (double) BOARDWIDTH*0.20,
"y", (double) y_start - gdk_pixbuf_get_height(pixmap) + GAP_TO_BUTTON,
"anchor", GTK_ANCHOR_CENTER,
"fill_color_rgba", gc_skin_get_color("gcompris/helpunselect"),
NULL);
gtk_signal_connect(GTK_OBJECT(item_prerequisite_text), "event",
(GtkSignalFunc) item_event_help,
"prerequisite");
}
// Goal Button
if(goal)
{
item_goal = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_pixbuf_get_type (),
"pixbuf", pixmap,
"x", (double) (BOARDWIDTH*0.4) - gdk_pixbuf_get_width(pixmap)/2,
"y", (double) y_start - gdk_pixbuf_get_height(pixmap) - 10,
NULL);
gtk_signal_connect(GTK_OBJECT(item_goal), "event",
(GtkSignalFunc) item_event_help,
"goal");
item_goal_text = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_text_get_type (),
"text", _("Goal"),
"font", gc_skin_font_content,
"x", (double) BOARDWIDTH*0.4,
"y", (double) y_start - gdk_pixbuf_get_height(pixmap) + GAP_TO_BUTTON,
"anchor", GTK_ANCHOR_CENTER,
"fill_color_rgba", gc_skin_get_color("gcompris/helpunselect"),
NULL);
gtk_signal_connect(GTK_OBJECT(item_goal_text), "event",
(GtkSignalFunc) item_event_help,
"goal");
}
// Manual Button
if(manual)
{
item_manual = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_pixbuf_get_type (),
"pixbuf", pixmap,
"x", (double) (BOARDWIDTH*0.6) - gdk_pixbuf_get_width(pixmap)/2,
"y", (double) y_start - gdk_pixbuf_get_height(pixmap) - 10,
NULL);
gtk_signal_connect(GTK_OBJECT(item_manual), "event",
(GtkSignalFunc) item_event_help,
"manual");
item_manual_text = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_text_get_type (),
"text", _("Manual"),
"font", gc_skin_font_content,
"x", (double) BOARDWIDTH*0.6,
"y", (double) y_start - gdk_pixbuf_get_height(pixmap) + GAP_TO_BUTTON,
"anchor", GTK_ANCHOR_CENTER,
"fill_color_rgba", gc_skin_get_color("gcompris/helpunselect"),
NULL);
gtk_signal_connect(GTK_OBJECT(item_manual_text), "event",
(GtkSignalFunc) item_event_help,
"manual");
}
// Credit Button
if(credit)
{
item_credit = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_pixbuf_get_type (),
"pixbuf", pixmap,
"x", (double) (BOARDWIDTH*0.8) - gdk_pixbuf_get_width(pixmap)/2,
"y", (double) y_start - gdk_pixbuf_get_height(pixmap) - 10,
NULL);
gtk_signal_connect(GTK_OBJECT(item_credit), "event",
(GtkSignalFunc) item_event_help,
"credit");
item_credit_text = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_text_get_type (),
"text", _("Credit"),
"font", gc_skin_font_content,
"x", (double) BOARDWIDTH*0.8,
"y", (double) y_start - gdk_pixbuf_get_height(pixmap) + GAP_TO_BUTTON,
"anchor", GTK_ANCHOR_CENTER,
"fill_color_rgba", gc_skin_get_color("gcompris/helpunselect"),
NULL);
gtk_signal_connect(GTK_OBJECT(item_credit_text), "event",
(GtkSignalFunc) item_event_help,
"credit");
}
gdk_pixbuf_unref(pixmap);
// CONTENT
// default text to display
if(prerequisite)
{
text_to_display = prerequisite;
select_item(item_prerequisite, item_prerequisite_text);
}
else if(goal)
{
text_to_display = goal;
select_item(item_goal, item_goal_text);
}
else if(manual)
{
text_to_display = manual;
select_item(item_manual, item_manual_text);
}
else if(credit)
{
text_to_display = credit;
select_item(item_credit, item_credit_text);
}
y_start += 5;
/* Create a scrolled area for the text content */
GtkWidget *view;
GtkWidget *sw;
view = gtk_text_view_new ();
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
gtk_text_view_set_editable(GTK_TEXT_VIEW (view), FALSE);
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (view), FALSE);
gtk_signal_connect(GTK_OBJECT(view), "button-press-event",
(GtkSignalFunc) event_disable_right_click_popup, NULL);
PangoFontDescription *font_desc;
font_desc = pango_font_description_from_string (gc_skin_font_content);
gtk_widget_modify_font (view, font_desc);
pango_font_description_free (font_desc);
GdkColor fg_color;
GdkColor bg_color;
gc_skin_get_gdkcolor("gcompris/helpfg", &fg_color);
gc_skin_get_gdkcolor("gcompris/helpbg", &bg_color);
gtk_widget_modify_base(view, GTK_STATE_NORMAL, &bg_color);
gtk_widget_modify_text(view, GTK_STATE_NORMAL, &fg_color);
buffer_content = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_container_add (GTK_CONTAINER (sw), view);
gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_widget_get_type (),
"widget", GTK_WIDGET(sw),
"x", (double) x_start + 40,
"y", (double) y_start,
"width", 618.0,
"height", 280.0,
NULL);
gtk_widget_show_all (sw);
set_content(text_to_display);
// OK
pixmap = gc_skin_pixmap_load("button_large.png");
item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_pixbuf_get_type (),
"pixbuf", pixmap,
"x", (double) (BOARDWIDTH*0.5) - gdk_pixbuf_get_width(pixmap)/2,
"y", (double) y - gdk_pixbuf_get_height(pixmap) - 5,
NULL);
gtk_signal_connect(GTK_OBJECT(item), "event",
(GtkSignalFunc) item_event_help,
"ok");
gtk_signal_connect(GTK_OBJECT(item), "event",
(GtkSignalFunc) gc_item_focus_event,
NULL);
gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_text_get_type (),
"text", _("OK"),
"font", gc_skin_font_title,
"x", (double) BOARDWIDTH*0.5 + 1.0,
"y", (double) y - gdk_pixbuf_get_height(pixmap) + 20 + 1.0,
"anchor", GTK_ANCHOR_CENTER,
"fill_color_rgba", gc_skin_color_shadow,
"weight", PANGO_WEIGHT_HEAVY,
NULL);
item2 = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
gnome_canvas_text_get_type (),
"text", _("OK"),
"font", gc_skin_font_title,
"x", (double) BOARDWIDTH*0.5,
"y", (double) y - gdk_pixbuf_get_height(pixmap) + 20,
"anchor", GTK_ANCHOR_CENTER,
"fill_color_rgba", gc_skin_color_text_button,
"weight", PANGO_WEIGHT_HEAVY,
NULL);
gtk_signal_connect(GTK_OBJECT(item2), "event",
(GtkSignalFunc) item_event_help,
"ok");
gtk_signal_connect(GTK_OBJECT(item2), "event",
(GtkSignalFunc) gc_item_focus_event,
item);
gdk_pixbuf_unref(pixmap);
gc_bar_hide(TRUE);
help_displayed = TRUE;
}
/*
* Remove the displayed help.
* Do nothing if none is currently being dislayed
*/
void gc_help_stop ()
{
if(help_displayed)
{
// Destroy the help box
if(rootitem!=NULL)
{
gtk_object_destroy(GTK_OBJECT(rootitem));
rootitem = NULL;
}
gc_board_pause(FALSE);
}
gc_bar_hide(FALSE);
help_displayed = FALSE;
}
/*-------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------*/
static void select_item(GnomeCanvasItem *item, GnomeCanvasItem *item_text)
{
GdkPixbuf *pixmap = NULL;
if(item_selected)
{
pixmap = gc_skin_pixmap_load("button_up.png");
/* Warning changing the image needs to update pixbuf_ref for the focus usage */
gc_item_focus_free(item_selected, NULL);
gnome_canvas_item_set(item_selected,
"pixbuf", pixmap,
NULL);
gnome_canvas_item_set(item_selected_text,
"fill_color_rgba", gc_skin_get_color("gcompris/helpunselect"),
NULL);
gdk_pixbuf_unref(pixmap);
}
pixmap = gc_skin_pixmap_load("button_up_selected.png");
/* Warning changing the image needs to update pixbuf_ref for the focus usage */
gc_item_focus_free(item, NULL);
gnome_canvas_item_set(item,
"pixbuf", pixmap,
NULL);
gdk_pixbuf_unref(pixmap);
gnome_canvas_item_set(item_text,
"fill_color_rgba", gc_skin_get_color("gcompris/helpselect"),
NULL);
item_selected = item;
item_selected_text = item_text;
}
/* Apply the style to the given RichText item */
static void set_content(gchar *text)
{
gtk_text_buffer_set_text (buffer_content, "", 0);
gtk_text_buffer_insert_at_cursor(buffer_content, text, -1);
}
/* Callback for the bar operations */
static gint
item_event_help(GnomeCanvasItem *item, GdkEvent *event, gpointer data)
{
switch (event->type)
{
case GDK_ENTER_NOTIFY:
break;
case GDK_LEAVE_NOTIFY:
break;
case GDK_BUTTON_PRESS:
gc_sound_play_ogg ("sounds/bleep.wav", NULL);
if(!strcmp((char *)data, "ok"))
{
gc_help_stop();
}
else if(!strcmp((char *)data, "prerequisite"))
{
select_item(item_prerequisite, item_prerequisite_text);
set_content(prerequisite);
}
else if(!strcmp((char *)data, "goal"))
{
select_item(item_goal, item_goal_text);
set_content(goal);
}
else if(!strcmp((char *)data, "manual"))
{
select_item(item_manual, item_manual_text);
set_content(manual);
}
else if(!strcmp((char *)data, "credit"))
{
select_item(item_credit, item_credit_text);
set_content(credit);
}
default:
break;
}
return FALSE;
}
/* Textview have a popup on right click to copy/paste. We don't want it */
static int
event_disable_right_click_popup(GtkWidget *w, GdkEvent *event, gpointer data)
{
if(event->button.button == 3)
return TRUE;
return FALSE;
}