1 /* gtkscrollbarpeer.c -- Native implementation of GtkScrollbarPeer
2 Copyright (C) 1998, 1999 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
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.
10
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.
15
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.
20
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.
25
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. */
37
38
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"
43
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
49
50 static jmethodID postAdjustmentEventID;
51
52 void
cp_gtk_scrollbar_init_jni(void)53 cp_gtk_scrollbar_init_jni (void)
54 {
55 jclass gtkscrollbarpeer;
56
57 gtkscrollbarpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
58 "gnu/java/awt/peer/gtk/GtkScrollbarPeer");
59
60 postAdjustmentEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(),
61 gtkscrollbarpeer,
62 "postAdjustmentEvent",
63 "(II)V");
64 }
65
66 #if GTK_MINOR_VERSION > 4
67 static gboolean slider_moved_cb (GtkRange *range,
68 GtkScrollType scroll,
69 gdouble value,
70 jobject obj);
71 #else
72 static void post_change_event_cb (GtkRange *range,
73 jobject peer);
74 #endif
75
76 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_create(JNIEnv * env,jobject obj,jint orientation,jint value,jint min,jint max,jint step_incr,jint page_incr,jint visible_amount)77 Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_create
78 (JNIEnv *env, jobject obj, jint orientation, jint value,
79 jint min, jint max, jint step_incr, jint page_incr, jint visible_amount)
80 {
81 GtkWidget *scrollbar;
82 GtkObject *adj;
83
84 /* Create global reference and save it for future use */
85 NSA_SET_GLOBAL_REF (env, obj);
86
87 gdk_threads_enter ();
88
89 adj = gtk_adjustment_new ((gdouble) value,
90 (gdouble) min,
91 (gdouble) max,
92 (gdouble) step_incr,
93 (gdouble) page_incr,
94 (gdouble) visible_amount);
95
96 scrollbar = orientation
97 ? gtk_vscrollbar_new (GTK_ADJUSTMENT (adj))
98 : gtk_hscrollbar_new (GTK_ADJUSTMENT (adj));
99
100 GTK_RANGE (scrollbar)->round_digits = 0;
101 /* These calls seem redundant but they are not. They clamp values
102 so that the slider's entirety is always between the two
103 steppers. */
104 gtk_range_set_range (GTK_RANGE (scrollbar), (gdouble) min, (gdouble) max);
105 gtk_range_set_value (GTK_RANGE (scrollbar), (gdouble) value);
106
107 gdk_threads_leave ();
108
109 NSA_SET_PTR (env, obj, scrollbar);
110 }
111
112 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_connectSignals(JNIEnv * env,jobject obj)113 Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_connectSignals
114 (JNIEnv *env, jobject obj)
115 {
116 void *ptr = NSA_GET_PTR (env, obj);
117 jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
118 g_assert (gref);
119
120 gdk_threads_enter ();
121
122 /* Scrollbar signals */
123 #if GTK_MINOR_VERSION > 4
124 g_signal_connect (G_OBJECT (ptr), "change-value",
125 G_CALLBACK (slider_moved_cb), *gref);
126 #else
127 g_signal_connect (G_OBJECT (ptr), "value-changed",
128 G_CALLBACK (post_change_event_cb), *gref);
129 #endif
130
131 /* Component signals */
132 cp_gtk_component_connect_signals (G_OBJECT (ptr), gref);
133
134 gdk_threads_leave ();
135 }
136
137 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_setLineIncrement(JNIEnv * env,jobject obj,jint amount)138 Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_setLineIncrement
139 (JNIEnv *env, jobject obj, jint amount)
140 {
141 void *ptr;
142 GtkAdjustment *adj;
143
144 ptr = NSA_GET_PTR (env, obj);
145
146 gdk_threads_enter ();
147
148 adj = gtk_range_get_adjustment (GTK_RANGE (ptr));
149 adj->step_increment = (gdouble) amount;
150 gtk_adjustment_changed (adj);
151
152 gdk_threads_leave ();
153 }
154
155 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_setPageIncrement(JNIEnv * env,jobject obj,jint amount)156 Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_setPageIncrement
157 (JNIEnv *env, jobject obj, jint amount)
158 {
159 void *ptr;
160 GtkAdjustment *adj;
161
162 ptr = NSA_GET_PTR (env, obj);
163
164 gdk_threads_enter ();
165
166 adj = gtk_range_get_adjustment (GTK_RANGE (ptr));
167 adj->page_increment = (gdouble) amount;
168 gtk_adjustment_changed (adj);
169
170 gdk_threads_leave ();
171 }
172
173 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_setValues(JNIEnv * env,jobject obj,jint value,jint visible,jint min,jint max)174 Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_setValues
175 (JNIEnv *env, jobject obj, jint value, jint visible, jint min, jint max)
176 {
177 void *ptr;
178 GtkAdjustment *adj;
179
180 ptr = NSA_GET_PTR (env, obj);
181
182 gdk_threads_enter ();
183
184 adj = gtk_range_get_adjustment (GTK_RANGE (ptr));
185 adj->page_size = (gdouble) visible;
186
187 gtk_range_set_range (GTK_RANGE (ptr), (gdouble) min, (gdouble) max);
188 gtk_range_set_value (GTK_RANGE (ptr), (gdouble) value);
189
190 gdk_threads_leave ();
191 }
192
193 #if GTK_MINOR_VERSION > 4
194 static gboolean
slider_moved_cb(GtkRange * range,GtkScrollType scroll,gdouble value,jobject obj)195 slider_moved_cb (GtkRange *range,
196 GtkScrollType scroll,
197 gdouble value,
198 jobject obj)
199 {
200 GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (range));
201
202 value = CLAMP (value, adj->lower,
203 (adj->upper - adj->page_size));
204
205 if (range->round_digits >= 0)
206 {
207 gdouble power;
208 gint i;
209
210 i = range->round_digits;
211 power = 1;
212 while (i--)
213 power *= 10;
214
215 value = floor ((value * power) + 0.5) / power;
216 }
217
218 switch (scroll)
219 {
220 case GTK_SCROLL_STEP_BACKWARD:
221 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
222 AWT_ADJUSTMENT_UNIT_DECREMENT,
223 (jint) value);
224 break;
225 case GTK_SCROLL_STEP_FORWARD:
226 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
227 AWT_ADJUSTMENT_UNIT_INCREMENT,
228 (jint) value);
229 break;
230 case GTK_SCROLL_PAGE_BACKWARD:
231 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
232 AWT_ADJUSTMENT_BLOCK_DECREMENT,
233 (jint) value);
234 break;
235 case GTK_SCROLL_PAGE_FORWARD:
236 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
237 AWT_ADJUSTMENT_BLOCK_INCREMENT,
238 (jint) value);
239 break;
240 default:
241 /* GTK_SCROLL_JUMP: */
242 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
243 AWT_ADJUSTMENT_TRACK,
244 (jint) value);
245 break;
246 }
247 return FALSE;
248 }
249 #else
250 static void
post_change_event_cb(GtkRange * range,jobject peer)251 post_change_event_cb (GtkRange *range, jobject peer)
252 {
253 GtkAdjustment *adj;
254 adj = gtk_range_get_adjustment (range);
255 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer, postAdjustmentEventID,
256 AWT_ADJUSTMENT_TRACK, (jint) adj->value);
257 }
258 #endif
259