Exemple #1
0
 /// <summary>
 ///     Adds a new class to the database using manual params
 /// </summary>
 /// <param name="name">Class name</param>
 /// <param name="days">Days the class meets</param>
 /// <param name="professor">Professor</param>
 /// <param name="room">Room number</param>
 /// <param name="time">Time the class meets</param>
 /// <remarks>If possible, add the class with the overload that takes a Class object</remarks>
 public static void AddClass(string name, string days, string professor, string room, string time)
 {
     using (SQLiteConnection db = new SQLiteConnection(new SQLitePlatformWinRT(), DbPath))
     {
         Class c = new Class
         {
             Name = name,
             Days = days,
             Professor = professor,
             Room = room,
             Time = time
         };
         db.Insert(c);
     }
 }
Exemple #2
0
 /// <summary>
 ///     Adds a new class to the database with object param
 /// </summary>
 /// <param name="c">Class object to add</param>
 public static void AddClass(Class c)
 {
     using (SQLiteConnection db = new SQLiteConnection(new SQLitePlatformWinRT(), DbPath))
     {
         db.Insert(c);
     }
 }
        /// <summary>
        ///     Creates the item that adds new tasks
        /// </summary>
        /// <param name="c">Class to add it to</param>
        /// <param name="class">Listview to add it to</param>
        public static void AddCreateButton(Class c, ListView @class)
        {
            #region Containers

            // Main ListViewItem
            ListViewItem create = new ListViewItem
            {
                Height = 30,
                Background = MainPage.TransparentBrush,
                Tag = false,
                HorizontalContentAlignment = HorizontalAlignment.Stretch,
                VerticalContentAlignment = VerticalAlignment.Top,
                Padding = new Thickness(0),
                BorderBrush = MainPage.MediumGrayBrush,
                BorderThickness = new Thickness(0)
            };

            // Item contents
            Grid content = new Grid
            {
                Background = MainPage.LightGrayBrush,
                Margin = new Thickness(0),
                HorizontalAlignment = HorizontalAlignment.Stretch,
                VerticalAlignment = VerticalAlignment.Stretch,
                Tag = true
            };

            #endregion

            #region Buttons

            // '+' button
            Button expand = new Button
            {
                FontFamily = Icons.IconFont,
                Content = Icons.Add,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Top,
                Margin = new Thickness(0, 7.5, 0, 0),
                Visibility = Visibility.Visible
            };

            // 'x' button
            Button collapse = new Button
            {
                FontFamily = Icons.IconFont,
                Content = Icons.Cancel,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Top,
                Margin = new Thickness(0, 7.5, 40, 0),
                Visibility = Visibility.Collapsed
            };

            // Check mark button
            Button confirm = new Button
            {
                FontFamily = Icons.IconFont,
                Content = Icons.Accept,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Top,
                Margin = new Thickness(40, 7.5, 0, 0),
                Visibility = Visibility.Collapsed
            };

            #endregion

            #region TitleBox

            TextBox title = new TextBox
            {
                Height = 25,
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Top,
                Margin = new Thickness(5, 45, 0, 0),
                Text = "Title"
            };
            title.GotFocus += (sender, args) =>
            {
                if (title.Text == "Title")
                {
                    title.Text = string.Empty;
                }
            };
            title.LostFocus += (sender, args) =>
            {
                if (title.Text == string.Empty)
                {
                    title.Text = "Title";
                }
            };

            #endregion TitleBox

            #region InfoBox

            TextBox info = new TextBox
            {
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Stretch,
                Margin = new Thickness(5, 80, 0, 5),
                AcceptsReturn = true,
                TextWrapping = TextWrapping.Wrap,
                Text = "Info"
            };
            info.GotFocus += (sender, args) =>
            {
                if (info.Text == "Info")
                {
                    info.Text = string.Empty;
                }
            };
            info.LostFocus += (sender, args) =>
            {
                if (info.Text == string.Empty)
                {
                    info.Text = "Info";
                }
            };

            #endregion

            #region Date and Time

            CalendarDatePicker startCalendar = new CalendarDatePicker
            {
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Top,
                Background = MainPage.MediumGrayBrush,
                BorderBrush = MainPage.TransparentBrush,
                Margin = new Thickness(5, 45, 5, 5),
                PlaceholderText = "Select Start Date",
                Date = DateTime.Today
            };

            TimePicker startTime = new TimePicker
            {
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Top,
                Background = MainPage.MediumGrayBrush,
                BorderBrush = MainPage.TransparentBrush,
                Margin = new Thickness(5, 80, 5, 5),
                MinWidth = 30
            };

            CalendarDatePicker endCalendar = new CalendarDatePicker
            {
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Top,
                Background = MainPage.MediumGrayBrush,
                BorderBrush = MainPage.TransparentBrush,
                Margin = new Thickness(5, 130, 5, 5),
                PlaceholderText = "Select End Date"
            };

            TimePicker endTime = new TimePicker
            {
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Top,
                Background = MainPage.MediumGrayBrush,
                BorderBrush = MainPage.TransparentBrush,
                Margin = new Thickness(5, 165, 5, 5),
                MinWidth = 30,
                Time = TimeSpan.Parse(c.Time)
            };

            endCalendar.CalendarViewDayItemChanging += (sender, args) =>
            {
                DateTimeOffset? startDate = startCalendar.Date;
                if (args.Item?.Date < startDate)
                {
                    args.Item.IsBlackout = true;
                }
            };
            endCalendar.DateChanged += (sender, args) =>
            {
                if (args.NewDate == null)
                {
                    return;
                }
                if (endCalendar.Date.Value.Date != startCalendar.Date.Value.Date)
                {
                }
            };

            #endregion

            #region Progress Bar Preview

            Grid progressGrid = new Grid
            {
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Top,
                Margin = new Thickness(5, 208, 5, 5),
                Height = 80
            };

            CircularProgressBar progressBack = new CircularProgressBar
            {
                Percentage = 100,
                SegmentColor = MainPage.MediumGrayBrush,
                Radius = 30,
                StrokeThickness = 5,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };

            CircularProgressBar progressFront = new CircularProgressBar
            {
                Percentage = 0,
                SegmentColor = MainPage.BlueBrush,
                Radius = 30,
                StrokeThickness = 5,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                Margin = progressBack.Margin,
                Transitions = new TransitionCollection()
            };

            TextBlock timeLeft = new TextBlock
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                Text = "--",
                FontSize = 12,
                Foreground = MainPage.BlueBrush,
                TextAlignment = TextAlignment.Center
            };

            Border border = new Border
            {
                BorderBrush = MainPage.BlueBrush,
                BorderThickness = new Thickness(0),
                Child = timeLeft,
                Height = 70,
                Width = 70,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                Margin = progressFront.Margin
            };
            progressGrid.Children.Add(progressBack);
            progressGrid.Children.Add(progressFront);
            progressGrid.Children.Add(border);

            Action updateProgress = () =>
            {
                DateTimeOffset? sDate = startCalendar.Date;
                TimeSpan sTime = startTime.Time;
                DateTimeOffset? eDate = endCalendar.Date;
                TimeSpan eTime = endTime.Time;
                if (sDate == null || eDate == null)
                {
                    timeLeft.Text = "--";
                    return;
                }
                DateTime sDt = new DateTime(
                    sDate.Value.Year, sDate.Value.Month, sDate.Value.Day,
                    sTime.Hours, sTime.Minutes, sTime.Seconds
                    );
                DateTime eDt = new DateTime(
                    eDate.Value.Year, eDate.Value.Month, eDate.Value.Day,
                    eTime.Hours, eTime.Minutes, eTime.Seconds
                    );
                progressFront.Percentage = Math.Min(Util.GetPercentTime(sDt, eDt) * 100, 100);
                bool finished;
                if (progressFront.Percentage.Equals(100.0))
                {
                    finished = true;
                    progressFront.SegmentColor = MainPage.OrangeRedBrush;
                    timeLeft.Foreground = MainPage.OrangeRedBrush;
                } else
                {
                    finished = false;
                    progressFront.SegmentColor = MainPage.BlueBrush;
                    timeLeft.Foreground = MainPage.BlueBrush;
                }
                timeLeft.Text = $"{Util.GetTimeString(eDt, finished)}{(finished ? " ago" : string.Empty)}";
            };
            updateProgress();

            ThreadPoolTimer.CreatePeriodicTimer(
                async poolTimer =>
                {
                    await progressFront.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { updateProgress(); });
                },
                new TimeSpan(0, 0, 0, 1));

            #endregion

            #region Sizing and Contents

            // Resize controls when the parent container is resized
            create.SizeChanged += (sender, args) =>
            {
                double width = args.NewSize.Width / 2 - 7.5;
                content.Height = args.NewSize.Height;
                title.Width = width;
                info.Width = width;
                startCalendar.Width = width;
                endCalendar.Width = width;
                startTime.Width = width;
                endTime.Width = width;
                progressGrid.Width = width;
            };

            // Add the elemetns to the content grid
            content.Children.Add(expand);
            content.Children.Add(collapse);
            content.Children.Add(confirm);
            content.Children.Add(title);
            content.Children.Add(info);
            content.Children.Add(startCalendar);
            content.Children.Add(startTime);
            content.Children.Add(endCalendar);
            content.Children.Add(endTime);
            content.Children.Add(progressGrid);

            // Set the contents of the item
            create.Content = content;

            #endregion

            #region Interactions and Animations

            // Handles expanding of the item when the '+' button is pressed
            expand.Tapped += (sender, args) =>
            {
                startTime.Time = DateTime.Now.TimeOfDay;
                const int to = 300; // Expands to 300px tall
                Storyboard anim = Util.CreateAnimation(150, expand, 1, 0, "Opacity");
                anim.Completed += (o, o1) =>
                {
                    expand.Visibility = Visibility.Collapsed;
                    collapse.Opacity = 0;
                    confirm.Opacity = 0;
                    collapse.Visibility = Visibility.Visible;
                    confirm.Visibility = Visibility.Visible;
                    Util.CreateAnimation(300, collapse, 0, 1, "Opacity").Begin();
                    Util.CreateAnimation(300, confirm, 0, 1, "Opacity").Begin();
                };
                anim.Begin();
                Util.CreateAnimation(150, create, null, to, "Height").Begin();
                create.Tag = true;
            };

            // This runs when the user cancels the new task
            Action collapseAction = () =>
            {
                const int to = 40;
                Storyboard anim = Util.CreateAnimation(150, collapse, 1, 0, "Opacity");
                Storyboard anim2 = Util.CreateAnimation(150, confirm, 1, 0, "Opacity");
                anim.Completed += (o, o1) =>
                {
                    collapse.Visibility = Visibility.Collapsed;
                    confirm.Visibility = Visibility.Collapsed;
                    expand.Opacity = 0;
                    expand.Visibility = Visibility.Visible;
                    Util.CreateAnimation(300, expand, 0, 1, "Opacity").Begin();
                };
                anim.Begin();
                anim2.Begin();
                Util.CreateAnimation(150, create, null, to, "Height").Begin();
                create.Tag = false; // Signifies that the panel is now closed

                // Reset control data
                endCalendar.Date = null;
                endTime.Time = TimeSpan.Parse(c.Time);
                startCalendar.Date = DateTime.Today;
                startTime.Time = DateTime.Now.TimeOfDay;
                title.Text = "Title";
                info.Text = "Info";
            };

            // "Are you sure" message when the user presses the cancel button
            collapse.Tapped += async (sender, args) =>
            {
                bool reallyDelete = false;
                MessageDialog popup =
                    new MessageDialog("Are you sure you want to delete the unfinished task? Your changes will be lost.");
                popup.Commands.Insert(0, new UICommand("Yes"));
                popup.Commands.Insert(1, new UICommand("No", command => { reallyDelete = true; }));
                await popup.ShowAsync();
                if (reallyDelete)
                {
                    return;
                }
                collapseAction();
            };

            // Adds the new task when the user accepts
            confirm.Tapped += async (sender, args) =>
            {
                // Make sure title is valid
                if (title.Text.EqualsAny(string.Empty, "Title"))
                {
                    MessageDialog popup = new MessageDialog("Enter a valid title.");
                    popup.Commands.Insert(0, new UICommand("OK"));
                    await popup.ShowAsync();
                    return;
                }

                // Create new task object and populate title and info
                Task newTask = new Task();
                newTask.Title = title.Text.Trim();
                newTask.Info = info.Text;

                // Get date/time info
                DateTimeOffset? sDate = startCalendar.Date;
                TimeSpan sTime = startTime.Time;
                DateTimeOffset? eDate = endCalendar.Date;
                TimeSpan eTime = endTime.Time;

                // Check to make sure the date/time info is correct
                if (sDate == null || eDate == null || eDate < sDate)
                {
                    MessageDialog popup = new MessageDialog("Invalid date/time selection.");
                    popup.Commands.Insert(0, new UICommand("OK"));
                    await popup.ShowAsync();
                    return;
                }

                // Get assigned on and due on dates/times
                DateTime assignedOn = new DateTime(
                    sDate.Value.Year, sDate.Value.Month, sDate.Value.Day,
                    sTime.Hours, sTime.Minutes, sTime.Seconds
                    );
                DateTime dueOn = new DateTime(
                    eDate.Value.Year, eDate.Value.Month, eDate.Value.Day,
                    eTime.Hours, eTime.Minutes, eTime.Seconds
                    );

                // Check to make sure the due date is after the assigned date
                if (dueOn < assignedOn)
                {
                    MessageDialog popup = new MessageDialog("Invalid date/time selection.");
                    popup.Commands.Insert(0, new UICommand("OK"));
                    await popup.ShowAsync();
                    return;
                }

                // Add info to the task object
                newTask.AssignedOn = assignedOn.ToString();
                newTask.DueOn = dueOn.ToString();
                newTask.ClassId = c.Id;
                collapseAction();

                // Close the new panel
                expand.Visibility = Visibility.Visible;
                collapse.Visibility = Visibility.Collapsed;
                confirm.Visibility = Visibility.Collapsed;
                Util.CreateAnimation(300, create, null, 40, "Height").Begin();
                TaskList.AddTask(c, @class, newTask, true);
                long newId = DataHandler.AddTask(newTask);
                Notifications.ScheduleTaskReminders(dueOn, c.Name, newTask.Title, newId);

                create.Tag = false; // Signifies that the panel is closed

                // Reset control data
                endCalendar.Date = null;
                endTime.Time = TimeSpan.Parse(c.Time.ToString());
                startCalendar.Date = DateTime.Today;
                startTime.Time = DateTime.Now.TimeOfDay;
                title.Text = "Title";
                info.Text = "Info";
            };

            // Add the new task
            @class.Items?.Add(create);

            #endregion
        }
        /// <summary>
        ///     Generates a new task panel
        /// </summary>
        /// <param name="cl">Class to generate it for</param>
        /// <param name="parent">ListView associated with the class</param>
        /// <param name="task">Task to add</param>
        /// <returns>A new ListViewItem for the task</returns>
        public static ListViewItem GenerateTaskPanel(Class cl, ListView parent, Task task)
        {
            #region Containers

            // Create the content area
            Grid content = new Grid
            {
                Margin = new Thickness(0),
                Height = 75,
                Background = MainPage.LightGrayBrush,
                Tag = "Task"
            };

            // Create the list of content items and a delegate to add them to the list
            List<UIElement> contentItems = new List<UIElement>();
            Action<UIElement> registerItem = i => { contentItems.Add(i); };

            // The main ListViewItem
            ListViewItem panel = new ListViewItem
            {
                Background = MainPage.TransparentBrush,
                Margin = new Thickness(0, 0, 0, 5),
                Height = 75,
                Tag = false, // Is Panel Expanded
                HorizontalContentAlignment = HorizontalAlignment.Stretch,
                VerticalContentAlignment = VerticalAlignment.Top,
                Padding = new Thickness(0),
                BorderBrush = MainPage.MediumGrayBrush,
                BorderThickness = new Thickness(1),
            };

            #endregion

            #region Title

            // Task title
            TextBlock title = new TextBlock
            {
                Text = task.Title.Trim(),
                TextAlignment = TextAlignment.Left,
                FontSize = 25,
                Foreground = MainPage.BlueBrush,
                Margin = new Thickness(5, 0, 0, 0)
            };
            // Sizing
            title.Measure(new Size(0, 0));
            title.Arrange(new Rect(0, 0, 0, 0));
            registerItem(title);

            #endregion

            #region Finish Button

            // The check mark that marks the task as completed
            Button finish = new Button
            {
                FontFamily = Icons.IconFont,
                Content = task.Complete == 1 ? Icons.Cancel : Icons.Accept,
                Margin = new Thickness(title.ActualWidth + 5, 5, 0, 0),
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Top,
                Background = MainPage.TransparentBrush
            };

            // Remove the task when the button is pressed
            finish.Tapped += (sender, args) => { TaskList.RemoveTask(cl, parent, panel, task); };
            registerItem(finish);

            #endregion

            #region Info Box

            // Info box
            TextBox info = new TextBox
            {
                TextAlignment = TextAlignment.Left,
                Foreground = new SolidColorBrush(Color.FromArgb(255, 50, 50, 50)),
                HorizontalAlignment = HorizontalAlignment.Left,
                TextWrapping = TextWrapping.Wrap,
                BorderThickness = new Thickness(0),
                AcceptsReturn = true,
                Width = parent.Width / 3 + 25,
                Tag = false, // Edit mode
                IsReadOnly = true, // Edit mode property
                Background = MainPage.TransparentBrush, // Edit mode property
                IsHitTestVisible = false // Edit mode property
            };

            // Add the text - only works if you append each character
            foreach (char c in task.Info)
            {
                info.Text += c.ToString();
            }

            // Border around the info box
            Border infoBorder = new Border
            {
                Child = info,
                Background = MainPage.MediumGrayBrush,
                Margin = new Thickness(5, 36, 0, 7),
                HorizontalAlignment = HorizontalAlignment.Left,
                BorderThickness = new Thickness(0),
                Padding = new Thickness(0)
            };
            registerItem(infoBorder);

            // Edit button for the info box
            Button edit = new Button
            {
                FontFamily = Icons.IconFont,
                Content = Icons.Edit,
                Width = 20,
                Height = 20,
                FontSize = 10,
                Padding = new Thickness(0),
                Background = MainPage.TransparentBrush,
                VerticalAlignment = VerticalAlignment.Bottom,
                HorizontalAlignment = HorizontalAlignment.Left,
                Margin = new Thickness(parent.Width / 3 + 10, 36, 0, 7)
            };

            // Toggles edit mode for the info box
            edit.Click += (sender, args) =>
            {
                if (!(bool) info.Tag)
                {
                    info.Tag = true;
                    edit.Content = Icons.Save;
                    info.IsReadOnly = false;
                    info.Background = new SolidColorBrush(Colors.White);
                    info.IsHitTestVisible = true;
                    info.Focus(FocusState.Pointer);
                    info.SelectionStart = info.Text.Length;
                    info.SelectionLength = 0;
                } else
                {
                    info.Tag = false;
                    edit.Content = Icons.Edit;
                    info.IsReadOnly = true;
                    info.Background = MainPage.MediumGrayBrush;
                    info.IsHitTestVisible = false;
                    DataHandler.EditTask(task.Id, "Info", info.Text);
                }
            };
            registerItem(edit);

            #endregion

            #region Circular Progress Bar

            // Progress bar background (gray)
            CircularProgressBar progressBack = new CircularProgressBar
            {
                Percentage = 100,
                SegmentColor = MainPage.MediumGrayBrush,
                Radius = 30,
                StrokeThickness = 5,
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Top,
                Margin = new Thickness(0, 2.75, 2.75 + 30, 0)
            };
            registerItem(progressBack);

            // Progress bar foreground (blue)
            CircularProgressBar progressFront = new CircularProgressBar
            {
                Percentage = 0,
                SegmentColor = MainPage.BlueBrush,
                Radius = 30,
                StrokeThickness = 5,
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Top,
                Margin = new Thickness(0, 2.75, 2.75 + 30, 0),
                Transitions = new TransitionCollection()
            };
            registerItem(progressFront);

            // Text inside the progress bar that shows the time remaining
            TextBlock timeLeft = new TextBlock
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                Text = string.Empty,
                FontSize = 12,
                Foreground = MainPage.BlueBrush,
                TextAlignment = TextAlignment.Center
            };

            // Helps with alignment for the progress bar
            Border border = new Border
            {
                BorderBrush = MainPage.BlueBrush,
                BorderThickness = new Thickness(0),
                Child = timeLeft,
                Height = 70,
                Width = 70,
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Top,
                Margin = progressFront.Margin
            };
            registerItem(border);

            // Delegate for
            Action updateProgress = () =>
            {
                // Clamp the progress to 100%
                progressFront.Percentage = Math.Min(Util.GetPercentTime(task) * 100, 100);

                // Finished tasks get an orange color
                bool finished = false;
                if (progressFront.Percentage.Equals(100.0))
                {
                    finished = true;
                    progressFront.SegmentColor = MainPage.OrangeRedBrush;
                    timeLeft.Foreground = MainPage.OrangeRedBrush;
                }

                // Set the new text
                timeLeft.Text = $"{Util.GetTimeString(task)}{(finished ? " ago" : string.Empty)}";
            };
            updateProgress();

            // Update the progress every second
            ThreadPoolTimer.CreatePeriodicTimer(
                async poolTimer =>
                {
                    await progressFront.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { updateProgress(); });
                },
                new TimeSpan(0, 0, 0, 1));

            #endregion

            #region Assigned/Due Times

            // Assigned/due info
            RichTextBlock timeInfo = new RichTextBlock
            {
                FontSize = 14,
                Margin = new Thickness(-5),
                TextAlignment = TextAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Stretch,
                TextWrapping = TextWrapping.NoWrap
            };

            // "Assigned on" and "Due on" text
            // Separated with different colors
            Run assignedText = new Run
            {
                Text = "Assigned: ",
                Foreground = MainPage.BlueBrush
            };

            Run assignedDate = new Run
            {
                Text = $"{task.AssignedOn}",
                Foreground = MainPage.GreenBrush
            };

            Run dueText = new Run
            {
                Text = "Due: ",
                Foreground = MainPage.BlueBrush
            };

            Run dueDate = new Run
            {
                Text = $"{task.DueOn}",
                Foreground = MainPage.OrangeRedBrush
            };

            // Set up lines
            Paragraph p1 = new Paragraph();
            p1.Inlines.Add(assignedText);
            p1.Inlines.Add(assignedDate);

            Paragraph p2 = new Paragraph();
            p2.Inlines.Add(dueText);
            p2.Inlines.Add(dueDate);

            // Add the info to the text box
            timeInfo.Blocks.Add(p1);
            timeInfo.Blocks.Add(p2);

            // Container for time info
            Border timeInfoBorder = new Border
            {
                Child = timeInfo,
                BorderBrush = MainPage.BlueBrush,
                BorderThickness = new Thickness(0),
                Margin = new Thickness(parent.Width / 3 + 35, 36, 105, 5),
                Padding = new Thickness(0),
                VerticalAlignment = VerticalAlignment.Stretch
            };
            registerItem(timeInfoBorder);

            #endregion

            #region Expand Button

            // Button that expands the box
            Button expand = new Button
            {
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Top,
                Height = 73,
                Width = 25,
                Margin = new Thickness(0, 0, 0, 0),
                Content = Icons.Down,
                FontFamily = Icons.IconFont,
                Padding = new Thickness(0)
            };

            // This makes sure all other task panels collapse smoothly if a new one is opened
            expand.Tapped += (sender, args) =>
            {
                // Get the new height based on the tag that tells you if the panel is open or closed
                int to = !(bool) panel.Tag ? 412 : 75;

                // Set the new button content to the opposite arrow
                expand.Content = !(bool) panel.Tag ? Icons.Up : Icons.Down;

                // If the panel is not opened
                if (!(bool) panel.Tag)
                {
                    // For each task that is open and has content
                    foreach (ListViewItem item in parent.Items.Cast<ListViewItem>()
                        .Where(item => (bool?) item.Tag ?? false && item.Content != null))
                    {
                        // If the grid content is not null and the grid tag is not null
                        if (!((item.Content as Grid)?.Tag as bool? ?? false))
                        {
                            // Find the button in the grid that has the Up icon
                            foreach (Button btn in (item.Content as Grid).Children.OfType<Button>()
                                .Where(btn => (string) btn.Content == Icons.Up))
                            {
                                // ... And change it to the down icon
                                btn.Content = Icons.Down;
                            }

                            // Collapse the panel
                            Util.CreateAnimation(150, item, null, 75, "Height").Begin();

                            // Set the tag to false indicating the panel is closed
                            item.Tag = false;
                        }
                    }
                }

                // Once all other panels have been collapsed, expand the new one
                Util.CreateAnimation(150, panel, null, to, "Height").Begin();

                // Set its tag appropriately
                panel.Tag = !(bool) panel.Tag;
            };

            registerItem(expand);

            #endregion

            #region Calendar

            // Calendar showing date assigned, date due, today
            CalendarView calendar = new CalendarView
            {
                HorizontalAlignment = HorizontalAlignment.Stretch,
                VerticalAlignment = VerticalAlignment.Top,
                SelectionMode = CalendarViewSelectionMode.None,
                BlackoutForeground = new SolidColorBrush(Colors.White),
                Background = MainPage.MediumGrayBrush,
                CalendarItemBackground = MainPage.TransparentBrush,
                BorderBrush = MainPage.TransparentBrush,
                CalendarItemBorderBrush = MainPage.TransparentBrush,
                OutOfScopeBackground = MainPage.TransparentBrush,
                OutOfScopeForeground = new SolidColorBrush(Colors.Gray),
                Margin = new Thickness(parent.Width / 3 + 35, 75, 3, 5),
            };

            // Override item rendering to change colors
            calendar.CalendarViewDayItemChanging += (sender, args) =>
            {
                if (args.Item == null)
                {
                    return;
                }
                DateTime day = args.Item.Date.DateTime;
                if (day.Date == DateTime.Parse(task.AssignedOn.ToString()).Date)
                {
                    args.Item.Background = MainPage.GreenBrush;
                    args.Item.IsBlackout = true; // Hack to change the foreground color
                } else if (day.Date == DateTime.Parse(task.DueOn.ToString()).Date)
                {
                    args.Item.Background = MainPage.OrangeRedBrush;
                    args.Item.IsBlackout = true;
                }
                if (day.Date == DateTime.Today)
                {
                    args.Item.IsBlackout = false;
                }
            };
            calendar.SetDisplayDate(DateTime.Today);
            registerItem(calendar);

            #endregion

            #region Sizing and Creation

            // Sizing
            parent.SizeChanged += (sender, args) =>
            {
                info.Width = args.NewSize.Width / 3 + 25;
                edit.Margin = new Thickness(args.NewSize.Width / 3 + 10, 36, 0, 7);
                calendar.Margin = new Thickness(args.NewSize.Width / 3 + 35, 75, 3, 5);
                timeInfoBorder.Margin = new Thickness(args.NewSize.Width / 3 + 35, 36, 105, 5);
            };

            panel.SizeChanged += (sender, args) => { content.Height = args.NewSize.Height; };

            // Add each element in the contentItems list
            foreach (UIElement element in contentItems)
            {
                content.Children.Add(element);
            }

            // Set the container content
            panel.Content = content;

            return panel;

            #endregion
        }
        /// <summary>
        ///     Creates a panel for a class
        /// </summary>
        /// <param name="classStackPanel">ClassStackPanel</param>
        /// <param name="cl">Class object containing details about the class</param>
        /// <returns>A generated listview</returns>
        public static ListView AddClassPanel(StackPanel classStackPanel, Class cl)
        {
            #region Containers

            // Create the class's listview
            ListView @class = new ListView
            {
                Margin = new Thickness(0, 40, 0, 0),
                Padding = new Thickness(5),
                BorderThickness = new Thickness(0),
                BorderBrush = MainPage.BlueBrush,
                Background = MainPage.TransparentBrush,
                Tag = cl,
                Width = Window.Current.Bounds.Width / 2 - 35
            };
            ThreadPoolTimer.CreatePeriodicTimer(async timer =>
            {
                await @class.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    double num = Window.Current.Bounds.Width / 2 - 35;
                    if (Math.Abs(@class.MinWidth - num) > 0)
                    {
                        @class.Width = num;
                    }
                });
            }, TimeSpan.FromMilliseconds(100));

            // Allows scrolling between classes
            ScrollViewer wrapper = new ScrollViewer
            {
                Content = @class,
                VerticalScrollBarVisibility = ScrollBarVisibility.Hidden
            };

            #endregion

            #region Contents

            // Header - contains class name
            ListViewItem header = new ListViewItem
            {
                IsHitTestVisible = false, // Makes the header unable to be selected
                HorizontalContentAlignment = HorizontalAlignment.Center,
                BorderThickness = new Thickness(0, 0, 0, 1),
                BorderBrush = MainPage.BlueBrush,
                Margin = new Thickness(0, 0, 0, 5)
            };

            TextBlock headerText = new TextBlock
            {
                Foreground = MainPage.BlueBrush,
                FontSize = 25,
                Text = cl.Name
            };

            #endregion

            #region Creation

            // Add the header text to the header item
            header.Content = headerText;

            // Add the header to the listview
            @class.Items?.Add(header);

            // Add the listview to the stackpanel of classes
            classStackPanel.Children.Add(wrapper);

            // Add the class and its listview to the dictionary
            //_classes.Add( cl, @class );

            return @class;

            #endregion
        }