diff pidgin/gtkdnd-hints.c @ 15374:5fe8042783c1

Rename gtk/ and libgaim/ to pidgin/ and libpurple/
author Sean Egan <seanegan@gmail.com>
date Sat, 20 Jan 2007 02:32:10 +0000
parents
children 32c366eeeb99
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/gtkdnd-hints.c	Sat Jan 20 02:32:10 2007 +0000
@@ -0,0 +1,202 @@
+/*
+ * @file gtkdnd-hints.c GTK+ Drag-and-Drop arrow hints
+ * @ingroup gtkui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or(at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "gtkdnd-hints.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#ifdef _WIN32
+#include "win32dep.h"
+#endif
+
+typedef struct
+{
+	GtkWidget *widget;
+	gchar *filename;
+	gint ox;
+	gint oy;
+
+} HintWindowInfo;
+
+/**
+ * Info about each hint widget. See DndHintWindowId enum.
+ */
+static HintWindowInfo hint_windows[] = { 
+	{ NULL, "tb_drag_arrow_up.xpm",   -13/2,     0 },
+	{ NULL, "tb_drag_arrow_down.xpm", -13/2,   -16 },
+	{ NULL, "tb_drag_arrow_left.xpm",     0, -13/2 },
+	{ NULL, "tb_drag_arrow_right.xpm",  -16, -13/2 },
+	{ NULL, NULL, 0, 0 }
+};
+
+static GtkWidget *
+dnd_hints_init_window(const gchar *fname)
+{
+	GdkPixbuf *pixbuf;
+	GdkPixmap *pixmap;
+	GdkBitmap *bitmap;
+	GtkWidget *pix;
+	GtkWidget *win;
+
+	pixbuf = gdk_pixbuf_new_from_file(fname, NULL);
+	g_return_val_if_fail(pixbuf, NULL);
+
+	gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap, &bitmap, 128);
+	g_object_unref(G_OBJECT(pixbuf));
+
+	gtk_widget_push_colormap(gdk_rgb_get_colormap());
+	win = gtk_window_new(GTK_WINDOW_POPUP);
+	pix = gtk_image_new_from_pixmap(pixmap, bitmap);
+	gtk_container_add(GTK_CONTAINER(win), pix);
+	gtk_widget_shape_combine_mask(win, bitmap, 0, 0);
+	gtk_widget_pop_colormap();
+
+	g_object_unref(G_OBJECT(pixmap));
+	g_object_unref(G_OBJECT(bitmap));
+
+	gtk_widget_show_all(pix);
+
+	return win;
+}
+
+static void
+get_widget_coords(GtkWidget *w, gint *x1, gint *y1, gint *x2, gint *y2)
+{
+	gint ox, oy, width, height;
+
+	if (w->parent && w->parent->window == w->window)
+	{
+		get_widget_coords(w->parent, &ox, &oy, NULL, NULL);
+		ox += w->allocation.x;
+		oy += w->allocation.y;
+		height = w->allocation.height;
+		width = w->allocation.width;
+	}
+	else
+	{
+		gdk_window_get_origin(w->window, &ox, &oy);
+		gdk_drawable_get_size(w->window, &width, &height);
+	}
+
+	if (x1) *x1 = ox;
+	if (y1) *y1 = oy;
+	if (x2) *x2 = ox + width;
+	if (y2) *y2 = oy + height;
+}
+
+static void
+dnd_hints_init(void)
+{
+	static gboolean done = FALSE;
+	gint i;
+
+	if (done)
+		return;
+
+	done = TRUE;
+
+	for (i = 0; hint_windows[i].filename != NULL; i++) {
+		gchar *fname;
+
+		fname = g_build_filename(DATADIR, "pixmaps", "gaim",
+								 hint_windows[i].filename, NULL);
+
+		hint_windows[i].widget = dnd_hints_init_window(fname);
+
+		g_free(fname);
+	}
+}
+
+void
+dnd_hints_hide_all(void)
+{
+	gint i;
+
+	for (i = 0; hint_windows[i].filename != NULL; i++)
+		dnd_hints_hide(i);
+}
+
+void 
+dnd_hints_hide(DndHintWindowId i)
+{
+	GtkWidget *w = hint_windows[i].widget;
+
+	if (w && GTK_IS_WIDGET(w))
+		gtk_widget_hide(w);
+}
+
+void 
+dnd_hints_show(DndHintWindowId id, gint x, gint y)
+{
+	GtkWidget *w;
+
+	dnd_hints_init();
+
+	w = hint_windows[id].widget;
+
+	if (w && GTK_IS_WIDGET(w))
+	{
+		gtk_window_move(GTK_WINDOW(w), hint_windows[id].ox + x,
+								 hint_windows[id].oy + y);
+		gtk_widget_show(w);
+	}
+}
+
+void 
+dnd_hints_show_relative(DndHintWindowId id, GtkWidget *widget,
+						DndHintPosition horiz, DndHintPosition vert)
+{
+	gint x1, x2, y1, y2;
+	gint x = 0, y = 0;
+
+	get_widget_coords(widget, &x1, &y1, &x2, &y2);
+
+	switch (horiz)
+	{
+		case HINT_POSITION_RIGHT:  x = x2;            break;
+		case HINT_POSITION_LEFT:   x = x1;            break;
+		case HINT_POSITION_CENTER: x = (x1 + x2) / 2; break;
+		default:
+			/* should not happen */
+			g_warning("Invalid parameter to dnd_hints_show_relative");
+			break;
+	}
+
+	switch (vert)
+	{
+		case HINT_POSITION_TOP:    y = y1;            break;
+		case HINT_POSITION_BOTTOM: y = y2;            break;
+		case HINT_POSITION_CENTER: y = (y1 + y2) / 2; break;
+		default:
+			/* should not happen */
+			g_warning("Invalid parameter to dnd_hints_show_relative");
+			break;
+	}
+
+	dnd_hints_show(id, x, y);
+}
+