#if FRAMEWORK20 using System; using System.Collections; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace DevComponents.DotNetBar.Schedule { public class YearMonth { #region Private constants private const int MaxRows = 6; private const int MaxCols = 7; private const int MaxDays = (MaxRows * MaxCols); private const int CellPadding = 4; #endregion #region Private variables private YearView _YearView; private DateTime _RootDate; private DateTime _StartDate; private DateTime _EndDate; private Rectangle _Bounds; private Rectangle _ContentBounds; private Rectangle _MonthHeaderBounds; private Rectangle _DayOfWeekHeaderBounds; private int _DaysInMonth; private int _DaysOffset; private ItemRects _DayRects; private BitArray _AppBits; private bool _DaysSelected; private DaysOfTheWeek.eDayType _DayType = DaysOfTheWeek.eDayType.None; #endregion /// /// Constructor /// /// /// public YearMonth(YearView yearView, DateTime date) { _YearView = yearView; StartDate = date; _DayRects = new ItemRects(yearView, MaxDays); _AppBits = new BitArray(32); } #region Internal properties #region AppBits /// /// Appointment (and CustomItem) bit array /// internal BitArray AppBits { get { return (_AppBits); } set { _AppBits = value; } } #endregion #region DayOfWeekHeaderHeight /// /// DayOfWeekHeaderHeight /// internal int DayOfWeekHeaderHeight { get { return (_YearView.Font.Height + 4); } } #endregion #region DayRects /// /// Gets the day Rectangles /// internal ItemRects DayRects { get { return (_DayRects); } } #endregion #region MonthHeaderHeight /// /// MonthHeaderHeight /// internal int MonthHeaderHeight { get { return (_YearView.Font.Height + 4); } } #endregion #endregion #region Public properties #region Bounds /// /// Gets and sets the week bounding Rectangle /// public Rectangle Bounds { get { return (_Bounds); } internal set { if (_Bounds.Equals(value) == false) { _Bounds = value; _DayType = DaysOfTheWeek.eDayType.None; CalcBoundingRects(); CalcDayRects(); } } } #endregion #region DaysInMonth /// /// Gets the number of Days in the Month /// public int DaysInMonth { get { return (_DaysInMonth); } } #endregion #region StartDate /// /// Gets or sets the month starting date /// public DateTime StartDate { get { return (_StartDate); } internal set { value = value.Date.AddDays(-(value.Day - 1)); if (_StartDate.Equals(value) == false) { _StartDate = value; _DaysInMonth = DateTime.DaysInMonth(_StartDate.Year, _StartDate.Month); _RootDate = DateHelper.GetDateForDayOfWeek(_StartDate, DateHelper.GetFirstDayOfWeek()); _EndDate = _StartDate.AddDays(_DaysInMonth).AddDays(-1); _DaysOffset = (_StartDate.Date - _RootDate.Date).Days; } } } #endregion #region EndDate /// /// Gets the month end date /// public DateTime EndDate { get { return (_EndDate); } } #endregion #region YearView /// /// Gets the parent YearView /// public YearView YearView { get { return (_YearView); } } #endregion #endregion #region CalcBoundingRects /// /// Calculates the control's Bounding Rects /// private void CalcBoundingRects() { // Calculate main content bounding rects _ContentBounds = _Bounds; _ContentBounds.Y += (MonthHeaderHeight + DayOfWeekHeaderHeight); _ContentBounds.Height -= (MonthHeaderHeight + DayOfWeekHeaderHeight); _MonthHeaderBounds = _Bounds; _MonthHeaderBounds.Height = MonthHeaderHeight; _DayOfWeekHeaderBounds = _Bounds; _DayOfWeekHeaderBounds.Y += MonthHeaderHeight; _DayOfWeekHeaderBounds.Height = DayOfWeekHeaderHeight; } #endregion #region CalcDayRects /// /// Calculates the day rectangles for the /// current bounding rectangle /// private void CalcDayRects() { // Loop through each day in the week Size cellSize = _YearView.CellSize; Rectangle r = new Rectangle(_Bounds.Location, cellSize); r.X += CellPadding; r.Y += DayOfWeekHeaderHeight + MonthHeaderHeight + CellPadding; int bWidth = _Bounds.Width - (CellPadding * 2); int bHeight = _Bounds.Height - (DayOfWeekHeaderHeight + MonthHeaderHeight) - (CellPadding * 2); int dx = (bWidth - (cellSize.Width * MaxCols)) / MaxCols; int dy = (bHeight - (cellSize.Height * MaxRows)) / MaxRows; int width = (dx + cellSize.Width) * MaxCols; int colSpread = (width < bWidth) ? bWidth - width : 0; int height = (dy + cellSize.Height) * MaxRows; int rowSpread = (height < bHeight) ? bHeight - height : 0; for (int i = 0; i < MaxRows; i++) { r.Height = cellSize.Height + dy; if (i < rowSpread) r.Height++; for (int j = 0; j < MaxCols; j++) { r.Width = cellSize.Width + dx; if (j < colSpread) r.Width++; _DayRects[i * MaxCols + j].Bounds = r; r.X += r.Width; } r.X = _Bounds.X + CellPadding; r.Y += r.Height; } } #endregion #region GetDateFromIndex /// /// Gets the month date from the given day index /// /// /// public DateTime GetDateFromIndex(int dayIndex) { if ((uint)dayIndex < MaxDays) return (_RootDate.AddDays(dayIndex).Date); return (_RootDate.Date); } #endregion #region GetDateFromPoint /// /// Gets the month date from the given Point /// /// /// /// public bool GetDateFromPoint(Point pt, ref DateTime date) { int dayIndex = GetDayIndexFromPoint(pt); if (dayIndex >= _DaysOffset && dayIndex < _DaysOffset + _DaysInMonth) { date = _RootDate.AddDays(dayIndex); return (true); } return (false); } #endregion #region GetViewAreaFromPoint /// /// Gets the month view area from the given Point /// /// /// public eViewArea GetViewAreaFromPoint(Point pt) { if (_ContentBounds.Contains(pt)) return (eViewArea.InContent); if (_MonthHeaderBounds.Contains(pt)) return (eViewArea.InMonthHeader); if (_DayOfWeekHeaderBounds.Contains(pt)) return (eViewArea.InDayOfWeekHeader); return (eViewArea.NotInView); } #endregion #region GetNormalizedDayIndex /// /// Gets the normalized month date for the given dayIndex /// /// /// internal int GetNormalizedDayIndex(int dayIndex) { if (dayIndex < _DaysOffset) dayIndex = _DaysOffset; else if (dayIndex >= _DaysOffset + _DaysInMonth) dayIndex = _DaysOffset + _DaysInMonth - 1; return (dayIndex); } #endregion #region GetDayIndexFromPoint /// /// Gets the month dayIndex from the given Point /// /// /// internal int GetDayIndexFromPoint(Point pt) { for (int i = 0; i < MaxDays; i++) { if (_DayRects[i].Bounds.Contains(pt)) return (i); } return (-1); } #endregion #region GetDayIndexFromDate /// /// Gets the month dayIndex from the given date /// /// /// internal int GetDayIndexFromDate(DateTime date) { if (ContainsDate(date) == true) return (date.Day - _StartDate.Day + _DaysOffset); return (-1); } #endregion #region ContainsDate /// /// Determines if the given date is contained in the month /// /// /// public bool ContainsDate(DateTime date) { return (date >= _StartDate && date <= _EndDate); } #endregion #region DayHasAppointments /// /// Determines if the given day of the month has /// Appointments or CustomItems associated with it /// /// Day of the month /// true, if there are Appointments associated with this day public bool DayHasAppointments(int day) { return (DayIndexHasAppointments(day + _DaysOffset - 1)); } /// /// Determines if the given dayIndex has /// Appointments or CustomItems associated with it /// /// /// internal bool DayIndexHasAppointments(int dayIndex) { dayIndex -= _DaysOffset; return (_AppBits.Count > (uint)dayIndex && _AppBits[dayIndex] == true); } #endregion #region DayIsSelected /// /// Determines if the given day of the month is selected /// /// Day of the month /// true if selected public bool DayIsSelected(int day) { day += (_DaysOffset - 1); return (_DayRects.Rects.Length > (uint)day && _DayRects[day].IsSelected == true); } #endregion #region UpdateDateSelection /// /// Updates the date selection for the month /// internal void UpdateDateSelection() { if (_YearView.DateSelectionStart.HasValue == false || _YearView.DateSelectionEnd.HasValue == false) { ClearSelection(); } else { DateTime selStart = _YearView.DateSelectionStart.Value; DateTime selEnd = _YearView.DateSelectionEnd.Value; if (_StartDate > selEnd || _EndDate < selStart) { ClearSelection(); } else { _DaysSelected = false; DateTime startDate = _StartDate; for (int i = 0; i < _DaysInMonth; i++) { DateTime endDate = startDate.AddDays(1); bool selected = (endDate > selStart && startDate < selEnd); DayRects[i + _DaysOffset].IsSelected = selected; _DaysSelected |= selected; startDate = startDate.AddDays(1); } } } } #region ClearSelection /// /// ClearSelection /// private void ClearSelection() { if (_DaysSelected == true) { for (int i = 0; i < MaxDays; i++) _DayRects[i].IsSelected = false; _DaysSelected = false; } } #endregion #endregion #region GetPreferredSize /// /// Gets the Preferred control size for the month /// /// internal Size GetPreferredSize() { Size size = _YearView.CellSize; size.Width = (size.Width + CellPadding) * MaxCols; size.Height = (size.Height + CellPadding) * MaxRows + DayOfWeekHeaderHeight + MonthHeaderHeight; return (size); } #endregion #region Paint /// /// Paint /// /// /// internal void Paint(ItemPaintArgs e, bool isNow) { DrawContent(e); DrawMonthHeader(e, isNow); DrawDayOfWeekHeader(e, isNow); DrawBorder(e, isNow); } #region DrawContent /// /// DrawContent /// /// private void DrawContent(ItemPaintArgs e) { DrawBackground(e); DrawDayContent(e); DrawGridLines(e); DrawNowHighlight(e); } #region DrawBackground /// /// DrawBackground /// /// private void DrawBackground(ItemPaintArgs e) { Graphics g = e.Graphics; using (Brush br = _YearView.ViewColor.BrushPart( (int)eCalendarMonthPart.DayContentActiveBackground, _ContentBounds)) { g.FillRectangle(br, _Bounds); } } #endregion #region DrawDayContent /// /// DrawDayContent /// /// private void DrawDayContent(ItemPaintArgs e) { Graphics g = e.Graphics; Color color1 = _YearView.ViewColor.GetColor((int)eCalendarMonthPart.DayContactInactiveBackground); Color color2 = _YearView.ViewColor.GetColor((int)eCalendarMonthPart.DayContentActiveBackground); DateTime date = _StartDate; for (int i = 0; i < _DaysInMonth; i++) { ItemRect ir = _DayRects[i + _DaysOffset]; DrawDayContentBackground(g, date, ir, color1, color2); DrawDayContentText(g, date, ir); date = date.AddDays(1); } } #region DrawDayContentBackground /// /// DrawDayContentBackground /// /// /// /// /// /// private void DrawDayContentBackground(Graphics g, DateTime date, ItemRect ir, Color color1, Color color2) { CalendarView cv = _YearView.CalendarView; if (_YearView.AllowDateSelection == false || ir.IsSelected == false) { if (_AppBits.Get(date.Day - 1) == true) { using (Brush br = _YearView.ViewColor.BrushPart( (int) eCalendarMonthPart.ContentLinkBackground, ir.Bounds)) { g.FillRectangle(br, ir.Bounds); } } } eYearViewLinkStyle linkStyle = cv.YearViewAppointmentLinkStyle; if (cv.DoYearViewDrawDayBackground( g, this, date, ir.Bounds, ref linkStyle) == false) { if (_YearView.AllowDateSelection == true && ir.IsSelected == true) { using (Brush br = _YearView.ViewColor.BrushPart( (int) eCalendarMonthPart.DayContentSelectionBackground, ir.Bounds)) { g.FillRectangle(br, ir.Bounds); } } if (_AppBits.Get(date.Day - 1) == true) { if (ir.IsSelected == false) DrawDayHighLight(g, linkStyle, ir.Bounds, color1, color2); } } } #endregion #region DrawDayContentText /// /// DrawDayContentText /// /// /// /// private void DrawDayContentText( Graphics g, DateTime date, ItemRect ir) { if (_YearView.CalendarView.DoYearViewDrawDayText(g, this, date, ir.Bounds) == false) { Font font = _YearView.Font; Color color = _YearView.ViewColor.GetColor((int)eCalendarMonthPart.DayHeaderForeground); if (_AppBits.Get(date.Day - 1) == true) { font = _YearView.BoldFont; color = _YearView.ViewColor.GetColor((int)eCalendarMonthPart.ContentLinkForeground); } TextDrawing.DrawString(g, date.Day.ToString(), font, color, ir.Bounds, eTextFormat.VerticalCenter | eTextFormat.HorizontalCenter | eTextFormat.NoPadding); } } #endregion #endregion #region DrawDayHighLight /// /// Draws the day highlight /// /// /// /// /// /// private void DrawDayHighLight(Graphics g, eYearViewLinkStyle style, Rectangle r, Color color1, Color color2) { switch (style) { case eYearViewLinkStyle.Style1: DrawDayHighLightStyle1(g, r, color1, color2); break; case eYearViewLinkStyle.Style2: DrawDayHighLightStyle2(g, r, color1, color2); break; case eYearViewLinkStyle.Style3: DrawDayHighLightStyle3(g, r, color1, color2); break; case eYearViewLinkStyle.Style4: DrawDayHighLightStyle4(g, r, color1, color2); break; case eYearViewLinkStyle.Style5: DrawDayHighLightStyle5(g, r, color1); break; } } #region DrawDayHighLightStyle1 private void DrawDayHighLightStyle1(Graphics g, Rectangle r, Color color1, Color color2) { using (Brush br = new LinearGradientBrush(r, color2, color1, 45f)) g.FillRectangle(br, r); } #endregion #region DrawDayHighLightStyle2 private void DrawDayHighLightStyle2(Graphics g, Rectangle r, Color color1, Color color2) { using (GraphicsPath path = new GraphicsPath()) { Rectangle t = r; if (t.Height > t.Width) { t.Y += (t.Height - t.Width) / 2; t.Height = t.Width; } else if (t.Width > t.Height) { t.X += (t.Width - t.Height) / 2; t.Width = t.Height; } t.Inflate(2, 2); path.AddEllipse(t); using (PathGradientBrush pbr = new PathGradientBrush(path)) { pbr.CenterPoint = new PointF(r.X + r.Width / 2, r.Y + r.Height / 2); pbr.CenterColor = color1; pbr.SurroundColors = new Color[] { color2 }; g.FillPath(pbr, path); } } } #endregion #region DrawDayHighLightStyle3 private void DrawDayHighLightStyle3(Graphics g, Rectangle r, Color color1, Color color2) { r.Height /= 2; using (LinearGradientBrush br = new LinearGradientBrush(r, color1, color2, 90f)) { r.Height *= 2; br.WrapMode = WrapMode.TileFlipXY; g.FillRectangle(br, r); } } #endregion #region DrawDayHighLightStyle4 private void DrawDayHighLightStyle4(Graphics g, Rectangle r, Color color1, Color color2) { r.Width /= 2; using (LinearGradientBrush br = new LinearGradientBrush(r, color1, color2, 0f)) { r.Width *= 2; br.WrapMode = WrapMode.TileFlipXY; g.FillRectangle(br, r); } } #endregion #region DrawDayHighLightStyle5 private void DrawDayHighLightStyle5(Graphics g, Rectangle r, Color color1) { using (Brush br = new SolidBrush(color1)) g.FillRectangle(br, r); } #endregion #endregion #region DrawGridLines /// /// DrawGridLines /// /// private void DrawGridLines(ItemPaintArgs e) { if (_YearView.ShowGridLines == true) { Graphics g = e.Graphics; using (Pen pen = new Pen( ControlPaint.Light(_YearView.ViewColor.GetColor((int)eCalendarMonthPart.DayContentBorder)))) { int right = DayRects[MaxCols - 1].Bounds.Right; for (int i = 1; i < MaxRows; i++) { Point pt1 = DayRects[i * MaxCols].Bounds.Location; Point pt2 = new Point(right, pt1.Y); g.DrawLine(pen, pt1, pt2); } int bottom = DayRects[(MaxRows - 1) * MaxCols].Bounds.Bottom; for (int i = 1; i < MaxCols; i++) { Point pt1 = DayRects[i].Bounds.Location; Point pt2 = new Point(pt1.X, bottom); g.DrawLine(pen, pt1, pt2); } } } } #endregion #region DrawNowHighlight /// /// DrawNowHighlight /// /// private void DrawNowHighlight(ItemPaintArgs e) { if (_YearView.CalendarView.HighlightCurrentDay) { Graphics g = e.Graphics; int nowDay = GetDayIndexFromDate(DateTime.Now); if (nowDay >= 0) { Rectangle r = DayRects[nowDay].Bounds; using (Pen pen = new Pen( _YearView.ViewColor.GetColor((int)eCalendarMonthPart.NowDayHeaderBorder), 1)) { r.Inflate(-1, -1); g.DrawRectangle(pen, r); } using (Pen pen = new Pen( _YearView.ViewColor.GetColor((int)eCalendarMonthPart.DayContentActiveBackground))) { r.Inflate(1, 1); g.DrawRectangle(pen, r); } } } } #endregion #endregion #region DrawMonthHeader /// /// DrawMonthHeader /// /// /// private void DrawMonthHeader(ItemPaintArgs e, bool isNow) { Graphics g = e.Graphics; // Draw the header background Rectangle r = _MonthHeaderBounds; if (r.Width > 0 && r.Height > 0) { if (isNow == true) { using (Brush br = _YearView.ViewColor.BrushPart( (int)eCalendarMonthPart.NowDayHeaderBackground, r)) { g.FillRectangle(br, r); } } else { using (Brush br = _YearView.ViewColor.BrushPart( (int) eCalendarMonthPart.DayHeaderBackground, r)) { g.FillRectangle(br, r); } } // Draw the header content string s = String.Format("{0:y}", _StartDate); Color color = _YearView.ViewColor.GetColor(isNow == true ? (int)eCalendarMonthPart.NowDayHeaderForeground : (int)eCalendarMonthPart.DayHeaderForeground); TextDrawing.DrawString(g, s, _YearView.Font, color, _MonthHeaderBounds, eTextFormat.VerticalCenter | eTextFormat.HorizontalCenter | eTextFormat.NoPadding); } } #endregion #region DrawDayOfWeekHeader /// /// DrawDayOfWeekHeader /// /// /// private void DrawDayOfWeekHeader(ItemPaintArgs e, bool isNow) { Graphics g = e.Graphics; // Draw the header background Rectangle r = _DayOfWeekHeaderBounds; if (r.Width > 0 && r.Height > 0) { if (isNow == true) { using (Brush br = _YearView.ViewColor.BrushPart( (int)eCalendarMonthPart.NowDayHeaderBackground, r)) { g.FillRectangle(br, r); } } else { using (Brush br = _YearView.ViewColor.BrushPart( (int)eCalendarMonthPart.DayOfTheWeekHeaderBackground, r)) { g.FillRectangle(br, r); } } // Establish our Days Of The Week text type DaysOfTheWeek.eDayType type = GetDaysOfTheWeekType(e); // Loop through each day, drawing the // day of the week text in the header area const eTextFormat tf = eTextFormat.VerticalCenter | eTextFormat.HorizontalCenter | eTextFormat.NoPadding; r = _DayOfWeekHeaderBounds; int width = r.Width / MaxCols; int spread = r.Width - (width * MaxCols); Color color = _YearView.ViewColor.GetColor(isNow == true ? (int)eCalendarMonthPart.NowDayHeaderForeground : (int)eCalendarMonthPart.DayOfTheWeekHeaderForeground); for (int i = 0; i < MaxCols; i++) { r.Width = width; if (i < spread) r.Width++; TextDrawing.DrawString(g, _YearView.DaysOfTheWeek.DayText[(int)type][i], _YearView.Font, color, r, tf); r.X += r.Width; } } } #endregion #region DrawBorder /// /// DrawBorder /// /// /// private void DrawBorder(ItemPaintArgs e, bool isNow) { Graphics g = e.Graphics; if (isNow == true) { using (Pen pen = new Pen(_YearView.ViewColor.GetColor( (int)eCalendarMonthPart.NowDayHeaderBorder))) { g.DrawRectangle(pen, _MonthHeaderBounds); g.DrawRectangle(pen, _DayOfWeekHeaderBounds); g.DrawRectangle(pen, _ContentBounds); } } else { using (Pen pen = new Pen( _YearView.ViewColor.GetColor((int) eCalendarMonthPart.DayContentBorder))) { g.DrawRectangle(pen, _MonthHeaderBounds); g.DrawRectangle(pen, _DayOfWeekHeaderBounds); } using (Pen pen = new Pen( _YearView.ViewColor.GetColor((int) eCalendarMonthPart.DayHeaderBorder))) { g.DrawRectangle(pen, _ContentBounds); } } } #endregion #region GetDaysOfTheWeekType /// /// GetDaysOfTheWeekType /// /// /// private DaysOfTheWeek.eDayType GetDaysOfTheWeekType(ItemPaintArgs e) { if (_DayType != DaysOfTheWeek.eDayType.None) return (_DayType); Graphics g = e.Graphics; _YearView.DaysOfTheWeek.MeasureText(g, _YearView.Font); int width = _Bounds.Width/MaxCols; for (int i = 0; i < MaxCols; i++) { if (_YearView.DaysOfTheWeek.DaySize[ (int) DaysOfTheWeek.eDayType.Long][i].Width > width) { if (_YearView.DaysOfTheWeek.DaySize[ (int) DaysOfTheWeek.eDayType.Short][i].Width > width) { return (DaysOfTheWeek.eDayType.Single); } return (DaysOfTheWeek.eDayType.Short); } } return (DaysOfTheWeek.eDayType.Long); } #endregion #endregion } } #endif