2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * See the COPYING file for license information.
18 * Guillaume Chazarain <guichaz@yahoo.fr>
21 /******************************************
22 * The vertical and horizontal scrollbars *
23 ******************************************/
26 #include "scrollbars.h"
28 #include "gliv_image.h"
32 #include "rendering.h"
35 extern options_struct
*options
;
36 extern gliv_image
*current_image
;
38 /* Horizontal Scrollbar. */
39 static GtkHScrollbar
*hscroll
;
41 /* Vertical Scrollbar. */
42 static GtkVScrollbar
*vscroll
;
44 void toggle_scrollbars(void)
46 /* We are not reentrant. */
47 static gboolean toggling
= FALSE
;
54 if (!toggle_widget(GTK_WIDGET(hscroll
), &options
->scrollbars
))
57 /* To undo the toggle_widget() side effect. */
58 options
->scrollbars
^= TRUE
;
60 if (!toggle_widget(GTK_WIDGET(vscroll
), &options
->scrollbars
))
63 if (options
->scrollbars
)
69 /* Update a given scrollbar. */
70 static void update_scroll(GtkScrollbar
* scroll
, gfloat min
, gfloat max
,
74 gboolean update_needed
= FALSE
;
77 adj
= gtk_range_get_adjustment(GTK_RANGE(scroll
));
79 /* Smallest length containing the image and the window = window U image. */
80 previous
= adj
->lower
;
81 adj
->lower
= MIN(min
, 0.0);
82 update_needed
= update_needed
|| !float_equal(previous
, adj
->lower
);
84 previous
= adj
->upper
;
85 adj
->upper
= MAX(max
, dim
);
86 update_needed
= update_needed
|| !float_equal(previous
, adj
->upper
);
91 adj
->step_increment
= MOVE_OFFSET
;
92 adj
->page_increment
= dim
;
94 /* The offset is actually computed with adj->lower and adj->upper. */
98 gtk_adjustment_changed(adj
);
99 gdk_window_process_updates(GTK_WIDGET(scroll
)->window
, FALSE
);
103 /* Update both scrollbars. */
104 void update_scrollbars(void)
106 gfloat min_x
, max_x
, min_y
, max_y
;
108 if (current_image
== NULL
|| options
->scrollbars
== FALSE
)
111 get_matrix_bounding_box(&min_x
, &max_x
, &min_y
, &max_y
);
113 update_scroll(GTK_SCROLLBAR(hscroll
), min_x
, max_x
,
114 (gfloat
) rt
->wid_size
->width
);
116 update_scroll(GTK_SCROLLBAR(vscroll
), min_y
, max_y
,
117 (gfloat
) rt
->wid_size
->height
);
120 static void scroll_val(GtkRange
* range
)
124 offset
= -1.0 * gtk_range_get_value(range
);
126 if (range
== GTK_RANGE(hscroll
))
127 matrix_move(offset
, 0.0);
129 /* range == GTK_RANGE(vscroll) */
130 matrix_move(0.0, offset
);
132 refresh(REFRESH_BURST
| APPEND_HISTORY
);
136 /* Called during the initialization to build the two scrollbars. */
137 GtkWidget
*get_new_scrollbar(gboolean horizontal
)
142 range
= GTK_RANGE(gtk_hscrollbar_new(NULL
));
143 hscroll
= GTK_HSCROLLBAR(range
);
145 range
= GTK_RANGE(gtk_vscrollbar_new(NULL
));
146 vscroll
= GTK_VSCROLLBAR(range
);
149 gtk_range_set_update_policy(range
, GTK_UPDATE_CONTINUOUS
);
151 g_signal_connect(range
, "value-changed", G_CALLBACK(scroll_val
), NULL
);
153 return GTK_WIDGET(range
);
156 void hide_scrollbars(void)
158 gtk_widget_hide(GTK_WIDGET(hscroll
));
159 gtk_widget_hide(GTK_WIDGET(vscroll
));