2 * @file gtkscrollbook.c GTK+ Scrolling notebook widget
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
,
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
),
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
,
64 return scroll_book_type
;
68 scroll_left_cb(PidginScrollBook
*scroll_book
, GdkEventButton
*event
)
72 if (event
->type
!= GDK_BUTTON_PRESS
)
75 index
= gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book
->notebook
));
78 gtk_notebook_set_current_page(GTK_NOTEBOOK(scroll_book
->notebook
), index
- 1);
83 scroll_right_cb(PidginScrollBook
*scroll_book
, GdkEventButton
*event
)
87 if (event
->type
!= GDK_BUTTON_PRESS
)
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);
99 refresh_scroll_box(PidginScrollBook
*scroll_book
, int index
, int count
)
103 gtk_widget_show_all(GTK_WIDGET(scroll_book
));
105 gtk_widget_hide_all(scroll_book
->hbox
);
107 gtk_widget_show_all(scroll_book
->hbox
);
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
);
120 gtk_widget_set_sensitive(scroll_book
->left_arrow
, FALSE
);
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
);
128 gtk_widget_set_sensitive(scroll_book
->right_arrow
, TRUE
);
133 page_count_change_cb(PidginScrollBook
*scroll_book
)
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
);
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
))));
150 switch_page_cb(GtkNotebook
*notebook
, GtkNotebookPage
*page
, guint page_num
, PidginScrollBook
*scroll_book
)
153 count
= gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book
->notebook
));
154 refresh_scroll_box(scroll_book
, page_num
, count
);
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
));
173 pidgin_scroll_book_remove(GtkContainer
*container
, GtkWidget
*widget
)
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
);
185 gtk_notebook_remove_page(GTK_NOTEBOOK(PIDGIN_SCROLL_BOOK(container
)->notebook
), page
);
190 pidgin_scroll_book_forall(GtkContainer
*container
,
191 gboolean include_internals
,
192 GtkCallback callback
,
193 gpointer callback_data
)
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
);
210 children
= scroll_book
->children
;
214 child
= children
->data
;
215 children
= children
->next
;
216 (*callback
)(child
, callback_data
);
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
;
232 close_button_left_cb(GtkWidget
*widget
, GdkEventCrossing
*event
, GtkLabel
*label
)
234 static GdkCursor
*ptr
= NULL
;
236 ptr
= gdk_cursor_new(GDK_LEFT_PTR
);
239 gtk_label_set_markup(label
, "×");
240 gdk_window_set_cursor(event
->window
, ptr
);
245 close_button_entered_cb(GtkWidget
*widget
, GdkEventCrossing
*event
, GtkLabel
*label
)
247 static GdkCursor
*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
);
258 pidgin_scroll_book_init (PidginScrollBook
*scroll_book
)
261 GtkWidget
*close_button
;
263 scroll_book
->hbox
= gtk_hbox_new(FALSE
, 0);
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
);
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
);
284 scroll_book
->label
= gtk_label_new(NULL
);
285 gtk_box_pack_end(GTK_BOX(scroll_book
->hbox
), scroll_book
->label
, FALSE
, FALSE
, 0);
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
);
308 pidgin_scroll_book_new()
310 return g_object_new(PIDGIN_TYPE_SCROLL_BOOK
, NULL
);