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
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
,
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
),
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
,
60 return scroll_book_type
;
64 scroll_left_cb(PidginScrollBook
*scroll_book
, GdkEventButton
*event
)
68 if (event
->type
!= GDK_BUTTON_PRESS
)
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
, GdkEventButton
*event
)
83 if (event
->type
!= GDK_BUTTON_PRESS
)
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);
95 refresh_scroll_box(PidginScrollBook
*scroll_book
, int index
, int count
)
99 gtk_widget_show_all(GTK_WIDGET(scroll_book
));
101 gtk_widget_hide(scroll_book
->hbox
);
103 gtk_widget_show_all(scroll_book
->hbox
);
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
);
116 gtk_widget_set_sensitive(scroll_book
->left_arrow
, FALSE
);
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
);
124 gtk_widget_set_sensitive(scroll_book
->right_arrow
, TRUE
);
129 page_count_change_cb(PidginScrollBook
*scroll_book
)
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
);
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
))));
146 switch_page_cb(GtkNotebook
*notebook
, GtkWidget
*page
, guint page_num
, PidginScrollBook
*scroll_book
)
149 count
= gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book
->notebook
));
150 refresh_scroll_box(scroll_book
, page_num
, count
);
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
));
169 pidgin_scroll_book_remove(GtkContainer
*container
, GtkWidget
*widget
)
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
);
181 gtk_notebook_remove_page(GTK_NOTEBOOK(PIDGIN_SCROLL_BOOK(container
)->notebook
), page
);
186 pidgin_scroll_book_forall(GtkContainer
*container
,
187 gboolean include_internals
,
188 GtkCallback callback
,
189 gpointer callback_data
)
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
);
206 children
= scroll_book
->children
;
210 child
= children
->data
;
211 children
= children
->next
;
212 (*callback
)(child
, callback_data
);
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
;
228 close_button_left_cb(GtkWidget
*widget
, GdkEventCrossing
*event
, GtkLabel
*label
)
230 static GdkCursor
*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
);
242 close_button_entered_cb(GtkWidget
*widget
, GdkEventCrossing
*event
, GtkLabel
*label
)
244 static GdkCursor
*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
);
256 pidgin_scroll_book_init (PidginScrollBook
*scroll_book
)
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);
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 #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
);
282 scroll_book
->right_arrow
= gtk_arrow_new(GTK_ARROW_RIGHT
, GTK_SHADOW_NONE
);
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
);
288 scroll_book
->label
= gtk_label_new(NULL
);
289 gtk_box_pack_end(GTK_BOX(scroll_book
->hbox
), scroll_book
->label
, FALSE
, FALSE
, 0);
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
);
297 scroll_book
->left_arrow
= gtk_arrow_new(GTK_ARROW_LEFT
, GTK_SHADOW_NONE
);
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
);
316 pidgin_scroll_book_new()
318 return g_object_new(PIDGIN_TYPE_SCROLL_BOOK
, NULL
);