ドラッグ&ドロップ

GUIの真骨頂とも言える(?)ドラッグ&ドロップをやってみます。
ウィンドウ(正しくはGtkLabel)にドロップされたファイルのパスを表示させるという簡単なもの。
今回はGladeは使わず、1ファイルでケリをつけています。


DnD.c

#include

#define DND_INFO_TEXT_URI_LIST 10

static GtkTargetEntry target[] = {
{ "text/uri-list", 0, DND_INFO_TEXT_URI_LIST }
};

void drag_data_received(GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *data,
guint info,
guint time_,
gpointer user_data)
{
gchar *fname = g_filename_from_uri(*g_uri_list_extract_uris(data->data), NULL, NULL);
gtk_label_set_text (user_data, fname);
}

int main(int argc, char ** argv)
{
GtkWidget *window;
GtkWidget *label;

gtk_init(&argc, &argv);

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "DnD");

gtk_window_set_default_size(GTK_WINDOW(window), 150, 150);

g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);

label = gtk_label_new("ここにドロップ");

gtk_widget_set_size_request(label, 150, 150);
gtk_container_add(GTK_CONTAINER(window), label);

g_signal_connect(G_OBJECT(label), "drag-data-received",
G_CALLBACK(drag_data_received), label);

gtk_drag_dest_set(label, GTK_DEST_DEFAULT_ALL, target, 1, GDK_ACTION_COPY);
gtk_widget_show_all(window);

gtk_main();
return 0;
}

ピンクの網掛け部分が、今回特有の部分です。
gtk_drag_dest_setの引数の1は、ドロップできるファイルの数(正確には1回に受け取れるデータ組の数)
詳しくは参考資料を読んでください ^^;


なかなか全ての動作を理解する、というところまではいきませんが、
ここからファイルオープンにつなげるのはすぐに出来そうです。

もっと突っ込もうとと思ったらURIやGdkAtomなんかについても勉強しないといけないかな..


参考資料


一応Makefile

Makefile

CC = gcc

CFLAGS = `pkg-config --cflags gtk+-2.0`

LDFLAGS = `pkg-config --libs-only-L gtk+-2.0`

LIBS = `pkg-config --libs-only-l gtk+-2.0`

SRCS = DnD.c

OBJS = $(SRCS:.c=.o)

PROGRAM = DnD

all: $(PROGRAM)

$(PROGRAM): $(OBJS) $(HDRS)
$(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $(PROGRAM)

clean:; rm -f *.o *~ $(PROGRAM)

### End of Makefile

$(CC)の前の空白はtab
`はバッククォート(日本語キーボードならshift + @)