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
)
71 index
= gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book
->notebook
));
74 gtk_notebook_set_current_page(GTK_NOTEBOOK(scroll_book
->notebook
), index
- 1);
79 scroll_right_cb(PidginScrollBook
*scroll_book
)
82 index
= gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book
->notebook
));
83 count
= gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book
->notebook
));
85 if (index
+ 1 < count
)
86 gtk_notebook_set_current_page(GTK_NOTEBOOK(scroll_book
->notebook
), index
+ 1);
91 refresh_scroll_box(PidginScrollBook
*scroll_book
, int index
, int count
)
95 gtk_widget_show_all(GTK_WIDGET(scroll_book
));
97 gtk_widget_hide_all(scroll_book
->hbox
);
99 gtk_widget_show_all(scroll_book
->hbox
);
101 gtk_widget_hide(scroll_book
->label
);
102 gtk_widget_hide(scroll_book
->left_arrow
);
103 gtk_widget_hide(scroll_book
->right_arrow
);
107 label
= g_strdup_printf("<span size='smaller' weight='bold'>(%d/%d)</span>", index
+1, count
);
108 gtk_label_set_markup(GTK_LABEL(scroll_book
->label
), label
);
112 gtk_widget_set_sensitive(scroll_book
->left_arrow
, FALSE
);
114 gtk_widget_set_sensitive(scroll_book
->left_arrow
, TRUE
);
117 if (index
+ 1 == count
)
118 gtk_widget_set_sensitive(scroll_book
->right_arrow
, FALSE
);
120 gtk_widget_set_sensitive(scroll_book
->right_arrow
, TRUE
);
125 page_count_change_cb(PidginScrollBook
*scroll_book
)
128 int index
= gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book
->notebook
));
129 count
= gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book
->notebook
));
130 refresh_scroll_box(scroll_book
, index
, count
);
134 scroll_close_cb(PidginScrollBook
*scroll_book
)
136 gtk_widget_destroy(gtk_notebook_get_nth_page(GTK_NOTEBOOK(scroll_book
->notebook
), gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book
->notebook
))));
141 switch_page_cb(GtkNotebook
*notebook
, GtkNotebookPage
*page
, guint page_num
, PidginScrollBook
*scroll_book
)
144 count
= gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book
->notebook
));
145 refresh_scroll_box(scroll_book
, page_num
, count
);
149 pidgin_scroll_book_add(GtkContainer
*container
, GtkWidget
*widget
)
151 PidginScrollBook
*scroll_book
;
153 g_return_if_fail(GTK_IS_WIDGET (widget
));
154 g_return_if_fail (widget
->parent
== NULL
);
156 scroll_book
= PIDGIN_SCROLL_BOOK(container
);
157 scroll_book
->children
= g_list_append(scroll_book
->children
, widget
);
158 gtk_widget_show(widget
);
159 gtk_notebook_append_page(GTK_NOTEBOOK(scroll_book
->notebook
), widget
, NULL
);
160 page_count_change_cb(PIDGIN_SCROLL_BOOK(container
));
164 pidgin_scroll_book_remove(GtkContainer
*container
, GtkWidget
*widget
)
167 PidginScrollBook
*scroll_book
;
168 g_return_if_fail(GTK_IS_WIDGET(widget
));
170 scroll_book
= PIDGIN_SCROLL_BOOK(container
);
171 scroll_book
->children
= g_list_remove(scroll_book
->children
, widget
);
172 /* gtk_widget_unparent(widget); */
174 page
= gtk_notebook_page_num(GTK_NOTEBOOK(PIDGIN_SCROLL_BOOK(container
)->notebook
), widget
);
176 gtk_notebook_remove_page(GTK_NOTEBOOK(PIDGIN_SCROLL_BOOK(container
)->notebook
), page
);
181 pidgin_scroll_book_forall(GtkContainer
*container
,
182 gboolean include_internals
,
183 GtkCallback callback
,
184 gpointer callback_data
)
189 PidginScrollBook
*scroll_book
;
191 g_return_if_fail(GTK_IS_CONTAINER(container
));
193 scroll_book
= PIDGIN_SCROLL_BOOK(container
);
195 if (include_internals
) {
196 (*callback
)(scroll_book
->hbox
, callback_data
);
197 (*callback
)(scroll_book
->notebook
, callback_data
);
201 children
= scroll_book
->children
;
205 child
= children
->data
;
206 children
= children
->next
;
207 (*callback
)(child
, callback_data
);
213 pidgin_scroll_book_class_init (PidginScrollBookClass
*klass
)
215 GtkContainerClass
*container_class
= (GtkContainerClass
*)klass
;
217 container_class
->add
= pidgin_scroll_book_add
;
218 container_class
->remove
= pidgin_scroll_book_remove
;
219 container_class
->forall
= pidgin_scroll_book_forall
;
223 close_button_left_cb(GtkWidget
*widget
, GdkEventCrossing
*event
, GtkLabel
*label
)
225 static GdkCursor
*ptr
= NULL
;
227 ptr
= gdk_cursor_new(GDK_LEFT_PTR
);
230 gtk_label_set_markup(label
, "×");
231 gdk_window_set_cursor(event
->window
, ptr
);
236 close_button_entered_cb(GtkWidget
*widget
, GdkEventCrossing
*event
, GtkLabel
*label
)
238 static GdkCursor
*hand
= NULL
;
240 hand
= gdk_cursor_new(GDK_HAND2
);
243 gtk_label_set_markup(label
, "<u>×</u>");
244 gdk_window_set_cursor(event
->window
, hand
);
249 pidgin_scroll_book_init (PidginScrollBook
*scroll_book
)
252 GtkWidget
*close_button
;
254 scroll_book
->hbox
= gtk_hbox_new(FALSE
, 0);
257 eb
= gtk_event_box_new();
258 gtk_box_pack_end(GTK_BOX(scroll_book
->hbox
), eb
, FALSE
, FALSE
, 0);
259 gtk_event_box_set_visible_window(GTK_EVENT_BOX(eb
), FALSE
);
260 gtk_widget_set_events(eb
, GDK_ENTER_NOTIFY_MASK
| GDK_LEAVE_NOTIFY_MASK
);
261 close_button
= gtk_label_new("×");
262 g_signal_connect(G_OBJECT(eb
), "enter-notify-event", G_CALLBACK(close_button_entered_cb
), close_button
);
263 g_signal_connect(G_OBJECT(eb
), "leave-notify-event", G_CALLBACK(close_button_left_cb
), close_button
);
264 gtk_container_add(GTK_CONTAINER(eb
), close_button
);
265 g_signal_connect_swapped(G_OBJECT(eb
), "button-press-event", G_CALLBACK(scroll_close_cb
), scroll_book
);
268 eb
= gtk_event_box_new();
269 gtk_box_pack_end(GTK_BOX(scroll_book
->hbox
), eb
, FALSE
, FALSE
, 0);
270 scroll_book
->right_arrow
= gtk_arrow_new(GTK_ARROW_RIGHT
, GTK_SHADOW_NONE
);
271 gtk_container_add(GTK_CONTAINER(eb
), scroll_book
->right_arrow
);
272 g_signal_connect_swapped(G_OBJECT(eb
), "button-press-event", G_CALLBACK(scroll_right_cb
), scroll_book
);
275 scroll_book
->label
= gtk_label_new(NULL
);
276 gtk_box_pack_end(GTK_BOX(scroll_book
->hbox
), scroll_book
->label
, FALSE
, FALSE
, 0);
279 eb
= gtk_event_box_new();
280 gtk_box_pack_end(GTK_BOX(scroll_book
->hbox
), eb
, FALSE
, FALSE
, 0);
281 scroll_book
->left_arrow
= gtk_arrow_new(GTK_ARROW_LEFT
, GTK_SHADOW_NONE
);
282 gtk_container_add(GTK_CONTAINER(eb
), scroll_book
->left_arrow
);
283 g_signal_connect_swapped(G_OBJECT(eb
), "button-press-event", G_CALLBACK(scroll_left_cb
), scroll_book
);
285 gtk_box_pack_start(GTK_BOX(scroll_book
), scroll_book
->hbox
, FALSE
, FALSE
, 0);
287 scroll_book
->notebook
= gtk_notebook_new();
288 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(scroll_book
->notebook
), FALSE
);
289 gtk_notebook_set_show_border(GTK_NOTEBOOK(scroll_book
->notebook
), FALSE
);
291 gtk_box_pack_start(GTK_BOX(scroll_book
), scroll_book
->notebook
, TRUE
, TRUE
, 0);
293 g_signal_connect_swapped(G_OBJECT(scroll_book
->notebook
), "remove", G_CALLBACK(page_count_change_cb
), scroll_book
);
294 g_signal_connect(G_OBJECT(scroll_book
->notebook
), "switch-page", G_CALLBACK(switch_page_cb
), scroll_book
);
295 gtk_widget_show_all(scroll_book
->notebook
);
299 pidgin_scroll_book_new()
301 return g_object_new(PIDGIN_TYPE_SCROLL_BOOK
, NULL
);