mmicalculatormain.c

来自「是一个手机功能的模拟程序」· C语言 代码 · 共 788 行 · 第 1/2 页

C
788
字号
	// Create window handler
	data->win = win_create (parent_window, 0, E_WIN_VISIBLE, NULL);
	if (data->win EQ NULL)
	{
		
		return NULL;
	}
	// connect the dialog data to the MFW-window
	data->mmi_control.dialog = (T_DIALOG_FUNC)calc_DialogCB;
	data->mmi_control.data   = data;
	win                      = ((T_MFW_HDR *)data->win)->data;
	win->user                = (void *)data;
	data->parent_win         = parent_window;
	calculator_win = data->win;
	return data->win;
}

/*******************************************************************************

 $Function:    	calc_DialogCB

 $Description:	Callback function for the calculator window
 
 $Returns:		nothing

 $Arguments:	Window, event, identifier (not used), parameter (not used)
 
*******************************************************************************/
static void calc_DialogCB(T_MFW_HND win, USHORT e,  SHORT identifier, void *parameter)
{ 	
	T_MFW_WIN       	*win_data   = ( (T_MFW_HDR *) win )->data;
	tCalcData* data = (tCalcData *) win_data->user;
	char display_buffer[28] = "";
	T_EDITOR_DATA		editor_data;
	char* running_total_out; 
	char debug_buffer[50];
 	TRACE_FUNCTION("calc_DialogCB()");

	switch( e )
    {	//when window first created
    	case CALC_INIT:
    	{	//set running total to 0 and display in editor
			TRACE_EVENT("CALC-INIT-JGG");
    		running_total = 0;
    		data->menu_options_win = NULL;
			//sprintf(data->buffer, "%d", running_total);
			//jgg
    		sprintf(data->buffer, "%s", "");
			//jgg
			calcSetEditor(win);//set editor with default attribute values
			data->editor_data.Callback     		= (T_EDIT_CB)calcGetNumberCB;
			data->editor_win = editor_start(win, &(data->editor_data));  /* start the editor */ 

			winShow(data->win);
    	}
    	break;

    	//when an arithmetic operator has been selected from the calc menu
    	case CALC_ENTER_OPERAND:
    	{ 	
			TRACE_EVENT("CALC-ENTER-OPERAND-JGG");
    		//this memory alloc seems to fix a problem where running_total_out
    		//would become an empty string after sevarla running calculations
    		running_total_out = (char*)malloc(22*sizeof(char));
    		
			sprintf(debug_buffer, "Running Total: %s %f",running_total_out, calcGetRunningTotal()); 
			TRACE_EVENT(debug_buffer);
			//jgg
			running_total_out[0] = '\0';
			//jgg
			//OK we display the first operand and the operator symbol
			//above the operand to be entered
			if ( (long)calcGetRunningTotal() == calcGetRunningTotal())
    			sprintf((char*)running_total_out, "%d", (long)calcGetRunningTotal());
			else
				sprintf((char*)running_total_out, "%f", calcGetRunningTotal());

			if (running_total_out[8] == '.')
				running_total_out[8] = '\0';
			else
				running_total_out[9] = '\0';
			
			sprintf(debug_buffer, "Running Total: %s %f",running_total_out, calcGetRunningTotal()); 
			TRACE_EVENT(debug_buffer);
				
    		sprintf((char*)display_buffer,"%s %c", running_total_out, operatorSymbol(data->operation));
			TRACE_EVENT(display_buffer);
			//jgg
			//sprintf(data->buffer, "%d", 0);
    		sprintf(data->buffer, "%s", "");
    		//jgg
    		calcSetEditor(win);
    		data->editor_data.TextString = display_buffer;
			data->editor_data.editor_attr.win.px = 0;
			data->editor_data.editor_attr.win.py = 30;
			data->editor_data.editor_attr.win.sx = 84;
			data->editor_data.editor_attr.win.sy = 10;
	
			data->editor_data.Callback     		= (T_EDIT_CB)calcGetOperandCB;
			/*data->input_number_win =*/ editor_start(win, &(data->editor_data));  /* start the editor */ 
			
			winShow(data->win);
			free((void*)running_total_out);
    	}    	
    	break;
    	
    	//when "Equals" selected from calc menu
    	case CALC_DISPLAY_RESULT:
    	{	
			TRACE_EVENT("CALC-DISPLAY-RESULT-JGG");
    		//if running total out of display range, set it to 0
    		if ((calcGetRunningTotal() > MAX_CALC_TOTAL) || (calcGetRunningTotal() < MIN_CALC_TOTAL))
    			running_total =0;
    		//Convert running total double to string
    		//if integer total, don't display any decimal places
    		if ( (long)calcGetRunningTotal() == calcGetRunningTotal())
    			sprintf(data->buffer, "%d", (long) calcGetRunningTotal());
    		else //if a floating-point total, display as many decimal places as will fit
    			sprintf(data->buffer, "%f", (double) calcGetRunningTotal());
			//if last number in display is a decimal point
			if (data->buffer[8] == '.') 
				data->buffer[8] = '\0';//remove it
    		data->buffer[9] = '\0'; //ensure string is properly terminated
    		//ensure string is no longer than 9 chars
    		
    		calcSetEditor(win);
			data->editor_data.Callback     		= (T_EDIT_CB)calcGetNumberCB;
			/*data->input_number_win =*/ editor_start(win, &(data->editor_data));  /* start the editor */ 

			winShow(data->win);
    	}
    	break;
    	default:
    	{
    			TRACE_EVENT("calc_DialogCB(): Unknown Event");
    	}
    	break;

    }
    	
   
}

/*******************************************************************************

 $Function:    	calcGetNumberCB

 $Description:	Callback function for the editor window
 
 $Returns:		nothing

 $Arguments:	Window,  identifier (not used), reason (not used)
 
*******************************************************************************/
static void calcGetNumberCB( T_MFW_HND win, USHORT Identifier,UBYTE reason)
{
    T_MFW_WIN       *win_data   = ( (T_MFW_HDR *) win )->data;
    tCalcData   *data       = (tCalcData *) win_data->user;   
    float after_decimal = 0;
    int digits_after_point = 0;
    int i;
	char* end;
    char debug[40];

    
    TRACE_FUNCTION("calcGetNumberCB()");

	switch (reason )
    {
        case INFO_KCD_LEFT:
        {	TRACE_EVENT("Left button pressed in calculator");
        	//get the number entered before the decimal point
			running_total = strtol(data->buffer, &end, 10);
        	if (strlen(end) != 0)
			{	//if decimal point entered
				if ((end[0] == '.') && isdigit(end[1]))//get number after decimal point
				{	
					end++;
					digits_after_point = strlen(end);
					after_decimal = strtol(end, &end, 10);
				}

				//convert number after decimal point to it's actual fractional value
				for (i=0; i < digits_after_point; i++)
					after_decimal = after_decimal/10;
				//add whole number and fraction together
				running_total = running_total + after_decimal;
			}
			if (data->menu_options_win != NULL)
				bookMenuDestroy( data->menu_options_win );
			//start the calculator option menu and kill this window
			data->menu_options_win = bookMenuStart( data->win, calcOptionMenuAttributes(),0);
			 SEND_EVENT(data->menu_options_win, ADD_CALLBACK, NULL, (void *)calc_menu_cb);
			 
        }
		break;
		
		case INFO_KCD_HUP:
        case INFO_KCD_RIGHT:
        {
            TRACE_EVENT("Right button pressed in calculator");
			calc_destroy(win);
        }
		break;

        default:
        {
            /* otherwise no action to be performed
            */
            calc_destroy(win);
		    break;
        }
	}
}


/*******************************************************************************

 $Function:    	calcGetOperandCB

 $Description:	Callback function for the editor window, when second number in operation
 				is entered.
 
 $Returns:		nothing

 $Arguments:	Window,  identifier (not used), reason (not used)
 
*******************************************************************************/

static void calcGetOperandCB( T_MFW_HND win, USHORT Identifier,UBYTE reason)
{
    T_MFW_WIN       *win_data   = ( (T_MFW_HDR *) win )->data;
    tCalcData   *data       = (tCalcData *) win_data->user;
	char* buffer;
    float operand = 0;
    float after_decimal = 0;
    int digits_after_point = 0;
    int i;
	//long integer_running_total = 0;
    char* end;
    char debug[40];
    
    TRACE_FUNCTION("calcGetNumberCB()");

	switch (reason )
    {
        case INFO_KCD_LEFT:
        {	//Get whole number before decimal point
			operand = strtol(data->buffer, &end, 10);

			//if buffer not pointing at an empty string now
			if (strlen(end) != 0)
			{	//if decimal point entered
				if ((end[0] == '.') && isdigit(end[1]))//get number after decimal point
				{	
					end++;
					digits_after_point = strlen(end);
					after_decimal = strtol(end, &end, 10);
					sprintf(debug,"Digits after decimal: %f.", after_decimal);
				}
				//convert number after decimal point to an appropriate fraction
				for (i=0; i < digits_after_point; i++)
					after_decimal = after_decimal/10;
				//add whole and fraction together
				operand = operand + after_decimal;
			}

			//perform the arithmetic function requested
        	switch (data->operation)
        	{
        		case PLUS: running_total = running_total + operand; break;
        		case MINUS: running_total = running_total - operand;break;
        		case MULTIPLY: running_total = running_total * operand;break; 
        		case DIVIDE: running_total = running_total / operand;break;
				default: TRACE_EVENT("Unknown calc operation"); break;
        	}
				
        
			//Show option menu
			if (data->menu_options_win != NULL)
				bookMenuDestroy( data->menu_options_win );
			data->menu_options_win = bookMenuStart( data->win, calcOptionMenuAttributes(),0);
			//calc_destroy(win);
        }
		break;
		
		case INFO_KCD_HUP:
        case INFO_KCD_RIGHT:
        {
            TRACE_EVENT("Right button pressed in calculator");
            
			calc_destroy(win);
        }
		break;

        default:
        {
            /* otherwise no action to be performed
            */
		    break;
        }
	}
}


static void calc_menu_cb(T_MFW_HND parent_win, UBYTE identifier, UBYTE reason)
{
	T_MFW_WIN       	*win_data   = ( (T_MFW_HDR *) parent_win )->data;
	tCalcData* data = (tCalcData *) win_data->user;
	//set menu window to NULL to prevent any dealloc problems
	data->menu_options_win = NULL;
	calc_destroy(parent_win);


}

/*******************************************************************************

 $Function:    	calcSetEditor

 $Description:	Sets the editor attributes to defaults for the calculator module
 
 $Returns:		nothing

 $Arguments:	Window
 
*******************************************************************************/
void calcSetEditor(T_MFW_HND win)
{
	T_MFW_WIN       	*win_data   = ( (T_MFW_HDR *) win )->data;
	tCalcData* data = (tCalcData *) win_data->user;

	editor_attr_init(&((data->editor_data).editor_attr), NULL, edtCurBar1, 0, 0, 0);
			data->editor_data.hide				= FALSE;
			data->editor_data.min_enter			= 1;  // Avoid returning empty strings
		
			
			data->editor_data.Identifier		= 0xFFFF ; 
			data->editor_data.TextString 		= NULL;  
			data->editor_data.timeout			= FOREVER;  // Avoid returning empty strings
			data->editor_data.destroyEditor		= TRUE; 
			data->editor_data.editor_attr.text	= (char *)data->buffer; 
			data->editor_data.editor_attr.size	= 10; 

			data->editor_data.TextId               = '\0';  				 							  
			data->editor_data.LeftSoftKey 		= TxtSoftOptions;
					
			data->editor_data.AlternateLeftSoftKey	= TxtNull;
			data->editor_data.RightSoftKey		= TxtDelete;
		
			data->editor_data.mode				= CALC_MODE;
}

/*******************************************************************************

 $Function:    	calc_destroy

 $Description:	Destroys the calculator editor window and frees up memory
 
 $Returns:		nothing

 $Arguments:	Window
 
*******************************************************************************/
void calc_destroy(MfwHnd own_window)
{
  T_MFW_WIN * win_data;
  tCalcData   * data = NULL; 

  if (own_window)
	{  	

	win_data = ((T_MFW_HDR *)own_window)->data;
		if (win_data != NULL) //PATCH TB
			data = (tCalcData *)win_data->user;

	  if (data)
		{
		TRACE_EVENT ("calc_destroy()");
			
			win_delete (data->win);
		  // Free Memory
			FREE_MEMORY ((void *)data, sizeof (tCalcData));
	
		}
	  else
		{
			TRACE_EVENT ("calc_destroy() called twice");
		}
	}
}


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?