// one line to give the program's name and an idea of what it does.
// Copyright (C) 2005 name of Borja Snchez Zamorano
//
// 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 2
// 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, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
using System;
using System.Drawing;
using System.Windows.Forms;
namespace CalWidget{
internal class CalTitle : System.Windows.Forms.Control {
Bitmap _offBmp = null;
System.DateTime firstDate, lastDate;
uint firstDayOfWeek;
int daysByWeek;
int[] limitsh = new int[8];
CalContent cc;
CalendarStyle style;
int width;
Pen pen1;
SolidBrush sb1;
string dateFormatShort = "", dateFormatNormal = "", dateFormatLong = "", dateFormatLong2 = "";
public void DefineContent(CalContent cc)
{
this.cc = cc;
}
public void setWidth(int width)
{
this.width = width;
Repaint2();
}
internal CalTitle()
{
sb1 = new SolidBrush(Color.Empty);
pen1 = new Pen(Color.Empty);
this.Resize += new System.EventHandler(this.CalTitleResize);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.CalTitlePaint);
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserMouse, true);
this.SetStyle(ControlStyles.ResizeRedraw, false);
this.SetStyle(ControlStyles.Opaque, true);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(CalTitleMouseDown);
daysByWeek = 7;
System.Globalization.DateTimeFormatInfo dtfi = new System.Globalization.DateTimeFormatInfo();
firstDayOfWeek = (uint) dtfi.FirstDayOfWeek;
style = CalendarStyle.Week;
}
void CalTitleMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left) {
if (e.Clicks == 2) {
if (style == CalendarStyle.Week) {
for (int i=0; i<=6; i++) {
if ((limitsh[i] <= e.X) && (limitsh[i+1] >= e.X)) {
cc.Date = firstDate.AddDays(i);
Style = CalendarStyle.Day;
cc.Style = CalendarStyle.Day;
UpdateCalendar(true);
OnStyleChanged();
}
}
}
}
}
}
void Repaint2()
{
if ((this.ClientRectangle.Width<1) || (this.ClientRectangle.Height<1)) return;
if ((_offBmp == null) || (_offBmp.Height != this.ClientRectangle.Height) || (_offBmp.Width != this.ClientRectangle.Width)) {
if (_offBmp != null) _offBmp.Dispose();
_offBmp = new Bitmap( this.ClientRectangle.Width, this.ClientRectangle.Height);
}
Graphics _g = Graphics.FromImage( _offBmp );
_g.Clear(Color.White);
if (style == CalendarStyle.Month)
PaintStyleMonth(_g);
else
PaintStyleWeek(_g);
_g.Dispose();
Paint2();
}
void Paint2()
{
if ((_offBmp == null) || (_offBmp.Height != this.ClientRectangle.Height) || (_offBmp.Width != this.ClientRectangle.Width)) {
Repaint2();
return;
}
if ((this.ClientRectangle.Width<1) || (this.ClientRectangle.Height<1)) return;
IntPtr hwnd = new IntPtr();
hwnd = this.Handle;
Graphics drawingSurface = Graphics.FromHwnd(hwnd);
drawingSurface.DrawImage(_offBmp, 0, 0);
drawingSurface.Dispose();
}
void CalTitlePaint(object sender, System.Windows.Forms.PaintEventArgs e)
{
e.Graphics.DrawImage(_offBmp, 0,0);
}
void CalTitleResize(object sender, System.EventArgs e)
{
Repaint2();
}
void DrawFillVGradient(Graphics g_, Rectangle rect1, Color color1, Color color2)
{
System.Int32 r, g, b;
for (int i=0; i<rect1.Height; i++) {
r = color2.R+((((rect1.Height-1)-i)*(color1.R-color2.R))/(rect1.Height-1));
g = color2.G+((((rect1.Height-1)-i)*(color1.G-color2.G))/(rect1.Height-1));
b = color2.B+((((rect1.Height-1)-i)*(color1.B-color2.B))/(rect1.Height-1));
pen1.Color = Color.FromArgb(255, r, g, b);
g_.DrawLine(pen1, rect1.Left, rect1.Top+i, rect1.Right-1, rect1.Top+i);
}
}
int FontWidth(Font font1, string text, int width)
{
int width2 = width + (font1.Height*2);
Bitmap auxBmp = new Bitmap( width2, font1.Height);
Graphics g = Graphics.FromImage( auxBmp );
g.Clear(Color.White);
g.DrawString(text, font1, sb1, 0, 0);
int pos = (width2)-1;
bool find = false;
while ((pos>0) && (!find)) {
for (int y=1; y<font1.Height; y+=3) {
if (auxBmp.GetPixel(pos, y).R != 255) {
find = true;
break;
}
}
pos-=2;
}
g.Dispose();
auxBmp.Dispose();
return pos;
}
string NameDayType(System.DateTime dt, int type)
{
switch (type) {
case 0:
return dt.ToString("%d");
case 1:
return dt.ToString(dateFormatShort);
case 2:
return dt.ToString(dateFormatNormal);
case 3:
return dt.ToString(dateFormatLong);
default:
return dt.ToString(dateFormatLong2);
}
}
int NameDayWidth(System.DateTime dt, int width, Font font1, int max)
{
if (max <= 0) return 0;
int op = max;
string text = NameDayType(dt, max);
while (FontWidth(font1, text, width) > width) {
op--;
text = NameDayType(dt, op);
if (op<=0) return 0;
}
return op;
}
void PaintDays(Graphics g)
{
Font font1 = new Font("Tahoma", 8, FontStyle.Bold);
StringFormat align1 = new StringFormat();
align1.Alignment = StringAlignment.Center;
sb1.Color = Color.FromArgb(255, 0, 0, 0);
g.DrawString(cc.Date.Year.ToString(), font1, sb1, limitsh[0]/2, (16-font1.Height)/2, align1);
System.DateTime dt = firstDate;
int i=0;
int max = 4;
while (dt < lastDate) {
max = NameDayWidth(dt, limitsh[i+1] - (limitsh[i] + 10), font1, max);
i++;
dt = dt.AddDays(1);
}
dt = firstDate;
i=0;
while (dt < lastDate) {
if (dt.ToString("yyyyMMdd") == System.DateTime.Now.ToString("yyyyMMdd")) {
Rectangle rect1 = new Rectangle(limitsh[i]+1, 0,limitsh[i+1] - limitsh[i] - 1,8);
DrawFillVGradient(g, rect1, Color.FromArgb(255, 208, 226, 245), Color.FromArgb(255, 104, 169, 234));
rect1 = new Rectangle(limitsh[i]+1, 7,limitsh[i+1] - limitsh[i] - 1,9);
DrawFillVGradient(g, rect1, Color.FromArgb(255, 104, 169, 234), Color.FromArgb(255, 187, 252, 255));
pen1.Color = Color.FromArgb(255, 102, 147, 192);
g.DrawLine(pen1, limitsh[i]+1, 15, limitsh[i+1], 15);
g.DrawLine(pen1, limitsh[i+1], 0, limitsh[i+1], 15);
sb1.Color = Color.FromArgb(255, 236, 243, 252);
g.FillRectangle(sb1, limitsh[i] + 1, 16, limitsh[i+1]-limitsh[i] - 1, this.ClientRectangle.Height-21);
sb1.Color = Color.FromArgb(255, 0, 0, 0);
}
// NameDayWidth(dt, limitsh[i], limitsh[i+1], font1);
g.DrawString(NameDayType(dt, max), font1, sb1, (limitsh[i]+limitsh[i+1])/2, (16-font1.Height)/2, align1);
i++;
dt = dt.AddDays(1);
}
font1.Dispose();
}
void PaintStyleWeek(Graphics g)
{
if (cc == null) return;
int x;
int max = (style == CalWidget.CalendarStyle.Day)? 1 : daysByWeek;
limitsh[0]= 40;
limitsh[max]= width-1;
for (int i=1;i < max; i++) {
limitsh[i]= (((limitsh[daysByWeek]-40)*i)/daysByWeek)+40;
}
for (int i=1; i<=6; i++) {
x = 255-(i*3);
pen1.Color = Color.FromArgb(255, x, x, x);
g.DrawLine(pen1, 0, i, this.ClientRectangle.Width, i);
g.DrawLine(pen1, 0, 14-i, this.ClientRectangle.Width, 14-i);
}
pen1.Color = Color.FromArgb(255, 234, 234, 234);
g.DrawLine(pen1, 0, 7, this.ClientRectangle.Width, 7);
pen1.Color = Color.FromArgb(255, 203, 203, 203);
for (int i=0;i<=max; i++) {
g.DrawLine(pen1, limitsh[i],0,limitsh[i],this.ClientRectangle.Height-6);
}
pen1.Color = Color.FromArgb(255, 203, 203, 203);
g.DrawLine(pen1, 0, 15, this.ClientRectangle.Width, 15);
pen1.Color = Color.FromArgb(255, 110, 110, 110);
g.DrawLine(pen1, 0, this.ClientRectangle.Height-1, this.ClientRectangle.Width, this.ClientRectangle.Height-1);
g.DrawLine(pen1, 0, this.ClientRectangle.Height-5, this.ClientRectangle.Width, this.ClientRectangle.Height-5);
pen1.Color = Color.FromArgb(255, 206, 206, 206);
for (int i=2; i<=4; i++)
g.DrawLine(pen1, 0, this.ClientRectangle.Height-i, this.ClientRectangle.Width, this.ClientRectangle.Height-i);
PaintDays(g);
}
void PaintStyleMonth(Graphics g)
{
Font font1 = new Font("Tahoma", 8, FontStyle.Bold);
StringFormat align1 = new StringFormat();
align1.Alignment = StringAlignment.Center;
sb1.Color = Color.FromArgb(255, 0, 0, 0);
g.DrawString(cc.Date.ToString("MMMM yyyy"), font1, sb1, this.ClientRectangle.Width/2, (16-font1.Height)/2, align1);
font1.Dispose();
}
public void UpdateCalendar(bool forceUpdate)
{
RecalculateDateLimits(forceUpdate);
Repaint2();
}
void RecalculateDateLimits(bool forceUpdate)
{
if (cc == null) return;
System.DateTime first, last;
switch(style) {
case CalendarStyle.Week:
first = cc.Date.AddDays(0);
for (int i=0; i<7; i++) {
first = cc.Date.AddDays(-i);
if (daysByWeek==5) {
if (first.DayOfWeek == DayOfWeek.Monday)
break;
} else {
if ((uint) first.DayOfWeek == firstDayOfWeek)
break;
}
}
last = first.AddDays(daysByWeek-1);
break;
default:
first = last = cc.Date;
break;
}
last = last.AddDays(1).AddSeconds(-1);
if ( forceUpdate || ((last != lastDate) || (first != firstDate))) {
firstDate = first;
lastDate = last;
RefreshData();
}
}
public uint FirstDayOfWeek {
get {
return firstDayOfWeek;
}
set {
firstDayOfWeek = value;
UpdateCalendar(false);
}
}
public int DaysByWeek {
get {
return daysByWeek;
}
set {
daysByWeek = value;
UpdateCalendar(false);
}
}
public CalendarStyle Style {
get {
return style;
}
set {
style = value;
UpdateCalendar(false);
}
}
void RefreshData()
{
// TODO:
SortData();
}
void SortData()
{
// TODO:
}
protected virtual void OnStyleChanged()
{
if (StyleChanged != null) StyleChanged(this, System.EventArgs.Empty);
}
new public event EventHandler StyleChanged;
public void Translate(string key, string text)
{
switch (key) {
case "DateFormatShort":
dateFormatShort = text;
break;
case "DateFormatNormal":
dateFormatNormal = text;
break;
case "DateFormatLong":
dateFormatLong = text;
break;
case "DateFormatLong2":
dateFormatLong2 = text;
break;
}
}
}
}
|