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.
23 using System.Collections.Generic;
24 using System.ComponentModel;
28 using System.Threading;
29 using System.Threading.Tasks;
30 using System.Windows.Forms;
35 /// OpenTween で使用する全てのフォームの基底となるクラス
37 public class OTBaseForm : Form
40 /// 全てのフォームで共通して使用する UI フォント
43 /// SettingLocal.xml に FontUIGlobalStr 要素を追加する事で変更できます
45 public static Font GlobalFont { get; set; }
48 /// デザイン時のスケールと現在のスケールの比
51 /// 例えば、デザイン時が 96 dpi (96.0, 96.0) で実行時が 120dpi (120.0, 120.0) の場合は 1.25, 1.25 が返ります
53 public SizeF CurrentScaleFactor { get; private set; }
55 private readonly SynchronizationContext synchronizationContext;
57 protected OTBaseForm()
59 this.CurrentScaleFactor = new SizeF(1.0f, 1.0f);
60 this.synchronizationContext = SynchronizationContext.Current;
62 this.Load += (o, e) =>
65 if (OTBaseForm.GlobalFont != null)
66 this.Font = OTBaseForm.GlobalFont;
70 public Task InvokeAsync(Action x)
71 => this.InvokeAsync(new Func<int>(() => { x(); return 0; }));
73 public Task InvokeAsync(Func<Task> x)
74 => this.InvokeAsync<Task>(x).Unwrap();
76 public Task<T> InvokeAsync<T>(Func<Task<T>> x)
77 => this.InvokeAsync<Task<T>>(x).Unwrap();
80 /// <see cref="Control.Invoke"/> メソッドのTask版みたいなやつ
82 public Task<T> InvokeAsync<T>(Func<T> x)
84 var tcs = new TaskCompletionSource<T>();
85 this.synchronizationContext.Post(_ =>
102 /// source で指定されたフォントのスタイルを維持しつつ GlobalFont に置き換えた Font を返します
104 protected Font ReplaceToGlobalFont(Font source)
106 if (OTBaseForm.GlobalFont == null)
109 return new Font(OTBaseForm.GlobalFont.Name, source.Size, source.Style);
112 protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
114 base.ScaleControl(factor, specified);
116 const float baseDpi = 96.0f;
118 this.CurrentScaleFactor = new SizeF(
119 this.CurrentAutoScaleDimensions.Width / baseDpi,
120 this.CurrentAutoScaleDimensions.Height / baseDpi);
124 /// 標準の ListView のスケーリングでは不十分な処理を補います
126 public static void ScaleChildControl(ListView listview, SizeF factor)
129 foreach (ColumnHeader col in listview.Columns)
131 col.Width = ScaleBy(factor.Width, col.Width);
136 /// 標準の VScrollBar のスケーリングでは不十分な処理を補います
138 public static void ScaleChildControl(VScrollBar scrollBar, SizeF factor)
140 scrollBar.Width = ScaleBy(factor.Width, scrollBar.Width);
144 /// 標準の ImageList のスケーリングでは不十分な処理を補います
146 public static void ScaleChildControl(ImageList imageList, SizeF factor)
148 imageList.ImageSize = ScaleBy(factor, imageList.ImageSize);
151 public static Size ScaleBy(SizeF factor, Size size)
153 return Size.Round(new SizeF(size.Width * factor.Width, size.Height * factor.Height));
156 public static int ScaleBy(float factor, int size)
158 return (int)Math.Round(size * factor);