diff --git a/SourceGen/AppSettings.cs b/SourceGen/AppSettings.cs index 3d8b53f..8d06140 100644 --- a/SourceGen/AppSettings.cs +++ b/SourceGen/AppSettings.cs @@ -69,9 +69,10 @@ namespace SourceGen { public const string CLIP_LINE_FORMAT = "clip-line-format"; - // Main project view settings. public const string PRVW_RECENT_PROJECT_LIST = "prvw-recent-project-list"; + public const string SKIN_DARK_COLOR_SCHEME = "skin-dark-color-scheme"; + // Symbol-list window options. public const string SYMWIN_SHOW_USER = "symwin-show-user"; public const string SYMWIN_SHOW_AUTO = "symwin-show-auto"; diff --git a/SourceGen/LineListGen.cs b/SourceGen/LineListGen.cs index 724dd9b..8c273e0 100644 --- a/SourceGen/LineListGen.cs +++ b/SourceGen/LineListGen.cs @@ -28,6 +28,11 @@ namespace SourceGen { /// Converts file data and Anattrib contents into a series of strings and format metadata. /// public class LineListGen { + /// + /// Color multiplier for Notes. + /// + public float NoteColorMultiplier { get; set; } = 1.0f; + /// /// List of display lines. /// @@ -815,7 +820,7 @@ namespace SourceGen { out MultiLineComment headerComment)) { List formatted = headerComment.FormatText(formatter, string.Empty); StringListToLines(formatted, Line.HEADER_COMMENT_OFFSET, Line.Type.LongComment, - CommonWPF.Helper.ZeroColor, tmpLines); + CommonWPF.Helper.ZeroColor, 1.0f, tmpLines); } // Format symbols. @@ -920,12 +925,12 @@ namespace SourceGen { if (mProject.Notes.TryGetValue(offset, out MultiLineComment noteData)) { List formatted = noteData.FormatText(mFormatter, "NOTE: "); StringListToLines(formatted, offset, Line.Type.Note, - noteData.BackgroundColor, lines); + noteData.BackgroundColor, NoteColorMultiplier, lines); } if (mProject.LongComments.TryGetValue(offset, out MultiLineComment longComment)) { List formatted = longComment.FormatText(mFormatter, string.Empty); StringListToLines(formatted, offset, Line.Type.LongComment, - longComment.BackgroundColor, lines); + longComment.BackgroundColor, NoteColorMultiplier, lines); } // Local variable tables come next. Defer rendering. @@ -1115,10 +1120,11 @@ namespace SourceGen { /// Background color (for Notes). /// Line list to add data to. private static void StringListToLines(List list, int offset, Line.Type lineType, - Color color, List lines) { + Color color, float mult, List lines) { foreach (string str in list) { Line line = new Line(offset, 0, lineType); - FormattedParts parts = FormattedParts.CreateNote(str, color); + FormattedParts parts = FormattedParts.CreateNote(str, + Color.Multiply(color, mult)); line.Parts = parts; line.BackgroundColor = color; lines.Add(line); diff --git a/SourceGen/MainController.cs b/SourceGen/MainController.cs index dfd842a..8f508dd 100644 --- a/SourceGen/MainController.cs +++ b/SourceGen/MainController.cs @@ -162,6 +162,11 @@ namespace SourceGen { /// private int mTargetHighlightIndex = -1; + /// + /// Code list color scheme. + /// + private MainWindow.ColorScheme mColorScheme = MainWindow.ColorScheme.Light; + /// /// CPU definition used when the Formatter was created. If the CPU choice or /// inclusion of undocumented opcodes changes, we need to wipe the formatter. @@ -517,6 +522,18 @@ namespace SourceGen { // Unpack the recent-project list. UnpackRecentProjectList(); + // Set the color scheme. + bool useDark = settings.GetBool(AppSettings.SKIN_DARK_COLOR_SCHEME, false); + if (useDark) { + mColorScheme = MainWindow.ColorScheme.Dark; + } else { + mColorScheme = MainWindow.ColorScheme.Light; + } + mMainWin.SetColorScheme(mColorScheme); + if (CodeLineList != null) { + SetCodeLineListColorMultiplier(); + } + // Enable the DEBUG menu if configured. mMainWin.ShowDebugMenu = AppSettings.Global.GetBool(AppSettings.DEBUG_MENU_ENABLED, false); @@ -531,6 +548,14 @@ namespace SourceGen { } } + private void SetCodeLineListColorMultiplier() { + if (mColorScheme == MainWindow.ColorScheme.Dark) { + CodeLineList.NoteColorMultiplier = 0.6f; + } else { + CodeLineList.NoteColorMultiplier = 1.0f; + } + } + private void UnpackRecentProjectList() { RecentProjectPaths.Clear(); @@ -670,6 +695,7 @@ namespace SourceGen { private void FinishPrep() { CodeLineList = new LineListGen(mProject, mMainWin.CodeDisplayList, mOutputFormatter, mPseudoOpNames); + SetCodeLineListColorMultiplier(); string messages = mProject.LoadExternalFiles(); if (messages.Length != 0) { diff --git a/SourceGen/Res/Theme_Dark.xaml b/SourceGen/Res/Theme_Dark.xaml new file mode 100644 index 0000000..a0a44df --- /dev/null +++ b/SourceGen/Res/Theme_Dark.xaml @@ -0,0 +1,51 @@ + + + + + + + + + #FF787D7F + #FF6A787F + #FF6C7A7F + #FF4D6E7D + #FF777777 + #FF6E6E6E + #FF757C7F + #FF64767E + + #FF6C7F7A + #FF4D7D6E + + + + + + + + + + + + diff --git a/SourceGen/Res/Theme_Light.xaml b/SourceGen/Res/Theme_Light.xaml new file mode 100644 index 0000000..86ceb88 --- /dev/null +++ b/SourceGen/Res/Theme_Light.xaml @@ -0,0 +1,44 @@ + + + + + + + + + #FFF1FBFF + #FFD5F1FE + #FFD9F4FF + #FF9BDDFB + #FFEEEDED + #FFDDDDDD + #FFEAF9FF + #FFC9EDFD + + #FFD9FFF4 + #FF9BFBDD + + + + + + + + + diff --git a/SourceGen/RuntimeData/Help/settings.html b/SourceGen/RuntimeData/Help/settings.html index 2922187..744d1a1 100644 --- a/SourceGen/RuntimeData/Help/settings.html +++ b/SourceGen/RuntimeData/Help/settings.html @@ -65,6 +65,14 @@ hex data in the code list "bytes" column from dense (20edfd) to spaced (20 ed fd). This also affects the format of clipboard copies and exports.

+

Check "use 'dark' color scheme" to change the main disassembly list +to use white text on a black background, and mute the Note highlight +colors. +(Most of the GUI uses standard Windows controls that take their colors +from the system theme, but the disassembly list uses a custom style. You +can change the rest of the UI from the Windows display "personalization" +controls.)

+

Text Delimiters

diff --git a/SourceGen/SourceGen.csproj b/SourceGen/SourceGen.csproj index d5fd7ef..61dd22b 100644 --- a/SourceGen/SourceGen.csproj +++ b/SourceGen/SourceGen.csproj @@ -237,6 +237,14 @@ + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/SourceGen/WpfGui/CodeListItemStyle.xaml b/SourceGen/WpfGui/CodeListItemStyle.xaml index 299bbc9..422ffed 100644 --- a/SourceGen/WpfGui/CodeListItemStyle.xaml +++ b/SourceGen/WpfGui/CodeListItemStyle.xaml @@ -15,8 +15,8 @@ limitations under the License. --> - - + + - - + + - - + + - - + + @@ -263,7 +263,7 @@ See also https://github.com/fadden/DisasmUiTest - + diff --git a/SourceGen/WpfGui/EditAppSettings.xaml b/SourceGen/WpfGui/EditAppSettings.xaml index ee40568..c67de58 100644 --- a/SourceGen/WpfGui/EditAppSettings.xaml +++ b/SourceGen/WpfGui/EditAppSettings.xaml @@ -129,8 +129,10 @@ limitations under the License. - + diff --git a/SourceGen/WpfGui/EditAppSettings.xaml.cs b/SourceGen/WpfGui/EditAppSettings.xaml.cs index 7eaf3f5..6b5d36c 100644 --- a/SourceGen/WpfGui/EditAppSettings.xaml.cs +++ b/SourceGen/WpfGui/EditAppSettings.xaml.cs @@ -414,6 +414,15 @@ namespace SourceGen.WpfGui { } } + public bool DarkColorScheme { + get { return mSettings.GetBool(AppSettings.SKIN_DARK_COLOR_SCHEME, false); } + set { + mSettings.SetBool(AppSettings.SKIN_DARK_COLOR_SCHEME, value); + OnPropertyChanged(); + IsDirty = true; + } + } + public bool EnableDebugMenu { get { return mSettings.GetBool(AppSettings.DEBUG_MENU_ENABLED, false); } set { diff --git a/SourceGen/WpfGui/MainWindow.xaml b/SourceGen/WpfGui/MainWindow.xaml index 8c40748..f131d92 100644 --- a/SourceGen/WpfGui/MainWindow.xaml +++ b/SourceGen/WpfGui/MainWindow.xaml @@ -33,10 +33,10 @@ limitations under the License. - - + + diff --git a/SourceGen/WpfGui/MainWindow.xaml.cs b/SourceGen/WpfGui/MainWindow.xaml.cs index 5a5869c..63518b2 100644 --- a/SourceGen/WpfGui/MainWindow.xaml.cs +++ b/SourceGen/WpfGui/MainWindow.xaml.cs @@ -157,6 +157,12 @@ namespace SourceGen.WpfGui { // Handle to protected ListView.SetSelectedItems() method private MethodInfo listViewSetSelectedItems; + // Color theme. + public enum ColorScheme { Unknown = 0, Light, Dark }; + private ColorScheme mColorScheme; + private ResourceDictionary mLightTheme; + private ResourceDictionary mDarkTheme; + public MainWindow() { Debug.WriteLine("START at " + DateTime.Now.ToLocalTime()); @@ -173,6 +179,16 @@ namespace SourceGen.WpfGui { this.DataContext = this; + mLightTheme = new ResourceDictionary() { + Source = new Uri("/Res/Theme_Light.xaml", UriKind.Relative) + }; + mDarkTheme = new ResourceDictionary() { + Source = new Uri("/Res/Theme_Dark.xaml", UriKind.Relative) + }; + Resources.MergedDictionaries.Add(mLightTheme); + mColorScheme = ColorScheme.Light; + + CodeDisplayList = new DisplayList(); codeListView.ItemsSource = CodeDisplayList; // https://dlaa.me/blog/post/9425496 to re-auto-size after data added (this may @@ -421,6 +437,38 @@ namespace SourceGen.WpfGui { } } + /// + /// Sets the primary color scheme. + /// + /// + /// H/T http://www.markodevcic.com/post/changing_wpf_themes_dynamically + /// + public void SetColorScheme(ColorScheme newScheme) { + if (mColorScheme == newScheme) { + // nothing to do + return; + } + + ResourceDictionary oldDict, newDict; + + if (mColorScheme == ColorScheme.Light) { + oldDict = mLightTheme; + } else { + oldDict = mDarkTheme; + } + if (newScheme == ColorScheme.Light) { + newDict = mLightTheme; + } else { + newDict = mDarkTheme; + } + Debug.WriteLine("Changing color scheme from " + mColorScheme + " to " + newScheme + + " (dict count=" + Resources.MergedDictionaries.Count + ")"); + + Resources.MergedDictionaries.Remove(oldDict); + Resources.MergedDictionaries.Add(newDict); + mColorScheme = newScheme; + } + #region Window placement //