gui/model: Configure the gui model as a drag source

We'll need to do this to enable drag and drop to reorder playlists.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2018-04-19 09:42:51 -04:00
parent a9970c455f
commit 77efa0c631
3 changed files with 54 additions and 0 deletions

View File

@ -28,6 +28,12 @@ static GType gui_model_columns[GUI_MODEL_N_COLUMNS] = {
[GUI_MODEL_FONT] = G_TYPE_STRING, [GUI_MODEL_FONT] = G_TYPE_STRING,
}; };
const GtkTargetEntry gui_model_drag_targets[] = {
{ GUI_DRAG_DATA, GTK_TARGET_SAME_APP, 0 },
};
const unsigned int gui_model_n_targets = G_N_ELEMENTS(gui_model_drag_targets);
static GtkTreeModelFlags __gui_model_get_flags(GtkTreeModel *model) static GtkTreeModelFlags __gui_model_get_flags(GtkTreeModel *model)
{ {
return GTK_TREE_MODEL_LIST_ONLY; return GTK_TREE_MODEL_LIST_ONLY;
@ -169,6 +175,27 @@ static gboolean __gui_model_iter_parent(GtkTreeModel *model, GtkTreeIter *iter,
return FALSE; return FALSE;
} }
static gboolean __gui_model_drag_data_get(GtkTreeDragSource *drag_source,
GtkTreePath *path,
GtkSelectionData *selection_data)
{
struct gui_model_drag_data *data = g_malloc(sizeof(*data));
data->drag_row = gtk_tree_path_get_indices(path)[0];
data->drag_track = gui_model_path_get_track(path);
gtk_selection_data_set(selection_data, gdk_atom_intern(GUI_DRAG_DATA, false),
8 /* bytes */, (void *)data, sizeof(*data));
g_free(data);
return true;
}
static gboolean __gui_model_drag_data_delete(GtkTreeDragSource *drag_source,
GtkTreePath *path)
{
return true;
}
static void __gui_model_init(GuiModel *model) static void __gui_model_init(GuiModel *model)
{ {
model->gm_stamp = g_random_int(); model->gm_stamp = g_random_int();
@ -203,6 +230,12 @@ static void __gui_tree_model_init(GtkTreeModelIface *iface)
iface->iter_parent = __gui_model_iter_parent; iface->iter_parent = __gui_model_iter_parent;
} }
static void __gui_drag_source_init(GtkTreeDragSourceIface *iface)
{
iface->drag_data_get = __gui_model_drag_data_get;
iface->drag_data_delete = __gui_model_drag_data_delete;
}
static const GTypeInfo gui_model_type_info = { static const GTypeInfo gui_model_type_info = {
.class_size = sizeof(GuiModelClass), .class_size = sizeof(GuiModelClass),
.base_init = NULL, .base_init = NULL,
@ -221,6 +254,12 @@ static const GInterfaceInfo gui_tree_model = {
.interface_data = NULL, .interface_data = NULL,
}; };
static const GInterfaceInfo gui_drag_source = {
.interface_init = (GInterfaceInitFunc)__gui_drag_source_init,
.interface_finalize = NULL,
.interface_data = NULL,
};
void gui_model_init(void) void gui_model_init(void)
{ {
@ -229,6 +268,9 @@ void gui_model_init(void)
(GTypeFlags)0); (GTypeFlags)0);
g_type_add_interface_static(gui_model_type, GTK_TYPE_TREE_MODEL, g_type_add_interface_static(gui_model_type, GTK_TYPE_TREE_MODEL,
&gui_tree_model); &gui_tree_model);
g_type_add_interface_static(gui_model_type, GTK_TYPE_TREE_DRAG_SOURCE,
&gui_drag_source);
gui_model = g_object_new(gui_model_type, NULL); gui_model = g_object_new(gui_model_type, NULL);
g_assert(gui_model != NULL); g_assert(gui_model != NULL);

View File

@ -167,6 +167,9 @@ void gui_treeview_init()
gtk_tree_view_set_model(gui_treeview(), gtk_tree_view_set_model(gui_treeview(),
GTK_TREE_MODEL(gui_filter_get())); GTK_TREE_MODEL(gui_filter_get()));
gtk_tree_view_enable_model_drag_source(gui_treeview(), GDK_BUTTON1_MASK,
gui_model_drag_targets, gui_model_n_targets,
GDK_ACTION_MOVE);
for (i = 0; i < GUI_MODEL_N_COLUMNS; i++) { for (i = 0; i < GUI_MODEL_N_COLUMNS; i++) {
col = gtk_tree_view_get_column(gui_treeview(), i); col = gtk_tree_view_get_column(gui_treeview(), i);

View File

@ -38,6 +38,15 @@ struct gui_model_class {
}; };
typedef struct gui_model_class GuiModelClass; typedef struct gui_model_class GuiModelClass;
struct gui_model_drag_data {
unsigned int drag_row;
struct track *drag_track;
};
#define GUI_DRAG_DATA "GUI_DRAG_DATA"
extern const GtkTargetEntry gui_model_drag_targets[];
extern const unsigned int gui_model_n_targets;
/* Called to initialize the GuiModel */ /* Called to initialize the GuiModel */
void gui_model_init(void); void gui_model_init(void);