2 * @file gtkdnd-hints.c GTK+ Drag-and-Drop arrow hints
8 * Pidgin is the legal property of its developers, whose names are too numerous
9 * to list here. Please refer to the COPYRIGHT file distributed with this
10 * source distribution.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or(at your option)
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, USA.
27 #include "gtkdnd-hints.h"
31 #include <gdk-pixbuf/gdk-pixbuf.h>
47 * Info about each hint widget. See DndHintWindowId enum.
49 static HintWindowInfo hint_windows
[] = {
50 { NULL
, "arrow-up.xpm", -13/2, 0 },
51 { NULL
, "arrow-down.xpm", -13/2, -16 },
52 { NULL
, "arrow-left.xpm", 0, -13/2 },
53 { NULL
, "arrow-right.xpm", -16, -13/2 },
58 dnd_hints_init_window(const gchar
*fname
)
66 pixbuf
= gdk_pixbuf_new_from_file(fname
, NULL
);
67 g_return_val_if_fail(pixbuf
, NULL
);
69 gdk_pixbuf_render_pixmap_and_mask(pixbuf
, &pixmap
, &bitmap
, 128);
70 g_object_unref(G_OBJECT(pixbuf
));
72 gtk_widget_push_colormap(gdk_rgb_get_colormap());
73 win
= gtk_window_new(GTK_WINDOW_POPUP
);
74 pix
= gtk_image_new_from_pixmap(pixmap
, bitmap
);
75 gtk_container_add(GTK_CONTAINER(win
), pix
);
76 gtk_widget_shape_combine_mask(win
, bitmap
, 0, 0);
77 gtk_widget_pop_colormap();
79 g_object_unref(G_OBJECT(pixmap
));
80 g_object_unref(G_OBJECT(bitmap
));
82 gtk_widget_show_all(pix
);
88 get_widget_coords(GtkWidget
*w
, gint
*x1
, gint
*y1
, gint
*x2
, gint
*y2
)
90 gint ox
, oy
, width
, height
;
92 if (w
->parent
&& w
->parent
->window
== w
->window
)
94 get_widget_coords(w
->parent
, &ox
, &oy
, NULL
, NULL
);
95 height
= w
->allocation
.height
;
96 width
= w
->allocation
.width
;
100 gdk_window_get_origin(w
->window
, &ox
, &oy
);
101 gdk_drawable_get_size(w
->window
, &width
, &height
);
106 if (x2
) *x2
= ox
+ width
;
107 if (y2
) *y2
= oy
+ height
;
113 static gboolean done
= FALSE
;
121 for (i
= 0; hint_windows
[i
].filename
!= NULL
; i
++) {
124 fname
= g_build_filename(DATADIR
, "pixmaps", "pidgin",
125 hint_windows
[i
].filename
, NULL
);
127 hint_windows
[i
].widget
= dnd_hints_init_window(fname
);
134 dnd_hints_hide_all(void)
138 for (i
= 0; hint_windows
[i
].filename
!= NULL
; i
++)
143 dnd_hints_hide(DndHintWindowId i
)
145 GtkWidget
*w
= hint_windows
[i
].widget
;
147 if (w
&& GTK_IS_WIDGET(w
))
152 dnd_hints_show(DndHintWindowId id
, gint x
, gint y
)
158 w
= hint_windows
[id
].widget
;
160 if (w
&& GTK_IS_WIDGET(w
))
162 gtk_window_move(GTK_WINDOW(w
), hint_windows
[id
].ox
+ x
,
163 hint_windows
[id
].oy
+ y
);
169 dnd_hints_show_relative(DndHintWindowId id
, GtkWidget
*widget
,
170 DndHintPosition horiz
, DndHintPosition vert
)
175 get_widget_coords(widget
, &x1
, &y1
, &x2
, &y2
);
176 x1
+= widget
->allocation
.x
; x2
+= widget
->allocation
.x
;
177 y1
+= widget
->allocation
.y
; y2
+= widget
->allocation
.y
;
181 case HINT_POSITION_RIGHT
: x
= x2
; break;
182 case HINT_POSITION_LEFT
: x
= x1
; break;
183 case HINT_POSITION_CENTER
: x
= (x1
+ x2
) / 2; break;
185 /* should not happen */
186 g_warning("Invalid parameter to dnd_hints_show_relative");
192 case HINT_POSITION_TOP
: y
= y1
; break;
193 case HINT_POSITION_BOTTOM
: y
= y2
; break;
194 case HINT_POSITION_CENTER
: y
= (y1
+ y2
) / 2; break;
196 /* should not happen */
197 g_warning("Invalid parameter to dnd_hints_show_relative");
201 dnd_hints_show(id
, x
, y
);