#include #include "gm-mcp-package.h" #include "gm-mcp-userlist-view.h" #include "../widgets/gm-world-view.h" #include "../gm-pixbuf.h" #include "../gm-debug.h" #define GM_USERLIST_ICON_SIZE 22 enum { GM_USERLIST_ICON, GM_USERLIST_NAME, GM_USERLIST_ID, GM_USERLIST_SORT, GM_USERLIST_N_COLUMNS }; typedef struct _GmMcpUserlistView { GmWorldView *view; GmMcpPackage *package; GtkTreeModel *model; GtkListStore *store; GtkTreeView *tree_view; GtkScrolledWindow *scrolled_window; } GmMcpUserlistView; void on_gm_mcp_userlist_view_weak_notify(gpointer data, GObject *obj); void on_gm_mcp_userlist_view_player_added(GmMcpPackage *package, gint id, gchar const *name, gchar const *icon, gchar const *sort, GmMcpUserlistView *view); void on_gm_mcp_userlist_view_player_removed(GmMcpPackage *package, gint id, GmMcpUserlistView *view); void on_gm_mcp_userlist_view_name_changed(GmMcpPackage *package, gint id, gchar const *name, gchar const *sort, GmMcpUserlistView *view); void on_gm_mcp_userlist_view_rank_changed(GmMcpPackage *package, gint id, gchar const *icon, gchar const *sort, GmMcpUserlistView *view); void on_gm_mcp_userlist_view_state_changed(GmMcpPackage *package, gint id, gchar const *icon, gchar const *sort, GmMcpUserlistView *view); GtkTreeModel * gm_mcp_userlist_view_model_create(GmMcpUserlistView *view) { GtkListStore *store = gtk_list_store_new(GM_USERLIST_N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING); GtkTreeModel *model = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL( store)); view->store = store; view->model = model; return model; } GtkWidget * gm_mcp_userlist_view_create_userlist(GmMcpUserlistView *view) { GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL); GtkTreeModel *model = gm_mcp_userlist_view_model_create(view); GtkWidget *tree_view = gtk_tree_view_new_with_model(model); GtkCellRenderer *renderer; GtkTreeViewColumn *column; gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_IN); gtk_widget_set_size_request(scrolled_window, 150, -1); gtk_widget_set_size_request(tree_view, 150, -1); gtk_container_add(GTK_CONTAINER(scrolled_window), tree_view); renderer = gtk_cell_renderer_pixbuf_new(); column = gtk_tree_view_column_new_with_attributes(_("I"), renderer, "pixbuf", GM_USERLIST_ICON, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column); gtk_tree_view_column_set_min_width(column, 30); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "text", GM_USERLIST_NAME, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), GM_USERLIST_SORT, GTK_SORT_ASCENDING); GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(tree_view), GTK_CAN_FOCUS); gtk_tree_view_columns_autosize(GTK_TREE_VIEW(tree_view)); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree_view), FALSE); view->tree_view = GTK_TREE_VIEW(tree_view); view->scrolled_window = GTK_SCROLLED_WINDOW(scrolled_window); return scrolled_window; } void gm_mcp_userlist_view_new(GmMcpPackage *package, GObject *parent) { GmMcpUserlistView *view; GtkPaned *paned; GtkWidget *vbox, *child; if (!GM_IS_WORLD_VIEW(parent)) { return; } view = g_new(GmMcpUserlistView, 1); view->view = GM_WORLD_VIEW(parent); view->package = package; paned = GTK_PANED(gm_world_view_hpaned(view->view)); vbox = gtk_paned_get_child2(paned); if (vbox == NULL) { vbox = gtk_vbox_new(FALSE, 6); gtk_paned_pack2(paned, vbox, FALSE, TRUE); } child = gm_mcp_userlist_view_create_userlist(view); gtk_box_pack_end(GTK_BOX(vbox), child, TRUE, TRUE, 0); gtk_widget_show_all(vbox); g_signal_connect(package, "player_added", G_CALLBACK(on_gm_mcp_userlist_view_player_added), view); g_signal_connect(package, "player_removed", G_CALLBACK(on_gm_mcp_userlist_view_player_removed), view); g_signal_connect(package, "name_changed", G_CALLBACK(on_gm_mcp_userlist_view_name_changed), view); g_signal_connect(package, "state_changed", G_CALLBACK(on_gm_mcp_userlist_view_state_changed), view); g_signal_connect(package, "rank_changed", G_CALLBACK(on_gm_mcp_userlist_view_rank_changed), view); g_object_weak_ref(G_OBJECT(package), on_gm_mcp_userlist_view_weak_notify, view); } /* Callbacks */ void on_gm_mcp_userlist_view_weak_notify(gpointer data, GObject *obj) { GmMcpUserlistView *view = (GmMcpUserlistView *)(data); GtkWidget *vbox; GList *children; if (GM_IS_WORLD_VIEW(view->view)) { GM_DEBUG("Destroying scrolled window!"); gtk_widget_destroy(GTK_WIDGET(view->scrolled_window)); vbox = gtk_paned_get_child2(GTK_PANED(gm_world_view_hpaned( view->view))); if (vbox != NULL) { GM_DEBUG("VBox is still there!"); children = gtk_container_get_children(GTK_CONTAINER(vbox)); if (children == NULL) { GM_DEBUG("VBox is empty, remove it!"); gtk_widget_destroy(vbox); } g_list_free(children); } } g_free(data); } gboolean gm_mcp_userlist_view_find(GmMcpUserlistView *view, gint id, GtkTreeIter *iter) { GtkTreeModel *model = GTK_TREE_MODEL(view->store); gint iterid; if (gtk_tree_model_get_iter_first(model, iter)) { do { gtk_tree_model_get(model, iter, GM_USERLIST_ID, &iterid, -1); if (iterid == id) { return TRUE; } } while (gtk_tree_model_iter_next(model, iter)); } return FALSE; } void on_gm_mcp_userlist_view_player_added(GmMcpPackage *package, gint id, gchar const *name, gchar const *icon, gchar const *sort, GmMcpUserlistView *view) { GtkTreeIter iter; if (gm_mcp_userlist_view_find(view, id, &iter)) { gm_debug_msg(DEBUG_MCP, "GmMcpUserlistView.OnPlayerAdded: player %d " "is already in the list, can't be added twice!", id); return; } gtk_list_store_append(view->store, &iter); gtk_list_store_set(view->store, &iter, GM_USERLIST_ID, id, GM_USERLIST_ICON, gm_pixbuf_get_at_size(icon, GM_USERLIST_ICON_SIZE, GM_USERLIST_ICON_SIZE), GM_USERLIST_NAME, name, GM_USERLIST_SORT, sort, -1); } void on_gm_mcp_userlist_view_player_removed(GmMcpPackage *package, gint id, GmMcpUserlistView *view) { GtkTreeIter iter; if (!gm_mcp_userlist_view_find(view, id, &iter)) { gm_debug_msg(DEBUG_MCP, "GmMcpUserlistView.OnPlayerRemoved: player %d " "is not in the list, can't be removed!", id); return; } gtk_list_store_remove(view->store, &iter); } void on_gm_mcp_userlist_view_name_changed(GmMcpPackage *package, gint id, gchar const *name, gchar const *sort, GmMcpUserlistView *view) { GtkTreeIter iter; if (!gm_mcp_userlist_view_find(view, id, &iter)) { gm_debug_msg(DEBUG_MCP, "GmMcpUserlistView.OnNameChanged: player %d " "is not in the list!", id); return; } gtk_list_store_set(view->store, &iter, GM_USERLIST_NAME, name, -1); if (sort) { gtk_list_store_set(view->store, &iter, GM_USERLIST_SORT, sort, -1); } } void on_gm_mcp_userlist_view_rank_changed(GmMcpPackage *package, gint id, gchar const *icon, gchar const *sort, GmMcpUserlistView *view) { GtkTreeIter iter; if (!gm_mcp_userlist_view_find(view, id, &iter)) { gm_debug_msg(DEBUG_MCP, "GmMcpUserlistView.OnRankChanged: player %d " "is not in the list!", id); return; } gtk_list_store_set(view->store, &iter, GM_USERLIST_ICON, gm_pixbuf_get_at_size(icon, GM_USERLIST_ICON_SIZE, GM_USERLIST_ICON_SIZE), -1); if (sort) { gtk_list_store_set(view->store, &iter, GM_USERLIST_SORT, sort, -1); } } void on_gm_mcp_userlist_view_state_changed(GmMcpPackage *package, gint id, gchar const *icon, gchar const *sort, GmMcpUserlistView *view) { GtkTreeIter iter; if (!gm_mcp_userlist_view_find(view, id, &iter)) { gm_debug_msg(DEBUG_MCP, "GmMcpUserlistView.OnStateChanged: player %d " "is not in the list!", id); return; } gtk_list_store_set(view->store, &iter, GM_USERLIST_ICON, gm_pixbuf_get_at_size(icon, GM_USERLIST_ICON_SIZE, GM_USERLIST_ICON_SIZE), -1); if (sort) { gtk_list_store_set(view->store, &iter, GM_USERLIST_SORT, sort, -1); } }