/// <summary> /// Generate a frame (card-like button) for the UI based on a QuizInfo /// </summary> /// <param name="quizInfo">QuizInfo of the quiz to generate a frame for</param> /// <returns></returns> private Frame GenerateFrame(QuizInfo quizInfo) { Frame frame = new Frame() { VerticalOptions = LayoutOptions.Start, HorizontalOptions = LayoutOptions.FillAndExpand, CornerRadius = 10 }; StackLayout frameStack = new StackLayout // 1st Child of frameLayout { FlowDirection = FlowDirection.LeftToRight, Orientation = StackOrientation.Vertical, Padding = 10 }; StackLayout topStack = new StackLayout { FlowDirection = FlowDirection.LeftToRight, Orientation = StackOrientation.Horizontal, VerticalOptions = LayoutOptions.StartAndExpand, HorizontalOptions = LayoutOptions.FillAndExpand }; Label title = new Label // 0 { Text = quizInfo.QuizName, FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)), FontAttributes = FontAttributes.Bold, VerticalOptions = LayoutOptions.StartAndExpand, HorizontalOptions = LayoutOptions.FillAndExpand //, //HeightRequest = 45 }; topStack.Children.Add(title); // Add the sync buttons, We create one for each sync action to keep correct formatting and fix a sizing bug. ImageButton SyncOffline = new ImageButton // 1 { IsVisible = false, Source = "ic_cloud_off_black_48dp.png", HeightRequest = 25, WidthRequest = 25, BackgroundColor = Color.White, VerticalOptions = LayoutOptions.StartAndExpand, HorizontalOptions = LayoutOptions.End, ClassId = quizInfo.DBId, StyleId = quizInfo.Category }; SyncOffline.Clicked += this.SyncOffline_Clicked; topStack.Children.Add(SyncOffline); ImageButton SyncUpload = new ImageButton // 2 { IsVisible = false, Source = "ic_cloud_upload_black_48dp.png", HeightRequest = 25, WidthRequest = 25, BackgroundColor = Color.White, VerticalOptions = LayoutOptions.StartAndExpand, HorizontalOptions = LayoutOptions.End, ClassId = quizInfo.DBId, StyleId = quizInfo.Category }; SyncUpload.Clicked += this.SyncUpload_Clicked; topStack.Children.Add(SyncUpload); ImageButton SyncDownload = new ImageButton // 3 { IsVisible = false, Source = "ic_cloud_download_black_48dp.png", HeightRequest = 25, WidthRequest = 25, BackgroundColor = Color.White, VerticalOptions = LayoutOptions.StartAndExpand, HorizontalOptions = LayoutOptions.End, ClassId = quizInfo.DBId, StyleId = quizInfo.Category }; SyncDownload.Clicked += this.SyncDownload_Clicked; topStack.Children.Add(SyncDownload); ImageButton SyncNoChange = new ImageButton // 4 { IsVisible = false, Source = "ic_cloud_done_black_48dp.png", HeightRequest = 25, WidthRequest = 25, BackgroundColor = Color.White, VerticalOptions = LayoutOptions.StartAndExpand, HorizontalOptions = LayoutOptions.End, ClassId = quizInfo.DBId, StyleId = quizInfo.Category }; SyncNoChange.Clicked += this.SyncNoChange_Clicked; topStack.Children.Add(SyncNoChange); ActivityIndicator Syncing = new ActivityIndicator // 5 { IsVisible = false, Color = Color.Accent, HeightRequest = 25, WidthRequest = 25, VerticalOptions = LayoutOptions.StartAndExpand, HorizontalOptions = LayoutOptions.End, }; topStack.Children.Add(Syncing); ImageButton imageButtonMenu = new ImageButton // 6 { Source = "ic_more_vert_black_48dp.png", HeightRequest = 35, WidthRequest = 35, BackgroundColor = Color.White, VerticalOptions = LayoutOptions.StartAndExpand, HorizontalOptions = LayoutOptions.End, ClassId = quizInfo.DBId }; imageButtonMenu.Clicked += this.ImageButtonMenu_Clicked; topStack.Children.Add(imageButtonMenu); if (CredentialManager.Username == quizInfo.AuthorName) { imageButtonMenu.StyleId = "Delete"; } else { imageButtonMenu.StyleId = "Unsubscribe"; } frameStack.Children.Add(topStack); BoxView Seperator = new BoxView // 1 { Color = Color.LightGray, CornerRadius = 1, HeightRequest = 2, WidthRequest = Application.Current.MainPage.Width - 75, HorizontalOptions = LayoutOptions.CenterAndExpand, VerticalOptions = LayoutOptions.CenterAndExpand }; frameStack.Children.Add(Seperator); Label Author = new Label // 2 { Text = "Created by: " + quizInfo.AuthorName, FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)), VerticalOptions = LayoutOptions.End, HorizontalOptions = LayoutOptions.StartAndExpand }; frameStack.Children.Add(Author); // The sync button thats active in the current frame ImageButton activeSync; if (quizInfo.SyncStatus == (int)SyncStatusEnum.Offline) // SyncOffline { SyncOffline.IsVisible = true; activeSync = SyncOffline; } else if (quizInfo.SyncStatus == (int)SyncStatusEnum.Synced) // SyncNoChange { SyncNoChange.IsVisible = true; activeSync = SyncNoChange; } else if (quizInfo.SyncStatus == (int)SyncStatusEnum.NeedUpload && quizInfo.AuthorName == CredentialManager.Username) // SyncUpload { SyncUpload.IsVisible = true; activeSync = SyncUpload; } else if (quizInfo.SyncStatus == (int)SyncStatusEnum.NeedDownload || quizInfo.SyncStatus == (int)SyncStatusEnum.NotDownloadedAndNeedDownload) // SyncDownload { SyncDownload.IsVisible = true; activeSync = SyncDownload; if (quizInfo.SyncStatus == (int)SyncStatusEnum.NotDownloadedAndNeedDownload) // Sync Download & notLocal yet { frame.StyleId = "notLocal"; } } else { SyncOffline.IsVisible = true; activeSync = SyncOffline; } TapGestureRecognizer recognizer = new TapGestureRecognizer(); recognizer.Tapped += async(object sender, EventArgs e) => { if (frame.StyleId != "notLocal") { frame.GestureRecognizers.Remove(recognizer); frame.BackgroundColor = Color.LightGray; Seperator.Color = Color.Gray; imageButtonMenu.BackgroundColor = Color.LightGray; activeSync.BackgroundColor = Color.LightGray; // Load the quiz associated with this DBId Quiz newQuiz = new Quiz(quizInfo.DBId); //await this.RemoveMenu(frameMenu); await this.Navigation.PushAsync(new Game(newQuiz)); frame.BackgroundColor = Color.Default; Seperator.Color = Color.LightGray; imageButtonMenu.BackgroundColor = Color.White; activeSync.BackgroundColor = Color.White; frame.GestureRecognizers.Add(recognizer); } else { await this.DisplayAlert("Hold on!", "In order to study with this quiz, you must download it first", "OK"); } }; frame.GestureRecognizers.Add(recognizer); frame.Content = frameStack; return(frame); }
/// <summary> /// Saves the user created quiz /// </summary> /// <param name="sender"> </param> /// <param name="e"> </param> private async void ButtonCreateQuiz_Clicked(object sender, EventArgs e) { this.Done.IsEnabled = false; if (string.IsNullOrWhiteSpace(this.EditorQuizName.Text)) { await this.DisplayAlert("Couldn't Create Quiz", "Please give your quiz a name.", "OK"); } else if (this.StackLayoutQuestionStack.Children.Count < 2) { await this.DisplayAlert("Couldn't Create Quiz", "Please create at least two questions", "OK"); } else if (this.PickerCategory.SelectedIndex == -1) { await this.DisplayAlert("Couldn't Create Quiz", "Please give your quiz a category", "OK"); } else { List <Question> previousQuestions = new List <Question>(); List <Question> NewQuestions = new List <Question>(); // A list of questions the user wants to add to the database // Loops through each question frame on the screen foreach (Frame frame in this.StackLayoutQuestionStack.Children) { // A list of all the children of the current frame IList <View> children = ((StackLayout)frame.Content).Children; Question addThis; //The answers to the question string[] answers = { ((Editor)children[2]).Text?.Trim(), //Correct answer ((Editor)children[3]).Text?.Trim(), // Incorect answer ((Editor)children[4]).Text?.Trim(), // Incorect answer ((Editor)children[5]).Text?.Trim() }; // Incorect answer // Checks if there is a question set if (string.IsNullOrWhiteSpace(((Editor)children[1]).Text)) { await this.DisplayAlert("Couldn't Create Quiz", "Every question must have a question set", "OK"); goto exit; } if (((ImageButton)children[6]).IsVisible) // if the question needs an image { addThis = new Question( ((Editor)children[1]).Text?.Trim(), // The Question ((ImageButton)children[6]).Source.ToString().Substring(6), // adds image using the image source answers) { NeedsPicture = true }; } else // if the question does not need an image { addThis = new Question( ((Editor)children[1]).Text?.Trim(), answers); } string questionType = ((Button)((StackLayout)children[0]).Children[0]).Text; // Sets the question type if (questionType == "Question Type: Multiple choice") { int size = 0; foreach (string answer in answers) { if (!string.IsNullOrWhiteSpace(answer)) { size++; } } if (size < 2 || string.IsNullOrWhiteSpace(answers[0])) { await this.DisplayAlert("Couldn't Create Quiz", "Mulitple choice questions must have a correct answer and at least one wrong answer", "OK"); goto exit; } addThis.QuestionType = 0; } else { if (string.IsNullOrWhiteSpace(answers[0])) { await this.DisplayAlert("Couldn't Create Quiz", "Text answer questions must have an answer", "OK"); goto exit; } if (questionType == "Question Type: Text answer") { addThis.QuestionType = 1; } else { addThis.QuestionType = 2; } } addThis.QuestionId = frame.StyleId; // Set the questionId NewQuestions.Add(addThis); } Quiz database; // If editing their own quiz if (this.originalQuizInfo != null && this.originalAuthor == CredentialManager.Username) { database = new Quiz(this.originalQuizInfo.DBId); // Set previousQuestions to the correct previous questions previousQuestions = database.GetQuestions(); } else // If new quiz { database = new Quiz( CredentialManager.Username, this.EditorQuizName.Text.Trim(), this.PickerCategory.Items[this.PickerCategory.SelectedIndex]); } // Add if it doesn't already exist, delete if it doesn't exist anymore, update the ones that need to be updated, and do nothing to the others if (previousQuestions.Count == 0 || originalAuthor != CredentialManager.Username) { // if the user created this for the first time // Save a new QuizInfo into the quiz database, which also adds this QuizInfo to the device quiz roster database.AddQuestions(NewQuestions.ToArray()); } else // edit { string currentDirectory = database.DBFolderPath; QuizInfo updatedQuizInfo = new QuizInfo(database.QuizInfo) { QuizName = this.EditorQuizName.Text?.Trim(), LastModifiedDate = DateTime.Now.ToString(), Category = this.PickerCategory.Items[this.PickerCategory.SelectedIndex] }; database.EditQuizInfo(updatedQuizInfo); if (currentDirectory != updatedQuizInfo.RelativePath) { Directory.CreateDirectory(updatedQuizInfo.RelativePath); Directory.Delete(updatedQuizInfo.RelativePath, true); Directory.Move(currentDirectory, updatedQuizInfo.RelativePath); } // Logic for how to save each question. for (int i = 0; i <= previousQuestions.Count() - 1; i++) { bool DBIdSame = true; // test each old question with each new question foreach (Question newQuestion in NewQuestions) { if (previousQuestions[i].QuestionId == newQuestion.QuestionId) { DBIdSame = true; // the same question, but changed, so update database.EditQuestion(newQuestion); NewQuestions.Remove(newQuestion); break; } else { DBIdSame = false; } } if (!DBIdSame) // if the question doesn't exist in the new list. delete it { database.DeleteQuestions(previousQuestions[i]); } } // Add all the questions that aren't eddited database.AddQuestions(NewQuestions.ToArray()); } File.Create(database.DBFolderPath + ".nomedia"); // Returns user to front page of QuizEditor and refreshed database await this.Navigation.PopAsync(true); } exit :; this.Done.IsEnabled = true; }