#if FRAMEWORK20 using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; using DevComponents.Schedule.Model; namespace DevComponents.DotNetBar.Schedule { public class BaseView : BaseItem { #region Events /// /// Occurs when SelectedItem has Changed /// public event EventHandler SelectedItemChanged; /// /// Occurs when CalendarColor has Changed /// public event EventHandler CalendarColorChanged; #endregion #region Constants protected const int DaysInWeek = 7; private const int TabRadius = 3; private const int TabDia = TabRadius * 2; #endregion #region Static variables private static DateTime _oldStartTime; // Pre-move/resize CalendarItem StartTime private static DateTime _oldEndTime; // Pre-move/resize CalendarItem EndTime private static string _oldOwnerKey; // Pre-move CalendarItem OwnerKey #endregion #region SubClasses internal class NonClientData { #region Data members public eTabOrientation TabOrientation; // Tab orientation public int TabBorder; // Tab border color public int TabFore; // Tab foreground color public int TabBack; // Tab background color public int ContBack; // Tab content background public int TabSelFore; // Tab selected foreground public int TabSelBack; // Tab selected background #endregion /// /// Constructor /// /// Tab Orientation /// Tab border color /// Tab foreground color /// Tab background color /// Tab content background /// Tab selected foreground /// Tab selected background public NonClientData( eTabOrientation tabOrientation, int tabBorder, int tabFore, int tabBack, int contBack, int tabSelFore, int tabSelBack) { TabOrientation = tabOrientation; TabBorder = tabBorder; TabFore = tabFore; TabBack = tabBack; ContBack = contBack; TabSelFore = tabSelFore; TabSelBack = tabSelBack; } } #endregion #region Private variables private CalendarView _CalendarView; // CalendarView private eCalendarView _ECalendarView; // Enum CalendarView private ModelViewConnector _Connector; // Connector private DateTime? _DateSelectionStart; // Date selection start private DateTime? _DateSelectionEnd; // Date selection end private DateTime? _DateSelectionAnchor; // Date selection anchor private DateTime _StartDate; // Display start date private DateTime _EndDate; // Display end date private bool _DateRangeChanged; // Date range has changed private CalendarColor _CalendarColor; // CalendarColor private Rectangle _ClientRect; // View client area private NonClientData _NClientData; // Non-client data private int _TabWidth; // Tab width private PosWin _PosWin; // Move/Resize Position window private bool _IsMouseDown; // Mouse is down private bool _IsMoving; // Flag denoting app moving private bool _IsStartResizing; // Flag denoting appt start resizing private bool _IsEndResizing; // Flag denoting appt end resizing private bool _IsTabMoving; // Flag denoting Tab is moving private bool _IsCondMoving; // Flag denoting Condensed view movement private bool _IsCopyDrag; // Flag denoting Appointment copy is dragging private bool _IsNewCopyDrag; private int _LastViewIndex; // Last MultiUser view index private string _OwnerKey; // Owner key private string _DisplayName; // Display name private int _DisplayedOwnerKeyIndex = -1; // DisplayedOwnerKey index private bool _IsViewSelected; // View selected? private bool _IsSelecting; // Selection inprogress flag private CalendarItem _SelectedItem; // Selected CalendarItem private bool _NeedRecalcLayout = true; // Layout needs recalculated private DaysOfTheWeek _DaysOfTheWeek; // Days of the week private Font _Font = SystemFonts.CaptionFont; // Display font private Font _BoldFont = // Bold display font new Font(SystemFonts.CaptionFont, FontStyle.Bold); #endregion /// /// Constructor /// /// /// public BaseView(CalendarView calendarView, eCalendarView ecv) { // Save the provided CalendarView and // tell the system we are a container _CalendarView = calendarView; _ECalendarView = ecv; SetIsContainer(true); SubItems.AllowParentRemove = false; // Make sure we see all our mouse events MouseDownCapture = true; MouseUpNotification = true; // Hook our events HookEvents(true); } #region Public properties #region BoldFont /// /// Gets the Bold display font /// public Font BoldFont { get { return (_BoldFont); } } #endregion #region Bounds /// /// Gets and sets the view bounding rectangle /// public override Rectangle Bounds { get { return (base.Bounds); } set { if (base.Bounds != value) { Rectangle r = base.Bounds; base.Bounds = value; InvalidateRect(r); NeedRecalcLayout = true; } } } #endregion #region DisplayedOwnerKey /// /// Gets and sets the DisplayedOwnerKey /// public string DisplayedOwnerKey { get { if (_DisplayedOwnerKeyIndex < 0 || _DisplayedOwnerKeyIndex > _CalendarView.DisplayedOwners.Count) { return (""); } return (_CalendarView.DisplayedOwners[_DisplayedOwnerKeyIndex]); } } /// /// Gets and sets the DisplayedOwnerKeyIndex /// public int DisplayedOwnerKeyIndex { get { return (_DisplayedOwnerKeyIndex); } internal set { _DisplayedOwnerKeyIndex = value; } } /// /// Gets and sets the view Owner Key /// public string OwnerKey { get { return (_OwnerKey); } internal set { _OwnerKey = value; } } /// /// Gets and sets the view Display Name /// public string DisplayName { get { return (_DisplayName); } set { if (_DisplayName != value) { _DisplayName = value; this.Refresh(); } } } #endregion #region Start/EndDate /// /// Gets and sets the display start date /// public DateTime StartDate { get { return (_StartDate); } set { if (_StartDate != value) { _StartDate = value; _DateRangeChanged = true; NeedRecalcLayout = true; } } } /// /// Gets and sets the display end date /// public DateTime EndDate { get { return (_EndDate); } set { if (_EndDate != value) { _EndDate = value; _DateRangeChanged = true; NeedRecalcLayout = true; } } } #endregion #region DateSelectionStart /// /// Gets and sets the date selection start /// public DateTime? DateSelectionStart { get { return (_DateSelectionStart); } set { if (_DateSelectionStart != value) { _DateSelectionStart = value; // Update our dayRects selection status UpdateDateSelection(); } } } #endregion #region DateSelectionEnd /// /// Gets or sets the end date of selection. /// public DateTime? DateSelectionEnd { get { return (_DateSelectionEnd); } set { if (_DateSelectionEnd != value) { _DateSelectionEnd = value; // Update our dayRects selection status UpdateDateSelection(); } } } #endregion #region CalendarColorTable /// /// Gets and sets the CalendarColorTable /// public CalendarColor CalendarColorTable { get { return (_CalendarColor); } internal set { _CalendarColor = value; } } #endregion #region CalendarColor /// /// Gets and sets the display calendar color scheme /// public eCalendarColor CalendarColor { get { return (_CalendarColor.ColorSch); } set { if (_CalendarColor.ColorSch != value) { eCalendarColor oldValue = _CalendarColor.ColorSch; _CalendarColor.ColorSch = value; OnCalendarColorChanged(oldValue, value); if (IsViewSelected == true) InvalidateRect(Bounds); } } } /// /// OnCalendarColorChanged event propagation /// protected virtual void OnCalendarColorChanged(eCalendarColor oldValue, eCalendarColor newValue) { if (CalendarColorChanged != null) { CalendarColorChanged(this, new CalendarColorChangedEventArgs(oldValue, newValue)); } // Reflect the change in alternate views CalendarView.UpdateAltViewCalendarColor(newValue, DisplayedOwnerKeyIndex); // Update the CalendarModel ColorScheme OwnerCollection owners = CalendarView.CalendarModel.Owners; foreach (Owner owner in owners) { if (owner.Key.Equals(OwnerKey) == true) { owner.ColorScheme = newValue; break; } } } #endregion #region Font /// /// Get and sets the calendar font. /// public virtual Font Font { get { return (_Font); } set { if (value != null && _Font.Equals(value) == false) { if (_Font != null) _Font.Dispose(); if (_BoldFont != null) _BoldFont.Dispose(); _Font = value; _BoldFont = new Font(_Font, FontStyle.Bold); InvalidateRect(true); } } } #endregion #region Selection support /// /// Gets and sets the currently selected CalendarItem /// public CalendarItem SelectedItem { get { return _SelectedItem; } set { if (_SelectedItem != value) { CalendarItem oldValue = _SelectedItem; _SelectedItem = value; if (value != null) { CalendarView.DateSelectionStart = null; CalendarView.DateSelectionEnd = null; DateSelectionAnchor = null; UpdateItemOrder(value); } SetSelectedItem(oldValue, value); OnSelectedItemChanged(oldValue, value); } } } internal void UpdateItemOrder(CalendarItem ci) { int n = SubItems.IndexOf(ci); int index = FirstCalendarItem(); if (index >= 0 && index < n) { SubItems._RemoveAt(n); SubItems._Insert(index, ci); } } private int FirstCalendarItem() { for (int i = 0; i < SubItems.Count; i++) { if (SubItems[i] is CalendarItem) return (i); } return (-1); } /// /// SelectedItemChanged event propagation /// protected virtual void OnSelectedItemChanged(CalendarItem oldValue, CalendarItem newValue) { if (SelectedItemChanged != null) { SelectedItemChanged(this, new SelectedItemChangedEventArgs(oldValue, newValue)); } } /// /// Gets the selected state of the view /// public bool IsViewSelected { get { return (_IsViewSelected); } internal set {_IsViewSelected = value; } } #endregion #region SelectedAppointments /// /// Gets a ReadOnlyCollection of the /// currently selected appointments for the view /// public ReadOnlyCollection SelectedAppointments { get { List apps = new List(); AppointmentView view = _SelectedItem as AppointmentView; if (view != null) apps.Add(view); return (new ReadOnlyCollection(apps)); } } #endregion #endregion #region Protected properties #region CalendarModel /// /// Gets the View CalendarModel /// protected CalendarModel CalendarModel { get { return (CalendarView.CalendarModel); } } #endregion #region Mouse related properties /// /// IsMouseDown /// protected bool IsMouseDown { get { return (_IsMouseDown); } set { _IsMouseDown = value; } } /// /// IsStartResizing /// protected bool IsStartResizing { get { return (_IsStartResizing); } set { _IsStartResizing = value; } } /// /// IsEndResizing /// protected bool IsEndResizing { get { return (_IsEndResizing); } set { _IsEndResizing = value; } } /// /// IsResizing /// protected bool IsResizing { get { return (_IsStartResizing || _IsEndResizing); } } /// /// IsMoving /// protected bool IsMoving { get { return (_IsMoving); } set { _IsMoving = value; } } /// /// IsTabMoving /// protected bool IsTabMoving { get { return (_IsTabMoving); } set { _IsTabMoving = value; } } /// /// IsConMoving /// protected bool IsCondMoving { get { return (_IsCondMoving); } set { _IsCondMoving = value; } } /// /// CanDrag /// protected bool CanDrag { get { return (SelectedItem != null && CalendarView.EnableDragDrop == true); } } /// /// Pre-move/resize StartTime /// protected DateTime OldStartTime { get { return (_oldStartTime); } set { _oldStartTime = value; } } /// /// Pre-move/resize EndTime /// protected DateTime OldEndTime { get { return (_oldEndTime); } set { _oldEndTime = value; } } #endregion #region Cursor properties /// /// Sets local view cursor /// protected Cursor MyCursor { set { CalendarView.ViewCursor = value; } } /// /// Gets CalendarView default cursor /// protected Cursor DefaultCursor { get { return (CalendarView.DefaultViewCursor); } } #endregion #region PosWin /// /// Gets and sets the view position window /// protected PosWin PosWin { get { return (_PosWin); } set { _PosWin = value; } } #endregion #endregion #region Internal properties /// /// Gets the CalendarView /// internal CalendarView CalendarView { get { return (_CalendarView); } } /// /// Gets the ECalendarView /// internal eCalendarView ECalendarView { get { return (_ECalendarView); } } /// /// Gets and sets the ModelViewConnector /// internal ModelViewConnector Connector { get { return (_Connector); } set { if (value != _Connector) { _Connector = value; _Connector.DisplayOwnerKey = DisplayedOwnerKey; _Connector.Connect(); } } } /// /// Gets the DayOfWeekHeader height /// internal int DayOfWeekHeaderHeight { get { return (Font.Height + 4); } } /// /// IsCopyDrag /// internal bool IsCopyDrag { get { return (_IsCopyDrag); } set { _IsCopyDrag = value; } } /// /// IsNewCopyDrag /// internal bool IsNewCopyDrag { get { return (_IsNewCopyDrag); } set { _IsNewCopyDrag = value; } } /// /// OldOwnerKey /// internal string OldOwnerKey { get { return (_oldOwnerKey); } set { _oldOwnerKey = value; } } #region MonthHeaderHeight internal int MonthHeaderHeight { get { return (Font.Height + 4); } } #endregion /// /// Gets the MultiUserTabHeight /// internal int MultiUserTabHeight { get { return (_CalendarView.MultiUserTabHeight); } } /// /// Gets the MultiUserTabWidth /// internal int MultiUserTabWidth { get { return (_CalendarView.TimeLineMultiUserTabWidth); } } /// /// Gets the Appointment height /// internal int AppointmentHeight { get { return (Font.Height + 4); } } /// /// Gets and sets the date selection anchor /// internal DateTime? DateSelectionAnchor { get { return (_DateSelectionAnchor); } set { _DateSelectionAnchor = value; } } /// /// Gets and sets the Days of the week object /// internal DaysOfTheWeek DaysOfTheWeek { get { return (_DaysOfTheWeek); } set { _DaysOfTheWeek = value; } } /// /// Gets and sets the selecting status /// internal bool IsSelecting { get { return (_IsSelecting); } set { _IsSelecting = value; } } /// /// Gets and sets recalc layout need /// internal bool NeedRecalcLayout { get { return (_NeedRecalcLayout); } set { _NeedRecalcLayout = value; if (value == true) InvalidateRect(true); } } /// /// Gets and sets the view client rectangle /// internal Rectangle ClientRect { get { return (_ClientRect); } set { _ClientRect = value; } } /// /// Gets and sets the DateRangeChanged state /// internal bool DateRangeChanged { get { return (_DateRangeChanged); } set { _DateRangeChanged = value; } } /// /// Gets and sets the base non-client data /// internal NonClientData NClientData { get { return (_NClientData); } set { _NClientData = value; } } #endregion #region HookEvents /// /// Hooks and unhooks our object events /// /// True - hook, false - unhook private void HookEvents(bool hook) { if (hook == true) { CalendarView.ModelChanged += CalendarViewModelChanged; CalendarView.DateSelectionStartChanged += CalendarViewDateSelectionStartChanged; CalendarView.DateSelectionEndChanged += CalendarViewDateSelectionEndChanged; } else { CalendarView.ModelChanged -= CalendarViewModelChanged; CalendarView.DateSelectionStartChanged -= CalendarViewDateSelectionStartChanged; CalendarView.DateSelectionEndChanged -= CalendarViewDateSelectionEndChanged; } } #endregion #region Event processing /// /// DateSelectionEndChanged /// /// /// void CalendarViewDateSelectionEndChanged(object sender, DateSelectionEventArgs e) { if (CalendarView.SelectedOwnerIndex == DisplayedOwnerKeyIndex) this.DateSelectionEnd = CalendarView.DateSelectionEnd; else this.DateSelectionEnd = null; } /// /// DateSelectionStartChanged /// /// /// void CalendarViewDateSelectionStartChanged(object sender, DateSelectionEventArgs e) { if (CalendarView.SelectedOwnerIndex == DisplayedOwnerKeyIndex) this.DateSelectionStart = CalendarView.DateSelectionStart; else this.DateSelectionStart = null; } /// /// ModelChanged /// /// /// void CalendarViewModelChanged(object sender, ModelEventArgs e) { ResetView(); } #endregion #region RecalcSize /// /// Performs NeedRecalcSize requests /// public override void RecalcSize() { base.RecalcSize(); Rectangle r = Bounds; if (CalendarView.IsMultiCalendar == true) { if (NClientData.TabOrientation == eTabOrientation.Horizontal) { r.Inflate(-2, -2); if (CalendarView.ShowTabs == true) { r.Y += MultiUserTabHeight; r.Height -= MultiUserTabHeight; } } else { if (CalendarView.ShowTabs == true) { if (CalendarView.TimeLineMultiUserTabOrientation == eOrientation.Vertical) { r.X += MultiUserTabHeight + Dpi.Width4; r.Width -= (MultiUserTabHeight + Dpi.Width4); } else { r.X += MultiUserTabWidth + Dpi.Width4; r.Width -= (MultiUserTabWidth + Dpi.Width4); } } } } ClientRect = r; } #endregion #region Paint processing /// /// Paint processing /// /// public override void Paint(ItemPaintArgs e) { if (CalendarView.IsMultiCalendar == true) { if (NClientData.TabOrientation == eTabOrientation.Horizontal) DrawHorizontalLayout(e); else DrawVerticalLayout(e); } } #region DrawHorizontalLayout /// /// Draws horizontal tab layout /// /// private void DrawHorizontalLayout(ItemPaintArgs e) { Graphics g = e.Graphics; Rectangle r = Bounds; r.Width = _ClientRect.Width; r.Height = MultiUserTabHeight + 3; if (r.Width > 0) { // Size-up the tab dimensions string s = string.IsNullOrEmpty(DisplayName) ? OwnerKey : DisplayName; Size sz = TextDrawing.MeasureString(g, s, Font); // Draw the control background border, and tab, DrawBackBorder(g, sz.Width); DrawHTab(e, s, sz.Width, r); } } #region DrawBackBorder /// /// Draws the background border around /// the entire control view /// /// /// private void DrawBackBorder(Graphics g, int width) { Rectangle r = _ClientRect; if (g.ClipBounds.X > r.X) { r.Width -= (int) (g.ClipBounds.X - r.X); r.X = (int) g.ClipBounds.X + 1; } if (g.ClipBounds.Right < r.Right) r.Width = (int) g.ClipBounds.Right - r.X - 1; if (CalendarView.DoRenderViewBorder(g, this, r) == false) { using (Pen pen = new Pen(_CalendarColor.GetColor(_NClientData.ContBack))) { g.DrawLines(pen, new Point[] { new Point(r.Left - 1, r.Y - 1), new Point(r.Right, r.Top - 1), new Point(r.Right, r.Bottom), new Point(r.Left - 1, r.Bottom), new Point(r.Left - 1, r.Top - 2), new Point(r.Right, r.Top - 2), }); } using (Pen pen = new Pen(_CalendarColor.GetColor(_NClientData.TabBorder))) { // Draw the tab border if (width + MultiUserTabHeight < _ClientRect.Width) { g.DrawLine(pen, _ClientRect.Left + width + MultiUserTabHeight, _ClientRect.Top - 2, _ClientRect.Right + 1, _ClientRect.Top - 2); } g.DrawLines(pen, new Point[] { new Point(_ClientRect.Right + 1, _ClientRect.Top - 2), new Point(_ClientRect.Right + 1, _ClientRect.Bottom + 1), new Point(_ClientRect.Left - 2, _ClientRect.Bottom + 1), new Point(_ClientRect.Left - 2, _ClientRect.Top - 2), }); } } } #endregion #region DrawHTab /// /// Draws the tab - border and content /// /// ItemPaintArgs /// Tab text /// Text measured width /// Bounding rectangle private void DrawHTab(ItemPaintArgs e, string text, int width, Rectangle r) { _TabWidth = Math.Min(width, _ClientRect.Width); if (CalendarView.ShowTabs == true) { if (e.ClipRectangle.Y < _ClientRect.Y) { Graphics g = e.Graphics; bool isSelected = (CalendarView.SelectedOwnerIndex == DisplayedOwnerKeyIndex); // Draw the tab using (GraphicsPath path = GetHTabPath(_TabWidth)) { if (CalendarView.DoRenderTabBackground(g, path, this, isSelected) == false) { using (Brush br = _CalendarColor.BrushPart( isSelected ? _NClientData.TabSelBack : _NClientData.TabBack, r)) { g.FillPath(br, path); } using (Pen pen = new Pen(_CalendarColor.GetColor(_NClientData.TabBorder))) { g.DrawPath(pen, path); } } // Draw the tab text if (CalendarView.DoRenderTabContent( g, path, this, ref text, isSelected) == false) { r.X += 4; Color color = _CalendarColor.GetColor(isSelected ? _NClientData.TabSelFore : _NClientData.TabFore); TextDrawing.DrawString(g, text, Font, color, r, eTextFormat.VerticalCenter); } } } } } #endregion #region GetHTabPath /// /// Gets the tab graphics path /// /// Tab width /// GraphicsPath protected GraphicsPath GetHTabPath(int tabWidth) { GraphicsPath path = new GraphicsPath(); Rectangle r = ClientRect; r.Width = tabWidth; r.Height = MultiUserTabHeight; path.AddLine(ClientRect.Left - 2, ClientRect.Top - 2, ClientRect.Left - 2, Bounds.Top + TabRadius); path.AddArc(ClientRect.Left - 2, Bounds.Y, TabDia, TabDia, 180, 90); if (tabWidth + MultiUserTabHeight < ClientRect.Width) { // Full tab path.AddLines(new Point[] { new Point(ClientRect.Left - 2 + TabRadius, Bounds.Top), new Point(ClientRect.Left + tabWidth, Bounds.Top), new Point(ClientRect.Left + tabWidth + MultiUserTabHeight, ClientRect.Top - 2) }); } else if (tabWidth < ClientRect.Width) { // Partial tab with end slant int n = ClientRect.Width - tabWidth + 2; path.AddLines(new Point[] { new Point(ClientRect.Left - 2 + TabRadius, Bounds.Top), new Point(ClientRect.Left + tabWidth, Bounds.Top), new Point(ClientRect.Left - 2 + tabWidth + n, Bounds.Top + n), new Point(ClientRect.Left - 2 + tabWidth + n, ClientRect.Top - 2) }); } else { // partial tab with no end slant path.AddLines(new Point[] { new Point(ClientRect.Left - 2 + TabRadius, Bounds.Top), new Point(ClientRect.Right + 1, Bounds.Top), new Point(ClientRect.Right + 1, ClientRect.Top - 2) }); } return (path); } #endregion #endregion #region DrawVerticalLayout /// /// Draws vertical tab layout /// /// private void DrawVerticalLayout(ItemPaintArgs e) { if (CalendarView.ShowTabs == true) { Rectangle r = ClientRect; if (r.Height > 0) { if (CalendarView.TimeLineMultiUserTabOrientation == eOrientation.Vertical) { r.X -= MultiUserTabHeight; r.Width = MultiUserTabHeight; DrawVTab(e, string.IsNullOrEmpty(DisplayName) ? OwnerKey : DisplayName, r); } else { r.X -= MultiUserTabWidth; r.Width = MultiUserTabWidth; DrawVTab2(e, string.IsNullOrEmpty(DisplayName) ? OwnerKey : DisplayName, r); } } } } #region DrawVTab /// /// Draws the tab - border and content /// /// ItemPaintArgs /// Tab text /// Bounding rectangle private void DrawVTab(ItemPaintArgs e, string text, Rectangle r) { if (e.ClipRectangle.X < _ClientRect.X) { Graphics g = e.Graphics; _TabWidth = _ClientRect.Height - MultiUserTabHeight; if (_TabWidth < MultiUserTabHeight) _TabWidth = Math.Min(MultiUserTabHeight, Math.Max(0, _ClientRect.Height - 4)); bool isSelected = CalendarView.SelectedOwnerIndex == DisplayedOwnerKeyIndex; using (GraphicsPath path = GetVTabPath(_TabWidth)) { // Draw the tab if (CalendarView.DoRenderTabBackground(g, path, this, isSelected) == false) { using (Brush br = _CalendarColor.BrushPart( isSelected ? _NClientData.TabSelBack : _NClientData.TabBack, r)) { g.FillPath(br, path); } using (Pen pen = new Pen(_CalendarColor.GetColor(_NClientData.TabBorder))) { g.DrawPath(pen, path); } } // Draw the tab text if (CalendarView.DoRenderTabContent(g, path, this, ref text, isSelected) == false) { r.Height -= 4; // Set uo our output to have vertically centered text StringFormat sf = new StringFormat(); sf.FormatFlags = StringFormatFlags.NoWrap; sf.Alignment = StringAlignment.Center; // Calc our rect origin and prepare to // output the SideBar text PointF ptf = new PointF(r.X, r.Bottom); Rectangle rf = new Rectangle(0, 0, _TabWidth, MultiUserTabHeight); g.TranslateTransform(ptf.X, ptf.Y); g.RotateTransform(-90); using (Brush br = _CalendarColor.BrushPart( isSelected ? _NClientData.TabSelFore : _NClientData.TabFore, rf)) { g.DrawString(text, Font, br, rf, sf); } g.ResetTransform(); } } } } #endregion #region GetVTabPath /// /// Gets the tab graphics path /// /// Tab width /// GraphicsPath protected GraphicsPath GetVTabPath(int tabWidth) { GraphicsPath path = new GraphicsPath(); Rectangle r = ClientRect; r.X -= (MultiUserTabHeight + 1); r.Width = MultiUserTabHeight; path.AddLine(r.Right, r.Bottom - 1, r.X + TabRadius, r.Bottom - 1); path.AddArc(r.X, r.Bottom - 1 - TabDia, TabDia, TabDia, 90, 90); if (r.Height > MultiUserTabHeight * 2) { // Full tab path.AddLines(new Point[] { new Point(r.X, r.Bottom - TabRadius), new Point(r.X, r.Bottom - tabWidth), new Point(r.Right, r.Bottom - tabWidth - MultiUserTabHeight) }); } else if (r.Height > MultiUserTabHeight) { // Partial tab with end slant int n = r.Height - MultiUserTabHeight; path.AddLines(new Point[] { new Point(r.X, r.Bottom - TabRadius), new Point(r.X, r.Top + n), new Point(r.X + n, r.Y), new Point(r.Right, r.Y) }); } else { // partial tab with no end slant path.AddLines(new Point[] { new Point(r.X, Bounds.Bottom - TabRadius), new Point(r.X, Bounds.Top), new Point(r.X + MultiUserTabHeight, Bounds.Top) }); } return (path); } #endregion #region DrawVTab2 /// /// Draws the tab - border and content /// /// ItemPaintArgs /// Tab text /// Bounding rectangle private void DrawVTab2(ItemPaintArgs e, string text, Rectangle r) { if (e.ClipRectangle.X < _ClientRect.X) { Graphics g = e.Graphics; _TabWidth = _ClientRect.Width - MultiUserTabWidth; if (_TabWidth < MultiUserTabWidth) _TabWidth = Math.Min(MultiUserTabWidth, Math.Max(0, _ClientRect.Width - 4)); bool isSelected = CalendarView.SelectedOwnerIndex == DisplayedOwnerKeyIndex; using (GraphicsPath path = GetVTab2Path(_TabWidth)) { // Draw the tab if (CalendarView.DoRenderTabBackground(g, path, this, isSelected) == false) { using (Brush br = _CalendarColor.BrushPart( isSelected ? _NClientData.TabSelBack : _NClientData.TabBack, r)) { g.FillPath(br, path); } using (Pen pen = new Pen(_CalendarColor.GetColor(_NClientData.TabBorder))) { g.DrawPath(pen, path); } } // Draw the tab text if (CalendarView.DoRenderTabContent(g, path, this, ref text, isSelected) == false) { r.Y += 2; r.Height -= 4; // Set uo our output to have vertically centered text StringFormat sf = new StringFormat(); sf.FormatFlags = StringFormatFlags.NoWrap; sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center; // Calc our rect origin and prepare to // output the SideBar text using (Brush br = _CalendarColor.BrushPart( isSelected ? _NClientData.TabSelFore : _NClientData.TabFore, r)) { g.DrawString(text, Font, br, r, sf); } } } } } #endregion #region GetVTab2Path /// /// Gets the tab graphics path /// /// Tab width /// GraphicsPath protected GraphicsPath GetVTab2Path(int tabWidth) { GraphicsPath path = new GraphicsPath(); Rectangle r = ClientRect; r.X -= (MultiUserTabWidth + 1); r.Width = MultiUserTabWidth; path.AddLine(r.Right, r.Bottom - 1, r.X + TabRadius, r.Bottom - 1); path.AddArc(r.X, r.Bottom - 1 - TabDia, TabDia, TabDia, 90, 90); path.AddArc(r.X, r.Top, TabDia, TabDia, 180, 90); path.AddLine(r.Right, r.Top, r.Right, r.Bottom - 1); path.CloseFigure(); return (path); } #endregion #endregion #endregion #region GetTabPath /// /// Gets the multiuser tab path /// /// /// GraphicsPath GetTabPath(int tabWidth) { if (NClientData.TabOrientation == eTabOrientation.Horizontal) return (GetHTabPath(tabWidth)); if (CalendarView.TimeLineMultiUserTabOrientation == eOrientation.Horizontal) return (GetVTab2Path(tabWidth)); return (GetVTabPath(tabWidth)); } #endregion #region PointInTab /// /// Determines if the given Point is /// within the View tab area /// /// Point in question /// true if the Point is in the tab private bool PointInTab(Point pt) { bool isInTab = false; if (CalendarView.IsMultiCalendar == true) { if (NClientData.TabOrientation == eTabOrientation.Horizontal) { if (pt.Y < ClientRect.Y) { using (GraphicsPath path = GetHTabPath(_TabWidth)) { if (path.IsVisible(pt) == true) isInTab = true; } } } else { if (pt.X < ClientRect.X) { if (CalendarView.TimeLineMultiUserTabOrientation == eOrientation.Vertical) { using (GraphicsPath path = GetVTabPath(_TabWidth)) { if (path.IsVisible(pt) == true) isInTab = true; } } else { using (GraphicsPath path = GetVTab2Path(_TabWidth)) { if (path.IsVisible(pt) == true) isInTab = true; } } } } } return (isInTab); } #endregion #region Mouse support #region InternalMouseDown /// /// MouseDown processing /// /// MouseEventArgs public override void InternalMouseDown(MouseEventArgs objArg) { // Pass the event on through base.InternalMouseDown(objArg); // Check to see if the use is attempting to reorder // the view via MouseDown in the view tab Point pt = objArg.Location; if (PointInTab(pt) == true) { SelectedItem = null; _CalendarView.SelectedOwnerIndex = DisplayedOwnerKeyIndex; if (objArg.Button == MouseButtons.Left) { if (CalendarView.AllowTabReorder && CalendarView.DisplayedOwners.Count > 1) { _IsTabMoving = true; _LastViewIndex = CalendarView.GetViewIndexFromPoint(pt); } } } else if (pt.Y >= ClientRect.Y) { _CalendarView.SelectedOwnerIndex = DisplayedOwnerKeyIndex; } IsNewCopyDrag = false; } #endregion #region InternalMouseMove /// /// MouseMove processing /// /// public override void InternalMouseMove(MouseEventArgs objArg) { // Pass the event on through base.InternalMouseMove(objArg); // If the user has initiated a tab reorder, then // track the tab movement if (_IsTabMoving == true) { Point pt = objArg.Location; int viewIndex = CalendarView.GetViewIndexFromPoint(pt); // If the user has dragged the tab to another view location // then reorder the tabs accordingly if (viewIndex >= 0 && viewIndex != _LastViewIndex) { CalendarView.ReorderViews(_LastViewIndex, viewIndex); _LastViewIndex = viewIndex; } MyCursor = Cursors.SizeAll; } } #endregion #region InternalMouseUp /// /// MouseUp processing /// /// public override void InternalMouseUp(MouseEventArgs objArg) { base.InternalMouseUp(objArg); // Hide our PosWindow if it is visible if (_PosWin != null) _PosWin.Hide(); if (SelectedItem != null) { // DoAppointmentViewChanged if (IsMoving == true) { if (TimeChanged(SelectedItem) == true || OwnerChanged() == true || IsCopyDrag == true || IsNewCopyDrag == true) { DoViewChanged(SelectedItem, eViewOperation.AppointmentMove); } } else if (IsResizing == true) { if (TimeChanged(SelectedItem) == true) DoViewChanged(SelectedItem, eViewOperation.AppointmentResize); } } // Reset our mouse states ClearMouseStates(); } private bool TimeChanged(CalendarItem item) { return (item.StartTime != _oldStartTime || item.EndTime != _oldEndTime); } private bool OwnerChanged() { if (OwnerKey != null) return (OwnerKey.Equals(_oldOwnerKey) == false); return (false); } private void DoViewChanged(CalendarItem item, eViewOperation eop) { if (item.StartTime != _oldStartTime) UpdateReminders(item, _oldStartTime); CalendarView.DoAppointmentViewChanged(item, _oldOwnerKey, _oldStartTime, _oldEndTime, eop, _IsNewCopyDrag); } /// /// Clears all mouse related state flags /// protected void ClearMouseStates() { _IsMouseDown = false; _IsMoving = false; _IsStartResizing = false; _IsEndResizing = false; _IsTabMoving = false; _IsCondMoving = false; _IsCopyDrag = false; } #endregion #endregion #region DragItem /// /// Initiates dragging of a copy of the /// current selectedItem - if the ctrl-key is pressed /// /// protected bool DragCopy() { if (CalendarView.EnableDragCopy == true) { if (IsCopyDrag == false && IsNewCopyDrag == false && (Control.ModifierKeys & Keys.Control) == Keys.Control) { AppointmentView av = SelectedItem as AppointmentView; if (av != null) { Appointment ap = av.Appointment.Copy(); CalendarModel.Appointments.Add(ap); IsNewCopyDrag = true; return (true); } } } return (false); } #endregion #region UpdateReminders /// /// Updates associated appointment reminders /// after an appointment has been moved /// protected void UpdateReminders(CalendarItem item, DateTime oldStartTime) { //AppointmentView view = item as AppointmentView; //if (view != null) //{ // ReminderCollection rc = view.Appointment.Reminders; // if (rc != null && rc.Count > 0) // { // TimeSpan ts = item.StartTime - oldStartTime; // for (int i = 0; i < rc.Count; i++) // rc[i].ReminderTime = rc[i].ReminderTime.Add(ts); // } //} } #endregion #region GetViewAreaFromPoint /// /// Gets the view area under the given mouse /// point (tab, header, content, etc) /// /// Point /// eViewArea public virtual eViewArea GetViewAreaFromPoint(Point pt) { if (Bounds.Contains(pt) == true) { if (NClientData.TabOrientation == eTabOrientation.Horizontal) { if (pt.Y < ClientRect.Y) { using (GraphicsPath path = GetTabPath(_TabWidth)) { if (path.IsVisible(pt) == true) return (eViewArea.InTab); } } } else { if (pt.X < ClientRect.X) { using (GraphicsPath path = GetTabPath(_TabWidth)) { if (path.IsVisible(pt) == true) return (eViewArea.InTab); } } } } return (eViewArea.NotInView); } #endregion #region GetDateSelectionFromPoint /// /// Gets the date selection from the given point. The startDate /// and endDate will vary based upon the view type (WeekDay / Month) /// /// Point in question /// out start date /// out end date /// True if a valid selection exists /// at the given point public virtual bool GetDateSelectionFromPoint( Point pt, out DateTime startDate, out DateTime endDate) { startDate = new DateTime(); endDate = new DateTime(); return (false); } #endregion #region GetAppointmentView /// /// Gets the appointment view created for an appointment in this view /// /// The appointment /// Reference to AppointmentView or null if no view is found public virtual AppointmentView GetAppointmentView(Appointment appointment) { for (int i = 0; i < SubItems.Count; i++) { AppointmentView view = SubItems[i] as AppointmentView; if (view != null) { if (view.Appointment == appointment) return (view); } } return (null); } #endregion #region GetAppointmentViewFromPoint /// /// Gets the appointment view created for an appointment in this view /// /// The appointment /// Reference to AppointmentView or null if no view is found public virtual AppointmentView GetAppointmentViewFromPoint(Point pt) { for (int i = 0; i < SubItems.Count; i++) { AppointmentView view = SubItems[i] as AppointmentView; if (view != null) { if (view.Bounds.Contains(pt)) return (view); } } return (null); } #endregion #region CustomCalendarItem /// /// Gets the CustomCalendarItem created for this view /// /// Reference to CustomCalendarItem or null if none found public virtual CustomCalendarItem GetCustomCalendarItem(CustomCalendarItem item) { if (item.BaseCalendarItem != null) item = item.BaseCalendarItem; for (int i = 0; i < SubItems.Count; i++) { CustomCalendarItem view = SubItems[i] as CustomCalendarItem; if (view != null) { if (view == item || view.BaseCalendarItem == item) return (view); } } return (null); } #endregion #region Invalidate routines /// /// Invalidates the given rectangle /// internal void InvalidateRect() { InvalidateRect(ClientRect, false); } /// /// Invalidates the entire calendar /// bounding rect area /// /// NeedRecalcSize flag internal void InvalidateRect(bool needRecalc) { InvalidateRect(ClientRect, needRecalc); } /// /// Invalidates the entire calendar /// bounding rect area /// internal void InvalidateRect(Rectangle rect) { InvalidateRect(rect, false); } /// /// Invalidates the given rectangle /// /// Rectangle to invalidate /// NeedRecalcSize flag internal void InvalidateRect(Rectangle rect, bool needRecalc) { Control c = (Control)this.GetContainerControl(true); if (c != null) { rect.Height += 0; rect.Width += 0; if (rect.Bottom >= ClientRect.Bottom) rect.Width += 0; c.Invalidate(rect); } if (needRecalc == true) this.NeedRecalcSize = true; } #endregion #region ResetView /// /// Disconnects and resets the Model connection /// internal virtual void ResetView() { if (_Connector != null) { // Disconnect the Model _Connector.Disconnect(); _Connector = null; // Reset our selected item SelectedItem = null; } DateRangeChanged = false; NeedRecalcLayout = true; NeedRecalcSize = true; } #endregion #region ReloadView internal void ReloadView() { if (CalendarModel != null) { CalendarModel.BeginUpdate(); CalendarModel.EndUpdate(); } } #endregion #region SetSelectedItem /// /// Sets the current selected item /// /// Previously selected CalendarItem /// New CalendarItem to select /// Base selected CalendarItem protected virtual CalendarItem SetSelectedItem(CalendarItem pci, CalendarItem nci) { return (null); } #endregion #region UpdateDateSelection /// /// Updates each monthWeeks DayRects to reflect /// the date selection start and end values /// protected virtual void UpdateDateSelection() { } internal void SetDateSelection(DateTime dateStart, DateTime dateEnd) { UpdateDateSelection(); } #endregion #region AutoSyncViewDate /// /// AutoSync our view start date /// /// protected void AutoSyncViewDate(eCalendarView syncView) { if (CalendarView.AutoSyncViewDates == true) { if (CalendarView.AutoSyncDate != DateTime.MinValue) { DateTime syncDate = CalendarView.AutoSyncDate; CalendarView.ShowViewDate(this.ECalendarView, syncDate); CalendarView.AutoSyncDate = syncDate; } } } #endregion #region ExtendSelection /// /// Extends the selection if the shift-key /// is pressed with selection /// /// /// protected void ExtendSelection(ref DateTime startDate, ref DateTime endDate) { if (DateSelectionAnchor.HasValue == false || ((Control.ModifierKeys & Keys.Shift) != Keys.Shift)) { DateSelectionAnchor = startDate; } else { if (DateSelectionAnchor < startDate) startDate = DateSelectionAnchor.Value; else { DateTime anchorEnd = DateSelectionAnchor.Value.Add(endDate - startDate); if (anchorEnd > endDate) endDate = anchorEnd; } } CalendarView.AutoSyncDate = startDate; } #endregion #region ValidDateSelection protected bool ValidDateSelection() { if (DateSelectionStart.HasValue && DateSelectionEnd.HasValue) { if (DateSelectionAnchor.HasValue == false) DateSelectionAnchor = DateSelectionStart; return (DateSelectionStart <= DateSelectionEnd); } return (false); } #endregion #region PosWindow support /// /// Pos window update /// protected void UpdatePosWin(Rectangle viewRect) { if (IsStartResizing || IsEndResizing || IsMoving) { // Only display if the Alt key is pressed if ((Control.ModifierKeys & Keys.Alt) == Keys.Alt) { // Allocate our pos window if not // previously allocated if (PosWin == null) { PosWin = new PosWin(this); PosWin.Size = new Size(1, 1); Control c = (Control)this.GetContainerControl(true); if (c != null) PosWin.Owner = c.FindForm(); } PosWin.UpdateWin(viewRect); } else { if (PosWin != null) PosWin.Hide(); } } } #endregion #region GetIndicatorRect internal virtual Rectangle GetIndicatorRect(TimeIndicator ti) { return (Rectangle.Empty); } internal virtual Rectangle GetIndicatorRect(TimeIndicator ti, DateTime time) { return (Rectangle.Empty); } #endregion #region InternalKeyUp internal virtual void InternalKeyUp(KeyEventArgs e) { } #endregion #region Copy implementation /// /// Returns copy of the item. /// public override BaseItem Copy() { BaseView objCopy = new BaseView(_CalendarView, _ECalendarView); CopyToItem(objCopy); return (objCopy); } /// /// Copies the BaseView specific properties to new instance of the item. /// /// New BaseView instance protected override void CopyToItem(BaseItem copy) { BaseView objCopy = copy as BaseView; if (objCopy != null) { base.CopyToItem(objCopy); objCopy._DateSelectionStart = this._DateSelectionStart; objCopy._DateSelectionEnd = this._DateSelectionEnd; objCopy._DisplayName = this._DisplayName; objCopy._EndDate = this._EndDate; objCopy._StartDate = this._StartDate; } } #endregion #region IDisposable Members protected override void Dispose(bool disposing) { if (disposing == true && IsDisposed == false) { ResetView(); HookEvents(false); } base.Dispose(disposing); } #endregion } #region enums public enum eViewArea { NotInView, InTab, InContent, InAllDayPanel, InDayOfWeekHeader, InWeekHeader, InSideBarPanel, InIntervalHeader, InPeriodHeader, InCondensedView, InMonthHeader } public enum eTabOrientation { Vertical, Horizontal, } #endregion #region EventsArgs /// /// SelectedItemChangedEventArgs /// public class SelectedItemChangedEventArgs : ValueChangedEventArgs { public SelectedItemChangedEventArgs(CalendarItem oldValue, CalendarItem newValue) : base(oldValue, newValue) { } } /// /// CalendarColorChangedEventArgs /// public class CalendarColorChangedEventArgs : ValueChangedEventArgs { public CalendarColorChangedEventArgs(eCalendarColor oldValue, eCalendarColor newValue) : base(oldValue, newValue) { } } #endregion } #endif