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; } } }