This repository has been archived on 2020-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
gnoemoe/gnoemoe/widgets/gm-world-tab.c

211 lines
5.3 KiB
C

#include <gtk/gtk.h>
#include "gm-world.h"
#include "gm-world-tab.h"
#include "gm-support.h"
#include "gm-pixbuf.h"
#include "gm-debug.h"
#define GM_WORLD_TAB_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GM_TYPE_WORLD_TAB, GmWorldTabPrivate))
void on_gm_world_tab_button_clicked(GtkButton *button, GmWorldTab *tab);
void on_gm_world_tab_world_activity_changed(GmWorld *world, GParamSpec *pspec,
GmWorldTab *tab);
void on_gm_world_tab_world_name_changed(GmWorld *world, GParamSpec *pspec,
GmWorldTab *tab);
struct _GmWorldTabPrivate {
GmWorld *world;
GtkImage *image;
GtkLabel *label;
GtkButton *button;
guint source_id;
};
// Signals
enum {
CLOSE,
NUM_SIGNALS
};
static guint gm_world_tab_signals[NUM_SIGNALS] = {0};
G_DEFINE_TYPE(GmWorldTab, gm_world_tab, GTK_TYPE_HBOX)
static void
gm_world_tab_stop_recolor(GmWorldTab *tab) {
if (tab->priv->source_id != 0) {
g_source_remove(tab->priv->source_id);
tab->priv->source_id = 0;
}
}
static void
gm_world_tab_finalize(GObject *object) {
GmWorldTab *obj = GM_WORLD_TAB(object);
gm_world_tab_stop_recolor(obj);
if (obj->priv->world) {
g_signal_handlers_disconnect_by_func(obj->priv->world,
G_CALLBACK(on_gm_world_tab_world_activity_changed), obj);
g_signal_handlers_disconnect_by_func(obj->priv->world,
G_CALLBACK(on_gm_world_tab_world_name_changed), obj);
g_object_unref(obj->priv->world);
}
G_OBJECT_CLASS(gm_world_tab_parent_class)->finalize(object);
}
static void
gm_world_tab_class_init(GmWorldTabClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
object_class->finalize = gm_world_tab_finalize;
gm_world_tab_signals[CLOSE] =
g_signal_new("close",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmWorldTabClass, close),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
g_type_class_add_private(object_class, sizeof(GmWorldTabPrivate));
}
static void
gm_world_tab_create_interface(GmWorldTab *obj) {
GtkWidget *image, *label, *button, *image_button;
GtkSettings *settings;
gint w, h;
GtkRcStyle *rcstyle;
image = gtk_image_new();
label = gtk_label_new("");
button = gtk_button_new();
image_button = gtk_image_new_from_stock(GTK_STOCK_CLOSE,
GTK_ICON_SIZE_MENU);
settings = gtk_widget_get_settings(GTK_WIDGET(obj));
gtk_icon_size_lookup_for_settings(settings, GTK_ICON_SIZE_MENU, &w, &h);
gtk_widget_set_size_request(button, w + 2, h + 2);
gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
gtk_button_set_focus_on_click(GTK_BUTTON(button), FALSE);
rcstyle = gtk_rc_style_new();
rcstyle->xthickness = rcstyle->ythickness = 0;
gtk_widget_modify_style(button, rcstyle);
gtk_rc_style_unref(rcstyle);
gtk_container_add(GTK_CONTAINER(button), image_button);
gtk_box_pack_start(GTK_BOX(obj), image, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(obj), label, FALSE, FALSE, 0);
gtk_box_pack_end(GTK_BOX(obj), button, FALSE, FALSE, 0);
gtk_box_set_spacing(GTK_BOX(obj), 3);
obj->priv->image = GTK_IMAGE(image);
obj->priv->label = GTK_LABEL(label);
obj->priv->button = GTK_BUTTON(button);
}
static void
gm_world_tab_init(GmWorldTab *obj) {
obj->priv = GM_WORLD_TAB_GET_PRIVATE(obj);
obj->priv->source_id = 0;
obj->priv->world = NULL;
gm_world_tab_create_interface(obj);
g_signal_connect(obj->priv->button, "clicked",
G_CALLBACK(on_gm_world_tab_button_clicked), obj);
gtk_widget_show_all(GTK_WIDGET(obj));
gtk_widget_hide(GTK_WIDGET(obj));
}
gboolean
gm_world_tab_update_color(GmWorldTab *tab) {
gchar *text;
gint activity = gm_world_activity(tab->priv->world);
text = g_strdup_printf("<span color=\"#0000%02x\">%s [%i]</span>",
CALC_COLOR_RANGE(activity),
gm_world_name(tab->priv->world), activity);
gtk_label_set_markup(tab->priv->label, text);
g_free(text);
tab->priv->source_id = 0;
return FALSE;
}
static void
gm_world_tab_update(GmWorldTab *tab) {
gint activity = gm_world_activity(tab->priv->world);
gchar *text;
gm_world_tab_stop_recolor(tab);
if (activity) {
text = g_strdup_printf("<span color=\"#%02x0000\">%s [%i]</span>",
CALC_COLOR_RANGE(activity),
gm_world_name(tab->priv->world), activity);
gtk_image_set_from_pixbuf(tab->priv->image,
gm_pixbuf_get_at_size("world_activity.svg", 16, 16));
tab->priv->source_id = g_idle_add((GSourceFunc)
gm_world_tab_update_color, tab);
} else {
text = g_strdup(gm_world_name(tab->priv->world));
gtk_image_set_from_pixbuf(tab->priv->image,
gm_pixbuf_get_at_size("world.svg", 16, 16));
}
gtk_label_set_markup(tab->priv->label, text);
g_free(text);
}
// Public
GmWorldTab *
gm_world_tab_new(GmWorld *world) {
GmWorldTab *obj = GM_WORLD_TAB(g_object_new(GM_TYPE_WORLD_TAB, NULL));
obj->priv->world = g_object_ref(world);
g_signal_connect(world, "notify::activity",
G_CALLBACK(on_gm_world_tab_world_activity_changed), obj);
g_signal_connect(world, "notify::name",
G_CALLBACK(on_gm_world_tab_world_name_changed), obj);
gm_world_tab_update(obj);
return obj;
}
// Callbacks
void
on_gm_world_tab_button_clicked(GtkButton *button, GmWorldTab *tab) {
g_signal_emit(tab, gm_world_tab_signals[CLOSE], 0);
}
void
on_gm_world_tab_world_activity_changed(GmWorld *world, GParamSpec *pspec,
GmWorldTab *tab) {
gm_world_tab_update(tab);
}
void
on_gm_world_tab_world_name_changed(GmWorld *world, GParamSpec *pspec,
GmWorldTab *tab) {
gm_world_tab_update(tab);
}