Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.h>
- #include <gtk/gtk.h>
- int main( int argc, char **argv );
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
- {
- return main (__argc, __argv);
- }
- /***********************************
- GLOBAL VARIABLES
- ***********************************/
- double accum = 0.0; //Holds the current number
- char op = NULL; //Holds the most recent operator clicked
- bool started = false; //Minor influence, makes the UI look better
- bool op_clicked = true; //Lets the num_button_clicked start a new number input
- /***********************************
- FUNCTION DECLARATIONS
- ***********************************/
- double stringToDouble(char *string); //Converts a char* to a double
- gboolean containsDecimal(char *string); //Returns TRUE if the char* passed contains a '.', and FALSE otherwise
- char* substr(char* string, int begin, int end); //Returns a substring of a char*
- char* removeZeros(char* string); //Removes unneeded zeros after the decimal
- double power(double a, int b); //Raises a to the power of b
- /***********************************
- EVENT HANDLERS
- ***********************************/
- void
- num_button_clicked (GtkButton *button, gpointer user_data)
- {
- GtkEntry *entry;
- const char *button_label;
- char *entry_text;
- entry = GTK_ENTRY (user_data);//convert back to a GtkEntry*
- int button_value;
- button_label = gtk_button_get_label (button);
- if(button_label[0] == '.' && (!containsDecimal((char*)gtk_entry_get_text (entry)) || op_clicked))//Only add a decimal if there are no decimals already in the string
- {
- entry_text = g_strdup_printf ("%s%c", op_clicked ? "0" : gtk_entry_get_text (entry), '.');
- }
- else if(button_label[0] == '.')//Do nothing if there is already a decimal and the decimal button was clicked
- {
- return;
- }
- else//Concatonate the numbers to the string
- {
- button_value = button_label[0] - '0';
- entry_text = g_strdup_printf ("%s%d", op_clicked ? "" : gtk_entry_get_text (entry), button_value);
- }
- gtk_entry_set_text (entry, entry_text);
- g_free (entry_text);//must free the memory that was used by g_strdup_printf
- op_clicked = false;
- }
- void
- buttonOp_clicked (GtkButton *button, gpointer user_data)
- {
- GtkEntry *entry;
- entry = GTK_ENTRY (user_data);
- if(!started)//Initialize accum if this is the first number entry
- {
- accum = stringToDouble((char*)gtk_entry_get_text (entry));
- }
- else//Do math otherwise
- {
- char* entry_text;
- switch(op)
- {
- case '+':
- accum += stringToDouble((char*)gtk_entry_get_text (entry));
- break;
- case '-':
- accum -= stringToDouble((char*)gtk_entry_get_text (entry));
- break;
- case '*':
- accum *= stringToDouble((char*)gtk_entry_get_text (entry));
- break;
- case '/':
- accum /= stringToDouble((char*)gtk_entry_get_text (entry));
- break;
- case '^':
- accum = power(accum, (int)stringToDouble((char*)gtk_entry_get_text (entry)));
- }
- entry_text = g_strdup_printf ("%f", accum);
- gtk_entry_set_text (entry, removeZeros(entry_text));//Update the text view
- g_free(entry_text);
- }
- op = gtk_button_get_label (button)[0];//Update the operator
- started = true;//User has started calculating
- op_clicked = true;
- }
- void
- buttonNeg_clicked (GtkButton *button, gpointer user_data)
- {
- GtkEntry *entry;
- entry = GTK_ENTRY (user_data);
- char *entry_text;
- entry_text = g_strdup (gtk_entry_get_text (entry));
- if(entry_text[0] == '0' && entry_text[1] == '\0')
- {
- g_free (entry_text);
- return;
- }
- if(entry_text[0] == '-')
- {
- gtk_entry_set_text (entry, removeZeros(substr(entry_text, 1, strlen(entry_text) - 1)));//Remove the '-'
- }
- else
- {
- g_free(entry_text);
- entry_text = g_strdup_printf ("%c%s", '-', gtk_entry_get_text (entry));//Put a '-' at the beginning of the string
- gtk_entry_set_text (entry, removeZeros(entry_text));
- }
- g_free(entry_text);//Free the memory
- }
- void
- buttonFct_clicked (GtkButton *button, gpointer user_data)
- {
- GtkEntry *entry;
- entry = GTK_ENTRY (user_data);
- if(containsDecimal((char*)gtk_entry_get_text (entry)) || gtk_entry_get_text (entry)[0] == '-')//Cannot take the factorial of a non-whole number
- {
- char *entry_text;
- entry_text = g_strdup_printf("CANNOT EVALUATE \"%s!\"", gtk_entry_get_text (entry));
- gtk_entry_set_text (entry, entry_text);
- g_free(entry_text);
- accum = 0.0;
- op = NULL;
- started = false;
- op_clicked = true;
- }
- else
- {
- __int64 total = 1;
- __int64 prev_total = 1;
- bool overflow = false;
- for(int i = (int)stringToDouble((char*)gtk_entry_get_text (entry)); i > 0; i--)
- {
- total *= i;
- if(total / i != prev_total)
- {
- overflow = true;
- break;
- }
- prev_total = total;
- }
- char *entry_text;
- entry_text = g_strdup_printf ("%d", total);
- if(overflow || entry_text[0] == '-')//Overflow error - This only works sometimes
- {
- gtk_entry_set_text (entry, "OVERFLOW");
- accum = 0.0;
- op = NULL;
- started = false;
- }
- else
- {
- gtk_entry_set_text (entry, entry_text);
- }
- op_clicked = true;
- g_free(entry_text);
- }
- }
- void
- buttonEqu_clicked (GtkButton *button, gpointer user_data)
- {
- GtkEntry *entry;
- entry = GTK_ENTRY (user_data);
- if(started)
- {
- char *entry_text;
- if(!op_clicked)
- {
- switch(op)
- {
- case '+':
- accum += stringToDouble((char*)gtk_entry_get_text (entry));
- break;
- case '-':
- accum -= stringToDouble((char*)gtk_entry_get_text (entry));
- break;
- case '*':
- accum *= stringToDouble((char*)gtk_entry_get_text (entry));
- break;
- case '/':
- accum /= stringToDouble((char*)gtk_entry_get_text (entry));
- break;
- case '^':
- accum = power(accum, (int)stringToDouble((char*)gtk_entry_get_text (entry)));
- }
- }
- entry_text = g_strdup_printf ("%f", accum);
- gtk_entry_set_text (entry, removeZeros(entry_text));
- g_free(entry_text);
- op_clicked = true;//Reset all the values to start a new calculator session
- accum = 0.0;
- op = NULL;
- started = false;
- }
- }
- void
- buttonClr_clicked (GtkButton *button, gpointer user_data)
- {
- GtkEntry *entry;
- entry = GTK_ENTRY (user_data);
- gtk_entry_set_text (entry, "0");//Reset all the values to start a new calculator session
- accum = 0.0;
- op = NULL;
- started = false;
- op_clicked = true;
- }
- /***********************************
- ENTRY POINT
- ***********************************/
- int main (int argc, char **argv)
- {
- GtkWidget *window;
- GtkWidget *vbox;
- GtkWidget *hbox1;
- GtkWidget *hbox2;
- GtkWidget *hbox3;
- GtkWidget *hbox4;
- GtkWidget *hbox5;
- GtkWidget *button0;
- GtkWidget *button1;
- GtkWidget *button2;
- GtkWidget *button3;
- GtkWidget *button4;
- GtkWidget *button5;
- GtkWidget *button6;
- GtkWidget *button7;
- GtkWidget *button8;
- GtkWidget *button9;
- GtkWidget *buttonAdd;
- GtkWidget *buttonSub;
- GtkWidget *buttonMul;
- GtkWidget *buttonDiv;
- GtkWidget *buttonEqu;
- GtkWidget *buttonClr;
- GtkWidget *buttonDec;
- GtkWidget *buttonExp;
- GtkWidget *buttonNeg;
- GtkWidget *buttonFct;
- GtkWidget *entry;
- //Call this before setting up widgets, etc
- gtk_init (&argc, &argv);
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title (GTK_WINDOW (window), "Calculator");
- gtk_window_set_default_size (GTK_WINDOW (window), 300, 200);
- vbox = gtk_vbox_new (TRUE, 6);
- hbox1 = gtk_hbox_new (TRUE, 6);
- hbox2 = gtk_hbox_new (TRUE, 6);
- hbox3 = gtk_hbox_new (TRUE, 6);
- hbox4 = gtk_hbox_new (TRUE, 6);
- hbox5 = gtk_hbox_new (TRUE, 6);
- button0 = gtk_button_new_with_label ("0");
- button1 = gtk_button_new_with_label ("1");
- button2 = gtk_button_new_with_label ("2");
- button3 = gtk_button_new_with_label ("3");
- button4 = gtk_button_new_with_label ("4");
- button5 = gtk_button_new_with_label ("5");
- button6 = gtk_button_new_with_label ("6");
- button7 = gtk_button_new_with_label ("7");
- button8 = gtk_button_new_with_label ("8");
- button9 = gtk_button_new_with_label ("9");
- buttonAdd = gtk_button_new_with_label ("+");
- buttonSub = gtk_button_new_with_label ("-");
- buttonMul = gtk_button_new_with_label ("*");
- buttonDiv = gtk_button_new_with_label ("/");
- buttonEqu = gtk_button_new_with_label ("=");
- buttonClr = gtk_button_new_with_label ("C");
- buttonDec = gtk_button_new_with_label (".");
- buttonExp = gtk_button_new_with_label ("^");
- buttonNeg = gtk_button_new_with_label ("~");
- buttonFct = gtk_button_new_with_label ("!");
- entry = gtk_entry_new ();
- gtk_entry_set_text (GTK_ENTRY (entry), "0");
- gtk_entry_set_editable (GTK_ENTRY (entry), FALSE);
- g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
- g_signal_connect (G_OBJECT (button0), "clicked", G_CALLBACK (num_button_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (button1), "clicked", G_CALLBACK (num_button_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (button2), "clicked", G_CALLBACK (num_button_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (button3), "clicked", G_CALLBACK (num_button_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (button4), "clicked", G_CALLBACK (num_button_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (button5), "clicked", G_CALLBACK (num_button_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (button6), "clicked", G_CALLBACK (num_button_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (button7), "clicked", G_CALLBACK (num_button_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (button8), "clicked", G_CALLBACK (num_button_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (button9), "clicked", G_CALLBACK (num_button_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (buttonDec), "clicked", G_CALLBACK (num_button_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (buttonAdd), "clicked", G_CALLBACK (buttonOp_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (buttonSub), "clicked", G_CALLBACK (buttonOp_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (buttonMul), "clicked", G_CALLBACK (buttonOp_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (buttonDiv), "clicked", G_CALLBACK (buttonOp_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (buttonExp), "clicked", G_CALLBACK (buttonOp_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (buttonNeg), "clicked", G_CALLBACK (buttonNeg_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (buttonFct), "clicked", G_CALLBACK (buttonFct_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (buttonEqu), "clicked", G_CALLBACK (buttonEqu_clicked), (gpointer)entry);
- g_signal_connect (G_OBJECT (buttonClr), "clicked", G_CALLBACK (buttonClr_clicked), (gpointer)entry);
- gtk_container_add (GTK_CONTAINER (window), vbox);
- gtk_box_pack_start (GTK_BOX (vbox), hbox1, FALSE, FALSE, 6);
- gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 6);
- gtk_box_pack_start (GTK_BOX (vbox), hbox3, FALSE, FALSE, 6);
- gtk_box_pack_start (GTK_BOX (vbox), hbox4, FALSE, FALSE, 6);
- gtk_box_pack_start (GTK_BOX (vbox), hbox5, FALSE, FALSE, 6);
- gtk_box_pack_start (GTK_BOX (hbox1), entry, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox2), button7, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox2), button8, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox2), button9, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox2), buttonAdd, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox2), buttonNeg, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox3), button4, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox3), button5, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox3), button6, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox3), buttonSub, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox3), buttonExp, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox4), button1, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox4), button2, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox4), button3, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox4), buttonMul, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox4), buttonFct, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox5), button0, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox5), buttonDec, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox5), buttonEqu, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox5), buttonDiv, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox5), buttonClr, TRUE, TRUE, 6);
- gtk_widget_show_all (window);
- //Call this AFTER setting up widgets etc
- gtk_main ();
- return 0;
- }
- /***********************************
- FUNCTION DEFINITIONS
- ***********************************/
- double stringToDouble(char *string)
- {
- double d = 0.0, e = 0.0;
- double sign = 1.0;
- bool past_decimal = false;
- int decimal_places = 0;
- for (int i = 0; i < strlen(string); i++)
- {
- if(string[i] == '-')
- {
- sign = -1.0;
- continue;
- }
- if(string[i] == '.' || past_decimal)
- {
- if(string[i] == '.')
- {
- i++;
- past_decimal = true;
- }
- decimal_places++;
- e *= 10.0;
- e += (string[i] - '0');
- continue;
- }
- d *= 10.0;
- d += (string[i] - '0');
- }
- for(int i = 0; i < decimal_places; i++)
- {
- e /= 10.0;
- }
- return (d + e) * sign;
- }
- gboolean containsDecimal(char *string)
- {
- for(int i = 0; i < strlen(string); i++)
- {
- if(string[i] == '.')
- {
- return TRUE;
- }
- }
- return FALSE;
- }
- char* substr(char* string, int begin, int end)
- {
- char* temp = new char[end - begin + 1];
- strncpy(temp, string+begin, end-begin+1);
- temp[end-begin+1] = '\0';
- return temp;
- }
- char* removeZeros(char* string)
- {
- bool extras = false;
- bool past_dec = false;
- int end = -1;
- for(int i = 0; i < strlen(string); i++)
- {
- if(string[i] == '.')
- {
- past_dec = true;
- continue;
- }
- else if(!past_dec)
- {
- continue;
- }
- else
- {
- if(string[i] == '0' && !extras)
- {
- int pad = 0;
- if(string[i-1] == '.')
- {
- pad = 1;
- }
- end = i - 1 - pad;
- extras = true;
- }
- else if(string[i] != '0' && extras)
- {
- end = -1;
- extras = false;
- }
- }
- }
- if(extras)
- {
- return substr(string, 0, end);
- }
- else
- {
- return string;
- }
- }
- double power(double a, int b)
- {
- double temp = 1.0;
- for(int i = 0; i < b; i++)
- {
- temp *= a;
- }
- return temp;
- }
Advertisement
Add Comment
Please, Sign In to add comment