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