OSDN Git Service

TweenMain.ListTab.SelectedTabへの参照をCurrentTabPageに置き換える
[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 : ToolStripStatusLabel
39     {
40         public ToolStripAPIGauge()
41         {
42             UpdateText();
43
44             this.DisplayStyle = ToolStripItemDisplayStyle.Text;
45         }
46
47         /// <summary>
48         /// ゲージに表示される横棒グラフの幅
49         /// </summary>
50         [DefaultValue(8)]
51         [RefreshProperties(RefreshProperties.Repaint)]
52         public int GaugeHeight
53         {
54             get => this._GaugeHeight;
55             set
56             {
57                 this._GaugeHeight = value;
58
59                 this.UpdateGaugeBounds();
60                 this.Invalidate();
61             }
62         }
63         private int _GaugeHeight = 8;
64
65         /// <summary>
66         /// API 実行回数制限の値
67         /// </summary>
68         [Browsable(false)]
69         public ApiLimit ApiLimit
70         {
71             get => this._ApiLimit;
72             private set
73             {
74                 this._ApiLimit = value;
75
76                 this.UpdateRemainMinutes();
77                 this.UpdateText();
78                 this.UpdateGaugeBounds();
79                 this.Invalidate();
80             }
81         }
82         private ApiLimit _ApiLimit = null;
83
84         /// <summary>
85         /// API エンドポイント名
86         /// </summary>
87         [Browsable(false)]
88         public string ApiEndpoint
89         {
90             get => this._ApiEndpoint;
91             set
92             {
93                 if (string.IsNullOrEmpty(value))
94                 {
95                     // リセット
96                     this._ApiEndpoint = null;
97                     this.ApiLimit = null;
98                     return;
99                 }
100
101                 var apiLimit = MyCommon.TwitterApiInfo.AccessLimit[value];
102
103                 if (this._ApiEndpoint != value)
104                 {
105                     // ApiEndpointが変更されているので更新する
106                     this._ApiEndpoint = value;
107                     this.ApiLimit = apiLimit;
108                 }
109                 else
110                 {
111                     // ApiLimitが変更されていれば更新する
112                     if (this._ApiLimit == null ||
113                         !this._ApiLimit.Equals(apiLimit))
114                     {
115                         this.ApiLimit = apiLimit;
116                     }
117                 }
118             }
119         }
120         private string _ApiEndpoint = null;
121
122         [Browsable(false)]
123         [EditorBrowsable(EditorBrowsableState.Never)]
124         public new string Text
125         {
126             get => base.Text;
127             set => base.Text = value;
128         }
129
130         [Browsable(false)]
131         [EditorBrowsable(EditorBrowsableState.Never)]
132         public new string ToolTipText
133         {
134             get => base.ToolTipText;
135             set => base.ToolTipText = value;
136         }
137
138         [DefaultValue(ToolStripItemDisplayStyle.Text)]
139         [RefreshProperties(RefreshProperties.Repaint)]
140         public new ToolStripItemDisplayStyle DisplayStyle
141         {
142             get => base.DisplayStyle;
143             set => base.DisplayStyle = value;
144         }
145
146         protected double remainMinutes = -1;
147
148         protected virtual void UpdateRemainMinutes()
149         {
150             if (this._ApiLimit != null)
151                 this.remainMinutes = (this._ApiLimit.AccessLimitResetDate - DateTimeUtc.Now).TotalMinutes;
152             else
153                 this.remainMinutes = -1;
154         }
155
156         protected override void OnPaint(PaintEventArgs e)
157         {
158             var g = e.Graphics;
159
160             if (this.apiGaugeBounds != Rectangle.Empty)
161                 g.FillRectangle(Brushes.LightBlue, this.apiGaugeBounds);
162
163             if (this.timeGaugeBounds != Rectangle.Empty)
164                 g.FillRectangle(Brushes.LightPink, this.timeGaugeBounds);
165
166             base.OnPaint(e);
167         }
168
169         #region from Tween v1.1.0.0
170
171         // The code in this region block is based on code written by the following authors:
172         //   (C) 2010 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
173         //   (C) 2010 Moz (@syo68k)
174
175         internal Rectangle apiGaugeBounds = Rectangle.Empty;
176         internal Rectangle timeGaugeBounds = Rectangle.Empty;
177
178         protected virtual void UpdateGaugeBounds()
179         {
180             if (this._ApiLimit == null || this._GaugeHeight < 1)
181             {
182                 this.apiGaugeBounds = Rectangle.Empty;
183                 this.timeGaugeBounds = Rectangle.Empty;
184                 return;
185             }
186
187             var apiGaugeValue = (double)this._ApiLimit.AccessLimitRemain / this._ApiLimit.AccessLimitCount;
188             this.apiGaugeBounds = new Rectangle(
189                 0,
190                 (this.Height - this._GaugeHeight * 2) / 2,
191                 (int)(this.Width * apiGaugeValue),
192                 this._GaugeHeight
193             );
194
195             var timeGaugeValue = this.remainMinutes >= 15 ? 1.00 : this.remainMinutes / 15;
196             this.timeGaugeBounds = new Rectangle(
197                 0,
198                 this.apiGaugeBounds.Top + this._GaugeHeight,
199                 (int)(this.Width * timeGaugeValue),
200                 this._GaugeHeight
201             );
202         }
203
204         protected virtual void UpdateText()
205         {
206             string remainCountText;
207             string maxCountText;
208             string minuteText;
209
210             if (this._ApiLimit == null || this.remainMinutes < 0)
211             {
212                 remainCountText = "???";
213                 maxCountText = "???";
214                 minuteText = "???";
215             }
216             else
217             {
218                 remainCountText = this._ApiLimit.AccessLimitRemain.ToString();
219                 maxCountText = this._ApiLimit.AccessLimitCount.ToString();
220                 minuteText = Math.Ceiling(this.remainMinutes).ToString();
221             }
222
223             var endpointText = string.IsNullOrEmpty(this._ApiEndpoint) ? "unknown" : this._ApiEndpoint;
224
225             var textFormat = "API {0}/{1}";
226             this.Text = string.Format(textFormat, remainCountText, maxCountText);
227
228             var toolTipTextFormat =
229                 "API rest {0} {1}/{2}" + Environment.NewLine +
230                 "(reset after {3} minutes)";
231
232             this.ToolTipText = String.Format(toolTipTextFormat, endpointText, remainCountText, maxCountText, minuteText);
233         }
234
235         #endregion
236     }
237 }