OSDN Git Service

ToolStripAPIGaugeTest ちょっと手を抜いてた箇所を修正
[opentween/open-tween.git] / OpenTween / ToolStripAPIGauge.cs
1 // OpenTween - Client of Twitter
2 // Copyright (c) 2013 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
3 // All rights reserved.
4 // 
5 // This file is part of OpenTween.
6 // 
7 // This program is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by the Free
9 // Software Foundation; either version 3 of the License, or (at your option)
10 // any later version.
11 // 
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // for more details. 
16 // 
17 // You should have received a copy of the GNU General Public License along
18 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
19 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 // Boston, MA 02110-1301, USA.
21
22 using System;
23 using System.Collections.Generic;
24 using System.Linq;
25 using System.Text;
26 using System.Windows.Forms;
27 using System.Drawing;
28 using System.Windows.Forms.Design;
29 using System.ComponentModel;
30 using OpenTween.Api;
31
32 namespace OpenTween
33 {
34     /// <summary>
35     /// API 実行回数制限に到達するまでの目安を表示する ToolStripItem
36     /// </summary>
37     [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.All)]
38     public class ToolStripAPIGauge : ToolStripButton
39     {
40         public ToolStripAPIGauge()
41             : base()
42         {
43             this.Text = "API ???/???";
44             this.ToolTipText = "API rest ???/???" + Environment.NewLine + "(reset after ??? minutes)";
45
46             this.DisplayStyle = ToolStripItemDisplayStyle.Text;
47         }
48
49         /// <summary>
50         /// ゲージに表示される横棒グラフの幅
51         /// </summary>
52         [DefaultValue(8)]
53         [RefreshProperties(RefreshProperties.Repaint)]
54         public int GaugeHeight
55         {
56             get { return this._GaugeHeight; }
57             set
58             {
59                 this._GaugeHeight = value;
60
61                 this.UpdateGaugeBounds();
62                 this.Invalidate();
63             }
64         }
65         private int _GaugeHeight = 8;
66
67         /// <summary>
68         /// API 実行回数制限の値
69         /// </summary>
70         [Browsable(false)]
71         public ApiLimit ApiLimit
72         {
73             get { return this._ApiLimit; }
74             set
75             {
76                 this._ApiLimit = value;
77
78                 this.UpdateRemainMinutes();
79                 this.UpdateText();
80                 this.UpdateGaugeBounds();
81                 this.Invalidate();
82             }
83         }
84         private ApiLimit _ApiLimit = null;
85
86         [Browsable(false)]
87         [EditorBrowsable(EditorBrowsableState.Never)]
88         public new string Text
89         {
90             get { return base.Text; }
91             set { base.Text = value; }
92         }
93
94         [Browsable(false)]
95         [EditorBrowsable(EditorBrowsableState.Never)]
96         public new string ToolTipText
97         {
98             get { return base.ToolTipText; }
99             set { base.ToolTipText = value; }
100         }
101
102         [DefaultValue(ToolStripItemDisplayStyle.Text)]
103         [RefreshProperties(RefreshProperties.Repaint)]
104         public new ToolStripItemDisplayStyle DisplayStyle
105         {
106             get { return base.DisplayStyle; }
107             set { base.DisplayStyle = value; }
108         }
109
110         protected double remainMinutes = -1;
111
112         protected virtual void UpdateRemainMinutes()
113         {
114             if (this._ApiLimit != null)
115                 this.remainMinutes = (this._ApiLimit.AccessLimitResetDate - DateTime.Now).TotalMinutes;
116             else
117                 this.remainMinutes = -1;
118         }
119
120         protected override void OnPaint(PaintEventArgs e)
121         {
122             var g = e.Graphics;
123
124             if (this.apiGaugeBounds != Rectangle.Empty)
125                 g.FillRectangle(Brushes.LightBlue, this.apiGaugeBounds);
126
127             if (this.timeGaugeBounds != Rectangle.Empty)
128                 g.FillRectangle(Brushes.LightPink, this.timeGaugeBounds);
129
130             base.OnPaint(e);
131         }
132
133         #region from Tween v1.1.0.0
134
135         // The code in this region block is based on code written by the following authors:
136         //   (C) 2010 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
137         //   (C) 2010 Moz (@syo68k)
138
139         internal Rectangle apiGaugeBounds = Rectangle.Empty;
140         internal Rectangle timeGaugeBounds = Rectangle.Empty;
141
142         protected virtual void UpdateGaugeBounds()
143         {
144             if (this._ApiLimit == null || this._GaugeHeight < 1)
145             {
146                 this.apiGaugeBounds = Rectangle.Empty;
147                 this.timeGaugeBounds = Rectangle.Empty;
148                 return;
149             }
150
151             var apiGaugeValue = (double)this._ApiLimit.AccessLimitRemain / this._ApiLimit.AccessLimitCount;
152             this.apiGaugeBounds = new Rectangle(
153                 0,
154                 (this.Height - this._GaugeHeight * 2) / 2,
155                 (int)(this.Width * apiGaugeValue),
156                 this._GaugeHeight
157             );
158
159             var timeGaugeValue = this.remainMinutes >= 60 ? 1.00 : this.remainMinutes / 60;
160             this.timeGaugeBounds = new Rectangle(
161                 0,
162                 this.apiGaugeBounds.Top + this._GaugeHeight,
163                 (int)(this.Width * timeGaugeValue),
164                 this._GaugeHeight
165             );
166         }
167
168         protected virtual void UpdateText()
169         {
170             string remainCountText;
171             string maxCountText;
172             string minuteText;
173
174             if (this._ApiLimit == null)
175             {
176                 remainCountText = "???";
177                 maxCountText = "???";
178                 minuteText = "???";
179             }
180             else
181             {
182                 remainCountText = this._ApiLimit.AccessLimitRemain.ToString();
183                 maxCountText = this._ApiLimit.AccessLimitCount.ToString();
184                 minuteText = Math.Ceiling(this.remainMinutes).ToString();
185             }
186
187             var textFormat = "API {0}/{1}";
188             this.Text = string.Format(textFormat, remainCountText, maxCountText);
189
190             var toolTipTextFormat =
191                 "API rest {0}/{1}" + Environment.NewLine +
192                 "(reset after {2} minutes)";
193
194             this.ToolTipText = String.Format(toolTipTextFormat, remainCountText, maxCountText, minuteText);
195         }
196
197         #endregion
198     }
199 }