Merged pidgin/main into default
[pidgin-git.git] / pidgin / gtkscrollbook.c
blobcf8d799351711227d746e8bdae32111749af64c4
1 /* pidgin
3 * Pidgin is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
5 * source distribution.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
22 #include "gtkscrollbook.h"
24 #include "gtk3compat.h"
26 static void pidgin_scroll_book_init (PidginScrollBook *scroll_book);
27 static void pidgin_scroll_book_class_init (PidginScrollBookClass *klass);
28 static void pidgin_scroll_book_forall (GtkContainer *c,
29 gboolean include_internals,
30 GtkCallback callback,
31 gpointer user_data);
33 GType
34 pidgin_scroll_book_get_type (void)
36 static GType scroll_book_type = 0;
38 if (!scroll_book_type)
40 static const GTypeInfo scroll_book_info =
42 sizeof (PidginScrollBookClass),
43 NULL, /* base_init */
44 NULL, /* base_finalize */
45 (GClassInitFunc) pidgin_scroll_book_class_init,
46 NULL, /* class_finalize */
47 NULL, /* class_data */
48 sizeof (PidginScrollBook),
50 (GInstanceInitFunc) pidgin_scroll_book_init,
51 NULL /* value_table */
54 scroll_book_type = g_type_register_static(GTK_TYPE_BOX,
55 "PidginScrollBook",
56 &scroll_book_info,
57 0);
60 return scroll_book_type;
63 static gboolean
64 scroll_left_cb(PidginScrollBook *scroll_book, GdkEventButton *event)
66 int index;
68 if (event->type != GDK_BUTTON_PRESS)
69 return FALSE;
71 index = gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book->notebook));
73 if (index > 0)
74 gtk_notebook_set_current_page(GTK_NOTEBOOK(scroll_book->notebook), index - 1);
75 return TRUE;
78 static gboolean
79 scroll_right_cb(PidginScrollBook *scroll_book, GdkEventButton *event)
81 int index, count;
83 if (event->type != GDK_BUTTON_PRESS)
84 return FALSE;
86 index = gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book->notebook));
87 count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book->notebook));
89 if (index + 1 < count)
90 gtk_notebook_set_current_page(GTK_NOTEBOOK(scroll_book->notebook), index + 1);
91 return TRUE;
94 static void
95 refresh_scroll_box(PidginScrollBook *scroll_book, int index, int count)
97 char *label;
99 gtk_widget_show_all(GTK_WIDGET(scroll_book));
100 if (count < 1)
101 gtk_widget_hide(scroll_book->hbox);
102 else {
103 gtk_widget_show_all(scroll_book->hbox);
104 if (count == 1) {
105 gtk_widget_hide(scroll_book->label);
106 gtk_widget_hide(scroll_book->left_arrow);
107 gtk_widget_hide(scroll_book->right_arrow);
111 label = g_strdup_printf("<span size='smaller' weight='bold'>(%d/%d)</span>", index+1, count);
112 gtk_label_set_markup(GTK_LABEL(scroll_book->label), label);
113 g_free(label);
115 if (index == 0)
116 gtk_widget_set_sensitive(scroll_book->left_arrow, FALSE);
117 else
118 gtk_widget_set_sensitive(scroll_book->left_arrow, TRUE);
121 if (index + 1 == count)
122 gtk_widget_set_sensitive(scroll_book->right_arrow, FALSE);
123 else
124 gtk_widget_set_sensitive(scroll_book->right_arrow, TRUE);
128 static void
129 page_count_change_cb(PidginScrollBook *scroll_book)
131 int count;
132 int index = gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book->notebook));
133 count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book->notebook));
134 refresh_scroll_box(scroll_book, index, count);
137 static gboolean
138 scroll_close_cb(PidginScrollBook *scroll_book, GdkEventButton *event)
140 if (event->type == GDK_BUTTON_PRESS)
141 gtk_widget_destroy(gtk_notebook_get_nth_page(GTK_NOTEBOOK(scroll_book->notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book->notebook))));
142 return FALSE;
145 static void
146 switch_page_cb(GtkNotebook *notebook, GtkWidget *page, guint page_num, PidginScrollBook *scroll_book)
148 int count;
149 count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book->notebook));
150 refresh_scroll_box(scroll_book, page_num, count);
153 static void
154 pidgin_scroll_book_add(GtkContainer *container, GtkWidget *widget)
156 PidginScrollBook *scroll_book;
158 g_return_if_fail(GTK_IS_WIDGET (widget));
159 g_return_if_fail(gtk_widget_get_parent(widget) == NULL);
161 scroll_book = PIDGIN_SCROLL_BOOK(container);
162 scroll_book->children = g_list_append(scroll_book->children, widget);
163 gtk_widget_show(widget);
164 gtk_notebook_append_page(GTK_NOTEBOOK(scroll_book->notebook), widget, NULL);
165 page_count_change_cb(PIDGIN_SCROLL_BOOK(container));
168 static void
169 pidgin_scroll_book_remove(GtkContainer *container, GtkWidget *widget)
171 int page;
172 PidginScrollBook *scroll_book;
173 g_return_if_fail(GTK_IS_WIDGET(widget));
175 scroll_book = PIDGIN_SCROLL_BOOK(container);
176 scroll_book->children = g_list_remove(scroll_book->children, widget);
177 /* gtk_widget_unparent(widget); */
179 page = gtk_notebook_page_num(GTK_NOTEBOOK(PIDGIN_SCROLL_BOOK(container)->notebook), widget);
180 if (page >= 0) {
181 gtk_notebook_remove_page(GTK_NOTEBOOK(PIDGIN_SCROLL_BOOK(container)->notebook), page);
185 static void
186 pidgin_scroll_book_forall(GtkContainer *container,
187 gboolean include_internals,
188 GtkCallback callback,
189 gpointer callback_data)
191 #if 0
192 GList *children;
193 #endif
194 PidginScrollBook *scroll_book;
196 g_return_if_fail(GTK_IS_CONTAINER(container));
198 scroll_book = PIDGIN_SCROLL_BOOK(container);
200 if (include_internals) {
201 (*callback)(scroll_book->hbox, callback_data);
202 (*callback)(scroll_book->notebook, callback_data);
205 #if 0
206 children = scroll_book->children;
208 while (children) {
209 GtkWidget *child;
210 child = children->data;
211 children = children->next;
212 (*callback)(child, callback_data);
214 #endif
217 static void
218 pidgin_scroll_book_class_init (PidginScrollBookClass *klass)
220 GtkContainerClass *container_class = (GtkContainerClass*)klass;
222 container_class->add = pidgin_scroll_book_add;
223 container_class->remove = pidgin_scroll_book_remove;
224 container_class->forall = pidgin_scroll_book_forall;
227 static gboolean
228 close_button_left_cb(GtkWidget *widget, GdkEventCrossing *event, GtkLabel *label)
230 static GdkCursor *ptr = NULL;
231 if (ptr == NULL) {
232 GdkDisplay *display = gtk_widget_get_display(widget);
233 ptr = gdk_cursor_new_for_display(display, GDK_LEFT_PTR);
236 gtk_label_set_markup(label, "×");
237 gdk_window_set_cursor(event->window, ptr);
238 return FALSE;
241 static gboolean
242 close_button_entered_cb(GtkWidget *widget, GdkEventCrossing *event, GtkLabel *label)
244 static GdkCursor *hand = NULL;
245 if (hand == NULL) {
246 GdkDisplay *display = gtk_widget_get_display(widget);
247 hand = gdk_cursor_new_for_display(display, GDK_HAND2);
250 gtk_label_set_markup(label, "<u>×</u>");
251 gdk_window_set_cursor(event->window, hand);
252 return FALSE;
255 static void
256 pidgin_scroll_book_init (PidginScrollBook *scroll_book)
258 GtkWidget *eb;
259 GtkWidget *close_button;
261 gtk_orientable_set_orientation(GTK_ORIENTABLE(scroll_book), GTK_ORIENTATION_VERTICAL);
263 scroll_book->hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
265 /* Close */
266 eb = gtk_event_box_new();
267 gtk_box_pack_end(GTK_BOX(scroll_book->hbox), eb, FALSE, FALSE, 0);
268 gtk_event_box_set_visible_window(GTK_EVENT_BOX(eb), FALSE);
269 gtk_widget_set_events(eb, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
270 close_button = gtk_label_new("×");
271 g_signal_connect(G_OBJECT(eb), "enter-notify-event", G_CALLBACK(close_button_entered_cb), close_button);
272 g_signal_connect(G_OBJECT(eb), "leave-notify-event", G_CALLBACK(close_button_left_cb), close_button);
273 gtk_container_add(GTK_CONTAINER(eb), close_button);
274 g_signal_connect_swapped(G_OBJECT(eb), "button-press-event", G_CALLBACK(scroll_close_cb), scroll_book);
276 /* Right arrow */
277 eb = gtk_event_box_new();
278 gtk_box_pack_end(GTK_BOX(scroll_book->hbox), eb, FALSE, FALSE, 0);
279 #if GTK_CHECK_VERSION(3,14,0)
280 scroll_book->right_arrow = gtk_image_new_from_icon_name("pan-right-symbolic", GTK_ICON_SIZE_BUTTON);
281 #else
282 scroll_book->right_arrow = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
283 #endif
284 gtk_container_add(GTK_CONTAINER(eb), scroll_book->right_arrow);
285 g_signal_connect_swapped(G_OBJECT(eb), "button-press-event", G_CALLBACK(scroll_right_cb), scroll_book);
287 /* Count */
288 scroll_book->label = gtk_label_new(NULL);
289 gtk_box_pack_end(GTK_BOX(scroll_book->hbox), scroll_book->label, FALSE, FALSE, 0);
291 /* Left arrow */
292 eb = gtk_event_box_new();
293 gtk_box_pack_end(GTK_BOX(scroll_book->hbox), eb, FALSE, FALSE, 0);
294 #if GTK_CHECK_VERSION(3,14,0)
295 scroll_book->left_arrow = gtk_image_new_from_icon_name("pan-left-symbolic", GTK_ICON_SIZE_BUTTON);
296 #else
297 scroll_book->left_arrow = gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_NONE);
298 #endif
299 gtk_container_add(GTK_CONTAINER(eb), scroll_book->left_arrow);
300 g_signal_connect_swapped(G_OBJECT(eb), "button-press-event", G_CALLBACK(scroll_left_cb), scroll_book);
302 gtk_box_pack_start(GTK_BOX(scroll_book), scroll_book->hbox, FALSE, FALSE, 0);
304 scroll_book->notebook = gtk_notebook_new();
305 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(scroll_book->notebook), FALSE);
306 gtk_notebook_set_show_border(GTK_NOTEBOOK(scroll_book->notebook), FALSE);
308 gtk_box_pack_start(GTK_BOX(scroll_book), scroll_book->notebook, TRUE, TRUE, 0);
310 g_signal_connect_swapped(G_OBJECT(scroll_book->notebook), "remove", G_CALLBACK(page_count_change_cb), scroll_book);
311 g_signal_connect(G_OBJECT(scroll_book->notebook), "switch-page", G_CALLBACK(switch_page_cb), scroll_book);
312 gtk_widget_show_all(scroll_book->notebook);
315 GtkWidget *
316 pidgin_scroll_book_new()
318 return g_object_new(PIDGIN_TYPE_SCROLL_BOOK, NULL);