From e1c77d5544c936ead00c02a8f093ca93cd1a8188 Mon Sep 17 00:00:00 2001 From: Christian Fiedler Date: Wed, 11 Sep 2013 17:00:13 +0200 Subject: [PATCH] timetable ui --- .../Model/TimeTable/AppointmentModel.cs | 134 +++++++++++++++--- .../Pages/TimeTable/TimeTableDay.xaml | 16 ++- .../Pages/TimeTable/TimeTableDay.xaml.cs | 121 ++++++++++++++-- .../CampusAppWP8/Utility/ICalObject.cs | 7 + 4 files changed, 248 insertions(+), 30 deletions(-) diff --git a/CampusAppWP8/CampusAppWP8/Model/TimeTable/AppointmentModel.cs b/CampusAppWP8/CampusAppWP8/Model/TimeTable/AppointmentModel.cs index 8dc202a2..e1ab97b1 100644 --- a/CampusAppWP8/CampusAppWP8/Model/TimeTable/AppointmentModel.cs +++ b/CampusAppWP8/CampusAppWP8/Model/TimeTable/AppointmentModel.cs @@ -15,7 +15,9 @@ namespace CampusAppWP8.Model.TimeTable using System.Xml.Serialization; using System.Windows.Controls; using System.Windows.Media; + using System.Windows; using CampusAppWP8.Utility; + using CampusAppWP8.Utility.ICSProperties; /// /// Model for appointments. @@ -23,8 +25,13 @@ namespace CampusAppWP8.Model.TimeTable [XmlRoot("root")] public class AppointmentModel { + public static readonly double DAY_HOUR_SPACING = 50; + /// The Visual object. private Rectangle rect = null; + private Canvas canvas = null; + private double offsetY = 0; + private double height = 0; private ICalObject icalObj = null; @@ -32,46 +39,135 @@ namespace CampusAppWP8.Model.TimeTable public AppointmentModel() { this.rect = new Rectangle(); + this.canvas = new Canvas(); + this.canvas.DoubleTap += new EventHandler(this.OnCanvasClick); } public AppointmentModel(string icsData) : this() { this.icalObj = ICSManager.ImportFromICS(icsData); + + this.CalcYOffset(); this.CalcRect(); } - public Rectangle GetRectangle() + public double GetYOffset { - return this.rect; + get + { + return this.offsetY; + } + } + + public Canvas GetCanvas() + { + return this.canvas; } private void CalcRect() { + this.CalcHeight(); + this.rect.Width = 200; - this.rect.MinHeight = 16; + this.rect.MinHeight = this.height; this.rect.MaxHeight = 600; - this.rect.Height = 200; + this.rect.Height = this.height; - this.rect.StrokeThickness = 4; + this.rect.StrokeThickness = 0; + this.rect.Stroke = new SolidColorBrush(Colors.Red); + this.rect.Fill = new SolidColorBrush(Colors.Green); + + this.canvas.Children.Add(this.rect); - SolidColorBrush borderBrush = new SolidColorBrush(); - borderBrush.Color = Colors.Red; - - this.rect.Stroke = borderBrush; - - Vis - - VisualBrush myBrush = new VisualBrush(); - StackPanel aPanel = new StackPanel(); - - if (this.icalObj != null) { - TextBlock tb = new TextBlock(); - tb.Text = this.icalObj.Header.Value; + ICalObject eventObj = this.GetVEventObj(); + Summary title = eventObj.GetProperty(ICSTag.SUMMARY) as Summary; - this.rect.Resources = tb; + TextBlock txtTitle = new TextBlock(); + txtTitle.Text = title.Value; + txtTitle.FontSize = 12; + txtTitle.FontWeight = FontWeights.Bold; + txtTitle.TextWrapping = TextWrapping.Wrap; + txtTitle.Width = this.rect.Width - 4.0; + txtTitle.SetValue(Canvas.LeftProperty, 2.0); + txtTitle.SetValue(Canvas.TopProperty, 2.0); + + /* + Description desc = eventObj.GetProperty(ICSTag.DESCRIPTION) as Description; + + TextBlock txtDesc = new TextBlock(); + txtDesc.Text = desc.Value; + txtDesc.FontSize = 12; + txtDesc.TextWrapping = TextWrapping.Wrap; + txtDesc.Width = this.rect.Width - 4.0; + txtDesc.SetValue(Canvas.LeftProperty, 2.0); + txtDesc.SetValue(Canvas.TopProperty, 20.0); + txtDesc.Height = this.height - 22.0; + */ + + this.canvas.Children.Add(txtTitle); + //this.canvas.Children.Add(txtDesc); } } + + private void CalcYOffset() + { + ICalObject eventObj = this.GetVEventObj(); + + DTStart startTimeObj = eventObj.GetProperty(ICSTag.DT_START) as DTStart; + + if (startTimeObj == null) + { + throw new NullReferenceException(); + } + + DateTime startTimeValue = startTimeObj.Value; + + this.offsetY = (startTimeValue.Hour * AppointmentModel.DAY_HOUR_SPACING) + (startTimeValue.Minute / 60.0 * AppointmentModel.DAY_HOUR_SPACING); + } + + private void CalcHeight() + { + ICalObject eventObj = this.GetVEventObj(); + + DTStart startTimeObj = eventObj.GetProperty(ICSTag.DT_START) as DTStart; + DTEnd endTimeObj = eventObj.GetProperty(ICSTag.DT_END) as DTEnd; + + if (startTimeObj == null + || endTimeObj == null) + { + throw new NullReferenceException(); + } + + DateTime startTimeValue = startTimeObj.Value; + DateTime endTimeValue = endTimeObj.Value; + + TimeSpan span = endTimeValue.Subtract(startTimeValue); + + this.height = span.TotalHours * AppointmentModel.DAY_HOUR_SPACING; + + if (this.height < (AppointmentModel.DAY_HOUR_SPACING / 4)) + { + this.height = AppointmentModel.DAY_HOUR_SPACING / 4; + } + } + + private ICalObject GetVEventObj() + { + ICalObject retValue = this.icalObj.GetProperty(ICSTag.VEVENT) as ICalObject; + + if (retValue == null) + { + throw new NullReferenceException(); + } + + return retValue; + } + + private void OnCanvasClick(object sender, EventArgs e) + { + + } } } diff --git a/CampusAppWP8/CampusAppWP8/Pages/TimeTable/TimeTableDay.xaml b/CampusAppWP8/CampusAppWP8/Pages/TimeTable/TimeTableDay.xaml index 4f8d4fda..53e083e6 100644 --- a/CampusAppWP8/CampusAppWP8/Pages/TimeTable/TimeTableDay.xaml +++ b/CampusAppWP8/CampusAppWP8/Pages/TimeTable/TimeTableDay.xaml @@ -14,8 +14,16 @@ shell:SystemTray.IsVisible="True"> - - + + + + - + \ No newline at end of file diff --git a/CampusAppWP8/CampusAppWP8/Pages/TimeTable/TimeTableDay.xaml.cs b/CampusAppWP8/CampusAppWP8/Pages/TimeTable/TimeTableDay.xaml.cs index 140b18e8..18a17146 100644 --- a/CampusAppWP8/CampusAppWP8/Pages/TimeTable/TimeTableDay.xaml.cs +++ b/CampusAppWP8/CampusAppWP8/Pages/TimeTable/TimeTableDay.xaml.cs @@ -4,7 +4,9 @@ using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; +using System.Windows.Media; using System.Windows.Navigation; +using System.Windows.Shapes; using Microsoft.Phone.Controls; using Microsoft.Phone.Shell; using CampusAppWP8.Model.TimeTable; @@ -14,29 +16,132 @@ namespace CampusAppWP8.Pages.TimeTable { public partial class TimeTableDay : PhoneApplicationPage { + private readonly double DAY_TABLE_HEAD_WIDTH = 48; + private readonly double DAY_TABLE_HEAD_HALF = 8; + private readonly double DAY_TABLE_CELL_HEIGHT = AppointmentModel.DAY_HOUR_SPACING; + private readonly double DAY_TABLE_HEAD_THICKNESS = 2; + private readonly double DAY_TABLE_INNER_THICKNESS = 1; + private AppointmentModel testMod = null; + private AppointmentModel testMod2 = null; + private bool DayLayoutDone = false; public TimeTableDay() { InitializeComponent(); - this.testMod = new AppointmentModel("BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:ownCloud Calendar 0.6.3\r\nX-WR-CALNAME:Das is der Titel\r\nBEGIN:VEVENT\r\nCREATED;VALUE=DATE-TIME:20130827T113216Z\r\nUID:c9904ea73c\r\nLAST-MODIFIED;VALUE=DATE-TIME:20130827T113216Z\r\nDTSTAMP;VALUE=DATE-TIME:20130827T113216Z\r\nSUMMARY:Das is der Titel\r\nDTSTART;VALUE=DATE:20130828\r\nDTEND;VALUE=DATE:20130829\r\nCLASS:PUBLIC\r\nLOCATION:BTU Campus\r\nDESCRIPTION:For Outlook 2003, the behavior is peculiar. It can save the sa\r\n me calendar entry in both .ics and .vcs format, but it only read & displa\r\n y .vcs file correctly. It can read .ics file but it omits some fields and \r\n does not display it in calendar mode. My guess is that back then Microsoft\r\n wanted to provide .ics to be compatible with Mac's iCal but not quite com\r\n mitted to v2.0 yet.\r\nCATEGORIES:Projekte\r\nEND:VEVENT\r\nEND:VCALENDAR"); - + this.testMod = new AppointmentModel("BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:ownCloud Calendar 0.6.3\r\nX-WR-CALNAME:Das is der Titel\r\nBEGIN:VEVENT\r\nCREATED;VALUE=DATE-TIME:20130827T113216Z\r\nUID:c9904ea73c\r\nLAST-MODIFIED;VALUE=DATE-TIME:20130827T113216Z\r\nDTSTAMP;VALUE=DATE-TIME:20130827T113216Z\r\nSUMMARY:Das is der Titel\r\nDTSTART;VALUE=DATE-TIME:20130827T113500Z\r\nDTEND;VALUE=DATE-TIME:20130827T152000Z\r\nCLASS:PUBLIC\r\nLOCATION:BTU Campus\r\nDESCRIPTION:For Outlook 2003, the behavior is peculiar. It can save the sa\r\n me calendar entry in both .ics and .vcs format, but it only read & displa\r\n y .vcs file correctly. It can read .ics file but it omits some fields and \r\n does not display it in calendar mode. My guess is that back then Microsoft\r\n wanted to provide .ics to be compatible with Mac's iCal but not quite com\r\n mitted to v2.0 yet.\r\nCATEGORIES:Projekte\r\nEND:VEVENT\r\nEND:VCALENDAR"); + this.testMod2 = new AppointmentModel("BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:http://www.example.com/calendarapplication/\r\nMETHOD:PUBLISH\r\nBEGIN:VEVENT\r\nUID:461092315540@example.com\r\nORGANIZER:MAILTO:alice@example.com\r\nLOCATION:Somewhere\r\nSUMMARY:Eine Kurzinfo\r\nDESCRIPTION:Beschreibung des Termines\r\nCLASS:PUBLIC\r\nDTSTART:20060910T110000Z\r\nDTEND:20060910T195900Z\r\nDTSTAMP:20060812T125900Z\r\nEND:VEVENT\r\nEND:VCALENDAR"); + + this.DayScroll.LayoutUpdated += new EventHandler(this.AutoScrollToDay); } protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); - //List elemList = Utilities.GetChild(this.thePivot.Items[0] as UIElement, "TestGrid"); + this.DrawDayViewBackground(); + + double maxW = Application.Current.Host.Content.ActualWidth; + + maxW -= (DAY_TABLE_HEAD_WIDTH + 6.0); - //if (elemList.Count() > 0) { - TextBlock tb = new TextBlock(); - tb.Text = "kk"; + Canvas temp = this.testMod.GetCanvas(); + temp.Margin = new Thickness(DAY_TABLE_HEAD_WIDTH + 2, this.testMod.GetYOffset, 0, 0); + this.DayView.Children.Add(temp); - this.LayoutRoot.Children.Add(tb); - this.LayoutRoot.Children.Add(this.testMod.GetRectangle()); + temp = this.testMod2.GetCanvas(); + temp.Margin = new Thickness(DAY_TABLE_HEAD_WIDTH + 2 + 2 + (maxW / 2), this.testMod2.GetYOffset, 0, 0); + this.DayView.Children.Add(temp); } + + this.DayLayoutDone = true; + } + + + private void AutoScrollToDay(object sender, EventArgs e) + { + if (this.DayLayoutDone == true) + { + this.DayScroll.ScrollToVerticalOffset(DAY_TABLE_CELL_HEIGHT * 7); + this.DayLayoutDone = false; + this.DayScroll.LayoutUpdated -= this.AutoScrollToDay; + } + } + + private void DrawDayViewBackground() + { + this.DayView.Height = DAY_TABLE_CELL_HEIGHT * 24; + + + Line vertLine = new Line(); + vertLine.X1 = 0; + vertLine.Y1 = 0; + vertLine.X2 = 0; + vertLine.Y2 = (DAY_TABLE_CELL_HEIGHT * 24); + vertLine.Stroke = new SolidColorBrush(Colors.White); + vertLine.Stretch = Stretch.Fill; + vertLine.HorizontalAlignment = HorizontalAlignment.Left; + vertLine.Margin = new Thickness(DAY_TABLE_HEAD_WIDTH, 0, 0, 0); + vertLine.StrokeThickness = DAY_TABLE_HEAD_THICKNESS; + + for (int i = 0; i <= 24; i++) + { + // lines + Line hLineHead = new Line(); + hLineHead.X1 = 0; + hLineHead.Y1 = 0; + hLineHead.X2 = DAY_TABLE_HEAD_WIDTH; + hLineHead.Y2 = 0; + hLineHead.Stroke = new SolidColorBrush(Colors.White); + hLineHead.Stretch = Stretch.Fill; + hLineHead.HorizontalAlignment = HorizontalAlignment.Left; + hLineHead.Margin = new Thickness(0, (DAY_TABLE_CELL_HEIGHT * i), 0, 0); + hLineHead.StrokeThickness = DAY_TABLE_HEAD_THICKNESS; + + Line hLineHalf = new Line(); + hLineHalf.X1 = 0; + hLineHalf.Y1 = 0; + hLineHalf.X2 = DAY_TABLE_HEAD_HALF; + hLineHalf.Y2 = 0; + hLineHalf.Stroke = new SolidColorBrush(Colors.Gray); + hLineHalf.Stretch = Stretch.Fill; + hLineHalf.HorizontalAlignment = HorizontalAlignment.Left; + hLineHalf.Margin = new Thickness((DAY_TABLE_HEAD_WIDTH - DAY_TABLE_HEAD_HALF), (DAY_TABLE_CELL_HEIGHT * i) + (DAY_TABLE_CELL_HEIGHT / 2), 0, 0); + hLineHalf.StrokeThickness = DAY_TABLE_HEAD_THICKNESS; + + Line hLineInn = new Line(); + hLineInn.X1 = 0; + hLineInn.Y1 = 0; + hLineInn.X2 = 1000; + hLineInn.Y2 = 0; + hLineInn.Stroke = new SolidColorBrush(Colors.DarkGray); + hLineInn.Stretch = Stretch.Fill; + hLineInn.HorizontalAlignment = HorizontalAlignment.Left; + hLineInn.Margin = new Thickness(DAY_TABLE_HEAD_WIDTH, (DAY_TABLE_CELL_HEIGHT * i), 0, 0); + hLineInn.StrokeDashArray = new DoubleCollection(); + hLineInn.StrokeDashArray.Add(2); + hLineInn.StrokeDashArray.Add(4); + hLineInn.StrokeThickness = DAY_TABLE_INNER_THICKNESS; + + this.DayView.Children.Add(hLineHead); + this.DayView.Children.Add(hLineInn); + + if (i < 24) + { + this.DayView.Children.Add(hLineHalf); + + // text + TextBlock timeStamp = new TextBlock(); + timeStamp.Text = i.ToString("00") + ":00"; + timeStamp.Margin = new Thickness(0, (DAY_TABLE_CELL_HEIGHT * i) + 2, 0, 0); + timeStamp.FontSize = 16; + + this.DayView.Children.Add(timeStamp); + } + } + + this.DayView.Children.Add(vertLine); } } } \ No newline at end of file diff --git a/CampusAppWP8/CampusAppWP8/Utility/ICalObject.cs b/CampusAppWP8/CampusAppWP8/Utility/ICalObject.cs index a8f52b21..a004b363 100644 --- a/CampusAppWP8/CampusAppWP8/Utility/ICalObject.cs +++ b/CampusAppWP8/CampusAppWP8/Utility/ICalObject.cs @@ -89,6 +89,13 @@ namespace CampusAppWP8.Utility retValue = this.props[i]; } } + else + { + if ((this.props[i] as ICalObject).Header.Value.Equals(propName)) + { + retValue = this.props[i]; + } + } } return retValue;