Project Files

Below are 2 versions of the project, the ExecutablePackage downloadable zip file holds the important files for running the application, the ProjectFiles downloadable zip files holds all of the files that were used to develop the application. If you are just interested in downloading and running the application, download the ExecutablePackage. If you are interested in seeing how the application works and playing with the code, download the ProjectFiles package.

MyForm.cpp (Main)

#include "MyForm.h"
#include <fstream>
#include <chrono>
#include <ctime>
//#include <thread>
//#include "OptionsForm.h"
//#include "ReusableTobiiFunctions.h"

using namespace System;
using namespace System::Windows::Forms;
//using namespace std;

//#pragma managed(push, off)
void RunForm()
{
	/*Create WinForm*/
	Application::EnableVisualStyles();
	Application::SetCompatibleTextRenderingDefault(false);
	CapstoneProjectV1::MyForm form;
	/*Run Form The rest of our code will be within this form*/
	Application::Run(%form);
	return;
}

#pragma managed(pop)
[STAThreadAttribute]
int main(array<String^>^ args)
{
	std::ofstream fout;
	fout.open("ErrorLog.txt");

	auto current_time = std::chrono::system_clock::now();
	std::time_t time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
	fout << std::ctime(&time);

	/*MAKE A NEW API*/
	tobii_api_t* api;
	tobii_error_t error = tobii_api_create(&api, NULL, NULL);
	if (error != TOBII_ERROR_NO_ERROR)
		fout << "ERROR: tobii_api_create failed to create instance of tobii api" << std::endl;
	assert(error == TOBII_ERROR_NO_ERROR);

	/*FIND A CONNECTED DEVICE URL*/
	char url[256] = { 0 };
	int count = 0;
	error = tobii_enumerate_local_device_urls(api, url_receiver, url); //Find all devices and copy one of the urls
	if (error != TOBII_ERROR_NO_ERROR || *url == '\0')
		fout << "ERROR: tobii_enumerate_local_device_urls failed to locate a device - Please ensure device is plugged in and installed correctly" << std::endl;
	assert(error == TOBII_ERROR_NO_ERROR && *url != '\0'); //we need a url to create a new device

	
	error = tobii_device_create(api, url, TOBII_FIELD_OF_USE_INTERACTIVE, &device); //Create a new interactive device (interactive is all we can do without a liscense but it should be fine)
	if (error != TOBII_ERROR_NO_ERROR)
		fout << "ERROR: tobii_device_create failed to create a new device instance" << std::endl;
	assert(error == TOBII_ERROR_NO_ERROR);

	/*SUBSCRIBE TO THE GAZE POINT*/
	error = tobii_gaze_point_subscribe(device, gaze_point_callback, 0);
	if (error != TOBII_ERROR_NO_ERROR)
		fout << "ERROR: tobii_gaze_point_subscribe failed to subscribe to gaze stream" << std::endl;
	assert(error == TOBII_ERROR_NO_ERROR);

	if (!LoadUsersFromFile())
	{
		fout << "ERROR: LoadUsersFromFile failed to locate the file Users.txt - Please ensure that Users.txt is in the correct directory" << std::endl;
		fout.close();
		return 0;
	}

	Threading::Thread^ form_thread = gcnew Threading::Thread(gcnew Threading::ThreadStart(RunForm));
	form_thread->Start();
	while (form_alive)//This will be set to false once the form is closed
	{
		if (currently_tracking)
		{
			tobii_error_t error = tobii_wait_for_callbacks(1, &device); //Avoids busy wait loops by waiting until new package of stream data arrives
			if (error != TOBII_ERROR_NO_ERROR && error != TOBII_ERROR_TIMED_OUT)
				fout << "ERROR: tobii_wait_for_callbacks did not recieve viable callback" << std::endl;
			assert(error == TOBII_ERROR_NO_ERROR || error == TOBII_ERROR_TIMED_OUT); //Could be either in normal usage
			error = tobii_device_process_callbacks(device);
			if (error != TOBII_ERROR_NO_ERROR)
				fout << "ERROR: tobii_device_process_callbacks did not successfully process the gazepoint callback" << std::endl;
			assert(error == TOBII_ERROR_NO_ERROR);
		}
		if (GetKeyState(GetPrimaryClickHotkey()) & 0x8000) //& 0x8000If the primary click hotkey is pressed down //THIS IS REALLY WEIRD SPACE SEEMS TO BE ONLY ONE THAT WORKS
		{
			if (!leftdown)
			{
				LeftMouseDown();
				leftdown = true;
			}
		}
		else if (leftdown)
		{
			LeftMouseUp();
			leftdown = false;
		}

		Sleep(5);
	}
	//hotkey_input.mi.dy = 0;
	//hotkey_input.mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP);
	//hotkey_input.mi.mouseData = 0;
	//hotkey_input.mi.dwExtraInfo = NULL;
	OutputUsersToFile();
	fout.close();
	return 0;
}

ReusableTobiiFunctions.h

//#pragma once
#ifndef REUSABLE_TOBII_FUNCTIONS
#define REUSABLE_TOBII_FUNCTIONS
#include "tobii.h"
#include "tobii_streams.h"
#include "Bin.h"
#include <string>
#include <iostream>
#include <assert.h>
#include <Windows.h>
#include <string>
#include <fstream>
#include <msclr\marshal_cppstd.h>

//Bin stuff
int GetBinWidthAccessor();
bool AdjustBinWidthConnector(int new_width);

//Mouse Clicking stuff
void LeftMouseDown();
void LeftMouseUp();

//Accessors for current user stuff
char GetPrimaryClickHotkey();
void SetPrimaryClickHotkey(char c);
bool GetLightMode();
void SetLightMode(bool);
bool LoadUsersFromFile();
void OutputUsersToFile();
bool UpdateCurrentUser(int index);
std::string GetCurrentUserName();
void SetCurrentUserName(std::string username);
int GetUserCount();
std::string GetUserNameAtIndex(int index);
int GetUserIndexByName(std::string name);
bool AddNewUser(std::string newName, char newHotkey, bool newLightMode, int newBinWidth);
void SetCurrentUserToDefault();
void RemoveCurrentUser();
std::string GetDefaultUserName();

//Tobii eye tracking stuff.
void url_receiver(char const* url, void* user_data);
void gaze_point_callback(tobii_gaze_point_t const* gaze_point, void* user_data);


#endif

ReusableTobiiFunctions.cpp

#include "ReusableTobiiFunctions.h"

//const int SCREEN_WIDTH_PIXELS = 1366;
//const int SCREEN_HEIGHT_PIXELS = 768;
const int SCREEN_WIDTH_PIXELS = ::GetSystemMetrics(SM_CXSCREEN) - 1;
const int SCREEN_HEIGHT_PIXELS = ::GetSystemMetrics(SM_CYSCREEN) - 1;
const double Y_OFFSET = 15.0;
double fx = 0 * (65535.0f / SCREEN_WIDTH_PIXELS);
double fy = 0 * (65535.0f / SCREEN_HEIGHT_PIXELS);
//VK_SPACE, VK_CONTROL, VK_SHIFT, VK_CAPITAL These are the Keycodes for the potential hotkeys
bool FormAlive = false;
int NumUsers;
int DefaultUserIndex;
int CurrentUserIndex;


Bin bin;

//Struct to hold the information of an individual user
struct User
{
	std::string name;
	char clickHotkey = VK_SPACE;
	bool lightMode = true;
	int binWidth = 5;
};

//Pointer to a dynamic array of users
User * users;

//Called by Options Form when the user field is updated
bool UpdateCurrentUser(int index)
{
	if (index >= NumUsers)
		return false;
	CurrentUserIndex = index;
	bin.AdjustBinWidth(users[index].binWidth);
	return true;
}

//Called by Options Form when the user field is updated to the Add New User option
bool AddNewUser(std::string newName, char newHotkey, bool newLightMode, int newBinWidth)
{
	//Change the size of the users dynamic array
	User * temp = new User[NumUsers + 1];
	if (temp == nullptr)
		return false;
	for (int i = 0; i < NumUsers; i++)
	{
		temp[i].name = users[i].name;
		temp[i].clickHotkey = users[i].clickHotkey;
		temp[i].lightMode = users[i].lightMode;
		temp[i].binWidth = users[i].binWidth;
	}
	temp[NumUsers].name = newName;
	temp[NumUsers].clickHotkey = newHotkey;
	temp[NumUsers].lightMode = newLightMode;
	temp[NumUsers].binWidth = newBinWidth;
	delete[] users;
	users = temp;
	NumUsers++;
	return true;
}

//Read in the users from the Users.txt file and save them into the users dynamic array
bool LoadUsersFromFile()
{
	std::ifstream fin;
	fin.open("Users.txt");
	if (!fin.is_open())
		return false;
	fin >> NumUsers;
	if(NumUsers > 0)
		users = new User[NumUsers];
	fin.get();
	fin >> DefaultUserIndex; //Puts loads the default user index into default user index
	fin.get();
	if (users == nullptr)
	{
		fin.close();
		return false;
	}
	int i = 0;
	char ch;
	int hotkeyInt;
	while (!fin.eof() && i < NumUsers)
	{
		fin >> users[i].name;
		fin.get();
		fin >> users[i].clickHotkey;
		fin >> ch;
		if (ch == 'D')
			users[i].lightMode = false;
		fin >> users[i].binWidth;
		fin.get();
		i++;
	}

	fin.close();
	CurrentUserIndex = DefaultUserIndex;
	UpdateCurrentUser(DefaultUserIndex);
	return true;
}

//Output the users dynamic array back to the Users.txt file, comes at the end of the code, once the
//main form is closed.
void OutputUsersToFile()
{
	std::ofstream fout;
	//fout.open("Users2.txt");
	fout.open("Users.txt");
	fout << NumUsers << std::endl << DefaultUserIndex << std::endl;
	for (int i = 0; i < NumUsers; i++)
	{
		fout << users[i].name << ' ' << users[i].clickHotkey << ' ';
		if (users[i].lightMode)
			fout << "L ";
		else
			fout << "D ";
		fout << users[i].binWidth << std::endl;
	}
	fout.close();
	return;
}

//This function will change the default user to the current user
void SetCurrentUserToDefault()
{
	DefaultUserIndex = CurrentUserIndex;
	return;
}

//This function will remove the current user from the dynamic array as long as
//that would not result in an empty dynamic array
void RemoveCurrentUser()
{
	User* temp;
	if (NumUsers - 1 > 0)
		temp = new User[NumUsers - 1];
	else
		return;
	int k = 0;
	for (int i = 0; i < NumUsers; i++)
	{
		if(i != CurrentUserIndex)
		{ 
			temp[k].name = users[i].name;
			temp[k].clickHotkey = users[i].clickHotkey;
			temp[k].lightMode = users[i].lightMode;
			temp[k].binWidth = users[i].binWidth;
			k++;
		}
	}
	delete[] users;
	users = temp;
	NumUsers--;
	if (DefaultUserIndex >= NumUsers) //Default user was deleted
		DefaultUserIndex = 0;
	CurrentUserIndex = DefaultUserIndex;
	return;
}

//Accessor of the Default user's name
std::string GetDefaultUserName()
{
	return users[DefaultUserIndex].name;
}

//Accessor for the Number of users
int GetUserCount()
{
	return NumUsers;
}

//Return the index in the users dynamic array whose name is "name"
int GetUserIndexByName(std::string name)
{
	for (int i = 0; i < NumUsers; i++)
	{
		if (users[i].name == name)
			return i;
	}
	return -1;
}

//Accessor of the index of a user by their name
std::string GetUserNameAtIndex(int index)
{
	if (index < NumUsers)
		return users[index].name;
	else
		return "";
}

//Accessor for the current user's name
std::string GetCurrentUserName()
{
	return users[CurrentUserIndex].name;
}

//Mutator for the current user's name
void SetCurrentUserName(std::string username)
{
	if (username != "")
		users[CurrentUserIndex].name = username;
}

//Accessor for the current bin width (used for sensitivity)
int GetBinWidthAccessor()
{
	return bin.GetBinWidth();
}

//Mutator for the Bin width (used for sensitivity)
bool AdjustBinWidthConnector(int new_width)
{
	users[CurrentUserIndex].binWidth = new_width;
	return bin.AdjustBinWidth(new_width);
}

//Returns true if the color mode is set to light mode and false if dark mode
bool GetLightMode()
{
	return users[CurrentUserIndex].lightMode;
}

//Sets the lightMode of the current user to setting (light mode == true, dark mode == false)
void SetLightMode(bool setting)
{
	users[CurrentUserIndex].lightMode = setting;
}

//Send mouse input corresponding to a left mouse click down.
//This will be called by the main thread when the hotkey is held down
void LeftMouseDown()
{
	INPUT mouse_left_click_down;
	mouse_left_click_down.type = INPUT_MOUSE;
	mouse_left_click_down.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
	/*POINT current_pos;
	if (!GetCursorPos(&current_pos)) 
		return;*/
	/*mouse_left_click_down.mi.dx = current_pos.x * (65535.0f / SCREEN_WIDTH_PIXELS);
	mouse_left_click_down.mi.dy = current_pos.y * (65535.0f / SCREEN_HEIGHT_PIXELS);*/
	SendInput(1, &mouse_left_click_down, sizeof(mouse_left_click_down));
	return;
}

//Send mouse input corresponding to a left mouse lift up.
//This will be called by the main thread when the hotkey is let go.
void LeftMouseUp()
{
	INPUT mouse_left_click_up;
	mouse_left_click_up.type = INPUT_MOUSE;
	mouse_left_click_up.mi.dwFlags = MOUSEEVENTF_LEFTUP;
	SendInput(1, &mouse_left_click_up, sizeof(mouse_left_click_up));
	return;
}

//Accessor for the primary click hotkey of the current user
char GetPrimaryClickHotkey()
{
	return users[CurrentUserIndex].clickHotkey;
	//return VK_SHIFT;
}

//Mutator for the current user's primary click hotkey
void SetPrimaryClickHotkey(char c)
{
	users[CurrentUserIndex].clickHotkey = c;
	return;
}




/*This function is called by tobii_enumerate_local_device_urls and is made to save a copy of the url which
would otherwise be destroyed once the tobii_enumerate_local_device_urls function is completed*/
void url_receiver(char const* url, void* user_data)
{
	char* buffer = (char*)user_data;
	if (*buffer != '\0')
		return;
	if (strlen(url) < 256)
		strcpy(buffer, url);
}

/*This function acts as a callback subscriber for the gaze_point stream adjust it as
necessary for whatever functionality it is supposed to have*/
void gaze_point_callback(tobii_gaze_point_t const* gaze_point, void* user_data)
{
	if (gaze_point->validity == TOBII_VALIDITY_VALID)
	{
		//cout << "Gaze Point X: " << gaze_point->position_xy[0] << " Y: " << gaze_point->position_xy[1] << endl;
		//IMPLEMENTATION WITHOUT SMOOTHIN ALGORITHM
		/*
		position pos;
		pos.x = gaze_point->position_xy[0] * SCREEN_WIDTH_PIXELS;
		pos.y = gaze_point->position_xy[1] * SCREEN_HEIGHT_PIXELS;
		SetCursorPos(pos.x, pos.y);
		*/

		//IMPLEMENTATION OF SMOOTHING ALGORITHM 1

		Position pos;
		pos.x = gaze_point->position_xy[0] * SCREEN_WIDTH_PIXELS;
		pos.y = gaze_point->position_xy[1] * SCREEN_HEIGHT_PIXELS + (Y_OFFSET * (1 - gaze_point->position_xy[1]));
		//^ The + (Y_OFFSET * (1 - gaze_point->position_xy[1])) is an implementation of a scaling y offset which
		//will offset the position of the mouse cursor higher on the screen the higher on the screen that you
		//are looking. This is to counteract the problem of the tobii sensor getting less precise as you look
		//toward the top edge of the screen. This feature could use more testing, it provides excellent results
		//for me (Sam Spika) but I have had other people experience more difficult with this implemented.
		//POTENTIALLY A FUTURE SETTING FOR THE END USER

		bin.Drop(pos); //Add the current position into the bin

		Position sum;
		sum = bin.GetSum();
		SetCursorPos(sum.x / bin.GetBinWidth(), sum.y / bin.GetBinWidth()); //Get the average of the bin


		//IMPLEMENTATION OF SMOOTHING ALGORITHM 2
		/*
		position pos;
		pos.x = gaze_point->position_xy[0] * SCREEN_WIDTH_PIXELS;
		pos.y = gaze_point->position_xy[1] * SCREEN_HEIGHT_PIXELS;
		bin[bin_counter] = pos;
		bin_counter = (bin_counter + 1) % BIN_WIDTH;
		if (bin_counter == 0)
		{
			int sum_x = 0;
			int sum_y = 0;
			for (int i = 0; i < BIN_WIDTH; i++)
			{
				sum_x += bin[i].x;
				sum_y += bin[i].y;
			}
			SetCursorPos(sum_x / BIN_WIDTH, sum_y / BIN_WIDTH);
		}
		*/
	}
}

Bin.h

#pragma once

//An ordered pair Position struct
struct Position
{
	int x;
	int y;
};

/*
The Bin class will basically act as a means of calculating a rolling average.
It will use a dynamic array to add new data points that come in in place of the
least recent piece of data. This will keep the n most recent pieces of data in a
Bin of size n.
*/
class Bin
{
public:
	//Constructor
	Bin();
	//Bin(int size);

	//Destructor
	~Bin();

	//Accessor
	int GetBinWidth(); //Get the Width of the bin (size)
	Position GetSum(); //Get the current sum of the values in the bin

	//Mutator
	bool AdjustBinWidth(int new_width); //Change the width of the bin (get a new dynamic array)
	void Drop(Position new_position); //Drop a new piece of data (new_position) into the bin


private:
	void InitializeBin();
	int bin_width;
	Position* bin;
	int current_position;
	Position sum;
};

//Constructor
inline Bin::Bin()
{
	bin_width = 5;
	bin = new Position[bin_width];
	current_position = 0;
	sum.x = 0;
	sum.y = 0;
	InitializeBin();
	return;
}

/*
inline Bin::Bin(int size)
{
	if (size < 0)
		Bin();
		return;
	if (bin != nullptr)
		delete[] bin;
	bin = new Position[size];
	current_position = 0;
	bin_width = size;
	sum.x = 0;
	sum.y = 0;
	InitializeBin();
	return;
}
*/

//Initialize all the values in the bin to (0,0)
inline void Bin::InitializeBin()
{
	for (int i = 0; i < bin_width; i++)
	{
		bin[i].x = 0;
		bin[i].y = 0;
	}
}

//Destructor
inline Bin::~Bin()
{
	delete[] bin;
}

//Accessors
inline int Bin::GetBinWidth()
{
	return bin_width;
}

inline Position Bin::GetSum()
{
	return sum;
}

//Mutators
inline bool Bin::AdjustBinWidth(int new_width)
{
	if (new_width < 0)
		return false;
	Position * temp_bin;
	temp_bin = new Position[new_width];
	if (temp_bin == nullptr)
		return false;

	for (int i = 0; i < new_width; i++)
	{
		temp_bin[i].x = 0;
		temp_bin[i].y = 0;
	}

	current_position = 0;
	sum.x = 0;
	sum.y = 0;

	delete[] bin;
	bin = temp_bin;
	bin_width = new_width;
	return true;
}

//Drop a new value into the bin at the current_position
//The current_position marks the position of the oldest piece of data
//which will be the next piece of data to be replaced.
inline void Bin::Drop(Position new_position)
{
	//Adjust the sum by subtracting the oldest piece of data and then adding the newest
	sum.x += new_position.x;
	sum.y += new_position.y;
	sum.x -= bin[current_position].x;
	sum.y -= bin[current_position].y;

	bin[current_position] = new_position; //Replace oldest position with new position

	current_position = (current_position + 1) % bin_width;

	return;
}

MyForm.h

#pragma once
#include "OptionsForm.h"
#include "ReusableTobiiFunctions.h"
tobii_device_t* device;
bool currently_tracking = false;
bool form_alive = true;
bool leftdown = false;

namespace CapstoneProjectV1 {
	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;

	/// <summary>
	/// Summary for MyForm
	/// </summary>
	public ref class MyForm : public System::Windows::Forms::Form
	{
	public:
		MyForm(void)
		{
			InitializeComponent();
			//
			//TODO: Add the constructor code here
			UpdateFormVisuals();
			//
		}
		/*
		The UpdateFormVisuals function is mainly used to manage the appearance of the form
		upon initialization.
		*/
		void UpdateFormVisuals()
		{
			//Set the text in the Current User label to the current users name
			String^ str = gcnew String(GetCurrentUserName().c_str());
			label2->Text = "Current User: \n" + str;

			//Adjust the sensitivity label to the current users sensitivity settings
			this->SensitivityLabel->Text = ""+(21-GetBinWidthAccessor());

			//Set the hotkey label to the current users hotkey settings
			char key = GetPrimaryClickHotkey();
			if (key == VK_SHIFT)
				this->HotkeyLabel->Text = "Shift";
			else if (key == VK_CONTROL)
				this->HotkeyLabel->Text = "Control";
			else if (key == VK_SPACE)
				this->HotkeyLabel->Text = "Spacebar";
			else if (key == VK_CAPITAL)
				this->HotkeyLabel->Text = "Caps Lock";

			//Light Mode / Dark Mode Stuff
			if (GetLightMode())
			{
				this->BackColor = SystemColors::Control;
				this->OptionsFormButton->BackColor = Drawing::Color::Gainsboro;
				this->OptionsFormButton->ForeColor = SystemColors::ControlText;
				this->label2->ForeColor = SystemColors::ControlText;
				this->HotkeyTextLabel->BackColor = SystemColors::Control;
				this->HotkeyTextLabel->ForeColor = SystemColors::ControlText;
				this->HotkeyLabel->BackColor = SystemColors::Control;
				this->HotkeyLabel->ForeColor = SystemColors::ControlText;
				this->SensitivityTextLabel->BackColor = SystemColors::Control;
				this->SensitivityTextLabel->ForeColor = SystemColors::ControlText;
				this->SensitivityLabel->BackColor = SystemColors::Control;
				this->SensitivityLabel->ForeColor = SystemColors::ControlText;
			}
			else
			{
				this->BackColor = Drawing::Color::Black;
				this->OptionsFormButton->BackColor = SystemColors::ControlDarkDark;
				this->OptionsFormButton->ForeColor = Drawing::Color::WhiteSmoke;
				this->label2->ForeColor = Drawing::Color::WhiteSmoke;
				this->HotkeyTextLabel->BackColor = Drawing::Color::Black;
				this->HotkeyTextLabel->ForeColor = Drawing::Color::WhiteSmoke;
				this->HotkeyLabel->BackColor = Drawing::Color::Black;
				this->HotkeyLabel->ForeColor = Drawing::Color::WhiteSmoke;
				this->SensitivityTextLabel->BackColor = Drawing::Color::Black;
				this->SensitivityTextLabel->ForeColor = Drawing::Color::WhiteSmoke;
				this->SensitivityLabel->BackColor = Drawing::Color::Black;
				this->SensitivityLabel->ForeColor = Drawing::Color::WhiteSmoke;
			}
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~MyForm()
		{
			form_alive = false;
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::Timer^  timer1;
	private: System::Windows::Forms::Button^  ToggleButton;
	private: System::Windows::Forms::Button^  OptionsFormButton;

	private: System::Windows::Forms::Label^  label1;

	private: System::Windows::Forms::Panel^  panel1;
	private: System::Windows::Forms::Label^  label2;
	private: System::Windows::Forms::Label^  SensitivityTextLabel;
	private: System::Windows::Forms::Label^  HotkeyTextLabel;
	private: System::Windows::Forms::Label^  SensitivityLabel;




	private: System::Windows::Forms::Label^  HotkeyLabel;

	private: System::Windows::Forms::Panel^  panel2;

	protected:
	private: System::ComponentModel::IContainer^  components;

	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>


#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			this->components = (gcnew System::ComponentModel::Container());
			this->timer1 = (gcnew System::Windows::Forms::Timer(this->components));
			this->ToggleButton = (gcnew System::Windows::Forms::Button());
			this->OptionsFormButton = (gcnew System::Windows::Forms::Button());
			this->label1 = (gcnew System::Windows::Forms::Label());
			this->panel1 = (gcnew System::Windows::Forms::Panel());
			this->label2 = (gcnew System::Windows::Forms::Label());
			this->SensitivityTextLabel = (gcnew System::Windows::Forms::Label());
			this->HotkeyTextLabel = (gcnew System::Windows::Forms::Label());
			this->SensitivityLabel = (gcnew System::Windows::Forms::Label());
			this->HotkeyLabel = (gcnew System::Windows::Forms::Label());
			this->panel2 = (gcnew System::Windows::Forms::Panel());
			this->panel1->SuspendLayout();
			this->panel2->SuspendLayout();
			this->SuspendLayout();
			// 
			// timer1
			// 
			this->timer1->Enabled = true;
			this->timer1->Interval = 30;
			this->timer1->Tick += gcnew System::EventHandler(this, &MyForm::UpdateMouse);
			// 
			// ToggleButton
			// 
			this->ToggleButton->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->ToggleButton->BackColor = System::Drawing::Color::LightCoral;
			this->ToggleButton->FlatStyle = System::Windows::Forms::FlatStyle::Popup;
			this->ToggleButton->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 15.75F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,
				static_cast<System::Byte>(0)));
			this->ToggleButton->Location = System::Drawing::Point(38, 50);
			this->ToggleButton->MinimumSize = System::Drawing::Size(100, 100);
			this->ToggleButton->Name = L"ToggleButton";
			this->ToggleButton->Size = System::Drawing::Size(171, 100);
			this->ToggleButton->TabIndex = 0;
			this->ToggleButton->TabStop = false;
			this->ToggleButton->Text = L"Tracking Off";
			this->ToggleButton->UseVisualStyleBackColor = false;
			this->ToggleButton->Click += gcnew System::EventHandler(this, &MyForm::ToggleTracking);
			// 
			// OptionsFormButton
			// 
			this->OptionsFormButton->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->OptionsFormButton->BackColor = System::Drawing::Color::Gainsboro;
			this->OptionsFormButton->FlatStyle = System::Windows::Forms::FlatStyle::Popup;
			this->OptionsFormButton->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 15.75F, System::Drawing::FontStyle::Regular,
				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
			this->OptionsFormButton->ForeColor = System::Drawing::SystemColors::ControlText;
			this->OptionsFormButton->Location = System::Drawing::Point(58, 156);
			this->OptionsFormButton->Name = L"OptionsFormButton";
			this->OptionsFormButton->Size = System::Drawing::Size(130, 45);
			this->OptionsFormButton->TabIndex = 1;
			this->OptionsFormButton->TabStop = false;
			this->OptionsFormButton->Text = L"Options";
			this->OptionsFormButton->UseVisualStyleBackColor = false;
			this->OptionsFormButton->Click += gcnew System::EventHandler(this, &MyForm::OpenOptionsForm);
			// 
			// label1
			// 
			this->label1->AccessibleName = L"focuslabel";
			this->label1->AutoSize = true;
			this->label1->Location = System::Drawing::Point(13, 38);
			this->label1->Name = L"label1";
			this->label1->Size = System::Drawing::Size(10, 13);
			this->label1->TabIndex = 2;
			this->label1->Text = L" ";
			// 
			// panel1
			// 
			this->panel1->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->panel1->Controls->Add(this->label2);
			this->panel1->Location = System::Drawing::Point(58, 12);
			this->panel1->Name = L"panel1";
			this->panel1->Size = System::Drawing::Size(130, 32);
			this->panel1->TabIndex = 4;
			// 
			// label2
			// 
			this->label2->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->label2->AutoSize = true;
			this->label2->Location = System::Drawing::Point(35, 0);
			this->label2->Name = L"label2";
			this->label2->Size = System::Drawing::Size(69, 13);
			this->label2->TabIndex = 0;
			this->label2->Text = L"Current User:";
			this->label2->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
			this->label2->Click += gcnew System::EventHandler(this, &MyForm::label2_Click);
			// 
			// SensitivityTextLabel
			// 
			this->SensitivityTextLabel->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->SensitivityTextLabel->AutoSize = true;
			this->SensitivityTextLabel->Location = System::Drawing::Point(3, 0);
			this->SensitivityTextLabel->Name = L"SensitivityTextLabel";
			this->SensitivityTextLabel->Size = System::Drawing::Size(57, 13);
			this->SensitivityTextLabel->TabIndex = 0;
			this->SensitivityTextLabel->Text = L"Sensitivity:";
			this->SensitivityTextLabel->TextAlign = System::Drawing::ContentAlignment::MiddleLeft;
			// 
			// HotkeyTextLabel
			// 
			this->HotkeyTextLabel->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->HotkeyTextLabel->AutoSize = true;
			this->HotkeyTextLabel->Location = System::Drawing::Point(3, 16);
			this->HotkeyTextLabel->Margin = System::Windows::Forms::Padding(0);
			this->HotkeyTextLabel->Name = L"HotkeyTextLabel";
			this->HotkeyTextLabel->Size = System::Drawing::Size(33, 13);
			this->HotkeyTextLabel->TabIndex = 1;
			this->HotkeyTextLabel->Text = L"Click:";
			this->HotkeyTextLabel->TextAlign = System::Drawing::ContentAlignment::MiddleLeft;
			// 
			// SensitivityLabel
			// 
			this->SensitivityLabel->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->SensitivityLabel->AutoSize = true;
			this->SensitivityLabel->Location = System::Drawing::Point(57, 0);
			this->SensitivityLabel->Name = L"SensitivityLabel";
			this->SensitivityLabel->Size = System::Drawing::Size(13, 13);
			this->SensitivityLabel->TabIndex = 2;
			this->SensitivityLabel->Text = L"5";
			this->SensitivityLabel->TextAlign = System::Drawing::ContentAlignment::MiddleLeft;
			// 
			// HotkeyLabel
			// 
			this->HotkeyLabel->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->HotkeyLabel->AutoSize = true;
			this->HotkeyLabel->Location = System::Drawing::Point(32, 16);
			this->HotkeyLabel->Margin = System::Windows::Forms::Padding(0);
			this->HotkeyLabel->Name = L"HotkeyLabel";
			this->HotkeyLabel->Size = System::Drawing::Size(28, 13);
			this->HotkeyLabel->TabIndex = 3;
			this->HotkeyLabel->Text = L"Shift";
			this->HotkeyLabel->TextAlign = System::Drawing::ContentAlignment::MiddleLeft;
			// 
			// panel2
			// 
			this->panel2->Controls->Add(this->HotkeyLabel);
			this->panel2->Controls->Add(this->SensitivityLabel);
			this->panel2->Controls->Add(this->HotkeyTextLabel);
			this->panel2->Controls->Add(this->SensitivityTextLabel);
			this->panel2->Location = System::Drawing::Point(16, 250);
			this->panel2->Name = L"panel2";
			this->panel2->Size = System::Drawing::Size(133, 35);
			this->panel2->TabIndex = 6;
			// 
			// MyForm
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->BackColor = System::Drawing::SystemColors::Control;
			this->ClientSize = System::Drawing::Size(242, 297);
			this->Controls->Add(this->panel2);
			this->Controls->Add(this->ToggleButton);
			this->Controls->Add(this->panel1);
			this->Controls->Add(this->OptionsFormButton);
			this->Controls->Add(this->label1);
			this->ForeColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(12)), static_cast<System::Int32>(static_cast<System::Byte>(12)),
				static_cast<System::Int32>(static_cast<System::Byte>(12)));
			this->Name = L"MyForm";
			this->Text = L"MainMenu";
			this->Load += gcnew System::EventHandler(this, &MyForm::MyForm_Load);
			this->panel1->ResumeLayout(false);
			this->panel1->PerformLayout();
			this->panel2->ResumeLayout(false);
			this->panel2->PerformLayout();
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion
	private: System::Void UpdateMouse(System::Object^  sender, System::EventArgs^  e) {
		//if (currently_tracking)
		//{
		//	tobii_error_t error = tobii_wait_for_callbacks(1, &device); //Avoids busy wait loops by waiting until new package of stream data arrives
		//	assert(error == TOBII_ERROR_NO_ERROR || error == TOBII_ERROR_TIMED_OUT); //Could be either in normal usage
		//	error = tobii_device_process_callbacks(device);
		//	assert(error == TOBII_ERROR_NO_ERROR);
		//}
		//This function is no longer necessary, I used to use it to manage the eye tracking
		//within the form. I have switched over to running the form on a thread now which makes this
		//implementation unnecessary.
	}
	
	/*
	The ToggleTracking function is called whenever the Toggle Tracking button is pressed.
	Manages the visuals of the tracking button of the form along with the internal currently_tracking
	variable.
	*/
	private: System::Void ToggleTracking(System::Object^  sender, System::EventArgs^  e) {
		currently_tracking = !currently_tracking;
		if (currently_tracking)
		{
			ToggleButton->BackColor = System::Drawing::Color::LightGreen;
			ToggleButton->Text = "Tracking On";
		}
		else
		{
			ToggleButton->BackColor = System::Drawing::Color::LightCoral;
			ToggleButton->Text = "Tracking Off";
		}
		label1->Focus();
	}

	/*
	The OpenOptionsForm function just opens a single instance of the options form.
	*/
	private: System::Void OpenOptionsForm(System::Object^  sender, System::EventArgs^  e) {
		label1->Focus();
		//currently_tracking = false;
		//ToggleButton->BackColor = System::Drawing::Color::LightCoral;
		//ToggleButton->Text = "Tracking Off";
		OptionsForm^ options = gcnew OptionsForm;
		options->ShowDialog();
		UpdateFormVisuals();
	}
private: System::Void MyForm_Load(System::Object^  sender, System::EventArgs^  e) {
}
private: System::Void label2_Click(System::Object^  sender, System::EventArgs^  e) {
}
};
}

OptionsForm.h

#pragma once
#include "ReusableTobiiFunctions.h"

namespace CapstoneProjectV1 {

	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;

	/// <summary>
	/// Summary for OptionsForm
	/// </summary>
	public ref class OptionsForm : public System::Windows::Forms::Form
	{
	public:
		OptionsForm(void)
		{
			InitializeComponent();
			//
			//TODO: Add the constructor code here
			UpdateFormVisuals();
			//
		}

		/*
		The UpdateFormVisuals function will update the visuals of the form to the current settings
		of the current user. This function will be called whenever the options form initializes as well
		as when the Apply Changes button is pressed.
		*/
		void UpdateFormVisuals()
		{
			//Set the Current User label to the current users name
			String^ user = gcnew String(GetCurrentUserName().c_str());
			this->UserLabel->Text = "Current User:\n" + user;
			//Remove all of the users in the User drop down menu (UserComboBox)
			while(UserComboBox->Items->Count > 0)
				UserComboBox->Items->RemoveAt(0);
			//Add all of the users that are currently set into the UserComboBox
			for (int i = 0; i < GetUserCount(); i++)
			{
				user = gcnew String(GetUserNameAtIndex(i).c_str());
				this->UserComboBox->Items->Add(user);
			}
			//Add another option at the end of the UserComboBox to add a new user
			this->UserComboBox->Items->Add("Add New User");

			user = gcnew String(GetDefaultUserName().c_str());
			this->DefaultUserLabel->Text = user;
			//Set the value of the Sensitivity Slider to the current settings of the current user
			SensitivitySlider->Value = 21 - GetBinWidthAccessor();
			SensitivityToolTip->SetToolTip(this->SensitivitySlider, L"Adjust the tracking sensitivity on a scale from\n 1 (least sensitive) to 20 (most "
				L"sensitive)");
			//Set the text of the HotkeyComboBox to the current users settings
			if (GetPrimaryClickHotkey() == VK_SHIFT)
				this->HotkeyComboBox->Text = "Shift";
			else if (GetPrimaryClickHotkey() == VK_CONTROL)
				this->HotkeyComboBox->Text = "Control";
			else if (GetPrimaryClickHotkey() == VK_CAPITAL)
				this->HotkeyComboBox->Text = "CapsLock";
			else if (GetPrimaryClickHotkey() == ' ')
				this->HotkeyComboBox->Text = "Space";
			//Light and Dark Mode stuff
			if (GetLightMode()) //Light mode is on
			{
				this->LightModeRadioButton->Checked = true;
				this->DarkModeRadioButton->Checked = false;
				this->BackColor = SystemColors::Control;
				this->tableLayoutPanel1->BackColor = SystemColors::Control;
				this->SensitivityLabel->BackColor = SystemColors::Control;
				this->SensitivityLabel->ForeColor = SystemColors::ControlText;
				this->SensitivitySlider->BackColor = SystemColors::Control;
				this->HotkeyLabel->BackColor = SystemColors::Control;
				this->HotkeyLabel->ForeColor = SystemColors::ControlText;
				this->HotkeyComboBox->BackColor = SystemColors::Control;
				this->HotkeyComboBox->ForeColor = SystemColors::ControlText;
				this->ColorModeLabel->BackColor = SystemColors::Control;
				this->ColorModeLabel->ForeColor = SystemColors::ControlText;
				this->UserLabel->BackColor = SystemColors::Control;
				this->UserLabel->ForeColor = SystemColors::ControlText;
				this->LightModeRadioButton->BackColor = SystemColors::Control;
				this->LightModeRadioButton->ForeColor = SystemColors::ControlText;
				this->DarkModeRadioButton->BackColor = SystemColors::Control;
				this->DarkModeRadioButton->ForeColor = SystemColors::ControlText;
				this->ApplyButton->BackColor = SystemColors::Control;
				this->ApplyButton->ForeColor = SystemColors::ControlText;
				this->RemoveUserButton->BackColor = SystemColors::Control;
				this->RemoveUserButton->ForeColor = SystemColors::ControlText;
				this->DefaultButton->BackColor = SystemColors::Control;
				this->DefaultButton->ForeColor = SystemColors::ControlText;
				this->DefaultUserLabel->BackColor = SystemColors::Control;
				this->DefaultUserLabel->ForeColor = SystemColors::ControlText;
			}
			else //Dark mode is on
			{
				this->LightModeRadioButton->Checked = false;
				this->DarkModeRadioButton->Checked = true;
				this->BackColor = Drawing::Color::Black;
				this->tableLayoutPanel1->BackColor = Drawing::Color::Black;
				this->SensitivityLabel->BackColor = Drawing::Color::Black;
				this->SensitivityLabel->ForeColor = Drawing::Color::WhiteSmoke;
				this->SensitivitySlider->BackColor = Drawing::Color::Black;
				this->HotkeyLabel->BackColor = Drawing::Color::Black;
				this->HotkeyLabel->ForeColor = Drawing::Color::WhiteSmoke;
				this->HotkeyComboBox->BackColor = Drawing::Color::Black;
				this->HotkeyComboBox->ForeColor = Drawing::Color::WhiteSmoke;
				this->ColorModeLabel->BackColor = Drawing::Color::Black;
				this->ColorModeLabel->ForeColor = Drawing::Color::WhiteSmoke;
				this->UserLabel->BackColor = Drawing::Color::Black;
				this->UserLabel->ForeColor = Drawing::Color::WhiteSmoke;
				this->LightModeRadioButton->BackColor = Drawing::Color::Black;
				this->LightModeRadioButton->ForeColor = Drawing::Color::WhiteSmoke;
				this->DarkModeRadioButton->BackColor = Drawing::Color::Black;
				this->DarkModeRadioButton->ForeColor = Drawing::Color::WhiteSmoke;
				this->ApplyButton->BackColor = SystemColors::ControlDarkDark;
				this->ApplyButton->ForeColor = Drawing::Color::WhiteSmoke;
				this->RemoveUserButton->BackColor = SystemColors::ControlDarkDark;
				this->RemoveUserButton->ForeColor = Drawing::Color::WhiteSmoke;
				this->DefaultButton->BackColor = SystemColors::ControlDarkDark;
				this->DefaultButton->ForeColor = Drawing::Color::WhiteSmoke;
				this->DefaultUserLabel->BackColor = Drawing::Color::Black;
				this->DefaultUserLabel->ForeColor = Drawing::Color::WhiteSmoke;
			}
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~OptionsForm()
		{
			if (components)
			{
				delete components;
			}
		}












	private: System::Windows::Forms::ToolTip^  SensitivityToolTip;
	private: System::Windows::Forms::Label^  ColorModeLabel;

	private: System::Windows::Forms::Label^  HotkeyLabel;
	private: System::Windows::Forms::Label^  SensitivityLabel;

	private: System::Windows::Forms::TrackBar^  SensitivitySlider;

	private: System::Windows::Forms::TableLayoutPanel^  tableLayoutPanel1;
	private: System::Windows::Forms::ComboBox^  HotkeyComboBox;
	private: System::Windows::Forms::Panel^  panel1;
	private: System::Windows::Forms::RadioButton^  DarkModeRadioButton;

	private: System::Windows::Forms::RadioButton^  LightModeRadioButton;
private: System::Windows::Forms::Button^  ApplyButton;
private: System::Windows::Forms::Label^  UserLabel;
private: System::Windows::Forms::ComboBox^  UserComboBox;
private: System::Windows::Forms::Button^  DefaultButton;
private: System::Windows::Forms::Button^  RemoveUserButton;
private: System::Windows::Forms::Label^  DefaultUserLabel;

private: System::Windows::Forms::Panel^  panel2;

















	private: System::ComponentModel::IContainer^  components;



	protected:

	protected:

	protected:

	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>


#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			this->components = (gcnew System::ComponentModel::Container());
			this->SensitivityToolTip = (gcnew System::Windows::Forms::ToolTip(this->components));
			this->ColorModeLabel = (gcnew System::Windows::Forms::Label());
			this->HotkeyLabel = (gcnew System::Windows::Forms::Label());
			this->SensitivityLabel = (gcnew System::Windows::Forms::Label());
			this->SensitivitySlider = (gcnew System::Windows::Forms::TrackBar());
			this->tableLayoutPanel1 = (gcnew System::Windows::Forms::TableLayoutPanel());
			this->HotkeyComboBox = (gcnew System::Windows::Forms::ComboBox());
			this->panel1 = (gcnew System::Windows::Forms::Panel());
			this->DarkModeRadioButton = (gcnew System::Windows::Forms::RadioButton());
			this->LightModeRadioButton = (gcnew System::Windows::Forms::RadioButton());
			this->ApplyButton = (gcnew System::Windows::Forms::Button());
			this->UserLabel = (gcnew System::Windows::Forms::Label());
			this->UserComboBox = (gcnew System::Windows::Forms::ComboBox());
			this->DefaultButton = (gcnew System::Windows::Forms::Button());
			this->RemoveUserButton = (gcnew System::Windows::Forms::Button());
			this->DefaultUserLabel = (gcnew System::Windows::Forms::Label());
			this->panel2 = (gcnew System::Windows::Forms::Panel());
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->SensitivitySlider))->BeginInit();
			this->tableLayoutPanel1->SuspendLayout();
			this->panel1->SuspendLayout();
			this->panel2->SuspendLayout();
			this->SuspendLayout();
			// 
			// ColorModeLabel
			// 
			this->ColorModeLabel->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->ColorModeLabel->AutoSize = true;
			this->ColorModeLabel->ForeColor = System::Drawing::Color::Gainsboro;
			this->ColorModeLabel->Location = System::Drawing::Point(3, 147);
			this->ColorModeLabel->Name = L"ColorModeLabel";
			this->ColorModeLabel->Size = System::Drawing::Size(86, 49);
			this->ColorModeLabel->TabIndex = 12;
			this->ColorModeLabel->Text = L"Color Mode";
			this->ColorModeLabel->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
			// 
			// HotkeyLabel
			// 
			this->HotkeyLabel->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->HotkeyLabel->AutoSize = true;
			this->HotkeyLabel->ForeColor = System::Drawing::Color::Gainsboro;
			this->HotkeyLabel->Location = System::Drawing::Point(3, 49);
			this->HotkeyLabel->Name = L"HotkeyLabel";
			this->HotkeyLabel->Size = System::Drawing::Size(86, 49);
			this->HotkeyLabel->TabIndex = 11;
			this->HotkeyLabel->Text = L"Hotkey";
			this->HotkeyLabel->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
			// 
			// SensitivityLabel
			// 
			this->SensitivityLabel->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Left | System::Windows::Forms::AnchorStyles::Right));
			this->SensitivityLabel->AutoSize = true;
			this->SensitivityLabel->ForeColor = System::Drawing::Color::Gainsboro;
			this->SensitivityLabel->Location = System::Drawing::Point(3, 18);
			this->SensitivityLabel->Name = L"SensitivityLabel";
			this->SensitivityLabel->Size = System::Drawing::Size(86, 13);
			this->SensitivityLabel->TabIndex = 1;
			this->SensitivityLabel->Text = L"Sensitivity";
			this->SensitivityLabel->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
			// 
			// SensitivitySlider
			// 
			this->SensitivitySlider->Anchor = static_cast<System::Windows::Forms::AnchorStyles>(((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->SensitivitySlider->BackColor = System::Drawing::Color::Black;
			this->SensitivitySlider->CausesValidation = false;
			this->SensitivitySlider->LargeChange = 0;
			this->SensitivitySlider->Location = System::Drawing::Point(95, 3);
			this->SensitivitySlider->Maximum = 20;
			this->SensitivitySlider->Minimum = 1;
			this->SensitivitySlider->Name = L"SensitivitySlider";
			this->SensitivitySlider->Size = System::Drawing::Size(366, 43);
			this->SensitivitySlider->SmallChange = 0;
			this->SensitivitySlider->TabIndex = 0;
			this->SensitivitySlider->TabStop = false;
			this->SensitivitySlider->Value = 20;
			// 
			// tableLayoutPanel1
			// 
			this->tableLayoutPanel1->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->tableLayoutPanel1->BackColor = System::Drawing::SystemColors::InfoText;
			this->tableLayoutPanel1->ColumnCount = 2;
			this->tableLayoutPanel1->ColumnStyles->Add((gcnew System::Windows::Forms::ColumnStyle(System::Windows::Forms::SizeType::Percent,
				20)));
			this->tableLayoutPanel1->ColumnStyles->Add((gcnew System::Windows::Forms::ColumnStyle(System::Windows::Forms::SizeType::Percent,
				80)));
			this->tableLayoutPanel1->Controls->Add(this->SensitivityLabel, 0, 0);
			this->tableLayoutPanel1->Controls->Add(this->SensitivitySlider, 1, 0);
			this->tableLayoutPanel1->Controls->Add(this->HotkeyComboBox, 1, 1);
			this->tableLayoutPanel1->Controls->Add(this->HotkeyLabel, 0, 1);
			this->tableLayoutPanel1->Controls->Add(this->ColorModeLabel, 0, 3);
			this->tableLayoutPanel1->Controls->Add(this->panel1, 1, 3);
			this->tableLayoutPanel1->Location = System::Drawing::Point(3, 79);
			this->tableLayoutPanel1->Name = L"tableLayoutPanel1";
			this->tableLayoutPanel1->RowCount = 5;
			this->tableLayoutPanel1->RowStyles->Add((gcnew System::Windows::Forms::RowStyle(System::Windows::Forms::SizeType::Percent, 20)));
			this->tableLayoutPanel1->RowStyles->Add((gcnew System::Windows::Forms::RowStyle(System::Windows::Forms::SizeType::Percent, 20)));
			this->tableLayoutPanel1->RowStyles->Add((gcnew System::Windows::Forms::RowStyle(System::Windows::Forms::SizeType::Percent, 20)));
			this->tableLayoutPanel1->RowStyles->Add((gcnew System::Windows::Forms::RowStyle(System::Windows::Forms::SizeType::Percent, 20)));
			this->tableLayoutPanel1->RowStyles->Add((gcnew System::Windows::Forms::RowStyle(System::Windows::Forms::SizeType::Percent, 20)));
			this->tableLayoutPanel1->Size = System::Drawing::Size(464, 246);
			this->tableLayoutPanel1->TabIndex = 8;
			// 
			// HotkeyComboBox
			// 
			this->HotkeyComboBox->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->HotkeyComboBox->BackColor = System::Drawing::Color::Black;
			this->HotkeyComboBox->DropDownStyle = System::Windows::Forms::ComboBoxStyle::DropDownList;
			this->HotkeyComboBox->ForeColor = System::Drawing::Color::Gainsboro;
			this->HotkeyComboBox->FormattingEnabled = true;
			this->HotkeyComboBox->Items->AddRange(gcnew cli::array< System::Object^  >(4) { L"Shift", L"Spacebar", L"Control", L"CapsLock" });
			this->HotkeyComboBox->Location = System::Drawing::Point(95, 52);
			this->HotkeyComboBox->Name = L"HotkeyComboBox";
			this->HotkeyComboBox->Size = System::Drawing::Size(366, 21);
			this->HotkeyComboBox->TabIndex = 10;
			this->HotkeyComboBox->TabStop = false;
			// 
			// panel1
			// 
			this->panel1->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->panel1->Controls->Add(this->DarkModeRadioButton);
			this->panel1->Controls->Add(this->LightModeRadioButton);
			this->panel1->Location = System::Drawing::Point(95, 150);
			this->panel1->Name = L"panel1";
			this->panel1->Size = System::Drawing::Size(366, 43);
			this->panel1->TabIndex = 13;
			// 
			// DarkModeRadioButton
			// 
			this->DarkModeRadioButton->AutoSize = true;
			this->DarkModeRadioButton->ForeColor = System::Drawing::Color::Gainsboro;
			this->DarkModeRadioButton->Location = System::Drawing::Point(226, 13);
			this->DarkModeRadioButton->Name = L"DarkModeRadioButton";
			this->DarkModeRadioButton->Size = System::Drawing::Size(78, 17);
			this->DarkModeRadioButton->TabIndex = 1;
			this->DarkModeRadioButton->TabStop = true;
			this->DarkModeRadioButton->Text = L"Dark Mode";
			this->DarkModeRadioButton->UseVisualStyleBackColor = true;
			// 
			// LightModeRadioButton
			// 
			this->LightModeRadioButton->AutoSize = true;
			this->LightModeRadioButton->ForeColor = System::Drawing::Color::Gainsboro;
			this->LightModeRadioButton->Location = System::Drawing::Point(51, 13);
			this->LightModeRadioButton->Name = L"LightModeRadioButton";
			this->LightModeRadioButton->Size = System::Drawing::Size(78, 17);
			this->LightModeRadioButton->TabIndex = 0;
			this->LightModeRadioButton->TabStop = true;
			this->LightModeRadioButton->Text = L"Light Mode";
			this->LightModeRadioButton->UseVisualStyleBackColor = true;
			this->LightModeRadioButton->CheckedChanged += gcnew System::EventHandler(this, &OptionsForm::LightModeChanged);
			// 
			// ApplyButton
			// 
			this->ApplyButton->BackColor = System::Drawing::SystemColors::ControlDarkDark;
			this->ApplyButton->FlatStyle = System::Windows::Forms::FlatStyle::Popup;
			this->ApplyButton->ForeColor = System::Drawing::Color::WhiteSmoke;
			this->ApplyButton->Location = System::Drawing::Point(348, 346);
			this->ApplyButton->Name = L"ApplyButton";
			this->ApplyButton->Size = System::Drawing::Size(75, 23);
			this->ApplyButton->TabIndex = 9;
			this->ApplyButton->Text = L"Apply";
			this->ApplyButton->UseVisualStyleBackColor = false;
			this->ApplyButton->Click += gcnew System::EventHandler(this, &OptionsForm::ApplyChanges);
			// 
			// UserLabel
			// 
			this->UserLabel->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->UserLabel->AutoSize = true;
			this->UserLabel->ForeColor = System::Drawing::Color::WhiteSmoke;
			this->UserLabel->Location = System::Drawing::Point(200, 9);
			this->UserLabel->Name = L"UserLabel";
			this->UserLabel->Size = System::Drawing::Size(69, 13);
			this->UserLabel->TabIndex = 14;
			this->UserLabel->Text = L"Current User:";
			this->UserLabel->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
			// 
			// UserComboBox
			// 
			this->UserComboBox->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->UserComboBox->BackColor = System::Drawing::SystemColors::Window;
			this->UserComboBox->FormattingEnabled = true;
			this->UserComboBox->Location = System::Drawing::Point(149, 40);
			this->UserComboBox->Name = L"UserComboBox";
			this->UserComboBox->Size = System::Drawing::Size(171, 21);
			this->UserComboBox->TabIndex = 15;
			this->UserComboBox->SelectedIndexChanged += gcnew System::EventHandler(this, &OptionsForm::CurrentUserComboBoxSelection);
			// 
			// DefaultButton
			// 
			this->DefaultButton->BackColor = System::Drawing::SystemColors::ControlDarkDark;
			this->DefaultButton->FlatStyle = System::Windows::Forms::FlatStyle::Popup;
			this->DefaultButton->ForeColor = System::Drawing::Color::WhiteSmoke;
			this->DefaultButton->Location = System::Drawing::Point(3, 0);
			this->DefaultButton->Name = L"DefaultButton";
			this->DefaultButton->Size = System::Drawing::Size(97, 23);
			this->DefaultButton->TabIndex = 16;
			this->DefaultButton->Text = L"Save as Default";
			this->DefaultButton->UseVisualStyleBackColor = false;
			this->DefaultButton->Click += gcnew System::EventHandler(this, &OptionsForm::NewDefault);
			// 
			// RemoveUserButton
			// 
			this->RemoveUserButton->BackColor = System::Drawing::SystemColors::ControlDarkDark;
			this->RemoveUserButton->FlatStyle = System::Windows::Forms::FlatStyle::Popup;
			this->RemoveUserButton->ForeColor = System::Drawing::Color::WhiteSmoke;
			this->RemoveUserButton->Location = System::Drawing::Point(203, 346);
			this->RemoveUserButton->Name = L"RemoveUserButton";
			this->RemoveUserButton->Size = System::Drawing::Size(93, 23);
			this->RemoveUserButton->TabIndex = 17;
			this->RemoveUserButton->Text = L"Remove User";
			this->RemoveUserButton->UseVisualStyleBackColor = false;
			this->RemoveUserButton->Click += gcnew System::EventHandler(this, &OptionsForm::RemoveUser);
			// 
			// DefaultUserLabel
			// 
			this->DefaultUserLabel->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->DefaultUserLabel->Location = System::Drawing::Point(3, 26);
			this->DefaultUserLabel->Name = L"DefaultUserLabel";
			this->DefaultUserLabel->Size = System::Drawing::Size(97, 23);
			this->DefaultUserLabel->TabIndex = 18;
			this->DefaultUserLabel->Text = L"Test";
			this->DefaultUserLabel->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
			// 
			// panel2
			// 
			this->panel2->Controls->Add(this->DefaultUserLabel);
			this->panel2->Controls->Add(this->DefaultButton);
			this->panel2->Location = System::Drawing::Point(40, 346);
			this->panel2->Name = L"panel2";
			this->panel2->Size = System::Drawing::Size(107, 49);
			this->panel2->TabIndex = 14;
			// 
			// OptionsForm
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->BackColor = System::Drawing::Color::Black;
			this->ClientSize = System::Drawing::Size(470, 404);
			this->Controls->Add(this->RemoveUserButton);
			this->Controls->Add(this->UserComboBox);
			this->Controls->Add(this->UserLabel);
			this->Controls->Add(this->ApplyButton);
			this->Controls->Add(this->tableLayoutPanel1);
			this->Controls->Add(this->panel2);
			this->ForeColor = System::Drawing::SystemColors::ControlDarkDark;
			this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedSingle;
			this->Name = L"OptionsForm";
			this->SizeGripStyle = System::Windows::Forms::SizeGripStyle::Hide;
			this->Text = L"OptionsForm";
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->SensitivitySlider))->EndInit();
			this->tableLayoutPanel1->ResumeLayout(false);
			this->tableLayoutPanel1->PerformLayout();
			this->panel1->ResumeLayout(false);
			this->panel1->PerformLayout();
			this->panel2->ResumeLayout(false);
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion
private: System::Void LightModeChanged(System::Object^  sender, System::EventArgs^  e) {
	/*if (LightModeRadioButton->Checked == true)
		SetLightMode(true);
	else
		SetLightMode(false);
	UpdateFormVisuals();*/
	//Deprecated as of right now, could potentially implement later
	//Depends on if we want color mode to swap as soon as new one is selected
	//or if you want to wait until the Apply Changes button is pressed
	
}

/*
The ApplyChanges function will be called whenever the Apply Changes button is pressed. It should
adjust the settings of the current user to the settings currently active in the Options Form.
Additionally, it will call the UpdateFormVisuals function to make the changes apparent to the 
user.
*/
private: System::Void ApplyChanges(System::Object^  sender, System::EventArgs^  e) {
	//HANDLE HOTKEY CHANGES
	if (HotkeyComboBox->Text == "Shift")
		SetPrimaryClickHotkey(VK_SHIFT);
	else if (HotkeyComboBox->Text == "Spacebar")
		SetPrimaryClickHotkey(' ');
	else if (HotkeyComboBox->Text == "Control")
		SetPrimaryClickHotkey(VK_CONTROL);
	else if (HotkeyComboBox->Text == "CapsLock")
		SetPrimaryClickHotkey(VK_CAPITAL);

	//HANDLE SENSITIVITY CHANGES
	AdjustBinWidthConnector(21 - SensitivitySlider->Value);

	//HANDLE COLOR MODE CHANGES
	if (LightModeRadioButton->Checked == true)
		SetLightMode(true);
	else
		SetLightMode(false);
	msclr::interop::marshal_context context;
	std::string standardString = context.marshal_as<std::string>(UserComboBox->Text);
	SetCurrentUserName(standardString);
	//UPDATE FORM VISUALS
	UpdateFormVisuals();
}

/*
The CurrentUserComboBoxSelection function will be called whenever the user changes the value of the
Current User Combo Box. That is, whenver they try to change the user. It will update the current
settings 
*/
private: System::Void CurrentUserComboBoxSelection(System::Object^  sender, System::EventArgs^  e) {

	//Code to convert System::String to std::string found from https://stackoverflow.com/questions/1300718/c-net-convert-systemstring-to-stdstring
	msclr::interop::marshal_context context;
	std::string standardString = context.marshal_as<std::string>(UserComboBox->Text);
	//Update the current user and change all of the current settings to the settings
	//of that user
	if (GetUserIndexByName(standardString) != -1)
	{
		UpdateCurrentUser(GetUserIndexByName(standardString));
		SetPrimaryClickHotkey(GetPrimaryClickHotkey());
		AdjustBinWidthConnector(GetBinWidthAccessor());
		SetLightMode(GetLightMode());
		UpdateFormVisuals();
	}
	//Did the user select the Add New User option in the combo box?
	//If so then we need to create a new user and let them name them.
	else if(UserComboBox->Text == "Add New User")
	{
		AddNewUser("EnterNewName", VK_CONTROL, true, 5);
		UpdateCurrentUser(GetUserIndexByName("EnterNewName"));
		UserComboBox->Items->Remove("Add New User");
		UserComboBox->Items->Add("EnterNewName");
		UserComboBox->Items->Add("Add New User");
		UpdateFormVisuals();

	}
}

/*
The NewDefault function will be called when the Save as Default button is pressed.
It will update the default user to the current user.
*/
private: System::Void NewDefault(System::Object^  sender, System::EventArgs^  e) {
	SetCurrentUserToDefault();
	String^ defaultUser;
	defaultUser = gcnew String(GetDefaultUserName().c_str());
	this->DefaultUserLabel->Text = defaultUser;

}

/*
The RemoveUser funciton will be called whenever the Remove User button is pressed.
The function will remove the current user from the list of users. If that user is also
the default user, then a new default user will be selected.
*/
private: System::Void RemoveUser(System::Object^  sender, System::EventArgs^  e) {
	RemoveCurrentUser();
	if (UserComboBox->Items->Count > 1) //There are users in the system
	{
		UserComboBox->Items->Remove(UserComboBox->Text);
	}
	UpdateCurrentUser(GetUserIndexByName(GetCurrentUserName()));
	SetPrimaryClickHotkey(GetPrimaryClickHotkey());
	AdjustBinWidthConnector(GetBinWidthAccessor());
	SetLightMode(GetLightMode());
	UpdateFormVisuals();
}
};
}
css.php