1 /* Xviewer - Thumbnail Navigator
2  *
3  * Copyright (C) 2006 The Free Software Foundation
4  *
5  * Author: Lucas Rocha <lucasr@gnome.org>
6  *
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.
11  *
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.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include "xviewer-thumb-nav.h"
27 #include "xviewer-thumb-view.h"
28 
29 #include <glib.h>
30 #include <glib/gi18n.h>
31 #include <glib-object.h>
32 #include <gtk/gtk.h>
33 #include <math.h>
34 #include <string.h>
35 
36 #define XVIEWER_THUMB_NAV_SCROLL_INC      20
37 #define XVIEWER_THUMB_NAV_SCROLL_MOVE     20
38 #define XVIEWER_THUMB_NAV_SCROLL_TIMEOUT  20
39 
40 enum
41 {
42 	PROP_0,
43 	PROP_SHOW_BUTTONS,
44 	PROP_THUMB_VIEW,
45 	PROP_MODE
46 };
47 
48 struct _XviewerThumbNavPrivate {
49 	XviewerThumbNavMode   mode;
50 
51 	gboolean          show_buttons;
52 	gboolean          scroll_dir;
53 	gint              scroll_pos;
54 	gint              scroll_id;
55 
56 	GtkWidget        *button_left;
57 	GtkWidget        *button_right;
58 	GtkWidget        *sw;
59 	GtkWidget        *thumbview;
60 	GtkAdjustment    *adj;
61 };
62 
63 G_DEFINE_TYPE_WITH_PRIVATE (XviewerThumbNav, xviewer_thumb_nav, GTK_TYPE_BOX);
64 
65 static gboolean
xviewer_thumb_nav_scroll_event(GtkWidget * widget,GdkEventScroll * event,gpointer user_data)66 xviewer_thumb_nav_scroll_event (GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
67 {
68 	XviewerThumbNav *nav = XVIEWER_THUMB_NAV (user_data);
69 	gint inc = XVIEWER_THUMB_NAV_SCROLL_INC * 3;
70 
71 	if (nav->priv->mode != XVIEWER_THUMB_NAV_MODE_ONE_ROW)
72 		return FALSE;
73 
74 	switch (event->direction) {
75 	case GDK_SCROLL_UP:
76 	case GDK_SCROLL_LEFT:
77 		inc *= -1;
78 		break;
79 
80 	case GDK_SCROLL_DOWN:
81 	case GDK_SCROLL_RIGHT:
82 		break;
83 
84 #if GTK_CHECK_VERSION (3, 3, 18)
85 	case GDK_SCROLL_SMOOTH:
86 	{
87 		/* Compatibility code to catch smooth events from mousewheels */
88 		gdouble x_delta, y_delta;
89 		gboolean set = gdk_event_get_scroll_deltas ((GdkEvent*)event,
90 		                                            &x_delta, &y_delta);
91 
92 		/* Propagate horizontal smooth scroll events further,
93 		   as well as non-mousewheel events. */
94 		if (G_UNLIKELY (!set) || x_delta != 0.0 || fabs(y_delta) != 1.0)
95 			return FALSE;
96 
97 		/* The y_delta is either +1.0 or -1.0 here */
98 		inc *= (gint) y_delta;
99 	}
100 	break;
101 #endif
102 	default:
103 		g_assert_not_reached ();
104 		return FALSE;
105 	}
106 
107 	if (inc < 0)
108 		gtk_adjustment_set_value (nav->priv->adj, MAX (0, gtk_adjustment_get_value (nav->priv->adj) + inc));
109 	else
110 		gtk_adjustment_set_value (nav->priv->adj, MIN (gtk_adjustment_get_upper (nav->priv->adj) - gtk_adjustment_get_page_size (nav->priv->adj), gtk_adjustment_get_value (nav->priv->adj) + inc));
111 
112 	return TRUE;
113 }
114 
115 static void
xviewer_thumb_nav_adj_changed(GtkAdjustment * adj,gpointer user_data)116 xviewer_thumb_nav_adj_changed (GtkAdjustment *adj, gpointer user_data)
117 {
118 	XviewerThumbNav *nav;
119 	XviewerThumbNavPrivate *priv;
120 	gboolean ltr;
121 
122 	nav = XVIEWER_THUMB_NAV (user_data);
123 	priv = xviewer_thumb_nav_get_instance_private (nav);
124 	ltr = gtk_widget_get_direction (priv->sw) == GTK_TEXT_DIR_LTR;
125 
126 	gtk_widget_set_sensitive (ltr ? priv->button_right : priv->button_left,
127 				  gtk_adjustment_get_value (adj)
128 				   < gtk_adjustment_get_upper (adj)
129 				    - gtk_adjustment_get_page_size (adj));
130 }
131 
132 static void
xviewer_thumb_nav_adj_value_changed(GtkAdjustment * adj,gpointer user_data)133 xviewer_thumb_nav_adj_value_changed (GtkAdjustment *adj, gpointer user_data)
134 {
135 	XviewerThumbNav *nav;
136 	XviewerThumbNavPrivate *priv;
137 	gboolean ltr;
138 
139 	nav = XVIEWER_THUMB_NAV (user_data);
140 	priv = xviewer_thumb_nav_get_instance_private (nav);
141 	ltr = gtk_widget_get_direction (priv->sw) == GTK_TEXT_DIR_LTR;
142 
143 	gtk_widget_set_sensitive (ltr ? priv->button_left : priv->button_right,
144 				  gtk_adjustment_get_value (adj) > 0);
145 
146 	gtk_widget_set_sensitive (ltr ? priv->button_right : priv->button_left,
147 				  gtk_adjustment_get_value (adj)
148 				   < gtk_adjustment_get_upper (adj)
149 				    - gtk_adjustment_get_page_size (adj));
150 }
151 
152 static gboolean
xviewer_thumb_nav_scroll_step(gpointer user_data)153 xviewer_thumb_nav_scroll_step (gpointer user_data)
154 {
155 	XviewerThumbNav *nav = XVIEWER_THUMB_NAV (user_data);
156 	GtkAdjustment *adj = nav->priv->adj;
157 	gint delta;
158 
159 	if (nav->priv->scroll_pos < 10)
160 		delta = XVIEWER_THUMB_NAV_SCROLL_INC;
161 	else if (nav->priv->scroll_pos < 20)
162 		delta = XVIEWER_THUMB_NAV_SCROLL_INC * 2;
163 	else if (nav->priv->scroll_pos < 30)
164 		delta = XVIEWER_THUMB_NAV_SCROLL_INC * 2 + 5;
165 	else
166 		delta = XVIEWER_THUMB_NAV_SCROLL_INC * 2 + 12;
167 
168 	if (!nav->priv->scroll_dir)
169 		delta *= -1;
170 
171 	if ((gint) (gtk_adjustment_get_value (adj) + (gdouble) delta) >= 0 &&
172 	    (gint) (gtk_adjustment_get_value (adj) + (gdouble) delta) <= gtk_adjustment_get_upper (adj) - gtk_adjustment_get_page_size (adj)) {
173 		gtk_adjustment_set_value(adj,
174 			gtk_adjustment_get_value (adj) + (gdouble) delta);
175 		nav->priv->scroll_pos++;
176 	} else {
177 		if (delta > 0)
178 		      gtk_adjustment_set_value (adj,
179 		      	gtk_adjustment_get_upper (adj) - gtk_adjustment_get_page_size (adj));
180 		else
181 		      gtk_adjustment_set_value (adj, 0);
182 
183 		nav->priv->scroll_pos = 0;
184 
185 		return FALSE;
186 	}
187 
188 	return TRUE;
189 }
190 
191 static void
xviewer_thumb_nav_button_clicked(GtkButton * button,XviewerThumbNav * nav)192 xviewer_thumb_nav_button_clicked (GtkButton *button, XviewerThumbNav *nav)
193 {
194 	nav->priv->scroll_pos = 0;
195 
196 	nav->priv->scroll_dir = gtk_widget_get_direction (GTK_WIDGET (button)) == GTK_TEXT_DIR_LTR ?
197 		GTK_WIDGET (button) == nav->priv->button_right :
198 		GTK_WIDGET (button) == nav->priv->button_left;
199 
200 	xviewer_thumb_nav_scroll_step (nav);
201 }
202 
203 static void
xviewer_thumb_nav_start_scroll(GtkButton * button,XviewerThumbNav * nav)204 xviewer_thumb_nav_start_scroll (GtkButton *button, XviewerThumbNav *nav)
205 {
206 	nav->priv->scroll_dir = gtk_widget_get_direction (GTK_WIDGET (button)) == GTK_TEXT_DIR_LTR ?
207 		GTK_WIDGET (button) == nav->priv->button_right :
208 		GTK_WIDGET (button) == nav->priv->button_left;
209 
210 	nav->priv->scroll_id = g_timeout_add (XVIEWER_THUMB_NAV_SCROLL_TIMEOUT,
211 					      xviewer_thumb_nav_scroll_step,
212 					      nav);
213 }
214 
215 static void
xviewer_thumb_nav_stop_scroll(GtkButton * button,XviewerThumbNav * nav)216 xviewer_thumb_nav_stop_scroll (GtkButton *button, XviewerThumbNav *nav)
217 {
218 	if (nav->priv->scroll_id > 0) {
219 		g_source_remove (nav->priv->scroll_id);
220 		nav->priv->scroll_id = 0;
221 		nav->priv->scroll_pos = 0;
222 	}
223 }
224 
225 static void
xviewer_thumb_nav_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)226 xviewer_thumb_nav_get_property (GObject    *object,
227 			    guint       property_id,
228 			    GValue     *value,
229 			    GParamSpec *pspec)
230 {
231 	XviewerThumbNav *nav = XVIEWER_THUMB_NAV (object);
232 
233 	switch (property_id)
234 	{
235 	case PROP_SHOW_BUTTONS:
236 		g_value_set_boolean (value,
237 			xviewer_thumb_nav_get_show_buttons (nav));
238 		break;
239 
240 	case PROP_THUMB_VIEW:
241 		g_value_set_object (value, nav->priv->thumbview);
242 		break;
243 
244 	case PROP_MODE:
245 		g_value_set_int (value,
246 			xviewer_thumb_nav_get_mode (nav));
247 		break;
248 	}
249 }
250 
251 static void
xviewer_thumb_nav_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)252 xviewer_thumb_nav_set_property (GObject      *object,
253 			    guint         property_id,
254 			    const GValue *value,
255 			    GParamSpec   *pspec)
256 {
257 	XviewerThumbNav *nav = XVIEWER_THUMB_NAV (object);
258 
259 	switch (property_id)
260 	{
261 	case PROP_SHOW_BUTTONS:
262 		xviewer_thumb_nav_set_show_buttons (nav,
263 			g_value_get_boolean (value));
264 		break;
265 
266 	case PROP_THUMB_VIEW:
267 		nav->priv->thumbview =
268 			GTK_WIDGET (g_value_get_object (value));
269 		break;
270 
271 	case PROP_MODE:
272 		xviewer_thumb_nav_set_mode (nav,
273 			g_value_get_int (value));
274 		break;
275 	}
276 }
277 
278 static GObject *
xviewer_thumb_nav_constructor(GType type,guint n_construct_properties,GObjectConstructParam * construct_params)279 xviewer_thumb_nav_constructor (GType type,
280 			   guint n_construct_properties,
281 			   GObjectConstructParam *construct_params)
282 {
283 	GObject *object;
284 	XviewerThumbNavPrivate *priv;
285 
286 	object = G_OBJECT_CLASS (xviewer_thumb_nav_parent_class)->constructor
287 			(type, n_construct_properties, construct_params);
288 
289 	priv = XVIEWER_THUMB_NAV (object)->priv;
290 
291 	if (priv->thumbview != NULL) {
292 		gtk_container_add (GTK_CONTAINER (priv->sw), priv->thumbview);
293 		gtk_widget_show_all (priv->sw);
294 	}
295 
296 	return object;
297 }
298 
299 static void
xviewer_thumb_nav_class_init(XviewerThumbNavClass * class)300 xviewer_thumb_nav_class_init (XviewerThumbNavClass *class)
301 {
302 	GObjectClass *g_object_class = (GObjectClass *) class;
303 
304 	g_object_class->constructor  = xviewer_thumb_nav_constructor;
305 	g_object_class->get_property = xviewer_thumb_nav_get_property;
306 	g_object_class->set_property = xviewer_thumb_nav_set_property;
307 
308 	g_object_class_install_property (g_object_class,
309 	                                 PROP_SHOW_BUTTONS,
310 	                                 g_param_spec_boolean ("show-buttons",
311 	                                                       "Show Buttons",
312 	                                                       "Whether to show navigation buttons or not",
313 	                                                       TRUE,
314 	                                                       (G_PARAM_READABLE | G_PARAM_WRITABLE)));
315 
316 	g_object_class_install_property (g_object_class,
317 	                                 PROP_THUMB_VIEW,
318 	                                 g_param_spec_object ("thumbview",
319 	                                                       "Thumbnail View",
320 	                                                       "The internal thumbnail viewer widget",
321 	                                                       XVIEWER_TYPE_THUMB_VIEW,
322 	                                                       (G_PARAM_CONSTRUCT_ONLY |
323 								G_PARAM_READABLE |
324 								G_PARAM_WRITABLE)));
325 
326 	g_object_class_install_property (g_object_class,
327 	                                 PROP_MODE,
328 	                                 g_param_spec_int ("mode",
329 	                                                   "Mode",
330 	                                                   "Thumb navigator mode",
331 	                                                   XVIEWER_THUMB_NAV_MODE_ONE_ROW,
332 							   XVIEWER_THUMB_NAV_MODE_MULTIPLE_ROWS,
333 							   XVIEWER_THUMB_NAV_MODE_ONE_ROW,
334 	                                                   (G_PARAM_READABLE | G_PARAM_WRITABLE)));
335 }
336 
337 static void
xviewer_thumb_nav_init(XviewerThumbNav * nav)338 xviewer_thumb_nav_init (XviewerThumbNav *nav)
339 {
340 	XviewerThumbNavPrivate *priv;
341 	GtkWidget *arrow;
342 
343 	gtk_orientable_set_orientation (GTK_ORIENTABLE (nav),
344 					GTK_ORIENTATION_HORIZONTAL);
345 
346 	nav->priv = xviewer_thumb_nav_get_instance_private (nav);
347 
348 	priv = nav->priv;
349 
350 	priv->mode = XVIEWER_THUMB_NAV_MODE_ONE_ROW;
351 
352 	priv->show_buttons = TRUE;
353 
354         priv->button_left = gtk_button_new ();
355 	gtk_button_set_relief (GTK_BUTTON (priv->button_left), GTK_RELIEF_NONE);
356 
357 	arrow = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_ETCHED_IN);
358 	gtk_container_add (GTK_CONTAINER (priv->button_left), arrow);
359 
360 	gtk_widget_set_size_request (GTK_WIDGET (priv->button_left), 25, 0);
361 
362         gtk_box_pack_start (GTK_BOX (nav), priv->button_left, FALSE, FALSE, 0);
363 
364 	g_signal_connect (priv->button_left,
365 			  "clicked",
366 			  G_CALLBACK (xviewer_thumb_nav_button_clicked),
367 			  nav);
368 
369 	g_signal_connect (priv->button_left,
370 			  "pressed",
371 			  G_CALLBACK (xviewer_thumb_nav_start_scroll),
372 			  nav);
373 
374 	g_signal_connect (priv->button_left,
375 			  "released",
376 			  G_CALLBACK (xviewer_thumb_nav_stop_scroll),
377 			  nav);
378 
379 	priv->sw = gtk_scrolled_window_new (NULL, NULL);
380 
381 	gtk_widget_set_name (gtk_scrolled_window_get_hscrollbar (GTK_SCROLLED_WINDOW (priv->sw)), "xviewer-image-gallery-scrollbar");
382 
383 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->sw),
384 					     GTK_SHADOW_IN);
385 
386 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->sw),
387 					GTK_POLICY_AUTOMATIC,
388 					GTK_POLICY_NEVER);
389 
390 	g_signal_connect (priv->sw,
391 			  "scroll-event",
392 			  G_CALLBACK (xviewer_thumb_nav_scroll_event),
393 			  nav);
394 	gtk_widget_add_events (priv->sw, GDK_SCROLL_MASK);
395 
396 	priv->adj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (priv->sw));
397 
398 	g_signal_connect (priv->adj,
399 			  "changed",
400 			  G_CALLBACK (xviewer_thumb_nav_adj_changed),
401 			  nav);
402 
403 	g_signal_connect (priv->adj,
404 			  "value-changed",
405 			  G_CALLBACK (xviewer_thumb_nav_adj_value_changed),
406 			  nav);
407 
408         gtk_box_pack_start (GTK_BOX (nav), priv->sw, TRUE, TRUE, 0);
409 
410         priv->button_right = gtk_button_new ();
411 	gtk_button_set_relief (GTK_BUTTON (priv->button_right), GTK_RELIEF_NONE);
412 
413 	arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
414 	gtk_container_add (GTK_CONTAINER (priv->button_right), arrow);
415 
416 	gtk_widget_set_size_request (GTK_WIDGET (priv->button_right), 25, 0);
417 
418         gtk_box_pack_start (GTK_BOX (nav), priv->button_right, FALSE, FALSE, 0);
419 
420 	g_signal_connect (priv->button_right,
421 			  "clicked",
422 			  G_CALLBACK (xviewer_thumb_nav_button_clicked),
423 			  nav);
424 
425 	g_signal_connect (priv->button_right,
426 			  "pressed",
427 			  G_CALLBACK (xviewer_thumb_nav_start_scroll),
428 			  nav);
429 
430 	g_signal_connect (priv->button_right,
431 			  "released",
432 			  G_CALLBACK (xviewer_thumb_nav_stop_scroll),
433 			  nav);
434 
435 	gtk_adjustment_value_changed (priv->adj);
436 }
437 
438 /**
439  * xviewer_thumb_nav_new:
440  * @thumbview: an #XviewerThumbView to embed in the navigation widget.
441  * @mode: The navigation mode.
442  * @show_buttons: Whether to show the navigation buttons.
443  *
444  * Creates a new thumbnail navigation widget.
445  *
446  * Returns: a new #XviewerThumbNav object.
447  **/
448 GtkWidget *
xviewer_thumb_nav_new(GtkWidget * thumbview,XviewerThumbNavMode mode,gboolean show_buttons)449 xviewer_thumb_nav_new (GtkWidget       *thumbview,
450 		   XviewerThumbNavMode  mode,
451 		   gboolean         show_buttons)
452 {
453 	GObject *nav;
454 
455 	nav = g_object_new (XVIEWER_TYPE_THUMB_NAV,
456 		            "show-buttons", show_buttons,
457 		            "mode", mode,
458 		            "thumbview", thumbview,
459 		            "homogeneous", FALSE,
460 		            "spacing", 0,
461 			    NULL);
462 
463 	return GTK_WIDGET (nav);
464 }
465 
466 /**
467  * xviewer_thumb_nav_get_show_buttons:
468  * @nav: an #XviewerThumbNav.
469  *
470  * Gets whether the navigation buttons are visible.
471  *
472  * Returns: %TRUE if the navigation buttons are visible,
473  * %FALSE otherwise.
474  **/
475 gboolean
xviewer_thumb_nav_get_show_buttons(XviewerThumbNav * nav)476 xviewer_thumb_nav_get_show_buttons (XviewerThumbNav *nav)
477 {
478 	g_return_val_if_fail (XVIEWER_IS_THUMB_NAV (nav), FALSE);
479 
480 	return nav->priv->show_buttons;
481 }
482 
483 /**
484  * xviewer_thumb_nav_set_show_buttons:
485  * @nav: an #XviewerThumbNav.
486  * @show_buttons: %TRUE to show the buttons, %FALSE to hide them.
487  *
488  * Sets whether the navigation buttons to the left and right of the
489  * widget should be visible.
490  **/
491 void
xviewer_thumb_nav_set_show_buttons(XviewerThumbNav * nav,gboolean show_buttons)492 xviewer_thumb_nav_set_show_buttons (XviewerThumbNav *nav, gboolean show_buttons)
493 {
494 	g_return_if_fail (XVIEWER_IS_THUMB_NAV (nav));
495 	g_return_if_fail (nav->priv->button_left  != NULL);
496 	g_return_if_fail (nav->priv->button_right != NULL);
497 
498 	nav->priv->show_buttons = show_buttons;
499 
500 	if (show_buttons &&
501 	    nav->priv->mode == XVIEWER_THUMB_NAV_MODE_ONE_ROW) {
502 		gtk_widget_show_all (nav->priv->button_left);
503 		gtk_widget_show_all (nav->priv->button_right);
504 	} else {
505 		gtk_widget_hide (nav->priv->button_left);
506 		gtk_widget_hide (nav->priv->button_right);
507 	}
508 }
509 
510 /**
511  * xviewer_thumb_nav_get_mode:
512  * @nav: an #XviewerThumbNav.
513  *
514  * Gets the navigation mode in @nav.
515  *
516  * Returns: A value in #XviewerThumbNavMode.
517  **/
518 XviewerThumbNavMode
xviewer_thumb_nav_get_mode(XviewerThumbNav * nav)519 xviewer_thumb_nav_get_mode (XviewerThumbNav *nav)
520 {
521 	g_return_val_if_fail (XVIEWER_IS_THUMB_NAV (nav), FALSE);
522 
523 	return nav->priv->mode;
524 }
525 
526 /**
527  * xviewer_thumb_nav_set_mode:
528  * @nav: An #XviewerThumbNav.
529  * @mode: One of #XviewerThumbNavMode.
530  *
531  * Sets the navigation mode in @nav. See #XviewerThumbNavMode for details.
532  **/
533 void
xviewer_thumb_nav_set_mode(XviewerThumbNav * nav,XviewerThumbNavMode mode)534 xviewer_thumb_nav_set_mode (XviewerThumbNav *nav, XviewerThumbNavMode mode)
535 {
536 	XviewerThumbNavPrivate *priv;
537 
538 	g_return_if_fail (XVIEWER_IS_THUMB_NAV (nav));
539 
540 	priv = nav->priv;
541 
542 	priv->mode = mode;
543 
544 	switch (mode)
545 	{
546 	case XVIEWER_THUMB_NAV_MODE_ONE_ROW:
547 		gtk_orientable_set_orientation (GTK_ORIENTABLE(priv->thumbview),
548 		                                GTK_ORIENTATION_HORIZONTAL);
549 
550 		gtk_widget_set_size_request (priv->thumbview, -1, -1);
551 		xviewer_thumb_view_set_item_height (XVIEWER_THUMB_VIEW (priv->thumbview),
552 						115);
553 
554 		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->sw),
555 						GTK_POLICY_AUTOMATIC,
556 						GTK_POLICY_NEVER);
557 
558 		xviewer_thumb_nav_set_show_buttons (nav, priv->show_buttons);
559 
560 		break;
561 
562 	case XVIEWER_THUMB_NAV_MODE_ONE_COLUMN:
563 		gtk_orientable_set_orientation (GTK_ORIENTABLE(priv->thumbview),
564 		                                GTK_ORIENTATION_VERTICAL);
565 		gtk_icon_view_set_columns (GTK_ICON_VIEW (priv->thumbview), 1);
566 
567 		gtk_widget_set_size_request (priv->thumbview, -1, -1);
568 		xviewer_thumb_view_set_item_height (XVIEWER_THUMB_VIEW (priv->thumbview),
569 						-1);
570 
571 		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->sw),
572 						GTK_POLICY_NEVER,
573 						GTK_POLICY_AUTOMATIC);
574 
575 		gtk_widget_hide (priv->button_left);
576 		gtk_widget_hide (priv->button_right);
577 
578 		break;
579 
580 	case XVIEWER_THUMB_NAV_MODE_MULTIPLE_ROWS:
581 		gtk_orientable_set_orientation (GTK_ORIENTABLE(priv->thumbview),
582 		                                GTK_ORIENTATION_VERTICAL);
583 		gtk_icon_view_set_columns (GTK_ICON_VIEW (priv->thumbview), -1);
584 
585 		gtk_widget_set_size_request (priv->thumbview, -1, 220);
586 		xviewer_thumb_view_set_item_height (XVIEWER_THUMB_VIEW (priv->thumbview),
587 						-1);
588 
589 		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->sw),
590 						GTK_POLICY_NEVER,
591 						GTK_POLICY_AUTOMATIC);
592 
593 		gtk_widget_hide (priv->button_left);
594 		gtk_widget_hide (priv->button_right);
595 
596 		break;
597 
598 	case XVIEWER_THUMB_NAV_MODE_MULTIPLE_COLUMNS:
599 		gtk_orientable_set_orientation (GTK_ORIENTABLE(priv->thumbview),
600 		                                GTK_ORIENTATION_VERTICAL);
601 		gtk_icon_view_set_columns (GTK_ICON_VIEW (priv->thumbview), -1);
602 
603 		gtk_widget_set_size_request (priv->thumbview, 230, -1);
604 		xviewer_thumb_view_set_item_height (XVIEWER_THUMB_VIEW (priv->thumbview),
605 						-1);
606 
607 		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->sw),
608 						GTK_POLICY_NEVER,
609 						GTK_POLICY_AUTOMATIC);
610 
611 		gtk_widget_hide (priv->button_left);
612 		gtk_widget_hide (priv->button_right);
613 
614 		break;
615 	}
616 }
617