OSDN Git Service

Font, Color, Brushインスタンスの管理をThemeManagerクラスに分離
authorKimura Youichi <kim.upsilon@bucyou.net>
Thu, 7 Apr 2022 23:18:50 +0000 (08:18 +0900)
committerKimura Youichi <kim.upsilon@bucyou.net>
Fri, 15 Apr 2022 20:04:53 +0000 (05:04 +0900)
OpenTween/ApplicationEvents.cs
OpenTween/OpenTween.csproj
OpenTween/ThemeManager.cs [new file with mode: 0644]
OpenTween/Tween.cs
OpenTween/TweetDetailsView.cs

index 2c7f134..a25638c 100644 (file)
@@ -70,6 +70,7 @@ namespace OpenTween
             var noLimit = StartupOptions.ContainsKey("nolimit");
             settings.Common.Validate(noLimit);
 
+            ThemeManager.ApplyGlobalUIFont(settings.Local);
             container.CultureService.Initialize();
 
             Networking.Initialize();
index f577c7c..da0ee3d 100644 (file)
     <Compile Include="ApplicationInstanceMutex.cs" />
     <Compile Include="ApplicationPreconditions.cs" />
     <Compile Include="ApplicationSettings.cs" />
+    <Compile Include="ThemeManager.cs" />
     <Compile Include="IconAssetsManager.cs" />
     <Compile Include="AsyncTimer.cs" />
     <Compile Include="AtIdSupplement.cs">
diff --git a/OpenTween/ThemeManager.cs b/OpenTween/ThemeManager.cs
new file mode 100644 (file)
index 0000000..5bccfd4
--- /dev/null
@@ -0,0 +1,180 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2007-2011 kiri_feather (@kiri_feather) <kiri.feather@gmail.com>
+//           (c) 2008-2011 Moz (@syo68k)
+//           (c) 2008-2011 takeshik (@takeshik) <http://www.takeshik.org/>
+//           (c) 2010-2011 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
+//           (c) 2010-2011 fantasticswallow (@f_swallow) <http://twitter.com/f_swallow>
+//           (c) 2011      kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
+// All rights reserved.
+//
+// This file is part of OpenTween.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License
+// for more details.
+//
+// You should have received a copy of the GNU General public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
+// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#nullable enable
+
+using System;
+using System.Drawing;
+
+namespace OpenTween
+{
+    public sealed class ThemeManager : IDisposable
+    {
+        public bool IsDisposed { get; private set; } = false;
+
+        /// <summary>未読用フォント</summary>
+        public Font FontUnread { get; }
+
+        /// <summary>既読用フォント</summary>
+        public Font FontReaded { get; }
+
+        /// <summary>発言詳細部用フォント</summary>
+        public Font FontDetail { get; }
+
+        /// <summary>入力欄フォント</summary>
+        public Font FontInputFont { get; }
+
+        /// <summary>未読用文字色</summary>
+        public Color ColorUnread { get; }
+
+        /// <summary>既読用文字色</summary>
+        public Color ColorRead { get; }
+
+        /// <summary>Fav用文字色</summary>
+        public Color ColorFav { get; }
+
+        /// <summary>片思い用文字色</summary>
+        public Color ColorOWL { get; }
+
+        /// <summary>Retweet用文字色</summary>
+        public Color ColorRetweet { get; }
+
+        /// <summary>選択中の行用文字色</summary>
+        public Color ColorHighLight { get; }
+
+        /// <summary>発言詳細部用色</summary>
+        public Color ColorDetail { get; }
+
+        /// <summary>発言詳細部用リンク文字色</summary>
+        public Color ColorDetailLink { get; }
+
+        /// <summary>発言詳細部用背景色</summary>
+        public Color ColorDetailBackcolor { get; }
+
+        /// <summary>自分の発言用背景色</summary>
+        public Color ColorSelf { get; }
+
+        /// <summary>自分宛返信用背景色</summary>
+        public Color ColorAtSelf { get; }
+
+        /// <summary>選択発言者の他の発言用背景色</summary>
+        public Color ColorTarget { get; }
+
+        /// <summary>選択発言中の返信先用背景色</summary>
+        public Color ColorAtTarget { get; }
+
+        /// <summary>選択発言者への返信発言用背景色</summary>
+        public Color ColorAtFromTarget { get; }
+
+        /// <summary>選択発言の唯一@先</summary>
+        public Color ColorAtTo { get; }
+
+        /// <summary>リスト部通常発言背景色</summary>
+        public Color ColorListBackcolor { get; }
+
+        /// <summary>入力欄背景色</summary>
+        public Color ColorInputBackcolor { get; }
+
+        /// <summary>入力欄文字色</summary>
+        public Color ColorInputFont { get; }
+
+        public Brush BrushSelf { get; }
+
+        public Brush BrushAtSelf { get; }
+
+        public Brush BrushTarget { get; }
+
+        public Brush BrushAtTarget { get; }
+
+        public Brush BrushAtFromTarget { get; }
+
+        public Brush BrushAtTo { get; }
+
+        public Brush BrushListBackcolor { get; }
+
+        public ThemeManager(SettingLocal settingLocal)
+        {
+            this.FontUnread = settingLocal.FontUnread;
+            this.FontReaded = settingLocal.FontRead;
+            this.FontDetail = settingLocal.FontDetail;
+            this.FontInputFont = settingLocal.FontInputFont;
+
+            this.ColorUnread = settingLocal.ColorUnread;
+            this.ColorRead = settingLocal.ColorRead;
+            this.ColorFav = settingLocal.ColorFav;
+            this.ColorOWL = settingLocal.ColorOWL;
+            this.ColorRetweet = settingLocal.ColorRetweet;
+            this.ColorHighLight = Color.FromKnownColor(KnownColor.HighlightText);
+            this.ColorDetail = settingLocal.ColorDetail;
+            this.ColorDetailLink = settingLocal.ColorDetailLink;
+            this.ColorDetailBackcolor = settingLocal.ColorDetailBackcolor;
+            this.ColorSelf = settingLocal.ColorSelf;
+            this.ColorAtSelf = settingLocal.ColorAtSelf;
+            this.ColorTarget = settingLocal.ColorTarget;
+            this.ColorAtTarget = settingLocal.ColorAtTarget;
+            this.ColorAtFromTarget = settingLocal.ColorAtFromTarget;
+            this.ColorAtTo = settingLocal.ColorAtTo;
+            this.ColorListBackcolor = settingLocal.ColorListBackcolor;
+            this.ColorInputBackcolor = settingLocal.ColorInputBackcolor;
+            this.ColorInputFont = settingLocal.ColorInputFont;
+
+            this.BrushSelf = new SolidBrush(this.ColorSelf);
+            this.BrushAtSelf = new SolidBrush(this.ColorAtSelf);
+            this.BrushTarget = new SolidBrush(this.ColorTarget);
+            this.BrushAtTarget = new SolidBrush(this.ColorAtTarget);
+            this.BrushAtFromTarget = new SolidBrush(this.ColorAtFromTarget);
+            this.BrushAtTo = new SolidBrush(this.ColorAtTo);
+            this.BrushListBackcolor = new SolidBrush(this.ColorListBackcolor);
+        }
+
+        public void Dispose()
+        {
+            if (this.IsDisposed)
+                return;
+
+            this.FontUnread.Dispose();
+            this.FontReaded.Dispose();
+            this.FontDetail.Dispose();
+            this.FontInputFont.Dispose();
+            this.BrushSelf.Dispose();
+            this.BrushAtSelf.Dispose();
+            this.BrushTarget.Dispose();
+            this.BrushAtTarget.Dispose();
+            this.BrushAtFromTarget.Dispose();
+            this.BrushAtTo.Dispose();
+            this.BrushListBackcolor.Dispose();
+
+            this.IsDisposed = true;
+        }
+
+        public static void ApplyGlobalUIFont(SettingLocal settingLocal)
+        {
+            var font = settingLocal.FontUIGlobal;
+            if (font != null)
+                OTBaseForm.GlobalFont = font;
+        }
+    }
+}
index f698039..9466c56 100644 (file)
@@ -157,72 +157,7 @@ namespace OpenTween
         public HashtagManage HashMgr = null!;
 
         // 表示フォント、色、アイコン
-
-        /// <summary>未読用フォント</summary>
-        private Font fntUnread = null!;
-
-        /// <summary>未読用文字色</summary>
-        private Color clUnread;
-
-        /// <summary>既読用フォント</summary>
-        private Font fntReaded = null!;
-
-        /// <summary>既読用文字色</summary>
-        private Color clReaded;
-
-        /// <summary>Fav用文字色</summary>
-        private Color clFav;
-
-        /// <summary>片思い用文字色</summary>
-        private Color clOWL;
-
-        /// <summary>Retweet用文字色</summary>
-        private Color clRetweet;
-
-        /// <summary>選択中の行用文字色</summary>
-        private readonly Color clHighLight = Color.FromKnownColor(KnownColor.HighlightText);
-
-        /// <summary>発言詳細部用フォント</summary>
-        private Font fntDetail = null!;
-
-        /// <summary>発言詳細部用色</summary>
-        private Color clDetail;
-
-        /// <summary>発言詳細部用リンク文字色</summary>
-        private Color clDetailLink;
-
-        /// <summary>発言詳細部用背景色</summary>
-        private Color clDetailBackcolor;
-
-        /// <summary>自分の発言用背景色</summary>
-        private Color clSelf;
-
-        /// <summary>自分宛返信用背景色</summary>
-        private Color clAtSelf;
-
-        /// <summary>選択発言者の他の発言用背景色</summary>
-        private Color clTarget;
-
-        /// <summary>選択発言中の返信先用背景色</summary>
-        private Color clAtTarget;
-
-        /// <summary>選択発言者への返信発言用背景色</summary>
-        private Color clAtFromTarget;
-
-        /// <summary>選択発言の唯一@先</summary>
-        private Color clAtTo;
-
-        /// <summary>リスト部通常発言背景色</summary>
-        private Color clListBackcolor;
-
-        /// <summary>入力欄背景色</summary>
-        private Color clInputBackcolor;
-
-        /// <summary>入力欄文字色</summary>
-        private Color clInputFont;
-
-        /// <summary>入力欄フォント</summary>
-        private Font fntInputFont = null!;
+        private ThemeManager themeManager;
 
         /// <summary>アイコン画像リスト</summary>
         private readonly ImageCache iconCache;
@@ -251,13 +186,6 @@ namespace OpenTween
 
         // 以下DrawItem関連
         private readonly SolidBrush brsHighLight = new(Color.FromKnownColor(KnownColor.Highlight));
-        private SolidBrush brsBackColorMine = null!;
-        private SolidBrush brsBackColorAt = null!;
-        private SolidBrush brsBackColorYou = null!;
-        private SolidBrush brsBackColorAtYou = null!;
-        private SolidBrush brsBackColorAtFromTarget = null!;
-        private SolidBrush brsBackColorAtTo = null!;
-        private SolidBrush brsBackColorNone = null!;
 
         /// <summary>Listにフォーカスないときの選択行の背景色</summary>
         private readonly SolidBrush brsDeactiveSelection = new(Color.FromKnownColor(KnownColor.ButtonFace));
@@ -428,13 +356,7 @@ namespace OpenTween
                 this.urlDialog.Dispose();
                 this.listViewImageList.Dispose();
                 this.brsHighLight.Dispose();
-                this.brsBackColorMine?.Dispose();
-                this.brsBackColorAt?.Dispose();
-                this.brsBackColorYou?.Dispose();
-                this.brsBackColorAtYou?.Dispose();
-                this.brsBackColorAtFromTarget?.Dispose();
-                this.brsBackColorAtTo?.Dispose();
-                this.brsBackColorNone?.Dispose();
+                this.themeManager.Dispose();
                 this.brsDeactiveSelection?.Dispose();
                 this.sfTab.Dispose();
 
@@ -636,8 +558,6 @@ namespace OpenTween
 
             this.hookGlobalHotkey = new HookGlobalHotkey(this);
 
-            this.tweetDetailsView.Owner = this;
-
             this.hookGlobalHotkey.HotkeyPressed += this.HookGlobalHotkey_HotkeyPressed;
             this.gh.NotifyClicked += this.GrowlHelper_Callback;
 
@@ -674,14 +594,6 @@ namespace OpenTween
             // 現在の DPI と設定保存時の DPI との比を取得する
             var configScaleFactor = this.settings.Local.GetConfigScaleFactor(this.CurrentAutoScaleDimensions);
 
-            // UIフォント設定
-            var fontUIGlobal = this.settings.Local.FontUIGlobal;
-            if (fontUIGlobal != null)
-            {
-                OTBaseForm.GlobalFont = fontUIGlobal;
-                this.Font = fontUIGlobal;
-            }
-
             // 認証関連
             this.tw.Initialize(this.settings.Common.Token, this.settings.Common.TokenSecret, this.settings.Common.UserName, this.settings.Common.UserId);
 
@@ -747,39 +659,9 @@ namespace OpenTween
                                     this.settings.Common.HashIsNotAddToAtReply);
             if (!MyCommon.IsNullOrEmpty(this.HashMgr.UseHash) && this.HashMgr.IsPermanent) this.HashStripSplitButton.Text = this.HashMgr.UseHash;
 
-            // アイコンリスト作成
-            this.tweetDetailsView.IconCache = this.iconCache;
-
             // フォント&文字色&背景色保持
-            this.fntUnread = this.settings.Local.FontUnread;
-            this.clUnread = this.settings.Local.ColorUnread;
-            this.fntReaded = this.settings.Local.FontRead;
-            this.clReaded = this.settings.Local.ColorRead;
-            this.clFav = this.settings.Local.ColorFav;
-            this.clOWL = this.settings.Local.ColorOWL;
-            this.clRetweet = this.settings.Local.ColorRetweet;
-            this.fntDetail = this.settings.Local.FontDetail;
-            this.clDetail = this.settings.Local.ColorDetail;
-            this.clDetailLink = this.settings.Local.ColorDetailLink;
-            this.clDetailBackcolor = this.settings.Local.ColorDetailBackcolor;
-            this.clSelf = this.settings.Local.ColorSelf;
-            this.clAtSelf = this.settings.Local.ColorAtSelf;
-            this.clTarget = this.settings.Local.ColorTarget;
-            this.clAtTarget = this.settings.Local.ColorAtTarget;
-            this.clAtFromTarget = this.settings.Local.ColorAtFromTarget;
-            this.clAtTo = this.settings.Local.ColorAtTo;
-            this.clListBackcolor = this.settings.Local.ColorListBackcolor;
-            this.clInputBackcolor = this.settings.Local.ColorInputBackcolor;
-            this.clInputFont = this.settings.Local.ColorInputFont;
-            this.fntInputFont = this.settings.Local.FontInputFont;
-
-            this.brsBackColorMine = new SolidBrush(this.clSelf);
-            this.brsBackColorAt = new SolidBrush(this.clAtSelf);
-            this.brsBackColorYou = new SolidBrush(this.clTarget);
-            this.brsBackColorAtYou = new SolidBrush(this.clAtTarget);
-            this.brsBackColorAtFromTarget = new SolidBrush(this.clAtFromTarget);
-            this.brsBackColorAtTo = new SolidBrush(this.clAtTo);
-            this.brsBackColorNone = new SolidBrush(this.clListBackcolor);
+            this.themeManager = new(this.settings.Local);
+            this.tweetDetailsView.Initialize(this, this.iconCache, this.themeManager);
 
             // StringFormatオブジェクトへの事前設定
             this.sfTab.Alignment = StringAlignment.Center;
@@ -850,8 +732,8 @@ namespace OpenTween
             this.PlaySoundMenuItem.Checked = this.settings.Common.PlaySound;
             this.PlaySoundFileMenuItem.Checked = this.settings.Common.PlaySound;
             // 入力欄
-            this.StatusText.Font = this.fntInputFont;
-            this.StatusText.ForeColor = this.clInputFont;
+            this.StatusText.Font = this.themeManager.FontInputFont;
+            this.StatusText.ForeColor = this.themeManager.ColorInputFont;
 
             // SplitContainer2.Panel2MinSize を一行表示の入力欄の高さに合わせる (MS UI Gothic 12pt (96dpi) の場合は 19px)
             this.StatusText.Multiline = false; // this.settings.Local.StatusMultiline の設定は後で反映される
@@ -999,13 +881,16 @@ namespace OpenTween
         {
             var htmlTemplate = this.settings.Common.IsMonospace ? DetailHtmlFormatTemplateMono : DetailHtmlFormatTemplateNormal;
 
+            static string ColorToRGBString(Color color)
+                => $"{color.R},{color.G},{color.B}";
+
             this.detailHtmlFormatPreparedTemplate = htmlTemplate
-                .Replace("%FONT_FAMILY%", this.fntDetail.Name)
-                .Replace("%FONT_SIZE%", this.fntDetail.Size.ToString())
-                .Replace("%FONT_COLOR%", $"{this.clDetail.R},{this.clDetail.G},{this.clDetail.B}")
-                .Replace("%LINK_COLOR%", $"{this.clDetailLink.R},{this.clDetailLink.G},{this.clDetailLink.B}")
-                .Replace("%BG_COLOR%", $"{this.clDetailBackcolor.R},{this.clDetailBackcolor.G},{this.clDetailBackcolor.B}")
-                .Replace("%BG_REPLY_COLOR%", $"{this.clAtTo.R}, {this.clAtTo.G}, {this.clAtTo.B}");
+                .Replace("%FONT_FAMILY%", this.themeManager.FontDetail.Name)
+                .Replace("%FONT_SIZE%", this.themeManager.FontDetail.Size.ToString())
+                .Replace("%FONT_COLOR%", ColorToRGBString(this.themeManager.ColorDetail))
+                .Replace("%LINK_COLOR%", ColorToRGBString(this.themeManager.ColorDetailLink))
+                .Replace("%BG_COLOR%", ColorToRGBString(this.themeManager.ColorDetailBackcolor))
+                .Replace("%BG_REPLY_COLOR%", ColorToRGBString(this.themeManager.ColorAtTo));
         }
 
         private void ListTab_DrawItem(object sender, DrawItemEventArgs e)
@@ -1681,12 +1566,12 @@ namespace OpenTween
             // フォント
             if (read)
             {
-                fnt = this.fntReaded;
+                fnt = this.themeManager.FontReaded;
                 star = "";
             }
             else
             {
-                fnt = this.fntUnread;
+                fnt = this.themeManager.FontUnread;
                 star = "★";
             }
             if (item.SubItems[5].Text != star)
@@ -1695,15 +1580,15 @@ namespace OpenTween
             // 文字色
             Color cl;
             if (post.IsFav)
-                cl = this.clFav;
+                cl = this.themeManager.ColorFav;
             else if (post.RetweetedId != null)
-                cl = this.clRetweet;
+                cl = this.themeManager.ColorRetweet;
             else if (post.IsOwl && (post.IsDm || this.settings.Common.OneWayLove))
-                cl = this.clOWL;
+                cl = this.themeManager.ColorOWL;
             else if (read || !this.settings.Common.UseUnreadStyle)
-                cl = this.clReaded;
+                cl = this.themeManager.ColorRead;
             else
-                cl = this.clUnread;
+                cl = this.themeManager.ColorUnread;
 
             if (dList == null || item.Index == -1)
             {
@@ -1772,25 +1657,25 @@ namespace OpenTween
             Color cl;
             if (targetPost.StatusId == basePost.InReplyToStatusId)
                 // @先
-                cl = this.clAtTo;
+                cl = this.themeManager.ColorAtTo;
             else if (targetPost.IsMe)
                 // 自分=発言者
-                cl = this.clSelf;
+                cl = this.themeManager.ColorSelf;
             else if (targetPost.IsReply)
                 // 自分宛返信
-                cl = this.clAtSelf;
+                cl = this.themeManager.ColorAtSelf;
             else if (basePost.ReplyToList.Any(x => x.UserId == targetPost.UserId))
                 // 返信先
-                cl = this.clAtFromTarget;
+                cl = this.themeManager.ColorAtFromTarget;
             else if (targetPost.ReplyToList.Any(x => x.UserId == basePost.UserId))
                 // その人への返信
-                cl = this.clAtTarget;
+                cl = this.themeManager.ColorAtTarget;
             else if (targetPost.UserId == basePost.UserId)
                 // 発言者
-                cl = this.clTarget;
+                cl = this.themeManager.ColorTarget;
             else
                 // その他
-                cl = this.clListBackcolor;
+                cl = this.themeManager.ColorListBackcolor;
 
             return cl;
         }
@@ -3313,47 +3198,19 @@ namespace OpenTween
                     this.NotifyFileMenuItem.Checked = this.settings.Common.NewAllPop;
                     this.PlaySoundMenuItem.Checked = this.settings.Common.PlaySound;
                     this.PlaySoundFileMenuItem.Checked = this.settings.Common.PlaySound;
-                    this.fntUnread = this.settings.Local.FontUnread;
-                    this.clUnread = this.settings.Local.ColorUnread;
-                    this.fntReaded = this.settings.Local.FontRead;
-                    this.clReaded = this.settings.Local.ColorRead;
-                    this.clFav = this.settings.Local.ColorFav;
-                    this.clOWL = this.settings.Local.ColorOWL;
-                    this.clRetweet = this.settings.Local.ColorRetweet;
-                    this.fntDetail = this.settings.Local.FontDetail;
-                    this.clDetail = this.settings.Local.ColorDetail;
-                    this.clDetailLink = this.settings.Local.ColorDetailLink;
-                    this.clDetailBackcolor = this.settings.Local.ColorDetailBackcolor;
-                    this.clSelf = this.settings.Local.ColorSelf;
-                    this.clAtSelf = this.settings.Local.ColorAtSelf;
-                    this.clTarget = this.settings.Local.ColorTarget;
-                    this.clAtTarget = this.settings.Local.ColorAtTarget;
-                    this.clAtFromTarget = this.settings.Local.ColorAtFromTarget;
-                    this.clAtTo = this.settings.Local.ColorAtTo;
-                    this.clListBackcolor = this.settings.Local.ColorListBackcolor;
-                    this.clInputBackcolor = this.settings.Local.ColorInputBackcolor;
-                    this.clInputFont = this.settings.Local.ColorInputFont;
-                    this.fntInputFont = this.settings.Local.FontInputFont;
-                    this.brsBackColorMine.Dispose();
-                    this.brsBackColorAt.Dispose();
-                    this.brsBackColorYou.Dispose();
-                    this.brsBackColorAtYou.Dispose();
-                    this.brsBackColorAtFromTarget.Dispose();
-                    this.brsBackColorAtTo.Dispose();
-                    this.brsBackColorNone.Dispose();
-                    this.brsBackColorMine = new SolidBrush(this.clSelf);
-                    this.brsBackColorAt = new SolidBrush(this.clAtSelf);
-                    this.brsBackColorYou = new SolidBrush(this.clTarget);
-                    this.brsBackColorAtYou = new SolidBrush(this.clAtTarget);
-                    this.brsBackColorAtFromTarget = new SolidBrush(this.clAtFromTarget);
-                    this.brsBackColorAtTo = new SolidBrush(this.clAtTo);
-                    this.brsBackColorNone = new SolidBrush(this.clListBackcolor);
+
+                    var newTheme = new ThemeManager(this.settings.Local);
+                    (var oldTheme, this.themeManager) = (this.themeManager, newTheme);
+                    this.tweetDetailsView.Theme = this.themeManager;
+                    oldTheme.Dispose();
 
                     try
                     {
-                        if (this.StatusText.Focused) this.StatusText.BackColor = this.clInputBackcolor;
-                        this.StatusText.Font = this.fntInputFont;
-                        this.StatusText.ForeColor = this.clInputFont;
+                        if (this.StatusText.Focused)
+                            this.StatusText.BackColor = this.themeManager.ColorInputBackcolor;
+
+                        this.StatusText.Font = this.themeManager.FontInputFont;
+                        this.StatusText.ForeColor = this.themeManager.ColorInputFont;
                     }
                     catch (Exception ex)
                     {
@@ -3406,8 +3263,8 @@ namespace OpenTween
                             using (ControlTransaction.Update(lst))
                             {
                                 lst.GridLines = this.settings.Common.ShowGrid;
-                                lst.Font = this.fntReaded;
-                                lst.BackColor = this.clListBackcolor;
+                                lst.Font = this.themeManager.FontReaded;
+                                lst.BackColor = this.themeManager.ColorListBackcolor;
 
                                 if (this.iconCol != oldIconCol)
                                     this.ResetColumns(lst);
@@ -3812,8 +3669,8 @@ namespace OpenTween
                 listCustom.View = View.Details;
                 listCustom.OwnerDraw = true;
                 listCustom.VirtualMode = true;
-                listCustom.Font = this.fntReaded;
-                listCustom.BackColor = this.clListBackcolor;
+                listCustom.Font = this.themeManager.FontReaded;
+                listCustom.BackColor = this.themeManager.ColorListBackcolor;
 
                 listCustom.GridLines = this.settings.Common.ShowGrid;
                 listCustom.AllowDrop = true;
@@ -4180,7 +4037,7 @@ namespace OpenTween
             }
             else
             {
-                this.StatusText.ForeColor = this.clInputFont;
+                this.StatusText.ForeColor = this.themeManager.ColorInputFont;
             }
 
             this.StatusText.AccessibleDescription = string.Format(Properties.Resources.StatusText_AccessibleDescription, pLen);
@@ -4586,23 +4443,23 @@ namespace OpenTween
             if (e.State == 0) return;
             e.DrawDefault = false;
 
-            SolidBrush brs2;
+            Brush brs2;
             if (!e.Item.Selected) // e.ItemStateでうまく判定できない???
             {
-                if (e.Item.BackColor == this.clSelf)
-                    brs2 = this.brsBackColorMine;
-                else if (e.Item.BackColor == this.clAtSelf)
-                    brs2 = this.brsBackColorAt;
-                else if (e.Item.BackColor == this.clTarget)
-                    brs2 = this.brsBackColorYou;
-                else if (e.Item.BackColor == this.clAtTarget)
-                    brs2 = this.brsBackColorAtYou;
-                else if (e.Item.BackColor == this.clAtFromTarget)
-                    brs2 = this.brsBackColorAtFromTarget;
-                else if (e.Item.BackColor == this.clAtTo)
-                    brs2 = this.brsBackColorAtTo;
+                if (e.Item.BackColor == this.themeManager.ColorSelf)
+                    brs2 = this.themeManager.BrushSelf;
+                else if (e.Item.BackColor == this.themeManager.ColorAtSelf)
+                    brs2 = this.themeManager.BrushAtSelf;
+                else if (e.Item.BackColor == this.themeManager.ColorTarget)
+                    brs2 = this.themeManager.BrushTarget;
+                else if (e.Item.BackColor == this.themeManager.ColorAtTarget)
+                    brs2 = this.themeManager.BrushAtTarget;
+                else if (e.Item.BackColor == this.themeManager.ColorAtFromTarget)
+                    brs2 = this.themeManager.BrushAtFromTarget;
+                else if (e.Item.BackColor == this.themeManager.ColorAtTo)
+                    brs2 = this.themeManager.BrushAtTo;
                 else
-                    brs2 = this.brsBackColorNone;
+                    brs2 = this.themeManager.BrushListBackcolor;
             }
             else
             {
@@ -4654,8 +4511,8 @@ namespace OpenTween
                 if (rct.Width > 0)
                 {
                     var color = (!e.Item.Selected) ? e.Item.ForeColor : // 選択されていない行
-                        ((Control)sender).Focused ? this.clHighLight : // 選択中の行
-                        this.clUnread;
+                        ((Control)sender).Focused ? this.themeManager.ColorHighLight : // 選択中の行
+                        this.themeManager.ColorUnread;
 
                     if (this.iconCol)
                     {
@@ -6726,14 +6583,11 @@ namespace OpenTween
         {
             // フォーカスの戻り先を StatusText に設定
             this.Tag = this.StatusText;
-            this.StatusText.BackColor = this.clInputBackcolor;
+            this.StatusText.BackColor = this.themeManager.ColorInputBackcolor;
         }
 
         public Color InputBackColor
-        {
-            get => this.clInputBackcolor;
-            set => this.clInputBackcolor = value;
-        }
+            => this.themeManager.ColorInputBackcolor;
 
         private void StatusText_Leave(object sender, EventArgs e)
         {
@@ -6836,28 +6690,6 @@ namespace OpenTween
                 this.settings.Local.StatusMultiline = this.StatusText.Multiline;
                 this.settings.Local.StatusTextHeight = this.mySpDis2;
 
-                this.settings.Local.FontUnread = this.fntUnread;
-                this.settings.Local.ColorUnread = this.clUnread;
-                this.settings.Local.FontRead = this.fntReaded;
-                this.settings.Local.ColorRead = this.clReaded;
-                this.settings.Local.FontDetail = this.fntDetail;
-                this.settings.Local.ColorDetail = this.clDetail;
-                this.settings.Local.ColorDetailBackcolor = this.clDetailBackcolor;
-                this.settings.Local.ColorDetailLink = this.clDetailLink;
-                this.settings.Local.ColorFav = this.clFav;
-                this.settings.Local.ColorOWL = this.clOWL;
-                this.settings.Local.ColorRetweet = this.clRetweet;
-                this.settings.Local.ColorSelf = this.clSelf;
-                this.settings.Local.ColorAtSelf = this.clAtSelf;
-                this.settings.Local.ColorTarget = this.clTarget;
-                this.settings.Local.ColorAtTarget = this.clAtTarget;
-                this.settings.Local.ColorAtFromTarget = this.clAtFromTarget;
-                this.settings.Local.ColorAtTo = this.clAtTo;
-                this.settings.Local.ColorListBackcolor = this.clListBackcolor;
-                this.settings.Local.ColorInputBackcolor = this.clInputBackcolor;
-                this.settings.Local.ColorInputFont = this.clInputFont;
-                this.settings.Local.FontInputFont = this.fntInputFont;
-
                 if (this.ignoreConfigSave) return;
                 this.settings.SaveLocal();
             }
index ccbb9f1..cc0fc08 100644 (file)
@@ -47,10 +47,12 @@ namespace OpenTween
 {
     public partial class TweetDetailsView : UserControl
     {
-        public TweenMain Owner { get; set; } = null!;
+        private TweenMain Owner
+            => this.owner ?? throw this.NotInitializedException();
 
         /// <summary>プロフィール画像のキャッシュ</summary>
-        public ImageCache IconCache { get; set; } = null!;
+        private ImageCache IconCache
+            => this.iconCache ?? throw this.NotInitializedException();
 
         /// <summary><see cref="PostClass"/> のダンプを表示するか</summary>
         public bool DumpPostClass { get; set; }
@@ -58,6 +60,12 @@ namespace OpenTween
         /// <summary>現在表示中の発言</summary>
         public PostClass? CurrentPost { get; private set; }
 
+        public ThemeManager Theme
+        {
+            get => this.themeManager ?? throw this.NotInitializedException();
+            set => this.themeManager = value;
+        }
+
         [DefaultValue(false)]
         public new bool TabStop
         {
@@ -71,6 +79,10 @@ namespace OpenTween
         /// <summary><see cref="ContextMenuPostBrowser"/> 展開時の <see cref="PostBrowser"/>.StatusText を保持するフィールド</summary>
         private string postBrowserStatusText = "";
 
+        private TweenMain? owner;
+        private ImageCache? iconCache;
+        private ThemeManager? themeManager;
+
         public TweetDetailsView()
         {
             this.InitializeComponent();
@@ -87,6 +99,16 @@ namespace OpenTween
             this.PostBrowser.AllowWebBrowserDrop = false;  // COMException を回避するため、ActiveX の初期化が終わってから設定する
         }
 
+        public void Initialize(TweenMain owner, ImageCache iconCache, ThemeManager themeManager)
+        {
+            this.owner = owner;
+            this.iconCache = iconCache;
+            this.themeManager = themeManager;
+        }
+
+        private Exception NotInitializedException()
+            => new InvalidOperationException("Cannot call before initialization");
+
         public void ClearPostBrowser()
             => this.PostBrowser.DocumentText = this.Owner.CreateDetailHtml("");
 
@@ -129,11 +151,11 @@ namespace OpenTween
 
                 var nameForeColor = SystemColors.ControlText;
                 if (post.IsOwl && (SettingManager.Instance.Common.OneWayLove || post.IsDm))
-                    nameForeColor = SettingManager.Instance.Local.ColorOWL;
+                    nameForeColor = this.Theme.ColorOWL;
                 if (post.RetweetedId != null)
-                    nameForeColor = SettingManager.Instance.Local.ColorRetweet;
+                    nameForeColor = this.Theme.ColorRetweet;
                 if (post.IsFav)
-                    nameForeColor = SettingManager.Instance.Local.ColorFav;
+                    nameForeColor = this.Theme.ColorFav;
 
                 this.AuthorNameLinkLabel.LinkColor = nameForeColor;
                 this.AuthorNameLinkLabel.ActiveLinkColor = nameForeColor;
@@ -219,9 +241,9 @@ namespace OpenTween
             if (tags.Count > 0)
             {
                 if (forward)
-                    tags[0].ScrollTop += SettingManager.Instance.Local.FontDetail.Height;
+                    tags[0].ScrollTop += this.Theme.FontDetail.Height;
                 else
-                    tags[0].ScrollTop -= SettingManager.Instance.Local.FontDetail.Height;
+                    tags[0].ScrollTop -= this.Theme.FontDetail.Height;
             }
         }
 
@@ -234,9 +256,9 @@ namespace OpenTween
             if (tags.Count > 0)
             {
                 if (forward)
-                    tags[0].ScrollTop += this.PostBrowser.ClientRectangle.Height - SettingManager.Instance.Local.FontDetail.Height;
+                    tags[0].ScrollTop += this.PostBrowser.ClientRectangle.Height - this.Theme.FontDetail.Height;
                 else
-                    tags[0].ScrollTop -= this.PostBrowser.ClientRectangle.Height - SettingManager.Instance.Local.FontDetail.Height;
+                    tags[0].ScrollTop -= this.PostBrowser.ClientRectangle.Height - this.Theme.FontDetail.Height;
             }
         }