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.Threading;
31 using System.Threading.Tasks;
32 using System.Windows.Forms;
37 /// OpenTween で使用する全てのフォームの基底となるクラス
39 public class OTBaseForm : Form
42 /// 全てのフォームで共通して使用する UI フォント
45 /// SettingLocal.xml に FontUIGlobalStr 要素を追加する事で変更できます
47 public static Font? GlobalFont { get; set; }
50 /// デザイン時のスケールと現在のスケールの比
53 /// 例えば、デザイン時が 96 dpi (96.0, 96.0) で実行時が 120dpi (120.0, 120.0) の場合は 1.25, 1.25 が返ります
55 public SizeF CurrentScaleFactor { get; private set; }
57 private readonly SynchronizationContext synchronizationContext;
59 protected OTBaseForm()
61 this.CurrentScaleFactor = new SizeF(1.0f, 1.0f);
62 this.synchronizationContext = SynchronizationContext.Current;
64 this.Load += (o, e) =>
67 if (OTBaseForm.GlobalFont != null)
68 this.Font = OTBaseForm.GlobalFont;
72 public Task InvokeAsync(Action x)
73 => this.InvokeAsync(new Func<int>(() => { x(); return 0; }));
75 public Task InvokeAsync(Func<Task> x)
76 => this.InvokeAsync<Task>(x).Unwrap();
78 public Task<T> InvokeAsync<T>(Func<Task<T>> x)
79 => this.InvokeAsync<Task<T>>(x).Unwrap();
82 /// <see cref="Control.Invoke"/> メソッドのTask版みたいなやつ
84 public Task<T> InvokeAsync<T>(Func<T> x)
86 var tcs = new TaskCompletionSource<T>();
87 this.synchronizationContext.Post(_ =>
104 /// source で指定されたフォントのスタイルを維持しつつ GlobalFont に置き換えた Font を返します
106 protected Font ReplaceToGlobalFont(Font source)
108 if (OTBaseForm.GlobalFont == null)
111 return new Font(OTBaseForm.GlobalFont.Name, source.Size, source.Style);
114 protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
116 base.ScaleControl(factor, specified);
118 const float baseDpi = 96.0f;
120 this.CurrentScaleFactor = new SizeF(
121 this.CurrentAutoScaleDimensions.Width / baseDpi,
122 this.CurrentAutoScaleDimensions.Height / baseDpi);
126 /// 標準の ListView のスケーリングでは不十分な処理を補います
128 public static void ScaleChildControl(ListView listview, SizeF factor)
131 foreach (ColumnHeader col in listview.Columns)
133 col.Width = ScaleBy(factor.Width, col.Width);
138 /// 標準の VScrollBar のスケーリングでは不十分な処理を補います
140 public static void ScaleChildControl(VScrollBar scrollBar, SizeF factor)
141 => scrollBar.Width = ScaleBy(factor.Width, scrollBar.Width);
144 /// 標準の ImageList のスケーリングでは不十分な処理を補います
146 public static void ScaleChildControl(ImageList imageList, SizeF factor)
147 => imageList.ImageSize = ScaleBy(factor, imageList.ImageSize);
149 public static Size ScaleBy(SizeF factor, Size size)
150 => Size.Round(new SizeF(size.Width * factor.Width, size.Height * factor.Height));
152 public static int ScaleBy(float factor, int size)
153 => (int)Math.Round(size * factor);