private void MenuFileClose_Click(object sender, EventArgs e) { log.Debug("EditorForm::MenuFileClose_Click() {"); if (hasUnsavedChanges) { try { DialogResult result = MessageBox.Show("There are unsaved changes. Save?", "Information", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information); switch (result) { case DialogResult.Yes: if (!SaveToFile()) { log.Debug("EditorForm::MenuFileClose_Click() } // cancelled (save existing)"); return; } break; case DialogResult.No: break; default: case DialogResult.Cancel: log.Debug("EditorForm::MenuFileClose_Click() } // cancelled (save existing)"); return; } } catch (Exception ex) { log.Error("Failed to close scoreboard: Failed to save existing scoreboard.", ex); MessageBox.Show("Failed to close scoreboard: Failed to save existing scoreboard: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } try { scoreboard = null; hasUnsavedChanges = false; UpdateScores(); UpdateControls(); } catch (Exception ex) { log.Error("Failed to close scoreboard.", ex); MessageBox.Show("Failed to close scoreboard: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } log.Debug("EditorForm::MenuFileClose_Click() }"); }
public static void SaveToFile(Scoreboard scoreboard, Stream stream) { if (stream == null) { throw new ArgumentException("Failed to save scoreboard to file: Argument 'stream' is null."); } if (scoreboard == null) { throw new ArgumentException("Failed to save scoreboard to file: Argument 'scoreboard' is null."); } using (TextWriter writer = new StreamWriter(stream, Encoding.UTF8)) { string[] teams = scoreboard.Teams; string[] categories = scoreboard.Categories; decimal[,] scores = scoreboard.Scores; writer.Write(scoreboard.ExpectedNumberOfCategories + "\\" + scoreboard.ExpectedNumberOfTeams); foreach (string team in teams) { writer.Write(",\""); writer.Write(team); writer.Write("\""); } writer.Write("\n"); for (int i = 0; i < categories.Length; ++i) { writer.Write("\""); writer.Write(categories[i]); writer.Write("\""); for (int j = 0; j < teams.Length; ++j) { writer.Write(","); writer.Write(scores[j, i].ToString(CultureInfo.InvariantCulture)); } writer.Write("\n"); } } }
public static Scoreboard LoadFromFile(Stream stream) { if (stream == null) { throw new ArgumentException("Failed to load scoreboard from file: Argument 'stream' is null."); } ScoreboardFile file; using (StreamReader reader = new StreamReader(stream)) { file = JsonConvert.DeserializeObject <ScoreboardFile>(reader.ReadToEnd()); } if (file.ExpectedNumberOfTeams < file.Teams.Length || file.Teams.Length != file.Scores.GetLength(0)) { throw new ArgumentException("Failed to load scoreboard from file: Invalid number of teams."); } if (file.ExpectedNumberOfCategories < file.Categories.Length || file.Categories.Length != file.Scores.GetLength(1)) { throw new ArgumentException("Failed to load scoreboard from file: Invalid number of categories."); } Scoreboard scoreboard = new Scoreboard(file.ExpectedNumberOfTeams, file.ExpectedNumberOfCategories); for (int i = 0; i < file.Teams.Length; ++i) { scoreboard.AddTeam(file.Teams[i]); } decimal[] scores = new decimal[file.Teams.Length]; for (int i = 0; i < file.Categories.Length; ++i) { for (int j = file.Teams.Length - 1; j >= 0; --j) { scores[j] = file.Scores[j, i]; } scoreboard.AddCategory(file.Categories[i], scores); } return(scoreboard); }
private void LoadFromFile() { log.Debug("EditorForm::LoadFromFile() {"); using (OpenFileDialog openFileDialog = new OpenFileDialog()) { openFileDialog.InitialDirectory = string.IsNullOrEmpty(fileName) ? Environment.SpecialFolder.MyDocuments.ToString() : fileName; openFileDialog.Filter = "CSV files (*.csv)|*.csv|JSON files (*.json)|*.json"; openFileDialog.FilterIndex = 1; openFileDialog.RestoreDirectory = true; if (openFileDialog.ShowDialog() == DialogResult.OK) { fileName = openFileDialog.FileName; switch (Path.GetExtension(fileName)) { case ".csv": scoreboard = CsvHandler.LoadFromFile(openFileDialog.OpenFile()); break; case ".json": scoreboard = JsonHandler.LoadFromFile(openFileDialog.OpenFile()); break; default: throw new ArgumentException("Unknown file format: '" + Path.GetExtension(fileName) + "'."); } hasUnsavedChanges = false; NumericInputAnimationLength.Value = GetSuggestedAnimationLength(); UpdateScores(); UpdateControls(); } } log.Debug("EditorForm::LoadFromFile() }"); }
public static Scoreboard LoadFromFile(Stream stream) { if (stream == null) { throw new ArgumentException("Failed to load scoreboard from file: Argument 'stream' is null."); } using (TextReader reader = new StreamReader(stream)) { string buffer = reader.ReadToEnd(); string[][] rows = CsvParser.Parse(buffer, true, out string[] header); string[] dimens = header[0].Split('\\'); if (!int.TryParse(dimens[0], out int expectedNumberOfCategories)) { throw new ArgumentException("Failed to load scoreboard fom file: Invalid number of categories in cell (0,0)."); } if (!int.TryParse(dimens[1], out int expectedNumberOfTeams)) { throw new ArgumentException("Failed to load scoreboard fom file: Invalid number of teams in cell (0,0)."); } // first column contains category names if (header.Length > expectedNumberOfTeams + 1) { throw new ArgumentException("Failed to load scoreboard fom file: Invalid number of columns in header."); } // header (row containing team names) is separate if (rows.Length > expectedNumberOfCategories) { throw new ArgumentException("Failed to load scoreboard fom file: Invalid number of rows."); } for (int i = rows.Length - 1; i >= 0; --i) { if (rows[i].Length != header.Length) { throw new ArgumentException("Failed to load scoreboard fom file: Invalid number columns in row " + (i + 1) + "."); } } Scoreboard scoreboard = new Scoreboard(expectedNumberOfTeams, expectedNumberOfCategories); for (int i = 1; i < header.Length; ++i) { scoreboard.AddTeam(header[i]); } decimal[] scores = new decimal[header.Length - 1]; for (int i = 0; i < rows.Length; ++i) { for (int j = header.Length - 2; j >= 0; --j) { if (!decimal.TryParse(rows[i][j + 1], NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out scores[j])) { throw new ArgumentException("Failed to load scoreboard fom file: Invalid score for team '" + header[j + 1] + "' at category '" + rows[i][0] + "'."); } } scoreboard.AddCategory(rows[i][0], scores); } return(scoreboard); } }
private async void ButtonOk_Click(object sender, EventArgs e) { try { ProgressBarImport.Visible = true; ButtonOk.Visible = false; ButtonCancel.Visible = false; ProgressBarImport.Value = 0; string url = TextBoxUrl.Text; if (url.EndsWith("/")) { url = url.Substring(0, url.Length - 1); } if (previousUrl != url) { previousCookieContainer = new CookieContainer(); } HttpClient client = new HttpClient(new HttpClientHandler() { CookieContainer = previousCookieContainer }); HttpResponseMessage response; ProgressBarImport.Value = 25; if (!CheckBoxExistingAuth.Checked) { HttpContent content = new StringContent(JsonConvert.SerializeObject(new LoginData() { Name = TextBoxName.Text, Password = TextBoxPassword.Text }, serializerSettings), Encoding.UTF8, "application/json"); response = await client.PostAsync(url + "/mods", content); if (!response.IsSuccessStatusCode) { throw new Exception("Failed to import from remote: Login failed: (" + response.StatusCode + ")" + response.ReasonPhrase); } } else { await Task.Delay(100); } ProgressBarImport.Value = 50; response = await client.GetAsync(url + "/standings"); if (!response.IsSuccessStatusCode) { throw new Exception("Failed to import from remote: (" + response.StatusCode + ")" + response.ReasonPhrase); } await Task.Delay(100); ProgressBarImport.Value = 75; Scoreboard = JsonHandler.LoadFromFile(await response.Content.ReadAsStreamAsync()); await Task.Delay(100); ProgressBarImport.Value = 100; previousUrl = url; await Task.Delay(100); DialogResult = DialogResult.OK; Close(); } catch (Exception ex) { log.Error("Failed to import from remote.", ex); MessageBox.Show("Failed to import from remote: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { ProgressBarImport.Visible = false; ButtonOk.Visible = true; ButtonCancel.Visible = true; } }
private void MenuFileImportFromRemote_Click(object sender, EventArgs e) { log.Debug("EditorForm::MenuFileImportFromRemote_Click() {"); if (hasUnsavedChanges) { try { DialogResult result = MessageBox.Show("There are unsaved changes. Save?", "Information", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information); switch (result) { case DialogResult.Yes: if (!SaveToFile()) { log.Debug("EditorForm::MenuFileImportFromRemote_Click() } // cancelled (save existing)"); return; } break; case DialogResult.No: break; default: case DialogResult.Cancel: log.Debug("EditorForm::MenuFileImportFromRemote_Click() } // cancelled (save existing)"); return; } } catch (Exception ex) { log.Error("Failed to import from remote: Failed to save existing scoreboard.", ex); MessageBox.Show("Failed to import from remote: Failed to save existing scoreboard: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); log.Debug("EditorForm::MenuFileImportFromRemote_Click() }"); return; } } try { ImportFromRemoteForm importFromRemoteForm = new ImportFromRemoteForm(); importFromRemoteForm.StartPosition = FormStartPosition.CenterParent; DialogResult result = importFromRemoteForm.ShowDialog(this); if (result != DialogResult.OK) { log.Debug("EditorForm::MenuFileImportFromRemote_Click() } // cancelled"); return; } scoreboard = importFromRemoteForm.Scoreboard; hasUnsavedChanges = true; NumericInputAnimationLength.Value = GetSuggestedAnimationLength(); UpdateScores(); UpdateControls(); } catch (Exception ex) { log.Error("Failed to import from remote.", ex); MessageBox.Show("Failed to import from remote: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } log.Debug("EditorForm::MenuFileImportFromRemote_Click() }"); }
private void MenuFileNewFromTemplate_Click(object sender, EventArgs e) { log.Debug("EditorForm::MenuFileNewFromTemplate_Click() {"); if (hasUnsavedChanges) { try { DialogResult result = MessageBox.Show("There are unsaved changes. Save?", "Information", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information); switch (result) { case DialogResult.Yes: if (!SaveToFile()) { log.Debug("EditorForm::MenuFileNewFromTemplate_Click() } // cancelled (save existing)"); return; } break; case DialogResult.No: break; default: case DialogResult.Cancel: log.Debug("EditorForm::MenuFileNewFromTemplate_Click() } // cancelled (save existing)"); return; } } catch (Exception ex) { log.Error("Failed to import template: Failed to save existing scoreboard.", ex); MessageBox.Show("Failed to import template: Failed to save existing scoreboard: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); log.Debug("EditorForm::MenuFileNewFromTemplate_Click() }"); return; } } try { using (OpenFileDialog openFileDialog = new OpenFileDialog()) { openFileDialog.InitialDirectory = string.IsNullOrEmpty(fileName) ? Environment.SpecialFolder.MyDocuments.ToString() : fileName; openFileDialog.Filter = "CSV files (*.csv)|*.csv|JSON files (*.json)|*.json"; openFileDialog.FilterIndex = 1; openFileDialog.RestoreDirectory = true; Scoreboard template; if (openFileDialog.ShowDialog() == DialogResult.OK) { fileName = openFileDialog.FileName; switch (Path.GetExtension(fileName)) { case ".csv": template = CsvHandler.LoadFromFile(openFileDialog.OpenFile()); break; case ".json": template = JsonHandler.LoadFromFile(openFileDialog.OpenFile()); break; default: throw new ArgumentException("Unknown file format: '" + Path.GetExtension(fileName) + "'."); } hasUnsavedChanges = false; scoreboard = new Scoreboard(template.ExpectedNumberOfTeams, template.ExpectedNumberOfCategories); foreach (string team in template.Teams) { scoreboard.AddTeam(team); } NumericInputAnimationLength.Value = GetSuggestedAnimationLength(); UpdateScores(); UpdateControls(); } } } catch (Exception ex) { log.Error("Failed to import template.", ex); MessageBox.Show("Failed to import template: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } log.Debug("EditorForm::MenuFileNewFromTemplate_Click() }"); }
private void MenuFileNew_Click(object sender, EventArgs e) { log.Debug("EditorForm::MenuFileNew_Click() {"); if (hasUnsavedChanges) { try { DialogResult result = MessageBox.Show("There are unsaved changes. Save?", "Information", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information); switch (result) { case DialogResult.Yes: if (!SaveToFile()) { log.Debug("EditorForm::MenuFileNew_Click() } // cancelled (save existing)"); return; } break; case DialogResult.No: break; default: case DialogResult.Cancel: log.Debug("EditorForm::MenuFileNew_Click() } // cancelled (save existing)"); return; } } catch (Exception ex) { log.Error("Failed to create new scoreboard: Failed to save existing scoreboard.", ex); MessageBox.Show("Failed to create new scoreboard: Failed to save existing scoreboard: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); log.Debug("EditorForm::MenuFileNew_Click() }"); return; } } try { NewScoreboardForm newScoreboardForm = new NewScoreboardForm(); newScoreboardForm.StartPosition = FormStartPosition.CenterParent; DialogResult result = newScoreboardForm.ShowDialog(this); if (result != DialogResult.OK) { log.Debug("EditorForm::MenuFileNew_Click() } // cancelled"); return; } scoreboard = new Scoreboard(newScoreboardForm.NumberOfTeams, newScoreboardForm.NumberOfCategories); hasUnsavedChanges = false; NumericInputAnimationLength.Value = 3m; UpdateScores(); UpdateControls(); } catch (Exception ex) { log.Error("Failed to create new scoreboard.", ex); MessageBox.Show("Failed to create new scoreboard: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } log.Debug("EditorForm::MenuFileNew_Click() }"); }
public void StartAnimation(Scoreboard scoreboard, double animationLength, bool enableFireworks) { // precompute some values // and start render-thread/draw-loop isRunning = true; keepRendering = true; this.animationLength = animationLength * 1000d; this.enableFireworks = enableFireworks; if (scoreboard == null) { throw new ArgumentException("Failed to show results: Argument 'scoreboard' is null."); } teams = scoreboard.Teams; categories = scoreboard.Categories; scores = scoreboard.Scores; int expectedNumberOfCategories = scoreboard.ExpectedNumberOfCategories; if (teams == null || teams.Length == 0 || categories == null || categories.Length == 0 || expectedNumberOfCategories == 0) { throw new ArgumentException("Failed to show results: Invalid scoreboard."); } decimal[] sortedTotalScores = scoreboard.TotalScores; Array.Sort(sortedTotalScores); bool maxScoreTie = sortedTotalScores.Length >= 2 && sortedTotalScores[sortedTotalScores.Length - 1] == sortedTotalScores[sortedTotalScores.Length - 2]; sortedTotalScores = sortedTotalScores.Distinct().ToArray(); maxScore = sortedTotalScores[sortedTotalScores.Length - 1]; // devide total into points where "teams finish" animationSpeedSlowdownDomain = new float[sortedTotalScores.Length + 1]; animationSpeedSlowdownDomain[0] = -0.01f; animationSpeedSlowdownDomain[sortedTotalScores.Length] = 100.01f; // get percentage of individual team scores w.r.t. to maxScore animationSpeedSlowdownImage = new float[sortedTotalScores.Length + 1]; animationSpeedSlowdownImage[0] = 0f; animationSpeedSlowdownImage[sortedTotalScores.Length] = 100f; for (int i = 1; i < sortedTotalScores.Length; ++i) { animationSpeedSlowdownDomain[i] = i * (100f / sortedTotalScores.Length); animationSpeedSlowdownImage[i] = (float)(sortedTotalScores[i + sortedTotalScores.Length - animationSpeedSlowdownDomain.Length] * 100m / maxScore); } if (!maxScoreTie) { animationSpeedSlowdownDomain[sortedTotalScores.Length - 1] = 98f; } colorsCategories = new Color[expectedNumberOfCategories]; brushesCategories = new Brush[expectedNumberOfCategories--]; for (int i = expectedNumberOfCategories; i >= 0; --i) { colorsCategories[i] = Color.FromArgb(255, 150 - (i * 100 / expectedNumberOfCategories), 0); brushesCategories[i] = new SolidBrush(colorsCategories[i]); } // category name rects categoryNamesPos = new RectangleF[categories.Length]; float height = categoryNamesHeight / categories.Length; for (int i = 0; i < categories.Length; ++i) { categoryNamesPos[i] = new RectangleF( categoryNamesLeft, categoryNamesBottom - (i + 1) * height, categoryNamesWidth, height); } #if VISUALIZE_ANIMATION_SPEED RenderAnimationSpeed(); #else renderThread = new Thread(new ThreadStart(RenderThreadLoop)); renderThread.Start(); #endif Invalidate(); }