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 System.Runtime.InteropServices;
namespace com.andoutomo.kybernetes.view
{
public partial class ClockForm : Form
{
//member
private Pen secondLine;
private Pen minuteLine;
private Pen hourLine;
private Pen oval;
private Pen scale;
private Bitmap canvas;
private int remainSec;
private const int CENTER = 89;
public ClockForm()
{
InitializeComponent();
//指定されなかった時は、ポモドーロ・テクニックに基づき25分とする
this.remainSec = 25*60;
}
public ClockForm(int sec)
:this()
{
this.remainSec = sec;
}
public ClockForm(int sec, string title)
: this(sec)
{
this.Text = title;
}
public ClockForm(string title)
:this()
{
this.Text = title;
}
///
/// フォーム呼び出し時処理です。ペンを用意し、タイマーを動かします。
///
///
///
private void clockForm_Load(object sender, EventArgs e)
{
//位置を自力で真ん中に持ってくる。
this.Location = new Point(this.Owner.Location.X + (this.Owner.Width - this.Width) / 2,
this.Owner.Location.Y + (this.Owner.Height - this.Height) / 2);
canvas = new Bitmap(pictureBox1.Width, pictureBox1.Height);
oval = new Pen(Color.Black, 1f);
secondLine = new Pen(Color.Gray, 2f);
minuteLine = new Pen(Color.Black, 4f);
hourLine = new Pen(Color.Black, 6f);
scale = new Pen(Color.LightGray, 1f);
//Tickするまでタイムラグがあるので、-1しておく
remainSec--;
kyTimer.Interval = 1000;
kyTimer.Start();
}
private void kyTimer_Tick(object sender, EventArgs e)
{
pictureBox1.Image = drawClock(canvas, remainSec);
label1.Text = getDigital(remainSec);
remainSec--;
if (remainSec == -1)
{
secondLine.Color = Color.Red;
minuteLine.Color = Color.Red;
hourLine.Color = Color.Red;
oval.Color = Color.Red;
label1.ForeColor = Color.Red;
}
if (remainSec < 0)
{
if (remainSec % 60 == -1)
{
((BaseForm)Owner).showAlert();
}
}
//10分経ったら強制終了。
if (remainSec < -600)
{
kyTimer.Stop();
}
}
///
/// デジタル部文言を生成します。
///
///
///
private string getDigital(int remainSec)
{
int sec = Math.Abs(remainSec % 60);
int min = Math.Abs((remainSec / 60) % 60);
//Hourバーは12分毎に動かす
int hour = Math.Abs((remainSec / (60 * 60)) % (60 * 60));
return (hour).ToString("00") + ":" + min.ToString("00") + ":" + sec.ToString("00");
}
///
/// 時計部分を生成します。
///
///
private Bitmap drawClock(Bitmap _canvas, int remainSec)
{
int sec = Math.Abs(remainSec % 60);
int min = Math.Abs((remainSec / 60) % 60);
//Hourバーは12分毎に動かす
int hour = (remainSec / (60 * 12)) % (60 * 12);
Graphics g = Graphics.FromImage(_canvas);
g.Clear(Color.Transparent);
//補助線を引く
for (int i = 0; i < 360; i += 30)
{
g.DrawPie(scale, 0, 0, CENTER * 2, CENTER * 2, i, 30);
}
SolidBrush bgColor = new SolidBrush(ClockForm.DefaultBackColor);
g.DrawEllipse(oval, 0, 0, CENTER * 2, CENTER * 2);
g.FillEllipse(bgColor, 10, 10, CENTER * 2 - 20, CENTER * 2 - 20);
//ポジションを計算します。
FloatedPosition center = new FloatedPosition(CENTER, CENTER);
FloatedPosition secPosition = getPosInOval(CENTER, CENTER, 6 * sec, CENTER - 10);
FloatedPosition minPosition = getPosInOval(CENTER, CENTER, 6 * min, CENTER - 30);
FloatedPosition hourPosition = getPosInOval(CENTER, CENTER, 6 * hour, CENTER - 50);
//線を引きます。
g.DrawLine(secondLine, center.xPosition, center.yPosition, secPosition.xPosition, secPosition.yPosition);
g.DrawLine(minuteLine, center.xPosition, center.yPosition, minPosition.xPosition, minPosition.yPosition);
g.DrawLine(hourLine, center.xPosition, center.yPosition, hourPosition.xPosition, hourPosition.yPosition);
g.Dispose();
return _canvas;
}
///
/// 角度と長さから、中心点からの相対位置を求めます。
///
///
///
///
private FloatedPosition getPosInOval(int centerX, int centerY, int degree, int length)
{
double posXInOval = (centerX + Math.Sin(degree * Math.PI / 180) * length);
double posYInOval = (centerY + Math.Cos(degree * Math.PI / 180) * -1 * length);
return new FloatedPosition(posXInOval, posYInOval);
}
private void button1_Click(object sender, EventArgs e)
{
this.Close();
}
}
class FloatedPosition
{
public float xPosition
{
get;
set;
}
public float yPosition
{
get;
set;
}
public FloatedPosition(int x, int y)
{
xPosition = (float)x;
yPosition = (float)y;
}
public FloatedPosition(float x, float y)
{
xPosition = x;
yPosition = y;
}
public FloatedPosition(double x, double y)
{
xPosition = (float)x;
yPosition = (float)y;
}
}
}