#if FRAMEWORK20 using System; using System.Drawing; using System.Drawing.Drawing2D; namespace DevComponents.DotNetBar.Schedule { public class TimeRulerPanel : BaseItem { #region Private Variables private CalendarView _CalendarView; // Assoc CalendarView private int _VScrollPos; // Vertical scroll position private TimeRulerColor _ViewColor = // View display color table new TimeRulerColor(); #endregion /// /// Constructor /// /// public TimeRulerPanel(CalendarView calendarView) { _CalendarView = calendarView; Name = "TimeRulerPanel"; HookEvents(true); } #region Private properties #region General display properties /// /// Gets the TimeRuler font /// private Font TimeRulerFont { get { return (_CalendarView.TimeRulerFont); } } /// /// Gets the TimeRuler font (small) /// private Font TimeRulerFontSm { get { return (_CalendarView.TimeRulerFontSm); } } #endregion #region Time Slice Properties /// /// Gets the default Time Slice height /// private float TimeSliceHeight { get { return (_CalendarView.TimeSliceHeight); } } /// /// Gets the TimeSlotDuration /// private int TimeSlotDuration { get { return (_CalendarView.TimeSlotDuration); } } /// /// Gets the SlotsPerHour /// private int SlotsPerHour { get { return (_CalendarView.SlotsPerHour); } } /// /// Gets the NumberOfSlices /// private int NumberOfSlices { get { return (_CalendarView.NumberOfSlices); } } /// /// Gets the starting Time Slice /// private int StartSlice { get { return (_CalendarView.StartSlice); } } #endregion #region AM / PM designators /// /// Gets the culturally correct AM time designator /// private string AmDesignator { get { return (ScheduleSettings.GetActiveCulture(). DateTimeFormat.AMDesignator.ToLower()); } } /// /// Gets the culturally correct PM time designator /// private string PmDesignator { get { return (ScheduleSettings.GetActiveCulture(). DateTimeFormat.PMDesignator.ToLower()); } } #endregion #endregion #region Hook / Unhook Events /// /// Routine hooks all necessary events for this control /// /// True to hook, false to unhook private void HookEvents(bool hook) { if (hook == true) { _CalendarView.LabelTimeSlotsChanged += CalendarView_LabelTimeSlotsChanged; _CalendarView.Is24HourFormatChanged += CalendarView_Is24HourFormatChanged; _CalendarView.TimeSlotDurationChanged += CalendarView_TimeSlotDurationChanged; _CalendarView.TimeIndicatorsChanged += CalendarView_TimeIndicatorsChanged; _CalendarView.TimeIndicatorTimeChanged += CalendarView_TimeIndicatorTimeChanged; _CalendarView.WeekDayVScrollPanel.ScrollBarChanged += VScrollPanel_ScrollBarChanged; } else { _CalendarView.LabelTimeSlotsChanged -= CalendarView_LabelTimeSlotsChanged; _CalendarView.Is24HourFormatChanged -= CalendarView_Is24HourFormatChanged; _CalendarView.TimeSlotDurationChanged -= CalendarView_TimeSlotDurationChanged; _CalendarView.TimeIndicatorsChanged -= CalendarView_TimeIndicatorsChanged; _CalendarView.TimeIndicatorTimeChanged -= CalendarView_TimeIndicatorTimeChanged; _CalendarView.WeekDayVScrollPanel.ScrollBarChanged -= VScrollPanel_ScrollBarChanged; } } #endregion #region Event Processing #region CalendarView_LabelTimeSlotsChanged /// /// Processes LabelTimeSlotsChanged events /// /// /// void CalendarView_LabelTimeSlotsChanged( object sender, LabelTimeSlotsChangedEventArgs e) { Refresh(); } #endregion #region CalendarView_Is24HourFormatChanged /// /// Processes Is24HourFormatChanged events /// /// /// void CalendarView_Is24HourFormatChanged( object sender, Is24HourFormatChangedEventArgs e) { Refresh(); } #endregion #region CalendarView_TimeSlotDurationChanged /// /// Processes TimeSlotDurationChanged events /// /// /// void CalendarView_TimeSlotDurationChanged( object sender, TimeSlotDurationChangedEventArgs e) { Refresh(); } #endregion #region CalendarView_TimeIndicatorsChanged /// /// Processes CalendarView_TimeIndicatorsChanged events /// /// /// void CalendarView_TimeIndicatorsChanged(object sender, EventArgs e) { Refresh(); } #endregion #region CalendarView_TimeIndicatorTimeChanged /// /// Processes CalendarView_TimeIndicatorTimeChanged events /// /// /// void CalendarView_TimeIndicatorTimeChanged( object sender, TimeIndicatorTimeChangedEventArgs e) { Refresh(); } #endregion #region VScrollPanel_ScrollBarChanged void VScrollPanel_ScrollBarChanged(object sender, EventArgs e) { Refresh(); Rectangle r = Bounds; r.Y = _CalendarView.WeekDayVScrollPanel.Bounds.Y; r.Height = _CalendarView.WeekDayVScrollPanel.Bounds.Height; Bounds = r; _VScrollPos = -_CalendarView.WeekDayVScrollPanel.ScrollBar.Value; Refresh(); } #endregion #endregion #region Paint processing /// /// Paint processing routine /// /// public override void Paint(ItemPaintArgs e) { int sliceStart, sliceEnd; int sliceCount = GetSliceRange(e, out sliceStart, out sliceEnd); if (sliceCount > 0) { _ViewColor.SetColorTable(); DrawTimeRuler(e, sliceStart, sliceEnd); } } #region Slice Support Routines /// /// Calculates the range of slices needed to be drawn /// to satisfy the specified paint request /// /// ItemPaintArgs /// [out] Slice start index /// [out] Slice end index /// Slice range count (end - start) internal int GetSliceRange(ItemPaintArgs e, out int sliceStart, out int sliceEnd) { // Calc our starting index int start = 0; while (start < NumberOfSlices) { Rectangle r = GetSliceRect(start); if (r.Bottom > Bounds.Top) { if (r.Bottom > e.ClipRectangle.Y) break; } start++; } // Calc our ending index int end = start; while (end < NumberOfSlices) { Rectangle r = GetSliceRect(end); if (r.Y >= e.ClipRectangle.Bottom) break; end++; } // Set the user supplied 'out' values, and // return the range count to the caller if (end - start == 0) { sliceStart = 0; sliceEnd = 0; return (0); } sliceStart = start; sliceEnd = end - 1; return (end - start); } /// /// Gets the given slice rectangle /// /// Slice /// Bounding rectangle private Rectangle GetSliceRect(int slice) { Rectangle r = Bounds; float n = slice * TimeSliceHeight; r.Y += (int)(n) + _VScrollPos; r.Height = (int)(n + TimeSliceHeight) - (int)n; return (r); } #endregion #region DrawTimeRuler /// /// Draws the TimeRuler /// /// ItemPaintArgs /// /// private void DrawTimeRuler(ItemPaintArgs e, int sliceStart, int sliceEnd) { Graphics g = e.Graphics; Region regSav = g.Clip; g.SetClip(Bounds); DrawBackGround(g); DrawTimeIndicators(g, sliceStart, sliceEnd); DrawRulerContent(g, sliceStart, sliceEnd); // Restore our original clip region g.Clip = regSav; } #endregion #region DrawBackGround /// /// DrawBackGround /// /// private void DrawBackGround(Graphics g) { using (Brush br = _ViewColor.BrushPart((int)eTimeRulerPart.TimeRulerBackground, Bounds)) g.FillRectangle(br, Bounds); } #endregion #region DrawTimeIndicators #region DrawTimeIndicators /// /// Draws TimeIndicators /// /// /// /// private void DrawTimeIndicators(Graphics g, int sliceStart, int sliceEnd) { DateTime start, end; GetViewDates(out start, out end); Rectangle r = Rectangle.Union(GetSliceRect(sliceStart), GetSliceRect(sliceEnd)); for (int i = 0; i < _CalendarView.TimeIndicators.Count; i++) { TimeIndicator ti = _CalendarView.TimeIndicators[i]; if (ti.IndicatorArea == eTimeIndicatorArea.All || ti.IndicatorArea == eTimeIndicatorArea.Header) { if (ti.IsVisible()) { DateTime time = ti.IndicatorDisplayTime; if (time >= start && time < end) DrawTimeIndicator(g, r, ti); } } } } #endregion #region DrawTimeIndicator #region DrawTimeIndicator /// /// Draws individual TimeIndicators /// /// /// /// private void DrawTimeIndicator(Graphics g, Rectangle sRect, TimeIndicator ti) { Rectangle r = GetIndicatorRect(ti); if (r.IntersectsWith(sRect) == true) { if (r.Height > 0) { ColorDef cdef = GetIndicatorColor(ti); if (cdef != null) { using (Brush br = _ViewColor.BrushPart(cdef, r)) { if (br is LinearGradientBrush) ((LinearGradientBrush)br).WrapMode = WrapMode.TileFlipX; g.FillRectangle(br, r); } } } Color color = GetIndicatorBorder(ti); if (color.IsEmpty == false) { using (Pen pen = new Pen(color)) g.DrawLine(pen, r.X + 1, r.Bottom, r.Right - 1, r.Bottom); } } } #endregion #region GetIndicatorColor /// /// Gets the Indicator Back color /// /// /// private ColorDef GetIndicatorColor(TimeIndicator ti) { ColorDef cdef = ti.IndicatorColor; if (cdef == null || cdef.IsEmpty == true) cdef = _ViewColor.GetColorDef((int)eTimeRulerPart.TimeRulerIndicator); return (cdef); } #endregion #region GetIndicatorBorder /// /// Gets the Indicator Border color /// /// /// private Color GetIndicatorBorder(TimeIndicator ti) { return (ti.BorderColor.IsEmpty == false ? ti.BorderColor : _ViewColor.GetColor((int)eTimeRulerPart.TimeRulerIndicatorBorder)); } #endregion #endregion #region GetViewDates /// /// GetViewDates /// /// /// private void GetViewDates(out DateTime start, out DateTime end) { switch (_CalendarView.SelectedView) { case eCalendarView.Day: start = _CalendarView.DayViewDate; end = _CalendarView.DayViewDate.AddDays(1); break; default: start = _CalendarView.WeekViewStartDate; end = _CalendarView.WeekViewEndDate.AddDays(1); break; } } #endregion #region GetIndicatorRect /// /// GetIndicatorRect /// /// /// private Rectangle GetIndicatorRect(TimeIndicator ti) { DateTime time = ti.IndicatorDisplayTime; int offset = (int)(time.Hour * SlotsPerHour * TimeSliceHeight + (TimeSliceHeight * time.Minute) / TimeSlotDuration); offset -= (int)(StartSlice * TimeSliceHeight); Rectangle r = Bounds; r.Y += (offset - ti.Thickness + _VScrollPos); r.Height = ti.Thickness; return (r); } #endregion #endregion #region DrawRulerContent private void DrawRulerContent(Graphics g, int sliceStart, int sliceEnd) { Point pt1 = new Point(); Point pt2 = new Point(); using (Pen pen = new Pen( _ViewColor.GetColor((int)eTimeRulerPart.TimeRulerBorder))) { pt1.X = 3; pt2.X = Bounds.Width - 4; for (int i = sliceStart; i <= sliceEnd; i++) { Rectangle r = GetSliceRect(i); // Draw an hourly separation border line if ((i % SlotsPerHour) == 0) { pt1.Y = pt2.Y = r.Y; g.DrawLine(pen, pt1, pt2); } // Draw the time text DrawTimeRulerText(g, r, i); } } } #endregion #region DrawTimeRulerText /// /// Draws the time text /// /// /// /// private void DrawTimeRulerText(Graphics g, Rectangle r, int slice) { // Get our hour and minute display text slice += StartSlice; int hour = slice / SlotsPerHour; int minute = (slice % SlotsPerHour) * TimeSlotDuration; if (_CalendarView.LabelTimeSlots == true || minute == 0) { string sHour = GetRulerHour(hour); string sMinute = GetRulerMinute(hour, minute); // Setup for our output Color color = _ViewColor.GetColor( (int)eTimeRulerPart.TimeRulerForeground); eTextFormat tf = eTextFormat.Top | eTextFormat.Left | eTextFormat.NoPadding; Size sz = TextDrawing.MeasureString(g, sHour, TimeRulerFont, 0, tf); Rectangle r2 = new Rectangle(Bounds.X, r.Y + 1, Bounds.Width / 2, (int)TimeSliceHeight - 1); // If we are displaying an hourly marker, then display // it as an offset hour and minute (or AM/PM designator) display if (minute == 0) { r2.X = r2.Right - sz.Width; if (r2.X < 0) r2.X = 0; r2.Width = sz.Width; TextDrawing.DrawString(g, sHour, TimeRulerFont, color, r2, tf); r2.X = r2.Right + 2; r2.Y += 1; tf = eTextFormat.Top | eTextFormat.Left | eTextFormat.NoPadding; TextDrawing.DrawString(g, sMinute, TimeRulerFontSm, color, r2, tf); } else { // Non-hourly display r2.Width = Bounds.Width - 4; r2.Y += 2; tf = eTextFormat.Top | eTextFormat.Right | eTextFormat.NoPadding; TextDrawing.DrawString(g, sHour + ScheduleSettings.GetActiveCulture().DateTimeFormat.TimeSeparator + sMinute, TimeRulerFontSm, color, r2, tf); } } } /// /// Gets the hourly display text /// /// Hour /// Hourly text private string GetRulerHour(int hour) { if (_CalendarView.Is24HourFormat == false) { int h = hour % 12; hour = (h == 0) ? 12 : h; } else { int h = hour % 24; hour = (h == 0) ? 0 : h; } return (hour.ToString(ScheduleSettings.TimeRulerHourFormatString)); } /// /// Gets the minute display text /// /// Hour /// Minute /// Minute text private string GetRulerMinute(int hour, int minute) { if (minute == 0 && _CalendarView.Is24HourFormat == false) { hour %= 24; if (hour == 0) return (AmDesignator); if (hour == 12) return (PmDesignator); } return (minute.ToString(ScheduleSettings.TimeRulerMinuteFormatString)); } #endregion #endregion #region IDisposable Members protected override void Dispose(bool disposing) { if (disposing == true && IsDisposed == false) HookEvents(false); base.Dispose(disposing); } #endregion #region Copy /// /// Returns copy of the item. /// public override BaseItem Copy() { TimeRulerPanel objCopy = new TimeRulerPanel(_CalendarView); CopyToItem(objCopy); return (objCopy); } /// /// Copies the TimeRulerPanel specific properties to new instance of the item. /// /// New TimeRulerPanel instance protected override void CopyToItem(BaseItem copy) { TimeRulerPanel objCopy = copy as TimeRulerPanel; base.CopyToItem(objCopy); } #endregion } } #endif