diff --git a/TestHarness/Form1.Designer.cs b/TestHarness/Form1.Designer.cs
new file mode 100644
index 0000000..8d672c0
--- /dev/null
+++ b/TestHarness/Form1.Designer.cs
@@ -0,0 +1,125 @@
+namespace TestHarness
+{
+ partial class Form1
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose( bool disposing )
+ {
+ if( disposing && ( components != null ) )
+ {
+ components.Dispose();
+ }
+ base.Dispose( disposing );
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+ this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
+ this.monthView1 = new WindowsFormsCalendar.MonthView();
+ this.calendar1 = new WindowsFormsCalendar.Calendar();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
+ this.splitContainer1.Panel1.SuspendLayout();
+ this.splitContainer1.Panel2.SuspendLayout();
+ this.splitContainer1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // splitContainer1
+ //
+ this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.splitContainer1.Location = new System.Drawing.Point(0, 0);
+ this.splitContainer1.Name = "splitContainer1";
+ //
+ // splitContainer1.Panel1
+ //
+ this.splitContainer1.Panel1.Controls.Add(this.monthView1);
+ //
+ // splitContainer1.Panel2
+ //
+ this.splitContainer1.Panel2.AutoScroll = true;
+ this.splitContainer1.Panel2.AutoScrollMargin = new System.Drawing.Size(5, 5);
+ this.splitContainer1.Panel2.Controls.Add(this.calendar1);
+ this.splitContainer1.Size = new System.Drawing.Size(784, 562);
+ this.splitContainer1.SplitterDistance = 260;
+ this.splitContainer1.TabIndex = 0;
+ //
+ // monthView1
+ //
+ this.monthView1.ArrowsColor = System.Drawing.SystemColors.Window;
+ this.monthView1.ArrowsSelectedColor = System.Drawing.Color.Gold;
+ this.monthView1.DayBackgroundColor = System.Drawing.Color.Empty;
+ this.monthView1.DayGrayedText = System.Drawing.SystemColors.GrayText;
+ this.monthView1.DaySelectedBackgroundColor = System.Drawing.SystemColors.Highlight;
+ this.monthView1.DaySelectedColor = System.Drawing.SystemColors.WindowText;
+ this.monthView1.DaySelectedTextColor = System.Drawing.SystemColors.HighlightText;
+ this.monthView1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.monthView1.ItemPadding = new System.Windows.Forms.Padding(2);
+ this.monthView1.Location = new System.Drawing.Point(0, 0);
+ this.monthView1.MonthTitleColor = System.Drawing.SystemColors.ActiveCaption;
+ this.monthView1.MonthTitleColorInactive = System.Drawing.SystemColors.InactiveCaption;
+ this.monthView1.MonthTitleTextColor = System.Drawing.SystemColors.ActiveCaptionText;
+ this.monthView1.MonthTitleTextColorInactive = System.Drawing.SystemColors.InactiveCaptionText;
+ this.monthView1.Name = "monthView1";
+ this.monthView1.SelectionMode = WindowsFormsCalendar.MonthViewSelection.Week;
+ this.monthView1.Size = new System.Drawing.Size(260, 562);
+ this.monthView1.TabIndex = 0;
+ this.monthView1.Text = "monthView1";
+ this.monthView1.TodayBorderColor = System.Drawing.Color.Maroon;
+ this.monthView1.SelectionChanged += new System.EventHandler(this.monthView1_SelectionChanged);
+ //
+ // calendar1
+ //
+ this.calendar1.AllowDrop = true;
+ this.calendar1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.calendar1.Font = new System.Drawing.Font("Segoe UI", 9F);
+ this.calendar1.ItemsBackgroundColor = System.Drawing.Color.Red;
+ this.calendar1.ItemsFont = new System.Drawing.Font("Monotype Corsiva", 12F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.calendar1.ItemsForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(192)))));
+ this.calendar1.Location = new System.Drawing.Point(0, 0);
+ this.calendar1.Name = "calendar1";
+ this.calendar1.Size = new System.Drawing.Size(520, 562);
+ this.calendar1.TabIndex = 0;
+ this.calendar1.Text = "calendar1";
+ this.calendar1.LoadItems += new WindowsFormsCalendar.Calendar.CalendarLoadEventHandler(this.calendar1_LoadItems);
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(784, 562);
+ this.Controls.Add(this.splitContainer1);
+ this.MinimumSize = new System.Drawing.Size(800, 600);
+ this.Name = "Form1";
+ this.Text = "Test Harness";
+ this.splitContainer1.Panel1.ResumeLayout(false);
+ this.splitContainer1.Panel2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
+ this.splitContainer1.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.SplitContainer splitContainer1;
+ private WindowsFormsCalendar.MonthView monthView1;
+ private WindowsFormsCalendar.Calendar calendar1;
+ private System.Windows.Forms.ToolTip toolTip1;
+ }
+}
+
diff --git a/TestHarness/Form1.cs b/TestHarness/Form1.cs
new file mode 100644
index 0000000..61ddad5
--- /dev/null
+++ b/TestHarness/Form1.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+
+using WindowsFormsCalendar;
+
+namespace TestHarness
+{
+ public partial class Form1 : Form
+ {
+ #region Fields
+
+ private List _items = new List();
+
+ #endregion
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public Form1()
+ {
+ InitializeComponent();
+
+ CalendarItem item = new CalendarItem( this.calendar1, DateTime.Now, DateTime.Now, "TEST" );
+
+ _items.Add( item );
+
+ }
+
+ #region Calendar Methods
+
+ ///
+ /// Handles the LoadItems event of the calendar1 control.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ private void calendar1_LoadItems( object sender, CalendarLoadEventArgs e )
+ {
+ foreach( CalendarItem calendarItem in _items )
+ {
+ if( this.calendar1.ViewIntersects( calendarItem ) )
+ {
+ this.calendar1.Items.Add( calendarItem );
+ }
+ }
+ }
+
+ #endregion
+
+ #region Month View Methods
+
+ ///
+ /// Handles the SelectionChanged event of the monthView1 control.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ private void monthView1_SelectionChanged( object sender, EventArgs e )
+ {
+ this.calendar1.SetViewRange( this.monthView1.SelectionStart.Date, this.monthView1.SelectionEnd.Date);
+ }
+
+ #endregion
+
+ }
+}
\ No newline at end of file
diff --git a/TestHarness/Form1.resx b/TestHarness/Form1.resx
new file mode 100644
index 0000000..7734f57
--- /dev/null
+++ b/TestHarness/Form1.resx
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+ 54
+
+
\ No newline at end of file
diff --git a/TestHarness/Program.cs b/TestHarness/Program.cs
new file mode 100644
index 0000000..45daddf
--- /dev/null
+++ b/TestHarness/Program.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace TestHarness
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault( false );
+ Application.Run( new Form1() );
+ }
+ }
+}
diff --git a/TestHarness/Properties/AssemblyInfo.cs b/TestHarness/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..20364db
--- /dev/null
+++ b/TestHarness/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle( "TestHarness" )]
+[assembly: AssemblyDescription( "" )]
+[assembly: AssemblyConfiguration( "" )]
+[assembly: AssemblyCompany( "HP" )]
+[assembly: AssemblyProduct( "TestHarness" )]
+[assembly: AssemblyCopyright( "Copyright © HP 2012" )]
+[assembly: AssemblyTrademark( "" )]
+[assembly: AssemblyCulture( "" )]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible( false )]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid( "734b7e11-5f67-4701-ae69-c7e558ebdb14" )]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion( "1.0.0.0" )]
+[assembly: AssemblyFileVersion( "1.0.0.0" )]
diff --git a/TestHarness/Properties/Resources.Designer.cs b/TestHarness/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..f77f918
--- /dev/null
+++ b/TestHarness/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.269
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace TestHarness.Properties
+{
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute( "System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0" )]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute( global::System.ComponentModel.EditorBrowsableState.Advanced )]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if( ( resourceMan == null ) )
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager( "TestHarness.Properties.Resources", typeof( Resources ).Assembly );
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute( global::System.ComponentModel.EditorBrowsableState.Advanced )]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/TestHarness/Properties/Resources.resx b/TestHarness/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/TestHarness/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/TestHarness/Properties/Settings.Designer.cs b/TestHarness/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..8e1c388
--- /dev/null
+++ b/TestHarness/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.269
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace TestHarness.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute( "Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0" )]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ( (Settings)( global::System.Configuration.ApplicationSettingsBase.Synchronized( new Settings() ) ) );
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/TestHarness/Properties/Settings.settings b/TestHarness/Properties/Settings.settings
new file mode 100644
index 0000000..3964565
--- /dev/null
+++ b/TestHarness/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/TestHarness/TestHarness.csproj b/TestHarness/TestHarness.csproj
new file mode 100644
index 0000000..d048f0d
--- /dev/null
+++ b/TestHarness/TestHarness.csproj
@@ -0,0 +1,93 @@
+
+
+
+ Debug
+ x86
+ 8.0.30703
+ 2.0
+ {C3A1985B-E396-4125-A176-61C2AEE5A41F}
+ WinExe
+ Properties
+ TestHarness
+ TestHarness
+ v4.0
+ Client
+ 512
+
+
+ x86
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ x86
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ Form1.cs
+
+
+
+
+ Form1.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+ {25649F08-3046-4891-ADB8-7EA787B57063}
+ WindowsFormsCalendar
+
+
+
+
+
\ No newline at end of file
diff --git a/WindowsFormsCalendar.sln b/WindowsFormsCalendar.sln
new file mode 100644
index 0000000..d17a878
--- /dev/null
+++ b/WindowsFormsCalendar.sln
@@ -0,0 +1,52 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsFormsCalendar", "WindowsFormsCalendar\WindowsFormsCalendar.csproj", "{25649F08-3046-4891-ADB8-7EA787B57063}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestHarness", "TestHarness\TestHarness.csproj", "{C3A1985B-E396-4125-A176-61C2AEE5A41F}"
+ ProjectSection(ProjectDependencies) = postProject
+ {25649F08-3046-4891-ADB8-7EA787B57063} = {25649F08-3046-4891-ADB8-7EA787B57063}
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9A09091C-9031-48EA-8EB5-C40716E28351}"
+ ProjectSection(SolutionItems) = preProject
+ WindowsFormsCalendar\GPL v3.txt = WindowsFormsCalendar\GPL v3.txt
+ WindowsFormsCalendar\ReadMe.txt = WindowsFormsCalendar\ReadMe.txt
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|Mixed Platforms = Debug|Mixed Platforms
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|Mixed Platforms = Release|Mixed Platforms
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {25649F08-3046-4891-ADB8-7EA787B57063}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {25649F08-3046-4891-ADB8-7EA787B57063}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {25649F08-3046-4891-ADB8-7EA787B57063}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {25649F08-3046-4891-ADB8-7EA787B57063}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {25649F08-3046-4891-ADB8-7EA787B57063}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {25649F08-3046-4891-ADB8-7EA787B57063}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {25649F08-3046-4891-ADB8-7EA787B57063}.Release|Any CPU.Build.0 = Release|Any CPU
+ {25649F08-3046-4891-ADB8-7EA787B57063}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {25649F08-3046-4891-ADB8-7EA787B57063}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {25649F08-3046-4891-ADB8-7EA787B57063}.Release|x86.ActiveCfg = Release|Any CPU
+ {C3A1985B-E396-4125-A176-61C2AEE5A41F}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {C3A1985B-E396-4125-A176-61C2AEE5A41F}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
+ {C3A1985B-E396-4125-A176-61C2AEE5A41F}.Debug|Mixed Platforms.Build.0 = Debug|x86
+ {C3A1985B-E396-4125-A176-61C2AEE5A41F}.Debug|x86.ActiveCfg = Debug|x86
+ {C3A1985B-E396-4125-A176-61C2AEE5A41F}.Debug|x86.Build.0 = Debug|x86
+ {C3A1985B-E396-4125-A176-61C2AEE5A41F}.Release|Any CPU.ActiveCfg = Release|x86
+ {C3A1985B-E396-4125-A176-61C2AEE5A41F}.Release|Any CPU.Build.0 = Release|x86
+ {C3A1985B-E396-4125-A176-61C2AEE5A41F}.Release|Mixed Platforms.ActiveCfg = Release|x86
+ {C3A1985B-E396-4125-A176-61C2AEE5A41F}.Release|Mixed Platforms.Build.0 = Release|x86
+ {C3A1985B-E396-4125-A176-61C2AEE5A41F}.Release|x86.ActiveCfg = Release|x86
+ {C3A1985B-E396-4125-A176-61C2AEE5A41F}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/WindowsFormsCalendar/CalendarColorTable.cs b/WindowsFormsCalendar/CalendarColorTable.cs
new file mode 100644
index 0000000..dbb91ab
--- /dev/null
+++ b/WindowsFormsCalendar/CalendarColorTable.cs
@@ -0,0 +1,271 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Provides color information of calendar graphical elements
+ ///
+ public class CalendarColorTable
+ {
+ #region Static
+
+ ///
+ /// Returns the result of combining the specified colors
+ ///
+ /// First color to combine
+ /// Second olor to combine
+ /// Average of both colors
+ public static Color Combine(Color c1, Color c2)
+ {
+ return Color.FromArgb(
+ (c1.R + c2.R) / 2,
+ (c1.G + c2.G) / 2,
+ (c1.B + c2.B) / 2
+ );
+ }
+
+ ///
+ /// Converts the hex formatted color to a
+ ///
+ ///
+ ///
+ public static Color FromHex(string hex)
+ {
+ if (hex.StartsWith("#"))
+ hex = hex.Substring(1);
+
+ if (hex.Length != 6) throw new Exception("Color not valid");
+
+ return Color.FromArgb(
+ int.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber),
+ int.Parse(hex.Substring(2, 2), System.Globalization.NumberStyles.HexNumber),
+ int.Parse(hex.Substring(4, 2), System.Globalization.NumberStyles.HexNumber));
+ }
+
+ #endregion
+
+ #region Colors
+
+ ///
+ /// Background color of calendar
+ ///
+ public Color Background = SystemColors.Control;
+
+ ///
+ /// Background color of days in even months
+ ///
+ public Color DayBackgroundEven = SystemColors.Control;
+
+ ///
+ /// Background color of days in odd months
+ ///
+ public Color DayBackgroundOdd = SystemColors.ControlLight;
+
+ ///
+ /// Background color of selected days
+ ///
+ public Color DayBackgroundSelected = SystemColors.Highlight;
+
+ ///
+ /// Border of
+ ///
+ public Color DayBorder = SystemColors.ControlDark;
+
+ ///
+ /// Background color of day headers.
+ ///
+ public Color DayHeaderBackground = Combine(SystemColors.ControlDark, SystemColors.Control);
+
+ ///
+ /// Color of text of day headers
+ ///
+ public Color DayHeaderText = SystemColors.GrayText;
+
+ ///
+ /// Color of secondary text in headers
+ ///
+ public Color DayHeaderSecondaryText = SystemColors.GrayText;
+
+ ///
+ /// Color of border of the top part of the days
+ ///
+ ///
+ /// The DayTop is the zone of the calendar where items that lasts all or more are placed.
+ ///
+ public Color DayTopBorder = SystemColors.ControlDark;
+
+ ///
+ /// Color of border of the top parth of the days when selected
+ ///
+ ///
+ /// The DayTop is the zone of the calendar where items that lasts all or more are placed.
+ ///
+ public Color DayTopSelectedBorder = SystemColors.ControlDark;
+
+ ///
+ /// Background color of day tops.
+ ///
+ ///
+ /// The DayTop is the zone of the calendar where items that lasts all or more are placed.
+ ///
+ public Color DayTopBackground = SystemColors.ControlLight;
+
+ ///
+ /// Background color of selected day tops.
+ ///
+ ///
+ /// The DayTop is the zone of the calendar where items that lasts all or more are placed.
+ ///
+ public Color DayTopSelectedBackground = SystemColors.Highlight;
+
+ ///
+ /// Color of items borders
+ ///
+ public Color ItemBorder = SystemColors.ControlText;
+
+ ///
+ /// Background color of items
+ ///
+ public Color ItemBackground = SystemColors.Window;
+
+ ///
+ /// Forecolor of items
+ ///
+ public Color ItemText = SystemColors.WindowText;
+
+ ///
+ /// Color of secondary text on items (Dates and times)
+ ///
+ public Color ItemSecondaryText = SystemColors.GrayText;
+
+ ///
+ /// Color of items shadow
+ ///
+ public Color ItemShadow = Color.FromArgb(50, Color.Black);
+
+ ///
+ /// Color of items selected border
+ ///
+ public Color ItemSelectedBorder = SystemColors.Highlight;
+
+ ///
+ /// Background color of selected items
+ ///
+ public Color ItemSelectedBackground = Combine(SystemColors.Highlight, SystemColors.HighlightText);
+
+ ///
+ /// Forecolor of selected items
+ ///
+ public Color ItemSelectedText = SystemColors.WindowText;
+
+ ///
+ /// Background color of week headers
+ ///
+ public Color WeekHeaderBackground = Combine(SystemColors.ControlDark, SystemColors.Control);
+
+ ///
+ /// Border color of week headers
+ ///
+ public Color WeekHeaderBorder = SystemColors.ControlDark;
+
+ ///
+ /// Forecolor of week headers
+ ///
+ public Color WeekHeaderText = SystemColors.ControlText;
+
+ ///
+ /// Forecolor of day names
+ ///
+ public Color WeekDayName = SystemColors.ControlText;
+
+ ///
+ /// Border color of today day
+ ///
+ public Color TodayBorder = Color.Orange;
+
+ ///
+ /// Background color of today's DayTop
+ ///
+ public Color TodayTopBackground = Color.Orange;
+
+ ///
+ /// Color of lines in timescale
+ ///
+ public Color TimeScaleLine = SystemColors.ControlDark;
+
+ ///
+ /// Color of text representing hours on the timescale
+ ///
+ public Color TimeScaleHours = SystemColors.GrayText;
+
+ ///
+ /// Color of text representing minutes on the timescale
+ ///
+ public Color TimeScaleMinutes = SystemColors.GrayText;
+
+ ///
+ /// Background color of time units
+ ///
+ public Color TimeUnitBackground = SystemColors.Control;
+
+ ///
+ /// Background color of highlighted time units
+ ///
+ public Color TimeUnitHighlightedBackground = Combine(SystemColors.Control, SystemColors.ControlLightLight);
+
+ ///
+ /// Background color of selected time units
+ ///
+ public Color TimeUnitSelectedBackground = SystemColors.Highlight;
+
+ ///
+ /// Color of light border of time units
+ ///
+ public Color TimeUnitBorderLight = SystemColors.ControlDark;
+
+ ///
+ /// Color of dark border of time units
+ ///
+ public Color TimeUnitBorderDark = SystemColors.ControlDarkDark;
+
+ ///
+ /// Border color of the overflow indicators
+ ///
+ public Color DayOverflowBorder = Color.White;
+
+ ///
+ /// Background color of the overflow indicators
+ ///
+ public Color DayOverflowBackground = SystemColors.ControlLight;
+
+ ///
+ /// Background color of selected overflow indicators
+ ///
+ public Color DayOverflowSelectedBackground = Color.Orange;
+
+ #endregion
+ }
+}
+
diff --git a/WindowsFormsCalendar/CalendarDay.cs b/WindowsFormsCalendar/CalendarDay.cs
new file mode 100644
index 0000000..663fc22
--- /dev/null
+++ b/WindowsFormsCalendar/CalendarDay.cs
@@ -0,0 +1,335 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Represents a day present on the control's view.
+ ///
+ public class CalendarDay
+ : CalendarSelectableElement
+ {
+ #region Static
+
+ private Size overflowSize = new Size(16, 16);
+ private Padding overflowPadding = new Padding(5);
+
+ #endregion
+
+ #region Events
+
+ #endregion
+
+ #region Fields
+ private List _containedItems;
+ private Calendar _calendar;
+ private DateTime _date;
+ private CalendarDayTop _dayTop;
+ private int _index;
+ private bool _overflowStart;
+ private bool _overflowEnd;
+ private bool _overflowStartSelected;
+ private bool _overlowEndSelected;
+ private CalendarTimeScaleUnit[] _timeUnits;
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets a list of items contained on the day
+ ///
+ internal List ContainedItems
+ {
+ get { return _containedItems; }
+ }
+
+ ///
+ /// Gets the DayTop of the day, the place where multi-day and all-day items are placed
+ ///
+ public CalendarDayTop DayTop
+ {
+ get { return _dayTop; }
+ }
+
+ ///
+ /// Gets the bounds of the body of the day (where time-based CalendarItems are placed)
+ ///
+ public Rectangle BodyBounds
+ {
+ get
+ {
+ return Rectangle.FromLTRB(Bounds.Left, DayTop.Bounds.Bottom, Bounds.Right, Bounds.Bottom);
+ }
+ }
+
+ ///
+ /// Gets the date this day represents
+ ///
+ public override DateTime Date
+ {
+ get { return _date; }
+ }
+
+ ///
+ /// Gets the bounds of the header of the day
+ ///
+ public Rectangle HeaderBounds
+ {
+ get
+ {
+ return new Rectangle(Bounds.Left, Bounds.Top, Bounds.Width, Calendar.Renderer.DayHeaderHeight);
+ }
+ }
+
+ ///
+ /// Gets the index of this day on the calendar
+ ///
+ public int Index
+ {
+ get { return _index; }
+ }
+
+ ///
+ /// Gets a value indicating if the day is specified on the view (See remarks).
+ ///
+ ///
+ /// A day may not be specified on the view, but still present to make up a square calendar.
+ /// This days should be drawn in a way that indicates it's necessary but unrequested presence.
+ ///
+ public bool SpecifiedOnView
+ {
+ get
+ {
+ return Date.CompareTo(Calendar.ViewStart) >= 0 && Date.CompareTo(Calendar.ViewEnd) <= 0;
+ }
+ }
+
+ ///
+ /// Gets the time units contained on the day
+ ///
+ public CalendarTimeScaleUnit[] TimeUnits
+ {
+ get { return _timeUnits; }
+ }
+
+ ///
+ /// ///
+ /// Gets a value indicating if the day contains items not shown through the start of the day
+ ///
+ ///
+ public bool OverflowStart
+ {
+ get { return _overflowStart; }
+ }
+
+ ///
+ /// Gets the bounds of the indicator
+ ///
+ public virtual Rectangle OverflowStartBounds
+ {
+ get { return new Rectangle(new Point(Bounds.Right - overflowPadding.Right - overflowSize.Width, Bounds.Top + overflowPadding.Top), overflowSize); }
+ }
+
+ ///
+ /// Gets a value indicating if the indicator is currently selected
+ ///
+ ///
+ /// This value set to true when user hovers the mouse on the area
+ ///
+ public bool OverflowStartSelected
+ {
+ get { return _overflowStartSelected; }
+ }
+
+ ///
+ /// Gets a value indicating if the day contains items not shown through the end of the day
+ ///
+ public bool OverflowEnd
+ {
+ get { return _overflowEnd; }
+ }
+
+ ///
+ /// Gets the bounds of the indicator
+ ///
+ public virtual Rectangle OverflowEndBounds
+ {
+ get { return new Rectangle(new Point(Bounds.Right - overflowPadding.Right - overflowSize.Width, Bounds.Bottom - overflowPadding.Bottom - overflowSize.Height), overflowSize); }
+ }
+
+ ///
+ /// Gets a value indicating if the indicator is currently selected
+ ///
+ ///
+ /// This value set to true when user hovers the mouse on the area
+ ///
+ public bool OverflowEndSelected
+ {
+ get { return _overlowEndSelected; }
+ }
+
+
+ #endregion
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The calendar.
+ /// The date.
+ /// The index.
+ internal CalendarDay(Calendar calendar, DateTime date, int index)
+ : base(calendar)
+ {
+ _containedItems = new List();
+ _calendar = calendar;
+ _dayTop = new CalendarDayTop(this);
+ _date = date;
+ _index = index;
+
+ UpdateUnits();
+ }
+
+ #region Public Methods
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return Date.ToShortDateString();
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ ///
+ /// Adds an item to the list if not in yet
+ ///
+ ///
+ internal void AddContainedItem(CalendarItem item)
+ {
+ if (!ContainedItems.Contains(item))
+ {
+ ContainedItems.Add(item);
+ }
+ }
+
+ ///
+ /// Sets the value of he property
+ ///
+ /// Value of the property
+ internal void SetOverflowEnd(bool overflow)
+ {
+ _overflowEnd = overflow;
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ /// Value to pass to the property
+ internal void SetOverflowEndSelected(bool selected)
+ {
+ _overlowEndSelected= selected;
+ }
+
+ ///
+ /// Sets the value of he property
+ ///
+ /// Value of the property
+ internal void SetOverflowStart(bool overflow)
+ {
+ _overflowStart = overflow;
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ /// Value to pass to the property
+ internal void SetOverflowStartSelected(bool selected)
+ {
+ _overflowStartSelected = selected;
+ }
+
+ ///
+ /// Updates the value of property
+ ///
+ internal void UpdateUnits()
+ {
+ int factor = 0;
+
+ switch (Calendar.TimeScale)
+ {
+ case CalendarTimeScale.SixtyMinutes: factor = 1; break;
+ case CalendarTimeScale.ThirtyMinutes: factor = 2; break;
+ case CalendarTimeScale.FifteenMinutes: factor = 4; break;
+ case CalendarTimeScale.TenMinutes: factor = 6; break;
+ case CalendarTimeScale.SixMinutes: factor = 10; break;
+ case CalendarTimeScale.FiveMinutes: factor = 12; break;
+ default: throw new NotImplementedException("TimeScale not supported");
+ }
+
+ _timeUnits = new CalendarTimeScaleUnit[24 * factor];
+
+ int hourSum = 0;
+ int minSum = 0;
+
+ for (int i = 0; i < _timeUnits.Length; i++)
+ {
+ _timeUnits[i] = new CalendarTimeScaleUnit(this, i, hourSum, minSum);
+
+ minSum += 60 / factor;
+
+ if (minSum >= 60)
+ {
+ minSum = 0;
+ hourSum++;
+ }
+ }
+
+ UpdateHighlights();
+ }
+
+ ///
+ /// Updates the highlights of the units
+ ///
+ internal void UpdateHighlights()
+ {
+ if (TimeUnits == null)
+ return;
+
+ for (int i = 0; i < TimeUnits.Length; i++)
+ {
+ TimeUnits[i].SetHighlighted(TimeUnits[i].CheckHighlighted());
+ }
+ }
+
+ #endregion
+
+ }
+}
diff --git a/WindowsFormsCalendar/CalendarDayTop.cs b/WindowsFormsCalendar/CalendarDayTop.cs
new file mode 100644
index 0000000..97305e0
--- /dev/null
+++ b/WindowsFormsCalendar/CalendarDayTop.cs
@@ -0,0 +1,106 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Represents the top area of a day, where multiday and all day items are stored
+ ///
+ public class CalendarDayTop
+ : CalendarSelectableElement
+ {
+ #region Events
+
+ #endregion
+
+ #region Fields
+ private CalendarDay _day;
+ private List _passingItems;
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets the date.
+ ///
+ public override DateTime Date
+ {
+ get
+ {
+ return new DateTime(Day.Date.Year, Day.Date.Month, Day.Date.Day);
+ }
+ }
+
+ ///
+ /// Gets the Day of this DayTop
+ ///
+ public CalendarDay Day
+ {
+ get { return _day; }
+ }
+
+
+ ///
+ /// Gets the list of items passing on this daytop
+ ///
+ public List PassingItems
+ {
+ get { return _passingItems; }
+ }
+
+ #endregion
+
+ ///
+ /// Creates a new DayTop for the specified day
+ ///
+ ///
+ public CalendarDayTop(CalendarDay day)
+ : base(day.Calendar)
+ {
+ _day = day;
+ _passingItems = new List();
+ }
+
+ #region Public Methods
+
+ #endregion
+
+ #region Private Methods
+
+ ///
+ /// Adds the passing item.
+ ///
+ /// The item.
+ internal void AddPassingItem(CalendarItem item)
+ {
+ if (!PassingItems.Contains(item))
+ {
+ PassingItems.Add(item);
+ }
+ }
+
+ #endregion
+
+ }
+}
diff --git a/WindowsFormsCalendar/CalendarHighlightRange.cs b/WindowsFormsCalendar/CalendarHighlightRange.cs
new file mode 100644
index 0000000..8401b9c
--- /dev/null
+++ b/WindowsFormsCalendar/CalendarHighlightRange.cs
@@ -0,0 +1,132 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Represents a range of time that is highlighted as work-time
+ ///
+ public class CalendarHighlightRange
+ {
+ #region Events
+
+ #endregion
+
+ #region Fields
+ private Calendar _calendar;
+ private DayOfWeek _dayOfWeek;
+ private TimeSpan _startTime;
+ private TimeSpan _endTime;
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets the calendar that this range is assigned to. (If any)
+ ///
+ public Calendar Calendar
+ {
+ get { return _calendar; }
+ }
+
+ ///
+ /// Gets or sets the day of the week for this range
+ ///
+ public DayOfWeek DayOfWeek
+ {
+ get { return _dayOfWeek; }
+ set { _dayOfWeek = value; Update(); }
+ }
+
+ ///
+ /// Gets or sets the start time of the range
+ ///
+ public TimeSpan StartTime
+ {
+ get { return _startTime; }
+ set { _startTime = value; Update(); }
+ }
+
+ ///
+ /// Gets or sets the end time of the range
+ ///
+ public TimeSpan EndTime
+ {
+ get { return _endTime; }
+ set { _endTime = value; Update(); }
+ }
+
+ #endregion
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public CalendarHighlightRange()
+ {
+
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The day.
+ /// The start time.
+ /// The end time.
+ public CalendarHighlightRange( DayOfWeek day, TimeSpan startTime, TimeSpan endTime )
+ : this()
+ {
+ _dayOfWeek = day;
+ _startTime = startTime;
+ _endTime = endTime;
+ }
+
+ #region Public Methods
+
+ #endregion
+
+ #region Private Methods
+
+ ///
+ /// Tells the calendar to update the highligts
+ ///
+ private void Update()
+ {
+ if (Calendar != null)
+ {
+ Calendar.UpdateHighlights();
+ }
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ /// Calendar that this range belongs to
+ internal void SetCalendar(Calendar calendar)
+ {
+ _calendar = calendar;
+ }
+
+ #endregion
+
+ }
+}
diff --git a/WindowsFormsCalendar/CalendarItem.cs b/WindowsFormsCalendar/CalendarItem.cs
new file mode 100644
index 0000000..5b91cf7
--- /dev/null
+++ b/WindowsFormsCalendar/CalendarItem.cs
@@ -0,0 +1,891 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Represents an item of the calendar with a date and timespan
+ ///
+ ///
+ /// CalendarItem provides a graphical representation of tasks within a date range.
+ ///
+ public class CalendarItem
+ : CalendarSelectableElement
+ {
+ #region Static
+
+ ///
+ /// Compares the bounds.
+ ///
+ /// The r1.
+ /// The r2.
+ ///
+ private static int CompareBounds( Rectangle r1, Rectangle r2 )
+ {
+ return r1.Top.CompareTo( r2.Top );
+ }
+
+ #endregion
+
+ #region Events
+
+ #endregion
+
+ #region Fields
+
+ private Rectangle[] _additionalBounds;
+
+ private Color _backgroundColor;
+ private Color _backgroundColorLighter;
+ private Color _borderColor;
+
+ private DateTime _startDate;
+ private DateTime _endDate;
+
+ private Color _foreColor;
+
+ private bool _locked;
+
+ private TimeSpan _duration;
+
+ private Image _image;
+
+ private CalendarItemImageAlign _imageAlign;
+
+ private bool _isDragging;
+ private bool _isEditing;
+ private bool _isResizingStartDate;
+ private bool _isResizingEndDate;
+ private bool _isOnView;
+
+ private int _minuteStartTop;
+ private int _minuteEndTop;
+
+ private HatchStyle _pattern;
+
+ private Color _patternColor;
+
+ private List _unitsPassing;
+
+ private List _topsPassing;
+
+ private object _tag;
+
+ private string _text;
+
+ private Font _font;
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets or sets an array of rectangles containing bounds additional to Bounds property.
+ ///
+ ///
+ /// Items may contain additional bounds because of several graphical occourences, mostly when in
+ /// mode, due to the duration of the item; e.g. when an all day item lasts several weeks,
+ /// one rectangle for week must be drawn to indicate the presence of the item.
+ ///
+ public virtual Rectangle[] AditionalBounds
+ {
+ get { return _additionalBounds; }
+ set { _additionalBounds = value; }
+ }
+
+ ///
+ /// Gets or sets the a background color for the object. If Color.Empty, renderer default's will be used.
+ ///
+ public Color BackgroundColor
+ {
+ get { return _backgroundColor; }
+ set { _backgroundColor = value; }
+ }
+
+ ///
+ /// Gets or sets the lighter background color of the item
+ ///
+ public Color BackgroundColorLighter
+ {
+ get { return _backgroundColorLighter; }
+ set { _backgroundColorLighter = value; }
+ }
+
+ ///
+ /// Gets or sets the bordercolor of the item. If Color.Empty, renderer default's will be used.
+ ///
+ public Color BorderColor
+ {
+ get { return _borderColor; }
+ set { _borderColor = value; }
+ }
+
+ ///
+ /// Gets the StartDate of the item. Implemented
+ ///
+ public override DateTime Date
+ {
+ get
+ {
+ return StartDate;
+ }
+ }
+
+ ///
+ /// Gets the day on the where this item ends
+ ///
+ ///
+ /// This day is not necesarily the day corresponding to the day on ,
+ /// since this date can be out of the range of the current view.
+ /// If Item is not on view date range this property will return null.
+ ///
+ public CalendarDay DayEnd
+ {
+ get
+ {
+ if( !IsOnViewDateRange )
+ {
+ return null;
+ }
+ else if( IsOpenEnd )
+ {
+ return Calendar.Days[Calendar.Days.Length - 1];
+ }
+ else
+ {
+ return Calendar.FindDay( EndDate );
+ }
+ }
+ }
+
+ ///
+ /// Gets the day on the where this item starts
+ ///
+ ///
+ /// This day is not necesarily the day corresponding to the day on ,
+ /// since start date can be out of the range of the current view.
+ /// If Item is not on view date range this property will return null.
+ ///
+ public CalendarDay DayStart
+ {
+ get
+ {
+ if( !IsOnViewDateRange )
+ {
+ return null;
+ }
+ else if( IsOpenStart )
+ {
+ return Calendar.Days[0];
+ }
+ else
+ {
+ return Calendar.FindDay( StartDate );
+ }
+ }
+ }
+
+ ///
+ /// Gets the duration of the item
+ ///
+ public TimeSpan Duration
+ {
+ get
+ {
+ if( _duration.TotalMinutes == 0 )
+ {
+ _duration = EndDate.Subtract( StartDate );
+ }
+ return _duration;
+ }
+ }
+
+ ///
+ /// Gets or sets the end time of the item
+ ///
+ public DateTime EndDate
+ {
+ get { return _endDate; }
+ set
+ {
+ _endDate = value;
+ _duration = new TimeSpan( 0, 0, 0 );
+ ClearPassings();
+ }
+ }
+
+ ///
+ /// Gets the text of the end date
+ ///
+ public virtual string EndDateText
+ {
+ get
+ {
+ string date = string.Empty;
+ string time = string.Empty;
+
+ if( IsOpenEnd )
+ {
+ date = EndDate.ToString( Calendar.ItemsDateFormat );
+ }
+
+ if( ShowEndTime && !EndDate.TimeOfDay.Equals( new TimeSpan( 23, 59, 59 ) ) )
+ {
+ time = EndDate.ToString( Calendar.ItemsTimeFormat );
+ }
+
+ return string.Format( "{0} {1}", date, time ).Trim();
+ }
+ }
+
+ ///
+ /// Gets or sets the forecolor of the item. If Color.Empty, renderer default's will be used.
+ ///
+ public Color ForeColor
+ {
+ get { return _foreColor; }
+ set
+ {
+ _foreColor = value;
+ }
+ }
+
+ ///
+ /// Gets or sets an image for the item
+ ///
+ public Image Image
+ {
+ get { return _image; }
+ set { _image = value; }
+ }
+
+ ///
+ /// Gets or sets the alignment of the image relative to the text
+ ///
+ public CalendarItemImageAlign ImageAlign
+ {
+ get { return _imageAlign; }
+ set { _imageAlign = value; }
+ }
+
+ ///
+ /// Gets a value indicating if the item is being dragged
+ ///
+ public bool IsDragging
+ {
+ get { return _isDragging; }
+ }
+
+ ///
+ /// Gets a value indicating if the item is currently being edited by the user
+ ///
+ public bool IsEditing
+ {
+ get { return _isEditing; }
+ }
+
+ ///
+ /// Gets a value indicating if the item goes on the DayTop area of the
+ ///
+ public bool IsOnDayTop
+ {
+ get
+ {
+ return StartDate.Day != EndDate.AddSeconds( 1 ).Day;
+ }
+ }
+
+ ///
+ /// Gets a value indicating if the item is currently on view.
+ ///
+ ///
+ /// The item may not be on view because of scrolling
+ ///
+ public bool IsOnView
+ {
+ get { return _isOnView; }
+ }
+
+ ///
+ /// Gets a value indicating if the item is on the range specified by and
+ ///
+ public bool IsOnViewDateRange
+ {
+ get
+ {
+ //Checks for an intersection of item's dates against calendar dates
+ DateTime fd = Calendar.Days[0].Date;
+ DateTime ld = Calendar.Days[Calendar.Days.Length - 1].Date.Add( new TimeSpan( 23, 59, 59 ) );
+ DateTime sd = StartDate;
+ DateTime ed = EndDate;
+ return sd < ld && fd < ed;
+ }
+ }
+
+ ///
+ /// Gets a value indicating if the item's is before the date.
+ ///
+ public bool IsOpenStart
+ {
+ get
+ {
+ return StartDate.CompareTo( Calendar.Days[0].Date ) < 0;
+ }
+ }
+
+ ///
+ /// Gets a value indicating if the item's is aftter the date.
+ ///
+ public bool IsOpenEnd
+ {
+ get
+ {
+ return EndDate.CompareTo( Calendar.Days[Calendar.Days.Length - 1].Date.Add( new TimeSpan( 23, 59, 59 ) ) ) > 0;
+ }
+ }
+
+ ///
+ /// Gets a value indicating if item is being resized by the
+ ///
+ public bool IsResizingStartDate
+ {
+ get { return _isResizingStartDate; }
+ }
+
+ ///
+ /// Gets a value indicating if item is being resized by the
+ ///
+ public bool IsResizingEndDate
+ {
+ get { return _isResizingEndDate; }
+ }
+
+ ///
+ /// Gets a value indicating if this item is locked.
+ ///
+ ///
+ /// When an item is locked, the user can't drag it or change it's text
+ ///
+ public bool Locked
+ {
+ get { return _locked; }
+ set { _locked = value; }
+ }
+
+ ///
+ /// Gets the top correspoinding to the ending minute
+ ///
+ public int MinuteEndTop
+ {
+ get { return _minuteEndTop; }
+ }
+
+ ///
+ /// Gets the top corresponding to the starting minute
+ ///
+ public int MinuteStartTop
+ {
+ get { return _minuteStartTop; }
+ }
+
+ ///
+ /// Gets or sets the units that this item passes by
+ ///
+ internal List UnitsPassing
+ {
+ get { return _unitsPassing; }
+ set { _unitsPassing = value; }
+ }
+
+ ///
+ /// Gets or sets the pattern style to use in the background of item.
+ ///
+ public HatchStyle Pattern
+ {
+ get { return _pattern; }
+ set { _pattern = value; }
+ }
+
+ ///
+ /// Gets or sets the pattern's color
+ ///
+ public Color PatternColor
+ {
+ get { return _patternColor; }
+ set { _patternColor = value; }
+ }
+
+ ///
+ /// Gets the list of DayTops that this item passes thru
+ ///
+ internal List TopsPassing
+ {
+ get { return _topsPassing; }
+ }
+
+ ///
+ /// Gets a value indicating if the item should show the time of the
+ ///
+ public bool ShowStartTime
+ {
+ get
+ {
+ return IsOpenStart || ( ( this.IsOnDayTop || Calendar.DaysMode == CalendarDaysMode.Short ) && !StartDate.TimeOfDay.Equals( new TimeSpan( 0, 0, 0 ) ) );
+ }
+ }
+
+ ///
+ /// Gets a value indicating if the item should show the time of the
+ ///
+ public virtual bool ShowEndTime
+ {
+ get
+ {
+ return ( IsOpenEnd ||
+ ( ( this.IsOnDayTop || Calendar.DaysMode == CalendarDaysMode.Short ) && !EndDate.TimeOfDay.Equals( new TimeSpan( 23, 59, 59 ) ) ) ) &&
+ !( Calendar.DaysMode == CalendarDaysMode.Short && StartDate.Date == EndDate.Date );
+ }
+ }
+
+ ///
+ /// Gets the text of the start date
+ ///
+ public virtual string StartDateText
+ {
+ get
+ {
+ string date = string.Empty;
+ string time = string.Empty;
+
+ if( IsOpenStart )
+ {
+ date = StartDate.ToString( Calendar.ItemsDateFormat );
+ }
+
+ if( ShowStartTime && !StartDate.TimeOfDay.Equals( new TimeSpan( 0, 0, 0 ) ) )
+ {
+ time = StartDate.ToString( Calendar.ItemsTimeFormat );
+ }
+
+ return string.Format( "{0} {1}", date, time ).Trim();
+ }
+ }
+
+ ///
+ /// Gets or sets the start time of the item
+ ///
+ public virtual DateTime StartDate
+ {
+ get { return _startDate; }
+ set
+ {
+ _startDate = value;
+ _duration = new TimeSpan( 0, 0, 0 );
+ ClearPassings();
+ }
+ }
+
+ ///
+ /// Gets or sets a tag object for the item
+ ///
+ public object Tag
+ {
+ get { return _tag; }
+ set { _tag = value; }
+ }
+
+ ///
+ /// Gets or sets the text of the item
+ ///
+ public virtual string Text
+ {
+ get { return _text; }
+ set { _text = value; }
+ }
+
+ ///
+ /// Gets or sets the font.
+ ///
+ ///
+ /// The font.
+ ///
+ public Font Font
+ {
+ get { return _font; }
+ set { _font = value; }
+ }
+
+ #endregion
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ public CalendarItem( Calendar calendar )
+ : base( calendar )
+ {
+ _unitsPassing = new List();
+ _topsPassing = new List();
+ _backgroundColor = Color.Empty;
+ _borderColor = Color.Empty;
+ _foreColor = Color.Empty;
+ _backgroundColorLighter = Color.Empty;
+ _imageAlign = CalendarItemImageAlign.West;
+ _font = calendar.ItemsFont;
+ _backgroundColor = calendar.ItemsBackgroundColor;
+ _foreColor = calendar.ItemsForeColor;
+
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The calendar.
+ /// The start date.
+ /// The end date.
+ /// The text.
+ public CalendarItem( Calendar calendar, DateTime startDate, DateTime endDate, string text )
+ : this( calendar )
+ {
+ StartDate = startDate;
+ EndDate = endDate;
+ Text = text;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The calendar.
+ /// The start date.
+ /// The duration.
+ /// The text.
+ public CalendarItem( Calendar calendar, DateTime startDate, TimeSpan duration, string text )
+ : this( calendar, startDate, startDate.Add( duration ), text )
+ { }
+
+ #region Public Methods
+
+ ///
+ /// Applies color to background, border, and forecolor, from the specified color.
+ ///
+ /// The color.
+ public void ApplyColor( Color color )
+ {
+ BackgroundColor = color;
+ BackgroundColorLighter = Color.FromArgb(
+ color.R + ( 255 - color.R ) / 2 + ( 255 - color.R ) / 3,
+ color.G + ( 255 - color.G ) / 2 + ( 255 - color.G ) / 3,
+ color.B + ( 255 - color.B ) / 2 + ( 255 - color.B ) / 3 );
+
+ BorderColor = Color.FromArgb(
+ Convert.ToInt32( Convert.ToSingle( color.R ) * .8f ),
+ Convert.ToInt32( Convert.ToSingle( color.G ) * .8f ),
+ Convert.ToInt32( Convert.ToSingle( color.B ) * .8f ) );
+
+ int avg = ( color.R + color.G + color.B ) / 3;
+
+ if( avg > 255 / 2 )
+ {
+ ForeColor = Color.Black;
+ }
+ else
+ {
+ ForeColor = Color.White;
+ }
+ }
+
+ ///
+ /// Gets all the bounds related to the item.
+ ///
+ ///
+ ///
+ /// Items that are broken on two or more weeks may have more than one rectangle bounds.
+ ///
+ public IEnumerable GetAllBounds()
+ {
+ List r = new List( AditionalBounds == null ? new Rectangle[] { } : AditionalBounds );
+ r.Add( Bounds );
+
+ r.Sort( CompareBounds );
+
+ return r;
+ }
+
+ ///
+ /// Removes all specific coloring for the item.
+ ///
+ public void RemoveColors()
+ {
+ BackgroundColor = Color.Empty;
+ ForeColor = Color.Empty;
+ BorderColor = Color.Empty;
+ }
+
+ ///
+ /// Gets a value indicating if the specified point is in a resize zone of
+ ///
+ /// The point.
+ ///
+ public bool ResizeStartDateZone( Point point )
+ {
+ int margin = 4;
+
+ List rects = new List( GetAllBounds() );
+ Rectangle first = rects[0];
+ Rectangle last = rects[rects.Count - 1];
+
+ if( IsOnDayTop || Calendar.DaysMode == CalendarDaysMode.Short )
+ {
+ return Rectangle.FromLTRB( first.Left, first.Top, first.Left + margin, first.Bottom ).Contains( point );
+ }
+ else
+ {
+ return Rectangle.FromLTRB( first.Left, first.Top, first.Right, first.Top + margin ).Contains( point );
+ }
+ }
+
+ ///
+ /// Gets a value indicating if the specified point is in a resize zone of
+ ///
+ /// The point.
+ ///
+ public bool ResizeEndDateZone( Point point )
+ {
+ int margin = 4;
+
+ List rects = new List( GetAllBounds() );
+ Rectangle first = rects[0];
+ Rectangle last = rects[rects.Count - 1];
+
+ if( IsOnDayTop || Calendar.DaysMode == CalendarDaysMode.Short )
+ {
+ return Rectangle.FromLTRB( last.Right - margin, last.Top, last.Right, last.Bottom ).Contains( point );
+ }
+ else
+ {
+ return Rectangle.FromLTRB( last.Left, last.Bottom - margin, last.Right, last.Bottom ).Contains( point );
+ }
+ }
+
+ ///
+ /// Sets the bounds of the item
+ ///
+ /// The rectangle.
+ public new void SetBounds( Rectangle rectangle )
+ {
+ base.SetBounds( rectangle );
+ }
+
+ ///
+ /// Indicates if the time of the item intersects with the provided time
+ ///
+ /// The start time.
+ /// The end time.
+ ///
+ public bool IntersectsWith( TimeSpan startTime, TimeSpan endTime )
+ {
+ Rectangle r1 = Rectangle.FromLTRB( 0, Convert.ToInt32( StartDate.TimeOfDay.TotalMinutes ), 5, Convert.ToInt32( EndDate.TimeOfDay.TotalMinutes ) );
+ Rectangle r2 = Rectangle.FromLTRB( 0, Convert.ToInt32( startTime.TotalMinutes ), 5, Convert.ToInt32( endTime.TotalMinutes - 1 ) );
+ return r1.IntersectsWith( r2 );
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return string.Format( "{0} - {1}", StartDate.ToShortTimeString(), EndDate.ToShortTimeString() );
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ ///
+ /// Adds bounds for the item
+ ///
+ ///
+ internal void AddBounds( Rectangle r )
+ {
+ if( r.IsEmpty ) throw new ArgumentException( "r can't be empty" );
+
+ if( Bounds.IsEmpty )
+ {
+ SetBounds( r );
+ }
+ else
+ {
+ List rs = new List( AditionalBounds == null ? new Rectangle[] { } : AditionalBounds );
+ rs.Add( r );
+ AditionalBounds = rs.ToArray();
+ }
+ }
+
+ ///
+ /// Adds the specified unit as a passing unit
+ ///
+ ///
+ internal void AddUnitPassing( CalendarTimeScaleUnit calendarTimeScaleUnit )
+ {
+ if( !UnitsPassing.Contains( calendarTimeScaleUnit ) )
+ {
+ UnitsPassing.Add( calendarTimeScaleUnit );
+ }
+ }
+
+ ///
+ /// Adds the specified as a passing one
+ ///
+ ///
+ internal void AddTopPassing( CalendarDayTop top )
+ {
+ if( !TopsPassing.Contains( top ) )
+ {
+ TopsPassing.Add( top );
+ }
+ }
+
+ ///
+ /// Clears the item's existance off passing units and tops
+ ///
+ internal void ClearPassings()
+ {
+ foreach( CalendarTimeScaleUnit unit in UnitsPassing )
+ {
+ unit.ClearItemExistance( this );
+ }
+
+ UnitsPassing.Clear();
+ TopsPassing.Clear();
+ }
+
+ ///
+ /// Clears all bounds of the item
+ ///
+ internal void ClearBounds()
+ {
+ SetBounds( Rectangle.Empty );
+ AditionalBounds = new Rectangle[] { };
+ SetMinuteStartTop( 0 );
+ SetMinuteEndTop( 0 );
+ }
+
+ ///
+ /// It pushes the left and the right to the center of the item
+ /// to visually indicate start and end time
+ ///
+ internal void FirstAndLastRectangleGapping()
+ {
+ if( !IsOpenStart )
+ SetBounds( Rectangle.FromLTRB( Bounds.Left + Calendar.Renderer.ItemsPadding,
+ Bounds.Top, Bounds.Right, Bounds.Bottom ) );
+
+ if( !IsOpenEnd )
+ {
+ if( AditionalBounds != null && AditionalBounds.Length > 0 )
+ {
+ Rectangle r = AditionalBounds[AditionalBounds.Length - 1];
+ AditionalBounds[AditionalBounds.Length - 1] = Rectangle.FromLTRB(
+ r.Left, r.Top, r.Right - Calendar.Renderer.ItemsPadding, r.Bottom );
+ }
+ else
+ {
+ Rectangle r = Bounds;
+ SetBounds( Rectangle.FromLTRB(
+ r.Left, r.Top, r.Right - Calendar.Renderer.ItemsPadding, r.Bottom ) );
+ }
+ }
+ }
+
+ ///
+ /// Sets the value of the IsDragging property
+ ///
+ /// Value indicating if the item is currently being dragged
+ internal void SetIsDragging( bool dragging )
+ {
+ _isDragging = dragging;
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ /// Value indicating if user is currently being editing
+ internal void SetIsEditing( bool editing )
+ {
+ _isEditing = editing;
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ /// Indicates if the item is currently on view
+ internal void SetIsOnView( bool onView )
+ {
+ _isOnView = onView;
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ ///
+ internal void SetIsResizingStartDate( bool resizing )
+ {
+ _isResizingStartDate = resizing;
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ ///
+ internal void SetIsResizingEndDate( bool resizing )
+ {
+ _isResizingEndDate = resizing;
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ ///
+ internal void SetMinuteStartTop( int top )
+ {
+ _minuteStartTop = top;
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ ///
+ internal void SetMinuteEndTop( int top )
+ {
+ _minuteEndTop = top;
+ }
+
+ #endregion
+
+ }
+}
\ No newline at end of file
diff --git a/WindowsFormsCalendar/CalendarItemCollection.cs b/WindowsFormsCalendar/CalendarItemCollection.cs
new file mode 100644
index 0000000..49d11d5
--- /dev/null
+++ b/WindowsFormsCalendar/CalendarItemCollection.cs
@@ -0,0 +1,176 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// A collection of calendar items
+ ///
+ public class CalendarItemCollection
+ : List
+ {
+ #region Events
+
+ #endregion
+
+ #region Fields
+ private Calendar _calendar;
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets the calendar.
+ ///
+ public Calendar Calendar
+ {
+ get { return _calendar; }
+ }
+
+ #endregion
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The c.
+ internal CalendarItemCollection( Calendar c )
+ {
+ _calendar = c;
+ }
+
+ #region Public Methods
+
+ ///
+ /// Adds an item to the end of the list
+ ///
+ /// The object to be added to the end of the collection. The value can be null for reference types.
+ public new void Add( CalendarItem item )
+ {
+ base.Add( item ); CollectionChanged();
+ }
+
+ ///
+ /// Adds the items of the specified collection to the end of the list.
+ ///
+ /// The items whose elements should be added to the end of the collection. The collection itself cannont be null, but it can contain elements that are null.
+ public new void AddRange( IEnumerable items )
+ {
+ base.AddRange( items ); CollectionChanged();
+ }
+
+ ///
+ /// Removes all elements from the collection.
+ ///
+ public new void Clear()
+ {
+ base.Clear(); CollectionChanged();
+ }
+
+ ///
+ /// Inserts an item into the collection at the specified index.
+ ///
+ /// The zero-based index at which item should be inserted.
+ /// The object to insert. The value can be null for reference types.
+ public new void Insert( int index, CalendarItem item )
+ {
+ base.Insert( index, item ); CollectionChanged();
+ }
+
+ ///
+ /// Inserts the items of a collection into this collection at the specified index.
+ ///
+ /// The zero-based index at which the new elements should be inserted.
+ ///
+ public new void InsertRange( int index, IEnumerable items )
+ {
+ base.InsertRange( index, items ); CollectionChanged();
+ }
+
+ ///
+ /// Removes the first occurrence of a specific object from the collection.
+ ///
+ /// The item to remove from the collection. The value can be null for reference types.
+ /// true if item is successfully removed; otherwise, false. This method also returns false if item was not found in the collection.
+ public new bool Remove( CalendarItem item )
+ {
+ bool result = base.Remove( item );
+
+ CollectionChanged();
+
+ return result;
+ }
+
+ ///
+ /// Removes the item at the specified index of the collection
+ ///
+ /// The zero-based index of the item to remove.
+ /// is less than 0.
+ /// -or-
+ /// is equal to or greater than .
+ ///
+ public new void RemoveAt( int index )
+ {
+ base.RemoveAt( index ); CollectionChanged();
+ }
+
+ ///
+ /// Removes the all the items that match the conditions defined by the specified predicate.
+ ///
+ /// The Predicate delegate that defines the conditions of the items to remove.
+ /// The number of items removed from the collection.
+ public new int RemoveAll( Predicate match )
+ {
+ int result = base.RemoveAll( match );
+
+ CollectionChanged();
+
+ return result;
+ }
+
+ ///
+ /// Removes a range of elements from the collection
+ ///
+ /// The zero-based starting index of the range of items to remove.
+ /// The number of items to remove
+ public new void RemoveRange( int index, int count )
+ {
+ base.RemoveRange( index, count ); CollectionChanged();
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ ///
+ /// Handles what to do when this collection changes
+ ///
+ private void CollectionChanged()
+ {
+ Calendar.Renderer.PerformItemsLayout();
+ Calendar.Invalidate();
+ }
+
+ #endregion
+
+ }
+}
\ No newline at end of file
diff --git a/WindowsFormsCalendar/CalendarSelectableElement.cs b/WindowsFormsCalendar/CalendarSelectableElement.cs
new file mode 100644
index 0000000..398bc58
--- /dev/null
+++ b/WindowsFormsCalendar/CalendarSelectableElement.cs
@@ -0,0 +1,130 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Implements a basic
+ ///
+ public abstract class CalendarSelectableElement
+ : ICalendarSelectableElement
+ {
+ #region Fields
+
+ private Calendar _calendar;
+
+ private Rectangle _bounds;
+
+ private DateTime _date;
+
+ private bool _selected;
+
+ #endregion
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The calendar.
+ public CalendarSelectableElement(Calendar calendar)
+ {
+ if (calendar == null) throw new ArgumentNullException("calendar");
+
+ _calendar = calendar;
+ }
+
+ #region ICalendarSelectableElement Members
+
+ ///
+ /// Gets the calendar
+ ///
+ public virtual DateTime Date
+ {
+ get { return _date; }
+ }
+
+ ///
+ /// Gets the Calendar this element belongs to
+ ///
+ public virtual Calendar Calendar
+ {
+ get { return _calendar; }
+ }
+
+ ///
+ /// Gets the Bounds of the element on the window
+ ///
+ public virtual Rectangle Bounds
+ {
+ get { return _bounds; }
+ }
+
+ ///
+ /// Gets a value indicating if the element is currently selected
+ ///
+ public virtual bool Selected
+ {
+ get
+ {
+ return _selected;
+ }
+ }
+
+ ///
+ /// Compares this element with other using date as comparer
+ ///
+ ///
+ ///
+ public virtual int CompareTo(ICalendarSelectableElement element)
+ {
+ return this.Date.CompareTo(element.Date);
+ }
+
+ #endregion
+
+ #region Internal Methods
+
+ ///
+ /// Sets the value of the property
+ ///
+ /// Bounds of the element
+ internal virtual void SetBounds(Rectangle bounds)
+ {
+ _bounds = bounds;
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ /// Value indicating if the element is currently selected
+ internal virtual void SetSelected(bool selected)
+ {
+ _selected = selected;
+
+ //Calendar.Invalidate(Bounds);
+ }
+
+ #endregion
+
+ }
+}
diff --git a/WindowsFormsCalendar/CalendarTimeScaleUnit.cs b/WindowsFormsCalendar/CalendarTimeScaleUnit.cs
new file mode 100644
index 0000000..f21816a
--- /dev/null
+++ b/WindowsFormsCalendar/CalendarTimeScaleUnit.cs
@@ -0,0 +1,252 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Represents a selectable timescale unit on a
+ ///
+ public class CalendarTimeScaleUnit
+ : CalendarSelectableElement
+ {
+ #region Events
+
+ #endregion
+
+ #region Fields
+ private DateTime _date;
+ private CalendarDay _day;
+ private bool _highlighted;
+ private int _hours;
+ private int _index;
+ private int _minutes;
+ private List _passingItems;
+ private bool _visible;
+ #endregion
+
+ #region Properties
+
+
+
+ ///
+ /// Gets the exact date when the unit starts
+ ///
+ public override DateTime Date
+ {
+ get
+ {
+ if( _date.Equals( DateTime.MinValue ) )
+ {
+ _date = new DateTime( Day.Date.Year, Day.Date.Month, Day.Date.Day, Hours, Minutes, 0 );
+ }
+
+ return _date;
+ }
+ }
+
+ ///
+ /// Gets the this unit belongs to
+ ///
+ public CalendarDay Day
+ {
+ get { return _day; }
+ }
+
+ ///
+ /// Gets the duration of the unit.
+ ///
+ public TimeSpan Duration
+ {
+ get
+ {
+ return new TimeSpan( 0, (int)Calendar.TimeScale, 0 );
+ }
+ }
+
+ ///
+ /// Gets if the unit is highlighted because it fits in some of the calendar's highlight ranges
+ ///
+ public bool Highlighted
+ {
+ get { return _highlighted; }
+ }
+
+ ///
+ /// Gets the hour when this unit starts
+ ///
+ public int Hours
+ {
+ get { return _hours; }
+ }
+
+ ///
+ /// Gets the index of the unit relative to the day
+ ///
+ public int Index
+ {
+ get { return _index; }
+ }
+
+ ///
+ /// Gets the minute when this unit starts
+ ///
+ public int Minutes
+ {
+ get { return _minutes; }
+ set { _minutes = value; }
+ }
+
+ ///
+ /// Gets or sets the amount of items that pass over the unit
+ ///
+ internal List PassingItems
+ {
+ get { return _passingItems; }
+ set { _passingItems = value; }
+ }
+
+ ///
+ /// Gets a value indicating if the unit is currently visible on viewport
+ ///
+ public bool Visible
+ {
+ get { return _visible; }
+ }
+
+ #endregion
+
+ ///
+ /// Creates a new
+ ///
+ /// this unit belongs to
+ /// Index of the unit relative to the container day
+ /// Hour of the unit
+ /// Minutes of the unit
+ internal CalendarTimeScaleUnit( CalendarDay day, int index, int hours, int minutes )
+ : base( day.Calendar )
+ {
+ _day = day;
+ _index = index;
+ _hours = hours;
+ _minutes = minutes;
+
+ _passingItems = new List();
+ }
+
+ #region Public Methods
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return string.Format( "[{0}] - {1}", Index, Date.ToShortTimeString() );
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ ///
+ /// Gets a value indicating if the unit should be higlighted
+ ///
+ ///
+ internal bool CheckHighlighted()
+ {
+ for( int i = 0; i < Day.Calendar.HighlightRanges.Length; i++ )
+ {
+ CalendarHighlightRange range = Day.Calendar.HighlightRanges[i];
+
+ if( range.DayOfWeek != Date.DayOfWeek )
+ continue;
+
+ if( Date.TimeOfDay.CompareTo( range.StartTime ) >= 0
+ && Date.TimeOfDay.CompareTo( range.EndTime ) < 0 )
+ {
+ return true;
+ }
+
+ }
+ return false;
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ /// Value of the property
+ internal void SetHighlighted( bool highlighted )
+ {
+ _highlighted = highlighted;
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ /// Value indicating if the unit is currently visible on viewport
+ internal void SetVisible( bool visible )
+ {
+ _visible = visible;
+ }
+
+ #endregion
+
+ #region Internal Methods
+
+ ///
+ /// Adds the passing item.
+ ///
+ /// The item.
+ internal void AddPassingItem( CalendarItem item )
+ {
+ if( !PassingItems.Contains( item ) )
+ {
+ PassingItems.Add( item );
+ Day.AddContainedItem( item );
+ }
+ }
+
+ ///
+ /// Clears existance of item from this unit and it's corresponding day.
+ ///
+ ///
+ internal void ClearItemExistance( CalendarItem item )
+ {
+ if( PassingItems.Contains( item ) )
+ {
+ PassingItems.Remove( item );
+ }
+
+ if( Day.ContainedItems.Contains( item ) )
+ {
+ Day.ContainedItems.Remove( item );
+ }
+ }
+
+ #endregion
+
+ }
+}
\ No newline at end of file
diff --git a/WindowsFormsCalendar/CalendarWeek.cs b/WindowsFormsCalendar/CalendarWeek.cs
new file mode 100644
index 0000000..18d3667
--- /dev/null
+++ b/WindowsFormsCalendar/CalendarWeek.cs
@@ -0,0 +1,174 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Represents a week displayed on the
+ ///
+ public class CalendarWeek
+ {
+ #region Events
+
+ #endregion
+
+ #region Fields
+ private Rectangle _bounds;
+ private Calendar _calendar;
+ private DateTime _firstDay;
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets the bounds of the week
+ ///
+ public Rectangle Bounds
+ {
+ get { return _bounds; }
+ }
+
+ ///
+ /// Gets the calendar this week belongs to
+ ///
+ public Calendar Calendar
+ {
+ get { return _calendar; }
+ }
+
+ ///
+ /// Gets the bounds of the week header
+ ///
+ public Rectangle HeaderBounds
+ {
+ get
+ {
+ return new Rectangle(
+ Bounds.Left,
+ Bounds.Top + Calendar.Renderer.DayHeaderHeight,
+ Calendar.Renderer.WeekHeaderWidth,
+ Bounds.Height - Calendar.Renderer.DayHeaderHeight );
+ }
+ }
+
+ ///
+ /// Gets the sunday that starts the week
+ ///
+ public DateTime StartDate
+ {
+ get { return _firstDay; }
+ }
+
+
+ #endregion
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The calendar.
+ /// The first day.
+ internal CalendarWeek(Calendar calendar, DateTime firstDay)
+ {
+ _calendar = calendar;
+ _firstDay = firstDay;
+ }
+
+ #region Public Methods
+
+ ///
+ /// Gets the short version of week's string representation
+ ///
+ ///
+ public string ToStringShort()
+ {
+ DateTime saturday = StartDate.AddDays(6);
+
+ if (saturday.Month != StartDate.Month)
+ {
+ return string.Format("{0} - {1}",
+ StartDate.ToString("d/M"),
+ saturday.ToString("d/M")
+ );
+ }
+ else
+ {
+ return string.Format("{0} - {1}",
+ StartDate.Day,
+ saturday.ToString("d/M")
+ );
+ }
+ }
+
+ ///
+ /// Gets the large version of string representation
+ ///
+ /// The week in a string format
+ public string ToStringLarge()
+ {
+ DateTime saturday = StartDate.AddDays(6);
+
+ if (saturday.Month != StartDate.Month)
+ {
+ return string.Format("{0} - {1}",
+ StartDate.ToString("d MMM"),
+ saturday.ToString("d MMM")
+ );
+ }
+ else
+ {
+ return string.Format("{0} - {1}",
+ StartDate.Day,
+ saturday.ToString("d MMM")
+ );
+ }
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return ToStringLarge();
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ ///
+ /// Sets the value of the property
+ ///
+ ///
+ internal void SetBounds(Rectangle r)
+ {
+ _bounds = r;
+ }
+
+ #endregion
+
+ }
+}
diff --git a/WindowsFormsCalendar/Enums/CalendarDaysMode.cs b/WindowsFormsCalendar/Enums/CalendarDaysMode.cs
new file mode 100644
index 0000000..9367e91
--- /dev/null
+++ b/WindowsFormsCalendar/Enums/CalendarDaysMode.cs
@@ -0,0 +1,41 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Enumerates the possible modes of the days visualization on the
+ ///
+ public enum CalendarDaysMode
+ {
+ ///
+ /// A short version of the day is visible without time scale.
+ ///
+ Short,
+
+ ///
+ /// The day is fully visible with time scale.
+ ///
+ Expanded
+ }
+}
diff --git a/WindowsFormsCalendar/Enums/CalendarItemImageAlign.cs b/WindowsFormsCalendar/Enums/CalendarItemImageAlign.cs
new file mode 100644
index 0000000..59cba1c
--- /dev/null
+++ b/WindowsFormsCalendar/Enums/CalendarItemImageAlign.cs
@@ -0,0 +1,51 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Possible alignment for images
+ ///
+ public enum CalendarItemImageAlign
+ {
+ ///
+ /// Image is drawn at north of text
+ ///
+ North,
+
+ ///
+ /// Image is drawn at south of text
+ ///
+ South,
+
+ ///
+ /// Image is drawn at east of text
+ ///
+ East,
+
+ ///
+ /// Image is drawn at west of text
+ ///
+ West,
+ }
+}
diff --git a/WindowsFormsCalendar/Enums/CalendarScrollBars.cs b/WindowsFormsCalendar/Enums/CalendarScrollBars.cs
new file mode 100644
index 0000000..fccbb3a
--- /dev/null
+++ b/WindowsFormsCalendar/Enums/CalendarScrollBars.cs
@@ -0,0 +1,52 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Enumeration for the different type of scroll bars
+ ///
+ public enum CalendarScrollBars
+ {
+ ///
+ /// No scroll bars
+ ///
+ None,
+
+ ///
+ /// Vertical and Horizontal scrollbars
+ ///
+ Both,
+
+ ///
+ /// Only vertical scrollbars
+ ///
+ Vertical,
+
+ ///
+ /// Only horizontal scrollbars
+ ///
+ Horizontal
+ }
+}
diff --git a/WindowsFormsCalendar/Enums/CalendarState.cs b/WindowsFormsCalendar/Enums/CalendarState.cs
new file mode 100644
index 0000000..4427091
--- /dev/null
+++ b/WindowsFormsCalendar/Enums/CalendarState.cs
@@ -0,0 +1,57 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Possible states of the calendar
+ ///
+ public enum CalendarState
+ {
+ ///
+ /// Nothing happening
+ ///
+ Idle,
+
+ ///
+ /// User is currently dragging on view to select a time range
+ ///
+ DraggingTimeSelection,
+
+ ///
+ /// User is currently dragging an item among the view
+ ///
+ DraggingItem,
+
+ ///
+ /// User is editing an item's Text
+ ///
+ EditingItemText,
+
+ ///
+ /// User is currently resizing an item
+ ///
+ ResizingItem
+ }
+}
diff --git a/WindowsFormsCalendar/Enums/CalendarTimeFormat.cs b/WindowsFormsCalendar/Enums/CalendarTimeFormat.cs
new file mode 100644
index 0000000..d231525
--- /dev/null
+++ b/WindowsFormsCalendar/Enums/CalendarTimeFormat.cs
@@ -0,0 +1,42 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// An enumeration that represents the time format of the calendar
+ ///
+ public enum CalendarTimeFormat
+ {
+ ///
+ /// A twelve hour clock
+ ///
+ TwelveHour,
+
+ ///
+ /// A twenty four hour clock
+ ///
+ TwentyFourHour
+ }
+}
\ No newline at end of file
diff --git a/WindowsFormsCalendar/Enums/CalendarTimeScale.cs b/WindowsFormsCalendar/Enums/CalendarTimeScale.cs
new file mode 100644
index 0000000..e361e8d
--- /dev/null
+++ b/WindowsFormsCalendar/Enums/CalendarTimeScale.cs
@@ -0,0 +1,61 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Enumerates possible timescales for control
+ ///
+ public enum CalendarTimeScale
+ {
+ ///
+ /// Makes calendar show intervals of 60 minutes
+ ///
+ SixtyMinutes = 60,
+
+ ///
+ /// Makes calendar show intervals of 30 minutes
+ ///
+ ThirtyMinutes = 30,
+
+ ///
+ /// Makes calendar show intervals of 15 minutes
+ ///
+ FifteenMinutes = 15,
+
+ ///
+ /// Makes calendar show intervals of 10 minutes
+ ///
+ TenMinutes = 10,
+
+ ///
+ /// Makes calendar show intervals of 6 minutes
+ ///
+ SixMinutes = 6,
+
+ ///
+ /// Makes calendar show intervals of 5 minutes
+ ///
+ FiveMinutes = 5
+ }
+}
diff --git a/WindowsFormsCalendar/Enums/Corners.cs b/WindowsFormsCalendar/Enums/Corners.cs
new file mode 100644
index 0000000..63d3511
--- /dev/null
+++ b/WindowsFormsCalendar/Enums/Corners.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Possible corners to pass to the RoundRectangle method
+ ///
+ [Flags()]
+ public enum Corners
+ {
+ ///
+ /// No corners
+ ///
+ None = 0,
+
+ ///
+ /// Northwest corner
+ ///
+ NorthWest = 2,
+
+ ///
+ /// Northeast corner
+ ///
+ NorthEast = 4,
+
+ ///
+ /// Southeast corner
+ ///
+ SouthEast = 8,
+
+ ///
+ /// Southwest corner
+ ///
+ SouthWest = 16,
+
+ ///
+ /// All corners
+ ///
+ All = NorthWest | NorthEast | SouthEast | SouthWest,
+
+ ///
+ /// North corner
+ ///
+ North = NorthWest | NorthEast,
+
+ ///
+ /// South corner
+ ///
+ South = SouthEast | SouthWest,
+
+ ///
+ /// East Corner
+ ///
+ East = NorthEast | SouthEast,
+
+ ///
+ /// West corner
+ ///
+ West = NorthWest | SouthWest
+ }
+}
\ No newline at end of file
diff --git a/WindowsFormsCalendar/Enums/MonthViewSelection.cs b/WindowsFormsCalendar/Enums/MonthViewSelection.cs
new file mode 100644
index 0000000..ebcb06f
--- /dev/null
+++ b/WindowsFormsCalendar/Enums/MonthViewSelection.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Represents the different kinds of selection in MonthView
+ ///
+ public enum MonthViewSelection
+ {
+ ///
+ /// User can select whatever date available to mouse reach
+ ///
+ Manual,
+
+ ///
+ /// Selection is limited to just one day
+ ///
+ Day,
+
+ ///
+ /// Selecion is limited to weekly ranges
+ ///
+ WorkWeek,
+
+ ///
+ /// Selection is limited to a full week
+ ///
+ Week,
+
+ ///
+ /// Selection is limited to a full month
+ ///
+ Month
+ }
+}
\ No newline at end of file
diff --git a/WindowsFormsCalendar/EventArgs/CalendarDayEventArgs.cs b/WindowsFormsCalendar/EventArgs/CalendarDayEventArgs.cs
new file mode 100644
index 0000000..4a51e9e
--- /dev/null
+++ b/WindowsFormsCalendar/EventArgs/CalendarDayEventArgs.cs
@@ -0,0 +1,54 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Event data with a element
+ ///
+ public class CalendarDayEventArgs
+ :EventArgs
+ {
+ ///
+ /// Creates a new event with the specified day
+ ///
+ /// Day of the event
+ public CalendarDayEventArgs(CalendarDay day)
+ {
+ _calendarDay = day;
+ }
+
+ #region Props
+ private CalendarDay _calendarDay;
+
+ ///
+ /// Gets the day related to the event
+ ///
+ public CalendarDay CalendarDay
+ {
+ get { return _calendarDay; }
+ }
+
+ #endregion
+ }
+}
diff --git a/WindowsFormsCalendar/EventArgs/CalendarItemCancelEventArgs.cs b/WindowsFormsCalendar/EventArgs/CalendarItemCancelEventArgs.cs
new file mode 100644
index 0000000..29fd4eb
--- /dev/null
+++ b/WindowsFormsCalendar/EventArgs/CalendarItemCancelEventArgs.cs
@@ -0,0 +1,57 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.ComponentModel;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Event arguments for calendar cancel item event
+ ///
+ public class CalendarItemCancelEventArgs
+ : CancelEventArgs
+ {
+ ///
+ /// Creates a new
+ ///
+ /// Related Item
+ public CalendarItemCancelEventArgs( CalendarItem item )
+ {
+ _item = item;
+ }
+
+ #region Props
+
+ private CalendarItem _item;
+
+ ///
+ /// Gets the related to the event
+ ///
+ public CalendarItem Item
+ {
+ get { return _item; }
+ }
+
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/WindowsFormsCalendar/EventArgs/CalendarItemEventArgs.cs b/WindowsFormsCalendar/EventArgs/CalendarItemEventArgs.cs
new file mode 100644
index 0000000..8886d34
--- /dev/null
+++ b/WindowsFormsCalendar/EventArgs/CalendarItemEventArgs.cs
@@ -0,0 +1,57 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.ComponentModel;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Event arguments for the calendar item events.
+ ///
+ public class CalendarItemEventArgs
+ : EventArgs
+ {
+ ///
+ /// Creates a new
+ ///
+ /// Related Item
+ public CalendarItemEventArgs(CalendarItem item)
+ {
+ _item = item;
+ }
+
+ #region Props
+
+ private CalendarItem _item;
+
+ ///
+ /// Gets the related to the event
+ ///
+ public CalendarItem Item
+ {
+ get { return _item; }
+ }
+
+
+ #endregion
+ }
+}
diff --git a/WindowsFormsCalendar/EventArgs/CalendarLoadEventArgs.cs b/WindowsFormsCalendar/EventArgs/CalendarLoadEventArgs.cs
new file mode 100644
index 0000000..074f36f
--- /dev/null
+++ b/WindowsFormsCalendar/EventArgs/CalendarLoadEventArgs.cs
@@ -0,0 +1,82 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Holds data of a Calendar Loading Items of certain date range
+ ///
+ public class CalendarLoadEventArgs
+ : EventArgs
+ {
+ #region Fields
+ private Calendar _calendar;
+ private DateTime _dateStart;
+ private DateTime _dateEnd;
+
+ #endregion
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The calendar.
+ /// The date start.
+ /// The date end.
+ public CalendarLoadEventArgs(Calendar calendar, DateTime dateStart, DateTime dateEnd)
+ {
+ _calendar = calendar;
+ _dateEnd = dateEnd;
+ _dateStart = dateStart;
+ }
+
+ #region Props
+
+ ///
+ /// Gets the calendar that originated the event
+ ///
+ public Calendar Calendar
+ {
+ get { return _calendar; }
+ }
+
+ ///
+ /// Gets the start date of the load
+ ///
+ public DateTime DateStart
+ {
+ get { return _dateStart; }
+ set { _dateStart = value; }
+ }
+
+ ///
+ /// Gets the end date of the load
+ ///
+ public DateTime DateEnd
+ {
+ get { return _dateEnd; }
+ }
+
+
+ #endregion
+ }
+}
diff --git a/WindowsFormsCalendar/EventArgs/CalendarRendererBoxEventArgs.cs b/WindowsFormsCalendar/EventArgs/CalendarRendererBoxEventArgs.cs
new file mode 100644
index 0000000..86b9494
--- /dev/null
+++ b/WindowsFormsCalendar/EventArgs/CalendarRendererBoxEventArgs.cs
@@ -0,0 +1,235 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Contains information about something's bounds and text to draw on the calendar
+ ///
+ public class CalendarRendererBoxEventArgs
+ : CalendarRendererEventArgs
+ {
+ #region Fields
+ private Color _backgroundColor;
+ private Rectangle _bounds;
+ private Font _font;
+ private TextFormatFlags _format;
+ private string _text;
+ private Color _textColor;
+ private Size _textSize;
+ #endregion
+
+ ///
+ /// Initializes some fields
+ ///
+ private CalendarRendererBoxEventArgs()
+ {
+ this.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
+ this.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
+ this.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
+ this.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The instance containing the event data.
+ public CalendarRendererBoxEventArgs(CalendarRendererEventArgs original)
+ : base(original)
+ {
+ Font = original.Calendar.Font;
+ Format |= TextFormatFlags.Default | TextFormatFlags.WordBreak | TextFormatFlags.PreserveGraphicsClipping;// | TextFormatFlags.WordEllipsis;
+ TextColor = SystemColors.ControlText;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The instance containing the event data.
+ /// The bounds.
+ public CalendarRendererBoxEventArgs(CalendarRendererEventArgs original, Rectangle bounds)
+ : this(original)
+ {
+ Bounds = bounds;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The instance containing the event data.
+ /// The bounds.
+ /// The text.
+ public CalendarRendererBoxEventArgs(CalendarRendererEventArgs original, Rectangle bounds, string text)
+ : this(original)
+ {
+ Bounds = bounds;
+ Text = text;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The instance containing the event data.
+ /// The bounds.
+ /// The text.
+ /// The flags.
+ public CalendarRendererBoxEventArgs(CalendarRendererEventArgs original, Rectangle bounds, string text, TextFormatFlags flags)
+ : this(original)
+ {
+ Bounds = bounds;
+ Text = text;
+ Format |= flags;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The instance containing the event data.
+ /// The bounds.
+ /// The text.
+ /// Color of the text.
+ public CalendarRendererBoxEventArgs(CalendarRendererEventArgs original, Rectangle bounds, string text, Color textColor)
+ : this(original)
+ {
+ Bounds = bounds;
+ Text = text;
+ TextColor = textColor;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The instance containing the event data.
+ /// The bounds.
+ /// The text.
+ /// Color of the text.
+ /// The flags.
+ public CalendarRendererBoxEventArgs(CalendarRendererEventArgs original, Rectangle bounds, string text, Color textColor, TextFormatFlags flags)
+ : this(original)
+ {
+ Bounds = bounds;
+ Text = text;
+ TextColor = TextColor;
+ Format |= flags;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The instance containing the event data.
+ /// The bounds.
+ /// The text.
+ /// Color of the text.
+ /// Color of the background.
+ public CalendarRendererBoxEventArgs(CalendarRendererEventArgs original, Rectangle bounds, string text, Color textColor, Color backgroundColor)
+ : this(original)
+ {
+ Bounds = bounds;
+ Text = text;
+ TextColor = TextColor;
+ BackgroundColor = backgroundColor;
+ }
+
+ #region Props
+
+ ///
+ /// Gets or sets the background color of the text
+ ///
+ public Color BackgroundColor
+ {
+ get { return _backgroundColor; }
+ set { _backgroundColor = value; }
+ }
+
+ ///
+ /// Gets or sets the bounds to draw the text
+ ///
+ public Rectangle Bounds
+ {
+ get { return _bounds; }
+ set { _bounds = value; }
+ }
+
+ ///
+ /// Gets or sets the font of the text to be rendered
+ ///
+ public Font Font
+ {
+ get { return _font; }
+ set { _font = value; _textSize = Size.Empty; }
+ }
+
+ ///
+ /// Gets or sets the format to draw the text
+ ///
+ public TextFormatFlags Format
+ {
+ get { return _format; }
+ set { _format = value; _textSize = Size.Empty; }
+ }
+
+ ///
+ /// Gets or sets the text to draw
+ ///
+ public string Text
+ {
+ get { return _text; }
+ set { _text = value; _textSize = Size.Empty; }
+ }
+
+ ///
+ /// Gets the result of measuring the text
+ ///
+ public Size TextSize
+ {
+ get
+ {
+ if (_textSize.IsEmpty)
+ {
+ _textSize = TextRenderer.MeasureText(Text, Font);
+ }
+ return _textSize;
+ }
+ }
+
+
+ ///
+ /// Gets or sets the color to draw the text
+ ///
+ public Color TextColor
+ {
+ get { return _textColor; }
+ set { _textColor = value; }
+ }
+
+
+
+ #endregion
+
+ #region Methods
+
+ #endregion
+ }
+}
diff --git a/WindowsFormsCalendar/EventArgs/CalendarRendererDayEventArgs.cs b/WindowsFormsCalendar/EventArgs/CalendarRendererDayEventArgs.cs
new file mode 100644
index 0000000..cbd1a35
--- /dev/null
+++ b/WindowsFormsCalendar/EventArgs/CalendarRendererDayEventArgs.cs
@@ -0,0 +1,60 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Contains information about a day to draw on the calendar
+ ///
+ public class CalendarRendererDayEventArgs
+ : CalendarRendererEventArgs
+ {
+ #region Fields
+ private CalendarDay _day;
+ #endregion
+
+ ///
+ /// Creates a new object
+ ///
+ /// Orignal object to copy basic paramters
+ /// Day to render
+ public CalendarRendererDayEventArgs(CalendarRendererEventArgs original, CalendarDay day)
+ : base(original)
+ {
+ _day = day;
+ }
+
+ #region Props
+
+ ///
+ /// Gets the day to paint
+ ///
+ public CalendarDay Day
+ {
+ get { return _day; }
+ }
+
+
+ #endregion
+ }
+}
diff --git a/WindowsFormsCalendar/EventArgs/CalendarRendererEventArgs.cs b/WindowsFormsCalendar/EventArgs/CalendarRendererEventArgs.cs
new file mode 100644
index 0000000..2a04872
--- /dev/null
+++ b/WindowsFormsCalendar/EventArgs/CalendarRendererEventArgs.cs
@@ -0,0 +1,171 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Contains basic information about a drawing event for
+ ///
+ public class CalendarRendererEventArgs
+ : EventArgs
+ {
+ #region Events
+
+ #endregion
+
+ #region Fields
+
+ private Calendar _calendar;
+
+ private Rectangle _clip;
+
+ private Graphics _graphics;
+
+ private object _tag;
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets the calendar where painting
+ ///
+ public Calendar Calendar
+ {
+ get { return _calendar; }
+ }
+
+ ///
+ /// Gets the clip of the paint event
+ ///
+ public Rectangle ClipRectangle
+ {
+ get { return _clip; }
+ }
+
+ ///
+ /// Gets the device where to paint
+ ///
+ public Graphics Graphics
+ {
+ get { return _graphics; }
+ }
+
+ ///
+ /// Gets or sets a tag for the event
+ ///
+ public object Tag
+ {
+ get { return _tag; }
+ set { _tag = value; }
+ }
+
+
+ #endregion
+
+ ///
+ /// Use it wisely just to initialize some stuff
+ ///
+ protected CalendarRendererEventArgs()
+ {
+ this.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
+ this.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
+ this.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
+ this.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
+ }
+
+ ///
+ /// Creates a new
+ ///
+ /// Calendar where painting
+ /// The graphics.
+ /// The clip rectangle.
+ public CalendarRendererEventArgs( Calendar calendar, Graphics graphics, Rectangle clipRectangle )
+ {
+ _calendar = calendar;
+ _graphics = graphics;
+ _clip = clipRectangle;
+
+ if( _graphics != null )
+ {
+ _graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
+ _graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
+ _graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
+ _graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
+ }
+ }
+
+ ///
+ /// Creates a new
+ ///
+ /// Calendar where painting
+ /// The graphics.
+ /// The clip rectangle.
+ /// The tag.
+ public CalendarRendererEventArgs( Calendar calendar, Graphics graphics, Rectangle clipRectangle, object tag )
+ {
+ _calendar = calendar;
+ _graphics = graphics;
+ _clip = clipRectangle;
+ _tag = tag;
+
+ if( _graphics != null )
+ {
+ _graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
+ _graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
+ _graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
+ _graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
+ }
+ }
+
+ ///
+ /// Copies the parameters from the specified
+ ///
+ /// The instance containing the event data.
+ public CalendarRendererEventArgs( CalendarRendererEventArgs original )
+ {
+ _calendar = original.Calendar;
+ _graphics = original.Graphics;
+ _clip = original.ClipRectangle;
+ _tag = original.Tag;
+
+ if( _graphics != null )
+ {
+ _graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
+ _graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
+ _graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
+ _graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
+ }
+ }
+
+ #region Public Methods
+
+ #endregion
+
+ #region Private Methods
+
+ #endregion
+
+ }
+}
\ No newline at end of file
diff --git a/WindowsFormsCalendar/EventArgs/CalendarRendererItemBoundsEventArgs.cs b/WindowsFormsCalendar/EventArgs/CalendarRendererItemBoundsEventArgs.cs
new file mode 100644
index 0000000..d1660a1
--- /dev/null
+++ b/WindowsFormsCalendar/EventArgs/CalendarRendererItemBoundsEventArgs.cs
@@ -0,0 +1,100 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Event arguments for calendar renter item bounds
+ ///
+ public class CalendarRendererItemBoundsEventArgs
+ : CalendarRendererItemEventArgs
+ {
+ #region Fields
+ private Rectangle _bounds;
+ private bool _isFirst;
+ private bool _isLast;
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets the bounds of the item to be rendered.
+ ///
+ ///
+ /// Items may have more than one bounds due to week segmentation.
+ ///
+ public Rectangle Bounds
+ {
+ get { return _bounds; }
+ }
+
+ ///
+ /// Gets a value indicating if the bounds are the first of the item.
+ ///
+ ///
+ /// Items may have more than one bounds due to week segmentation.
+ ///
+ public bool IsFirst
+ {
+ get { return _isFirst; }
+ }
+
+ ///
+ /// Gets a value indicating if the bounds are the last of the item.
+ ///
+ ///
+ /// Items may have more than one bounds due to week segmentation.
+ ///
+ public bool IsLast
+ {
+ get { return _isLast; }
+ set { _isLast = value; }
+ }
+
+
+ #endregion
+
+ ///
+ /// Creates a new Event
+ ///
+ ///
+ ///
+ ///
+ ///
+ internal CalendarRendererItemBoundsEventArgs(CalendarRendererItemEventArgs original, Rectangle bounds, bool isFirst, bool isLast)
+ : base(original, original.Item)
+ {
+ _isFirst = isFirst;
+ _isLast = isLast;
+ _bounds = bounds;
+
+ this.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
+ this.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
+ this.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
+ this.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
+
+ }
+
+ }
+}
diff --git a/WindowsFormsCalendar/EventArgs/CalendarRendererItemEventArgs.cs b/WindowsFormsCalendar/EventArgs/CalendarRendererItemEventArgs.cs
new file mode 100644
index 0000000..102c6e0
--- /dev/null
+++ b/WindowsFormsCalendar/EventArgs/CalendarRendererItemEventArgs.cs
@@ -0,0 +1,66 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Contains information to render an item
+ ///
+ public class CalendarRendererItemEventArgs
+ : CalendarRendererEventArgs
+ {
+ #region Fields
+ private CalendarItem _item;
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets the Item being rendered
+ ///
+ public CalendarItem Item
+ {
+ get { return _item; }
+ }
+
+ #endregion
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The instance containing the event data.
+ /// The item.
+ public CalendarRendererItemEventArgs( CalendarRendererEventArgs original, CalendarItem item )
+ : base( original )
+ {
+ _item = item;
+
+ this.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
+ this.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
+ this.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
+ this.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/WindowsFormsCalendar/EventArgs/CalendarRendererTimeUnitEventArgs.cs b/WindowsFormsCalendar/EventArgs/CalendarRendererTimeUnitEventArgs.cs
new file mode 100644
index 0000000..68a1292
--- /dev/null
+++ b/WindowsFormsCalendar/EventArgs/CalendarRendererTimeUnitEventArgs.cs
@@ -0,0 +1,77 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Contains information about a that is about to be painted
+ ///
+ public class CalendarRendererTimeUnitEventArgs
+ : CalendarRendererEventArgs
+ {
+ #region Events
+
+ #endregion
+
+ #region Fields
+ private CalendarTimeScaleUnit _unit;
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets the unit that is about to be painted
+ ///
+ public CalendarTimeScaleUnit Unit
+ {
+ get { return _unit; }
+ }
+
+ #endregion
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The instance containing the event data.
+ /// The unit.
+ public CalendarRendererTimeUnitEventArgs(CalendarRendererEventArgs original, CalendarTimeScaleUnit unit)
+ : base(original)
+ {
+ _unit = unit;
+
+ this.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
+ this.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
+ this.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
+ this.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
+
+ }
+
+ #region Public Methods
+
+ #endregion
+
+ #region Private Methods
+
+ #endregion
+ }
+}
diff --git a/WindowsFormsCalendar/EventArgs/MonthViewBoxEventArgs.cs b/WindowsFormsCalendar/EventArgs/MonthViewBoxEventArgs.cs
new file mode 100644
index 0000000..728353e
--- /dev/null
+++ b/WindowsFormsCalendar/EventArgs/MonthViewBoxEventArgs.cs
@@ -0,0 +1,215 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Holds data about a box of text to be rendered on the month view
+ ///
+ public class MonthViewBoxEventArgs
+ {
+ #region Fields
+ private Graphics _graphics;
+ private Color _textColor;
+ private Color _backgroundColor;
+ private string _text;
+ private Color _borderColor;
+ private Rectangle _bounds;
+ private Font _font;
+ private TextFormatFlags _TextFlags;
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets or sets the bounds of the box
+ ///
+ public Rectangle Bounds
+ {
+ get { return _bounds; }
+ }
+
+ ///
+ /// Gets or sets the font of the text. If null, default will be used.
+ ///
+ public Font Font
+ {
+ get { return _font; }
+ set { _font = value; }
+ }
+
+ ///
+ /// Gets or sets the Graphics object where to draw
+ ///
+ public Graphics Graphics
+ {
+ get { return _graphics; }
+ }
+
+ ///
+ /// Gets or sets the border color of the box
+ ///
+ public Color BorderColor
+ {
+ get { return _borderColor; }
+ set { _borderColor = value; }
+ }
+
+ ///
+ /// Gets or sets the text of the box
+ ///
+ public string Text
+ {
+ get { return _text; }
+ set { _text = value; }
+ }
+
+ ///
+ /// Gets or sets the background color of the box
+ ///
+ public Color BackgroundColor
+ {
+ get { return _backgroundColor; }
+ set { _backgroundColor = value; }
+ }
+
+ ///
+ /// Gets or sets the text color of the box
+ ///
+ public Color TextColor
+ {
+ get { return _textColor; }
+ set { _textColor = value; }
+ }
+
+ ///
+ /// Gets or sets the flags of the text
+ ///
+ public TextFormatFlags TextFlags
+ {
+ get { return _TextFlags; }
+ set { _TextFlags = value; }
+ }
+
+
+ #endregion
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The graphics.
+ /// The bounds.
+ /// The text.
+ /// The text align.
+ /// Color of the text.
+ /// Color of the back.
+ /// Color of the border.
+ internal MonthViewBoxEventArgs( Graphics graphics, Rectangle bounds, string text, StringAlignment textAlign, Color textColor, Color backColor, Color borderColor )
+ {
+ _graphics = graphics;
+
+ _graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
+ _graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
+ _graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
+ _graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
+
+ _bounds = bounds;
+ Text = text;
+ TextColor = textColor;
+ BackgroundColor = backColor;
+ BorderColor = borderColor;
+
+ switch( textAlign )
+ {
+ case StringAlignment.Center:
+ TextFlags |= TextFormatFlags.HorizontalCenter;
+ break;
+
+ case StringAlignment.Far:
+ TextFlags |= TextFormatFlags.Right;
+ break;
+
+ case StringAlignment.Near:
+ TextFlags |= TextFormatFlags.Left;
+ break;
+
+ default:
+ break;
+
+ }
+
+ TextFlags |= TextFormatFlags.VerticalCenter;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The graphics.
+ /// The bounds.
+ /// The text.
+ /// Color of the text.
+ internal MonthViewBoxEventArgs( Graphics graphics, Rectangle bounds, string text, Color textColor )
+ : this( graphics, bounds, text, StringAlignment.Center, textColor, Color.Empty, Color.Empty )
+ { }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The graphics.
+ /// The bounds.
+ /// The text.
+ /// Color of the text.
+ /// Color of the back.
+ internal MonthViewBoxEventArgs( Graphics graphics, Rectangle bounds, string text, Color textColor, Color backColor )
+ : this( graphics, bounds, text, StringAlignment.Center, textColor, backColor, Color.Empty )
+ { }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The graphics.
+ /// The bounds.
+ /// The text.
+ /// The text align.
+ /// Color of the text.
+ /// Color of the back.
+ internal MonthViewBoxEventArgs( Graphics graphics, Rectangle bounds, string text, StringAlignment textAlign, Color textColor, Color backColor )
+ : this( graphics, bounds, text, textAlign, textColor, backColor, Color.Empty )
+ { }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The graphics.
+ /// The bounds.
+ /// The text.
+ /// The text align.
+ /// Color of the text.
+ internal MonthViewBoxEventArgs( Graphics graphics, Rectangle bounds, string text, StringAlignment textAlign, Color textColor )
+ : this( graphics, bounds, text, textAlign, textColor, Color.Empty, Color.Empty )
+ { }
+
+ }
+}
\ No newline at end of file
diff --git a/WindowsFormsCalendar/EventArgs/MonthViewMontEventArgs.cs b/WindowsFormsCalendar/EventArgs/MonthViewMontEventArgs.cs
new file mode 100644
index 0000000..6ca8645
--- /dev/null
+++ b/WindowsFormsCalendar/EventArgs/MonthViewMontEventArgs.cs
@@ -0,0 +1,33 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Month view event argument data
+ ///
+ public class MonthViewMontEventArgs
+ {
+
+ }
+}
diff --git a/WindowsFormsCalendar/GPL v3.txt b/WindowsFormsCalendar/GPL v3.txt
new file mode 100644
index 0000000..20d40b6
--- /dev/null
+++ b/WindowsFormsCalendar/GPL v3.txt
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
\ No newline at end of file
diff --git a/WindowsFormsCalendar/ICalendarSelectableElement.cs b/WindowsFormsCalendar/ICalendarSelectableElement.cs
new file mode 100644
index 0000000..29a88e8
--- /dev/null
+++ b/WindowsFormsCalendar/ICalendarSelectableElement.cs
@@ -0,0 +1,45 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Interface implemented by every selectable element of the calendar
+ ///
+ public interface ICalendarSelectableElement
+ : ISelectableElement, IComparable
+ {
+
+ ///
+ /// Gets the calendar this element belongs to
+ ///
+ Calendar Calendar { get; }
+
+ ///
+ /// Gets the calendar
+ ///
+ DateTime Date { get; }
+
+ }
+}
diff --git a/WindowsFormsCalendar/ISelectableElement.cs b/WindowsFormsCalendar/ISelectableElement.cs
new file mode 100644
index 0000000..77a6f81
--- /dev/null
+++ b/WindowsFormsCalendar/ISelectableElement.cs
@@ -0,0 +1,43 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Represents a clickable element of control
+ ///
+ public interface ISelectableElement
+ {
+
+ ///
+ /// Gets the bounds of the element
+ ///
+ Rectangle Bounds { get; }
+
+ ///
+ /// Gets if the element is currently selected
+ ///
+ bool Selected { get; }
+ }
+}
diff --git a/WindowsFormsCalendar/MonthViewDay.cs b/WindowsFormsCalendar/MonthViewDay.cs
new file mode 100644
index 0000000..aace914
--- /dev/null
+++ b/WindowsFormsCalendar/MonthViewDay.cs
@@ -0,0 +1,133 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// A class that represents a month view day
+ ///
+ public class MonthViewDay
+ {
+ #region Fields
+
+ Rectangle _bounds;
+ private DateTime _date;
+ private MonthViewMonth _month;
+ private MonthView _monthView;
+
+ #endregion
+
+ #region Propserties
+
+ ///
+ /// Gets the parent MonthView
+ ///
+ public MonthView MonthView
+ {
+ get { return _monthView; }
+ set { _monthView = value; }
+ }
+
+ ///
+ /// Gets the parent MonthViewMonth
+ ///
+ public MonthViewMonth Month
+ {
+ get { return _month; }
+ }
+
+ ///
+ /// Gets the bounds of the day
+ ///
+ public Rectangle Bounds
+ {
+ get { return _bounds; }
+ }
+
+ ///
+ /// Gets the date this day represents
+ ///
+ public DateTime Date
+ {
+ get { return _date; }
+ }
+
+ ///
+ /// Gets or sets if the day is currently selected
+ ///
+ public bool Selected
+ {
+ get { return Date >= MonthView.SelectionStart && Date <= MonthView.SelectionEnd; }
+ }
+
+ ///
+ /// Gets if the day is grayed
+ ///
+ public bool Grayed
+ {
+ get { return Month.Date.Month != Date.Month; }
+ }
+
+ ///
+ /// Gets a value indicating if the day instance is visible on the calendar
+ ///
+ public bool Visible
+ {
+ get
+ {
+ return !( Grayed && ( Date > MonthView.ViewStart && Date < MonthView.ViewEnd ) );
+ }
+ }
+
+ #endregion
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The month.
+ /// The date.
+ internal MonthViewDay(MonthViewMonth month, DateTime date)
+ {
+ _month = month;
+ _monthView = month.MonthView;
+ _date = date;
+
+
+ }
+
+ #region Methods
+
+ ///
+ /// Sets the value of the property
+ ///
+ ///
+ internal void SetBounds(Rectangle bounds)
+ {
+ _bounds = bounds;
+ }
+
+ #endregion
+
+ }
+}
diff --git a/WindowsFormsCalendar/MonthViewMontEventArgs.cs b/WindowsFormsCalendar/MonthViewMontEventArgs.cs
new file mode 100644
index 0000000..650dc3f
--- /dev/null
+++ b/WindowsFormsCalendar/MonthViewMontEventArgs.cs
@@ -0,0 +1,31 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WindowsFormsCalendar
+{
+ public class MonthViewMontEventArgs
+
+ {
+
+ }
+}
diff --git a/WindowsFormsCalendar/MonthViewMonth.cs b/WindowsFormsCalendar/MonthViewMonth.cs
new file mode 100644
index 0000000..309543f
--- /dev/null
+++ b/WindowsFormsCalendar/MonthViewMonth.cs
@@ -0,0 +1,231 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Represents a month displayed"/>
+ ///
+ public class MonthViewMonth
+ {
+ #region Fields
+
+ private DateTime _date;
+ private Rectangle monthNameBounds;
+ private Rectangle[] dayNamesBounds;
+ private MonthViewDay[] days;
+ private string[] _dayHeaders;
+ private Size _size = new Size();
+ private Point _location;
+ private MonthView _monthview;
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets the bounds.
+ ///
+ public Rectangle Bounds
+ {
+ get { return new Rectangle( Location, Size ); }
+ }
+
+ ///
+ /// Gets the month view.
+ ///
+ public MonthView MonthView
+ {
+ get { return _monthview; }
+ }
+
+ ///
+ /// Gets the location.
+ ///
+ public Point Location
+ {
+ get { return _location; }
+ }
+
+ ///
+ /// Gets the size.
+ ///
+ public Size Size
+ {
+ get { return MonthView.MonthSize; }
+ }
+
+ ///
+ /// Gets or sets the days.
+ ///
+ ///
+ /// The days.
+ ///
+ public MonthViewDay[] Days
+ {
+ get { return days; }
+ set { days = value; }
+ }
+
+ ///
+ /// Gets or sets the day names bounds.
+ ///
+ ///
+ /// The day names bounds.
+ ///
+ public Rectangle[] DayNamesBounds
+ {
+ get { return dayNamesBounds; }
+ set { dayNamesBounds = value; }
+ }
+
+ ///
+ /// Gets or sets the day headers.
+ ///
+ ///
+ /// The day headers.
+ ///
+ public string[] DayHeaders
+ {
+ get { return _dayHeaders; }
+ set { _dayHeaders = value; }
+ }
+
+ ///
+ /// Gets or sets the month name bounds.
+ ///
+ ///
+ /// The month name bounds.
+ ///
+ public Rectangle MonthNameBounds
+ {
+ get { return monthNameBounds; }
+ set { monthNameBounds = value; }
+ }
+
+ ///
+ /// Gets or sets the date of the first day of the month
+ ///
+ public DateTime Date
+ {
+ get { return _date; }
+ }
+
+ #endregion
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The month view.
+ /// The date.
+ internal MonthViewMonth( MonthView monthView, DateTime date )
+ {
+ if( date.Day != 1 )
+ {
+ date = new DateTime( date.Year, date.Month, 1 );
+ }
+
+
+ _monthview = monthView;
+ _date = date;
+
+ int preDays = ( new int[] { 0, 1, 2, 3, 4, 5, 6 } )[(int)date.DayOfWeek] - (int)MonthView.FirstDayOfWeek;
+ days = new MonthViewDay[6 * 7];
+ DateTime curDate = date.AddDays( -preDays );
+ DayHeaders = new string[7];
+
+ for( int i = 0; i < days.Length; i++ )
+ {
+ days[i] = new MonthViewDay( this, curDate );
+
+ if( i < 7 )
+ {
+ DayHeaders[i] = curDate.ToString( MonthView.DayNamesFormat ).Substring( 0, MonthView.DayNamesLength );
+ }
+
+ curDate = curDate.AddDays( 1 );
+ }
+ }
+
+ #region Public Methods
+
+ #endregion
+
+ #region Private Methods
+
+ ///
+ /// Sets the value of the property
+ ///
+ ///
+ internal void SetLocation( Point location )
+ {
+
+ int startX = location.X;
+ int startY = location.Y;
+ int curX = startX;
+ int curY = startY;
+
+ _location = location;
+
+ monthNameBounds = new Rectangle( location, new Size( Size.Width, MonthView.DaySize.Height ) );
+
+ if( MonthView.DayNamesVisible )
+ {
+ dayNamesBounds = new Rectangle[7];
+ curY = location.Y + MonthView.DaySize.Height;
+ for( int i = 0; i < dayNamesBounds.Length; i++ )
+ {
+ DayNamesBounds[i] = new Rectangle( curX, curY, MonthView.DaySize.Width, MonthView.DaySize.Height );
+
+ curX += MonthView.DaySize.Width;
+ }
+
+ }
+ else
+ {
+ dayNamesBounds = new Rectangle[] { };
+ }
+
+ curX = startX;
+ curY = startY + MonthView.DaySize.Height * 2;
+
+ for( int i = 0; i < Days.Length; i++ )
+ {
+ Days[i].SetBounds( new Rectangle( new Point( curX, curY ), MonthView.DaySize ) );
+
+ curX += MonthView.DaySize.Width;
+
+ if( ( i + 1 ) % 7 == 0 )
+ {
+ curX = startX;
+ curY += MonthView.DaySize.Height;
+ }
+ }
+
+ }
+
+ #endregion
+
+ }
+}
\ No newline at end of file
diff --git a/WindowsFormsCalendar/Properties/AssemblyInfo.cs b/WindowsFormsCalendar/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..b9a9af3
--- /dev/null
+++ b/WindowsFormsCalendar/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("WindowsFormsCalendar")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct( "WindowsFormsCalendar" )]
+[assembly: AssemblyCopyright("Copyright © 2012 Justin LeCheminant")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("25ba6a13-96fe-4dd9-baae-0656f18fbcd0")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.1.*")]
+[assembly: AssemblyFileVersion("1.1.0.0")]
diff --git a/WindowsFormsCalendar/ReadMe.txt b/WindowsFormsCalendar/ReadMe.txt
new file mode 100644
index 0000000..44e6f17
--- /dev/null
+++ b/WindowsFormsCalendar/ReadMe.txt
@@ -0,0 +1,15 @@
+This is the read me file for the WindowsFormsCalendar project.
+
+This project is a fork of the A Professional Calendar project on codeplex.
+
+The current version is 1.1
+
+1.1 features
+ - Added Font selection for calendar items
+ - Added Foreground Color settings for calendar items
+ - Added Background Color settings for calendar items
+ - Updated the assembly version information to be correct.
+
+1.0 features
+ - Moved the project to the 4.0 framework
+ - Added a clock format selection to the calendar
\ No newline at end of file
diff --git a/WindowsFormsCalendar/Renderers/CalendarProfessionalRenderer.cs b/WindowsFormsCalendar/Renderers/CalendarProfessionalRenderer.cs
new file mode 100644
index 0000000..4d0e5a2
--- /dev/null
+++ b/WindowsFormsCalendar/Renderers/CalendarProfessionalRenderer.cs
@@ -0,0 +1,271 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Renders the professional calendar control
+ ///
+ public class CalendarProfessionalRenderer
+ : CalendarSystemRenderer
+ {
+ #region Fields
+
+ ///
+ /// HeaderA
+ ///
+ public Color HeaderA = FromHex("#E4ECF6");
+
+ ///
+ /// HeaderB
+ ///
+ public Color HeaderB = FromHex("#D6E2F1");
+
+ ///
+ /// HeaderC
+ ///
+ public Color HeaderC = FromHex("#C2D4EB");
+
+ ///
+ /// HeaderD
+ ///
+ public Color HeaderD = FromHex("#D0DEEF");
+
+ ///
+ /// TodayA
+ ///
+ public Color TodayA = FromHex("#F8D478");
+
+ ///
+ /// TodayB
+ ///
+ public Color TodayB = FromHex("#F8D478");
+
+ ///
+ /// TodayC
+ ///
+ public Color TodayC = FromHex("#F2AA36");
+
+ ///
+ /// TodayD
+ ///
+ public Color TodayD = FromHex("#F7C966");
+
+ #endregion
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The c.
+ public CalendarProfessionalRenderer(Calendar c)
+ : base(c)
+ {
+
+ ColorTable.Background = FromHex("#E3EFFF");
+ ColorTable.DayBackgroundEven = FromHex("#A5BFE1");
+ ColorTable.DayBackgroundOdd = FromHex("#FFFFFF");
+ ColorTable.DayBackgroundSelected = FromHex("#E6EDF7");
+ ColorTable.DayBorder = FromHex("#5D8CC9");
+ ColorTable.DayHeaderBackground = FromHex("#DFE8F5");
+ ColorTable.DayHeaderText = Color.Black;
+ ColorTable.DayHeaderSecondaryText = Color.Black;
+ ColorTable.DayTopBorder = FromHex("#5D8CC9");
+ ColorTable.DayTopSelectedBorder = FromHex("#5D8CC9");
+ ColorTable.DayTopBackground = FromHex("#A5BFE1");
+ ColorTable.DayTopSelectedBackground = FromHex("#294C7A");
+ ColorTable.ItemBorder = FromHex("#5D8CC9");
+ ColorTable.ItemBackground = FromHex("#C0D3EA");
+ ColorTable.ItemText = Color.Black;
+ ColorTable.ItemSecondaryText = FromHex("#294C7A");
+ ColorTable.ItemSelectedBorder = Color.Black;
+ ColorTable.ItemSelectedBackground = FromHex("#C0D3EA");
+ ColorTable.ItemSelectedText = Color.Black;
+ ColorTable.WeekHeaderBackground = FromHex("#DFE8F5");
+ ColorTable.WeekHeaderBorder = FromHex("#5D8CC9");
+ ColorTable.WeekHeaderText = FromHex("#5D8CC9");
+ ColorTable.TodayBorder = FromHex("#EE9311");
+ ColorTable.TodayTopBackground = FromHex("#EE9311");
+ ColorTable.TimeScaleLine = FromHex("#6593CF");
+ ColorTable.TimeScaleHours = FromHex("#6593CF");
+ ColorTable.TimeScaleMinutes = FromHex("#6593CF");
+ ColorTable.TimeUnitBackground = FromHex("#E6EDF7");
+ ColorTable.TimeUnitHighlightedBackground = Color.White;
+ ColorTable.TimeUnitSelectedBackground = FromHex("#294C7A");
+ ColorTable.TimeUnitBorderLight = FromHex("#D5E1F1");
+ ColorTable.TimeUnitBorderDark = FromHex("#A5BFE1");
+ ColorTable.WeekDayName = FromHex("#6593CF");
+
+ SelectedItemBorder = 2f;
+ ItemRoundness = 5;
+ }
+
+ #region Private Method
+
+ ///
+ /// Gradients the rect.
+ ///
+ /// The g.
+ /// The bounds.
+ /// A.
+ /// The b.
+ public static void GradientRect(Graphics g, Rectangle bounds, Color a, Color b)
+ {
+ using (LinearGradientBrush br = new LinearGradientBrush(bounds, b, a, -90))
+ {
+ g.FillRectangle(br, bounds);
+ }
+ }
+
+ ///
+ /// Glossies the rect.
+ ///
+ /// The g.
+ /// The bounds.
+ /// A.
+ /// The b.
+ /// The c.
+ /// The d.
+ public static void GlossyRect(Graphics g, Rectangle bounds, Color a, Color b, Color c, Color d)
+ {
+ Rectangle top = new Rectangle(bounds.Left, bounds.Top, bounds.Width, bounds.Height / 2);
+ Rectangle bot = Rectangle.FromLTRB(bounds.Left, top.Bottom, bounds.Right, bounds.Bottom);
+
+ GradientRect(g, top, a, b);
+ GradientRect(g, bot, c, d);
+
+ }
+
+ ///
+ /// Shortcut to one on CalendarColorTable
+ ///
+ ///
+ ///
+ private static Color FromHex(string color)
+ {
+ return CalendarColorTable.FromHex(color);
+ }
+
+ #endregion
+
+ #region Overrides
+
+ ///
+ /// Initializes the Calendar
+ ///
+ ///
+ public override void OnInitialize(CalendarRendererEventArgs e)
+ {
+ base.OnInitialize(e);
+
+ e.Calendar.Font = SystemFonts.CaptionFont;
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ public override void OnDrawDayHeaderBackground(CalendarRendererDayEventArgs e)
+ {
+ Rectangle r = e.Day.HeaderBounds;
+
+ if (e.Day.Date == DateTime.Today)
+ {
+ GlossyRect(e.Graphics, e.Day.HeaderBounds, TodayA, TodayB, TodayC, TodayD);
+ }
+ else
+ {
+ GlossyRect(e.Graphics, e.Day.HeaderBounds, HeaderA, HeaderB, HeaderC, HeaderD);
+ }
+
+ if (e.Calendar.DaysMode == CalendarDaysMode.Short)
+ {
+ using (Pen p = new Pen(ColorTable.DayBorder))
+ {
+ e.Graphics.DrawLine(p, r.Left, r.Top, r.Right, r.Top);
+ e.Graphics.DrawLine(p, r.Left, r.Bottom, r.Right, r.Bottom);
+ }
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ public override void OnDrawItemBorder(CalendarRendererItemBoundsEventArgs e)
+ {
+ base.OnDrawItemBorder(e);
+
+ using (Pen p = new Pen(Color.FromArgb(150, Color.White)))
+ {
+ e.Graphics.DrawLine(p, e.Bounds.Left + ItemRoundness, e.Bounds.Top + 1, e.Bounds.Right - ItemRoundness, e.Bounds.Top + 1);
+ }
+
+ if (e.Item.Selected && !e.Item.IsDragging)
+ {
+ bool horizontal = false;
+ bool vertical = false;
+ Rectangle r1 = new Rectangle(0, 0, 5, 5);
+ Rectangle r2 = new Rectangle(0, 0, 5, 5);
+
+ horizontal = e.Item.IsOnDayTop;
+ vertical = !e.Item.IsOnDayTop && e.Calendar.DaysMode == CalendarDaysMode.Expanded;
+
+ if (horizontal)
+ {
+ r1.X = e.Bounds.Left - 2;
+ r2.X = e.Bounds.Right - r1.Width + 2;
+ r1.Y = e.Bounds.Top + (e.Bounds.Height - r1.Height) / 2;
+ r2.Y = r1.Y;
+ }
+
+ if (vertical)
+ {
+ r1.Y = e.Bounds.Top - 2;
+ r2.Y = e.Bounds.Bottom - r1.Height + 2;
+ r1.X = e.Bounds.Left + (e.Bounds.Width - r1.Width) / 2;
+ r2.X = r1.X;
+ }
+
+ if ((horizontal || vertical) && Calendar.AllowItemResize)
+ {
+ if (!e.Item.IsOpenStart && e.IsFirst)
+ {
+ e.Graphics.FillRectangle(Brushes.White, r1);
+ e.Graphics.DrawRectangle(Pens.Black, r1);
+ }
+
+ if (!e.Item.IsOpenEnd && e.IsLast)
+ {
+ e.Graphics.FillRectangle(Brushes.White, r2);
+ e.Graphics.DrawRectangle(Pens.Black, r2);
+ }
+ }
+ }
+ }
+
+ #endregion
+
+ }
+}
diff --git a/WindowsFormsCalendar/Renderers/CalendarRenderer.cs b/WindowsFormsCalendar/Renderers/CalendarRenderer.cs
new file mode 100644
index 0000000..2b5191e
--- /dev/null
+++ b/WindowsFormsCalendar/Renderers/CalendarRenderer.cs
@@ -0,0 +1,1973 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Base class that renders visual elements of Calendar control
+ ///
+ public class CalendarRenderer
+ {
+ #region Static
+
+ ///
+ /// Comparison delegate to sort items
+ ///
+ ///
+ ///
+ ///
+ private static int CompareItems(CalendarItem item1, CalendarItem item2)
+ {
+ return item1.StartDate.CompareTo(item2.StartDate) * -1;
+ }
+
+ ///
+ /// Comparison delegate to sort units
+ ///
+ ///
+ ///
+ ///
+ private static int CompareUnits(CalendarTimeScaleUnit item1, CalendarTimeScaleUnit item2)
+ {
+ return item1.Date.CompareTo(item2.Date);
+ }
+
+ ///
+ /// Compares both items by Date
+ ///
+ ///
+ ///
+ ///
+ private static int CompareTops(CalendarDayTop top1, CalendarDayTop top2)
+ {
+ return top1.Date.CompareTo(top2.Date);
+ }
+
+ ///
+ /// Creates a rectangle with rounded corners
+ ///
+ ///
+ ///
+ ///
+ public static GraphicsPath RoundRectangle(Rectangle r, int radius)
+ {
+ return RoundRectangle(r, radius, Corners.All);
+ }
+
+ ///
+ /// Creates a rectangle with the specified corners rounded
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static GraphicsPath RoundRectangle(Rectangle r, int radius, Corners corners)
+ {
+ GraphicsPath path = new GraphicsPath(); if (r.Width <= 0 || r.Height <= 0) return path;
+ int d = radius * 2;
+
+ int nw = (corners & Corners.NorthWest) == Corners.NorthWest ? d : 0;
+ int ne = (corners & Corners.NorthEast) == Corners.NorthEast ? d : 0;
+ int se = (corners & Corners.SouthEast) == Corners.SouthEast ? d : 0;
+ int sw = (corners & Corners.SouthWest) == Corners.SouthWest ? d : 0;
+
+ path.AddLine(r.Left + nw, r.Top, r.Right - ne, r.Top);
+
+ if (ne > 0)
+ {
+ path.AddArc(Rectangle.FromLTRB(r.Right - ne, r.Top, r.Right, r.Top + ne),
+ -90, 90);
+ }
+
+ path.AddLine(r.Right, r.Top + ne, r.Right, r.Bottom - se);
+
+ if (se > 0)
+ {
+ path.AddArc(Rectangle.FromLTRB(r.Right - se, r.Bottom - se, r.Right, r.Bottom),
+ 0, 90);
+ }
+
+ path.AddLine(r.Right - se, r.Bottom, r.Left + sw, r.Bottom);
+
+ if (sw > 0)
+ {
+ path.AddArc(Rectangle.FromLTRB(r.Left, r.Bottom - sw, r.Left + sw, r.Bottom),
+ 90, 90);
+ }
+
+ path.AddLine(r.Left, r.Bottom - sw, r.Left, r.Top + nw);
+
+ if (nw > 0)
+ {
+ path.AddArc(Rectangle.FromLTRB(r.Left, r.Top, r.Left + nw, r.Top + nw),
+ 180, 90);
+ }
+
+ path.CloseFigure();
+
+ return path;
+ }
+
+
+ #endregion
+
+ #region Events
+
+ #endregion
+
+ #region Fields
+
+ private int _allDayItemsPadding;
+ private int _standardItemHeight;
+ private int _dayTopHeight;
+ private int _dayTopMinHeight;
+ private Calendar _calendar;
+ private Rectangle[] _dayNameHeaderColumns;
+ private int _dayHeaderHeight;
+ private int _dayNameHeadersHeight;
+ private int _itemInvalidateMargin;
+ private int _itemsPadding;
+ private Padding _itemTextMargin;
+ private int _itemShadowPadding;
+ private int _itemRoundness;
+ private Rectangle _timeScaleBounds;
+ private int _timeScaleUnitHeight;
+ private int _timeScaleWidth;
+ private int _weekHeaderWidth;
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets or sets the padding of the items that goes on the top part of the days,
+ /// when in
+ ///
+ ///
+ /// The day top items padding.
+ ///
+ public int DayTopItemsPadding
+ {
+ get { return _allDayItemsPadding; }
+ set { _allDayItemsPadding = value; }
+ }
+
+ ///
+ /// Gets the current height of the all day items area
+ ///
+ ///
+ /// The height of the day top.
+ ///
+ public virtual int DayTopHeight
+ {
+ get
+ {
+ if( _dayTopHeight == 0 )
+ {
+ _dayTopHeight = DayTopMinHeight;
+ }
+ return _dayTopHeight;
+ }
+ set
+ {
+ _dayTopHeight = value;
+ }
+ }
+
+ ///
+ /// Gets the height of items on day tops
+ ///
+ ///
+ /// The height of the standard item.
+ ///
+ public virtual int StandardItemHeight
+ {
+ get
+ {
+ if( _standardItemHeight == 0 )
+ {
+ _standardItemHeight = TextRenderer.MeasureText( "Ag", Calendar.Font ).Height;
+ }
+
+ return _standardItemHeight + ItemTextMargin.Vertical;
+ }
+ }
+
+ ///
+ /// Gets the minimum height for day tops
+ ///
+ ///
+ /// The height of the day top min.
+ ///
+ public virtual int DayTopMinHeight
+ {
+ get
+ {
+ if( _dayTopMinHeight == 0 )
+ {
+ _dayTopMinHeight = TextRenderer.MeasureText( "Ag", Calendar.Font ).Height + 16;
+ }
+
+ return _dayTopMinHeight;
+ }
+ }
+
+ ///
+ /// Gets the this renderer belongs to
+ ///
+ public Calendar Calendar
+ {
+ get { return _calendar; }
+ }
+
+ ///
+ /// Gets the bounds for day name headers
+ ///
+ public Rectangle[] DayNameHeaderColumns
+ {
+ get { return _dayNameHeaderColumns; }
+ }
+
+ ///
+ /// Gets the height of the header of days
+ ///
+ ///
+ /// The height of the day header.
+ ///
+ public virtual int DayHeaderHeight
+ {
+ get
+ {
+ if( _dayHeaderHeight == 0 )
+ {
+ _dayHeaderHeight = TextRenderer.MeasureText( "Ag", Calendar.Font ).Height + 4;
+ }
+
+ return _dayHeaderHeight;
+ }
+ }
+
+ ///
+ /// Gets a value indicating if the day names headers are visible (e.g. Monday, Tuesday, Wednesday ...)
+ ///
+ ///
+ /// true if [day name headers visible]; otherwise, false.
+ ///
+ public bool DayNameHeadersVisible
+ {
+ get { return Calendar.DaysMode == CalendarDaysMode.Short; }
+ }
+
+ ///
+ /// Gets the height of the day name headers
+ ///
+ ///
+ /// The height of the day name headers.
+ ///
+ public virtual int DayNameHeadersHeight
+ {
+ get
+ {
+ if( _dayNameHeadersHeight == 0 )
+ {
+ _dayNameHeadersHeight = DayHeaderHeight;
+ }
+
+ return _dayNameHeadersHeight;
+ }
+ }
+
+ ///
+ /// Gets the margin of the text in the items
+ ///
+ ///
+ /// The item text margin.
+ ///
+ public virtual Padding ItemTextMargin
+ {
+ get { return _itemTextMargin; }
+ set
+ {
+ _itemTextMargin = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the amount of pixels that the item's shadow is dropped
+ ///
+ ///
+ /// The item shadow padding.
+ ///
+ public virtual int ItemShadowPadding
+ {
+ get { return _itemShadowPadding; }
+ set { _itemShadowPadding = value; }
+ }
+
+ ///
+ /// Gets or sets the extra margin for invalidating and redrawing items
+ ///
+ ///
+ /// The item invalidate margin.
+ ///
+ public int ItemInvalidateMargin
+ {
+ get { return _itemInvalidateMargin; }
+ set { _itemInvalidateMargin = value; }
+ }
+
+ ///
+ /// Gets or sets the padding of items on expanded mode
+ ///
+ ///
+ /// The items padding.
+ ///
+ public int ItemsPadding
+ {
+ get { return _itemsPadding; }
+ set { _itemsPadding = value; }
+ }
+
+ ///
+ /// Gets or sets the roundness of the item
+ ///
+ ///
+ /// The item roundness.
+ ///
+ public int ItemRoundness
+ {
+ get { return _itemRoundness; }
+ set { _itemRoundness = value; }
+ }
+
+ ///
+ /// Gets or sets the bounds of the timescale
+ ///
+ ///
+ /// The time scale bounds.
+ ///
+ public Rectangle TimeScaleBounds
+ {
+ get { return _timeScaleBounds; }
+ set { _timeScaleBounds = value; }
+ }
+
+ ///
+ /// Gets the height of the time scale unit.
+ ///
+ ///
+ /// The height of the time scale unit.
+ ///
+ public virtual int TimeScaleUnitHeight
+ {
+ get
+ {
+ if( _timeScaleUnitHeight == 0 )
+ {
+ _timeScaleUnitHeight = TextRenderer.MeasureText( "Ag", Calendar.Font ).Height + 10;
+ }
+
+ return _timeScaleUnitHeight;
+ }
+ }
+
+ ///
+ /// Gets a value indicating whether [time scale visible].
+ ///
+ ///
+ /// true if [time scale visible]; otherwise, false.
+ ///
+ public bool TimeScaleVisible
+ {
+ get { return Calendar.DaysMode == CalendarDaysMode.Expanded; }
+ }
+
+ ///
+ /// Gets the width of the timescale
+ ///
+ ///
+ /// The width of the time scale.
+ ///
+ public virtual int TimeScaleWidth
+ {
+ get
+ {
+ if( _timeScaleWidth == 0 )
+ {
+ _timeScaleWidth = 60;
+ }
+ return _timeScaleWidth;
+ }
+ }
+
+ ///
+ /// Gets the width of the week header.
+ ///
+ ///
+ /// The width of the week header.
+ ///
+ public virtual int WeekHeaderWidth
+ {
+ get
+ {
+ if( _weekHeaderWidth == 0 )
+ {
+ _weekHeaderWidth = TextRenderer.MeasureText( "Ag", Calendar.Font ).Height + 4;
+ }
+
+ return _weekHeaderWidth;
+ }
+ }
+
+ #endregion
+
+ ///
+ /// Creates a new renderer for the specified calendar
+ ///
+ ///
+ public CalendarRenderer(Calendar calendar)
+ {
+ if (calendar == null)
+ {
+ throw new ArgumentNullException("calendar");
+ }
+
+ _calendar = calendar;
+ _allDayItemsPadding = 5;
+ _itemsPadding = 5;
+ _itemTextMargin = new Padding(3);
+ _itemShadowPadding = 4;
+ _itemInvalidateMargin = 0;
+ }
+
+ #region Public Methods
+
+ ///
+ /// Gets the exact Y coordinate that corresponds to the specified time.
+ /// This only works when in Expanded mode.
+ ///
+ /// Time of day to get Y coordinate
+ ///
+ /// Y coordinate corresponding to the specified time
+ ///
+ /// When calendar is not in Expaned mode.
+ public int GetTimeY(TimeSpan time)
+ {
+ if (Calendar.DaysMode != CalendarDaysMode.Expanded)
+ throw new InvalidOperationException("Can't measure Time's Y when calendar isn't in Expanded mode");
+
+ //If no days, no Y
+ if (Calendar.Days == null || Calendar.Days.Length == 0)
+ return 0;
+
+ CalendarDay fisrtDay = Calendar.Days[0];
+ CalendarTimeScaleUnit firstUnit = fisrtDay.TimeUnits[0];
+ double duration = Convert.ToDouble(firstUnit.Duration.TotalMinutes);
+ double totalmins = time.TotalMinutes;
+ int unitIndex = Convert.ToInt32(Math.Floor(totalmins / duration));
+ double module = Convert.ToInt32(Math.Floor(totalmins % duration));
+
+ CalendarTimeScaleUnit unit = Calendar.Days[0].TimeUnits[unitIndex];
+
+ int minuteHeight = Convert.ToInt32(Convert.ToDouble(unit.Bounds.Height) / duration);
+
+ return unit.Bounds.Top + minuteHeight * Convert.ToInt32(module);
+
+ }
+
+ ///
+ /// Creates a rectangle with item roundess
+ ///
+ /// The instance containing the event data.
+ /// The bounds.
+ ///
+ public GraphicsPath ItemRectangle(CalendarRendererItemBoundsEventArgs evtData, Rectangle bounds)
+ {
+ int pointerPadding = 5;
+
+
+ if ((evtData.Item.Bounds.Top != evtData.Item.MinuteStartTop ||
+ evtData.Item.Bounds.Bottom != evtData.Item.MinuteEndTop) &&
+ (evtData.Item.MinuteEndTop != 0 && evtData.Item.MinuteStartTop != 0) &&
+ ! evtData.Item.IsOnDayTop && evtData.Calendar.DaysMode == CalendarDaysMode.Expanded)
+ {
+ /*
+ * Trace pointed item
+ *
+ * C--------------------D
+ * | |
+ * A---B |
+ * | |
+ * H---G |
+ * | |
+ * F--------------------E
+ */
+
+ int sq = ItemRoundness * 2;
+ Point a = new Point(bounds.Left, evtData.Item.MinuteStartTop);
+ Point b = new Point(a.X + pointerPadding, a.Y);
+ Point c = new Point(b.X, bounds.Top);
+ Point d = new Point(bounds.Right, c.Y);
+ Point e = new Point(d.X, bounds.Bottom);
+ Point f = new Point(b.X, e.Y);
+ Point g = new Point(b.X, evtData.Item.MinuteEndTop);
+ Point h = new Point(a.X, g.Y);
+
+
+ GraphicsPath path = new GraphicsPath();
+
+ path.AddLine(a, b);
+ path.AddLine(b, c);
+ path.AddLine(c, new Point(d.X - sq, d.Y));
+ path.AddArc(new Rectangle(d.X - sq, d.Y, sq, sq), -90, 90);
+ path.AddLine(new Point(d.X, d.Y + sq), new Point(d.X, e.Y - sq));
+ path.AddArc(new Rectangle(e.X - sq, e.Y - sq, sq, sq), 0, 90);
+ path.AddLine(new Point(e.X - sq, e.Y), f);
+ path.AddLine(f, g);
+ path.AddLine(g, h);
+ path.AddLine(h, a);
+
+ path.CloseFigure();
+
+ return path;
+
+ }
+ else
+ {
+ Corners crns = Corners.None;
+
+ if (evtData.IsFirst)
+ {
+ crns |= Corners.West;
+ }
+
+ if (evtData.IsLast)
+ {
+ crns |= Corners.East;
+ }
+
+ return RoundRectangle(bounds, ItemRoundness, crns);
+ }
+ }
+
+ ///
+ /// Fills the specified rectangle with item border roundness
+ ///
+ /// The instance containing the event data.
+ /// The bounds.
+ /// The north.
+ /// The south.
+ public void ItemFill(CalendarRendererItemBoundsEventArgs e, Rectangle bounds, Color north, Color south)
+ {
+ if (bounds.Width <= 0 || bounds.Height <= 0)
+ {
+ return;
+ }
+
+ using (GraphicsPath r = ItemRectangle(e, bounds))
+ {
+ using (LinearGradientBrush b = new LinearGradientBrush(bounds, north, south, 90))
+ {
+ e.Graphics.FillPath(b, r);
+ }
+ }
+ }
+
+ ///
+ /// Items the pattern.
+ ///
+ /// The instance containing the event data.
+ /// The bounds.
+ /// Color of the pattern.
+ public void ItemPattern(CalendarRendererItemBoundsEventArgs e, Rectangle bounds, Color patternColor)
+ {
+ if (bounds.Width <= 0 || bounds.Height <= 0)
+ {
+ return;
+ }
+
+ using (GraphicsPath r = ItemRectangle(e, bounds))
+ {
+ using (Brush b = new HatchBrush(e.Item.Pattern, patternColor, Color.Transparent))
+ {
+ e.Graphics.FillPath(b, r);
+ }
+ }
+ }
+
+ ///
+ /// Draws the specified rectangle with item border roundnesss
+ ///
+ /// The instance containing the event data.
+ /// The bounds.
+ /// The color.
+ /// The width.
+ public void ItemBorder(CalendarRendererItemBoundsEventArgs e, Rectangle bounds, Color color, float width)
+ {
+ using (GraphicsPath r = ItemRectangle(e, bounds))
+ {
+ using (Pen p = new Pen(color, width))
+ {
+ e.Graphics.DrawPath(p, r);
+ }
+ }
+ }
+
+ ///
+ /// Peform layout of elements and items of the calendar
+ ///
+ public void PerformLayout()
+ {
+ PerformLayout(true);
+ }
+
+ ///
+ /// Updates the bounds of graphical elements.
+ /// Optionally calls to update bounds of items.
+ ///
+ ///
+ /// This method is called every time the control is resized.
+ ///
+ public void PerformLayout(bool performItemsLayout)
+ {
+ if (Calendar.Days == null) return;
+
+ int leftStart = 0;
+ int curLeft = 0;
+ int curTop = 0;
+ int dayWidth = 0;
+ int dayHeight = 0;
+ int scrollBarWidth = 20;
+
+ TimeScaleBounds = Rectangle.Empty;
+
+ if (Calendar.DaysMode == CalendarDaysMode.Expanded)
+ {
+ #region Expanded days
+ TimeScaleBounds = new Rectangle(0, 0, TimeScaleWidth, Calendar.ClientRectangle.Height);
+ curLeft = TimeScaleBounds.Right;
+ dayHeight = Calendar.ClientSize.Height - 1;
+ dayWidth = (Calendar.ClientSize.Width - TimeScaleBounds.Width - scrollBarWidth) / Calendar.Days.Length;
+
+ for (int i = 0; i < Calendar.Days.Length; i++)
+ {
+ CalendarDay day = Calendar.Days[i];
+ day.SetBounds(new Rectangle(curLeft, curTop, dayWidth, dayHeight));
+ day.DayTop.SetBounds(new Rectangle(curLeft, day.HeaderBounds.Bottom, dayWidth, DayTopHeight));
+ curLeft += dayWidth + 1;
+ //int k = 0;
+ int utop = day.BodyBounds.Top + Calendar.TimeUnitsOffset * TimeScaleUnitHeight;
+
+ for (int j = 0; j < day.TimeUnits.Length; j++)
+ {
+ CalendarTimeScaleUnit unit = day.TimeUnits[j];
+
+ if (Calendar.TimeUnitsOffset * -1 >= (j + 1))
+ {
+ unit.SetVisible(false);
+ }
+ else
+ {
+ unit.SetVisible(true);
+ //unit.SetBounds(new Rectangle(day.Bounds.Left, day.BodyBounds.Top + k++ * TimeScaleUnitHeight, day.Bounds.Width, TimeScaleUnitHeight));
+ }
+ unit.SetBounds(new Rectangle(day.Bounds.Left, utop, day.Bounds.Width, TimeScaleUnitHeight));
+ utop += TimeScaleUnitHeight;
+ }
+ }
+ #endregion
+ }
+ else
+ {
+ #region Short days (Calendar View)
+ leftStart = WeekHeaderWidth;
+ curLeft = leftStart;
+ curTop = DayNameHeadersHeight;
+ dayWidth = (Calendar.ClientSize.Width - leftStart - scrollBarWidth) / 7;
+ dayHeight = (Calendar.ClientSize.Height - curTop) / (Calendar.Days.Length / 7) - 1;
+ _dayNameHeaderColumns = new Rectangle[7];
+ int j = 0;
+
+ for (int i = 0; i < Calendar.Days.Length; i++)
+ {
+ Calendar.Days[i].SetBounds(new Rectangle(curLeft, curTop, dayWidth, dayHeight));
+ curLeft += dayWidth + 1;
+
+ if ((i + 1) % 7 == 0)
+ {
+ curTop += dayHeight + 1;
+ curLeft = leftStart;
+ }
+
+ if (i < _dayNameHeaderColumns.Length)
+ {
+ _dayNameHeaderColumns[i] = new Rectangle(curLeft, 0, dayWidth, DayNameHeadersHeight);
+ }
+
+ if (Calendar.Days[i].Date.DayOfWeek == Calendar.FirstDayOfWeek)
+ {
+ Calendar.Weeks[j++].SetBounds(new Rectangle(0, curTop, Calendar.ClientSize.Width, dayHeight));
+ }
+ }
+ #endregion
+ }
+
+ if(performItemsLayout)
+ PerformItemsLayout();
+ }
+
+ ///
+ /// Updates the bounds of CalendarItems
+ ///
+ public void PerformItemsLayout()
+ {
+ if (Calendar.Days == null || Calendar.Items.Count == 0) return;
+ bool alldaychanged = false;
+ int offset = Math.Abs(Calendar.TimeUnitsOffset);
+ List itemsOnScene = new List();
+
+ foreach (CalendarDay day in Calendar.Days)
+ day.ContainedItems.Clear();
+
+ if (Calendar.DaysMode == CalendarDaysMode.Expanded)
+ {
+ #region Expanded mode algorithm
+
+ #region Assign units and initial coords
+
+ int maxItemsOnDayTop = 0;
+
+ foreach (CalendarItem item in Calendar.Items)
+ {
+ item.ClearBounds();
+ item.ClearPassings();
+
+ if (item.IsOnDayTop)
+ {
+ #region Among day tops
+
+ CalendarDay dayStart = item.DayStart;
+ CalendarDay dayEnd = item.DayEnd;
+
+ if (dayStart == null) dayStart = Calendar.Days[0];
+ if (dayEnd == null) dayEnd = Calendar.Days[Calendar.Days.Length - 1];
+
+ for (int i = dayStart.Index; i <= dayEnd.Index; i++)
+ {
+ item.AddTopPassing(Calendar.Days[i].DayTop);
+ Calendar.Days[i].DayTop.AddPassingItem(item);
+ }
+
+ item.SetBounds(Rectangle.FromLTRB(dayStart.DayTop.Bounds.Left, 0, dayEnd.DayTop.Bounds.Right, 1));
+
+ #endregion
+ }
+ else
+ {
+ #region Among time units
+
+ CalendarDay day = item.DayStart; if (day == null) continue;
+ double unitDurationMinutes = Convert.ToDouble((int)Calendar.TimeScale);
+ DateTime date1 = item.StartDate;
+ DateTime date2 = item.EndDate;
+
+ int indexStart = Convert.ToInt32(Math.Floor(date1.TimeOfDay.TotalMinutes / unitDurationMinutes));
+ int indexEnd = Convert.ToInt32(Math.Ceiling(date2.TimeOfDay.TotalMinutes / unitDurationMinutes));
+
+ for (int i = 0; i < day.TimeUnits.Length; i++)
+ {
+ if (i >= indexStart && i < indexEnd)
+ {
+ day.TimeUnits[i].AddPassingItem(item);
+ item.AddUnitPassing(day.TimeUnits[i]);
+ }
+ }
+
+ item.SetBounds(Rectangle.Empty);
+ itemsOnScene.Add(item);
+
+ #endregion
+ }
+ }
+
+ //Calendar.Items.Sort(CompareItems);
+ #endregion
+
+ #region Items on DayTops
+ foreach (CalendarDay day in Calendar.Days)
+ {
+ maxItemsOnDayTop = Math.Max(maxItemsOnDayTop, day.DayTop.PassingItems.Count);
+ }
+
+ int[,] tmatix = new int[Calendar.Days.Length, maxItemsOnDayTop];
+
+ if (tmatix.GetLength(1) > 0)
+ {
+ foreach (CalendarItem item in Calendar.Items)
+ {
+ if (!item.IsOnDayTop) continue;
+
+ item.TopsPassing.Sort(CompareTops);
+
+ int topStart = item.TopsPassing[0].Day.Index;
+ int topEnd = item.TopsPassing[item.TopsPassing.Count - 1].Day.Index;
+
+ PlaceInMatrix(ref tmatix, Calendar.Items.IndexOf(item) + 1, topStart, topEnd);
+ }
+
+ int dayTopsHeight = tmatix.GetLength(1) * StandardItemHeight + DayTopMinHeight;
+
+ if (DayTopHeight != dayTopsHeight)
+ {
+ DayTopHeight = dayTopsHeight;
+ alldaychanged = true;
+ }
+
+ int itemHeight = StandardItemHeight;//Convert.ToInt32(Math.Floor(Convert.ToSingle(DayTopHeight) / Convert.ToSingle(tmatix.GetLength(1))));
+
+ foreach (CalendarItem item in Calendar.Items)
+ {
+ if (!item.IsOnDayTop) continue;
+
+ int index = Calendar.Items.IndexOf(item);
+
+ int top, left;
+ FindInMatrix(tmatix, index + 1, out left, out top);
+
+ Rectangle r = item.Bounds;
+ r.Y = Calendar.Days[0].DayTop.Bounds.Top + top * itemHeight;
+ r.Height = itemHeight;
+ item.SetBounds(r);
+ item.FirstAndLastRectangleGapping();
+ }
+ }
+ if (alldaychanged)
+ PerformLayout(false);
+ #endregion
+
+ foreach (CalendarDay day in Calendar.Days)
+ {
+ #region Create groups
+
+ maxItemsOnDayTop = Math.Max(maxItemsOnDayTop, day.DayTop.PassingItems.Count);
+
+ List> groups = new List>();
+ List items = new List(day.ContainedItems);
+
+ while (items.Count > 0)
+ {
+ List group = new List();
+
+ CollectIntersectingGroup(items[0], items, group);
+
+ groups.Add(group);
+
+ foreach (CalendarItem item in group)
+ items.Remove(item);
+ }
+
+ #endregion
+
+ foreach (List group in groups)
+ {
+ #region Create group matrix
+
+ int maxConcurrent = 0;
+ int startIndex, endIndex;
+ GetGroupBoundUnits(group, out startIndex, out endIndex);
+
+ //Get the maximum concurrent items
+ for (int i = startIndex; i <= endIndex; i++) maxConcurrent = Math.Max(day.TimeUnits[i].PassingItems.Count, maxConcurrent);
+
+ int[,] matix = new int[maxConcurrent, endIndex - startIndex + 1];
+
+ foreach (CalendarItem item in group)
+ {
+ int x = 0;
+ item.UnitsPassing.Sort(CompareUnits);
+ int unitStart = item.UnitsPassing[0].Index - startIndex;
+ int unitEnd = unitStart + item.UnitsPassing.Count - 1;
+ bool xFound = false;
+
+ //if (startIndex + unitEnd < offset)
+ //{
+ // item.SetIsOnView(false);
+ // continue;
+ //}
+ //else
+ //{
+ // item.SetIsOnView(true);
+ //}
+
+ while (!xFound)
+ {
+ xFound = true;
+
+ for (int i = unitStart; i <= unitEnd; i++)
+ {
+ if (matix[x, i] != 0)
+ {
+ xFound = false;
+ break;
+ }
+ }
+ if (!xFound) x++;
+ }
+
+ for (int i = unitStart; i <= unitEnd; i++)
+ {
+ matix[x, i] = group.IndexOf(item) + 1;
+ }
+ }
+ #endregion
+
+ #region Expand Items
+ foreach (CalendarItem item in group)
+ {
+ int index = group.IndexOf(item);
+ int left, top;
+ int height = item.UnitsPassing.Count;
+ int width = 1;
+ FindInMatrix(matix, index + 1, out left, out top);
+
+
+ bool canExpand = left >= 0 && top >= 0;
+ while (canExpand)
+ {
+ for (int i = top; i < top + height; i++)
+ {
+ if (matix.GetLength(0) <= left + width || matix[left + width, i] != 0)
+ {
+ canExpand = false;
+ break;
+ }
+ }
+
+ if (canExpand)
+ {
+ for (int i = top; i < top + height; i++)
+ {
+ matix[left + width, i] = index + 1;
+ }
+ width++;
+ }
+ }
+ }
+ #endregion
+
+ #region Matrix to rectangles
+
+ int itemWidth = Convert.ToInt32(Math.Floor(Convert.ToSingle(day.Bounds.Width - ItemsPadding) / Convert.ToSingle(matix.GetLength(0))));
+
+ foreach (CalendarItem item in group)
+ {
+ int index = group.IndexOf(item);
+ int top, left;
+ int width = 1;
+ FindInMatrix(matix, index + 1, out left, out top);
+
+ if (left >= 0 && top >= 0)
+ {
+ for (int i = left + 1; i < matix.GetLength(0); i++)
+ {
+ if (matix[i, top] == index + 1)
+ {
+ width++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ int rtop = day.TimeUnits[item.UnitsPassing[0].Index].Bounds.Top;
+ int bottom = day.TimeUnits[item.UnitsPassing[item.UnitsPassing.Count - 1].Index].Bounds.Bottom;
+ int rleft = day.Bounds.Left + left * itemWidth;
+ int right = rleft + itemWidth * width;
+ item.SetBounds(Rectangle.FromLTRB(rleft, rtop, right, bottom));
+ item.SetMinuteStartTop(GetTimeY(item.StartDate.TimeOfDay));
+ item.SetMinuteEndTop(GetTimeY(item.EndDate.TimeOfDay));
+
+ }
+
+ #endregion
+ }
+ }
+ #endregion
+ }
+ else if (Calendar.DaysMode == CalendarDaysMode.Short)
+ {
+ #region Short mode algorithm
+
+ Calendar.Items.Reverse();
+
+ for (int i = 0; i < Calendar.Days.Length; i++)
+ {
+ Calendar.Days[i].ContainedItems.Clear();
+ Calendar.Days[i].SetOverflowEnd(false);
+ Calendar.Days[i].SetOverflowStart(false);
+ }
+
+ int maxItems = 0;
+
+ foreach (CalendarItem item in Calendar.Items)
+ {
+ CalendarDay dayStart = item.DayStart;
+ CalendarDay dayEnd = item.DayEnd;
+ item.ClearBounds();
+
+ for (int i = dayStart.Index; i <= dayEnd.Index; i++)
+ {
+ Calendar.Days[i].AddContainedItem(item);
+ maxItems = Math.Max(maxItems, Calendar.Days[i].ContainedItems.Count);
+ }
+ }
+
+ int[,] matix = new int[Calendar.Days.Length, maxItems];
+ int curIndex = 0;
+ foreach (CalendarItem item in Calendar.Items)
+ {
+ CalendarDay dayStart = item.DayStart;
+ CalendarDay dayEnd = item.DayEnd;
+
+ PlaceInMatrix(ref matix, curIndex + 1, dayStart.Index, dayEnd.Index);
+ curIndex++;
+ }
+
+
+ for (int week = 0; week < Calendar.Weeks.Length; week++)
+ {
+ int xStart = week * 7;
+ int xEnd = xStart + 6;
+ int index = 0;
+ int[,] wmatix = new int[7, matix.GetLength(1)];
+ CalendarDay sunday = Calendar.FindDay(Calendar.Weeks[week].StartDate);
+
+ #region Fill week matrix
+
+ for (int i = 0; i < wmatix.GetLength(1); i++)
+ for (int j = 0; j < wmatix.GetLength(0); j++)
+ wmatix[j, i] = matix[j + xStart, i];
+
+ #endregion
+
+ foreach (CalendarItem item in Calendar.Items)
+ {
+ int left, top, width = 0;
+
+ FindInMatrix(wmatix, ++index, out left, out top);
+
+ if (left < 0 || top < 0) continue;
+
+ for (int i = left; i < wmatix.GetLength(0); i++)
+ if (wmatix[i, top] == index)
+ width++;
+ else
+ break;
+
+
+ CalendarDay dayStart = Calendar.Days[xStart + left];
+ CalendarDay dayEnd = Calendar.Days[xStart + left + width - 1];
+ Rectangle rStart = dayStart.Bounds;
+ Rectangle rEnd = dayEnd.Bounds;
+ int rtop = rStart.Top + DayHeaderHeight + top * StandardItemHeight;
+ Rectangle r = Rectangle.FromLTRB(rStart.Left, rtop, rEnd.Right, rtop + StandardItemHeight);
+
+ if (r.Bottom <= sunday.Bounds.Bottom)
+ item.AddBounds(r);
+ else
+ for (int i = dayStart.Index; i <= dayEnd.Index; i++)
+ Calendar.Days[i].SetOverflowEnd(true);
+
+ }
+ }
+
+ foreach (CalendarItem item in Calendar.Items)
+ item.FirstAndLastRectangleGapping();
+
+ Calendar.Items.Reverse();
+
+ #endregion
+ }
+
+ Calendar.RaiseItemsPositioned();
+ }
+
+ ///
+ /// Places the specified item in the matrix for the layout engine purposes
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void PlaceInMatrix(ref int[,] m, int index, int startX, int endX)
+ {
+ int y = 0;
+ bool yFound = false;
+
+ while (!yFound && y < m.GetLength(1)) //HACK: && y < m.GetLength(1) //This is Because of some bug, possible item not showing
+ {
+ yFound = true;
+
+ for (int i = startX; i <= endX; i++)
+ {
+ if (i >= 0 && i < m.GetLength(0) &&
+ m[i, y] != 0)
+ {
+ yFound = false;
+ break;
+ }
+ }
+
+ if (!yFound) y++;
+ }
+
+
+ if (y < m.GetLength(1)) //HACK: This if is because of same bug
+ {
+ for (int i = startX; i <= endX; i++)
+ {
+ m[i, y] = index;
+ }
+ }
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ ///
+ /// Gets the amout of units that can be displayed on the calendar viewport
+ ///
+ internal int GetVisibleTimeUnits()
+ {
+ if (Calendar.DaysMode == CalendarDaysMode.Short)
+ {
+ return 0;
+ }
+ else if (Calendar.Days != null && Calendar.Days.Length > 0)
+ {
+ return Convert.ToInt32(Math.Floor(
+ Convert.ToSingle(Calendar.Days[0].BodyBounds.Height) / Convert.ToSingle(TimeScaleUnitHeight)
+ ));
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ /// Height of all elements
+ protected void SetDayTopHeight(int height)
+ {
+ _dayTopHeight = height;
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ /// Height of the day header
+ protected void SetDayHeaderHeight(int height)
+ {
+ _dayHeaderHeight = height;
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ /// Height of the day name headers
+ protected void SetDayNameHeadersHeight(int height)
+ {
+ _dayNameHeadersHeight = height;
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ /// Height of the time scale unit
+ protected void SetTimeScaleUnitHeight(int height)
+ {
+ _timeScaleUnitHeight = height;
+ }
+
+ ///
+ /// Sets the value of the property
+ ///
+ /// New width for the time scale
+ protected void SetTimeScaleWidth(int width)
+ {
+ _timeScaleWidth = width;
+ }
+
+ ///
+ /// Draws text using the information of the
+ ///
+ ///
+ protected virtual void DrawStandarBoxText(CalendarRendererBoxEventArgs e)
+ {
+ TextRenderer.DrawText(e.Graphics, e.Text, e.Font, e.Bounds, e.TextColor, e.Format);
+ }
+
+ ///
+ /// Outs the location of the specified number in the matrix
+ ///
+ /// Matrix to search in
+ /// Number to find
+ /// Result left
+ /// Result top
+ private void FindInMatrix(int[,] m, int number, out int left, out int top)
+ {
+ for (int i = 0; i < m.GetLength(1); i++)
+ {
+ for (int j = 0; j < m.GetLength(0); j++)
+ {
+ if (m[j, i] == number)
+ {
+ left = j;
+ top = i;
+ return;
+ }
+ }
+ }
+
+ left = top = -1;
+ }
+
+ ///
+ /// Outs the startIndex and the endIndex of units in the group
+ ///
+ ///
+ ///
+ ///
+ private void GetGroupBoundUnits(List group, out int startIndex, out int endIndex)
+ {
+ startIndex = int.MaxValue;
+ endIndex = int.MinValue;
+
+ foreach (CalendarItem item in group)
+ {
+ foreach (CalendarTimeScaleUnit unit in item.UnitsPassing)
+ {
+ startIndex = Math.Min(startIndex, unit.Index);
+ endIndex = Math.Max(endIndex, unit.Index);
+ }
+ }
+ }
+
+ ///
+ /// Recursive method that collects items intersecting on time, to graphically represent-them on the layout
+ ///
+ ///
+ ///
+ ///
+ private void CollectIntersectingGroup(CalendarItem calendarItem, List items, List grouped)
+ {
+ if (!grouped.Contains(calendarItem))
+ grouped.Add(calendarItem);
+
+ foreach (CalendarItem item in items)
+ {
+ if (!grouped.Contains(item) &&
+ calendarItem.IntersectsWith(item.StartDate.TimeOfDay, item.EndDate.TimeOfDay))
+ {
+ grouped.Add(item);
+
+ CollectIntersectingGroup(item, items, grouped);
+ }
+ }
+ }
+
+ ///
+ /// Prints the specified matrix on debug
+ ///
+ ///
+ private void PrintMatrix(int[,] m)
+ {
+ //return;
+ Console.WriteLine("--------------------------------");
+ for (int i = 0; i < m.GetLength(1); i++)
+ {
+ for (int j = 0; j < m.GetLength(0); j++)
+ {
+ Console.Write(string.Format(" {0}", m[j, i]));
+ }
+ Console.WriteLine(" ");
+ }
+ Console.WriteLine("--------------------------------");
+ }
+
+ #endregion
+
+ #region Render Methods
+
+ ///
+ /// Initializes the Calendar
+ ///
+ ///
+ public virtual void OnInitialize(CalendarRendererEventArgs e)
+ {
+
+ }
+
+ ///
+ /// Paints the background of the calendar
+ ///
+ /// Paint info
+ public virtual void OnDrawBackground(CalendarRendererEventArgs e)
+ {
+ }
+
+ ///
+ /// Paints the timescale of the calendar
+ ///
+ /// Paint info
+ public virtual void OnDrawTimeScale(CalendarRendererEventArgs e)
+ {
+ if (e.Calendar.DaysMode == CalendarDaysMode.Short
+ || e.Calendar.Days == null
+ || e.Calendar.Days.Length == 0
+ || e.Calendar.Days[0].TimeUnits == null
+ ) return;
+
+ Font hourFont = new Font(e.Calendar.Font.FontFamily, e.Calendar.Font.Size * (e.Calendar.TimeScale == CalendarTimeScale.SixtyMinutes ? 1f : 1.5f));
+ Font minuteFont = e.Calendar.Font;
+ int hourLeft = TimeScaleBounds.Left;
+ int hourWidth = TimeScaleBounds.Left + TimeScaleBounds.Width / 2;
+ int minuteLeft = hourLeft + hourWidth;
+ int minuteWidth = hourWidth;
+ int k = 0;
+
+ for (int i = 0; i < e.Calendar.Days[0].TimeUnits.Length; i++)
+ {
+ CalendarTimeScaleUnit unit = e.Calendar.Days[0].TimeUnits[i];
+
+ if (!unit.Visible) continue;
+
+ string hours = unit.Hours.ToString("00");
+ string minutes = unit.Minutes == 0 ? "00" : string.Empty;
+
+ if (!string.IsNullOrEmpty(minutes))
+ {
+ switch( _calendar.CalendarTimeFormat )
+ {
+ case CalendarTimeFormat.TwelveHour:
+ if( Convert.ToInt32( hours ) > 12 ) hours = ( Convert.ToInt32( hours ) - 12 ).ToString();
+ break;
+
+ case CalendarTimeFormat.TwentyFourHour:
+ if( hours == "00" ) hours = "12";
+ break;
+ }
+
+ CalendarRendererBoxEventArgs hevt = new CalendarRendererBoxEventArgs(e, new Rectangle(hourLeft, unit.Bounds.Top, hourWidth, unit.Bounds.Height), hours, TextFormatFlags.Right);
+
+ hevt.Font = hourFont;
+
+ OnDrawTimeScaleHour(hevt);
+
+ if (k++ == 0 || unit.Hours == 0 || unit.Hours == 12 ) minutes = unit.Date.ToString("tt");
+
+ CalendarRendererBoxEventArgs mevt = new CalendarRendererBoxEventArgs(e, new Rectangle(minuteLeft, unit.Bounds.Top, minuteWidth, unit.Bounds.Height), minutes, TextFormatFlags.Top | TextFormatFlags.Left);
+
+ mevt.Font = minuteFont;
+
+ OnDrawTimeScaleMinutes(mevt);
+ }
+ }
+ }
+
+ ///
+ /// Paints an hour of a timescale unit
+ ///
+ /// Paint Info
+ public virtual void OnDrawTimeScaleHour(CalendarRendererBoxEventArgs e)
+ {
+ DrawStandarBoxText(e);
+ }
+
+ ///
+ /// Paints minutes of a timescale unit
+ ///
+ /// Paint Info
+ public virtual void OnDrawTimeScaleMinutes(CalendarRendererBoxEventArgs e)
+ {
+ DrawStandarBoxText(e);
+ }
+
+ ///
+ /// Paints the days on the current calendar view
+ ///
+ /// Paint Info
+ public virtual void OnDrawDays(CalendarRendererEventArgs e)
+ {
+ for (int i = 0; i < e.Calendar.Days.Length; i++)
+ {
+ CalendarDay day = e.Calendar.Days[i];
+
+ e.Tag = day;
+
+ OnDrawDay(new CalendarRendererDayEventArgs(e,
+ day));
+ }
+ }
+
+ ///
+ /// Paints the specified day on the calendar
+ ///
+ /// Paint info
+ public virtual void OnDrawDay(CalendarRendererDayEventArgs e)
+ {
+ CalendarDay day = e.Day;
+
+ CalendarRendererBoxEventArgs hevt = new CalendarRendererBoxEventArgs(e,
+ day.HeaderBounds,
+ day.Date.Day.ToString(),
+ TextFormatFlags.VerticalCenter);
+ hevt.Font = new Font(Calendar.Font, FontStyle.Bold);
+
+ CalendarRendererBoxEventArgs devt = new CalendarRendererBoxEventArgs(e,
+ day.HeaderBounds,
+ day.Date.ToString("dddd"),
+ TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
+
+ OnDrawDayHeaderBackground(e);
+
+ if (Calendar.DaysMode == CalendarDaysMode.Short && (day.Index == 0 || day.Date.Day == 1))
+ {
+ hevt.Text = day.Date.ToString("dd MMM");
+ }
+
+ OnDrawDayHeaderText(hevt);
+
+ if (devt.TextSize.Width < day.HeaderBounds.Width - hevt.TextSize.Width * 2
+ && e.Calendar.DaysMode == CalendarDaysMode.Expanded)
+ {
+ OnDrawDayHeaderText(devt);
+ }
+
+
+
+ OnDrawDayTimeUnits(e);
+ OnDrawDayTop(e);
+ OnDrawDayBorder(e);
+ }
+
+ ///
+ /// Paints the border of the specified day
+ ///
+ ///
+ public virtual void OnDrawDayBorder(CalendarRendererDayEventArgs e)
+ {
+
+ }
+
+ ///
+ /// Draws the all day items area
+ ///
+ /// Paint Info
+ public virtual void OnDrawDayTop(CalendarRendererDayEventArgs e)
+ {
+ }
+
+ ///
+ /// Paints the background of the specified day's header
+ ///
+ ///
+ public virtual void OnDrawDayHeaderBackground(CalendarRendererDayEventArgs e)
+ {
+
+ }
+
+ ///
+ /// Paints the header of the specified day
+ ///
+ /// Paint info
+ public virtual void OnDrawDayHeaderText(CalendarRendererBoxEventArgs e)
+ {
+ DrawStandarBoxText(e);
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ public virtual void OnDrawDayTimeUnits(CalendarRendererDayEventArgs e)
+ {
+ for (int i = 0; i < e.Day.TimeUnits.Length; i++)
+ {
+ CalendarTimeScaleUnit unit = e.Day.TimeUnits[i];
+
+ if(unit.Visible)
+ OnDrawDayTimeUnit(new CalendarRendererTimeUnitEventArgs(e, unit));
+ }
+ }
+
+ ///
+ /// Draws a time unit of a day
+ ///
+ ///
+ public virtual void OnDrawDayTimeUnit(CalendarRendererTimeUnitEventArgs e)
+ {
+
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ public virtual void OnDrawDayNameHeaders(CalendarRendererEventArgs e)
+ {
+ DateTime startDate = DateTime.Now.AddDays(-((int)DateTime.Now.DayOfWeek % 7) + 1 + (int)Calendar.FirstDayOfWeek);
+
+ for (int i = 0; i < DayNameHeaderColumns.Length; i++)
+ {
+ OnDrawDayNameHeader(new CalendarRendererBoxEventArgs(e,
+ DayNameHeaderColumns[i],
+ startDate.AddDays(i).ToString("dddd"),
+ TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter));
+
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ public virtual void OnDrawDayNameHeader(CalendarRendererBoxEventArgs e)
+ {
+ DrawStandarBoxText(e);
+ }
+
+ ///
+ /// Draws the items of the calendar
+ ///
+ /// Event info
+ public virtual void OnDrawItems(CalendarRendererEventArgs e)
+ {
+ Rectangle days = e.Calendar.DaysBodyRectangle; days.Inflate(-1, -1);
+ Region oldclip = e.Graphics.Clip;
+ bool doClip = e.Calendar.DaysMode == CalendarDaysMode.Expanded;
+ bool clipped = false;
+
+ #region Shadows
+ foreach (CalendarItem item in e.Calendar.Items)
+ {
+ clipped = false;
+
+ if (doClip && !item.IsOnDayTop && item.Bounds.Top < days.Top)
+ {
+ e.Graphics.SetClip(days, CombineMode.Intersect);
+ clipped = true;
+ }
+
+ List rects = new List(item.GetAllBounds());
+
+ for (int i = 0; i < rects.Count; i++)
+ {
+ CalendarRendererItemBoundsEventArgs evt = new CalendarRendererItemBoundsEventArgs(
+ new CalendarRendererItemEventArgs(e, item),
+ rects[i],
+ i == 0 && !item.IsOpenStart,
+ (i == rects.Count - 1) && !item.IsOpenEnd);
+ OnDrawItemShadow(evt);
+ }
+
+ if (clipped)
+ e.Graphics.SetClip(oldclip, CombineMode.Replace);
+ }
+ #endregion
+
+ #region Items
+ foreach (CalendarItem item in e.Calendar.Items)
+ {
+ clipped = false;
+
+ if( doClip && !item.IsOnDayTop && item.Bounds.Top < days.Top )
+ {
+ e.Graphics.SetClip( days, CombineMode.Intersect );
+ clipped = true;
+ }
+
+ OnDrawItem(new CalendarRendererItemEventArgs(e, item));
+
+ if( clipped )
+ {
+ e.Graphics.SetClip( oldclip, CombineMode.Replace );
+ }
+ }
+ #endregion
+
+ #region Borders of selected items
+ foreach (CalendarItem item in e.Calendar.Items)
+ {
+ if (!item.Selected) continue;
+
+ List rects = new List(item.GetAllBounds());
+
+ for (int i = 0; i < rects.Count; i++)
+ {
+ CalendarRendererItemBoundsEventArgs evt = new CalendarRendererItemBoundsEventArgs(
+ new CalendarRendererItemEventArgs(e, item),
+ rects[i],
+ i == 0 && !item.IsOpenStart,
+ (i == rects.Count - 1) && !item.IsOpenEnd);
+
+ SmoothingMode smbuff = e.Graphics.SmoothingMode;
+ e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
+
+ OnDrawItemBorder(evt);
+
+ e.Graphics.SmoothingMode = smbuff;
+ }
+
+ }
+ #endregion
+ }
+
+ ///
+ /// Draws an item of the calendar
+ ///
+ /// Event Info
+ public virtual void OnDrawItem( CalendarRendererItemEventArgs e )
+ {
+ List rects = new List( e.Item.GetAllBounds() );
+
+ for( int i = 0; i < rects.Count; i++ )
+ {
+ CalendarRendererItemBoundsEventArgs evt = new CalendarRendererItemBoundsEventArgs(
+ e,
+ rects[i],
+ i == 0 && !e.Item.IsOpenStart,
+ ( i == rects.Count - 1 ) && !e.Item.IsOpenEnd );
+
+ OnDrawItemBackground( evt );
+
+ if( !evt.Item.PatternColor.IsEmpty )
+ {
+ OnDrawItemPattern( evt );
+ }
+
+ if( !e.Item.IsEditing )
+ {
+ OnDrawItemContent( evt );
+ }
+
+ OnDrawItemBorder( evt );
+
+ }
+ }
+
+ ///
+ /// Draws the background of the specified item
+ ///
+ /// Event Info
+ public virtual void OnDrawItemBackground(CalendarRendererItemBoundsEventArgs e)
+ {
+
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ public virtual void OnDrawItemPattern(CalendarRendererItemBoundsEventArgs e)
+ {
+ foreach (Rectangle bounds in e.Item.GetAllBounds())
+ {
+ ItemPattern(e, bounds, e.Item.PatternColor);
+ }
+ }
+
+ ///
+ /// Draws the strings of an item. Strings inlude StartTime, EndTime and Text
+ ///
+ /// Event Info
+ public virtual void OnDrawItemContent(CalendarRendererItemBoundsEventArgs e)
+ {
+ if (e.Item == e.Calendar.EditModeItem) return;
+
+ List rectangles = new List(e.Item.GetAllBounds());
+
+ for (int i = 0; i < rectangles.Count; i++)
+ {
+ Rectangle bounds = rectangles[i];
+ Rectangle imageBounds = Rectangle.Empty;
+ Rectangle rStartTime = new Rectangle();
+ Rectangle rEndTime = new Rectangle();
+ string endTime = string.Empty;
+ string startTime = string.Empty;
+ Color secondaryForecolor = e.Item.ForeColor;
+
+ if (e.Item.ShowEndTime && i == rectangles.Count - 1)
+ {
+ endTime = e.Item.EndDateText;
+ rEndTime = new Rectangle(Point.Empty, TextRenderer.MeasureText(endTime, e.Calendar.Font));
+ rEndTime = Rectangle.FromLTRB(bounds.Right - rEndTime.Width - ItemTextMargin.Right,
+ bounds.Top + ItemTextMargin.Top,
+ bounds.Right - ItemTextMargin.Right,
+ bounds.Bottom - ItemTextMargin.Bottom);
+ OnDrawItemEndTime(new CalendarRendererBoxEventArgs(e, rEndTime, endTime, secondaryForecolor));
+ }
+
+ if (e.Item.ShowStartTime && i == 0)
+ {
+ startTime = e.Item.StartDateText;
+ rStartTime = new Rectangle(Point.Empty, TextRenderer.MeasureText(startTime, e.Calendar.Font));
+ rStartTime.X = bounds.Left + ItemTextMargin.Left;
+ rStartTime.Y = bounds.Top + ItemTextMargin.Top;
+ rStartTime.Height = bounds.Height - ItemTextMargin.Vertical;
+ OnDrawItemStartTime(new CalendarRendererBoxEventArgs(e, rStartTime, startTime, secondaryForecolor));
+ }
+
+ Rectangle r = Rectangle.FromLTRB(
+ bounds.Left + ItemTextMargin.Left + rStartTime.Width,
+ bounds.Top + ItemTextMargin.Top,
+ bounds.Right - ItemTextMargin.Right - rEndTime.Width,
+ bounds.Bottom - ItemTextMargin.Bottom);
+
+ CalendarRendererBoxEventArgs evt = new CalendarRendererBoxEventArgs(e, r, e.Item.Text, TextFormatFlags.Left | TextFormatFlags.Top);
+
+ evt.Font = e.Item.Font;
+
+ if( e.Item.ShowStartTime || e.Item.ShowEndTime )
+ {
+ evt.Font = new Font( evt.Font, FontStyle.Bold );
+ }
+
+ if( e.Item.IsOnDayTop || Calendar.DaysMode == CalendarDaysMode.Short )
+ {
+ evt.Format |= TextFormatFlags.HorizontalCenter;
+ }
+
+ if (!e.Item.ForeColor.IsEmpty)
+ {
+ evt.TextColor = e.Item.ForeColor;
+ }
+
+ evt.Tag = e.Item;
+
+ #region Image
+
+ if (e.Item.Image != null)
+ {
+ Rectangle tBounds = e.Item.Bounds;
+ imageBounds.Size = e.Item.Image.Size;
+
+ switch (e.Item.ImageAlign)
+ {
+ case CalendarItemImageAlign.North:
+ tBounds.Height -= imageBounds.Height;
+ tBounds.Y += imageBounds.Height;
+ imageBounds.Y = tBounds.Y - imageBounds.Height;
+ break;
+ case CalendarItemImageAlign.South:
+ tBounds.Height -= imageBounds.Height;
+ imageBounds.Y = tBounds.Bottom;
+ break;
+ case CalendarItemImageAlign.East:
+ tBounds.Width -= imageBounds.Width;
+ imageBounds.X = tBounds.Right;
+ break;
+ case CalendarItemImageAlign.West:
+ tBounds.Width -= imageBounds.Width;
+ tBounds.X += imageBounds.Width;
+ imageBounds.X = tBounds.Left - imageBounds.Width;
+ break;
+ }
+
+ switch (e.Item.ImageAlign)
+ {
+ case CalendarItemImageAlign.North:
+ case CalendarItemImageAlign.South:
+ imageBounds.X = e.Item.Bounds.X + ( ( e.Item.Bounds.Width - imageBounds.Width ) / 2);
+ break;
+ case CalendarItemImageAlign.East:
+ case CalendarItemImageAlign.West:
+ imageBounds.Y = e.Item.Bounds.Y + ((e.Item.Bounds.Height - imageBounds.Height) / 2);
+ break;
+ }
+
+ evt.Bounds = tBounds;
+ OnDrawItemImage(new CalendarRendererItemBoundsEventArgs(e, imageBounds, false, false));
+ }
+
+ #endregion
+
+ OnDrawItemText(evt);
+ }
+ }
+
+ ///
+ /// Draws the text of an item
+ ///
+ ///
+ public virtual void OnDrawItemText(CalendarRendererBoxEventArgs e)
+ {
+ DrawStandarBoxText(e);
+ }
+
+ ///
+ /// Draws the image of an item
+ ///
+ ///
+ public virtual void OnDrawItemImage(CalendarRendererItemBoundsEventArgs e)
+ {
+ if (e.Item.Image != null)
+ {
+ e.Graphics.DrawImage(e.Item.Image, e.Bounds);
+ }
+ }
+
+ ///
+ /// Draws the starttime of the item if applicable
+ ///
+ /// Event data
+ public virtual void OnDrawItemStartTime(CalendarRendererBoxEventArgs e)
+ {
+ DrawStandarBoxText(e);
+ }
+
+ ///
+ /// Draws the end time of the item if applicable
+ ///
+ /// Event data
+ public virtual void OnDrawItemEndTime(CalendarRendererBoxEventArgs e)
+ {
+ DrawStandarBoxText(e);
+ }
+
+ ///
+ /// Draws the border of the specified item
+ ///
+ /// Event Info
+ public virtual void OnDrawItemBorder(CalendarRendererItemBoundsEventArgs e)
+ {
+
+ }
+
+ ///
+ /// Draws the shadow of the specified item
+ ///
+ ///
+ public virtual void OnDrawItemShadow(CalendarRendererItemBoundsEventArgs e)
+ {
+
+ }
+
+ ///
+ /// Draws the overflows of days
+ ///
+ ///
+ public virtual void OnDrawOverflows(CalendarRendererEventArgs e)
+ {
+ for (int i = 0; i < e.Calendar.Days.Length; i++)
+ {
+ CalendarDay day = e.Calendar.Days[i];
+
+ if (day.OverflowStart)
+ {
+ OnDrawDayOverflowStart(new CalendarRendererDayEventArgs(e, day));
+ }
+
+ if(day.OverflowEnd)
+ {
+ OnDrawDayOverflowEnd(new CalendarRendererDayEventArgs(e, day));
+ }
+ }
+ }
+
+ ///
+ /// Draws the overflow to start of specified day
+ ///
+ /// Event data
+ public virtual void OnDrawDayOverflowStart(CalendarRendererDayEventArgs e)
+ {
+
+ }
+
+ ///
+ /// Draws the overflow to end of specified day
+ ///
+ ///
+ public virtual void OnDrawDayOverflowEnd(CalendarRendererDayEventArgs e)
+ {
+ //e.Graphics.FillRectangle(Brushes.Red, e.Day.OverflowEndBounds);
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ public virtual void OnDrawWeekHeaders(CalendarRendererEventArgs e)
+ {
+ if (Calendar.Weeks == null) return;
+
+ for (int i = 0; i < Calendar.Weeks.Length; i++)
+ {
+ string str = Calendar.Weeks[i].ToStringLarge();
+ SizeF sz = e.Graphics.MeasureString(str, e.Calendar.Font);
+
+ if (sz.Width > Calendar.Weeks[i].HeaderBounds.Height)
+ {
+ str = Calendar.Weeks[i].ToStringShort();
+ }
+
+ OnDrawWeekHeader(new CalendarRendererBoxEventArgs(e,
+ Calendar.Weeks[i].HeaderBounds, str, TextFormatFlags.Default));
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ public virtual void OnDrawWeekHeader(CalendarRendererBoxEventArgs e)
+ {
+ StringFormat sf = new StringFormat();
+ sf.FormatFlags = StringFormatFlags.DirectionVertical | StringFormatFlags.DirectionRightToLeft | StringFormatFlags.NoWrap;
+ sf.LineAlignment = StringAlignment.Center;
+ sf.Alignment = StringAlignment.Center;
+
+ using (SolidBrush b = new SolidBrush(e.TextColor))
+ {
+ e.Graphics.DrawString(e.Text, e.Font, b, e.Bounds, sf);
+ }
+
+ e.Graphics.ResetTransform();
+
+ sf.Dispose();
+ }
+
+
+
+ #endregion
+
+ }
+}
diff --git a/WindowsFormsCalendar/Renderers/CalendarSystemRenderer.cs b/WindowsFormsCalendar/Renderers/CalendarSystemRenderer.cs
new file mode 100644
index 0000000..a1b3fe9
--- /dev/null
+++ b/WindowsFormsCalendar/Renderers/CalendarSystemRenderer.cs
@@ -0,0 +1,479 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// CalendarRenderer that renders low-intensity calendar for slow computers
+ ///
+ public class CalendarSystemRenderer
+ : CalendarRenderer
+ {
+ #region Fields
+ private CalendarColorTable _colorTable;
+ private float _selectedItemBorder;
+ #endregion
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ public CalendarSystemRenderer( Calendar calendar )
+ : base( calendar )
+ {
+ ColorTable = new CalendarColorTable();
+ SelectedItemBorder = 1;
+ }
+
+ #region Properties
+
+ ///
+ /// Gets or sets the for this renderer
+ ///
+ public CalendarColorTable ColorTable
+ {
+ get { return _colorTable; }
+ set { _colorTable = value; }
+ }
+
+ ///
+ /// Gets or sets the size of the border of selected items
+ ///
+ public float SelectedItemBorder
+ {
+ get { return _selectedItemBorder; }
+ set { _selectedItemBorder = value; }
+ }
+
+ #endregion
+
+ #region Overrides
+
+ ///
+ /// Paints the background of the calendar
+ ///
+ /// Paint info
+ public override void OnDrawBackground( CalendarRendererEventArgs e )
+ {
+ e.Graphics.Clear( ColorTable.Background );
+ }
+
+ ///
+ /// Paints the specified day on the calendar
+ ///
+ /// Paint info
+ public override void OnDrawDay( CalendarRendererDayEventArgs e )
+ {
+ Rectangle r = e.Day.Bounds;
+
+ if( e.Day.Selected )
+ {
+ using( Brush b = new SolidBrush( ColorTable.DayBackgroundSelected ) )
+ {
+ e.Graphics.FillRectangle( b, r );
+ }
+ }
+ else if( e.Day.Date.Month % 2 == 0 )
+ {
+ using( Brush b = new SolidBrush( ColorTable.DayBackgroundEven ) )
+ {
+ e.Graphics.FillRectangle( b, r );
+ }
+ }
+ else
+ {
+ using( Brush b = new SolidBrush( ColorTable.DayBackgroundOdd ) )
+ {
+ e.Graphics.FillRectangle( b, r );
+ }
+ }
+
+ base.OnDrawDay( e );
+ }
+
+ ///
+ /// Paints the border of the specified day
+ ///
+ ///
+ public override void OnDrawDayBorder( CalendarRendererDayEventArgs e )
+ {
+ base.OnDrawDayBorder( e );
+
+ Rectangle r = e.Day.Bounds;
+ bool today = e.Day.Date.Date.Equals( DateTime.Today.Date );
+
+ using( Pen p = new Pen( today ? ColorTable.TodayBorder : ColorTable.DayBorder, today ? 2 : 1 ) )
+ {
+ if( e.Calendar.DaysMode == CalendarDaysMode.Short )
+ {
+ e.Graphics.DrawLine( p, r.Right, r.Top, r.Right, r.Bottom );
+ e.Graphics.DrawLine( p, r.Left, r.Bottom, r.Right, r.Bottom );
+
+ if( e.Day.Date.DayOfWeek == DayOfWeek.Sunday || today )
+ {
+ e.Graphics.DrawLine( p, r.Left, r.Top, r.Left, r.Bottom );
+ }
+ }
+ else
+ {
+ e.Graphics.DrawRectangle( p, r );
+ }
+ }
+ }
+
+ ///
+ /// Draws the all day items area
+ ///
+ /// Paint Info
+ public override void OnDrawDayTop( CalendarRendererDayEventArgs e )
+ {
+ bool s = e.Day.DayTop.Selected;
+
+ using( Brush b = new SolidBrush( s ? ColorTable.DayTopSelectedBackground : ColorTable.DayTopBackground ) )
+ {
+ e.Graphics.FillRectangle( b, e.Day.DayTop.Bounds );
+ }
+
+ using( Pen p = new Pen( s ? ColorTable.DayTopSelectedBorder : ColorTable.DayTopBorder ) )
+ {
+ e.Graphics.DrawRectangle( p, e.Day.DayTop.Bounds );
+ }
+
+ base.OnDrawDayTop( e );
+ }
+
+ ///
+ /// Paints the background of the specified day's header
+ ///
+ ///
+ public override void OnDrawDayHeaderBackground( CalendarRendererDayEventArgs e )
+ {
+ bool today = e.Day.Date.Date.Equals( DateTime.Today.Date );
+
+ using( Brush b = new SolidBrush( today ? ColorTable.TodayTopBackground : ColorTable.DayHeaderBackground ) )
+ {
+ e.Graphics.FillRectangle( b, e.Day.HeaderBounds );
+ }
+
+ base.OnDrawDayHeaderBackground( e );
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ public override void OnDrawWeekHeader( CalendarRendererBoxEventArgs e )
+ {
+ using( Brush b = new SolidBrush( ColorTable.WeekHeaderBackground ) )
+ {
+ e.Graphics.FillRectangle( b, e.Bounds );
+ }
+
+ using( Pen p = new Pen( ColorTable.WeekHeaderBorder ) )
+ {
+ e.Graphics.DrawRectangle( p, e.Bounds );
+ }
+
+ e.TextColor = ColorTable.WeekHeaderText;
+
+ base.OnDrawWeekHeader( e );
+ }
+
+ ///
+ /// Draws a time unit of a day
+ ///
+ ///
+ public override void OnDrawDayTimeUnit( CalendarRendererTimeUnitEventArgs e )
+ {
+ base.OnDrawDayTimeUnit( e );
+
+ using( SolidBrush b = new SolidBrush( ColorTable.TimeUnitBackground ) )
+ {
+ if( e.Unit.Selected )
+ {
+ b.Color = ColorTable.TimeUnitSelectedBackground;
+ }
+ else if( e.Unit.Highlighted )
+ {
+ b.Color = ColorTable.TimeUnitHighlightedBackground;
+ }
+
+ e.Graphics.FillRectangle( b, e.Unit.Bounds );
+ }
+
+ using( Pen p = new Pen( e.Unit.Minutes == 0 ? ColorTable.TimeUnitBorderDark : ColorTable.TimeUnitBorderLight ) )
+ {
+ e.Graphics.DrawLine( p, e.Unit.Bounds.Location, new Point( e.Unit.Bounds.Right, e.Unit.Bounds.Top ) );
+ }
+ }
+
+ ///
+ /// Paints the timescale of the calendar
+ ///
+ /// Paint info
+ public override void OnDrawTimeScale( CalendarRendererEventArgs e )
+ {
+ int margin = 5;
+ int largeX1 = TimeScaleBounds.Left + margin;
+ int largeX2 = TimeScaleBounds.Right - margin;
+ int shortX1 = TimeScaleBounds.Left + TimeScaleBounds.Width / 2;
+ int shortX2 = largeX2;
+ int top = 0;
+ Pen p = new Pen( ColorTable.TimeScaleLine );
+
+ for( int i = 0; i < e.Calendar.Days[0].TimeUnits.Length; i++ )
+ {
+ CalendarTimeScaleUnit unit = e.Calendar.Days[0].TimeUnits[i];
+
+ if( !unit.Visible ) continue;
+
+ top = unit.Bounds.Top;
+
+ if( unit.Minutes == 0 )
+ {
+ e.Graphics.DrawLine( p, largeX1, top, largeX2, top );
+ }
+ else
+ {
+ e.Graphics.DrawLine( p, shortX1, top, shortX2, top );
+ }
+ }
+
+ if( e.Calendar.DaysMode == CalendarDaysMode.Expanded
+ && e.Calendar.Days != null
+ && e.Calendar.Days.Length > 0
+ && e.Calendar.Days[0].TimeUnits != null
+ && e.Calendar.Days[0].TimeUnits.Length > 0
+ )
+ {
+ top = e.Calendar.Days[0].BodyBounds.Top;
+
+ //Timescale top line is full
+ e.Graphics.DrawLine( p, TimeScaleBounds.Left, top, TimeScaleBounds.Right, top );
+ }
+
+ p.Dispose();
+
+ base.OnDrawTimeScale( e );
+ }
+
+ ///
+ /// Paints an hour of a timescale unit
+ ///
+ /// Paint Info
+ public override void OnDrawTimeScaleHour( CalendarRendererBoxEventArgs e )
+ {
+ e.TextColor = ColorTable.TimeScaleHours;
+ base.OnDrawTimeScaleHour( e );
+ }
+
+ ///
+ /// Paints minutes of a timescale unit
+ ///
+ /// Paint Info
+ public override void OnDrawTimeScaleMinutes( CalendarRendererBoxEventArgs e )
+ {
+ e.TextColor = ColorTable.TimeScaleMinutes;
+ base.OnDrawTimeScaleMinutes( e );
+ }
+
+ ///
+ /// Draws the background of the specified item
+ ///
+ /// Event Info
+ public override void OnDrawItemBackground( CalendarRendererItemBoundsEventArgs e )
+ {
+ base.OnDrawItemBackground( e );
+
+ int alpha = 255;
+
+ if( e.Item.IsDragging )
+ {
+ alpha = 120;
+ }
+ else if( e.Calendar.DaysMode == CalendarDaysMode.Short )
+ {
+ alpha = 200;
+ }
+
+ Color color1 = Color.White;
+ Color color2 = e.Item.Selected ? ColorTable.ItemSelectedBackground : ColorTable.ItemBackground;
+
+ if( !e.Item.BackgroundColorLighter.IsEmpty )
+ {
+ color1 = e.Item.BackgroundColorLighter;
+ }
+
+ if( !e.Item.BackgroundColor.IsEmpty )
+ {
+ color2 = e.Item.BackgroundColor;
+ }
+
+ ItemFill( e, e.Bounds, Color.FromArgb( alpha, color1 ), Color.FromArgb( alpha, color2 ) );
+
+ }
+
+ ///
+ /// Draws the shadow of the specified item
+ ///
+ ///
+ public override void OnDrawItemShadow( CalendarRendererItemBoundsEventArgs e )
+ {
+ base.OnDrawItemShadow( e );
+
+ if( e.Item.IsOnDayTop || e.Calendar.DaysMode == CalendarDaysMode.Short || e.Item.IsDragging )
+ {
+ return;
+ }
+
+ Rectangle r = e.Bounds;
+ r.Offset( ItemShadowPadding, ItemShadowPadding );
+
+ using( SolidBrush b = new SolidBrush( ColorTable.ItemShadow ) )
+ {
+ ItemFill( e, r, ColorTable.ItemShadow, ColorTable.ItemShadow );
+ }
+ }
+
+ ///
+ /// Draws the border of the specified item
+ ///
+ /// Event Info
+ public override void OnDrawItemBorder( CalendarRendererItemBoundsEventArgs e )
+ {
+ base.OnDrawItemBorder( e );
+
+ Color a = e.Item.BorderColor.IsEmpty ? ColorTable.ItemBorder : e.Item.BorderColor;
+ Color b = e.Item.Selected && !e.Item.IsDragging ? ColorTable.ItemSelectedBorder : a;
+ Color c = Color.FromArgb( e.Item.IsDragging ? 120 : 255, b );
+
+ ItemBorder( e, e.Bounds, c, e.Item.Selected && !e.Item.IsDragging ? SelectedItemBorder : 1f );
+
+ }
+
+ ///
+ /// Draws the starttime of the item if applicable
+ ///
+ /// Event data
+ public override void OnDrawItemStartTime( CalendarRendererBoxEventArgs e )
+ {
+ if( e.TextColor.IsEmpty )
+ {
+ e.TextColor = ColorTable.ItemSecondaryText;
+ }
+
+ base.OnDrawItemStartTime( e );
+ }
+
+ ///
+ /// Draws the end time of the item if applicable
+ ///
+ /// Event data
+ public override void OnDrawItemEndTime( CalendarRendererBoxEventArgs e )
+ {
+ if( e.TextColor.IsEmpty )
+ {
+ e.TextColor = ColorTable.ItemSecondaryText;
+ }
+
+ base.OnDrawItemEndTime( e );
+
+ }
+
+ ///
+ /// Draws the text of an item
+ ///
+ ///
+ public override void OnDrawItemText( CalendarRendererBoxEventArgs e )
+ {
+ CalendarItem item = e.Tag as CalendarItem;
+
+ if( item != null )
+ {
+ if( item.IsDragging )
+ {
+ e.TextColor = Color.FromArgb( 120, e.TextColor );
+ }
+ }
+
+ base.OnDrawItemText( e );
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ public override void OnDrawWeekHeaders( CalendarRendererEventArgs e )
+ {
+ base.OnDrawWeekHeaders( e );
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ public override void OnDrawDayNameHeader( CalendarRendererBoxEventArgs e )
+ {
+ e.TextColor = ColorTable.WeekDayName;
+
+ base.OnDrawDayNameHeader( e );
+
+ using( Pen p = new Pen( ColorTable.WeekDayName ) )
+ {
+ e.Graphics.DrawLine( p, e.Bounds.Right, e.Bounds.Top, e.Bounds.Right, e.Bounds.Bottom );
+ }
+ }
+
+ ///
+ /// Draws the overflow to end of specified day
+ ///
+ ///
+ public override void OnDrawDayOverflowEnd( CalendarRendererDayEventArgs e )
+ {
+ using( GraphicsPath path = new GraphicsPath() )
+ {
+ int top = e.Day.OverflowEndBounds.Top + e.Day.OverflowEndBounds.Height / 2;
+ path.AddPolygon( new Point[] {
+ new Point(e.Day.OverflowEndBounds.Left, top),
+ new Point(e.Day.OverflowEndBounds.Right, top),
+ new Point(e.Day.OverflowEndBounds.Left + e.Day.OverflowEndBounds.Width / 2, e.Day.OverflowEndBounds.Bottom),
+ } );
+
+ using( Brush b = new SolidBrush( e.Day.OverflowEndSelected ? ColorTable.DayOverflowSelectedBackground : ColorTable.DayOverflowBackground ) )
+ {
+ e.Graphics.FillPath( b, path );
+ }
+
+ using( Pen p = new Pen( ColorTable.DayOverflowBorder ) )
+ {
+ e.Graphics.DrawPath( p, path );
+ }
+ }
+ }
+
+ #endregion
+
+ }
+}
\ No newline at end of file
diff --git a/WindowsFormsCalendar/UserControls/Calendar.cs b/WindowsFormsCalendar/UserControls/Calendar.cs
new file mode 100644
index 0000000..69bb84e
--- /dev/null
+++ b/WindowsFormsCalendar/UserControls/Calendar.cs
@@ -0,0 +1,2084 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Hosts a calendar view where user can manage calendar items.
+ ///
+ [DefaultEvent( "LoadItems" )]
+ public class Calendar
+ : ScrollableControl
+ {
+ #region Static
+
+ ///
+ /// Returns a value indicating if two date ranges intersect.
+ ///
+ /// The start A.
+ /// The end A.
+ /// The start B.
+ /// The end B.
+ ///
+ public static bool DateIntersects( DateTime startA, DateTime endA, DateTime startB, DateTime endB )
+ {
+ return startB < endA && startA < endB;
+ }
+
+ #endregion
+
+ #region Events
+
+ ///
+ /// Delegate that supports event
+ ///
+ /// Sender of the event
+ /// Event Data
+ public delegate void CalendarLoadEventHandler( object sender, CalendarLoadEventArgs e );
+
+ ///
+ /// Delegate that supports item-related events
+ ///
+ ///
+ ///
+ public delegate void CalendarItemEventHandler( object sender, CalendarItemEventArgs e );
+
+ ///
+ /// Delegate that supports cancelable item-related events
+ ///
+ ///
+ ///
+ public delegate void CalendarItemCancelEventHandler( object sender, CalendarItemCancelEventArgs e );
+
+ ///
+ /// Delegate that supports -related events
+ ///
+ ///
+ ///
+ public delegate void CalendarDayEventHandler( object sender, CalendarDayEventArgs e );
+
+ ///
+ /// Occurs when items are load into view
+ ///
+ [Description( "Occurs when items are load into view" )]
+ public event CalendarLoadEventHandler LoadItems;
+
+ ///
+ /// Occurs when a day header is clicked
+ ///
+ [Description( "Occurs when a day header is clicked" )]
+ public event CalendarDayEventHandler DayHeaderClick;
+
+ ///
+ /// Occurs when an item is about to be created.
+ ///
+ ///
+ /// Event can be cancelled
+ ///
+ [Description( "Occurs when an item is about to be created." )]
+ public event CalendarItemCancelEventHandler ItemCreating;
+
+ ///
+ /// Occurs when an item has been created.
+ ///
+ [Description( "Occurs when an item has been created." )]
+ public event CalendarItemCancelEventHandler ItemCreated;
+
+ ///
+ /// Occurs before an item is deleted
+ ///
+ [Description( "Occurs before an item is deleted" )]
+ public event CalendarItemCancelEventHandler ItemDeleting;
+
+ ///
+ /// Occurs when an item has been deleted
+ ///
+ [Description( "Occurs when an item has been deleted" )]
+ public event CalendarItemEventHandler ItemDeleted;
+
+ ///
+ /// Occurs when an item text is about to be edited
+ ///
+ [Description( "Occurs when an item text is about to be edited" )]
+ public event CalendarItemCancelEventHandler ItemTextEditing;
+
+ ///
+ /// Occurs when an item text is edited
+ ///
+ [Description( "Occurs when an item text is edited" )]
+ public event CalendarItemCancelEventHandler ItemTextEdited;
+
+ ///
+ /// Occurs when an item time range has changed
+ ///
+ [Description( "Occurs when an item time range has changed" )]
+ public event CalendarItemEventHandler ItemDatesChanged;
+
+ ///
+ /// Occurs when an item is clicked
+ ///
+ [Description( "Occurs when an item is clicked" )]
+ public event CalendarItemEventHandler ItemClick;
+
+ ///
+ /// Occurs when an item is double-clicked
+ ///
+ [Description( "Occurs when an item is double-clicked" )]
+ public event CalendarItemEventHandler ItemDoubleClick;
+
+ ///
+ /// Occurs when an item is selected
+ ///
+ [Description( "Occurs when an item is selected" )]
+ public event CalendarItemEventHandler ItemSelected;
+
+ ///
+ /// Occurs after the items are positioned
+ ///
+ ///
+ /// Items bounds can be altered using the method.
+ ///
+ [Description( "Occurs after the items are positioned" )]
+ public event EventHandler ItemsPositioned;
+
+ ///
+ /// Occurs when the mouse is moved over an item
+ ///
+ [Description( "Occurs when the mouse is moved over an item" )]
+ public event CalendarItemEventHandler ItemMouseHover;
+
+ #endregion
+
+ #region Fields
+
+ private CalendarTextBox _textBox;
+
+ private bool _allowNew;
+ private bool _allowItemEdit;
+ private bool _allowItemResize;
+ private bool _creatingItem;
+
+ private CalendarDay[] _days;
+
+ private CalendarDaysMode _daysMode;
+
+ private CalendarItem _editModeItem;
+
+ private bool _finalizingEdition;
+
+ private DayOfWeek _firstDayOfWeek;
+
+ private CalendarHighlightRange[] _highlightRanges;
+ private CalendarItemCollection _items;
+
+ private string _itemsDateFormat;
+ private string _itemsTimeFormat;
+
+ private int _maximumFullDays;
+ private int _maximumViewDays;
+
+ private CalendarRenderer _renderer;
+
+ private DateTime _selEnd;
+ private DateTime _selStart;
+
+ private CalendarState _state;
+
+ private CalendarTimeScale _timeScale;
+
+ private int _timeUnitsOffset;
+
+ private DateTime _viewEnd;
+ private DateTime _viewStart;
+
+ private CalendarWeek[] _weeks;
+
+ private List _selectedElements;
+
+ private ICalendarSelectableElement _selectedElementEnd;
+ private ICalendarSelectableElement _selectedElementStart;
+
+ private Rectangle _selectedElementSquare;
+
+ private CalendarItem itemOnState;
+
+ private bool itemOnStateChanged;
+
+ private CalendarTimeFormat _timeFormat;
+
+ private CalendarScrollBars _scrollbars;
+
+ private Font _itemsmFont;
+
+ private DateTime _itemsStartViewTime;
+ private DateTime _itemEndViewTime;
+
+ private Color _itemsForeColor = Color.Black;
+ private Color _itemsBackgroundColor = Color.RoyalBlue;
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets or sets the color of the items fore.
+ ///
+ ///
+ /// The color of the items fore.
+ ///
+ [Description( "The default foreground color of the calendar items." )]
+ public Color ItemsForeColor
+ {
+ get { return _itemsForeColor; }
+ set { _itemsForeColor = value; }
+ }
+
+ ///
+ /// Gets or sets the color of the items background.
+ ///
+ ///
+ /// The color of the items background.
+ ///
+ [Description( "The default background color of the calendar items." )]
+ public Color ItemsBackgroundColor
+ {
+ get { return _itemsBackgroundColor; }
+ set { _itemsBackgroundColor = value; }
+ }
+
+ ///
+ /// Gets or sets the calendar item font.
+ ///
+ ///
+ /// The calendar item font.
+ ///
+ [Description("The default font values for all calendar items. This can be overriden in code.")]
+ public Font ItemsFont
+ {
+ get { return _itemsmFont; }
+ set { _itemsmFont = value; }
+ }
+
+ ///
+ /// Gets or sets a value indicating if the control let's the user create new items.
+ ///
+ [DefaultValue( true )]
+ [Description( "Allows the user to create new items on the view" )]
+ public bool AllowNew
+ {
+ get { return _allowNew; }
+ set { _allowNew = value; }
+ }
+
+ ///
+ /// Gets or sets a value indicating if the user can edit the item using the mouse or keyboard
+ ///
+ [DefaultValue( true )]
+ [Description( "Allows or denies the user the edition of items text or date ranges." )]
+ public bool AllowItemEdit
+ {
+ get { return _allowItemEdit; }
+ set { _allowItemEdit = value; }
+ }
+
+ ///
+ /// Gets or sets a value indicating if calendar allows user to resize the calendar.
+ ///
+ [DefaultValue( true )]
+ [Description( "Allows or denies the user to resize items on the calendar" )]
+ public bool AllowItemResize
+ {
+ get { return _allowItemResize; }
+ set { _allowItemResize = value; }
+ }
+
+ ///
+ /// Gets the days visible on the ccurrent view
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ [Browsable( false ), EditorBrowsable( EditorBrowsableState.Never )]
+ public CalendarDay[] Days
+ {
+ get { return _days; }
+ }
+
+ ///
+ /// Gets the mode in which days are drawn.
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ [Browsable( false ), EditorBrowsable( EditorBrowsableState.Never )]
+ public CalendarDaysMode DaysMode
+ {
+ get { return _daysMode; }
+ }
+
+ ///
+ /// Gets the union of day body rectangles
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ [Browsable( false ), EditorBrowsable( EditorBrowsableState.Never )]
+ public Rectangle DaysBodyRectangle
+ {
+ get
+ {
+ Rectangle first = Days[0].BodyBounds;
+ Rectangle last = Days[Days.Length - 1].BodyBounds;
+
+ return Rectangle.Union( first, last );
+ }
+ }
+
+ ///
+ /// Gets if the calendar is currently in edit mode of some item
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ [Browsable( false ), EditorBrowsable( EditorBrowsableState.Never )]
+ public bool EditMode
+ {
+ get { return TextBox != null; }
+ }
+
+ ///
+ /// Gets the item being edited (if any)
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ [Browsable( false ), EditorBrowsable( EditorBrowsableState.Never )]
+ public CalendarItem EditModeItem
+ {
+ get
+ {
+ return _editModeItem;
+ }
+ }
+
+ ///
+ /// Gets or sets the first day of weeks
+ ///
+ [Description( "Starting day of weeks" )]
+ [DefaultValue( DayOfWeek.Sunday )]
+ public DayOfWeek FirstDayOfWeek
+ {
+ set { _firstDayOfWeek = value; }
+ get { return _firstDayOfWeek; }
+ }
+
+ ///
+ /// Gets or sets the time ranges that should be highlighted as work-time.
+ /// This ranges are week based.
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ [Browsable( false ), EditorBrowsable( EditorBrowsableState.Never )]
+ public CalendarHighlightRange[] HighlightRanges
+ {
+ get { return _highlightRanges; }
+ set { _highlightRanges = value; UpdateHighlights(); }
+ }
+
+ ///
+ /// Gets the collection of items currently on the view.
+ ///
+ ///
+ /// This collection changes every time the view is changed
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ [Browsable( false ), EditorBrowsable( EditorBrowsableState.Never )]
+ public CalendarItemCollection Items
+ {
+ get { return _items; }
+ }
+
+ ///
+ /// Gets or sets the format in which time is shown in the items, when applicable
+ ///
+ [DefaultValue( "dd/MMM" )]
+ public string ItemsDateFormat
+ {
+ get { return _itemsDateFormat; }
+ set { _itemsDateFormat = value; }
+ }
+
+ ///
+ /// Gets or sets the format in which time is shown in the items, when applicable
+ ///
+ [DefaultValue( "hh:mm tt" )]
+ public string ItemsTimeFormat
+ {
+ get { return _itemsTimeFormat; }
+ set { _itemsTimeFormat = value; }
+ }
+
+ ///
+ /// Gets or sets the maximum full days shown on the view.
+ /// After this amount of days, they will be shown as short days.
+ ///
+ [DefaultValue( 8 )]
+ public int MaximumFullDays
+ {
+ get { return _maximumFullDays; }
+ set { _maximumFullDays = value; }
+ }
+
+ ///
+ /// Gets or sets the maximum amount of days supported by the view.
+ /// Value must be multiple of 7
+ ///
+ [DefaultValue( 35 )]
+ public int MaximumViewDays
+ {
+ get { return _maximumViewDays; }
+ set
+ {
+ if( value % 7 != 0 )
+ {
+ throw new Exception( "MaximumViewDays must be multiple of 7" );
+ }
+ _maximumViewDays = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the time format.
+ ///
+ ///
+ /// The time format.
+ ///
+ [Description( "The format of the calendar time (12 or 24 hour)." )]
+ [DefaultValue( CalendarTimeFormat.TwelveHour )]
+ public CalendarTimeFormat CalendarTimeFormat
+ {
+ get { return _timeFormat; }
+ set { _timeFormat = value; }
+ }
+
+ ///
+ /// Gets or sets the of the
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ [Browsable( false ), EditorBrowsable( EditorBrowsableState.Never )]
+ public CalendarRenderer Renderer
+ {
+ get { return _renderer; }
+ set
+ {
+ _renderer = value;
+
+ if( value != null && Created )
+ {
+ value.OnInitialize( new CalendarRendererEventArgs( null, null, Rectangle.Empty ) );
+ }
+ }
+ }
+
+ ///
+ /// Gets the last selected element
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ [Browsable( false ), EditorBrowsable( EditorBrowsableState.Never )]
+ public ICalendarSelectableElement SelectedElementEnd
+ {
+ get { return _selectedElementEnd; }
+ set
+ {
+ _selectedElementEnd = value;
+
+ UpdateSelectionElements();
+ }
+ }
+
+ ///
+ /// Gets the first selected element
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ [Browsable( false ), EditorBrowsable( EditorBrowsableState.Never )]
+ public ICalendarSelectableElement SelectedElementStart
+ {
+ get { return _selectedElementStart; }
+ set
+ {
+ _selectedElementStart = value;
+
+ UpdateSelectionElements();
+ }
+ }
+
+ ///
+ /// Gets or sets the end date-time of the view's selection.
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ [Browsable( false ), EditorBrowsable( EditorBrowsableState.Never )]
+ public DateTime SelectionEnd
+ {
+ get { return _selEnd; }
+ set { _selEnd = value; }
+ }
+
+ ///
+ /// Gets or sets the start date-time of the view's selection.
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ [Browsable( false ), EditorBrowsable( EditorBrowsableState.Never )]
+ public DateTime SelectionStart
+ {
+ get { return _selStart; }
+ set { _selStart = value; }
+ }
+
+ ///
+ /// Gets or sets the state of the calendar
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ [Browsable( false ), EditorBrowsable( EditorBrowsableState.Never )]
+ public CalendarState State
+ {
+ get { return _state; }
+ }
+
+ ///
+ /// Gets or sets the scrollbars.
+ ///
+ ///
+ /// The scrollbars.
+ ///
+ [Description( "Does the calendar show scrollbars." )]
+ [DefaultValue( CalendarScrollBars.None )]
+ public CalendarScrollBars Scrollbars
+ {
+ get { return _scrollbars; }
+ set { _scrollbars = value; }
+ }
+
+ ///
+ /// Gets the TextBox of the edit mode
+ ///
+ internal CalendarTextBox TextBox
+ {
+ get { return _textBox; }
+ set { _textBox = value; }
+ }
+
+ ///
+ /// Gets or sets the for visualization.
+ ///
+ [DefaultValue( CalendarTimeScale.ThirtyMinutes )]
+ public CalendarTimeScale TimeScale
+ {
+ get { return _timeScale; }
+ set
+ {
+ _timeScale = value;
+
+ if( Days != null )
+ {
+ for( int i = 0; i < Days.Length; i++ )
+ {
+ Days[i].UpdateUnits();
+ }
+ }
+
+ Renderer.PerformLayout();
+ Refresh();
+ }
+ }
+
+ ///
+ /// Gets or sets the offset of scrolled units
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ public int TimeUnitsOffset
+ {
+ get { return _timeUnitsOffset; }
+ set
+ {
+ _timeUnitsOffset = value;
+ Renderer.PerformLayout();
+ Invalidate();
+ }
+ }
+
+ ///
+ /// Gets or sets the end date-time of the current view.
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ [Browsable( false ), EditorBrowsable( EditorBrowsableState.Never )]
+ public DateTime ViewEnd
+ {
+ get { return _viewEnd; }
+ set
+ {
+ _viewEnd = value.Date.Add( new TimeSpan( 23, 59, 59 ) );
+ ClearItems();
+ UpdateDaysAndWeeks();
+ Renderer.PerformLayout();
+ Invalidate();
+ ReloadItems();
+ }
+ }
+
+ ///
+ /// Gets or sets the start date-time of the current view.
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ [Browsable( false ), EditorBrowsable( EditorBrowsableState.Never )]
+ public DateTime ViewStart
+ {
+ get { return _viewStart; }
+ set
+ {
+ _viewStart = value.Date;
+ ClearItems();
+ UpdateDaysAndWeeks();
+ Renderer.PerformLayout();
+ Invalidate();
+ ReloadItems();
+ }
+ }
+
+ ///
+ /// Gets the weeks currently visible on the calendar, if is
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ [Browsable( false ), EditorBrowsable( EditorBrowsableState.Never )]
+ public CalendarWeek[] Weeks
+ {
+ get { return _weeks; }
+ }
+
+ #endregion
+
+ ///
+ /// Creates a new control
+ ///
+ public Calendar()
+ {
+ SetStyle( ControlStyles.ResizeRedraw, true );
+ SetStyle( ControlStyles.Selectable, true );
+
+ DoubleBuffered = true;
+
+ _selectedElements = new List();
+ _items = new CalendarItemCollection( this );
+ _renderer = new CalendarProfessionalRenderer( this );
+ _maximumFullDays = 8;
+ _maximumViewDays = 35;
+
+ HighlightRanges = new CalendarHighlightRange[] {
+ new CalendarHighlightRange( DayOfWeek.Monday, new TimeSpan(8,0,0), new TimeSpan(17,0,0)),
+ new CalendarHighlightRange( DayOfWeek.Tuesday, new TimeSpan(8,0,0), new TimeSpan(17,0,0)),
+ new CalendarHighlightRange( DayOfWeek.Wednesday, new TimeSpan(8,0,0), new TimeSpan(17,0,0)),
+ new CalendarHighlightRange( DayOfWeek.Thursday, new TimeSpan(8,0,0), new TimeSpan(17,0,0)),
+ new CalendarHighlightRange( DayOfWeek.Friday, new TimeSpan(8,0,0), new TimeSpan(17,0,0)),
+ };
+
+ _timeScale = CalendarTimeScale.ThirtyMinutes;
+ SetViewRange( DateTime.Now, DateTime.Now.AddDays( 2 ) );
+
+
+ _itemsDateFormat = "dd/MMM";
+ _itemsTimeFormat = "hh:mm tt";
+ _allowItemEdit = true;
+ _allowNew = true;
+ _allowItemResize = true;
+ }
+
+ #region Public Methods
+
+ ///
+ /// Activates the edit mode on the first selected item
+ ///
+ public void ActivateEditMode()
+ {
+ foreach( CalendarItem item in Items )
+ {
+ if( item.Selected )
+ {
+ ActivateEditMode( item );
+ return;
+ }
+ }
+ }
+
+ ///
+ /// Activates the edit mode on the specified item
+ ///
+ /// The item.
+ public void ActivateEditMode( CalendarItem item )
+ {
+ CalendarItemCancelEventArgs evt = new CalendarItemCancelEventArgs( item );
+
+ if( !_creatingItem )
+ {
+ OnItemEditing( evt );
+ }
+
+ if( evt.Cancel )
+ {
+ return;
+ }
+
+ _editModeItem = item;
+ TextBox = new CalendarTextBox( this );
+ TextBox.KeyDown += new KeyEventHandler( TextBox_KeyDown );
+ TextBox.LostFocus += new EventHandler( TextBox_LostFocus );
+ Rectangle r = item.Bounds;
+ r.Inflate( -2, -2 );
+ TextBox.Bounds = r;
+ TextBox.BorderStyle = BorderStyle.None;
+ TextBox.Text = item.Text;
+ TextBox.Multiline = true;
+
+ Controls.Add( TextBox );
+ TextBox.Visible = true;
+ TextBox.Focus();
+ TextBox.SelectionStart = TextBox.Text.Length;
+
+ SetState( CalendarState.EditingItemText );
+ }
+
+ ///
+ /// Creates a new item on the current selection.
+ /// If there's no selection, this will be ignored.
+ ///
+ /// Text of the item
+ /// If true activates the edit mode so user can edit the text of the item.
+ public void CreateItemOnSelection( string itemText, bool editMode )
+ {
+ if( SelectedElementEnd == null || SelectedElementStart == null ) return;
+
+ CalendarTimeScaleUnit unitEnd = SelectedElementEnd as CalendarTimeScaleUnit;
+ CalendarDayTop dayTop = SelectedElementEnd as CalendarDayTop;
+ CalendarDay day = SelectedElementEnd as CalendarDay;
+ TimeSpan duration = unitEnd != null ? unitEnd.Duration : new TimeSpan( 23, 59, 59 );
+ CalendarItem item = new CalendarItem( this );
+
+ DateTime dstart = SelectedElementStart.Date;
+ DateTime dend = SelectedElementEnd.Date;
+
+ if( dend.CompareTo( dstart ) < 0 )
+ {
+ DateTime dtmp = dend;
+ dend = dstart;
+ dstart = dtmp;
+ }
+
+ item.StartDate = dstart;
+ item.EndDate = dend.Add( duration );
+ item.Text = itemText;
+
+ CalendarItemCancelEventArgs evtA = new CalendarItemCancelEventArgs( item );
+
+ OnItemCreating( evtA );
+
+ if( !evtA.Cancel )
+ {
+ // set the default font, developers can change this anytime via override
+ Items.Add( item );
+
+ if( editMode )
+ {
+ _creatingItem = true;
+ ActivateEditMode( item );
+ }
+ }
+
+
+ }
+
+ ///
+ /// Ensures the scrolling shows the specified time unit. It doesn't affect View date ranges.
+ ///
+ /// Unit to ensure visibility
+ public void EnsureVisible( CalendarTimeScaleUnit unit )
+ {
+ if( Days == null || Days.Length == 0 ) return;
+
+ Rectangle view = Days[0].BodyBounds;
+
+ if( unit.Bounds.Bottom > view.Bottom )
+ {
+ TimeUnitsOffset = -Convert.ToInt32( Math.Ceiling( unit.Date.TimeOfDay.TotalMinutes / (double)TimeScale ) )
+ + Renderer.GetVisibleTimeUnits();
+ }
+ else if( unit.Bounds.Top < view.Top )
+ {
+ TimeUnitsOffset = -Convert.ToInt32( Math.Ceiling( unit.Date.TimeOfDay.TotalMinutes / (double)TimeScale ) );
+ }
+ }
+
+ ///
+ /// Finalizes editing the .
+ ///
+ /// Value indicating if edition of item should be canceled.
+ public void FinalizeEditMode( bool cancel )
+ {
+ if( !EditMode || EditModeItem == null || _finalizingEdition ) return;
+
+ _finalizingEdition = true;
+
+ string cancelText = _editModeItem.Text;
+ CalendarItem itemBuffer = _editModeItem;
+ _editModeItem = null;
+ CalendarItemCancelEventArgs evt = new CalendarItemCancelEventArgs( itemBuffer );
+
+ if( !cancel )
+ itemBuffer.Text = TextBox.Text.Trim();
+
+ if( TextBox != null )
+ {
+ TextBox.Visible = false;
+ Controls.Remove( TextBox );
+ TextBox.Dispose();
+ }
+
+ if( _editModeItem != null )
+ Invalidate( itemBuffer );
+
+ _textBox = null;
+
+ if( _creatingItem )
+ {
+ OnItemCreated( evt );
+ }
+ else
+ {
+ OnItemEdited( evt );
+ }
+
+ if( evt.Cancel )
+ {
+ itemBuffer.Text = cancelText;
+ }
+
+
+ _creatingItem = false;
+ _finalizingEdition = false;
+
+ if( State == CalendarState.EditingItemText )
+ {
+ SetState( CalendarState.Idle );
+ }
+ }
+
+ ///
+ /// Finds the for the specified date, if in the view.
+ ///
+ /// Date to find day
+ /// object that matches the date, null if day was not found.
+ public CalendarDay FindDay( DateTime d )
+ {
+ if( Days == null ) return null;
+
+ for( int i = 0; i < Days.Length; i++ )
+ {
+ if( Days[i].Date.Date.Equals( d.Date.Date ) )
+ {
+ return Days[i];
+ }
+ }
+
+ return null;
+ }
+
+ ///
+ /// Gets the items that are currently selected
+ ///
+ ///
+ public IEnumerable GetSelectedItems()
+ {
+ List items = new List();
+
+ foreach( CalendarItem item in Items )
+ {
+ if( item.Selected )
+ {
+ items.Add( item );
+ }
+ }
+
+ return items;
+ }
+
+ ///
+ /// Gets the time unit that starts with the specified date
+ ///
+ /// The d.
+ ///
+ /// Matching time unit. null If out of range.
+ ///
+ public CalendarTimeScaleUnit GetTimeUnit( DateTime d )
+ {
+ if( Days != null )
+ {
+ foreach( CalendarDay day in Days )
+ {
+ if( day.Date.Equals( d.Date ) )
+ {
+ double duration = Convert.ToDouble( (int)TimeScale );
+ int index =
+ Convert.ToInt32(
+ Math.Floor(
+ d.TimeOfDay.TotalMinutes / duration
+ )
+ );
+
+ return day.TimeUnits[index];
+ }
+ }
+ }
+
+ return null;
+ }
+
+ ///
+ /// Hits the test.
+ ///
+ /// The p.
+ ///
+ public ICalendarSelectableElement HitTest( Point p )
+ {
+ return HitTest( p, false );
+ }
+
+ ///
+ /// Searches for the first hitted
+ ///
+ /// Point to check for hit test
+ /// if set to true [ignore items].
+ ///
+ public ICalendarSelectableElement HitTest( Point p, bool ignoreItems )
+ {
+ if( !ignoreItems )
+ foreach( CalendarItem item in Items )
+ {
+ foreach( Rectangle r in item.GetAllBounds() )
+ {
+ if( r.Contains( p ) )
+ {
+ return item;
+ }
+ }
+ }
+
+ for( int i = 0; i < Days.Length; i++ )
+ {
+ if( Days[i].Bounds.Contains( p ) )
+ {
+ if( DaysMode == CalendarDaysMode.Expanded )
+ {
+ if( Days[i].DayTop.Bounds.Contains( p ) )
+ {
+ return Days[i].DayTop;
+ }
+ else
+ {
+ for( int j = 0; j < Days[i].TimeUnits.Length; j++ )
+ {
+ if( Days[i].TimeUnits[j].Visible &&
+ Days[i].TimeUnits[j].Bounds.Contains( p ) )
+ {
+ return Days[i].TimeUnits[j];
+ }
+ }
+ }
+
+ return Days[i];
+ }
+ else if( DaysMode == CalendarDaysMode.Short )
+ {
+ return Days[i];
+ }
+ }
+ }
+
+ return null;
+ }
+
+ ///
+ /// Returns the item hitted at the specified location. Null if no item hitted.
+ ///
+ /// Location to serach for items
+ /// Hitted item at the location. Null if no item hitted.
+ public CalendarItem ItemAt( Point p )
+ {
+ return HitTest( p ) as CalendarItem;
+ }
+
+ ///
+ /// Invalidates the bounds of the specified day
+ ///
+ /// The day.
+ public void Invalidate( CalendarDay day )
+ {
+ Invalidate( day.Bounds );
+ }
+
+ ///
+ /// Ivalidates the bounds of the specified unit
+ ///
+ /// The unit.
+ public void Invalidate( CalendarTimeScaleUnit unit )
+ {
+ Invalidate( unit.Bounds );
+ }
+
+ ///
+ /// Invalidates the area of the specified item
+ ///
+ /// The item.
+ public void Invalidate( CalendarItem item )
+ {
+ Rectangle r = item.Bounds;
+
+ foreach( Rectangle bounds in item.GetAllBounds() )
+ {
+ r = Rectangle.Union( r, bounds );
+ }
+
+ r.Inflate( Renderer.ItemShadowPadding + Renderer.ItemInvalidateMargin, Renderer.ItemShadowPadding + Renderer.ItemInvalidateMargin );
+ Invalidate( r );
+ }
+
+ ///
+ /// Establishes the selection range with only one graphical update.
+ ///
+ /// Fisrt selected element
+ /// Last selection element
+ public void SetSelectionRange( ICalendarSelectableElement selectionStart, ICalendarSelectableElement selectionEnd )
+ {
+ _selectedElementStart = selectionStart;
+ SelectedElementEnd = selectionEnd;
+ }
+
+ ///
+ /// Sets the value of and properties
+ /// triggering only one repaint process
+ ///
+ /// Start date of view
+ /// End date of view
+ public void SetViewRange( DateTime dateStart, DateTime dateEnd )
+ {
+ _viewStart = dateStart.Date;
+ ViewEnd = dateEnd;
+ }
+
+ ///
+ /// Returns a value indicating if the view range intersects the specified date range.
+ ///
+ /// The start date.
+ /// The end date.
+ ///
+ public bool ViewIntersects( DateTime startDate, DateTime endDate )
+ {
+ return DateIntersects( ViewStart, ViewEnd, startDate, endDate );
+ }
+
+ ///
+ /// Returns a value indicating if the view range intersect the date range of the specified item
+ ///
+ /// The item.
+ ///
+ public bool ViewIntersects( CalendarItem item )
+ {
+ return ViewIntersects( item.StartDate, item.EndDate );
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ ///
+ /// Determines whether the specified key is a regular input key or a special key that requires preprocessing.
+ ///
+ /// One of the values.
+ ///
+ /// true if the specified key is a regular input key; otherwise, false.
+ ///
+ protected override bool IsInputKey( Keys keyData )
+ {
+ if(
+ keyData == Keys.Down ||
+ keyData == Keys.Up ||
+ keyData == Keys.Right ||
+ keyData == Keys.Left )
+ {
+ return true;
+ }
+ else
+ {
+
+ return base.IsInputKey( keyData );
+ }
+ }
+
+ ///
+ /// Removes all the items currently on the calendar
+ ///
+ private void ClearItems()
+ {
+ Items.Clear();
+ Renderer.DayTopHeight = Renderer.DayTopMinHeight;
+ }
+
+ ///
+ /// Unselects the selected items
+ ///
+ private void ClearSelectedItems()
+ {
+ Rectangle r = Rectangle.Empty;
+
+ foreach( CalendarItem item in Items )
+ {
+ if( item.Selected )
+ {
+ if( r.IsEmpty )
+ {
+ r = item.Bounds;
+ }
+ else
+ {
+ r = Rectangle.Union( r, item.Bounds );
+ }
+ }
+
+ item.SetSelected( false );
+ }
+
+ Invalidate( r );
+ }
+
+ ///
+ /// Deletes the currently selected item
+ ///
+ private void DeleteSelectedItems()
+ {
+ Stack toDelete = new Stack();
+
+ foreach( CalendarItem item in Items )
+ {
+ if( item.Selected )
+ {
+ CalendarItemCancelEventArgs evt = new CalendarItemCancelEventArgs( item );
+
+ OnItemDeleting( evt );
+
+ if( !evt.Cancel )
+ {
+ toDelete.Push( item );
+ }
+ }
+ }
+
+ if( toDelete.Count > 0 )
+ {
+ while( toDelete.Count > 0 )
+ {
+ CalendarItem item = toDelete.Pop();
+
+ Items.Remove( item );
+
+ OnItemDeleted( new CalendarItemEventArgs( item ) );
+ }
+
+ Renderer.PerformItemsLayout();
+ }
+ }
+
+ ///
+ /// Clears current items and reloads for specified view
+ ///
+ private void ReloadItems()
+ {
+ OnLoadItems( new CalendarLoadEventArgs( this, ViewStart, ViewEnd ) );
+ }
+
+ ///
+ /// Grows the rectangle to repaint currently selected elements
+ ///
+ /// The rect.
+ private void GrowSquare( Rectangle rect )
+ {
+ if( _selectedElementSquare.IsEmpty )
+ {
+ _selectedElementSquare = rect;
+ }
+ else
+ {
+ _selectedElementSquare = Rectangle.Union( _selectedElementSquare, rect );
+ }
+ }
+
+ ///
+ /// Clears selection of currently selected components (As quick as possible)
+ ///
+ private void ClearSelectedComponents()
+ {
+ foreach( CalendarSelectableElement element in _selectedElements )
+ {
+ element.SetSelected( false );
+ }
+
+ _selectedElements.Clear();
+
+ Invalidate( _selectedElementSquare );
+ _selectedElementSquare = Rectangle.Empty;
+
+ }
+
+ ///
+ /// Scrolls the calendar using the specified delta
+ ///
+ /// The delta.
+ private void ScrollCalendar( int delta )
+ {
+ if( delta < 0 )
+ {
+ SetViewRange( ViewStart.AddDays( 7 ), ViewEnd.AddDays( 7 ) );
+ }
+ else
+ {
+ SetViewRange( ViewStart.AddDays( -7 ), ViewEnd.AddDays( -7 ) );
+ }
+ }
+
+ ///
+ /// Raises the event
+ ///
+ internal void RaiseItemsPositioned()
+ {
+ OnItemsPositioned( EventArgs.Empty );
+ }
+
+ ///
+ /// Scrolls the time units using the specified delta
+ ///
+ /// The delta.
+ private void ScrollTimeUnits( int delta )
+ {
+ int possible = TimeUnitsOffset;
+ int visible = Renderer.GetVisibleTimeUnits();
+
+ if( delta < 0 )
+ {
+ possible--;
+ }
+ else
+ {
+ possible++;
+ }
+
+ if( possible > 0 )
+ {
+ possible = 0;
+ }
+ else if(
+ Days != null
+ && Days.Length > 0
+ && Days[0].TimeUnits != null
+ && possible * -1 >= Days[0].TimeUnits.Length )
+ {
+ possible = Days[0].TimeUnits.Length - 1;
+ possible *= -1;
+ }
+ else if( Days != null
+ && Days.Length > 0
+ && Days[0].TimeUnits != null )
+ {
+ int max = Days[0].TimeUnits.Length - visible;
+ max *= -1;
+ if( possible < max ) possible = max;
+ }
+
+ if( possible != TimeUnitsOffset )
+ {
+ TimeUnitsOffset = possible;
+ }
+ }
+
+ ///
+ /// Sets the value of the property.
+ ///
+ /// Mode in which days will be rendered
+ private void SetDaysMode( CalendarDaysMode mode )
+ {
+ _daysMode = mode;
+ }
+
+ ///
+ /// Sets the state.
+ ///
+ /// The state.
+ private void SetState( CalendarState state )
+ {
+ _state = state;
+ }
+
+ ///
+ /// Handles the LostFocus event of the TextBox control.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ private void TextBox_LostFocus( object sender, EventArgs e )
+ {
+ FinalizeEditMode( false );
+ }
+
+ ///
+ /// Handles the KeyDown event of the TextBox control.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ private void TextBox_KeyDown( object sender, KeyEventArgs e )
+ {
+ if( e.KeyCode == Keys.Escape )
+ {
+ FinalizeEditMode( true );
+ }
+ else if( e.KeyCode == Keys.Enter )
+ {
+ FinalizeEditMode( false );
+ }
+ }
+
+ ///
+ /// Updates the days and weeks.
+ ///
+ private void UpdateDaysAndWeeks()
+ {
+ TimeSpan span = ( new DateTime( ViewEnd.Year, ViewEnd.Month, ViewEnd.Day, 23, 59, 59 ) ).Subtract( ViewStart.Date );
+ int preDays = 0;
+ span = span.Add( new TimeSpan( 0, 0, 0, 1, 0 ) );
+
+ if( span.Days < 1 || span.Days > MaximumViewDays )
+ {
+ throw new Exception( "Days between ViewStart and ViewEnd should be between 1 and MaximumViewDays" );
+ }
+
+ if( span.Days > MaximumFullDays )
+ {
+ SetDaysMode( CalendarDaysMode.Short );
+ preDays = ( new int[] { 0, 1, 2, 3, 4, 5, 6 } )[(int)ViewStart.DayOfWeek] - (int)FirstDayOfWeek;
+ span = span.Add( new TimeSpan( preDays, 0, 0, 0 ) );
+
+ while( span.Days % 7 != 0 )
+ span = span.Add( new TimeSpan( 1, 0, 0, 0 ) );
+ }
+ else
+ {
+ SetDaysMode( CalendarDaysMode.Expanded );
+ }
+
+ _days = new CalendarDay[span.Days];
+
+ for( int i = 0; i < Days.Length; i++ )
+ Days[i] = new CalendarDay( this, ViewStart.AddDays( -preDays + i ), i );
+
+
+ //Weeks
+ if( DaysMode == CalendarDaysMode.Short )
+ {
+ List weeks = new List();
+
+ for( int i = 0; i < Days.Length; i++ )
+ {
+ if( Days[i].Date.DayOfWeek == FirstDayOfWeek )
+ {
+ weeks.Add( new CalendarWeek( this, Days[i].Date ) );
+ }
+ }
+
+ _weeks = weeks.ToArray();
+ }
+ else
+ {
+ _weeks = new CalendarWeek[] { };
+ }
+
+ UpdateHighlights();
+
+ }
+
+ ///
+ /// Updates the value of the property on the time units of days.
+ ///
+ internal void UpdateHighlights()
+ {
+ if( Days == null ) return;
+
+ for( int i = 0; i < Days.Length; i++ )
+ {
+ Days[i].UpdateHighlights();
+ }
+ }
+
+ ///
+ /// Informs elements who's selected and who's not, and repaints
+ ///
+ private void UpdateSelectionElements()
+ {
+ CalendarTimeScaleUnit unitStart = _selectedElementStart as CalendarTimeScaleUnit;
+ CalendarDayTop topStart = _selectedElementStart as CalendarDayTop;
+ CalendarDay dayStart = _selectedElementStart as CalendarDay;
+ CalendarTimeScaleUnit unitEnd = _selectedElementEnd as CalendarTimeScaleUnit;
+ CalendarDayTop topEnd = _selectedElementEnd as CalendarDayTop;
+ CalendarDay dayEnd = _selectedElementEnd as CalendarDay;
+
+ ClearSelectedComponents();
+
+ if( _selectedElementEnd == null || _selectedElementStart == null ) return;
+
+ if( _selectedElementEnd.CompareTo( SelectedElementStart ) < 0 )
+ {
+ //swap
+ unitStart = _selectedElementEnd as CalendarTimeScaleUnit;
+ topStart = _selectedElementEnd as CalendarDayTop;
+ dayStart = _selectedElementEnd as CalendarDay;
+ unitEnd = SelectedElementStart as CalendarTimeScaleUnit;
+ topEnd = SelectedElementStart as CalendarDayTop;
+ dayEnd = _selectedElementStart as CalendarDay;
+ }
+
+ if( unitStart != null && unitEnd != null )
+ {
+ bool reached = false;
+ for( int i = unitStart.Day.Index; !reached; i++ )
+ {
+ for( int j = ( i == unitStart.Day.Index ? unitStart.Index : 0 ); i < Days.Length && j < Days[i].TimeUnits.Length; j++ )
+ {
+ CalendarTimeScaleUnit unit = Days[i].TimeUnits[j];
+ unit.SetSelected( true );
+ GrowSquare( unit.Bounds );
+ _selectedElements.Add( unit );
+
+ if( unit.Equals( unitEnd ) )
+ {
+ reached = true;
+ break;
+ }
+ }
+ }
+ }
+ else if( topStart != null && topEnd != null )
+ {
+ for( int i = topStart.Day.Index; i <= topEnd.Day.Index; i++ )
+ {
+ CalendarDayTop top = Days[i].DayTop;
+
+ top.SetSelected( true );
+ GrowSquare( top.Bounds );
+ _selectedElements.Add( top );
+ }
+ }
+ else if( dayStart != null && dayEnd != null )
+ {
+ for( int i = dayStart.Index; i <= dayEnd.Index; i++ )
+ {
+ CalendarDay day = Days[i];
+
+ day.SetSelected( true );
+ GrowSquare( day.Bounds );
+ _selectedElements.Add( day );
+ }
+ }
+
+ Invalidate( _selectedElementSquare );
+ }
+
+ #endregion
+
+ #region Overrided Events and Raisers
+
+ ///
+ /// Raises the method.
+ ///
+ protected override void OnCreateControl()
+ {
+ base.OnCreateControl();
+
+ Renderer.OnInitialize( new CalendarRendererEventArgs( new CalendarRendererEventArgs( this, null, Rectangle.Empty ) ) );
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// An that contains the event data.
+ protected override void OnClick( EventArgs e )
+ {
+ base.OnClick( e );
+
+ Select();
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// An that contains the event data.
+ protected override void OnDoubleClick( EventArgs e )
+ {
+ base.OnDoubleClick( e );
+
+ CreateItemOnSelection( string.Empty, true );
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ protected virtual void OnDayHeaderClick( CalendarDayEventArgs e )
+ {
+ if( DayHeaderClick != null )
+ {
+ DayHeaderClick( this, e );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ protected virtual void OnItemClick( CalendarItemEventArgs e )
+ {
+ if( ItemClick != null )
+ {
+ ItemClick( this, e );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ protected virtual void OnItemCreating( CalendarItemCancelEventArgs e )
+ {
+ if( ItemCreating != null )
+ {
+ ItemCreating( this, e );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ protected virtual void OnItemCreated( CalendarItemCancelEventArgs e )
+ {
+ if( ItemCreated != null )
+ {
+ ItemCreated( this, e );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ protected virtual void OnItemDeleting( CalendarItemCancelEventArgs e )
+ {
+ if( ItemDeleting != null )
+ {
+ ItemDeleting( this, e );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ protected virtual void OnItemDeleted( CalendarItemEventArgs e )
+ {
+ if( ItemDeleted != null )
+ {
+ ItemDeleted( this, e );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ protected virtual void OnItemDoubleClick( CalendarItemEventArgs e )
+ {
+ if( ItemDoubleClick != null )
+ {
+ ItemDoubleClick( this, e );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ protected virtual void OnItemEditing( CalendarItemCancelEventArgs e )
+ {
+ if( ItemTextEditing != null )
+ {
+ ItemTextEditing( this, e );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ protected virtual void OnItemEdited( CalendarItemCancelEventArgs e )
+ {
+ if( ItemTextEdited != null )
+ {
+ ItemTextEdited( this, e );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ protected virtual void OnItemSelected( CalendarItemEventArgs e )
+ {
+ if( ItemSelected != null )
+ {
+ ItemSelected( this, e );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ protected virtual void OnItemsPositioned( EventArgs e )
+ {
+ if( ItemsPositioned != null )
+ {
+ ItemsPositioned( this, e );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ protected virtual void OnItemDatesChanged( CalendarItemEventArgs e )
+ {
+ if( ItemDatesChanged != null )
+ {
+ ItemDatesChanged( this, e );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ protected virtual void OnItemMouseHover( CalendarItemEventArgs e )
+ {
+ if( ItemMouseHover != null )
+ {
+ ItemMouseHover( this, e );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// A that contains the event data.
+ protected override void OnKeyDown( KeyEventArgs e )
+ {
+ base.OnKeyDown( e );
+
+ bool shiftPressed = ( ModifierKeys & Keys.Shift ) == Keys.Shift;
+ int jump = (int)TimeScale;
+ ICalendarSelectableElement sStart = null;
+ ICalendarSelectableElement sEnd = null;
+
+ if( e.KeyCode == Keys.F2 )
+ {
+ ActivateEditMode();
+ }
+ else if( e.KeyCode == Keys.Delete )
+ {
+ DeleteSelectedItems();
+ }
+ else if( e.KeyCode == Keys.Insert )
+ {
+ if( AllowNew )
+ CreateItemOnSelection( string.Empty, true );
+ }
+ else if( e.KeyCode == Keys.Down )
+ {
+ if( e.Shift )
+ sStart = SelectedElementStart;
+
+ sEnd = GetTimeUnit( SelectedElementEnd.Date.Add( new TimeSpan( 0, (int)TimeScale, 0 ) ) );
+ }
+ else if( e.KeyCode == Keys.Up )
+ {
+ if( e.Shift )
+ sStart = SelectedElementStart;
+
+ sEnd = GetTimeUnit( SelectedElementEnd.Date.Add( new TimeSpan( 0, -(int)TimeScale, 0 ) ) );
+ }
+ else if( e.KeyCode == Keys.Right )
+ {
+ sEnd = GetTimeUnit( SelectedElementEnd.Date.Add( new TimeSpan( 24, 0, 0 ) ) );
+ }
+ else if( e.KeyCode == Keys.Left )
+ {
+ sEnd = GetTimeUnit( SelectedElementEnd.Date.Add( new TimeSpan( -24, 0, 0 ) ) );
+ }
+ else if( e.KeyCode == Keys.PageDown )
+ {
+
+ }
+ else if( e.KeyCode == Keys.PageUp )
+ {
+
+ }
+
+
+ if( sStart != null )
+ {
+ SetSelectionRange( sStart, sEnd );
+ }
+ else if( sEnd != null )
+ {
+ SetSelectionRange( sEnd, sEnd );
+
+ if( sEnd is CalendarTimeScaleUnit )
+ EnsureVisible( sEnd as CalendarTimeScaleUnit );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// A that contains the event data.
+ protected override void OnKeyPress( KeyPressEventArgs e )
+ {
+ base.OnKeyPress( e );
+
+ if( AllowNew )
+ CreateItemOnSelection( e.KeyChar.ToString(), true );
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ protected virtual void OnLoadItems( CalendarLoadEventArgs e )
+ {
+ if( LoadItems != null )
+ {
+ LoadItems( this, e );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// An that contains the event data.
+ protected override void OnMouseDoubleClick( MouseEventArgs e )
+ {
+ base.OnMouseDoubleClick( e );
+
+ CalendarItem item = ItemAt( e.Location );
+
+ if( item != null )
+ {
+ OnItemDoubleClick( new CalendarItemEventArgs( item ) );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// A that contains the event data.
+ protected override void OnMouseDown( MouseEventArgs e )
+ {
+ base.OnMouseDown( e );
+
+ ICalendarSelectableElement hitted = HitTest( e.Location );
+ CalendarItem hittedItem = hitted as CalendarItem;
+ bool shiftPressed = ( ModifierKeys & Keys.Shift ) == Keys.Shift;
+
+ if( !Focused )
+ {
+ Focus();
+ }
+
+ switch( State )
+ {
+ case CalendarState.Idle:
+ if( hittedItem != null )
+ {
+ if( !shiftPressed )
+ ClearSelectedItems();
+
+ hittedItem.SetSelected( true );
+ Invalidate( hittedItem );
+ OnItemSelected( new CalendarItemEventArgs( hittedItem ) );
+
+ itemOnState = hittedItem;
+ itemOnStateChanged = false;
+
+ if( AllowItemEdit )
+ {
+ if( itemOnState.ResizeStartDateZone( e.Location ) && AllowItemResize )
+ {
+ SetState( CalendarState.ResizingItem );
+ itemOnState.SetIsResizingStartDate( true );
+ }
+ else if( itemOnState.ResizeEndDateZone( e.Location ) && AllowItemResize )
+ {
+ SetState( CalendarState.ResizingItem );
+ itemOnState.SetIsResizingEndDate( true );
+ }
+ else
+ {
+ SetState( CalendarState.DraggingItem );
+ }
+ }
+
+ SetSelectionRange( null, null );
+ }
+ else
+ {
+ ClearSelectedItems();
+
+ if( shiftPressed )
+ {
+ if( hitted != null && SelectedElementEnd == null && !SelectedElementEnd.Equals( hitted ) )
+ SelectedElementEnd = hitted;
+ }
+ else
+ {
+ if( SelectedElementStart == null || ( hitted != null && !SelectedElementStart.Equals( hitted ) ) )
+ {
+ SetSelectionRange( hitted, hitted );
+ }
+ }
+
+ SetState( CalendarState.DraggingTimeSelection );
+ }
+ break;
+ case CalendarState.DraggingTimeSelection:
+ break;
+ case CalendarState.DraggingItem:
+ break;
+ case CalendarState.ResizingItem:
+ break;
+ case CalendarState.EditingItemText:
+ break;
+
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// A that contains the event data.
+ protected override void OnMouseMove( MouseEventArgs e )
+ {
+ base.OnMouseMove( e );
+
+ ICalendarSelectableElement hitted = HitTest( e.Location, State != CalendarState.Idle );
+ CalendarItem hittedItem = hitted as CalendarItem;
+ CalendarDayTop hittedTop = hitted as CalendarDayTop;
+ bool shiftPressed = ( ModifierKeys & Keys.Shift ) == Keys.Shift;
+
+ if( hitted != null )
+ {
+ switch( State )
+ {
+ case CalendarState.Idle:
+ Cursor should = Cursors.Default;
+
+ if( hittedItem != null )
+ {
+ if( ( hittedItem.ResizeEndDateZone( e.Location ) || hittedItem.ResizeStartDateZone( e.Location ) ) && AllowItemResize )
+ {
+ should = hittedItem.IsOnDayTop || DaysMode == CalendarDaysMode.Short ? Cursors.SizeWE : Cursors.SizeNS;
+ }
+
+ OnItemMouseHover( new CalendarItemEventArgs( hittedItem ) );
+
+ }
+ if( !Cursor.Equals( should ) ) Cursor = should;
+ break;
+ case CalendarState.DraggingTimeSelection:
+ if( SelectedElementStart != null && !SelectedElementEnd.Equals( hitted ) )
+ SelectedElementEnd = hitted;
+ break;
+ case CalendarState.DraggingItem:
+ TimeSpan duration = itemOnState.Duration;
+ itemOnState.SetIsDragging( true );
+ itemOnState.StartDate = hitted.Date;
+ itemOnState.EndDate = itemOnState.StartDate.Add( duration );
+ Renderer.PerformItemsLayout();
+ Invalidate();
+ itemOnStateChanged = true;
+ break;
+ case CalendarState.ResizingItem:
+ if( itemOnState.IsResizingEndDate && hitted.Date.CompareTo( itemOnState.StartDate ) >= 0 )
+ {
+ itemOnState.EndDate = hitted.Date.Add( hittedTop != null || DaysMode == CalendarDaysMode.Short ? new TimeSpan( 23, 59, 59 ) : Days[0].TimeUnits[0].Duration );
+ }
+ else if( itemOnState.IsResizingStartDate && hitted.Date.CompareTo( itemOnState.EndDate ) <= 0 )
+ {
+ itemOnState.StartDate = hitted.Date;
+ }
+ Renderer.PerformItemsLayout();
+ Invalidate();
+ itemOnStateChanged = true;
+ break;
+ case CalendarState.EditingItemText:
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// A that contains the event data.
+ protected override void OnMouseUp( MouseEventArgs e )
+ {
+ base.OnMouseUp( e );
+
+ ICalendarSelectableElement hitted = HitTest( e.Location, State == CalendarState.DraggingTimeSelection );
+ CalendarItem hittedItem = hitted as CalendarItem;
+ CalendarDay hittedDay = hitted as CalendarDay;
+ bool shiftPressed = ( ModifierKeys & Keys.Shift ) == Keys.Shift;
+
+ switch( State )
+ {
+ case CalendarState.Idle:
+
+ break;
+ case CalendarState.DraggingTimeSelection:
+ if( SelectedElementStart == null || ( hitted != null && !SelectedElementEnd.Equals( hitted ) ) )
+ {
+ SelectedElementEnd = hitted;
+ }
+ if( hittedDay != null )
+ {
+ if( hittedDay.HeaderBounds.Contains( e.Location ) )
+ {
+ OnDayHeaderClick( new CalendarDayEventArgs( hittedDay ) );
+ }
+ }
+ break;
+ case CalendarState.DraggingItem:
+ if( itemOnStateChanged )
+ OnItemDatesChanged( new CalendarItemEventArgs( itemOnState ) );
+ break;
+ case CalendarState.ResizingItem:
+ if( itemOnStateChanged )
+ OnItemDatesChanged( new CalendarItemEventArgs( itemOnState ) );
+ break;
+ case CalendarState.EditingItemText:
+ break;
+ }
+
+ if( itemOnState != null )
+ {
+ itemOnState.SetIsDragging( false );
+ itemOnState.SetIsResizingEndDate( false );
+ itemOnState.SetIsResizingStartDate( false );
+ Invalidate( itemOnState );
+ OnItemClick( new CalendarItemEventArgs( itemOnState ) );
+ itemOnState = null;
+ }
+ SetState( CalendarState.Idle );
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// A that contains the event data.
+ protected override void OnMouseWheel( MouseEventArgs e )
+ {
+ base.OnMouseWheel( e );
+
+ if( DaysMode == CalendarDaysMode.Expanded )
+ {
+ ScrollTimeUnits( e.Delta );
+ }
+ else if( DaysMode == CalendarDaysMode.Short )
+ {
+ ScrollCalendar( e.Delta );
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// A that contains the event data.
+ protected override void OnPaint( PaintEventArgs e )
+ {
+ base.OnPaint( e );
+
+ CalendarRendererEventArgs evt = new CalendarRendererEventArgs( this, e.Graphics, e.ClipRectangle );
+
+ //Calendar background
+ Renderer.OnDrawBackground( evt );
+
+ // Headers / Timescale
+ switch( DaysMode )
+ {
+ case CalendarDaysMode.Short:
+ Renderer.OnDrawDayNameHeaders( evt );
+ Renderer.OnDrawWeekHeaders( evt );
+ break;
+ case CalendarDaysMode.Expanded:
+ Renderer.OnDrawTimeScale( evt );
+ break;
+ default:
+ throw new NotImplementedException( "Current DaysMode not implemented" );
+ }
+
+ //Days on view
+ Renderer.OnDrawDays( evt );
+
+ //Items
+ Renderer.OnDrawItems( evt );
+
+ //Overflow marks
+ Renderer.OnDrawOverflows( evt );
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// An that contains the event data.
+ protected override void OnResize( EventArgs e )
+ {
+ base.OnResize( e );
+
+ TimeUnitsOffset = TimeUnitsOffset;
+ Renderer.PerformLayout();
+ }
+
+ #endregion
+
+ }
+}
\ No newline at end of file
diff --git a/WindowsFormsCalendar/UserControls/CalendarTextBox.cs b/WindowsFormsCalendar/UserControls/CalendarTextBox.cs
new file mode 100644
index 0000000..3414aac
--- /dev/null
+++ b/WindowsFormsCalendar/UserControls/CalendarTextBox.cs
@@ -0,0 +1,68 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// A text box control used in the calendar
+ ///
+ public class CalendarTextBox
+ : TextBox
+ {
+ #region Fields
+
+ private Calendar _calendar;
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets the calendar where this control lives
+ ///
+ public Calendar Calendar
+ {
+ get { return _calendar; }
+ }
+
+ #endregion
+
+ ///
+ /// Creates a new for the specified
+ ///
+ /// Calendar where this control lives
+ public CalendarTextBox( Calendar calendar )
+ {
+ _calendar = calendar;
+ this.Font = _calendar.ItemsFont;
+ this.ForeColor = _calendar.ItemsForeColor;
+ this.BackColor = _calendar.ItemsBackgroundColor;
+ }
+
+ #region Methods
+ #endregion
+
+ }
+}
\ No newline at end of file
diff --git a/WindowsFormsCalendar/UserControls/MonthView.cs b/WindowsFormsCalendar/UserControls/MonthView.cs
new file mode 100644
index 0000000..ef623c3
--- /dev/null
+++ b/WindowsFormsCalendar/UserControls/MonthView.cs
@@ -0,0 +1,1025 @@
+/*
+ Copyright 2012 Justin LeCheminant
+
+ This file is part of WindowsFormsCalendar.
+
+ indowsFormsCalendar is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ indowsFormsCalendar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with indowsFormsCalendar. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace WindowsFormsCalendar
+{
+ ///
+ /// Hosts a month-level calendar where user can select day-based dates
+ ///
+ [DefaultEvent("SelectionChanged")]
+ public class MonthView
+ : ContainerControl
+ {
+ #region Fields
+ private int _forwardMonthIndex;
+ private MonthViewDay _lastHitted;
+ private bool _mouseDown;
+ private Size _daySize;
+ private DateTime _selectionStart;
+ private DateTime _selectionEnd;
+ private string _monthTitleFormat;
+ private DayOfWeek _weekStart;
+ private DayOfWeek _workWeekStart;
+ private DayOfWeek _workWeekEnd;
+ private MonthViewSelection _selectionMode;
+ private string _dayNamesFormat;
+ private bool _dayNamesVisible;
+ private int _dayNamesLength;
+ private DateTime _viewStart;
+ private Size _monthSize;
+ private MonthViewMonth[] _months;
+ private Padding _itemPadding;
+ private Color _monthTitleColor;
+ private Color _monthTitleColorInactive;
+ private Color _monthTitleTextColor;
+ private Color _monthTitleTextColorInactive;
+ private Color _dayBackgroundColor;
+ private Color _daySelectedBackgroundColor;
+ private Color _dayTextColor;
+ private Color _daySelectedTextColor;
+ private Color _arrowsColor;
+ private Color _arrowsSelectedColor;
+ private Color _dayGrayedText;
+ private Color _todayBorderColor;
+ private int _maxSelectionCount;
+ private Rectangle _forwardButtonBounds;
+ private bool _forwardButtonSelected;
+ private Rectangle _backwardButtonBounds;
+ private bool _backwardButtonSelected;
+ #endregion
+
+ #region Events
+
+ ///
+ /// Occurs when selection has changed.
+ ///
+ public event EventHandler SelectionChanged;
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets the size of days rectangles
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ public Size DaySize
+ {
+ get { return _daySize; }
+ }
+
+ ///
+ /// Gets or sets the format of day names
+ ///
+ [DefaultValue( "ddd" )]
+ public string DayNamesFormat
+ {
+ get { return _dayNamesFormat; }
+ set { _dayNamesFormat = value; }
+ }
+
+ ///
+ /// Gets or sets a value indicating if day names should be visible
+ ///
+ [DefaultValue( true )]
+ public bool DayNamesVisible
+ {
+ get { return _dayNamesVisible; }
+ set { _dayNamesVisible = value; }
+ }
+
+ ///
+ /// Gets or sets how many characters of day names should be displayed
+ ///
+ [DefaultValue( 2 )]
+ public int DayNamesLength
+ {
+ get { return _dayNamesLength; }
+ set { _dayNamesLength = value; UpdateMonths(); }
+ }
+
+ ///
+ /// Gets or sets what the first day of weeks should be
+ ///
+ [DefaultValue( DayOfWeek.Sunday )]
+ public DayOfWeek FirstDayOfWeek
+ {
+ get { return _weekStart; }
+ set { _weekStart = value; }
+ }
+
+ ///
+ /// Gets a value indicating if the backward button is selected
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ public bool BackwardButtonSelected
+ {
+ get { return _backwardButtonSelected; }
+ }
+
+ ///
+ /// Gets the bounds of the backward button
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ public Rectangle BackwardButtonBounds
+ {
+ get { return _backwardButtonBounds; }
+ }
+
+ ///
+ /// Gets a value indicating if the forward button is selected
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ public bool ForwardButtonSelected
+ {
+ get { return _forwardButtonSelected; }
+ }
+
+ ///
+ /// Gets the bounds of the forward button
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ public Rectangle ForwardButtonBounds
+ {
+ get { return _forwardButtonBounds; }
+ }
+
+ ///
+ /// Gets or sets the Font of the Control
+ ///
+ public override Font Font
+ {
+ get
+ {
+ return base.Font;
+ }
+ set
+ {
+ base.Font = value;
+
+ UpdateMonthSize();
+ UpdateMonths();
+ }
+ }
+
+ ///
+ /// Gets or sets the internal padding of items (Days, day names, month names)
+ ///
+ public Padding ItemPadding
+ {
+ get { return _itemPadding; }
+ set { _itemPadding = value; }
+ }
+
+ ///
+ /// Gets or sets the maximum selection count of days
+ ///
+ [DefaultValue( 0 )]
+ public int MaxSelectionCount
+ {
+ get { return _maxSelectionCount; }
+ set { _maxSelectionCount = value; }
+ }
+
+ ///
+ /// Gets the Months currently displayed on the calendar
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ public MonthViewMonth[] Months
+ {
+ get { return _months; }
+ }
+
+ ///
+ /// Gets the size of an entire month inside the
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ public Size MonthSize
+ {
+ get { return _monthSize; }
+ }
+
+ ///
+ /// Gets or sets the format of month titles
+ ///
+ [DefaultValue( "MMMM yyyy" )]
+ public string MonthTitleFormat
+ {
+ get { return _monthTitleFormat; }
+ set { _monthTitleFormat = value; UpdateMonths(); }
+ }
+
+ ///
+ /// Gets or sets the start of selection
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ public DateTime SelectionStart
+ {
+ get { return _selectionStart; }
+ set
+ {
+ if( MaxSelectionCount > 0 )
+ {
+ if( Math.Abs( value.Subtract( SelectionEnd ).TotalDays ) >= MaxSelectionCount )
+ {
+ return;
+ }
+ }
+
+ _selectionStart = value;
+ Invalidate();
+ OnSelectionChanged( EventArgs.Empty );
+ }
+ }
+
+ ///
+ /// Gets or sets the end of selection
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ public DateTime SelectionEnd
+ {
+ get { return _selectionEnd; }
+ set
+ {
+ if( MaxSelectionCount > 0 )
+ {
+ if( Math.Abs( value.Subtract( SelectionStart ).TotalDays ) >= MaxSelectionCount )
+ {
+ return;
+ }
+ }
+
+ _selectionEnd = value.Date.Add( new TimeSpan( 23, 59, 59 ) );
+ Invalidate();
+ OnSelectionChanged( EventArgs.Empty );
+ }
+ }
+
+ ///
+ /// Gets or sets the selection mode of
+ ///
+ [DefaultValue( MonthViewSelection.Manual )]
+ public MonthViewSelection SelectionMode
+ {
+ get { return _selectionMode; }
+ set { _selectionMode = value; }
+ }
+
+ ///
+ /// Gets or sets the date of the first displayed month
+ ///
+ [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
+ public DateTime ViewStart
+ {
+ get { return _viewStart; }
+ set { _viewStart = value; UpdateMonths(); Invalidate(); }
+ }
+
+ ///
+ /// Gets the last day of the last month showed on the view.
+ ///
+ public DateTime ViewEnd
+ {
+ get
+ {
+ DateTime month = Months[Months.Length - 1].Date;
+ return month.Date.AddDays( DateTime.DaysInMonth( month.Year, month.Month ) );
+ }
+ }
+
+ ///
+ /// Gets or sets the day that starts a work-week
+ ///
+ [DefaultValue( DayOfWeek.Monday )]
+ public DayOfWeek WorkWeekStart
+ {
+ get { return _workWeekStart; }
+ set { _workWeekStart = value; }
+ }
+
+ ///
+ /// Gets or sets the day that ends a work-week
+ ///
+ [DefaultValue( DayOfWeek.Friday )]
+ public DayOfWeek WorkWeekEnd
+ {
+ get { return _workWeekEnd; }
+ set { _workWeekEnd = value; }
+ }
+
+ #endregion
+
+ #region Color Properties
+
+ ///
+ /// Gets or sets the color of the arrows selected.
+ ///
+ ///
+ /// The color of the arrows selected.
+ ///
+ public Color ArrowsSelectedColor
+ {
+ get { return _arrowsSelectedColor; }
+ set { _arrowsSelectedColor = value; }
+ }
+
+ ///
+ /// Gets or sets the color of the arrows.
+ ///
+ ///
+ /// The color of the arrows.
+ ///
+ public Color ArrowsColor
+ {
+ get { return _arrowsColor; }
+ set { _arrowsColor = value; }
+ }
+
+ ///
+ /// Gets or sets the color of the day selected text.
+ ///
+ ///
+ /// The color of the day selected text.
+ ///
+ public Color DaySelectedTextColor
+ {
+ get { return _daySelectedTextColor; }
+ set { _daySelectedTextColor = value; }
+ }
+
+ ///
+ /// Gets or sets the color of the day selected.
+ ///
+ ///
+ /// The color of the day selected.
+ ///
+ public Color DaySelectedColor
+ {
+ get { return _dayTextColor; }
+ set { _dayTextColor = value; }
+ }
+
+ ///
+ /// Gets or sets the color of the day selected background.
+ ///
+ ///
+ /// The color of the day selected background.
+ ///
+ public Color DaySelectedBackgroundColor
+ {
+ get { return _daySelectedBackgroundColor; }
+ set { _daySelectedBackgroundColor = value; }
+ }
+
+ ///
+ /// Gets or sets the color of the day background.
+ ///
+ ///
+ /// The color of the day background.
+ ///
+ public Color DayBackgroundColor
+ {
+ get { return _dayBackgroundColor; }
+ set { _dayBackgroundColor = value; }
+ }
+
+ ///
+ /// Gets or sets the day grayed text.
+ ///
+ ///
+ /// The day grayed text.
+ ///
+ public Color DayGrayedText
+ {
+ get { return _dayGrayedText; }
+ set { _dayGrayedText = value; }
+ }
+
+ ///
+ /// Gets or sets the color of the month title.
+ ///
+ ///
+ /// The color of the month title.
+ ///
+ public Color MonthTitleColor
+ {
+ get { return _monthTitleColor; }
+ set { _monthTitleColor = value; }
+ }
+
+ ///
+ /// Gets or sets the month title text color inactive.
+ ///
+ ///
+ /// The month title text color inactive.
+ ///
+ public Color MonthTitleTextColorInactive
+ {
+ get { return _monthTitleTextColorInactive; }
+ set { _monthTitleTextColorInactive = value; }
+ }
+
+ ///
+ /// Gets or sets the color of the month title text.
+ ///
+ ///
+ /// The color of the month title text.
+ ///
+ public Color MonthTitleTextColor
+ {
+ get { return _monthTitleTextColor; }
+ set { _monthTitleTextColor = value; }
+ }
+
+ ///
+ /// Gets or sets the month title color inactive.
+ ///
+ ///
+ /// The month title color inactive.
+ ///
+ public Color MonthTitleColorInactive
+ {
+ get { return _monthTitleColorInactive; }
+ set { _monthTitleColorInactive = value; }
+ }
+
+ ///
+ /// Gets or sets the color of the today day border color
+ ///
+ public Color TodayBorderColor
+ {
+ get { return _todayBorderColor; }
+ set { _todayBorderColor = value; }
+ }
+
+ #endregion
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MonthView()
+ {
+ SetStyle(ControlStyles.Opaque, true);
+ DoubleBuffered = true;
+
+ _dayNamesFormat = "ddd";
+ _monthTitleFormat = "MMMM yyyy";
+ _selectionMode = MonthViewSelection.Manual;
+ _workWeekStart = DayOfWeek.Monday;
+ _workWeekEnd = DayOfWeek.Friday;
+ _weekStart = DayOfWeek.Sunday;
+ _dayNamesVisible = true;
+ _dayNamesLength = 2;
+ _viewStart = DateTime.Now;
+ _itemPadding = new Padding(2);
+ _monthTitleColor = SystemColors.ActiveCaption;
+ _monthTitleColorInactive = SystemColors.InactiveCaption;
+ _monthTitleTextColor = SystemColors.ActiveCaptionText;
+ _monthTitleTextColorInactive = SystemColors.InactiveCaptionText;
+ _dayBackgroundColor = Color.Empty;
+ _daySelectedBackgroundColor = SystemColors.Highlight;
+ _dayTextColor = SystemColors.WindowText;
+ _daySelectedTextColor = SystemColors.HighlightText;
+ _arrowsColor = SystemColors.Window;
+ _arrowsSelectedColor = Color.Gold;
+ _dayGrayedText = SystemColors.GrayText;
+ _todayBorderColor = Color.Maroon;
+
+ UpdateMonthSize();
+ UpdateMonths();
+ }
+
+ #region Public Methods
+
+ ///
+ /// Checks if a day is hitted on the specified point
+ ///
+ ///
+ ///
+ public MonthViewDay HitTest(Point p)
+ {
+ for (int i = 0; i < Months.Length; i++)
+ {
+ if (Months[i].Bounds.Contains(p))
+ {
+ for (int j = 0; j < Months[i].Days.Length; j++)
+ {
+ if (/*Months[i].Days[j].Visible && */Months[i].Days[j].Bounds.Contains(p))
+ {
+ return Months[i].Days[j];
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ ///
+ /// Moves the view one month forward
+ ///
+ public void GoForward()
+ {
+ ViewStart = ViewStart.AddMonths(1);
+ }
+
+ ///
+ /// Moves the view one month backward
+ ///
+ public void GoBackward()
+ {
+ ViewStart = ViewStart.AddMonths(-1);
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ ///
+ /// Sets the forward button bounds.
+ ///
+ /// The bounds.
+ private void SetForwardButtonBounds(Rectangle bounds)
+ {
+ _forwardButtonBounds = bounds;
+ }
+
+ ///
+ /// Sets the backward button bounds.
+ ///
+ /// The bounds.
+ private void SetBackwardButtonBounds(Rectangle bounds)
+ {
+ _backwardButtonBounds = bounds;
+ }
+
+ ///
+ /// Sets the forward button selected.
+ ///
+ /// if set to true [selected].
+ private void SetForwardButtonSelected(bool selected)
+ {
+ _forwardButtonSelected = selected;
+ Invalidate(ForwardButtonBounds);
+ }
+
+ ///
+ /// Sets the backward button selected.
+ ///
+ /// if set to true [selected].
+ private void SetBackwardButtonSelected(bool selected)
+ {
+ _backwardButtonSelected = selected;
+ Invalidate(BackwardButtonBounds);
+ }
+
+ ///
+ /// Selects the week where the hit is contained
+ ///
+ ///
+ private void SelectWeek(DateTime hit)
+ {
+ int preDays = (new int[] { 0, 1, 2, 3, 4, 5, 6 })[(int)hit.DayOfWeek] - (int)FirstDayOfWeek;
+
+ _selectionStart = hit.AddDays(-preDays);
+ SelectionEnd = SelectionStart.AddDays(6);
+ }
+
+ ///
+ /// Selecs the work-week where the hit is contanied
+ ///
+ ///
+ private void SelectWorkWeek(DateTime hit)
+ {
+ int preDays = (new int[] { 0, 1, 2, 3, 4, 5, 6 })[(int)hit.DayOfWeek] - (int)WorkWeekStart;
+
+ _selectionStart = hit.AddDays(-preDays);
+ SelectionEnd = SelectionStart.AddDays(Math.Abs(WorkWeekStart - WorkWeekEnd));
+ }
+
+ ///
+ /// Selecs the month where the hit is contanied
+ ///
+ ///
+ private void SelectMonth(DateTime hit)
+ {
+ _selectionStart = new DateTime(hit.Year, hit.Month, 1);
+ SelectionEnd = new DateTime(hit.Year, hit.Month, DateTime.DaysInMonth(hit.Year, hit.Month));
+ }
+
+ ///
+ /// Draws a box of text
+ ///
+ ///
+ private void DrawBox(MonthViewBoxEventArgs e)
+ {
+ if (!e.BackgroundColor.IsEmpty)
+ {
+ using (SolidBrush b = new SolidBrush(e.BackgroundColor))
+ {
+ e.Graphics.FillRectangle(b, e.Bounds);
+ }
+ }
+
+ if (!e.TextColor.IsEmpty && !string.IsNullOrEmpty(e.Text))
+ {
+ TextRenderer.DrawText(e.Graphics, e.Text, e.Font != null ? e.Font : Font, e.Bounds, e.TextColor, e.TextFlags);
+ }
+
+ if (!e.BorderColor.IsEmpty)
+ {
+ using (Pen p = new Pen(e.BorderColor))
+ {
+ Rectangle r = e.Bounds;
+ r.Width--; r.Height--;
+ e.Graphics.DrawRectangle(p, r);
+ }
+ }
+ }
+
+ ///
+ /// Updates the size of the month.
+ ///
+ private void UpdateMonthSize()
+ {
+ //One row of day names plus 31 possible numbers
+ string[] strs = new string[7 + 31];
+ int maxWidth = 0;
+ int maxHeight = 0;
+
+ for (int i = 0; i < 7; i++)
+ {
+ strs[i] = ViewStart.AddDays(i).ToString(DayNamesFormat).Substring(0, DayNamesLength);
+ }
+
+ for (int i = 7; i < strs.Length; i++)
+ {
+ strs[i] = (i - 6).ToString();
+ }
+
+ Font f = new Font(Font, FontStyle.Bold);
+
+ for (int i = 0; i < strs.Length; i++)
+ {
+ Size s = TextRenderer.MeasureText(strs[i], f);
+ maxWidth = Math.Max(s.Width, maxWidth);
+ maxHeight = Math.Max(s.Height, maxHeight);
+ }
+
+ maxWidth += ItemPadding.Horizontal;
+ maxHeight += ItemPadding.Vertical;
+
+ _daySize = new Size(maxWidth, maxHeight);
+ _monthSize = new Size(maxWidth * 7, maxHeight * 7 + maxHeight * (DayNamesVisible ? 1 : 0));
+ }
+
+ ///
+ /// Updates the months.
+ ///
+ private void UpdateMonths()
+ {
+ int gapping = 2;
+ int calendarsX = Convert.ToInt32(Math.Max(Math.Floor((double)ClientSize.Width / (double)(MonthSize.Width + gapping)), 1.0));
+ int calendarsY = Convert.ToInt32(Math.Max(Math.Floor((double)ClientSize.Height / (double)(MonthSize.Height + gapping)), 1.0));
+ int calendars = calendarsX * calendarsY;
+ int monthsWidth = (calendarsX * MonthSize.Width) + (calendarsX - 1) * gapping;
+ int monthsHeight = (calendarsY * MonthSize.Height) + (calendarsY - 1) * gapping;
+ int startX = (ClientSize.Width - monthsWidth) / 2;
+ int startY = (ClientSize.Height - monthsHeight) / 2;
+ int curX = startX;
+ int curY = startY;
+ _forwardMonthIndex = calendarsX - 1;
+
+ _months = new MonthViewMonth[calendars];
+
+ for (int i = 0; i < Months.Length; i++)
+ {
+ Months[i] = new MonthViewMonth(this, ViewStart.AddMonths(i));
+ Months[i].SetLocation(new Point(curX, curY));
+
+ curX += gapping + MonthSize.Width;
+
+ if ((i + 1) % calendarsX == 0)
+ {
+ curX = startX;
+ curY += gapping + MonthSize.Height;
+ }
+ }
+
+ MonthViewMonth first = Months[0];
+ MonthViewMonth last = Months[_forwardMonthIndex];
+
+ SetBackwardButtonBounds(new Rectangle(first.Bounds.Left + ItemPadding.Left, first.Bounds.Top + ItemPadding.Top, DaySize.Height - ItemPadding.Horizontal, DaySize.Height - ItemPadding.Vertical));
+ SetForwardButtonBounds(new Rectangle(first.Bounds.Right - ItemPadding.Right - BackwardButtonBounds.Width, first.Bounds.Top + ItemPadding.Top, BackwardButtonBounds.Width, BackwardButtonBounds.Height ));
+ }
+
+ #endregion
+
+ #region Overrides
+
+ ///
+ /// Raises the event.
+ ///
+ /// An that contains the event data.
+ protected override void OnGotFocus(EventArgs e)
+ {
+ base.OnGotFocus(e);
+
+ Invalidate();
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// A that contains the event data.
+ protected override void OnMouseDown(MouseEventArgs e)
+ {
+ base.OnMouseDown(e);
+
+ Focus();
+
+ _mouseDown = true;
+
+ MonthViewDay day = HitTest(e.Location);
+
+ if (day != null)
+ {
+ switch (SelectionMode)
+ {
+ case MonthViewSelection.Manual:
+ case MonthViewSelection.Day:
+ SelectionEnd = _selectionStart = day.Date;
+ break;
+ case MonthViewSelection.WorkWeek:
+ SelectWorkWeek(day.Date);
+ break;
+ case MonthViewSelection.Week:
+ SelectWeek(day.Date);
+ break;
+ case MonthViewSelection.Month:
+ SelectMonth(day.Date);
+ break;
+ }
+ }
+
+ if (ForwardButtonSelected)
+ {
+ GoForward();
+ }
+ else if (BackwardButtonSelected)
+ {
+ GoBackward();
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// A that contains the event data.
+ protected override void OnMouseMove(MouseEventArgs e)
+ {
+ base.OnMouseMove(e);
+
+ if (_mouseDown)
+ {
+ MonthViewDay day = HitTest(e.Location);
+
+ if (day != null && day != _lastHitted)
+ {
+ switch (SelectionMode)
+ {
+ case MonthViewSelection.Manual:
+ if (day.Date > SelectionStart)
+ {
+ SelectionEnd = day.Date;
+ }
+ else
+ {
+ SelectionStart = day.Date;
+ }
+ break;
+ case MonthViewSelection.Day:
+ SelectionEnd = _selectionStart = day.Date;
+ break;
+ case MonthViewSelection.WorkWeek:
+ SelectWorkWeek(day.Date);
+ break;
+ case MonthViewSelection.Week:
+ SelectWeek(day.Date);
+ break;
+ case MonthViewSelection.Month:
+ SelectMonth(day.Date);
+ break;
+ }
+
+ _lastHitted = day;
+ }
+ }
+
+ if (ForwardButtonBounds.Contains(e.Location))
+ {
+ SetForwardButtonSelected(true);
+ }
+ else if (ForwardButtonSelected)
+ {
+ SetForwardButtonSelected(false);
+ }
+
+ if (BackwardButtonBounds.Contains(e.Location))
+ {
+ SetBackwardButtonSelected(true);
+ }
+ else if (BackwardButtonSelected)
+ {
+ SetBackwardButtonSelected(false);
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// A that contains the event data.
+ protected override void OnMouseUp(MouseEventArgs e)
+ {
+ base.OnMouseUp(e);
+
+ _mouseDown = false;
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// A that contains the event data.
+ protected override void OnMouseWheel(MouseEventArgs e)
+ {
+ base.OnMouseWheel(e);
+
+ if (e.Delta < 0)
+ {
+ GoForward();
+ }
+ else
+ {
+ GoBackward();
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// An that contains the event data.
+ protected override void OnLostFocus(EventArgs e)
+ {
+ base.OnLostFocus(e);
+
+ Invalidate();
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// A that contains the event data.
+ protected override void OnPaint(PaintEventArgs e)
+ {
+ base.OnPaint(e);
+
+ e.Graphics.Clear(SystemColors.Window);
+
+ for (int i = 0; i < Months.Length; i++)
+ {
+ if (Months[i].Bounds.IntersectsWith(e.ClipRectangle))
+ {
+ #region MonthTitle
+
+ string title = Months[i].Date.ToString(MonthTitleFormat);
+ MonthViewBoxEventArgs evtTitle = new MonthViewBoxEventArgs(e.Graphics, Months[i].MonthNameBounds,
+ title,
+ Focused ? MonthTitleTextColor : MonthTitleTextColorInactive,
+ Focused ? MonthTitleColor : MonthTitleColorInactive);
+
+ DrawBox(evtTitle);
+
+ #endregion
+
+ #region DayNames
+
+ for (int j = 0; j < Months[i].DayNamesBounds.Length; j++)
+ {
+ MonthViewBoxEventArgs evtDay = new MonthViewBoxEventArgs(e.Graphics, Months[i].DayNamesBounds[j], Months[i].DayHeaders[j],
+ StringAlignment.Far, ForeColor, DayBackgroundColor);
+
+ DrawBox(evtDay);
+ }
+
+ if (Months[i].DayNamesBounds != null && Months[i].DayNamesBounds.Length != 0)
+ {
+ using (Pen p = new Pen(MonthTitleColor))
+ {
+ int y = Months[i].DayNamesBounds[0].Bottom;
+ e.Graphics.DrawLine(p, new Point(Months[i].Bounds.X, y), new Point(Months[i].Bounds.Right, y));
+ }
+ }
+ #endregion
+
+ #region Days
+ foreach (MonthViewDay day in Months[i].Days)
+ {
+ if (!day.Visible) continue;
+
+ MonthViewBoxEventArgs evtDay = new MonthViewBoxEventArgs(e.Graphics, day.Bounds, day.Date.Day.ToString(),
+ StringAlignment.Far,
+ day.Grayed ? DayGrayedText : (day.Selected ? DaySelectedTextColor : ForeColor),
+ day.Selected ? DaySelectedBackgroundColor : DayBackgroundColor);
+
+ if (day.Date.Equals(DateTime.Now.Date))
+ {
+ evtDay.BorderColor = TodayBorderColor;
+ }
+
+ DrawBox(evtDay);
+ }
+ #endregion
+
+ #region Arrows
+
+ if (i == 0)
+ {
+ Rectangle r = BackwardButtonBounds;
+ using (Brush b = new SolidBrush(BackwardButtonSelected ? ArrowsSelectedColor : ArrowsColor))
+ {
+ e.Graphics.FillPolygon(b, new Point[] {
+ new Point(r.Right, r.Top),
+ new Point(r.Right, r.Bottom - 1),
+ new Point(r.Left + r.Width / 2, r.Top + r.Height / 2),
+ });
+ }
+ }
+
+ if (i == _forwardMonthIndex)
+ {
+ Rectangle r = ForwardButtonBounds;
+ using (Brush b = new SolidBrush(ForwardButtonSelected ? ArrowsSelectedColor : ArrowsColor))
+ {
+ e.Graphics.FillPolygon(b, new Point[] {
+ new Point(r.X, r.Top),
+ new Point(r.X, r.Bottom - 1),
+ new Point(r.Left + r.Width / 2, r.Top + r.Height / 2),
+ });
+ }
+ }
+
+ #endregion
+ }
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// An that contains the event data.
+ protected override void OnResize(EventArgs e)
+ {
+ UpdateMonths();
+ Invalidate();
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// The instance containing the event data.
+ protected void OnSelectionChanged(EventArgs e)
+ {
+ if (SelectionChanged != null)
+ {
+ SelectionChanged(this, e);
+ }
+ }
+
+ #endregion
+
+ }
+}
+
diff --git a/WindowsFormsCalendar/WindowsFormsCalendar.csproj b/WindowsFormsCalendar/WindowsFormsCalendar.csproj
new file mode 100644
index 0000000..e352a3d
--- /dev/null
+++ b/WindowsFormsCalendar/WindowsFormsCalendar.csproj
@@ -0,0 +1,144 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.50727
+ 2.0
+ {25649F08-3046-4891-ADB8-7EA787B57063}
+ Library
+ Properties
+ WindowsFormsCalendar
+ WindowsFormsCalendar
+ v4.0
+
+
+ 2.0
+
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ bin\Release\WindowsFormsCalendar.XML
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Component
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Component
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Component
+
+
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/WindowsFormsCalendar/help/Documentation.chm b/WindowsFormsCalendar/help/Documentation.chm
new file mode 100644
index 0000000..2f1c308
Binary files /dev/null and b/WindowsFormsCalendar/help/Documentation.chm differ