Initial import

This commit is contained in:
Jesse van den Kieboom 2006-03-29 11:20:06 +00:00
parent 98a61810e4
commit 7accf8e78f
2 changed files with 349 additions and 0 deletions

View File

@ -0,0 +1,282 @@
#include <gtk/gtk.h>
#include <string.h>
#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("<b>", gm_options_get(options, "name"),
_("</b>\n<small>Server: "),
((server && *server != '\0') ? server : _("<i>unspecified</i>")),
_("\nPlayer: "),
((player && *player != '\0') ? player : _("<i>unspecified</i>")),
"</small>",
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);
}
}

View File

@ -0,0 +1,67 @@
#ifndef __GM_WORLDS_VIEW_H__
#define __GM_WORLDS_VIEW_H__
#include <gtk/gtk.h>
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__ */