Dutch translation updated (Gideon van Melle)
[pidgin-git.git] / pidgin / gtkscrollbook.c
blobaa499932eda848d4676d6bd177870e1e902ecd97
1 /*
2 * @file gtkscrollbook.c GTK+ Scrolling notebook widget
3 * @ingroup pidgin
4 */
6 /* pidgin
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 of the License, or
15 * (at your option) any later version.
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 "gtkscrollbook.h"
30 static void pidgin_scroll_book_init (PidginScrollBook *scroll_book);
31 static void pidgin_scroll_book_class_init (PidginScrollBookClass *klass);
32 static void pidgin_scroll_book_forall (GtkContainer *c,
33 gboolean include_internals,
34 GtkCallback callback,
35 gpointer user_data);
37 GType
38 pidgin_scroll_book_get_type (void)
40 static GType scroll_book_type = 0;
42 if (!scroll_book_type)
44 static const GTypeInfo scroll_book_info =
46 sizeof (PidginScrollBookClass),
47 NULL, /* base_init */
48 NULL, /* base_finalize */
49 (GClassInitFunc) pidgin_scroll_book_class_init,
50 NULL, /* class_finalize */
51 NULL, /* class_data */
52 sizeof (PidginScrollBook),
54 (GInstanceInitFunc) pidgin_scroll_book_init,
55 NULL /* value_table */
58 scroll_book_type = g_type_register_static(GTK_TYPE_VBOX,
59 "PidginScrollBook",
60 &scroll_book_info,
61 0);
64 return scroll_book_type;
67 static gboolean
68 scroll_left_cb(PidginScrollBook *scroll_book, GdkEventButton *event)
70 int index;
72 if (event->type != GDK_BUTTON_PRESS)
73 return FALSE;
75 index = gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book->notebook));
77 if (index > 0)
78 gtk_notebook_set_current_page(GTK_NOTEBOOK(scroll_book->notebook), index - 1);
79 return TRUE;
82 static gboolean
83 scroll_right_cb(PidginScrollBook *scroll_book, GdkEventButton *event)
85 int index, count;
87 if (event->type != GDK_BUTTON_PRESS)
88 return FALSE;
90 index = gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book->notebook));
91 count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book->notebook));
93 if (index + 1 < count)
94 gtk_notebook_set_current_page(GTK_NOTEBOOK(scroll_book->notebook), index + 1);
95 return TRUE;
98 static void
99 refresh_scroll_box(PidginScrollBook *scroll_book, int index, int count)
101 char *label;
103 gtk_widget_show_all(GTK_WIDGET(scroll_book));
104 if (count < 1)
105 gtk_widget_hide_all(scroll_book->hbox);
106 else {
107 gtk_widget_show_all(scroll_book->hbox);
108 if (count == 1) {
109 gtk_widget_hide(scroll_book->label);
110 gtk_widget_hide(scroll_book->left_arrow);
111 gtk_widget_hide(scroll_book->right_arrow);
115 label = g_strdup_printf("<span size='smaller' weight='bold'>(%d/%d)</span>", index+1, count);
116 gtk_label_set_markup(GTK_LABEL(scroll_book->label), label);
117 g_free(label);
119 if (index == 0)
120 gtk_widget_set_sensitive(scroll_book->left_arrow, FALSE);
121 else
122 gtk_widget_set_sensitive(scroll_book->left_arrow, TRUE);
125 if (index + 1 == count)
126 gtk_widget_set_sensitive(scroll_book->right_arrow, FALSE);
127 else
128 gtk_widget_set_sensitive(scroll_book->right_arrow, TRUE);
132 static void
133 page_count_change_cb(PidginScrollBook *scroll_book)
135 int count;
136 int index = gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book->notebook));
137 count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book->notebook));
138 refresh_scroll_box(scroll_book, index, count);
141 static gboolean
142 scroll_close_cb(PidginScrollBook *scroll_book, GdkEventButton *event)
144 if (event->type == GDK_BUTTON_PRESS)
145 gtk_widget_destroy(gtk_notebook_get_nth_page(GTK_NOTEBOOK(scroll_book->notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book->notebook))));
146 return FALSE;
149 static void
150 switch_page_cb(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, PidginScrollBook *scroll_book)
152 int count;
153 count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book->notebook));
154 refresh_scroll_box(scroll_book, page_num, count);
157 static void
158 pidgin_scroll_book_add(GtkContainer *container, GtkWidget *widget)
160 PidginScrollBook *scroll_book;
162 g_return_if_fail(GTK_IS_WIDGET (widget));
163 g_return_if_fail (widget->parent == NULL);
165 scroll_book = PIDGIN_SCROLL_BOOK(container);
166 scroll_book->children = g_list_append(scroll_book->children, widget);
167 gtk_widget_show(widget);
168 gtk_notebook_append_page(GTK_NOTEBOOK(scroll_book->notebook), widget, NULL);
169 page_count_change_cb(PIDGIN_SCROLL_BOOK(container));
172 static void
173 pidgin_scroll_book_remove(GtkContainer *container, GtkWidget *widget)
175 int page;
176 PidginScrollBook *scroll_book;
177 g_return_if_fail(GTK_IS_WIDGET(widget));
179 scroll_book = PIDGIN_SCROLL_BOOK(container);
180 scroll_book->children = g_list_remove(scroll_book->children, widget);
181 /* gtk_widget_unparent(widget); */
183 page = gtk_notebook_page_num(GTK_NOTEBOOK(PIDGIN_SCROLL_BOOK(container)->notebook), widget);
184 if (page >= 0) {
185 gtk_notebook_remove_page(GTK_NOTEBOOK(PIDGIN_SCROLL_BOOK(container)->notebook), page);
189 static void
190 pidgin_scroll_book_forall(GtkContainer *container,
191 gboolean include_internals,
192 GtkCallback callback,
193 gpointer callback_data)
195 #if 0
196 GList *children;
197 #endif
198 PidginScrollBook *scroll_book;
200 g_return_if_fail(GTK_IS_CONTAINER(container));
202 scroll_book = PIDGIN_SCROLL_BOOK(container);
204 if (include_internals) {
205 (*callback)(scroll_book->hbox, callback_data);
206 (*callback)(scroll_book->notebook, callback_data);
209 #if 0
210 children = scroll_book->children;
212 while (children) {
213 GtkWidget *child;
214 child = children->data;
215 children = children->next;
216 (*callback)(child, callback_data);
218 #endif
221 static void
222 pidgin_scroll_book_class_init (PidginScrollBookClass *klass)
224 GtkContainerClass *container_class = (GtkContainerClass*)klass;
226 container_class->add = pidgin_scroll_book_add;
227 container_class->remove = pidgin_scroll_book_remove;
228 container_class->forall = pidgin_scroll_book_forall;
231 static gboolean
232 close_button_left_cb(GtkWidget *widget, GdkEventCrossing *event, GtkLabel *label)
234 static GdkCursor *ptr = NULL;
235 if (ptr == NULL) {
236 ptr = gdk_cursor_new(GDK_LEFT_PTR);
239 gtk_label_set_markup(label, "×");
240 gdk_window_set_cursor(event->window, ptr);
241 return FALSE;
244 static gboolean
245 close_button_entered_cb(GtkWidget *widget, GdkEventCrossing *event, GtkLabel *label)
247 static GdkCursor *hand = NULL;
248 if (hand == NULL) {
249 hand = gdk_cursor_new(GDK_HAND2);
252 gtk_label_set_markup(label, "<u>×</u>");
253 gdk_window_set_cursor(event->window, hand);
254 return FALSE;
257 static void
258 pidgin_scroll_book_init (PidginScrollBook *scroll_book)
260 GtkWidget *eb;
261 GtkWidget *close_button;
263 scroll_book->hbox = gtk_hbox_new(FALSE, 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 scroll_book->right_arrow = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
280 gtk_container_add(GTK_CONTAINER(eb), scroll_book->right_arrow);
281 g_signal_connect_swapped(G_OBJECT(eb), "button-press-event", G_CALLBACK(scroll_right_cb), scroll_book);
283 /* Count */
284 scroll_book->label = gtk_label_new(NULL);
285 gtk_box_pack_end(GTK_BOX(scroll_book->hbox), scroll_book->label, FALSE, FALSE, 0);
287 /* Left arrow */
288 eb = gtk_event_box_new();
289 gtk_box_pack_end(GTK_BOX(scroll_book->hbox), eb, FALSE, FALSE, 0);
290 scroll_book->left_arrow = gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_NONE);
291 gtk_container_add(GTK_CONTAINER(eb), scroll_book->left_arrow);
292 g_signal_connect_swapped(G_OBJECT(eb), "button-press-event", G_CALLBACK(scroll_left_cb), scroll_book);
294 gtk_box_pack_start(GTK_BOX(scroll_book), scroll_book->hbox, FALSE, FALSE, 0);
296 scroll_book->notebook = gtk_notebook_new();
297 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(scroll_book->notebook), FALSE);
298 gtk_notebook_set_show_border(GTK_NOTEBOOK(scroll_book->notebook), FALSE);
300 gtk_box_pack_start(GTK_BOX(scroll_book), scroll_book->notebook, TRUE, TRUE, 0);
302 g_signal_connect_swapped(G_OBJECT(scroll_book->notebook), "remove", G_CALLBACK(page_count_change_cb), scroll_book);
303 g_signal_connect(G_OBJECT(scroll_book->notebook), "switch-page", G_CALLBACK(switch_page_cb), scroll_book);
304 gtk_widget_show_all(scroll_book->notebook);
307 GtkWidget *
308 pidgin_scroll_book_new()
310 return g_object_new(PIDGIN_TYPE_SCROLL_BOOK, NULL);