1 // OpenTween - Client of Twitter
2 // Copyright (c) 2013 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
3 // All rights reserved.
5 // This file is part of OpenTween.
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)
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
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.
25 using System.Collections.Generic;
26 using System.ComponentModel;
30 using System.Windows.Forms;
31 using System.Windows.Forms.Design;
37 /// API 実行回数制限に到達するまでの目安を表示する ToolStripItem
39 [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.All)]
40 public class ToolStripAPIGauge : ToolStripStatusLabel
42 public ToolStripAPIGauge()
46 this.DisplayStyle = ToolStripItemDisplayStyle.Text;
53 [RefreshProperties(RefreshProperties.Repaint)]
54 public int GaugeHeight
56 get => this.gaugeHeight;
59 this.gaugeHeight = value;
61 this.UpdateGaugeBounds();
66 private int gaugeHeight = 8;
72 public ApiLimit? ApiLimit
77 this.apiLimit = value;
79 this.UpdateRemainMinutes();
81 this.UpdateGaugeBounds();
86 private ApiLimit? apiLimit = null;
92 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
93 public string? ApiEndpoint
95 get => this.apiEndpoint;
98 if (MyCommon.IsNullOrEmpty(value))
101 this.apiEndpoint = null;
102 this.ApiLimit = null;
106 var apiLimit = MyCommon.TwitterApiInfo.AccessLimit[value];
108 if (this.apiEndpoint != value)
110 // ApiEndpointが変更されているので更新する
111 this.apiEndpoint = value;
112 this.ApiLimit = apiLimit;
116 // ApiLimitが変更されていれば更新する
117 if (this.apiLimit == null ||
118 !this.apiLimit.Equals(apiLimit))
120 this.ApiLimit = apiLimit;
126 private string? apiEndpoint = null;
129 [EditorBrowsable(EditorBrowsableState.Never)]
130 public new string Text
133 set => base.Text = value;
137 [EditorBrowsable(EditorBrowsableState.Never)]
138 public new string ToolTipText
140 get => base.ToolTipText;
141 set => base.ToolTipText = value;
144 [DefaultValue(ToolStripItemDisplayStyle.Text)]
145 [RefreshProperties(RefreshProperties.Repaint)]
146 public new ToolStripItemDisplayStyle DisplayStyle
148 get => base.DisplayStyle;
149 set => base.DisplayStyle = value;
152 protected double remainMinutes = -1;
154 protected virtual void UpdateRemainMinutes()
156 if (this.apiLimit != null)
157 this.remainMinutes = (this.apiLimit.AccessLimitResetDate - DateTimeUtc.Now).TotalMinutes;
159 this.remainMinutes = -1;
162 protected override void OnPaint(PaintEventArgs e)
166 if (this.ApiGaugeBounds != Rectangle.Empty)
167 g.FillRectangle(Brushes.LightBlue, this.ApiGaugeBounds);
169 if (this.TimeGaugeBounds != Rectangle.Empty)
170 g.FillRectangle(Brushes.LightPink, this.TimeGaugeBounds);
175 #region from Tween v1.1.0.0
177 // The code in this region block is based on code written by the following authors:
178 // (C) 2010 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
179 // (C) 2010 Moz (@syo68k)
181 internal Rectangle ApiGaugeBounds = Rectangle.Empty;
182 internal Rectangle TimeGaugeBounds = Rectangle.Empty;
184 protected virtual void UpdateGaugeBounds()
186 if (this.apiLimit == null || this.gaugeHeight < 1)
188 this.ApiGaugeBounds = Rectangle.Empty;
189 this.TimeGaugeBounds = Rectangle.Empty;
193 var apiGaugeValue = (double)this.apiLimit.AccessLimitRemain / this.apiLimit.AccessLimitCount;
194 this.ApiGaugeBounds = new Rectangle(
196 (this.Height - this.gaugeHeight * 2) / 2,
197 (int)(this.Width * apiGaugeValue),
201 var timeGaugeValue = this.remainMinutes >= 15 ? 1.00 : this.remainMinutes / 15;
202 this.TimeGaugeBounds = new Rectangle(
204 this.ApiGaugeBounds.Top + this.gaugeHeight,
205 (int)(this.Width * timeGaugeValue),
210 protected virtual void UpdateText()
212 string remainCountText;
216 if (this.apiLimit == null || this.remainMinutes < 0)
218 remainCountText = "???";
219 maxCountText = "???";
224 remainCountText = this.apiLimit.AccessLimitRemain.ToString();
225 maxCountText = this.apiLimit.AccessLimitCount.ToString();
226 minuteText = Math.Ceiling(this.remainMinutes).ToString();
229 var endpointText = MyCommon.IsNullOrEmpty(this.apiEndpoint) ? "unknown" : this.apiEndpoint;
231 var textFormat = "API {0}/{1}";
232 this.Text = string.Format(textFormat, remainCountText, maxCountText);
234 var toolTipTextFormat =
235 "API rest {0} {1}/{2}" + Environment.NewLine +
236 "(reset after {3} minutes)";
238 this.ToolTipText = string.Format(toolTipTextFormat, endpointText, remainCountText, maxCountText, minuteText);