public void DrawCircleMenu(Point center, int menuRadius, int circleRadius, int fontSize, List <string> menuOptions, bool active, bool isInnerMenu) { int optionsCount = menuOptions.Count; // Броят на възможностите, т.е. колко окръжности ще се изчертаят double coefToRad = Math.PI / 180; // Множител за превръщане от градуси в радиани, понеже тригонометричните функции работят с радиани double angle = 0; // Инициализация (в градуси) на ъгъла на завъртане, определящ позицията на съответната окръжност foreach (string menuOption in menuOptions) // Една по една се обхождат подадените опции { Point location = new Point(); // Определя се позицията (в "полярна координатна система") на центъра на всяка окръжност location.X = center.X + Convert.ToInt32(menuRadius * Math.Sin(coefToRad * angle)); // по-точно: неговата абсциса location.Y = center.Y - Convert.ToInt32(menuRadius * Math.Cos(coefToRad * angle)); // и ордината if (isInnerMenu) { innerMenuCenters.Add(location); // Координатите на текущия център се добавят към списъка за центровете на вътрешното меню } else { outerMenuCenters.Add(location); // или външното, според това коео меню се чертае } RoundButton roundButton = new RoundButton(location, circleRadius, menuOption, fontSize, otherMenuItemsForeColor, otherMenuItemsBackColor, otherMenuItemsBorderColor); Controls.Add(roundButton); angle += 360 / optionsCount; // Ъгълът се завърта, така че да застане на следващата опция } }
private void DrawCentralReactant(Point center) // Показва първия реагент в центъра на формата { Element element = new Element(); string symbol = element.GetFirstReactantFormula(); string text = string.Empty; if (element.Exists(symbol)) { text = element.SearchNameBySymbol(symbol); } else { Compound compound = new Compound(); text = compound.SearchNameByFormula(symbol); } RoundButton roundButton = new RoundButton(center, centralMenuItemCircleRadius, text, centralMenuItemFontSize, centralMenuItemForeColor, centralMenuItemBackColor, centralMenuItemBorderColor); roundButton.Enabled = false; // като определя той да е неактивен Controls.Add(roundButton); }
protected override void OnMouseClick(MouseEventArgs e) { if (MouseInCircle(e.Location)) // Събитието натискане на бутон на мишката се отчита само, ако контролът е активен и мишката се намира в рамките на кръга { FmTable fmTable = (FmTable)Application.OpenForms["FmTable"]; if (fmTable.FirstReactantFormula == string.Empty) { FmFirstReactantMenu fmFirstReactantMenu = (FmFirstReactantMenu)Application.OpenForms["FmFirstReactantMenu"]; if (Text == "неметал" || Text == "метал") { Folder folder = new Folder(); List <string> reactants = folder.LoadReactants(); string generalCategory = (Text == "метал") ? "метал" : "неметал"; // Въз основа на надписа се определя основната група елементи, която потребителят е избрал fmTable.EnableButtonsByReactionsAndGeneralCategory(reactants, generalCategory); // Като се знае основната група се филтрират само елементите, за които има въведени реакции и са от същата група fmFirstReactantMenu.ChoiceHasBeenMade = true; // Потребителя е направил своя избор fmFirstReactantMenu.Close(); // и формата се затваря } else if (Text == "вода") { Element element = new Element(); element.SetFirstReactantFormula("H2O"); fmFirstReactantMenu.ChoiceHasBeenMade = true; fmFirstReactantMenu.Close(); FmSecondReactantMenu fmSecondReactantMenu = new FmSecondReactantMenu(); fmSecondReactantMenu.ShowDialog(fmTable); } else if (Text == "киселина" || Text == "основа" || Text == "оксид") // Ако избраното е "киселина", "основа" или "оксид" { foreach (Control control in fmFirstReactantMenu.Controls) // се деактивира "вътрешното" меню { if (control is RoundButton) // т.е. всички потребителски контроли показани до момента { RoundButton roundButton = (RoundButton)control; roundButton.Enabled = false; } } fmFirstReactantMenu.OuterMenuCenter = circleCenter; // Съхраняват се координатите на центъра на външното меню List <string> outerMenuOptions = fmFirstReactantMenu.LoadOuterMenuOptions(Text); // след това веществата, за които има въведени реакции fmFirstReactantMenu.OuterMenuCenters = new List <Point>(outerMenuOptions.Count); // Определя се броя на центровете за външното меню fmFirstReactantMenu.DrawCircleMenu(circleCenter, fmFirstReactantMenu.OuterMenuRadius, fmFirstReactantMenu.OuterMenuCircleRadius, fmFirstReactantMenu.OuterMenuFontSize, outerMenuOptions, true, false); // и по определения нов център и списък с вещества се изчертава "външното" меню } else // Във всички останали случаи, потребителят е избрал опция от външното меню { string text = Text.Replace('\n', ' '); // Възвръща се оригиналното име на съединението (без знаците за нов ред) Compound compound = new Compound(); string formula = compound.SearchFormulaByName(text); Element element = new Element(); element.SetFirstReactantFormula(formula); // След като е открито съвпадение, то се записва като формула за първия реагент fmFirstReactantMenu.ChoiceHasBeenMade = true; fmFirstReactantMenu.Close(); FmSecondReactantMenu fmSecondReactantMenu = new FmSecondReactantMenu(); fmSecondReactantMenu.ShowDialog(fmTable); } } else if (fmTable.SecondReactantFormula == string.Empty) { FmSecondReactantMenu fmSecondReactantMenu = (FmSecondReactantMenu)Application.OpenForms["FmSecondReactantMenu"]; Element element = new Element(); if (Text == "неметал" || Text == "метал") { string generalCategory = (Text == "метал") ? "метал" : "неметал"; // Въз основа на надписа се определя основната група елементи, която потребителят е избрал string firstReactantFormula = element.GetFirstReactantFormula(); // и формулата на първия реагент fmTable.EnableButtonsByFirstReactantAndGeneralCategory(generalCategory); // След това, като се знае първия реагент и основната група за втория се филтрират само елементите, които реагират с първия избран и са от същата основна група fmSecondReactantMenu.ChoiceHasBeenMade = true; // Потребителя е направил своя избор fmSecondReactantMenu.Close(); // и формата се затваря } else if (Text == "водород" || Text == "кислород" || Text == "вода") // Ако потребителят е избрал опция с надпис водород, кислород или вода { switch (Text) { case "водород": element.SetSecondReactantFormula("H"); break; case "кислород": element.SetSecondReactantFormula("O"); break; case "вода": element.SetSecondReactantFormula("H2O"); break; } fmTable.LoadBalanceAndShowEquations(); // Понеже формулата е ясна, може направо да се премина към изравняване на реакцията fmSecondReactantMenu.ChoiceHasBeenMade = true; // и да се затвори формата с менюто fmSecondReactantMenu.Close(); } else if (Text == "киселина" || Text == "основа" || Text == "оксид") // Ако избраното е "киселина", "основа" или "оксид" { foreach (Control control in fmSecondReactantMenu.Controls) // се деактивира "вътрешното" меню { if (control is RoundButton) // т.е. всички потребителски контроли показани до момента { RoundButton roundButton = (RoundButton)control; roundButton.Enabled = false; } } fmSecondReactantMenu.OuterMenuCenter = circleCenter; // Съхраняват се координатите на центъра на външното меню List <string> outerMenuOptions = fmSecondReactantMenu.LoadOuterMenuOptions(Text); // след това веществата, с които реагира първият реагент fmSecondReactantMenu.OuterMenuCenters = new List <Point>(outerMenuOptions.Count); // Определя се броя на центровете за външното меню fmSecondReactantMenu.DrawCircleMenu(circleCenter, fmSecondReactantMenu.OuterMenuRadius, fmSecondReactantMenu.OuterMenuCircleRadius, fmSecondReactantMenu.OuterMenuFontSize, outerMenuOptions, true, false); // и по определения нов център и списък с вещества се изчертава "външното" меню } else // Във всички останали случаи, потребителят е избрал опция от външното меню { string text = Text.Replace('\n', ' '); // Възвръща се оригиналното име на съединението (без знаците за нов ред) Compound compound = new Compound(); string formula = compound.SearchFormulaByName(text); element.SetSecondReactantFormula(formula); // След като е открито съвпадение, то се записва като формула за втория реагент fmTable.LoadBalanceAndShowEquations(); fmSecondReactantMenu.ChoiceHasBeenMade = true; fmSecondReactantMenu.Close(); } } } }