1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <gtk/gtk.h>
25
26
27
28 #define abs(n) (((n)>=0)?(n):-(n))
29
30 gdouble delta = 0.00000000000000001;
31
32 struct {
33 GtkWidget *pantalla;
34 gdouble acumulador;
35 gchar *ultimaOperacion;
36 gboolean hayPunto;
37 gboolean borrarPantalla;
38 } cal;
39
40 void cal_borrar_pantalla(){
41 gtk_label_set_text(GTK_LABEL(cal.pantalla), "");
42 cal.borrarPantalla = FALSE;
43 }
44
45 void cal_mod_pantalla(char *cad){
46 gtk_label_set_text(GTK_LABEL(cal.pantalla), cad);
47 }
48
49 void cal_pantalla_adic_digito(const gchar *digito){
50 char etiqueta[100 + 1];
51 if(cal.borrarPantalla){
52 cal_borrar_pantalla();
53 }
54 sprintf(etiqueta, "%s%s", gtk_label_get_text(GTK_LABEL(cal.pantalla)), digito);
55 gtk_label_set_text(GTK_LABEL(cal.pantalla), etiqueta);
56 }
57
58 void cal_pantalla_adic_punto(){
59 if(cal.borrarPantalla){
60 cal_borrar_pantalla();
61 }
62 if( ! cal.hayPunto){
63 char etiqueta[100 + 1];
64
65 sprintf(etiqueta, "%s,", gtk_label_get_text(GTK_LABEL(cal.pantalla)));
66 gtk_label_set_text(GTK_LABEL(cal.pantalla), etiqueta);
67 cal.hayPunto = TRUE;
68 }
69 }
70
71 gdouble cal_obt_ultimoOperando(){
72 gdouble ultimoOperando;
73 sscanf(gtk_label_get_text(GTK_LABEL(cal.pantalla)),"%lf", &ultimoOperando);
74 return ultimoOperando;
75 }
76
77 void cal_ini(){
78 cal_borrar_pantalla();
79 cal.acumulador = 0.0;
80 cal.ultimaOperacion = NULL;
81 cal.hayPunto = FALSE;
82 cal.borrarPantalla = FALSE;
83 }
84
85 void cal_mod_ultimaOperacion(const gchar *operacion){
86 cal.ultimaOperacion = (gchar *)operacion;
87 }
88
89 void cal_operar(){
90 gchar cad[100 + 1];
91
92 cal.borrarPantalla = TRUE;
93 if(cal.ultimaOperacion == NULL){
94 cal.acumulador = cal_obt_ultimoOperando();
95 return;
96 }
97 if(strcmp(cal.ultimaOperacion, "+") == 0){
98 cal.acumulador += cal_obt_ultimoOperando();
99 }
100 else if(strcmp(cal.ultimaOperacion, "-") == 0){
101 cal.acumulador -= cal_obt_ultimoOperando();
102 }
103 else if(strcmp(cal.ultimaOperacion, "*") == 0){
104 cal.acumulador *= cal_obt_ultimoOperando();
105 }
106 else if(strcmp(cal.ultimaOperacion, "/") == 0){
107 if(abs(cal_obt_ultimoOperando()) < delta){
108 cal_mod_pantalla("Error");
109 cal.ultimaOperacion = NULL;
110 cal.hayPunto = FALSE;
111 cal.borrarPantalla = TRUE;
112 return;
113 }
114 else{
115 cal.acumulador /= cal_obt_ultimoOperando();
116 }
117 }
118 sprintf(cad, "%g", cal.acumulador);
119 cal_mod_pantalla(cad);
120 cal.ultimaOperacion = NULL;
121 cal.hayPunto = FALSE;
122 }
123
124
125
126 static gboolean cerrar(GtkWidget *ventana, GdkEvent *evento, gpointer datos){
127 gtk_main_quit();
128 return FALSE;
129 }
130
131 static void al_oprimir_teclaNumerica(GtkWidget *tecla, gpointer datos){
132 cal_pantalla_adic_digito(gtk_button_get_label(GTK_BUTTON(tecla)));
133 }
134
135 static void al_oprimir_teclaPunto(GtkWidget *teclaPunto, gpointer datos){
136 cal_pantalla_adic_punto();
137 }
138
139 static void al_oprimir_teclaCe(GtkWidget *tecla, gpointer datos){
140 cal_borrar_pantalla();
141 }
142
143 static void al_oprimir_teclaC(GtkWidget *tecla, gpointer datos){
144 cal_ini();
145 }
146
147 static void al_oprimir_teclaIgual(GtkWidget *tecla, gpointer datos){
148 cal_operar();
149 }
150
151 static void al_oprimir_teclaOperacion(GtkWidget *tecla, gpointer datos){
152 cal_operar();
153 cal_mod_ultimaOperacion(gtk_button_get_label(GTK_BUTTON(tecla)));
154 }
155
156
157
158 int main(int argc, char *argv[]){
159 GtkWidget *ventana;
160 GtkWidget *tabla;
161 GtkWidget *tecla[10];
162 GtkWidget *teclaPunto;
163 GtkWidget *teclaIgual;
164 GtkWidget *teclaMas;
165 GtkWidget *teclaMenos;
166 GtkWidget *teclaPor;
167 GtkWidget *teclaDiv;
168 GtkWidget *teclaC;
169 GtkWidget *teclaCe;
170 int x, y , k;
171 gchar etiqueta[2];
172
173 cal_ini();
174 gtk_init(&argc, &argv);
175 ventana = gtk_window_new(GTK_WINDOW_TOPLEVEL);
176 g_signal_connect(G_OBJECT(ventana), "delete_event", G_CALLBACK(cerrar), NULL);
177 tabla = gtk_table_new(5, 5, TRUE);
178 gtk_container_add(GTK_CONTAINER(ventana), tabla);
179 cal.pantalla = gtk_label_new("");
180
181 gtk_table_attach_defaults(GTK_TABLE(tabla), cal.pantalla, 0, 5, 0, 1);
182 gtk_widget_show(cal.pantalla);
183
184
185 for(k = 0; k < 10; k++){
186 etiqueta[0] = k + '0';
187 etiqueta[1] = '\0';
188 tecla[k] = gtk_button_new_with_label(etiqueta);
189 g_signal_connect(G_OBJECT(tecla[k]), "clicked", G_CALLBACK(al_oprimir_teclaNumerica), NULL);
190 }
191
192
193 teclaPunto = gtk_button_new_with_label(".");
194 teclaIgual = gtk_button_new_with_label("=");
195 teclaMas = gtk_button_new_with_label("+");
196 teclaMenos = gtk_button_new_with_label("-");
197 teclaPor = gtk_button_new_with_label("*");
198 teclaDiv = gtk_button_new_with_label("/");
199 teclaC = gtk_button_new_with_label("C");
200 teclaCe= gtk_button_new_with_label("CE");
201
202
203 k = 1;
204 for(y = 3; y >= 1; y--){
205 for(x = 0; x <= 2; x++){
206 gtk_table_attach_defaults(GTK_TABLE(tabla), tecla[k], x, x + 1, y, y + 1);
207 gtk_widget_show(tecla[k++]);
208 }
209 }
210
211
212 gtk_table_attach_defaults(GTK_TABLE(tabla), tecla[0], 0, 1, 4, 5);
213 gtk_widget_show(tecla[0]);
214 gtk_table_attach_defaults(GTK_TABLE(tabla), teclaPunto, 1, 2, 4, 5);
215 g_signal_connect(G_OBJECT(teclaPunto), "clicked", G_CALLBACK(al_oprimir_teclaPunto), NULL);
216 gtk_widget_show(teclaPunto);
217 gtk_table_attach_defaults(GTK_TABLE(tabla), teclaCe, 3, 4, 1, 2);
218 g_signal_connect(G_OBJECT(teclaCe), "clicked", G_CALLBACK(al_oprimir_teclaCe), NULL);
219 gtk_widget_show(teclaCe);
220 gtk_table_attach_defaults(GTK_TABLE(tabla), teclaC, 4, 5, 1, 2);
221 g_signal_connect(GTK_OBJECT(teclaC), "clicked", G_CALLBACK(al_oprimir_teclaC), NULL);
222 gtk_widget_show(teclaC);
223 gtk_table_attach_defaults(GTK_TABLE(tabla), teclaPor, 3, 4, 2, 3);
224 g_signal_connect(G_OBJECT(teclaPor), "clicked", G_CALLBACK(al_oprimir_teclaOperacion), NULL);
225 gtk_widget_show(teclaPor);
226 gtk_table_attach_defaults(GTK_TABLE(tabla), teclaDiv, 4, 5, 2, 3);
227 g_signal_connect(G_OBJECT(teclaDiv), "clicked", G_CALLBACK(al_oprimir_teclaOperacion), NULL);
228 gtk_widget_show(teclaDiv);
229 gtk_table_attach_defaults(GTK_TABLE(tabla), teclaMas, 3, 4, 3, 4);
230 g_signal_connect(G_OBJECT(teclaMas), "clicked", G_CALLBACK(al_oprimir_teclaOperacion), NULL);
231 gtk_widget_show(teclaMas);
232 gtk_table_attach_defaults(GTK_TABLE(tabla), teclaMenos, 4, 5, 3, 4);
233 g_signal_connect(G_OBJECT(teclaMenos), "clicked", G_CALLBACK(al_oprimir_teclaOperacion), NULL);
234 gtk_widget_show(teclaMenos);
235 gtk_table_attach_defaults(GTK_TABLE(tabla), teclaIgual, 3, 5, 4, 5);
236 g_signal_connect(G_OBJECT(teclaIgual), "clicked", G_CALLBACK(al_oprimir_teclaIgual), NULL);
237 gtk_widget_show(teclaIgual);
238
239 gtk_widget_show(tabla);
240 gtk_widget_show(ventana);
241 gtk_main();
242
243 return 0;
244 }