Hi calculator program help
- From: Anand <akiyer vsnl com>
- To: gtk-list gnome org
- Subject: Hi calculator program help
- Date: Sun, 22 Jul 2001 14:14:29 +0530
/*hello GTK friends,
I recently purchased Eric, Harlows book on developing linux applications
with GTK+/GDK by new rider publications.
However this application about calculator has some bugs. I resolved a few,
but others still remain.
Any help is welcoms.
Anand
*/
#include <gtk/gtk.h>
/*2 data Structure to keep track of the calculator buttons*/
typedef struct {
char *szLabel;
int row;
int col;
GtkWidget *widget;
} typCalculatorButton;
/* 10 This is the button list.
Each button is documented here so that we can access it */
typCalculatorButton buttonList[]={
{"C", 1, 0, NULL}, /*---Clear---*/
{"CE", 1, 1, NULL}, /*---Clear---*/
{"/", 1, 3, NULL}, /*---Division---*/
{"7", 2, 0, NULL}, /*---Digit 7---*/
{"8", 2, 1, NULL}, /*---Digit 8---*/
{"9", 2, 2, NULL}, /*---Digit 9---*/
{"*", 2, 3, NULL}, /*---Multiplication---*/
{"%", 2, 4, NULL}, /*---Percent---*/
{"4", 3, 0, NULL}, /*---Digit 4---*/
{"5", 3, 1, NULL}, /*---Digit 5---*/
{"5", 3, 2, NULL}, /*---Digit 6---*/
{"-", 3, 3, NULL}, /*---Subtraction---*/
{"1/x", 3, 4, NULL}, /*---1/x---*/
{"1", 4, 0, NULL}, /*---Digit 1---*/
{"2", 4, 1, NULL}, /*---Digit 2---*/
{"3", 4, 2, NULL}, /*---Digit 3---*/
{"+", 4, 3, NULL}, /*---Addition---*/
{"sqrt",4, 4, NULL}, /*---Square root---*/
{"+/-", 5, 0, NULL}, /*---Negate value---*/
{"0", 5, 1, NULL}, /*---Zero---*/
{".", 5, 2, NULL}, /*---Decimal---*/
{"=", 5, 3, NULL}, /*---Equals total---*/
{"x^2", 5, 4, NULL}, /*---Square---*/
};
/*38*/
int nButtons =sizeof(buttonList)/sizeof (typCalculatorButton);
/*40*/
int FloatingPointChar(char ch);
int Command (char ch);
void TrimLeadingZeros(char *szDigits);
void TrimTrailingZeros(char *szDigits);
void HandleBinaryoperation ();
void MaybeUnaryOperation (char *str);
void HandleDigit (char *str, char ch);
void button_clicked (GtkWidget *widget, gpointer data);
void key_press (GtkWidget *widget, GdkEventKey *event, gpointer data);
GtkWidget *CreateButton(GtkWidget *table, char *szlabel, int row, int
column);
void CreateCalculatorButtons(GtkWidget *table);
gint CloseAppWindow(GtkWidget *widget, gpointer data);
int BUF_SIZE;
GtkWidget *label;
char *prevCmd, *lastChar;
int nIndex,num1,num2;
int main(int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *table;
/*70 ----GTK Initialization---*/
gtk_init(&argc,&argv);
/*72----Create the calculator window*/
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window),"Calculator");
gtk_widget_set-usize(window,200,200);
gtk_signal_connect(GTK_OBJECT(window),"key_press_event",GTK_SIGNAL_FUNC(key_press),NULL);
gtk_signal_connect(GTK_OBJECT(window),"delete_event",GTK_SIGNAL_FUNC(CloseAppWindow),NULL);
/*79 Create a 5X5 table for the items of the calculator*/
table=gtk_table_new(5,5,TRUE);
CreateCalculatorButtons(table);
/*83 Create the calculator LED */
label=gtk_label_new("0");
gtk_misc_set_alignment(GTK_MISC(label),1,-5);
/*86 Add label to the table */
gtk_table_attach_defaults(GTK_TABLE(table),label,0,4,0,1);
gtk_widget_show(label);
gtk_container_add(GTK_CONTAINER(window),table);
gtk_widget_show(table);
gtk_widget_show(window);
gtk_main();
exit(0);
}
/*95 Close App Window */
gint CloseAppWindow(GtkWidget *widget, gpointer data)
{
gtk_main_quit();
return (FALSE);
}
/*101 create the calculator buttons*/
void CreateCalculatorButtons(GtkWidget *table)
{
int nIndex;
for (nIndex=0;nIndex<nButtons;nIndex++)
{
buttonList[nIndex].widget=
CreateButton(table,buttonList[nIndex].szLabel,buttonList[nIndex].row,buttonList[nIndex].col);
}
}
/* 111 Create a button, assign event handlers and attach the button to
the table
in the proper place */
GtkWidget *CreateButton (GtkWidget *table, char *szlabel, int row, int
column)
{
GtkWidget *button;
button = gtk_button_new_with_label(szlabel);
gtk_signal_connect(GTK_OBJECT(button),"clicked",GTK_SIGNAL_FUNC(button_clicked),szlabel);
gtk_table_attach(GTK_TABLE(table),button,column,column+1,row,row+1,GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,5,5);
gtk_widget_show(button);
return(button);
}
/*124
handle the key_press event.
Function looks for the keystroke in the calculator
data structure and (if a match is found) presses the button
that matches the keystroke for the user.
It keeps our code small because we only have to
handle the button clicked events
121*/
void key_press (GtkWidget *widget, GdkEventKey *event, gpointer data)
{
int nIndex;
for (nIndex=0;nIndex<nButtons;nIndex++)
{
/* 137 If the keystroke is the first character of the button and
the button length is one */
if (event->keyval==buttonList[nIndex].szLabel[0] &&
buttonList[nIndex].szLabel[1]==(char)0)
{
gtk_widget_grab_focus(buttonList[nIndex].widget);
gtk_button_clicked(GTK_BUTTON(buttonList[nIndex].widget));
return;
}
}
}
/*147*/
/* button clicked
widget button presses
data button label.
button was pressed handle it*/
void button_clicked (GtkWidget *widget, gpointer data)
{
char ch=*((char *) data);
int len;
char *str;
str = (char *)data;
if (FloatingPointchar (ch) && strlen(str)==1){
HandleDigit(str,ch);
} else{
if (strcmp(str,"CE")==0){
gtk_label_set(GTK_LABEL(label),"0");
return;} else if (strcmp(str, "C")==0){
prevCmd=(char)0;
lastChar=(char)0;
gtk_label_set(GTK_LABEL(label),"0");
return;
} else {
MaybeUnaryOperation(str);}
HandleBinaryOperation();
prevCmd=ch;
}
lastChar=ch;
}
/* 176
HandleDigit
Digit button Was presses, deal with it. How it is
dealt with depends on the situation.
180 */
void HandleDigit(char *str, char ch)
{
char *labelText;
char buffer[BUF_SIZE];
int len;
if (Command(lastChar)){
gtk_label_set (GTK_LABEL(label),"");
if (lastChar == '='){
lastChar = (char)0;
prevCmd=(char)0;
}
}
gtk_label_get(GTK_LABEL(label),&labelText);
strcpy(buffer,labelText);
len=strlen(buffer);
buffer[len]=(gchar)ch;
buffer[len+1]=(gchar) 0;
TrimLeadingZeros(buffer);
gtk_label_set(GTK_LABEL(label),(char *)buffer);
}
/* 202
maybe unary operation
str label on button that describes operation.
Check to see if the user hit a unary operator button
like %, sqrt, 1/x etc. that should be dealt with NOW,
not later*/
void MaybeUnaryOperation (char *str)
{
char *labelText;
char *buffer[BUF_SIZE];
float num2;
gtk_label_get(GTK_LABEL(label),&labelText);
num2=atof(labelText);
if (strcmp(str, "%")==0){num2=num2/100;}
else {if (strcmp(str, "1/x")==0){if (num2==0){return;}else {num2=1/num2;}}}
else {if (strcmp(str, "sqrt")==0){num2=sqrt((double)num2);}}
else {if (strcmp(str, "x^2")==0){num2 = num2*num2;}}
sprintf (buffer, "%f",(float)num2);
TrimTrailingZeros(buffer);
TrimLeadingZeros(buffer);
gtk_label_set (GTK_LABEL(label),buffer);
}
/*225
Handle binary operation
perform a calculation with two sets of digits. one set is in
the LED display and the other set is saved in the
global variable (num1)
*/
void HandleBinaryoperation ()
{
char *labelText;
char *buffer[BUF_SIZE];
float num2;
gtk_label_get(GTK_LABEL(label),&labelText);
num2=atof(labelText);
switch (prevCmd){
case'+':
num1=num2+num1;
break;
case'-':
num1=num1-num2;
break;
case'*':
num1=num2*num1;
break;
case'/':
num1=num1/num2;
break;
case'=':
num1=num2;
break;
default:
num1=num2;
break;
}
sprintf (buffer, "%f",(float)num1);
TrimTrailingZeros(buffer);
TrimLeadingZeros (buffer);
gtk_label_set (GTK_LABEL(label),buffer);
}
/*264*/
/* TrimTrailingZeros
get rid of trailing zeros
takes the string and removes the trailing zeros*/
void TrimTrailingZeros(char *szDigits)
{
int nIndex;
int bDecimal=FALSE;
int npos=-1;
for(nIndex=0;nIndex<strlen(szDigits);nIndex++)
{
if(szDigits[nIndex]=='.'){
bDecimal=TRUE;}
if(bDecimal){
if(szDigits[nIndex]=='0'){
if(nPos<0 ){
nPos=nIndex;
}
}
}
else {
nPos=-1;
}
}
if (nPos>0) {
szDigits[nPos]=(char)0;
}
}
/* 291
Trim leading Zeros
Converts numbers like 000012 to 12
*/
void TrimLeadingZeros(char *szDigits)
{
int nPos;
if (szDigits==NULL) return;
for (nPos=0;(szDigits[nPos] && szDigits[nPos]=='0');nPos++)
{ if(isdigit(szDigits[nPos+1])){
szDigits[nPos]=' ';
}
}
}
int Command (char ch)
{
switch (ch) {
case '+':
case '-':
case '/':
case '*':
case '=':
return(TRUE);
}
return (FALSE);
}
int FloatingPointChar(char ch)
{
return(isdigit(ch)||ch=='.');
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]