1 /*
2 * Copyright (C) 2002 2003 2004 2005 2011, Magnus Hjorth
3 *
4 * This file is part of mhWaveEdit.
5 *
6 * mhWaveEdit 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 of the License, or
9 * (at your option) any later version.
10 *
11 * mhWaveEdit is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with mhWaveEdit; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21
22 #include <config.h>
23
24 #include <stdlib.h>
25 #include <gtk/gtk.h>
26 #include "um.h"
27 #include "int_box.h"
28 #include "main.h"
29 #include "gettext.h"
30
31 #if GTK_MAJOR_VERSION==2
32 static GtkEntryClass *parent_class;
33 #else
34 static GtkEditableClass *parent_class;
35 #endif
36
37 enum {
38 NUMCHANGED_SIGNAL,
39 LAST_SIGNAL
40 };
41
42 typedef void (*GtkSignal_NONE__LONG) (GtkObject *object, long int arg1,
43 gpointer user_data);
44
45 #if GTK_MAJOR_VERSION == 2
46
47 # include "int_box_marsh.c"
48 # define gtk_marshal_NONE__LONG gtk_marshal_VOID__LONG
49
50 #else
51
gtk_marshal_NONE__LONG(GtkObject * object,GtkSignalFunc func,gpointer func_data,GtkArg * args)52 static void gtk_marshal_NONE__LONG(GtkObject *object, GtkSignalFunc func,
53 gpointer func_data, GtkArg *args)
54 {
55 GtkSignal_NONE__LONG rfunc;
56 rfunc=(GtkSignal_NONE__LONG)func;
57 rfunc(object,GTK_VALUE_LONG(args[0]),func_data);
58 }
59
60 #endif /* GTK 2 */
61
62 static guint intbox_signals[LAST_SIGNAL] = { 0 };
63
intbox_update_text(Intbox * box)64 static void intbox_update_text(Intbox *box)
65 {
66 gchar e[30];
67 g_snprintf(e,sizeof(e),"%ld",box->val);
68 gtk_entry_set_text(GTK_ENTRY(box),e);
69 }
70
71 #if GTK_MAJOR_VERSION==2
intbox_activate(GtkEntry * editable)72 static void intbox_activate(GtkEntry *editable)
73 #else
74 static void intbox_activate(GtkEditable *editable)
75 #endif
76 {
77 long l;
78 char *c,*d;
79 c=(char *)gtk_entry_get_text(GTK_ENTRY(editable));
80 l=strtol(c,&d,10);
81 if (*d==0)
82 intbox_set(INTBOX(editable),l);
83 else
84 intbox_update_text(INTBOX(editable));
85 if (parent_class->activate) parent_class->activate(editable);
86 }
87
intbox_focus_out(GtkWidget * widget,GdkEventFocus * event)88 static gint intbox_focus_out(GtkWidget *widget, GdkEventFocus *event)
89 {
90 long l;
91 char *c,*d;
92 Intbox *b = INTBOX(widget);
93 c=(char *)gtk_entry_get_text(GTK_ENTRY(widget));
94 l=strtol(c,&d,10);
95 if (*d==0 && b->adj!=NULL && l>=(long)gtk_adjustment_get_lower(b->adj) &&
96 l<=(long)gtk_adjustment_get_upper(b->adj))
97 gtk_adjustment_set_value(b->adj,l);
98 return GTK_WIDGET_CLASS(parent_class)->focus_out_event(widget,event);
99 }
100
intbox_class_init(IntboxClass * klass)101 static void intbox_class_init(IntboxClass *klass)
102 {
103 parent_class = gtk_type_class(gtk_entry_get_type());
104 #if GTK_MAJOR_VERSION==2
105 GTK_ENTRY_CLASS(klass)->activate = intbox_activate;
106 #else
107 GTK_EDITABLE_CLASS(klass)->activate = intbox_activate;
108 #endif
109 GTK_WIDGET_CLASS(klass)->focus_out_event = intbox_focus_out;
110 klass->numchange=NULL;
111 intbox_signals[NUMCHANGED_SIGNAL] =
112 gtk_signal_new("numchanged",GTK_RUN_FIRST,
113 GTK_CLASS_TYPE(klass),
114 GTK_SIGNAL_OFFSET(IntboxClass,numchange),
115 gtk_marshal_NONE__LONG,GTK_TYPE_NONE,1,
116 GTK_TYPE_LONG);
117
118 gtk_object_class_add_signals(GTK_OBJECT_CLASS(klass),intbox_signals,
119 LAST_SIGNAL);
120 }
121
intbox_init(Intbox * fbox)122 static void intbox_init(Intbox *fbox)
123 {
124 #if GTK_MAJOR_VERSION==2
125 gtk_entry_set_width_chars(GTK_ENTRY(fbox),10);
126 #else
127 GtkRequisition req;
128 gtk_widget_size_request(GTK_WIDGET(fbox),&req);
129 gtk_widget_set_usize(GTK_WIDGET(fbox),req.width/3,req.height);
130 #endif
131 fbox->adj = NULL;
132 }
133
intbox_get_type(void)134 GtkType intbox_get_type(void)
135 {
136 static GtkType id=0;
137 if (!id) {
138 GtkTypeInfo info = {
139 "Intbox",
140 sizeof(Intbox),
141 sizeof(IntboxClass),
142 (GtkClassInitFunc) intbox_class_init,
143 (GtkObjectInitFunc) intbox_init,
144 NULL,
145 NULL};
146 id=gtk_type_unique(gtk_entry_get_type(),&info);
147 }
148 return id;
149 }
150
intbox_set(Intbox * box,long val)151 void intbox_set(Intbox *box, long val)
152 {
153 if (box->val == val) return;
154 if (box->adj != NULL &&
155 val >= (long)gtk_adjustment_get_lower(box->adj) &&
156 val <= (long)gtk_adjustment_get_upper(box->adj)) {
157 gtk_adjustment_set_value(box->adj,(gfloat)val);
158 return;
159 }
160 box->val=val;
161 intbox_update_text(box);
162 gtk_signal_emit(GTK_OBJECT(box),intbox_signals[NUMCHANGED_SIGNAL],box->val);
163 }
164
intbox_new(long val)165 GtkWidget *intbox_new(long val)
166 {
167 Intbox *box;
168 box=gtk_type_new(intbox_get_type());
169 box->val=val-1;
170 intbox_set(box,val);
171 return GTK_WIDGET(box);
172 }
173
intbox_check(Intbox * box)174 gboolean intbox_check(Intbox *box)
175 {
176 long l;
177 char *c,*d;
178 c=(char *)gtk_entry_get_text(GTK_ENTRY(box));
179 l=strtol(c,&d,10);
180 if (*d==0) {
181 intbox_set(box,l);
182 return FALSE;
183 } else {
184 d = g_strdup_printf(_("'%s' is not a number!"),c);
185 user_error(d);
186 g_free(d);
187 return TRUE;
188 }
189 }
190
intbox_check_limit(Intbox * box,long int lowest,long int highest,gchar * valuename)191 gboolean intbox_check_limit(Intbox *box, long int lowest, long int highest,
192 gchar *valuename)
193 {
194 long l;
195 char *c,*d;
196 c = (char *)gtk_entry_get_text(GTK_ENTRY(box));
197 l = strtol(c,&d,10);
198 if (*d == 0 && l >= lowest && l <= highest) {
199 intbox_set(box,l);
200 return FALSE;
201 } else {
202 d = g_strdup_printf(_("Value for %s must be a number between %ld and "
203 "%ld"),valuename,lowest,highest);
204 user_error(d);
205 g_free(d);
206 return TRUE;
207 }
208 }
209
intbox_adj_changed(GtkAdjustment * adjustment,gpointer user_data)210 static void intbox_adj_changed(GtkAdjustment *adjustment, gpointer user_data)
211 {
212 Intbox *box = INTBOX(user_data);
213 box->val = box->adj->value;
214 intbox_update_text(box);
215 gtk_signal_emit(GTK_OBJECT(box),intbox_signals[NUMCHANGED_SIGNAL],
216 box->val);
217 }
218
219
intbox_create_scale(Intbox * box,long minval,long maxval)220 GtkWidget *intbox_create_scale(Intbox *box, long minval, long maxval)
221 {
222 GtkWidget *w;
223 #if GTK_MAJOR_VERSION > 1
224 GtkRequisition req;
225 #endif
226
227 if (box->adj == NULL) {
228 box->adj = GTK_ADJUSTMENT(gtk_adjustment_new(minval,minval,
229 maxval+1.0,
230 1.0,
231 10.0,
232 1.0));
233 gtk_signal_connect(GTK_OBJECT(box->adj),"value_changed",
234 GTK_SIGNAL_FUNC(intbox_adj_changed),box);
235 gtk_adjustment_set_value(box->adj,box->val);
236 }
237 w = gtk_hscale_new(box->adj);
238 gtk_scale_set_digits(GTK_SCALE(w),0);
239 #if GTK_MAJOR_VERSION > 1
240 gtk_widget_size_request(w,&req);
241 gtk_widget_set_usize(w,req.width*5,req.height);
242 #endif
243 return w;
244 }
245