From 7accf8e78f73872ef7a82b525ead67f3f5563c24 Mon Sep 17 00:00:00 2001 From: Jesse van den Kieboom Date: Wed, 29 Mar 2006 11:20:06 +0000 Subject: [PATCH] Initial import --- gnoemoe/widgets/gm-worlds-view.c | 282 +++++++++++++++++++++++++++++++ gnoemoe/widgets/gm-worlds-view.h | 67 ++++++++ 2 files changed, 349 insertions(+) create mode 100644 gnoemoe/widgets/gm-worlds-view.c create mode 100644 gnoemoe/widgets/gm-worlds-view.h diff --git a/gnoemoe/widgets/gm-worlds-view.c b/gnoemoe/widgets/gm-worlds-view.c new file mode 100644 index 0000000..af755a4 --- /dev/null +++ b/gnoemoe/widgets/gm-worlds-view.c @@ -0,0 +1,282 @@ +#include +#include +#include "gm-app.h" +#include "gm-pixbuf.h" +#include "gm-worlds-view.h" +#include "gm-world.h" +#include "gm-options.h" +#include "gm-support.h" + +#define GM_WORLDS_VIEW_GET_PRIVATE(object)( \ + G_TYPE_INSTANCE_GET_PRIVATE((object), \ + GM_TYPE_WORLDS_VIEW, GmWorldsViewPrivate)) + +static void on_gm_worlds_view_world_option_changed(GmOptions *options, + gchar const *key, GmWorldsView *view); +static void on_gm_worlds_view_app_world_added(GmApp *app, GmWorld *world, + GmWorldsView *view); +static void on_gm_worlds_view_app_world_removed(GmApp *app, GmWorld *world, + GmWorldsView *view); + +struct _GmWorldsViewPrivate { + GtkTreeModel *model; +}; + +/* Signals + +enum { + PROTO + NUM_SIGNALS +}; + +static guint gm_worlds_view_signals[NUM_SIGNALS] = {0};*/ + +G_DEFINE_TYPE(GmWorldsView, gm_worlds_view, GTK_TYPE_TREE_VIEW) + +static void +gm_worlds_view_finalize(GObject *object) { + GmWorldsView *obj = GM_WORLDS_VIEW(object); + GtkTreeModel *model = obj->priv->model; + GmWorld *list_world; + GtkTreeIter iter; + + if (gtk_tree_model_get_iter_first(model, &iter)) { + do { + gtk_tree_model_get(model, &iter, GM_WORLDS_VIEW_WORLD_COLUMN, + &list_world, -1); + g_signal_handlers_disconnect_by_func(gm_world_options(list_world), + G_CALLBACK(on_gm_worlds_view_world_option_changed), + obj); + } while (gtk_tree_model_iter_next(model, &iter)); + } + + g_signal_handlers_disconnect_by_func(gm_app_instance(), + G_CALLBACK(on_gm_worlds_view_app_world_added), obj); + g_signal_handlers_disconnect_by_func(gm_app_instance(), + G_CALLBACK(on_gm_worlds_view_app_world_removed), obj); + + G_OBJECT_CLASS(gm_worlds_view_parent_class)->finalize(object); +} + +static void +gm_worlds_view_class_init(GmWorldsViewClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + object_class->finalize = gm_worlds_view_finalize; + + /*gm_worlds_view_signals[PROTO] = + g_signal_new("proto", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GmWorldsViewClass, proto), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0);*/ + + g_type_class_add_private(object_class, sizeof(GmWorldsViewPrivate)); +} + +static void +gm_worlds_view_init(GmWorldsView *obj) { + obj->priv = GM_WORLDS_VIEW_GET_PRIVATE(obj); +} + +static gchar * +gm_worlds_view_world_text(GmWorldsView *view, GmWorld *world) { + gchar *text; + gchar const *player, *server; + GmOptions *options = gm_world_options(world); + + player = gm_options_get(options, "player_name"); + server = gm_options_get(options, "host"); + + text = g_strconcat("", gm_options_get(options, "name"), + _("\nServer: "), + ((server && *server != '\0') ? server : _("unspecified")), + _("\nPlayer: "), + ((player && *player != '\0') ? player : _("unspecified")), + "", + NULL); + + return text; +} + +static void +gm_worlds_view_populate_worlds(GmWorldsView *view) { + GmApp *app = gm_app_instance(); + GList *worlds = gm_app_worlds(app); + GList *item; + GmWorld *world; + + for (item = worlds; item; item = item->next) { + world = (GmWorld *)(item->data); + gm_worlds_view_add_world(view, world); + } + + g_list_free(worlds); +} + +static void +gm_worlds_view_build(GmWorldsView *view) { + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkTreeView *tree_view = GTK_TREE_VIEW(view); + + view->priv->model = GTK_TREE_MODEL(gtk_list_store_new( + GM_WORLDS_VIEW_N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, + G_TYPE_POINTER, G_TYPE_STRING)); + + gtk_tree_view_set_model(tree_view, view->priv->model); + gtk_tree_selection_set_mode(gtk_tree_view_get_selection(tree_view), + GTK_SELECTION_MULTIPLE); + + renderer = gtk_cell_renderer_pixbuf_new(); + column = gtk_tree_view_column_new_with_attributes(_("Logo"), renderer, + "pixbuf", GM_WORLDS_VIEW_LOGO_COLUMN, NULL); + gtk_tree_view_column_set_min_width(column, 40); + gtk_tree_view_append_column(tree_view, column); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, + "markup", GM_WORLDS_VIEW_NAME_COLUMN, NULL); + gtk_tree_view_append_column(tree_view, column); + + gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(view->priv->model), + GM_WORLDS_VIEW_SORT_COLUMN, GTK_SORT_ASCENDING); + + gm_worlds_view_populate_worlds(view); +} + +static gboolean +gm_worlds_view_find_by_options(GmWorldsView *view, GmOptions *options, + GtkTreeIter *iter, GmWorld **world) { + GtkTreeModel *model = view->priv->model; + GmWorld *list_world; + + if (gtk_tree_model_get_iter_first(model, iter)) { + do { + gtk_tree_model_get(model, iter, GM_WORLDS_VIEW_WORLD_COLUMN, + &list_world, -1); + + if (options == gm_world_options(list_world)) { + if (world != NULL) { + *world = list_world; + } + + return TRUE; + } + } while (gtk_tree_model_iter_next(model, iter)); + } + + return FALSE; +} + +static gboolean +gm_worlds_view_find(GmWorldsView *view, GmWorld *world, GtkTreeIter *iter) { + return gm_worlds_view_find_by_options(view, gm_world_options(world), iter, + NULL); +} + +/* Public */ +GtkWidget * +gm_worlds_view_new() { + GmWorldsView *obj = GM_WORLDS_VIEW(g_object_new(GM_TYPE_WORLDS_VIEW, NULL)); + + gm_worlds_view_build(obj); + gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(obj), FALSE); + + g_signal_connect(gm_app_instance(), "world_added", + G_CALLBACK(on_gm_worlds_view_app_world_added), obj); + g_signal_connect(gm_app_instance(), "world_removed", + G_CALLBACK(on_gm_worlds_view_app_world_removed), obj); + + return GTK_WIDGET(obj); +} + +void +gm_worlds_view_add_world(GmWorldsView *view, GmWorld *world) { + GtkTreeIter iter; + GdkPixbuf *pix_logo = NULL; + gchar *name = gm_worlds_view_world_text(view, world); + gchar const *logo = gm_options_get(gm_world_options(world), "logo"); + GtkListStore *store = GTK_LIST_STORE(view->priv->model); + + if (logo) { + pix_logo = gm_pixbuf_get_at_size(logo, 32, 32); + } + + if (!pix_logo) { + pix_logo = gm_pixbuf_get_at_size("world.svg", 32, 32); + } + + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + GM_WORLDS_VIEW_LOGO_COLUMN, pix_logo, + GM_WORLDS_VIEW_NAME_COLUMN, name, + GM_WORLDS_VIEW_WORLD_COLUMN, world, + GM_WORLDS_VIEW_SORT_COLUMN, gm_world_name(world), + -1); + + g_signal_connect(gm_world_options(world), "option_changed", + G_CALLBACK(on_gm_worlds_view_world_option_changed), view); + + g_free(name); +} + +GtkTreeModel * +gm_worlds_view_model(GmWorldsView *view) { + return view->priv->model; +} + +/* Callbacks */ + +static void +on_gm_worlds_view_world_option_changed(GmOptions *options, + gchar const *key, GmWorldsView *view) { + GtkTreeIter iter; + GtkListStore *store = GTK_LIST_STORE(view->priv->model); + gchar *text; + gchar const *logo; + GdkPixbuf *pix_logo; + GmWorld *world; + + if (!gm_worlds_view_find_by_options(view, options, &iter, &world)) { + return; + } + + if (strcmp(key, "name") == 0 || + strcmp(key, "player_name") == 0 || + strcmp(key, "host") == 0) { + text = gm_worlds_view_world_text(view, world); + gtk_list_store_set(store, &iter, GM_WORLDS_VIEW_NAME_COLUMN, text, -1); + g_free(text); + } else if (strcmp(key, "logo")) { + logo = gm_options_get(options, "logo"); + + if (logo) { + pix_logo = gm_pixbuf_get_at_size(logo, 32, 32); + } else { + pix_logo = gm_pixbuf_get_at_size("world.svg", 32, 32); + } + + gtk_list_store_set(store, &iter, GM_WORLDS_VIEW_LOGO_COLUMN, + pix_logo, -1); + } +} + +static void +on_gm_worlds_view_app_world_added(GmApp *app, GmWorld *world, + GmWorldsView *view) { + gm_worlds_view_add_world(view, world); +} + +static void +on_gm_worlds_view_app_world_removed(GmApp *app, GmWorld *world, + GmWorldsView *view) { + GtkTreeIter iter; + + if (gm_worlds_view_find(view, world, &iter)) { + gtk_list_store_remove(GTK_LIST_STORE(view->priv->model), &iter); + } +} diff --git a/gnoemoe/widgets/gm-worlds-view.h b/gnoemoe/widgets/gm-worlds-view.h new file mode 100644 index 0000000..de4d0cf --- /dev/null +++ b/gnoemoe/widgets/gm-worlds-view.h @@ -0,0 +1,67 @@ +#ifndef __GM_WORLDS_VIEW_H__ +#define __GM_WORLDS_VIEW_H__ + +#include + +G_BEGIN_DECLS + +/* + * Type checking and casting macros + */ +#define GM_TYPE_WORLDS_VIEW (gm_worlds_view_get_type()) +#define GM_WORLDS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GM_TYPE_WORLDS_VIEW, GmWorldsView)) +#define GM_WORLDS_VIEW_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GM_TYPE_WORLDS_VIEW, GmWorldsView const)) +#define GM_WORLDS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \ + GM_TYPE_WORLDS_VIEW, GmWorldsViewClass)) +#define GM_IS_WORLDS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \ + GM_TYPE_WORLDS_VIEW)) +#define GM_IS_WORLDS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + GM_TYPE_WORLDS_VIEW)) +#define GM_WORLDS_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \ + GM_TYPE_WORLDS_VIEW, GmWorldsViewClass)) + +enum { + GM_WORLDS_VIEW_LOGO_COLUMN, + GM_WORLDS_VIEW_NAME_COLUMN, + GM_WORLDS_VIEW_WORLD_COLUMN, + GM_WORLDS_VIEW_SORT_COLUMN, + GM_WORLDS_VIEW_N_COLUMNS +}; + +/* Private structure type */ +typedef struct _GmWorldsViewPrivate GmWorldsViewPrivate; + +/* + * Main object structure + */ +typedef struct _GmWorldsView GmWorldsView; + +struct _GmWorldsView { + GtkTreeView parent; + + /*< private > */ + GmWorldsViewPrivate *priv; +}; + +/* + * Class definition + */ +typedef struct _GmWorldsViewClass GmWorldsViewClass; + +struct _GmWorldsViewClass { + GtkTreeViewClass parent_class; + + /* Signals + void (* proto) (GmWorldsView *obj); */ +}; + +GType gm_worlds_view_get_type(void) G_GNUC_CONST; +GtkWidget *gm_worlds_view_new(); + +void gm_worlds_view_add_world(GmWorldsView *view, GmWorld *world); +GtkTreeModel *gm_worlds_view_model(GmWorldsView *view); + +G_END_DECLS +#endif /* __GM_WORLDS_VIEW_H__ */