Menu.c

Fra Hougaard

Skift til: Navigation, Søgning
// AkvarieComputer - menu.c
 
#include <pic18.h>
#include <stdio.h>
#include <string.h>
#include "lcd.h"
#include "delay.h"
#include "akvarie.h"
#include "menu.h"
#include "xeeprom.h"
 
// ---------------------------------------------------------------
// Main Menu
// ---------------------------------------------------------------
const char HardwareMenuItem[] 	= "Technical Setup    ";
const char AutomationMenuItem[] = "Automation Setup   ";
const char CaliMenuItem[] 			= "Calibration        ";
const char ManualMenuItem[]   	= "Manual Operations  ";
const char FyldMenuItem[] 			= "Secret Menu        ";
const char *MainMenuTexts[] = {AutomationMenuItem,
		 	                         ManualMenuItem,
	     			                   CaliMenuItem,
	          			             HardwareMenuItem,
 	  	 	                       NULL};
 
#define MainMenuTriggerMenu		 	0
#define MainMenuAutomationMenu 	0
#define MainMenuManualMenu 			1
#define MainMenuCalMenu 				2
#define MainMenuHardwareMenu 		3
#define MainMenuFyldMenu 				4
 
// ---------------------------------------------------------------
// Hardware Menu
// ---------------------------------------------------------------
const char ClockMenuItem[]			= "Internal clock     ";
const char Probe1MenuItem[] 		= "Probe 1 <%s>       ";
const char Probe2MenuItem[]			= "Probe 2 <%s>       ";
const char Probe3MenuItem[] 		= "Probe 3 <%s>       ";
const char Probe4MenuItem[]			= "Probe 4 <%s>       ";
const char PowerPanelMenuItem[] = "PowerPanel <%s>    ";
const char Input1MenuItem[]     = "Input 1 <%s>       ";
const char Input2MenuItem[]     = "Input 2 <%s>       ";
const char *HardwareMenuTexts[] = {ClockMenuItem,
																	 Probe1MenuItem,
												 					 Probe2MenuItem,
																	 Probe3MenuItem,
												 					 Probe4MenuItem,
																	 PowerPanelMenuItem,
																	 Input1MenuItem,
																	 Input2MenuItem,
																	 NULL};
const void *HardwareMenuData[] = {NULL,
																	&AI.ProbeSetup[0],
																	&AI.ProbeSetup[1],
																	&AI.ProbeSetup[2],
																	&AI.ProbeSetup[3],
																	&AI.PowerPanel,
																	&AI.Input1,
																	&AI.Input2};
const char HardwareMenuTypes[] = {TYPE_TIME,
																	TYPE_PROBE,
																	TYPE_PROBE,
																	TYPE_PROBE,
																	TYPE_PROBE,
																	TYPE_ONOFF,
																	TYPE_ONOFF,
																	TYPE_ONOFF}; 
#define HardwareMenuClock 0
#define HardwareMenuProbe1 1
#define HardwareMenuProbe2 2
#define HardwareMenuProbe3 3
#define HardwareMenuProbe4 4
#define HardwareMenuPowerPanel 5
#define HardwareMenuInput1 6
#define HardwareMenuInput2 7															
 
// ---------------------------------------------------------------
// Calibration Menu
// ---------------------------------------------------------------
const char Calibration_Probe1Item[] = "Probe 1 (%s) Cal.";
const char Calibration_Probe2Item[] = "Probe 2 (%s) Cal.";
const char Calibration_Probe3Item[] = "Probe 3 (%s) Cal.";
const char Calibration_Probe4Item[] = "Probe 4 (%s) Cal.";
const char *CalibrationMenuTexts[] = {Calibration_Probe1Item,
																			Calibration_Probe2Item,
																			Calibration_Probe3Item,
																			Calibration_Probe4Item,NULL};
const void *CalibrationMenuData[] = {&AI.ProbeSetup[0],
																		 &AI.ProbeSetup[1],
																		 &AI.ProbeSetup[2],
																		 &AI.ProbeSetup[3]};
// ---------------------------------------------------------------
// Manual Menu
// ---------------------------------------------------------------
const char ManualPower1Item[] = "Power 1 <%s> ";
const char ManualPower2Item[] = "Power 2 <%s> ";
const char ManualPower3Item[] = "Power 3 <%s> ";
const char ManualPower4Item[] = "Power 4 <%s> ";
const char *ManualMenuTexts[]= {ManualPower1Item,ManualPower2Item,ManualPower3Item,ManualPower4Item,NULL};
const void *ManualMenuData[] = {&AI.Power[0],&AI.Power[1],&AI.Power[2],&AI.Power[3]};
const char ManualMenuTypes[] = {TYPE_ONOFF,TYPE_ONOFF,TYPE_ONOFF,TYPE_ONOFF,0}; 
#define ManualPower1Menu 0
#define ManualPower2Menu 1
#define ManualPower3Menu 2
#define ManualPower4Menu 3
 
// Global variables for menu
unsigned char CursorPosition = 1;
unsigned char MenuPosition = 0;
 
void ShowMenuLine(char *Menu[],void *Data[],const char *Types,int i,int pos)
{
	char Text[19];
	int OriginalInt;
	float OriginalFloat;
	switch(Types[i])
	{
		case TYPE_INTEGER:
			memcpy(&OriginalInt,Data[i],sizeof(int));
			sprintf(Text,Menu[i],OriginalInt);
			break;
		case TYPE_FLOAT2:
			memcpy(&OriginalFloat,Data[i],sizeof(float));
			sprintf(Text,Menu[i],OriginalFloat);
			break;
		default:
			sprintf(Text,Menu[i],Data[i]);
	}
	lcdtext(2,pos,Text);	
}
 
char OpenMenu(char *Menu[], void *Data[],const char *Types)
{
	unsigned char i = 0;
 
	CursorPosition = 1;
	MenuPosition = 0;
 
	// Fill Menu
	lcd_clear();
	while (i < 4 && Menu[i] != NULL)
	{
		ShowMenuLine(Menu,Data,Types,i,i+1);
		i++;
	}
 
	while(1)
	{
		lcdtext(1,CursorPosition,"*");
		if (KeyDown)
		{
			while (KeyDown);
 
			if (Menu[MenuPosition + 1] != NULL)
			{
			  MenuPosition++;
			  if (CursorPosition < 4)
			  {
					lcdtext(1,CursorPosition," ");
			    CursorPosition++;
			  }
			  else
			  {
				  // Scroll down
				  for (i = 0; i < 4 ; i++)
				  {
						ShowMenuLine(Menu,Data,Types,MenuPosition - i,4 - i);
						/*
					  if (Types[i] != TYPE_INTEGER)
							sprintf(Text,Menu[MenuPosition - i],Data[MenuPosition - i]);
						else
						{
							int x = (int*)Data[MenuPosition - i];
							sprintf(Text,Menu[MenuPosition - i],x);
						}
					  lcdtext(2,4 - i,Text);
					  */
					}
				}
			}
		}
		else
		  if (KeyUp)
		  {
			  while (KeyUp);
			  if (MenuPosition > 0)
			  	if(Menu[MenuPosition - 1] != NULL)
				  {
					  MenuPosition--;
					  if (CursorPosition > 1)
					  {
							lcdtext(1,CursorPosition," ");
					  	CursorPosition--;
					  }
					  else
					  {
						  // Scroll up
	  				  for (i = 0; i < 4 ; i++)
		  			  {
								ShowMenuLine(Menu,Data,Types,MenuPosition + i,i + 1);
								/*
								if (Types[i] != TYPE_INTEGER)
				  			  sprintf(Text,Menu[MenuPosition + i],Data[MenuPosition + i]);
						  	else
						  	{
							  	int x = (int*)Data[MenuPosition + i];
				  			  sprintf(Text,Menu[MenuPosition + i],x);
							  }
			 				  lcdtext(2,i + 1,Text);
			 				  */
							}
						}
					}
			}
			else
			  if (KeyLeft) // Exit Menu
			  {
				  while(KeyLeft);
				  lcd_clear();
				  return -1;
				}
				else
				  if (KeyRight) // Go into submenu / item
				  {
					  while(KeyRight);
					  return MenuPosition;
					}
		DelayMs(100);
	}
}
 
char OpenAutomationMenu()
{
	unsigned char i = 0;
	char Text[30];
 
	CursorPosition = 1;
	MenuPosition = 0;
 
	// Fill Menu
	lcd_clear();
	lcdtext(2,1,"<New Automation>");
	for (i = 1; i <=3; i++)
	{
		ReadAutomation(i);	
		if (CA.MagicChar == MAGICCHAR)
		{
			sprintf(Text,"[%03d] %s ",CA.No,CA.Type);
		}
		else
			sprintf(Text,"                    ");
		lcdtext(2,i + 1,Text);
	}
 
	while(1)
	{
		lcdtext(1,CursorPosition,"*");
		if (KeyDown)
		{
			while (KeyDown);
 
			if (ReadAutomation(MenuPosition + 1))
			{
				if (CA.MagicChar == MAGICCHAR)
				{
				  MenuPosition++;
				  if (CursorPosition < 4)
				  {
						lcdtext(1,CursorPosition," ");
				    CursorPosition++;
				  }
				  else
				  {
					  // Scroll down
					  for (i = 0; i < 4 ; i++)
					  {
						  ReadAutomation(MenuPosition - i);
							sprintf(Text,"[%03d] %s       ",CA.No,CA.Type);
						  lcdtext(2,4 - i,Text);
						}
					}
				}
			}
		}
		else
		  if (KeyUp)
		  {
			  while (KeyUp);
			  if (MenuPosition > 0)
			  	if(ReadAutomation(MenuPosition - 1))
				  {
					  MenuPosition--;
					  if (CursorPosition > 1)
					  {
							lcdtext(1,CursorPosition," ");
					  	CursorPosition--;
					  }
					  else
					  {
						  // Scroll up
	  				  for (i = 0; i < 4 ; i++)
		  			  {
			  			  if (MenuPosition + i == 0)
			  			  	sprintf(Text,"<New Automation>");
			  			  else
			  			  {
								  ReadAutomation(MenuPosition + i);
									sprintf(Text,"[%03d] %s       ",CA.No,CA.Type);
								}
			 				  lcdtext(2,i + 1,Text);
							}
						}
					}
			}
			else
			  if (KeyLeft) // Exit Menu
			  {
				  while(KeyLeft);
				  lcd_clear();
				  return -1;
				}
				else
				  if (KeyRight) // Go into submenu / item
				  {
					  while(KeyRight);
					  return MenuPosition;
					}
		DelayMs(100);
	}
}
 
const char Type_power_void[] = "Void\0";
const char Type_power_on[] = "On\0";
const char Type_power_off[] = "Off\0";
const char *Type_power_values[] = {Type_power_void,Type_power_off,Type_power_on,NULL};
 
const char Type_onoff_on[] = "On\0";
const char Type_onoff_off[] = "Off\0";
const char *Type_onoff_values[] = {Type_onoff_off,Type_onoff_on,NULL};
 
const char Type_probe_off[] = "Off\0";
const char Type_probe_ph[] = "pH\0";
const char Type_probe_mV[] = "mV\0";
const char *Type_probe_values[] = {Type_probe_off,Type_probe_ph,Type_probe_mV,NULL};
 
const char Automation_1[] = "Off\0";
const char Automation_2[] = "Light\0";
const char Automation_3[] = "Osmolator\0";
const char Automation_4[] = "Ozonizer\0";
const char Automation_5[] = "CaReactor\0";
const char Automation_6[] = "Dos.Pump\0";
//const char Automation_5[] = "
const char *Automationtypes_values[] = {Automation_1,
																				Automation_2,
																				Automation_3,
																				Automation_4,
																				Automation_5,
																				Automation_6,
																				NULL};
 
char EditOption(char *Menu[], const void *Data[],const char *Types,signed char UseMenu,char Refresh)
{
	char 	i;
	char	Original;
	int		OriginalInt;
	float OriginalFloat;
	char	Text[30];
	char *Values[20];
	//far char *Values;
 
	if (UseMenu != -1)
	{
		MenuPosition = 0;
	}
 
	switch(Types[MenuPosition])
	{
		case TYPE_ONOFF:
			memcpy(Values,Type_onoff_values,3 * sizeof(char*)); // Fusk
			//Values = Type_onoff_values;
			break;
		case TYPE_PROBE:
			memcpy(Values,Type_probe_values,4 * sizeof(char*)); // Fusk
			//Values = Type_probe_values;
			break;
		case TYPE_AUTOMATION:
			memcpy(Values,Automationtypes_values,6 * sizeof(char*)); // Fusk
			//Values = Automationtypes_values;
			break;
		case TYPE_POWER:
			memcpy(Values,Type_power_values,4 * sizeof(char*)); // Fusk
			//Values = Type_power_values;
			break;
		case TYPE_INTEGER:
			break;
		case TYPE_FLOAT2:
			break;
		default:
			FatalError(1,Types[MenuPosition]);
	}
 
	if (UseMenu != -1)
	{
		MenuPosition = 0;
		CursorPosition = UseMenu;
		switch(Types[MenuPosition])
		{
			case TYPE_INTEGER:
				memcpy(&OriginalInt,Data[MenuPosition],sizeof(int));
				sprintf(Text,Menu[MenuPosition],OriginalInt);
				break;
			case TYPE_FLOAT2:
				memcpy(&OriginalFloat,Data[MenuPosition],sizeof(float));
				sprintf(Text,Menu[MenuPosition],OriginalFloat);
				break;
			default:
				sprintf(Text,Menu[MenuPosition],Data[MenuPosition]);
		}
		lcdtext(2,CursorPosition,Text);
 
	}
	else
	{
		lcdtext(1,CursorPosition,"#");
	}
 
	switch(Types[MenuPosition])
	{
		case TYPE_INTEGER:
			memcpy(&OriginalInt,Data[MenuPosition],sizeof(int)); // Fusk
			while(1)
			{
				int CurrentValue;
				memcpy(&CurrentValue,Data[MenuPosition],sizeof(int));
				if (KeyUp)
				{
					if (CurrentValue < 9998)
					{
						CurrentValue++;
						sprintf(Text,Menu[MenuPosition],CurrentValue);
						lcdtext(2,CursorPosition,Text);
						if (Refresh)
							return 1;
					}
				}
				if (KeyDown)
				{
					if (CurrentValue > -9998)
					{
						CurrentValue--;
						sprintf(Text,Menu[MenuPosition],CurrentValue);
						lcdtext(2,CursorPosition,Text);
						if (Refresh)
							return 1;
					}
				}
				memcpy(Data[MenuPosition],&CurrentValue,sizeof(int));
				if (KeyEnter)
				{
					while(KeyEnter);
					return 1;
				}
				if (KeyLeft)
				{
					while(KeyLeft);
					memcpy(Data[MenuPosition],&OriginalInt,sizeof(int)); // Fusk !!
					sprintf(Text,Menu[MenuPosition],Data[MenuPosition]);
					lcdtext(2,CursorPosition,Text);
					return 0;
				}
				DelayMs(250);
			}
			break;
		case TYPE_FLOAT2:
			memcpy(&OriginalFloat,Data[MenuPosition],sizeof(float)); // Fusk
			while(1)
			{
				float CurrentValue;
				memcpy(&CurrentValue,Data[MenuPosition],sizeof(float)); // Fusk
				if (KeyUp)
				{
					if (CurrentValue < 9999.98f)
					{
						CurrentValue = CurrentValue + 0.01f;
						memcpy(Data[MenuPosition],&CurrentValue,sizeof(float)); // Fusk
						sprintf(Text,Menu[MenuPosition],CurrentValue);
						lcdtext(2,CursorPosition,Text);
					}
				}
				if (KeyDown)
				{
					if (CurrentValue > -9999.98f)
					{
						CurrentValue = CurrentValue - 0.01f;
						memcpy(Data[MenuPosition],&CurrentValue,sizeof(float)); // Fusk
						sprintf(Text,Menu[MenuPosition],CurrentValue);
						lcdtext(2,CursorPosition,Text);
					}
				}	
				if (KeyEnter)
				{
				DelayMs(25);
					while(KeyEnter);
					return 1;
				}
				if (KeyLeft)
				{
					DelayMs(25);
					while(KeyLeft);
					memcpy(Data[MenuPosition],&OriginalFloat,sizeof(float)); // Fusk !!
					sprintf(Text,Menu[MenuPosition],Data[MenuPosition]);
					lcdtext(2,CursorPosition,Text);
					return 0;
				}
				DelayMs(25);
			}
			break;
		case TYPE_ONOFF:
		case TYPE_PROBE:
		case TYPE_AUTOMATION:
		case TYPE_POWER:
		  i = 0;
			while (strcmp(Data[MenuPosition],Values[i]) != 0 && Values[i] != NULL)
				i++;
			if  (*Values[i] == NULL)
				i = 0;
			Original = i;
			while(1)
			{
				if (KeyUp)
				{
					while(KeyUp);
					if  (Values[i + 1])
					{
						i++;
						strcpy(Data[MenuPosition],Values[i]);
						sprintf(Text,Menu[MenuPosition],Data[MenuPosition]);
						//sprintf(Text,"Choice %d",i);
						lcdtext(2,CursorPosition,Text);
					}
				}
				if (KeyDown)
				{
					while(KeyDown);
					if  (i > 0)
					{
						i--;
						strcpy(Data[MenuPosition],Values[i]);
						sprintf(Text,Menu[MenuPosition],Data[MenuPosition]);
						//sprintf(Text,"Choice %d",i);
						lcdtext(2,CursorPosition,Text);
					}
				}
				if (KeyEnter)
				{
					while(KeyEnter);
					return 1;
				}
				if (KeyLeft)
				{
					// Restore original value
					while(KeyLeft);
					strcpy(Data[MenuPosition],Values[Original]);
					sprintf(Text,Menu[MenuPosition],Data[MenuPosition]);
					lcdtext(2,CursorPosition,Text);
					return 0;
				}
			}	
	}
}
 
void MenuHandler()
{
	unsigned char OneUp = 0;
	while(1)
	{
		switch(OpenMenu(MainMenuTexts,NULL,NULL))
		{
			case -1:
				return;
				break;
			case MainMenuAutomationMenu:
				OneUp = 0;
				while (OneUp == 0)
				{
					char No = OpenAutomationMenu();
					switch(No)
					{
						case 0: // New Automation
							NewAutomation();
							break;
						case -1:
							OneUp = 1;
							break;
						default:
							EditAutomation(No);
							break;
					}
				}
				break;
			case MainMenuManualMenu:
				OneUp = 0;
				while(OneUp == 0)
				{
					switch(OpenMenu(ManualMenuTexts,ManualMenuData,ManualMenuTypes))
					{
						case ManualPower1Menu:
						case ManualPower2Menu:
						case ManualPower3Menu:
						case ManualPower4Menu:
							EditOption(ManualMenuTexts,ManualMenuData,(char*)ManualMenuTypes,-1,0);
							UpdatePowers();
							break;
						case -1:
							OneUp = 1;
							break;
					}
				}
				break;
			case MainMenuCalMenu:
				OneUp = 0;
				while (OneUp == 0)
				{
					switch(OpenMenu(CalibrationMenuTexts,CalibrationMenuData,NULL))
					{
						case 0:
							Calibrate(0);
							break;
						case 1:
							Calibrate(1);
							break;
						case 2:
							Calibrate(2);
							break;
						case 3:
							Calibrate(3);
							break;
						case -1:
							OneUp = 1;
							break;
					}
				}
				break;
			case MainMenuHardwareMenu:
				OneUp = 0;
				while(OneUp == 0)
				  switch(OpenMenu(HardwareMenuTexts,HardwareMenuData,HardwareMenuTypes))
				  {
					  case HardwareMenuClock:
					  	SetClock();
					  	break;
						case HardwareMenuProbe1:
						case HardwareMenuProbe2:
						case HardwareMenuProbe3:
						case HardwareMenuProbe4:
						case HardwareMenuPowerPanel:
						case HardwareMenuInput1:
						case HardwareMenuInput2:
							EditOption(HardwareMenuTexts,HardwareMenuData,(char*)HardwareMenuTypes,-1,0);
							break;
						case -1:
						  OneUp = 1;
							break;
					}
				break;
			case MainMenuFyldMenu:
				break;
		}
	}
}
Personlige værktøjer