예제 #1
0
        /// <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
        }
예제 #2
0
        private double BlockHeightOf( TextBlock t )
        {
            t.Measure( new Size( double.PositiveInfinity, double.PositiveInfinity ) );
            t.Arrange( new Rect( new Point(), t.DesiredSize ) );

            /* INTENSIVE_LOG
            if( t.FontSize == 16 )
            {
                Logger.Log( ID, string.Format( "FontSize 16 detected {0}, Should be {1}. Text {2}", t.FontSize, FontSize, t.Text ), LogType.DEBUG );
            }
            //*/

            return t.ActualHeight;
        }