Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / native / jni / gtk-peer / gnu_java_awt_peer_gtk_GtkScrollbarPeer.c
bloba90501968b684fe1ab94eb3fd632169e22a400c3
1 /* gtkscrollbarpeer.c -- Native implementation of GtkScrollbarPeer
2 Copyright (C) 1998, 1999, 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 #include <math.h>
40 #include "gtkpeer.h"
41 #include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
42 #include "gnu_java_awt_peer_gtk_GtkScrollbarPeer.h"
44 #define AWT_ADJUSTMENT_UNIT_INCREMENT 1
45 #define AWT_ADJUSTMENT_UNIT_DECREMENT 2
46 #define AWT_ADJUSTMENT_BLOCK_DECREMENT 3
47 #define AWT_ADJUSTMENT_BLOCK_INCREMENT 4
48 #define AWT_ADJUSTMENT_TRACK 5
50 static jmethodID postAdjustmentEventID;
51 static GtkWidget *scrollbar_get_widget (GtkWidget *widget);
53 void
54 cp_gtk_scrollbar_init_jni (void)
56 jclass gtkscrollbarpeer;
58 gtkscrollbarpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
59 "gnu/java/awt/peer/gtk/GtkScrollbarPeer");
61 postAdjustmentEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(),
62 gtkscrollbarpeer,
63 "postAdjustmentEvent",
64 "(II)V");
67 #if GTK_MINOR_VERSION > 4
68 static gboolean slider_moved_cb (GtkRange *range,
69 GtkScrollType scroll,
70 gdouble value,
71 jobject obj);
72 #else
73 static void post_change_event_cb (GtkRange *range,
74 jobject peer);
75 #endif
77 JNIEXPORT void JNICALL
78 Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_create
79 (JNIEnv *env, jobject obj, jint orientation, jint value,
80 jint min, jint max, jint step_incr, jint page_incr, jint visible_amount)
82 GtkWidget *scrollbar;
83 GtkWidget *eventbox;
84 GtkObject *adj;
86 /* Create global reference and save it for future use */
87 NSA_SET_GLOBAL_REF (env, obj);
89 gdk_threads_enter ();
91 /* A little hack because gtk_range_set_range() doesn't allow min == max. */
92 if (min == max)
94 if (visible_amount == 0)
95 visible_amount = 1;
96 max++;
99 adj = gtk_adjustment_new ((gdouble) value,
100 (gdouble) min,
101 (gdouble) max,
102 (gdouble) step_incr,
103 (gdouble) page_incr,
104 (gdouble) visible_amount);
106 scrollbar = orientation
107 ? gtk_vscrollbar_new (GTK_ADJUSTMENT (adj))
108 : gtk_hscrollbar_new (GTK_ADJUSTMENT (adj));
109 eventbox = gtk_event_box_new ();
110 gtk_container_add (GTK_CONTAINER (eventbox), scrollbar);
111 gtk_widget_show (scrollbar);
113 GTK_RANGE (scrollbar)->round_digits = 0;
114 /* These calls seem redundant but they are not. They clamp values
115 so that the slider's entirety is always between the two
116 steppers. */
117 gtk_range_set_range (GTK_RANGE (scrollbar), (gdouble) min, (gdouble) max);
118 gtk_range_set_value (GTK_RANGE (scrollbar), (gdouble) value);
120 gdk_threads_leave ();
122 NSA_SET_PTR (env, obj, eventbox);
125 JNIEXPORT void JNICALL
126 Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_connectSignals
127 (JNIEnv *env, jobject obj)
129 void *ptr = NSA_GET_PTR (env, obj);
130 GtkWidget *wid = scrollbar_get_widget (GTK_WIDGET (ptr));
131 jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
132 g_assert (gref);
134 gdk_threads_enter ();
136 /* Scrollbar signals */
137 #if GTK_MINOR_VERSION > 4
138 g_signal_connect (G_OBJECT (wid), "change-value",
139 G_CALLBACK (slider_moved_cb), *gref);
140 #else
141 g_signal_connect (G_OBJECT (wid), "value-changed",
142 G_CALLBACK (post_change_event_cb), *gref);
143 #endif
145 /* Component signals */
146 cp_gtk_component_connect_signals (G_OBJECT (wid), gref);
148 gdk_threads_leave ();
151 JNIEXPORT void JNICALL
152 Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_setLineIncrement
153 (JNIEnv *env, jobject obj, jint amount)
155 void *ptr;
156 GtkAdjustment *adj;
157 GtkWidget *wid;
159 ptr = NSA_GET_PTR (env, obj);
160 wid = scrollbar_get_widget (GTK_WIDGET (ptr));
162 gdk_threads_enter ();
164 adj = gtk_range_get_adjustment (GTK_RANGE (wid));
165 adj->step_increment = (gdouble) amount;
166 gtk_adjustment_changed (adj);
168 gdk_threads_leave ();
171 JNIEXPORT void JNICALL
172 Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_setPageIncrement
173 (JNIEnv *env, jobject obj, jint amount)
175 void *ptr;
176 GtkAdjustment *adj;
177 GtkWidget *wid;
179 ptr = NSA_GET_PTR (env, obj);
180 wid = scrollbar_get_widget (GTK_WIDGET (ptr));
182 gdk_threads_enter ();
184 adj = gtk_range_get_adjustment (GTK_RANGE (wid));
185 adj->page_increment = (gdouble) amount;
186 gtk_adjustment_changed (adj);
188 gdk_threads_leave ();
191 JNIEXPORT void JNICALL
192 Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_setBarValues
193 (JNIEnv *env, jobject obj, jint value, jint visible, jint min, jint max)
195 void *ptr;
196 GtkAdjustment *adj;
197 GtkWidget *wid;
199 ptr = NSA_GET_PTR (env, obj);
200 wid = scrollbar_get_widget (GTK_WIDGET (ptr));
202 gdk_threads_enter ();
204 /* A little hack because gtk_range_set_range() doesn't allow min == max. */
205 if (min == max)
207 if (visible == 0)
208 visible = 1;
209 max++;
212 adj = gtk_range_get_adjustment (GTK_RANGE (wid));
213 adj->page_size = (gdouble) visible;
215 gtk_range_set_range (GTK_RANGE (wid), (gdouble) min, (gdouble) max);
216 gtk_range_set_value (GTK_RANGE (wid), (gdouble) value);
218 gdk_threads_leave ();
221 #if GTK_MINOR_VERSION > 4
222 static gboolean
223 slider_moved_cb (GtkRange *range,
224 GtkScrollType scroll,
225 gdouble value,
226 jobject obj)
228 GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (range));
230 value = CLAMP (value, adj->lower,
231 (adj->upper - adj->page_size));
233 if (range->round_digits >= 0)
235 gdouble power;
236 gint i;
238 i = range->round_digits;
239 power = 1;
240 while (i--)
241 power *= 10;
243 value = floor ((value * power) + 0.5) / power;
246 switch (scroll)
248 case GTK_SCROLL_STEP_BACKWARD:
249 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
250 AWT_ADJUSTMENT_UNIT_DECREMENT,
251 (jint) value);
252 break;
253 case GTK_SCROLL_STEP_FORWARD:
254 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
255 AWT_ADJUSTMENT_UNIT_INCREMENT,
256 (jint) value);
257 break;
258 case GTK_SCROLL_PAGE_BACKWARD:
259 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
260 AWT_ADJUSTMENT_BLOCK_DECREMENT,
261 (jint) value);
262 break;
263 case GTK_SCROLL_PAGE_FORWARD:
264 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
265 AWT_ADJUSTMENT_BLOCK_INCREMENT,
266 (jint) value);
267 break;
268 default:
269 /* GTK_SCROLL_JUMP: */
270 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
271 AWT_ADJUSTMENT_TRACK,
272 (jint) value);
273 break;
275 return FALSE;
277 #else
278 static void
279 post_change_event_cb (GtkRange *range, jobject peer)
281 GtkAdjustment *adj;
282 adj = gtk_range_get_adjustment (range);
283 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer, postAdjustmentEventID,
284 AWT_ADJUSTMENT_TRACK, (jint) adj->value);
286 #endif
288 static GtkWidget *
289 scrollbar_get_widget (GtkWidget *widget)
291 GtkWidget *wid;
292 g_assert (GTK_IS_EVENT_BOX (widget));
293 wid = gtk_bin_get_child (GTK_BIN(widget));
295 return wid;