diff --git a/doc/org.eclipse.cdt.doc.isv/guide/deprecated_API_removals.html b/doc/org.eclipse.cdt.doc.isv/guide/deprecated_API_removals.html index 5ca7c9f71f8..0cc11223002 100644 --- a/doc/org.eclipse.cdt.doc.isv/guide/deprecated_API_removals.html +++ b/doc/org.eclipse.cdt.doc.isv/guide/deprecated_API_removals.html @@ -43,6 +43,7 @@
  • DSF and DSF-GDB API Changes.
  • Partial removal of CDT 3.X project support.
  • Removal of CDT Core Options API.
  • +
  • TM Terminal has major changes to support new color and preference functionality.
  • Planned Removals after June 2022 @@ -228,6 +229,34 @@ See Bug 565154.

    +

    12. TM Terminal has major changes to support new color and preference functionality.

    +

    + The TM Terminal's control (org.eclipse.tm.terminal.control) bundle has a major new version to support numerous API + changes to support features such as new colors, preference sharing and some other code clean-up. +

    + + +

    Future Deletions

    @@ -289,4 +318,4 @@

    - \ No newline at end of file + diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/META-INF/MANIFEST.MF b/terminal/plugins/org.eclipse.tm.terminal.control/META-INF/MANIFEST.MF index 14b8ffa5393..f37c8e4105b 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/META-INF/MANIFEST.MF +++ b/terminal/plugins/org.eclipse.tm.terminal.control/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.tm.terminal.control; singleton:=true -Bundle-Version: 4.6.100.qualifier +Bundle-Version: 5.0.0.qualifier Bundle-Activator: org.eclipse.tm.internal.terminal.control.impl.TerminalPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/build.properties b/terminal/plugins/org.eclipse.tm.terminal.control/build.properties index 4e1b392a770..eb7d53d07b5 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/build.properties +++ b/terminal/plugins/org.eclipse.tm.terminal.control/build.properties @@ -28,7 +28,6 @@ bin.includes = .,\ about.properties,\ icons/,\ HelpContexts.xml,\ - css/,\ about.mappings,\ cdt_logo_icon32.png diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/css/org.eclipse.tm.terminal.stylesheet.dark.css b/terminal/plugins/org.eclipse.tm.terminal.control/css/org.eclipse.tm.terminal.stylesheet.dark.css deleted file mode 100644 index 6b612015089..00000000000 --- a/terminal/plugins/org.eclipse.tm.terminal.control/css/org.eclipse.tm.terminal.stylesheet.dark.css +++ /dev/null @@ -1,15 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014, 2015 vogella GmbH and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * Contributors: - * Lars Vogel - initial API and implementation - ******************************************************************************/ - -IEclipsePreferences#org-eclipse-tm-terminal-control { - preferences: - "TerminalPrefInvertColors=true" -} diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/plugin.properties b/terminal/plugins/org.eclipse.tm.terminal.control/plugin.properties index 6ac4936405a..e3c9236c3f2 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/plugin.properties +++ b/terminal/plugins/org.eclipse.tm.terminal.control/plugin.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2003 - 2018 Wind River Systems, Inc. and others. +# Copyright (c) 2003, 2020 Wind River Systems, Inc. and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 # which accompanies this distribution, and is available at @@ -40,7 +40,10 @@ terminal.command.maximize.name=Maximize Active View or Editor terminal.command.quickaccess.name=Quick Access terminal.preferences.name = Terminal -terminal.font.description = The font for the terminal console. +terminal.font.description = The font for the terminal console. Please also see the Terminal Preference pages for changing colors. terminal.font.label = Terminal Console Font +terminal.views.theme.category.label = Terminal +terminal.views.theme.category.description = Fonts used in the Terminal View. Please also see the Terminal Preference pages for changing colors. + terminal.connectors.name = Terminal Connector Extensions diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/plugin.xml b/terminal/plugins/org.eclipse.tm.terminal.control/plugin.xml index a5ca83d730d..ee9eaaf0a03 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/plugin.xml +++ b/terminal/plugins/org.eclipse.tm.terminal.control/plugin.xml @@ -257,6 +257,7 @@ @@ -264,14 +265,14 @@ %terminal.font.description - + + + %terminal.views.theme.category.description + + - - - - - - + diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/control/impl/TerminalMessages.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/control/impl/TerminalMessages.java index cf95067c05c..2826d00fc31 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/control/impl/TerminalMessages.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/control/impl/TerminalMessages.java @@ -19,6 +19,33 @@ public class TerminalMessages extends NLS { NLS.initializeMessages(TerminalMessages.class.getName(), TerminalMessages.class); } + public static String TerminalColorPresets_EclipseDark; + public static String TerminalColorPresets_EclipseLight; + public static String TerminalColorPresets_TerminalDefaults; + public static String TerminalColorsFieldEditor_Background; + public static String TerminalColorsFieldEditor_Black; + public static String TerminalColorsFieldEditor_Blue; + public static String TerminalColorsFieldEditor_BrightBlack; + public static String TerminalColorsFieldEditor_BrightBlue; + public static String TerminalColorsFieldEditor_BrightCyan; + public static String TerminalColorsFieldEditor_BrightGreen; + public static String TerminalColorsFieldEditor_BrightMagenta; + public static String TerminalColorsFieldEditor_BrightRed; + public static String TerminalColorsFieldEditor_BrightWhite; + public static String TerminalColorsFieldEditor_BrightYellow; + public static String TerminalColorsFieldEditor_Cyan; + public static String TerminalColorsFieldEditor_GeneralColors; + public static String TerminalColorsFieldEditor_Green; + public static String TerminalColorsFieldEditor_LoadPresets; + public static String TerminalColorsFieldEditor_Magenta; + public static String TerminalColorsFieldEditor_PaletteColors; + public static String TerminalColorsFieldEditor_Presets; + public static String TerminalColorsFieldEditor_Red; + public static String TerminalColorsFieldEditor_SelectedText; + public static String TerminalColorsFieldEditor_Selection; + public static String TerminalColorsFieldEditor_TextColor; + public static String TerminalColorsFieldEditor_White; + public static String TerminalColorsFieldEditor_Yellow; public static String TerminalError; public static String SocketError; public static String IOError; diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/control/impl/TerminalMessages.properties b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/control/impl/TerminalMessages.properties index 34492a197cb..7d6366889ea 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/control/impl/TerminalMessages.properties +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/control/impl/TerminalMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2003, 2018 Wind River Systems, Inc. and others. +# Copyright (c) 2003, 2020 Wind River Systems, Inc. and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 # which accompanies this distribution, and is available at @@ -19,7 +19,33 @@ ############################################################################### # NLS_MESSAGEFORMAT_VAR - +TerminalColorPresets_EclipseLight=Eclipse Light +TerminalColorPresets_TerminalDefaults=Terminal Defaults +TerminalColorPresets_EclipseDark=Eclipse Dark +TerminalColorsFieldEditor_Background=Background +TerminalColorsFieldEditor_Black=Black +TerminalColorsFieldEditor_Blue=Blue +TerminalColorsFieldEditor_BrightBlack=Bright Black +TerminalColorsFieldEditor_BrightBlue=Bright Blue +TerminalColorsFieldEditor_BrightCyan=Bright Cyan +TerminalColorsFieldEditor_BrightGreen=Bright Green +TerminalColorsFieldEditor_BrightMagenta=Bright Magenta +TerminalColorsFieldEditor_BrightRed=Bright Red +TerminalColorsFieldEditor_BrightWhite=Bright White +TerminalColorsFieldEditor_BrightYellow=Bright Yellow +TerminalColorsFieldEditor_Cyan=Cyan +TerminalColorsFieldEditor_GeneralColors=General colors +TerminalColorsFieldEditor_Green=Green +TerminalColorsFieldEditor_LoadPresets=Load Presets... +TerminalColorsFieldEditor_Magenta=Magenta +TerminalColorsFieldEditor_PaletteColors=Palette colors +TerminalColorsFieldEditor_Presets=Presets +TerminalColorsFieldEditor_Red=Red +TerminalColorsFieldEditor_SelectedText=Selected text +TerminalColorsFieldEditor_Selection=Selection +TerminalColorsFieldEditor_TextColor=Text color +TerminalColorsFieldEditor_White=White +TerminalColorsFieldEditor_Yellow=Yellow TerminalError = Terminal Error SocketError = Socket Error IOError = IO Error diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/IVT100EmulatorBackend.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/IVT100EmulatorBackend.java index 6e67c970dcc..77f6f428aea 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/IVT100EmulatorBackend.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/IVT100EmulatorBackend.java @@ -13,7 +13,7 @@ *******************************************************************************/ package org.eclipse.tm.internal.terminal.emulator; -import org.eclipse.tm.terminal.model.Style; +import org.eclipse.tm.terminal.model.TerminalStyle; /** * @@ -100,17 +100,17 @@ public interface IVT100EmulatorBackend { */ void deleteLines(int n); - Style getDefaultStyle(); + TerminalStyle getDefaultStyle(); - void setDefaultStyle(Style defaultStyle); + void setDefaultStyle(TerminalStyle defaultStyle); - Style getStyle(); + TerminalStyle getStyle(); /** * Sets the style to be used from now on * @param style */ - void setStyle(Style style); + void setStyle(TerminalStyle style); /** * This method displays a subset of the newly-received text in the Terminal diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100BackendTraceDecorator.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100BackendTraceDecorator.java index 3626f18afc2..1c589c258c3 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100BackendTraceDecorator.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100BackendTraceDecorator.java @@ -15,7 +15,7 @@ package org.eclipse.tm.internal.terminal.emulator; import java.io.PrintStream; -import org.eclipse.tm.terminal.model.Style; +import org.eclipse.tm.terminal.model.TerminalStyle; public class VT100BackendTraceDecorator implements IVT100EmulatorBackend { final IVT100EmulatorBackend fBackend; @@ -102,7 +102,7 @@ public class VT100BackendTraceDecorator implements IVT100EmulatorBackend { } @Override - public Style getDefaultStyle() { + public TerminalStyle getDefaultStyle() { return fBackend.getDefaultStyle(); } @@ -112,7 +112,7 @@ public class VT100BackendTraceDecorator implements IVT100EmulatorBackend { } @Override - public Style getStyle() { + public TerminalStyle getStyle() { return fBackend.getStyle(); } @@ -153,7 +153,7 @@ public class VT100BackendTraceDecorator implements IVT100EmulatorBackend { } @Override - public void setDefaultStyle(Style defaultStyle) { + public void setDefaultStyle(TerminalStyle defaultStyle) { fWriter.println("setDefaultStyle(" + defaultStyle + ")"); //$NON-NLS-1$ //$NON-NLS-2$ fBackend.setDefaultStyle(defaultStyle); } @@ -165,7 +165,7 @@ public class VT100BackendTraceDecorator implements IVT100EmulatorBackend { } @Override - public void setStyle(Style style) { + public void setStyle(TerminalStyle style) { fWriter.println("setStyle(" + style + ")"); //$NON-NLS-1$ //$NON-NLS-2$ fBackend.setStyle(style); } diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100Emulator.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100Emulator.java index 080c26258e7..f6c20042b25 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100Emulator.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100Emulator.java @@ -29,15 +29,14 @@ *******************************************************************************/ package org.eclipse.tm.internal.terminal.emulator; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.BLACK; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.BLUE; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.CYAN; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.GREEN; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.MAGENTA; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.RED; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.WHITE; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.WHITE_FOREGROUND; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.YELLOW; +import static org.eclipse.tm.terminal.model.TerminalColor.BLACK; +import static org.eclipse.tm.terminal.model.TerminalColor.BLUE; +import static org.eclipse.tm.terminal.model.TerminalColor.CYAN; +import static org.eclipse.tm.terminal.model.TerminalColor.GREEN; +import static org.eclipse.tm.terminal.model.TerminalColor.MAGENTA; +import static org.eclipse.tm.terminal.model.TerminalColor.RED; +import static org.eclipse.tm.terminal.model.TerminalColor.WHITE; +import static org.eclipse.tm.terminal.model.TerminalColor.YELLOW; import java.io.IOException; import java.io.Reader; @@ -49,7 +48,7 @@ import org.eclipse.tm.internal.terminal.control.impl.TerminalPlugin; import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector; import org.eclipse.tm.internal.terminal.provisional.api.Logger; import org.eclipse.tm.terminal.model.ITerminalTextData; -import org.eclipse.tm.terminal.model.Style; +import org.eclipse.tm.terminal.model.TerminalStyle; /** * This class processes character data received from the remote host and @@ -170,7 +169,7 @@ public class VT100Emulator implements ControlListener { text = new VT100EmulatorBackend(data); // text.setDimensions(24, 80); - Style style = Style.getStyle("BLACK", "WHITE"); //$NON-NLS-1$ //$NON-NLS-2$ + TerminalStyle style = TerminalStyle.getDefaultStyle(); text.setDefaultStyle(style); text.setStyle(style); } @@ -851,7 +850,7 @@ public class VT100Emulator implements ControlListener { ansiParameters[0].append('0'); } - Style style = text.getStyle(); + TerminalStyle style = text.getStyle(); // There are a non-zero number of ANSI parameters. Process each one in // order. @@ -904,39 +903,39 @@ public class VT100Emulator implements ControlListener { break; case 30: - style = style.setForground(BLACK); + style = style.setForeground(BLACK); break; case 31: - style = style.setForground(RED); + style = style.setForeground(RED); break; case 32: - style = style.setForground(GREEN); + style = style.setForeground(GREEN); break; case 33: - style = style.setForground(YELLOW); + style = style.setForeground(YELLOW); break; case 34: - style = style.setForground(BLUE); + style = style.setForeground(BLUE); break; case 35: - style = style.setForground(MAGENTA); + style = style.setForeground(MAGENTA); break; case 36: - style = style.setForground(CYAN); + style = style.setForeground(CYAN); break; case 37: - style = style.setForground(WHITE_FOREGROUND); + style = style.setForeground(WHITE); break; case 39: //Foreground: Default - style = style.setForground(text.getDefaultStyle().getForground()); + style = style.setForeground(text.getDefaultStyle()); break; case 40: @@ -972,7 +971,7 @@ public class VT100Emulator implements ControlListener { break; case 49: //Background: Default - style = style.setBackground(text.getDefaultStyle().getBackground()); + style = style.setBackground(text.getDefaultStyle()); break; default: diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackend.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackend.java index d66b4bcd32c..959e8e85a2d 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackend.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackend.java @@ -15,7 +15,7 @@ package org.eclipse.tm.internal.terminal.emulator; import org.eclipse.tm.terminal.model.ITerminalTextData; -import org.eclipse.tm.terminal.model.Style; +import org.eclipse.tm.terminal.model.TerminalStyle; /** * @noextend This class is not intended to be subclassed by clients. @@ -87,8 +87,8 @@ public class VT100EmulatorBackend implements IVT100EmulatorBackend { * and next output requires line wrap */ private boolean fWrapPending; private boolean fInsertMode; - private Style fDefaultStyle; - private Style fStyle; + private TerminalStyle fDefaultStyle; + private TerminalStyle fStyle; int fLines; int fColumns; final private ITerminalTextData fTerminal; @@ -161,7 +161,7 @@ public class VT100EmulatorBackend implements IVT100EmulatorBackend { int n = charactersToInsert; for (int col = fColumns - 1; col >= fCursorColumn + n; col--) { char c = fTerminal.getChar(line, col - n); - Style style = fTerminal.getStyle(line, col - n); + TerminalStyle style = fTerminal.getStyle(line, col - n); fTerminal.setChar(line, col, c, style); } int last = Math.min(fCursorColumn + n, fColumns); @@ -246,7 +246,7 @@ public class VT100EmulatorBackend implements IVT100EmulatorBackend { int line = toAbsoluteLine(fCursorLine); for (int col = fCursorColumn + n; col < fColumns; col++) { char c = fTerminal.getChar(line, col); - Style style = fTerminal.getStyle(line, col); + TerminalStyle style = fTerminal.getStyle(line, col); fTerminal.setChar(line, col - n, c, style); } int first = Math.max(fCursorColumn, fColumns - n); @@ -273,21 +273,21 @@ public class VT100EmulatorBackend implements IVT100EmulatorBackend { } @Override - public Style getDefaultStyle() { + public TerminalStyle getDefaultStyle() { synchronized (fTerminal) { return fDefaultStyle; } } @Override - public void setDefaultStyle(Style defaultStyle) { + public void setDefaultStyle(TerminalStyle defaultStyle) { synchronized (fTerminal) { fDefaultStyle = defaultStyle; } } @Override - public Style getStyle() { + public TerminalStyle getStyle() { synchronized (fTerminal) { if (fStyle == null) return fDefaultStyle; @@ -296,7 +296,7 @@ public class VT100EmulatorBackend implements IVT100EmulatorBackend { } @Override - public void setStyle(Style style) { + public void setStyle(TerminalStyle style) { synchronized (fTerminal) { fStyle = style; } diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100TerminalControl.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100TerminalControl.java index ae58e006baf..6271c0d8733 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100TerminalControl.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100TerminalControl.java @@ -52,21 +52,26 @@ import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.net.SocketException; import java.nio.charset.Charset; +import java.util.EnumMap; +import java.util.Map; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.ParameterizedCommand; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.bindings.Binding; import org.eclipse.jface.bindings.keys.KeySequence; import org.eclipse.jface.bindings.keys.KeyStroke; import org.eclipse.jface.bindings.keys.SWTKeySupport; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.DataFormatException; import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.StringConverter; import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.Clipboard; @@ -81,6 +86,7 @@ import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; @@ -98,6 +104,7 @@ import org.eclipse.tm.internal.terminal.control.impl.ITerminalControlForText; import org.eclipse.tm.internal.terminal.control.impl.TerminalMessages; import org.eclipse.tm.internal.terminal.control.impl.TerminalPlugin; import org.eclipse.tm.internal.terminal.preferences.ITerminalConstants; +import org.eclipse.tm.internal.terminal.preferences.TerminalColorPresets; import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector; import org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl; import org.eclipse.tm.internal.terminal.provisional.api.Logger; @@ -108,6 +115,7 @@ import org.eclipse.tm.internal.terminal.textcanvas.TextCanvas; import org.eclipse.tm.internal.terminal.textcanvas.TextLineRenderer; import org.eclipse.tm.terminal.model.ITerminalTextData; import org.eclipse.tm.terminal.model.ITerminalTextDataSnapshot; +import org.eclipse.tm.terminal.model.TerminalColor; import org.eclipse.tm.terminal.model.TerminalTextDataFactory; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.contexts.IContextActivation; @@ -144,7 +152,7 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC private TerminalFocusListener fFocusListener; private ITerminalConnector fConnector; private final ITerminalConnector[] fConnectors; - private final boolean fUseCommonPrefs; + private final IPreferenceStore fPreferenceStore; private boolean connectOnEnterIfClosed = true; PipedInputStream fInputStream; @@ -165,17 +173,8 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC /** * Listens to changes in the preferences */ - private final IPropertyChangeListener fPreferenceListener = event -> { - if (event.getProperty().equals(ITerminalConstants.PREF_BUFFERLINES) - || event.getProperty().equals(ITerminalConstants.PREF_INVERT_COLORS)) { - updatePreferences(); - } - }; - private final IPropertyChangeListener fFontListener = event -> { - if (event.getProperty().equals(ITerminalConstants.FONT_DEFINITION)) { - onTerminalFontChanged(); - } - }; + private final IPropertyChangeListener fPreferenceListener = this::updatePreferences; + private final IPropertyChangeListener fFontListener = this::updateFont; /** * Is protected by synchronize on this @@ -184,12 +183,22 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC private PollingTextCanvasModel fPollingTextCanvasModel; + /** + * Instantiate a Terminal widget. + * @param target Callback for notifying the owner of Terminal state changes. + * @param wndParent The Window parent to embed the Terminal in. + * @param connectors Provided connectors. + * @param preferenceStore If non-null, the Terminal widget will pick up settings + * from the given store. + * @since 3.2 + */ public VT100TerminalControl(ITerminalListener target, Composite wndParent, ITerminalConnector[] connectors) { - this(target, wndParent, connectors, false); + this(target, wndParent, connectors, null); } /** - * Instantiate a Terminal widget. + * Instantiate a Terminal widget using the org.eclipse.tm.terminal.TerminalPreferencePage Preference page's + * default preference store. * @param target Callback for notifying the owner of Terminal state changes. * @param wndParent The Window parent to embed the Terminal in. * @param connectors Provided connectors. @@ -200,8 +209,22 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC */ public VT100TerminalControl(ITerminalListener target, Composite wndParent, ITerminalConnector[] connectors, boolean useCommonPrefs) { + this(target, wndParent, connectors, useCommonPrefs ? TerminalPlugin.getDefault().getPreferenceStore() : null); + } + + /** + * Instantiate a Terminal widget. + * @param target Callback for notifying the owner of Terminal state changes. + * @param wndParent The Window parent to embed the Terminal in. + * @param connectors Provided connectors. + * @param preferenceStore If non-null, the Terminal widget will pick up settings + * from the given store. + * @since 5.0 + */ + public VT100TerminalControl(ITerminalListener target, Composite wndParent, ITerminalConnector[] connectors, + IPreferenceStore preferenceStore) { fConnectors = connectors; - fUseCommonPrefs = useCommonPrefs; + fPreferenceStore = preferenceStore; fTerminalListener = target; fTerminalModel = TerminalTextDataFactory.makeTerminalTextData(); fTerminalModel.setMaxHeight(1000); @@ -373,10 +396,10 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC @Override public void disposeTerminal() { Logger.log("entered."); //$NON-NLS-1$ - if (fUseCommonPrefs) { - TerminalPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(fPreferenceListener); - JFaceResources.getFontRegistry().removeListener(fFontListener); + if (fPreferenceStore != null) { + fPreferenceStore.removePropertyChangeListener(fPreferenceListener); } + JFaceResources.getFontRegistry().removeListener(fFontListener); disconnectTerminal(); fClipboard.dispose(); getTerminalText().dispose(); @@ -642,12 +665,11 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC setupControls(parent); setCommandInputField(fCommandInputField); setupListeners(); - if (fUseCommonPrefs && wasDisposed) { - updatePreferences(); - onTerminalFontChanged(); - TerminalPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(fPreferenceListener); - JFaceResources.getFontRegistry().addListener(fFontListener); + if (fPreferenceStore != null && wasDisposed) { + updatePreferences(null); + fPreferenceStore.addPropertyChangeListener(fPreferenceListener); } + JFaceResources.getFontRegistry().addListener(fFontListener); setupHelp(fWndParent, TerminalPlugin.HELP_VIEW); if (!wasDisposed) { @@ -655,18 +677,58 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC } } - private void updatePreferences() { - int bufferLineLimit = Platform.getPreferencesService().getInt(TerminalPlugin.PLUGIN_ID, - ITerminalConstants.PREF_BUFFERLINES, 0, null); - boolean invert = Platform.getPreferencesService().getBoolean(TerminalPlugin.PLUGIN_ID, - ITerminalConstants.PREF_INVERT_COLORS, false, null); + private void updatePreferences(PropertyChangeEvent unused) { + int bufferLineLimit = fPreferenceStore.getInt(ITerminalConstants.PREF_BUFFERLINES); + boolean invert = fPreferenceStore.getBoolean(ITerminalConstants.PREF_INVERT_COLORS); setBufferLineLimit(bufferLineLimit); setInvertedColors(invert); + onTerminalColorsChanged(); + onTerminalFontChanged(); + } + + private void onTerminalColorsChanged() { + Map map = new EnumMap<>(TerminalColor.class); + TerminalColor[] values = TerminalColor.values(); + for (TerminalColor terminalColor : values) { + RGB rgb = null; + if (fPreferenceStore != null) { + try { + rgb = StringConverter.asRGB( + fPreferenceStore.getString(ITerminalConstants.getPrefForTerminalColor(terminalColor))); + } catch (DataFormatException dfe) { + // bad color, use default preset value instead + } + } + + if (rgb == null) { + rgb = TerminalColorPresets.INSTANCE.getDefaultPreset().getRGB(terminalColor); + } + map.put(terminalColor, rgb); + } + fCtlText.updateColors(map); + } + + private String getFontDefinition() { + String definition; + if (fPreferenceStore != null) { + definition = fPreferenceStore.getString(ITerminalConstants.PREF_FONT_DEFINITION); + } else { + definition = ITerminalConstants.DEFAULT_FONT_DEFINITION; + } + if (definition == null || definition.isEmpty()) { + definition = "org.eclipse.jface.textfont"; //$NON-NLS-1$ + } + return definition; } private void onTerminalFontChanged() { - // set the font for all - setFont(ITerminalConstants.FONT_DEFINITION); + setFont(getFontDefinition()); + } + + private void updateFont(PropertyChangeEvent event) { + if (event.getProperty().equals(getFontDefinition())) { + onTerminalFontChanged(); + } } @Override diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/SynchronizedTerminalTextData.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/SynchronizedTerminalTextData.java index c99d01a4a7a..54f637a78ab 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/SynchronizedTerminalTextData.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/SynchronizedTerminalTextData.java @@ -14,7 +14,7 @@ package org.eclipse.tm.internal.terminal.model; import org.eclipse.tm.terminal.model.ITerminalTextData; import org.eclipse.tm.terminal.model.ITerminalTextDataSnapshot; import org.eclipse.tm.terminal.model.LineSegment; -import org.eclipse.tm.terminal.model.Style; +import org.eclipse.tm.terminal.model.TerminalStyle; /** * This is a decorator to make all access to @@ -89,12 +89,12 @@ public class SynchronizedTerminalTextData implements ITerminalTextData { } @Override - synchronized public Style getStyle(int line, int column) { + synchronized public TerminalStyle getStyle(int line, int column) { return fData.getStyle(line, column); } @Override - synchronized public Style[] getStyles(int line) { + synchronized public TerminalStyle[] getStyles(int line) { return fData.getStyles(line); } @@ -114,17 +114,17 @@ public class SynchronizedTerminalTextData implements ITerminalTextData { } @Override - synchronized public void setChar(int line, int column, char c, Style style) { + synchronized public void setChar(int line, int column, char c, TerminalStyle style) { fData.setChar(line, column, c, style); } @Override - synchronized public void setChars(int line, int column, char[] chars, int start, int len, Style style) { + synchronized public void setChars(int line, int column, char[] chars, int start, int len, TerminalStyle style) { fData.setChars(line, column, chars, start, len, style); } @Override - synchronized public void setChars(int line, int column, char[] chars, Style style) { + synchronized public void setChars(int line, int column, char[] chars, TerminalStyle style) { fData.setChars(line, column, chars, style); } diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/SystemDefaultColors.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/SystemDefaultColors.java new file mode 100644 index 00000000000..930a97a1e73 --- /dev/null +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/SystemDefaultColors.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2020 Kichwa Coders Canada Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.tm.internal.terminal.model; + +import java.util.function.Supplier; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.ui.preferences.ScopedPreferenceStore; +import org.eclipse.ui.themes.ColorUtil; + +/** + * Wrapper class to get standard colors from Eclipse trying to match existing theme where possible + * by using standard editor colors. + * + * This class has an implied and optional dependency on org.eclipse.ui.editors bundle by reading + * that bundles preferences. + */ +public enum SystemDefaultColors implements Supplier { + + /** + * Standard text foreground. Typically black in Light theme. + */ + FOREGROUND("Foreground", "COLOR_LIST_FOREGROUND", new RGB(0, 0, 0)), //$NON-NLS-1$ //$NON-NLS-2$ + + /** + * Standard text background. Typically white in Light theme. + */ + BACKGROUND("Background", "COLOR_LIST_BACKGROUND", new RGB(255, 255, 255)), //$NON-NLS-1$ //$NON-NLS-2$ + + /** + * Selection foreground. Typically white in Light theme. + */ + SELECTION_FOREGROUND("SelectionForeground", "COLOR_LIST_SELECTION_TEXT", //$NON-NLS-1$ //$NON-NLS-2$ + new RGB(255, 255, 255)), + + /** + * Selection background. Typically blue in Light theme. + */ + SELECTION_BACKGROUND("SelectionBackground", "COLOR_LIST_SELECTION", new RGB(74, 144, 9)); //$NON-NLS-1$ //$NON-NLS-2$ + + private static final String EDITOR_SCOPE = "org.eclipse.ui.editors"; //$NON-NLS-1$ + private static final String PREF_PREFIX = "AbstractTextEditor.Color."; //$NON-NLS-1$ + private static final String PREF_SYSTEM_DEFAULT_SUFFIX = ".SystemDefault"; //$NON-NLS-1$ + + /** + * SWT Name of Color + * + * Values from SWT + */ + private String swtColor; + + /** + * Preference name for color. + * + * Values from org.eclipse.ui.texteditor.AbstractTextEditor.... + */ + private String editorColor; + + /** If all else fails, use this standard color */ + private RGB fallbackColor; + + SystemDefaultColors(String editorColor, String swtColor, RGB rgb) { + this.editorColor = editorColor; + this.swtColor = swtColor; + this.fallbackColor = rgb; + } + + /** + * Get the color for this enum value. + * + * @return the RGB color or a non-null color as a fallback. + */ + @Override + public RGB get() { + IPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, EDITOR_SCOPE); + + RGB rgb = null; + String pref = PREF_PREFIX + editorColor; + String prefSystemDefault = pref + PREF_SYSTEM_DEFAULT_SUFFIX; + if (Platform.getPreferencesService() != null) { + if (!store.getBoolean(prefSystemDefault)) { + if (store.contains(pref)) { + if (store.isDefault(pref)) + rgb = PreferenceConverter.getDefaultColor(store, pref); + else { + rgb = PreferenceConverter.getColor(store, pref); + } + } + } + } + + if (rgb == null) { + rgb = ColorUtil.getColorValue(swtColor); + } + + if (rgb == null) { + rgb = fallbackColor; + } + + return rgb; + } +} \ No newline at end of file diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextData.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextData.java index 409e6bc63ee..9e6cf40f9d1 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextData.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextData.java @@ -22,7 +22,7 @@ import org.eclipse.tm.terminal.model.ITerminalTextData; import org.eclipse.tm.terminal.model.ITerminalTextDataReadOnly; import org.eclipse.tm.terminal.model.ITerminalTextDataSnapshot; import org.eclipse.tm.terminal.model.LineSegment; -import org.eclipse.tm.terminal.model.Style; +import org.eclipse.tm.terminal.model.TerminalStyle; /** * This class is thread safe. @@ -136,24 +136,24 @@ public class TerminalTextData implements ITerminalTextData { } @Override - public Style getStyle(int line, int column) { + public TerminalStyle getStyle(int line, int column) { return fData.getStyle(line, column); } @Override - public void setChar(int line, int column, char c, Style style) { + public void setChar(int line, int column, char c, TerminalStyle style) { fData.setChar(line, column, c, style); sendLineChangedToSnapshots(line); } @Override - public void setChars(int line, int column, char[] chars, Style style) { + public void setChars(int line, int column, char[] chars, TerminalStyle style) { fData.setChars(line, column, chars, style); sendLineChangedToSnapshots(line); } @Override - public void setChars(int line, int column, char[] chars, int start, int len, Style style) { + public void setChars(int line, int column, char[] chars, int start, int len, TerminalStyle style) { fData.setChars(line, column, chars, start, len, style); sendLineChangedToSnapshots(line); } @@ -279,7 +279,7 @@ public class TerminalTextData implements ITerminalTextData { } @Override - public Style[] getStyles(int line) { + public TerminalStyle[] getStyles(int line) { return fData.getStyles(line); } diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataFastScroll.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataFastScroll.java index 8cb0bd3cad5..519fad0a3e1 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataFastScroll.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataFastScroll.java @@ -14,7 +14,7 @@ package org.eclipse.tm.internal.terminal.model; import org.eclipse.tm.terminal.model.ITerminalTextData; import org.eclipse.tm.terminal.model.ITerminalTextDataSnapshot; import org.eclipse.tm.terminal.model.LineSegment; -import org.eclipse.tm.terminal.model.Style; +import org.eclipse.tm.terminal.model.TerminalStyle; /** * This class is optimized for scrolling the entire {@link #getHeight()}. @@ -151,13 +151,13 @@ public class TerminalTextDataFastScroll implements ITerminalTextData { } @Override - public Style getStyle(int line, int column) { + public TerminalStyle getStyle(int line, int column) { assert (line >= 0 && line < fHeight) || throwRuntimeException(); return fData.getStyle(getPositionOfLine(line), column); } @Override - public Style[] getStyles(int line) { + public TerminalStyle[] getStyles(int line) { assert (line >= 0 && line < fHeight) || throwRuntimeException(); return fData.getStyles(getPositionOfLine(line)); } @@ -214,19 +214,19 @@ public class TerminalTextDataFastScroll implements ITerminalTextData { } @Override - public void setChar(int line, int column, char c, Style style) { + public void setChar(int line, int column, char c, TerminalStyle style) { assert (line >= 0 && line < fHeight) || throwRuntimeException(); fData.setChar(getPositionOfLine(line), column, c, style); } @Override - public void setChars(int line, int column, char[] chars, int start, int len, Style style) { + public void setChars(int line, int column, char[] chars, int start, int len, TerminalStyle style) { assert (line >= 0 && line < fHeight) || throwRuntimeException(); fData.setChars(getPositionOfLine(line), column, chars, start, len, style); } @Override - public void setChars(int line, int column, char[] chars, Style style) { + public void setChars(int line, int column, char[] chars, TerminalStyle style) { assert (line >= 0 && line < fHeight) || throwRuntimeException(); fData.setChars(getPositionOfLine(line), column, chars, style); } diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataSnapshot.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataSnapshot.java index 7d3d5a7f88e..26a6982c871 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataSnapshot.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataSnapshot.java @@ -18,7 +18,7 @@ import java.util.List; import org.eclipse.tm.terminal.model.ITerminalTextData; import org.eclipse.tm.terminal.model.ITerminalTextDataSnapshot; import org.eclipse.tm.terminal.model.LineSegment; -import org.eclipse.tm.terminal.model.Style; +import org.eclipse.tm.terminal.model.TerminalStyle; /** * The public methods of this class have to be called from one thread! @@ -137,7 +137,7 @@ class TerminalTextDataSnapshot implements ITerminalTextDataSnapshot { } @Override - public Style getStyle(int line, int column) { + public TerminalStyle getStyle(int line, int column) { return fSnapshot.getStyle(line, column); } @@ -299,7 +299,7 @@ class TerminalTextDataSnapshot implements ITerminalTextDataSnapshot { } @Override - public Style[] getStyles(int line) { + public TerminalStyle[] getStyles(int line) { return fSnapshot.getStyles(line); } diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataStore.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataStore.java index 2ab5b22025a..f0472aba928 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataStore.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataStore.java @@ -19,7 +19,7 @@ import java.util.List; import org.eclipse.tm.terminal.model.ITerminalTextData; import org.eclipse.tm.terminal.model.ITerminalTextDataSnapshot; import org.eclipse.tm.terminal.model.LineSegment; -import org.eclipse.tm.terminal.model.Style; +import org.eclipse.tm.terminal.model.TerminalStyle; /** * This class is thread safe. @@ -27,7 +27,7 @@ import org.eclipse.tm.terminal.model.Style; */ public class TerminalTextDataStore implements ITerminalTextData { private char[][] fChars; - private Style[][] fStyle; + private TerminalStyle[][] fStyle; private int fWidth; private int fHeight; private int fMaxHeight; @@ -37,7 +37,7 @@ public class TerminalTextDataStore implements ITerminalTextData { public TerminalTextDataStore() { fChars = new char[0][]; - fStyle = new Style[0][]; + fStyle = new TerminalStyle[0][]; fWidth = 0; } @@ -69,7 +69,7 @@ public class TerminalTextDataStore implements ITerminalTextData { int h = 4 * height / 3; if (fMaxHeight > 0 && h > fMaxHeight) h = fMaxHeight; - fStyle = (Style[][]) resizeArray(fStyle, height); + fStyle = (TerminalStyle[][]) resizeArray(fStyle, height); fChars = (char[][]) resizeArray(fChars, height); } // clean the new lines @@ -106,16 +106,16 @@ public class TerminalTextDataStore implements ITerminalTextData { @Override public LineSegment[] getLineSegments(int line, int column, int len) { // get the styles and chars for this line - Style[] styles = fStyle[line]; + TerminalStyle[] styles = fStyle[line]; char[] chars = fChars[line]; int col = column; int n = column + len; // expand the line if needed.... if (styles == null) - styles = new Style[n]; + styles = new TerminalStyle[n]; else if (styles.length < n) - styles = (Style[]) resizeArray(styles, n); + styles = (TerminalStyle[]) resizeArray(styles, n); if (chars == null) chars = new char[n]; @@ -123,7 +123,7 @@ public class TerminalTextDataStore implements ITerminalTextData { chars = (char[]) resizeArray(chars, n); // and create the line segments - Style style = styles[column]; + TerminalStyle style = styles[column]; List segments = new ArrayList<>(); for (int i = column; i < n; i++) { if (styles[i] != style) { @@ -147,7 +147,7 @@ public class TerminalTextDataStore implements ITerminalTextData { } @Override - public Style getStyle(int line, int column) { + public TerminalStyle getStyle(int line, int column) { assert column < fWidth || throwRuntimeException(); if (fStyle[line] == null || column >= fStyle[line].length) return null; @@ -163,26 +163,26 @@ public class TerminalTextDataStore implements ITerminalTextData { fChars[iLine] = (char[]) resizeArray(fChars[iLine], length); } if (fStyle[iLine] == null) { - fStyle[iLine] = new Style[length]; + fStyle[iLine] = new TerminalStyle[length]; } else if (fStyle[iLine].length < length) { - fStyle[iLine] = (Style[]) resizeArray(fStyle[iLine], length); + fStyle[iLine] = (TerminalStyle[]) resizeArray(fStyle[iLine], length); } } @Override - public void setChar(int line, int column, char c, Style style) { + public void setChar(int line, int column, char c, TerminalStyle style) { ensureLineLength(line, column + 1); fChars[line][column] = c; fStyle[line][column] = style; } @Override - public void setChars(int line, int column, char[] chars, Style style) { + public void setChars(int line, int column, char[] chars, TerminalStyle style) { setChars(line, column, chars, 0, chars.length, style); } @Override - public void setChars(int line, int column, char[] chars, int start, int len, Style style) { + public void setChars(int line, int column, char[] chars, int start, int len, TerminalStyle style) { ensureLineLength(line, column + len); for (int i = 0; i < len; i++) { fChars[line][column + i] = chars[i + start]; @@ -262,7 +262,7 @@ public class TerminalTextDataStore implements ITerminalTextData { int n = source.getHeight(); if (getHeight() != n) { fChars = new char[n][]; - fStyle = new Style[n][]; + fStyle = new TerminalStyle[n][]; } for (int i = 0; i < n; i++) { copyLine(source, i, i); @@ -294,13 +294,13 @@ public class TerminalTextDataStore implements ITerminalTextData { } @Override - public Style[] getStyles(int line) { + public TerminalStyle[] getStyles(int line) { if (fStyle[line] == null) return null; return fStyle[line].clone(); } - public void setLine(int line, char[] chars, Style[] styles) { + public void setLine(int line, char[] chars, TerminalStyle[] styles) { fChars[line] = chars.clone(); fStyle[line] = styles.clone(); fWrappedLines.clear(line); diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataWindow.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataWindow.java index f9ec141d858..31e6d625901 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataWindow.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataWindow.java @@ -14,7 +14,7 @@ package org.eclipse.tm.internal.terminal.model; import org.eclipse.tm.terminal.model.ITerminalTextData; import org.eclipse.tm.terminal.model.ITerminalTextDataSnapshot; import org.eclipse.tm.terminal.model.LineSegment; -import org.eclipse.tm.terminal.model.Style; +import org.eclipse.tm.terminal.model.TerminalStyle; /** * This class stores the data only within a window {@link #setWindow(int, int)} and @@ -86,14 +86,14 @@ public class TerminalTextDataWindow implements ITerminalTextData { } @Override - public Style getStyle(int line, int column) { + public TerminalStyle getStyle(int line, int column) { if (!isInWindow(line)) return null; return fData.getStyle(line - fWindowStartLine, column); } @Override - public Style[] getStyles(int line) { + public TerminalStyle[] getStyles(int line) { if (!isInWindow(line)) return null; return fData.getStyles(line - fWindowStartLine); @@ -168,21 +168,21 @@ public class TerminalTextDataWindow implements ITerminalTextData { } @Override - public void setChar(int line, int column, char c, Style style) { + public void setChar(int line, int column, char c, TerminalStyle style) { if (!isInWindow(line)) return; fData.setChar(line - fWindowStartLine, column, c, style); } @Override - public void setChars(int line, int column, char[] chars, int start, int len, Style style) { + public void setChars(int line, int column, char[] chars, int start, int len, TerminalStyle style) { if (!isInWindow(line)) return; fData.setChars(line - fWindowStartLine, column, chars, start, len, style); } @Override - public void setChars(int line, int column, char[] chars, Style style) { + public void setChars(int line, int column, char[] chars, TerminalStyle style) { if (!isInWindow(line)) return; fData.setChars(line - fWindowStartLine, column, chars, style); diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/ITerminalConstants.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/ITerminalConstants.java index 0c44566fb77..9f87a310388 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/ITerminalConstants.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/ITerminalConstants.java @@ -14,6 +14,8 @@ *******************************************************************************/ package org.eclipse.tm.internal.terminal.preferences; +import org.eclipse.tm.terminal.model.TerminalColor; + /** * Constants for Terminal Preferences. * @@ -22,13 +24,27 @@ package org.eclipse.tm.internal.terminal.preferences; */ public interface ITerminalConstants { + public static final String FONT_DEFINITION = "terminal.views.view.font.definition"; //$NON-NLS-1$ public static final String PREF_HAS_MIGRATED = "TerminalPref.migrated"; //$NON-NLS-1$ public static final String PREF_BUFFERLINES = "TerminalPrefBufferLines"; //$NON-NLS-1$ public static final String PREF_INVERT_COLORS = "TerminalPrefInvertColors"; //$NON-NLS-1$ + /** + * @since 5.0 + */ + public static final String PREF_FONT_DEFINITION = "TerminalFontDefinition"; //$NON-NLS-1$ public static final int DEFAULT_BUFFERLINES = 1000; public static final boolean DEFAULT_INVERT_COLORS = false; + /** + * @since 5.0 + */ + public static final String DEFAULT_FONT_DEFINITION = FONT_DEFINITION; - public static final String FONT_DEFINITION = "terminal.views.view.font.definition"; //$NON-NLS-1$ + /** + * @since 5.0 + */ + public static String getPrefForTerminalColor(TerminalColor tc) { + return tc.toString(); + } } diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/TerminalColorPresets.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/TerminalColorPresets.java new file mode 100644 index 00000000000..108ac7de0c2 --- /dev/null +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/TerminalColorPresets.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (c) 2020 Kichwa Coders Canada Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.tm.internal.terminal.preferences; + +import static org.eclipse.tm.terminal.model.TerminalColor.BACKGROUND; +import static org.eclipse.tm.terminal.model.TerminalColor.BLACK; +import static org.eclipse.tm.terminal.model.TerminalColor.BLUE; +import static org.eclipse.tm.terminal.model.TerminalColor.BRIGHT_BLACK; +import static org.eclipse.tm.terminal.model.TerminalColor.BRIGHT_BLUE; +import static org.eclipse.tm.terminal.model.TerminalColor.BRIGHT_CYAN; +import static org.eclipse.tm.terminal.model.TerminalColor.BRIGHT_GREEN; +import static org.eclipse.tm.terminal.model.TerminalColor.BRIGHT_MAGENTA; +import static org.eclipse.tm.terminal.model.TerminalColor.BRIGHT_RED; +import static org.eclipse.tm.terminal.model.TerminalColor.BRIGHT_WHITE; +import static org.eclipse.tm.terminal.model.TerminalColor.BRIGHT_YELLOW; +import static org.eclipse.tm.terminal.model.TerminalColor.CYAN; +import static org.eclipse.tm.terminal.model.TerminalColor.FOREGROUND; +import static org.eclipse.tm.terminal.model.TerminalColor.GREEN; +import static org.eclipse.tm.terminal.model.TerminalColor.MAGENTA; +import static org.eclipse.tm.terminal.model.TerminalColor.RED; +import static org.eclipse.tm.terminal.model.TerminalColor.SELECTION_BACKGROUND; +import static org.eclipse.tm.terminal.model.TerminalColor.SELECTION_FOREGROUND; +import static org.eclipse.tm.terminal.model.TerminalColor.WHITE; +import static org.eclipse.tm.terminal.model.TerminalColor.YELLOW; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import org.eclipse.swt.graphics.RGB; +import org.eclipse.tm.internal.terminal.control.impl.TerminalMessages; +import org.eclipse.tm.internal.terminal.model.SystemDefaultColors; +import org.eclipse.tm.terminal.model.TerminalColor; + +/** + * @since 5.0 + */ +public enum TerminalColorPresets { + + INSTANCE; + + private final List presets = new ArrayList<>(); + + public List getPresets() { + return presets.stream().map(Preset::getName).collect(Collectors.toList()); + } + + public Preset getPreset(int index) { + return presets.get(index); + } + + public static class Preset { + private String name; + private Map> map = new EnumMap<>(TerminalColor.class); + + Preset(String name) { + this.name = name; + set(BLACK, 0, 0, 0); + set(RED, 205, 0, 0); + set(GREEN, 0, 205, 0); + set(YELLOW, 205, 205, 0); + set(BLUE, 0, 0, 238); + set(MAGENTA, 205, 0, 205); + set(CYAN, 0, 205, 205); + set(WHITE, 229, 229, 229); + + set(BRIGHT_BLACK, 0, 0, 0); + set(BRIGHT_RED, 255, 0, 0); + set(BRIGHT_GREEN, 0, 255, 0); + set(BRIGHT_YELLOW, 255, 255, 0); + set(BRIGHT_BLUE, 92, 92, 255); + set(BRIGHT_MAGENTA, 255, 0, 255); + set(BRIGHT_CYAN, 0, 255, 255); + set(BRIGHT_WHITE, 255, 255, 255); + + set(FOREGROUND, SystemDefaultColors.FOREGROUND); + set(BACKGROUND, SystemDefaultColors.BACKGROUND); + set(SELECTION_FOREGROUND, SystemDefaultColors.SELECTION_FOREGROUND); + set(SELECTION_BACKGROUND, SystemDefaultColors.SELECTION_BACKGROUND); + } + + Preset set(TerminalColor color, RGB rgb) { + return set(color, () -> rgb); + } + + Preset set(TerminalColor color, int r, int g, int b) { + return set(color, new RGB(r, g, b)); + } + + Preset set(TerminalColor color, Supplier rgbSupplier) { + map.put(color, rgbSupplier); + return this; + } + + public String getName() { + return name; + } + + /** + * Returns the preset value for the given color. Will never return null + * because each color must be defined in the map. + * + * @param terminalColor to get RGB value for + * @return non-null color + */ + public RGB getRGB(TerminalColor terminalColor) { + return map.getOrDefault(terminalColor, () -> new RGB(0, 0, 0)).get(); + } + } + + TerminalColorPresets() { + presets.add(new Preset(TerminalMessages.TerminalColorPresets_TerminalDefaults)); + presets.add(new Preset(TerminalMessages.TerminalColorPresets_EclipseLight) // + .set(FOREGROUND, getDefaultPreset().getRGB(BLACK)) // + .set(BACKGROUND, getDefaultPreset().getRGB(WHITE))); + presets.add(new Preset(TerminalMessages.TerminalColorPresets_EclipseDark) // + .set(FOREGROUND, getDefaultPreset().getRGB(WHITE)) // + .set(BACKGROUND, getDefaultPreset().getRGB(BLACK))); + } + + public Preset getDefaultPreset() { + return presets.get(0); + } +} diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/TerminalColorsFieldEditor.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/TerminalColorsFieldEditor.java new file mode 100644 index 00000000000..1ea8983c5ac --- /dev/null +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/TerminalColorsFieldEditor.java @@ -0,0 +1,227 @@ +/******************************************************************************* + * Copyright (c) 2020 Kichwa Coders Canada Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.tm.internal.terminal.preferences; + +import static org.eclipse.tm.terminal.model.TerminalColor.BACKGROUND; +import static org.eclipse.tm.terminal.model.TerminalColor.BLACK; +import static org.eclipse.tm.terminal.model.TerminalColor.BLUE; +import static org.eclipse.tm.terminal.model.TerminalColor.BRIGHT_BLACK; +import static org.eclipse.tm.terminal.model.TerminalColor.BRIGHT_BLUE; +import static org.eclipse.tm.terminal.model.TerminalColor.BRIGHT_CYAN; +import static org.eclipse.tm.terminal.model.TerminalColor.BRIGHT_GREEN; +import static org.eclipse.tm.terminal.model.TerminalColor.BRIGHT_MAGENTA; +import static org.eclipse.tm.terminal.model.TerminalColor.BRIGHT_RED; +import static org.eclipse.tm.terminal.model.TerminalColor.BRIGHT_WHITE; +import static org.eclipse.tm.terminal.model.TerminalColor.BRIGHT_YELLOW; +import static org.eclipse.tm.terminal.model.TerminalColor.CYAN; +import static org.eclipse.tm.terminal.model.TerminalColor.FOREGROUND; +import static org.eclipse.tm.terminal.model.TerminalColor.GREEN; +import static org.eclipse.tm.terminal.model.TerminalColor.MAGENTA; +import static org.eclipse.tm.terminal.model.TerminalColor.RED; +import static org.eclipse.tm.terminal.model.TerminalColor.SELECTION_BACKGROUND; +import static org.eclipse.tm.terminal.model.TerminalColor.SELECTION_FOREGROUND; +import static org.eclipse.tm.terminal.model.TerminalColor.WHITE; +import static org.eclipse.tm.terminal.model.TerminalColor.YELLOW; + +import java.util.EnumMap; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.preference.ColorSelector; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.tm.internal.terminal.control.impl.TerminalMessages; +import org.eclipse.tm.terminal.model.TerminalColor; + +/** + * A field editor that can be used for editing terminal colors. + * + * @since 5.0 + */ +public class TerminalColorsFieldEditor extends FieldEditor { + + private EnumMap colorSelectors; + private Composite controls; + private Font boldFont; + + /** + * Creates a field editor for editing colors of {@link TerminalColor}. + * The preference names used are as they are returned from {@link TerminalColor#getPreferenceName()} + * @param labelText + * @param parent + */ + public TerminalColorsFieldEditor(Composite parent) { + super("", "", parent); //$NON-NLS-1$ //$NON-NLS-2$ + } + + @Override + protected void adjustForNumColumns(int numColumns) { + GridData gd = (GridData) controls.getLayoutData(); + gd.horizontalSpan = numColumns; + } + + @Override + public int getNumberOfControls() { + return 1; + } + + @Override + protected void doFillIntoGrid(Composite parent, int numColumns) { + colorSelectors = new EnumMap<>(TerminalColor.class); + controls = new Composite(parent, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(controls); + GridLayoutFactory.fillDefaults().applyTo(controls); + + FontDescriptor boldDescriptor = FontDescriptor.createFrom(parent.getFont()).setStyle(SWT.BOLD); + boldFont = boldDescriptor.createFont(parent.getDisplay()); + + Group general = new Group(controls, SWT.SHADOW_NONE); + general.setText(TerminalMessages.TerminalColorsFieldEditor_GeneralColors); + general.setFont(boldFont); + GridDataFactory.fillDefaults().applyTo(general); + GridLayoutFactory.swtDefaults().numColumns(4).applyTo(general); + + createLabelledSelector(general, FOREGROUND, TerminalMessages.TerminalColorsFieldEditor_TextColor); + createLabelledSelector(general, BACKGROUND, TerminalMessages.TerminalColorsFieldEditor_Background); + createLabelledSelector(general, SELECTION_BACKGROUND, TerminalMessages.TerminalColorsFieldEditor_Selection); + createLabelledSelector(general, SELECTION_FOREGROUND, TerminalMessages.TerminalColorsFieldEditor_SelectedText); + + Group palette = new Group(controls, SWT.SHADOW_NONE); + palette.setText(TerminalMessages.TerminalColorsFieldEditor_PaletteColors); + palette.setFont(boldFont); + GridDataFactory.fillDefaults().applyTo(palette); + GridLayoutFactory.swtDefaults().numColumns(8).applyTo(palette); + + createSelector(palette, BLACK, TerminalMessages.TerminalColorsFieldEditor_Black); + createSelector(palette, RED, TerminalMessages.TerminalColorsFieldEditor_Red); + createSelector(palette, GREEN, TerminalMessages.TerminalColorsFieldEditor_Green); + createSelector(palette, YELLOW, TerminalMessages.TerminalColorsFieldEditor_Yellow); + createSelector(palette, BLUE, TerminalMessages.TerminalColorsFieldEditor_Blue); + createSelector(palette, MAGENTA, TerminalMessages.TerminalColorsFieldEditor_Magenta); + createSelector(palette, CYAN, TerminalMessages.TerminalColorsFieldEditor_Cyan); + createSelector(palette, WHITE, TerminalMessages.TerminalColorsFieldEditor_White); + + createSelector(palette, BRIGHT_BLACK, TerminalMessages.TerminalColorsFieldEditor_BrightBlack); + createSelector(palette, BRIGHT_RED, TerminalMessages.TerminalColorsFieldEditor_BrightRed); + createSelector(palette, BRIGHT_GREEN, TerminalMessages.TerminalColorsFieldEditor_BrightGreen); + createSelector(palette, BRIGHT_YELLOW, TerminalMessages.TerminalColorsFieldEditor_BrightYellow); + createSelector(palette, BRIGHT_BLUE, TerminalMessages.TerminalColorsFieldEditor_BrightBlue); + createSelector(palette, BRIGHT_MAGENTA, TerminalMessages.TerminalColorsFieldEditor_BrightMagenta); + createSelector(palette, BRIGHT_CYAN, TerminalMessages.TerminalColorsFieldEditor_BrightCyan); + createSelector(palette, BRIGHT_WHITE, TerminalMessages.TerminalColorsFieldEditor_BrightWhite); + + Group presets = new Group(controls, SWT.SHADOW_NONE); + presets.setText(TerminalMessages.TerminalColorsFieldEditor_Presets); + presets.setFont(boldFont); + GridDataFactory.fillDefaults().applyTo(presets); + GridLayoutFactory.swtDefaults().numColumns(2).applyTo(presets); + Combo presetsCombo = new Combo(presets, SWT.DROP_DOWN | SWT.READ_ONLY); + presetsCombo.add(TerminalMessages.TerminalColorsFieldEditor_LoadPresets); + TerminalColorPresets colorPresets = TerminalColorPresets.INSTANCE; + colorPresets.getPresets().forEach(presetsCombo::add); + presetsCombo.addListener(SWT.Selection, e -> { + int selectionIndex = presetsCombo.getSelectionIndex(); + if (selectionIndex > 0) { + int selectedPresetIndex = selectionIndex - 1; // account for "Load Presets..." entry + colorSelectors.forEach((terminalColor, colorSelector) -> colorSelector + .setColorValue(colorPresets.getPreset(selectedPresetIndex).getRGB(terminalColor))); + + } + }); + presetsCombo.select(0); + } + + @Override + public void dispose() { + if (boldFont != null) { + boldFont.dispose(); + } + } + + private void createLabelledSelector(Composite parent, TerminalColor color, String label) { + Label labelControl = new Label(parent, SWT.LEFT); + labelControl.setText(label); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).applyTo(labelControl); + createSelector(parent, color, label); + } + + private void createSelector(Composite parent, TerminalColor color, String label) { + ColorSelector colorSelector = new ColorSelector(parent); + colorSelector.getButton().setToolTipText(label); + GridDataFactory.fillDefaults().applyTo(colorSelector.getButton()); + colorSelectors.put(color, colorSelector); + } + + @Override + protected void doLoad() { + IPreferenceStore store = getPreferenceStore(); + colorSelectors.forEach((terminalColor, colorSelector) -> colorSelector.setColorValue( + PreferenceConverter.getColor(store, ITerminalConstants.getPrefForTerminalColor(terminalColor)))); + } + + @Override + protected void doLoadDefault() { + IPreferenceStore store = getPreferenceStore(); + colorSelectors.forEach((terminalColor, colorSelector) -> colorSelector.setColorValue( + PreferenceConverter.getDefaultColor(store, ITerminalConstants.getPrefForTerminalColor(terminalColor)))); + } + + @Override + public void store() { + IPreferenceStore store = getPreferenceStore(); + if (store == null) { + return; + } + + if (presentsDefaultValue()) { + doStoreDefault(store); + } else { + doStore(); + } + } + + /** + * Stores the default preference value from this field editor into + * the preference store. + */ + protected void doStoreDefault(IPreferenceStore store) { + colorSelectors.forEach((terminalColor, colorSelector) -> store + .setToDefault(ITerminalConstants.getPrefForTerminalColor(terminalColor))); + } + + @Override + protected void doStore() { + IPreferenceStore store = getPreferenceStore(); + colorSelectors.forEach((terminalColor, colorSelector) -> PreferenceConverter.setValue(store, + ITerminalConstants.getPrefForTerminalColor(terminalColor), colorSelector.getColorValue())); + } + + @Override + public String getPreferenceName() { + throw new IllegalArgumentException( + "preference name should not be accessed as this class represent multiple preferences"); //$NON-NLS-1$ + } + + @Override + public String getLabelText() { + throw new IllegalArgumentException( + "label text should not be accessed as this class represent multiple preferences"); //$NON-NLS-1$ + } + +} diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/TerminalPreferenceInitializer.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/TerminalPreferenceInitializer.java index df901498ce6..d6d737459b4 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/TerminalPreferenceInitializer.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/TerminalPreferenceInitializer.java @@ -18,7 +18,10 @@ package org.eclipse.tm.internal.terminal.preferences; import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; import org.eclipse.core.runtime.preferences.DefaultScope; import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.jface.resource.StringConverter; import org.eclipse.tm.internal.terminal.control.impl.TerminalPlugin; +import org.eclipse.tm.internal.terminal.preferences.TerminalColorPresets.Preset; +import org.eclipse.tm.terminal.model.TerminalColor; /** * Terminal Preference Initializer. @@ -38,5 +41,13 @@ public class TerminalPreferenceInitializer extends AbstractPreferenceInitializer IEclipsePreferences defaultPrefs = DefaultScope.INSTANCE.getNode(TerminalPlugin.PLUGIN_ID); defaultPrefs.putBoolean(ITerminalConstants.PREF_INVERT_COLORS, ITerminalConstants.DEFAULT_INVERT_COLORS); defaultPrefs.putInt(ITerminalConstants.PREF_BUFFERLINES, ITerminalConstants.DEFAULT_BUFFERLINES); + defaultPrefs.put(ITerminalConstants.PREF_FONT_DEFINITION, ITerminalConstants.DEFAULT_FONT_DEFINITION); + + Preset defaultPresets = TerminalColorPresets.INSTANCE.getDefaultPreset(); + TerminalColor[] colors = TerminalColor.values(); + for (TerminalColor color : colors) { + defaultPrefs.put(ITerminalConstants.getPrefForTerminalColor(color), + StringConverter.asString(defaultPresets.getRGB(color))); + } } } diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/TerminalPreferencePage.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/TerminalPreferencePage.java index e3b0691977a..6dcc77da03f 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/TerminalPreferencePage.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/preferences/TerminalPreferencePage.java @@ -36,9 +36,6 @@ import org.eclipse.ui.IWorkbenchPreferencePage; * @noreference This class is not intended to be referenced by clients. */ public class TerminalPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { - protected BooleanFieldEditor fInvertColors; - - protected IntegerFieldEditor fEditorBufferSize; public TerminalPreferencePage() { super(GRID); @@ -69,14 +66,12 @@ public class TerminalPreferencePage extends FieldEditorPreferencePage implements } protected void setupEditors() { - fInvertColors = new BooleanFieldEditor(ITerminalConstants.PREF_INVERT_COLORS, TerminalMessages.INVERT_COLORS, - getFieldEditorParent()); - fEditorBufferSize = new IntegerFieldEditor(ITerminalConstants.PREF_BUFFERLINES, TerminalMessages.BUFFERLINES, - getFieldEditorParent()); + addField(new BooleanFieldEditor(ITerminalConstants.PREF_INVERT_COLORS, TerminalMessages.INVERT_COLORS, + getFieldEditorParent())); - fEditorBufferSize.setValidRange(0, Integer.MAX_VALUE); + addField(new IntegerFieldEditor(ITerminalConstants.PREF_BUFFERLINES, TerminalMessages.BUFFERLINES, + getFieldEditorParent())); - addField(fInvertColors); - addField(fEditorBufferSize); + addField(new TerminalColorsFieldEditor(getFieldEditorParent())); } } diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/AnsiColorNames.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/AnsiColorNames.java deleted file mode 100644 index b57da7239f3..00000000000 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/AnsiColorNames.java +++ /dev/null @@ -1,26 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2020 Wind River Systems, Inc. and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Jonah Graham - extracted colour names from StyleMap to be reused and cross referenced in VT100Emulator - *******************************************************************************/ -package org.eclipse.tm.internal.terminal.textcanvas; - -public class AnsiColorNames { - public static final String BLACK = "black"; //$NON-NLS-1$ - public static final String WHITE = "white"; //$NON-NLS-1$ - public static final String WHITE_FOREGROUND = "white_foreground"; //$NON-NLS-1$ - public static final String GRAY = "gray"; //$NON-NLS-1$ - public static final String MAGENTA = "magenta"; //$NON-NLS-1$ - public static final String CYAN = "cyan"; //$NON-NLS-1$ - public static final String YELLOW = "yellow"; //$NON-NLS-1$ - public static final String BLUE = "blue"; //$NON-NLS-1$ - public static final String GREEN = "green"; //$NON-NLS-1$ - public static final String RED = "red"; //$NON-NLS-1$ -} diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/ILinelRenderer.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/ILinelRenderer.java index 2d38a96eac0..8ef7c58cb89 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/ILinelRenderer.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/ILinelRenderer.java @@ -14,8 +14,13 @@ *******************************************************************************/ package org.eclipse.tm.internal.terminal.textcanvas; +import java.util.Map; + import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.tm.terminal.model.TerminalColor; /** * @@ -41,7 +46,16 @@ public interface ILinelRenderer { */ void updateFont(String fontName); + void updateColors(Map map); + void setInvertedColors(boolean invert); + /** + * @deprecated use {@link #getDefaultBackgroundColor(Device)} + */ + @Deprecated Color getDefaultBackgroundColor(); + + Color getDefaultBackgroundColor(Device device); + } diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/StyleMap.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/StyleMap.java index 6a0a7c0dd8b..badc43b6730 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/StyleMap.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/StyleMap.java @@ -19,170 +19,104 @@ *******************************************************************************/ package org.eclipse.tm.internal.terminal.textcanvas; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.BLACK; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.BLUE; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.CYAN; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.GRAY; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.GREEN; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.MAGENTA; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.RED; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.WHITE; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.WHITE_FOREGROUND; -import static org.eclipse.tm.internal.terminal.textcanvas.AnsiColorNames.YELLOW; - -import java.util.HashMap; +import java.util.EnumMap; import java.util.Map; import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Display; import org.eclipse.tm.internal.terminal.preferences.ITerminalConstants; -import org.eclipse.tm.terminal.model.Style; -import org.eclipse.tm.terminal.model.StyleColor; +import org.eclipse.tm.internal.terminal.preferences.TerminalColorPresets; +import org.eclipse.tm.terminal.model.TerminalColor; +import org.eclipse.tm.terminal.model.TerminalStyle; +/** + * The split between responsibilities of StyleMap and TerminalStyle are not always clear. Generally + * the style parts that are global for a terminal are here, where as in TerminalStyle is about + * a specific range. + */ public class StyleMap { - private static final String PREFIX = "org.eclipse.tm.internal."; //$NON-NLS-1$ String fFontName = ITerminalConstants.FONT_DEFINITION; - Map fColorMapForeground = new HashMap<>(); - Map fColorMapBackground = new HashMap<>(); - Map fColorMapIntense = new HashMap<>(); private Point fCharSize; - private final Style fDefaultStyle; + private final TerminalStyle fDefaultStyle; private boolean fInvertColors; private boolean fProportional; private final int[] fOffsets = new int[256]; + private final Map fColorMap = new EnumMap<>(TerminalColor.class); - StyleMap() { + public StyleMap() { + fDefaultStyle = TerminalStyle.getDefaultStyle(); + initFont(); initColors(); - fDefaultStyle = Style.getStyle(StyleColor.getStyleColor(BLACK), StyleColor.getStyleColor(WHITE)); - updateFont(); } private void initColors() { - initForegroundColors(); - initBackgroundColors(); - initIntenseColors(); - } - - private void initForegroundColors() { - if (fInvertColors) { - setColor(fColorMapForeground, WHITE, 0, 0, 0); - setColor(fColorMapForeground, WHITE_FOREGROUND, 50, 50, 50); - setColor(fColorMapForeground, BLACK, 229, 229, 229); - } else { - setColor(fColorMapForeground, WHITE, 255, 255, 255); - setColor(fColorMapForeground, WHITE_FOREGROUND, 229, 229, 229); - setColor(fColorMapForeground, BLACK, 50, 50, 50); + Map map = new EnumMap<>(TerminalColor.class); + TerminalColor[] values = TerminalColor.values(); + for (TerminalColor terminalColor : values) { + RGB rgb = TerminalColorPresets.INSTANCE.getDefaultPreset().getRGB(terminalColor); + map.put(terminalColor, rgb); } - setColor(fColorMapForeground, RED, 205, 0, 0); - setColor(fColorMapForeground, GREEN, 0, 205, 0); - setColor(fColorMapForeground, BLUE, 0, 0, 238); - setColor(fColorMapForeground, YELLOW, 205, 205, 0); - setColor(fColorMapForeground, CYAN, 0, 205, 205); - setColor(fColorMapForeground, MAGENTA, 205, 0, 205); - setColor(fColorMapForeground, GRAY, 229, 229, 229); + updateColors(map); } - private void initBackgroundColors() { - if (fInvertColors) { - setColor(fColorMapBackground, WHITE, 0, 0, 0); - setColor(fColorMapBackground, WHITE_FOREGROUND, 50, 50, 50); // only used when colors are inverse - setColor(fColorMapBackground, BLACK, 255, 255, 255); + private void initFont() { + updateFont(ITerminalConstants.FONT_DEFINITION); + } + + private RGB getRGB(TerminalColor color) { + return fColorMap.get(color); + } + + public RGB getForegrondRGB(TerminalStyle style) { + style = defaultIfNull(style); + TerminalColor color; + if (style.isReverse()) { + color = style.getBackgroundTerminalColor(); } else { - setColor(fColorMapBackground, WHITE, 255, 255, 255); - setColor(fColorMapBackground, WHITE_FOREGROUND, 229, 229, 229); - setColor(fColorMapBackground, BLACK, 0, 0, 0); + color = style.getForegroundTerminalColor(); } - setColor(fColorMapBackground, RED, 205, 0, 0); - setColor(fColorMapBackground, GREEN, 0, 205, 0); - setColor(fColorMapBackground, BLUE, 0, 0, 238); - setColor(fColorMapBackground, YELLOW, 205, 205, 0); - setColor(fColorMapBackground, CYAN, 0, 205, 205); - setColor(fColorMapBackground, MAGENTA, 205, 0, 205); - setColor(fColorMapBackground, GRAY, 229, 229, 229); - } - private void initIntenseColors() { - if (fInvertColors) { - setColor(fColorMapIntense, WHITE, 127, 127, 127); - setColor(fColorMapIntense, WHITE_FOREGROUND, 0, 0, 0); // only used when colors are inverse - setColor(fColorMapIntense, BLACK, 255, 255, 255); - } else { - setColor(fColorMapIntense, WHITE, 255, 255, 255); - setColor(fColorMapIntense, WHITE_FOREGROUND, 255, 255, 255); - setColor(fColorMapIntense, BLACK, 0, 0, 0); - } - setColor(fColorMapIntense, RED, 255, 0, 0); - setColor(fColorMapIntense, GREEN, 0, 255, 0); - setColor(fColorMapIntense, BLUE, 92, 92, 255); - setColor(fColorMapIntense, YELLOW, 255, 255, 0); - setColor(fColorMapIntense, CYAN, 0, 255, 255); - setColor(fColorMapIntense, MAGENTA, 255, 0, 255); - setColor(fColorMapIntense, GRAY, 255, 255, 255); - } - - private void setColor(Map colorMap, String name, int r, int g, int b) { - String colorName = PREFIX + r + "-" + g + "-" + b; //$NON-NLS-1$//$NON-NLS-2$ - Color color = JFaceResources.getColorRegistry().get(colorName); if (color == null) { - JFaceResources.getColorRegistry().put(colorName, new RGB(r, g, b)); - color = JFaceResources.getColorRegistry().get(colorName); + color = TerminalColor.FOREGROUND; } - colorMap.put(StyleColor.getStyleColor(name), color); - colorMap.put(StyleColor.getStyleColor(name.toUpperCase()), color); + + color = color.convertColor(fInvertColors, style.isBold()); + return getRGB(color); } - public Color getForegrondColor(Style style) { + public RGB getBackgroundRGB(TerminalStyle style) { style = defaultIfNull(style); - Map map = style.isBold() ? fColorMapIntense : fColorMapForeground; - //Map map = fColorMapForeground; - if (style.isReverse()) - return getColor(map, style.getBackground()); - else - return getColor(map, style.getForground()); - } - - public Color getBackgroundColor(Style style) { - style = defaultIfNull(style); - if (style.isReverse()) - return getColor(fColorMapBackground, style.getForground()); - else - return getColor(fColorMapBackground, style.getBackground()); - } - - Color getColor(Map map, StyleColor color) { - Color c = map.get(color); - if (c == null) { - c = Display.getCurrent().getSystemColor(SWT.COLOR_GRAY); + TerminalColor color; + if (style.isReverse()) { + color = style.getForegroundTerminalColor(); + } else { + color = style.getBackgroundTerminalColor(); } - return c; + + if (color == null) { + color = TerminalColor.BACKGROUND; + } + + color = color.convertColor(fInvertColors, style.isBold()); + return getRGB(color); } - private Style defaultIfNull(Style style) { + private TerminalStyle defaultIfNull(TerminalStyle style) { if (style == null) style = fDefaultStyle; return style; } public void setInvertedColors(boolean invert) { - if (invert == fInvertColors) - return; fInvertColors = invert; - initColors(); } - // static Font getBoldFont(Font font) { - // FontData fontDatas[] = font.getFontData(); - // FontData data = fontDatas[0]; - // return new Font(Display.getCurrent(), data.getName(), data.getHeight(), data.getStyle()|SWT.BOLD); - // } - public Font getFont(Style style) { + public Font getFont(TerminalStyle style) { style = defaultIfNull(style); if (style.isBold()) { return JFaceResources.getFontRegistry().getBold(fFontName); @@ -195,7 +129,6 @@ public class StyleMap { public Font getFont() { return JFaceResources.getFontRegistry().get(fFontName); - } public int getFontWidth() { @@ -314,4 +247,8 @@ public class StyleMap { return 0; return fOffsets[c]; } + + public void updateColors(Map colorMap) { + fColorMap.putAll(colorMap); + } } diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/TextCanvas.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/TextCanvas.java index 5913fde1d9b..493b8b17c88 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/TextCanvas.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/TextCanvas.java @@ -25,6 +25,7 @@ package org.eclipse.tm.internal.terminal.textcanvas; import java.util.ArrayList; import java.util.List; +import java.util.Map; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.Clipboard; @@ -35,11 +36,14 @@ import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import org.eclipse.tm.internal.terminal.control.ITerminalMouseListener; +import org.eclipse.tm.terminal.model.TerminalColor; /** * A cell oriented Canvas. Maintains a list of "cells". @@ -369,6 +373,12 @@ public class TextCanvas extends GridCanvas { } @Override + protected Color getTerminalBackgroundColor(Device device) { + return fCellRenderer.getDefaultBackgroundColor(device); + } + + @Override + @Deprecated protected Color getTerminalBackgroundColor() { return fCellRenderer.getDefaultBackgroundColor(); } @@ -490,6 +500,11 @@ public class TextCanvas extends GridCanvas { calculateGrid(); } + public void updateColors(Map map) { + fCellRenderer.updateColors(map); + redraw(); + } + public void setInvertedColors(boolean invert) { fCellRenderer.setInvertedColors(invert); redraw(); @@ -520,4 +535,5 @@ public class TextCanvas extends GridCanvas { public void removeTerminalMouseListener(ITerminalMouseListener listener) { fMouseListeners.remove(listener); } + } diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/TextLineRenderer.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/TextLineRenderer.java index 88babe72d6e..6f4cc343fbe 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/TextLineRenderer.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/TextLineRenderer.java @@ -16,26 +16,32 @@ *******************************************************************************/ package org.eclipse.tm.internal.terminal.textcanvas; +import java.util.Map; + import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Display; import org.eclipse.tm.terminal.model.ITerminalTextDataReadOnly; import org.eclipse.tm.terminal.model.LineSegment; -import org.eclipse.tm.terminal.model.Style; +import org.eclipse.tm.terminal.model.TerminalColor; +import org.eclipse.tm.terminal.model.TerminalStyle; /** * */ public class TextLineRenderer implements ILinelRenderer { private final ITextCanvasModel fModel; - StyleMap fStyleMap = new StyleMap(); + private final StyleMap fStyleMap; public TextLineRenderer(TextCanvas c, ITextCanvasModel model) { fModel = model; + fStyleMap = new StyleMap(); } @Override @@ -65,7 +71,7 @@ public class TextLineRenderer implements ILinelRenderer { LineSegment[] segments = getTerminalText().getLineSegments(line, colFirst, colLast - colFirst); for (int i = 0; i < segments.length; i++) { LineSegment segment = segments[i]; - Style style = segment.getStyle(); + TerminalStyle style = segment.getStyle(); setupGC(doubleBufferGC, style); String text = segment.getText(); drawText(doubleBufferGC, 0, 0, colFirst, segment.getColumn(), text); @@ -102,7 +108,7 @@ public class TextLineRenderer implements ILinelRenderer { private void fillBackground(GC gc, int x, int y, int width, int height) { Color bg = gc.getBackground(); - gc.setBackground(getDefaultBackgroundColor()); + gc.setBackground(getDefaultBackgroundColor(gc.getDevice())); gc.fillRectangle(x, y, width, height); gc.setBackground(bg); @@ -110,8 +116,14 @@ public class TextLineRenderer implements ILinelRenderer { @Override public Color getDefaultBackgroundColor() { + return getDefaultBackgroundColor(Display.getDefault()); + } + + @Override + public Color getDefaultBackgroundColor(Device device) { // null == default style - return fStyleMap.getBackgroundColor(null); + RGB backgroundRGB = fStyleMap.getBackgroundRGB(null); + return new Color(device, backgroundRGB); } private void drawCursor(ITextCanvasModel model, GC gc, int row, int x, int y, int colFirst) { @@ -122,10 +134,10 @@ public class TextLineRenderer implements ILinelRenderer { if (row == cursorLine) { int cursorColumn = model.getCursorColumn(); if (cursorColumn < getTerminalText().getWidth()) { - Style style = getTerminalText().getStyle(row, cursorColumn); + TerminalStyle style = getTerminalText().getStyle(row, cursorColumn); if (style == null) { // TODO make the cursor color customizable - style = Style.getStyle("BLACK", "WHITE"); //$NON-NLS-1$//$NON-NLS-2$ + style = TerminalStyle.getStyle(TerminalColor.FOREGROUND, TerminalColor.BACKGROUND); } style = style.setReverse(!style.isReverse()); setupGC(gc, style); @@ -156,9 +168,12 @@ public class TextLineRenderer implements ILinelRenderer { } } - private void setupGC(GC gc, Style style) { - gc.setForeground(fStyleMap.getForegrondColor(style)); - gc.setBackground(fStyleMap.getBackgroundColor(style)); + private void setupGC(GC gc, TerminalStyle style) { + RGB foregrondColor = fStyleMap.getForegrondRGB(style); + gc.setForeground(new Color(gc.getDevice(), foregrondColor)); + RGB backgroundColor = fStyleMap.getBackgroundRGB(style); + gc.setBackground(new Color(gc.getDevice(), backgroundColor)); + Font f = fStyleMap.getFont(style); if (f != gc.getFont()) { gc.setFont(f); @@ -183,6 +198,11 @@ public class TextLineRenderer implements ILinelRenderer { fStyleMap.updateFont(fontName); } + @Override + public void updateColors(Map map) { + fStyleMap.updateColors(map); + } + @Override public void setInvertedColors(boolean invert) { fStyleMap.setInvertedColors(invert); diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/VirtualCanvas.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/VirtualCanvas.java index af4d794dc3e..2fc846e7dbc 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/VirtualCanvas.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/textcanvas/VirtualCanvas.java @@ -15,6 +15,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Canvas; @@ -136,6 +137,12 @@ public abstract class VirtualCanvas extends Canvas { */ abstract protected void paint(GC gc); + abstract protected Color getTerminalBackgroundColor(Device device); + + /** + * @deprecated Use {@link #getTerminalBackgroundColor(Device)} + */ + @Deprecated protected Color getTerminalBackgroundColor() { // return getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND); return getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/ITerminalTextData.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/ITerminalTextData.java index 37a85731e45..37a563284b2 100644 --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/ITerminalTextData.java +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/ITerminalTextData.java @@ -15,7 +15,7 @@ package org.eclipse.tm.terminal.model; /** - * A writable matrix of characters and {@link Style}. This is intended to be the + * A writable matrix of characters and {@link TerminalStyle}. This is intended to be the * low level representation of the text of a Terminal. Higher layers are * responsible to fill the text and styles into this representation. *

    @@ -41,33 +41,36 @@ public interface ITerminalTextData extends ITerminalTextDataReadOnly { int getMaxHeight(); /** - * Set a single character and the associated {@link Style}. + * Set a single character and the associated {@link TerminalStyle}. * @param line line must be >=0 and < height * @param column column must be >=0 and < width * @param c the new character at this position * @param style the style or null + * @since 5.0 */ - void setChar(int line, int column, char c, Style style); + void setChar(int line, int column, char c, TerminalStyle style); /** - * Set an array of characters showing in the same {@link Style}. + * Set an array of characters showing in the same {@link TerminalStyle}. * @param line line must be >=0 and < height * @param column column must be >=0 and < width * @param chars the new characters at this position * @param style the style or null + * @since 5.0 */ - void setChars(int line, int column, char[] chars, Style style); + void setChars(int line, int column, char[] chars, TerminalStyle style); /** - * Set a subrange of an array of characters showing in the same {@link Style}. + * Set a subrange of an array of characters showing in the same {@link TerminalStyle}. * @param line line must be >=0 and < height * @param column column must be >=0 and < width * @param chars the new characters at this position * @param start the start index in the chars array * @param len the number of characters to insert. Characters beyond width are not inserted. * @param style the style or null + * @since 5.0 */ - void setChars(int line, int column, char[] chars, int start, int len, Style style); + void setChars(int line, int column, char[] chars, int start, int len, TerminalStyle style); /** * Cleans the entire line. @@ -77,7 +80,7 @@ public interface ITerminalTextData extends ITerminalTextDataReadOnly { /** * Shifts some lines up or down. The "empty" space is filled with '\000' chars - * and null {@link Style} + * and null {@link TerminalStyle} *

    To illustrate shift, here is some sample data: *

     	 * 0 aaaa
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/ITerminalTextDataReadOnly.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/ITerminalTextDataReadOnly.java
    index d935b409a71..af30864e56f 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/ITerminalTextDataReadOnly.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/ITerminalTextDataReadOnly.java
    @@ -49,8 +49,9 @@ public interface ITerminalTextDataReadOnly {
     	 * @param line must be >=0 and < height
     	 * @param column must be >=0 and < width
     	 * @return style at column,line or null
    +	 * @since 5.0
     	 */
    -	Style getStyle(int line, int column);
    +	TerminalStyle getStyle(int line, int column);
     
     	/**
     	 * Creates a new instance of {@link ITerminalTextDataSnapshot} that
    @@ -67,7 +68,10 @@ public interface ITerminalTextDataReadOnly {
     
     	char[] getChars(int line);
     
    -	Style[] getStyles(int line);
    +	/**
    +	 * @since 5.0
    +	 */
    +	TerminalStyle[] getStyles(int line);
     
     	/**
     	 * @return the line in which the cursor is at the moment
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/LineSegment.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/LineSegment.java
    index d92100fd6ce..548dc705891 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/LineSegment.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/LineSegment.java
    @@ -13,15 +13,21 @@ package org.eclipse.tm.terminal.model;
     public class LineSegment {
     	private final String fText;
     	private final int fCol;
    -	private final Style fStyle;
    +	private final TerminalStyle fStyle;
     
    -	public LineSegment(int col, String text, Style style) {
    +	/**
    +	 * @since 5.0
    +	 */
    +	public LineSegment(int col, String text, TerminalStyle style) {
     		fCol = col;
     		fText = text;
     		fStyle = style;
     	}
     
    -	public Style getStyle() {
    +	/**
    +	 * @since 5.0
    +	 */
    +	public TerminalStyle getStyle() {
     		return fStyle;
     	}
     
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/Style.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/Style.java
    deleted file mode 100644
    index e05d17e9eb7..00000000000
    --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/Style.java
    +++ /dev/null
    @@ -1,192 +0,0 @@
    -/*******************************************************************************
    - * Copyright (c) 2007, 2018 Wind River Systems, Inc. and others.
    - * All rights reserved. This program and the accompanying materials
    - * are made available under the terms of the Eclipse Public License 2.0
    - * which accompanies this distribution, and is available at
    - * https://www.eclipse.org/legal/epl-2.0/
    - *
    - * Contributors:
    - * Michael Scharf (Wind River) - initial API and implementation
    - *******************************************************************************/
    -package org.eclipse.tm.terminal.model;
    -
    -import java.util.Collections;
    -import java.util.LinkedHashMap;
    -import java.util.Map;
    -
    -import org.eclipse.tm.internal.terminal.control.impl.TerminalPlugin;
    -import org.eclipse.tm.internal.terminal.provisional.api.Logger;
    -
    -/**
    - * @author scharf
    - * Flyweight
    - * Threadsafe.
    - *
    - */
    -// TODO add an Object for user data, use weak map to keep track of styles with associated
    -// user data
    -public class Style {
    -	private final StyleColor fForground;
    -	private final StyleColor fBackground;
    -	private final boolean fBold;
    -	private final boolean fBlink;
    -	private final boolean fUnderline;
    -	private final boolean fReverse;
    -	private final static Map fgStyles = Collections.synchronizedMap(new LinkedHashMap() {
    -		@Override
    -		protected boolean removeEldestEntry(Map.Entry eldest) {
    -			int size = size();
    -			boolean removeEldest = size >= 1000;
    -			if (TerminalPlugin.isOptionEnabled(Logger.TRACE_DEBUG_LOG_VT100BACKEND)) {
    -				if (removeEldest) {
    -					Logger.log("Removing eldest Style from style cache, size = " + size); //$NON-NLS-1$
    -				} else {
    -					Logger.log("Leaving eldest Style in style cache, size = " + size); //$NON-NLS-1$
    -				}
    -			}
    -			return removeEldest;
    -		}
    -	});
    -
    -	private Style(StyleColor forground, StyleColor background, boolean bold, boolean blink, boolean underline,
    -			boolean reverse) {
    -		fForground = forground;
    -		fBackground = background;
    -		fBold = bold;
    -		fBlink = blink;
    -		fUnderline = underline;
    -		fReverse = reverse;
    -	}
    -
    -	public static Style getStyle(StyleColor forground, StyleColor background, boolean bold, boolean blink,
    -			boolean underline, boolean reverse) {
    -		Style style = new Style(forground, background, bold, blink, underline, reverse);
    -		// If set had a computeIfAbsent we would use a set, instead just store 1-2-1 mapping
    -		return fgStyles.computeIfAbsent(style, (s) -> style);
    -	}
    -
    -	public static Style getStyle(String forground, String background) {
    -		return getStyle(StyleColor.getStyleColor(forground), StyleColor.getStyleColor(background), false, false, false,
    -				false);
    -	}
    -
    -	public static Style getStyle(StyleColor forground, StyleColor background) {
    -		return getStyle(forground, background, false, false, false, false);
    -	}
    -
    -	public Style setForground(StyleColor forground) {
    -		return getStyle(forground, fBackground, fBold, fBlink, fUnderline, fReverse);
    -	}
    -
    -	public Style setBackground(StyleColor background) {
    -		return getStyle(fForground, background, fBold, fBlink, fUnderline, fReverse);
    -	}
    -
    -	public Style setForground(String colorName) {
    -		return getStyle(StyleColor.getStyleColor(colorName), fBackground, fBold, fBlink, fUnderline, fReverse);
    -	}
    -
    -	public Style setBackground(String colorName) {
    -		return getStyle(fForground, StyleColor.getStyleColor(colorName), fBold, fBlink, fUnderline, fReverse);
    -	}
    -
    -	public Style setBold(boolean bold) {
    -		return getStyle(fForground, fBackground, bold, fBlink, fUnderline, fReverse);
    -	}
    -
    -	public Style setBlink(boolean blink) {
    -		return getStyle(fForground, fBackground, fBold, blink, fUnderline, fReverse);
    -	}
    -
    -	public Style setUnderline(boolean underline) {
    -		return getStyle(fForground, fBackground, fBold, fBlink, underline, fReverse);
    -	}
    -
    -	public Style setReverse(boolean reverse) {
    -		return getStyle(fForground, fBackground, fBold, fBlink, fUnderline, reverse);
    -	}
    -
    -	public StyleColor getBackground() {
    -		return fBackground;
    -	}
    -
    -	public boolean isBlink() {
    -		return fBlink;
    -	}
    -
    -	public boolean isBold() {
    -		return fBold;
    -	}
    -
    -	public StyleColor getForground() {
    -		return fForground;
    -	}
    -
    -	public boolean isReverse() {
    -		return fReverse;
    -	}
    -
    -	public boolean isUnderline() {
    -		return fUnderline;
    -	}
    -
    -	@Override
    -	public int hashCode() {
    -		final int prime = 31;
    -		int result = 1;
    -		result = prime * result + ((fBackground == null) ? 0 : fBackground.hashCode());
    -		result = prime * result + (fBlink ? 1231 : 1237);
    -		result = prime * result + (fBold ? 1231 : 1237);
    -		result = prime * result + ((fForground == null) ? 0 : fForground.hashCode());
    -		result = prime * result + (fReverse ? 1231 : 1237);
    -		result = prime * result + (fUnderline ? 1231 : 1237);
    -		return result;
    -	}
    -
    -	@Override
    -	public boolean equals(Object obj) {
    -		if (this == obj)
    -			return true;
    -		if (obj == null)
    -			return false;
    -		if (getClass() != obj.getClass())
    -			return false;
    -		final Style other = (Style) obj;
    -		// background == is the same as equals
    -		if (fBackground != other.fBackground)
    -			return false;
    -		if (fBlink != other.fBlink)
    -			return false;
    -		if (fBold != other.fBold)
    -			return false;
    -		if (fForground != other.fForground)
    -			return false;
    -		if (fReverse != other.fReverse)
    -			return false;
    -		if (fUnderline != other.fUnderline)
    -			return false;
    -		return true;
    -	}
    -
    -	@Override
    -	public String toString() {
    -		StringBuffer result = new StringBuffer();
    -		result.append("Style(foreground="); //$NON-NLS-1$
    -		result.append(fForground);
    -		result.append(", background="); //$NON-NLS-1$
    -		result.append(fBackground);
    -		if (fBlink)
    -			result.append(", blink"); //$NON-NLS-1$
    -		if (fBold)
    -			result.append(", bold"); //$NON-NLS-1$
    -		if (fBlink)
    -			result.append(", blink"); //$NON-NLS-1$
    -		if (fReverse)
    -			result.append(", reverse"); //$NON-NLS-1$
    -		if (fUnderline)
    -			result.append(", underline"); //$NON-NLS-1$
    -		result.append(")"); //$NON-NLS-1$
    -		return result.toString();
    -	}
    -
    -}
    \ No newline at end of file
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/StyleColor.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/StyleColor.java
    deleted file mode 100644
    index be4611fb880..00000000000
    --- a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/StyleColor.java
    +++ /dev/null
    @@ -1,56 +0,0 @@
    -/*******************************************************************************
    - * Copyright (c) 2007, 2018 Wind River Systems, Inc. and others.
    - * All rights reserved. This program and the accompanying materials
    - * are made available under the terms of the Eclipse Public License 2.0
    - * which accompanies this distribution, and is available at
    - * https://www.eclipse.org/legal/epl-2.0/
    - *
    - * Contributors:
    - * Michael Scharf (Wind River) - initial API and implementation
    - *******************************************************************************/
    -package org.eclipse.tm.terminal.model;
    -
    -import java.util.HashMap;
    -import java.util.Map;
    -
    -/**
    - *
    - * Flyweight
    - * Threadsafe.
    - */
    -public class StyleColor {
    -	private final static Map fgStyleColors = new HashMap<>();
    -	final String fName;
    -
    -	/**
    -	 * @param name the name of the color. It is up to the UI to associate a
    -	 * named color with a visual representation
    -	 * @return a StyleColor
    -	 */
    -	public static StyleColor getStyleColor(String name) {
    -		StyleColor result;
    -		synchronized (fgStyleColors) {
    -			result = fgStyleColors.get(name);
    -			if (result == null) {
    -				result = new StyleColor(name);
    -				fgStyleColors.put(name, result);
    -			}
    -		}
    -		return result;
    -	}
    -
    -	// nobody except the factory method is allowed to instantiate this class!
    -	private StyleColor(String name) {
    -		fName = name;
    -	}
    -
    -	public String getName() {
    -		return fName;
    -	}
    -
    -	@Override
    -	public String toString() {
    -		return fName;
    -	}
    -	// no need to override equals and hashCode, because Object uses object identity
    -}
    \ No newline at end of file
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/TerminalColor.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/TerminalColor.java
    new file mode 100644
    index 00000000000..6ed0a1e89a3
    --- /dev/null
    +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/TerminalColor.java
    @@ -0,0 +1,168 @@
    +/*******************************************************************************
    + * Copyright (c) 2020 Kichwa Coders Canada Inc. and others.
    + * All rights reserved. This program and the accompanying materials
    + * are made available under the terms of the Eclipse Public License 2.0
    + * which accompanies this distribution, and is available at
    + * https://www.eclipse.org/legal/epl-2.0/
    + *
    + * SPDX-License-Identifier: EPL-2.0
    + *******************************************************************************/
    +package org.eclipse.tm.terminal.model;
    +
    +import org.eclipse.core.runtime.Assert;
    +import org.eclipse.jface.resource.ColorDescriptor;
    +import org.eclipse.swt.graphics.Color;
    +import org.eclipse.swt.graphics.RGB;
    +import org.eclipse.swt.widgets.Display;
    +
    +/**
    + * Colors that can be used in the Terminal are represented by this class. The enum contains
    + * the colors with well known names defined by the ANSI Escape Sequences, plus other colors needed
    + * to render a display (such as Background color).
    + *
    + * @since 5.0
    + */
    +public enum TerminalColor {
    +	BLACK, //
    +	RED, //
    +	GREEN, //
    +	YELLOW, //
    +	BLUE, //
    +	MAGENTA, //
    +	CYAN, //
    +	WHITE, //
    +
    +	BRIGHT_BLACK, //
    +	BRIGHT_RED, //
    +	BRIGHT_GREEN, //
    +	BRIGHT_YELLOW, //
    +	BRIGHT_BLUE, //
    +	BRIGHT_MAGENTA, //
    +	BRIGHT_CYAN, //
    +	BRIGHT_WHITE, //
    +
    +	FOREGROUND, //
    +	BACKGROUND, //
    +	SELECTION_FOREGROUND, //
    +	SELECTION_BACKGROUND;
    +
    +	/**
    +	 * The first 16-items in the 8-bit lookup table map to the user changeable colors
    +	 * above, so this array handles that mapping.
    +	 */
    +	private final static TerminalColor table8bitIndexedTerminalColors[] = new TerminalColor[16];
    +
    +	/**
    +	 * The rest of the colors in the lookup table (240 colors) are pre-defined by
    +	 * the standard. The colors that fill this table were derived from
    +	 * https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit which was more
    +	 * digestible and accessible than the underlying ITU and ISO standards.
    +	 */
    +	private final static RGB table8bitIndexedRGB[] = new RGB[256 - 16];
    +
    +	/**
    +	 * Color to use instead when inverted color is selected
    +	 */
    +	private TerminalColor invertColor;
    +
    +	/**
    +	 * Color to use instead when bright color is selected
    +	 */
    +	private TerminalColor brightColor;
    +
    +	/**
    +	 * Pre-calculate the lookup tables for 8-bit colors, inverses and equivalent brights.
    +	 */
    +	static {
    +		TerminalColor[] values = TerminalColor.values();
    +
    +		// 8-bit color lookup tables
    +		{
    +			int index = 0;
    +			for (; index < 16; index++) {
    +				TerminalColor c = values[index];
    +				table8bitIndexedTerminalColors[index] = c;
    +			}
    +
    +			int vals[] = { 0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff };
    +			Assert.isTrue(index == 16);
    +			for (int r = 0; r < 6; r++) {
    +				for (int g = 0; g < 6; g++) {
    +					for (int b = 0; b < 6; b++) {
    +						table8bitIndexedRGB[index++ - 16] = new RGB(vals[r], vals[g], vals[b]);
    +					}
    +				}
    +			}
    +
    +			int greys[] = { 0x08, 0x12, 0x1c, 0x26, 0x30, 0x3a, 0x44, 0x4e, 0x58, 0x62, 0x6c, 0x76, 0x80, 0x8a, 0x94,
    +					0x9e, 0xa8, 0xb2, 0xbc, 0xc6, 0xd0, 0xda, 0xe4, 0xee };
    +
    +			Assert.isTrue(index == 232);
    +			for (int g : greys) {
    +				table8bitIndexedRGB[index++ - 16] = new RGB(g, g, g);
    +			}
    +			Assert.isTrue(index == 256);
    +		}
    +
    +		// bright equivalents
    +		{
    +			// The second set of 8 colors are the bright of the first 8.
    +			for (int i = 0; i < 8; i++) {
    +				values[i].brightColor = values[i + 8];
    +			}
    +			// The rest of the colors are not brightened
    +			for (int i = 8; i < values.length; i++) {
    +				values[i].brightColor = values[i];
    +			}
    +		}
    +
    +		// inverses
    +		{
    +			// by default make all colors invert of themself
    +			for (int i = 0; i < values.length; i++) {
    +				values[i].invertColor = values[i];
    +			}
    +			// and then mark the colors that are actual inverts
    +			inverts(BLACK, WHITE);
    +			inverts(BRIGHT_BLACK, BRIGHT_WHITE);
    +			inverts(BACKGROUND, FOREGROUND);
    +		}
    +
    +	}
    +
    +	private static void inverts(TerminalColor a, TerminalColor b) {
    +		a.invertColor = b;
    +		b.invertColor = a;
    +	}
    +
    +	/**
    +	 * Return a new color for the given color with inversions or brightness attributes applied.
    +	 *
    +	 * @param invert For invertible colors, return the inverse (typically white <-> black)
    +	 * @param bright returns the brighter version of the color if one is available
    +	 * @return {@link ColorDescriptor} that a {@link Color} can be made from
    +	 *     using {@link ColorDescriptor#createColor(org.eclipse.swt.graphics.Device)}
    +	 * @throws NullPointerException if there is no current {@link Display}
    +	 */
    +	public TerminalColor convertColor(boolean invert, boolean bright) {
    +		TerminalColor selected = this;
    +		// it doesn't matter which order you apply bright and invert, you get to
    +		// the same color when both are set
    +		if (invert) {
    +			selected = selected.invertColor;
    +		}
    +		if (bright) {
    +			selected = selected.brightColor;
    +		}
    +		return selected;
    +	}
    +
    +	/**
    +	 * FOR TEST ONLY.
    +	 *
    +	 * @noreference This enum method is not intended to be referenced by clients.
    +	 */
    +	public static TerminalColor getForTest(int c) {
    +		return TerminalColor.values()[c % TerminalColor.values().length];
    +	}
    +}
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/TerminalStyle.java b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/TerminalStyle.java
    new file mode 100644
    index 00000000000..f63d0f0be2b
    --- /dev/null
    +++ b/terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/terminal/model/TerminalStyle.java
    @@ -0,0 +1,193 @@
    +/*******************************************************************************
    + * Copyright (c) 2007, 2020 Wind River Systems, Inc. and others.
    + * All rights reserved. This program and the accompanying materials
    + * are made available under the terms of the Eclipse Public License 2.0
    + * which accompanies this distribution, and is available at
    + * https://www.eclipse.org/legal/epl-2.0/
    + *
    + * Contributors:
    + * Michael Scharf (Wind River) - initial API and implementation
    + *******************************************************************************/
    +package org.eclipse.tm.terminal.model;
    +
    +import java.util.Collections;
    +import java.util.LinkedHashMap;
    +import java.util.Map;
    +
    +import org.eclipse.tm.internal.terminal.control.impl.TerminalPlugin;
    +import org.eclipse.tm.internal.terminal.provisional.api.Logger;
    +
    +/**
    + * @author scharf
    + * Flyweight
    + * Threadsafe.
    + * @since 5.0
    + *
    + */
    +// TODO add an Object for user data, use weak map to keep track of styles with associated
    +// user data
    +public class TerminalStyle {
    +	private final TerminalColor fForegroundTerminalColor;
    +	private final TerminalColor fBackgroundTerminalColor;
    +	private final boolean fBold;
    +	private final boolean fBlink;
    +	private final boolean fUnderline;
    +	private final boolean fReverse;
    +	private final static Map fgStyles = Collections
    +			.synchronizedMap(new LinkedHashMap() {
    +				@Override
    +				protected boolean removeEldestEntry(Map.Entry eldest) {
    +					int size = size();
    +					boolean removeEldest = size >= 1000;
    +					if (TerminalPlugin.isOptionEnabled(Logger.TRACE_DEBUG_LOG_VT100BACKEND)) {
    +						if (removeEldest) {
    +							Logger.log("Removing eldest Style from style cache, size = " + size); //$NON-NLS-1$
    +						} else {
    +							Logger.log("Leaving eldest Style in style cache, size = " + size); //$NON-NLS-1$
    +						}
    +					}
    +					return removeEldest;
    +				}
    +			});
    +
    +	private TerminalStyle(TerminalColor foregroundTerminalColor, TerminalColor backgroundTerminalColor, boolean bold,
    +			boolean blink, boolean underline, boolean reverse) {
    +		fForegroundTerminalColor = foregroundTerminalColor;
    +		fBackgroundTerminalColor = backgroundTerminalColor;
    +		fBold = bold;
    +		fBlink = blink;
    +		fUnderline = underline;
    +		fReverse = reverse;
    +	}
    +
    +	public static TerminalStyle getStyle(TerminalColor foregroundTerminalColor, TerminalColor backgroundTerminalColor,
    +			boolean bold, boolean blink, boolean underline, boolean reverse) {
    +		TerminalStyle style = new TerminalStyle(foregroundTerminalColor, backgroundTerminalColor, bold, blink,
    +				underline, reverse);
    +		// If set had a computeIfAbsent we would use a set, instead just store 1-2-1 mapping
    +		return fgStyles.computeIfAbsent(style, (s) -> style);
    +	}
    +
    +	public static TerminalStyle getDefaultStyle() {
    +		return getStyle(TerminalColor.FOREGROUND, TerminalColor.BACKGROUND);
    +	}
    +
    +	public static TerminalStyle getStyle(TerminalColor foregroundTerminalColor, TerminalColor backgroundTerminalColor) {
    +		return getStyle(foregroundTerminalColor, backgroundTerminalColor, false, false, false, false);
    +	}
    +
    +	public TerminalStyle setForeground(TerminalColor foregroundTerminalColor) {
    +		return getStyle(foregroundTerminalColor, fBackgroundTerminalColor, fBold, fBlink, fUnderline, fReverse);
    +	}
    +
    +	public TerminalStyle setBackground(TerminalColor backgroundTerminalColor) {
    +		return getStyle(fForegroundTerminalColor, backgroundTerminalColor, fBold, fBlink, fUnderline, fReverse);
    +	}
    +
    +	public TerminalStyle setForeground(TerminalStyle other) {
    +		return getStyle(other.fForegroundTerminalColor, fBackgroundTerminalColor, fBold, fBlink, fUnderline, fReverse);
    +	}
    +
    +	public TerminalStyle setBackground(TerminalStyle other) {
    +		return getStyle(fForegroundTerminalColor, other.fBackgroundTerminalColor, fBold, fBlink, fUnderline, fReverse);
    +	}
    +
    +	public TerminalStyle setBold(boolean bold) {
    +		return getStyle(fForegroundTerminalColor, fBackgroundTerminalColor, bold, fBlink, fUnderline, fReverse);
    +	}
    +
    +	public TerminalStyle setBlink(boolean blink) {
    +		return getStyle(fForegroundTerminalColor, fBackgroundTerminalColor, fBold, blink, fUnderline, fReverse);
    +	}
    +
    +	public TerminalStyle setUnderline(boolean underline) {
    +		return getStyle(fForegroundTerminalColor, fBackgroundTerminalColor, fBold, fBlink, underline, fReverse);
    +	}
    +
    +	public TerminalStyle setReverse(boolean reverse) {
    +		return getStyle(fForegroundTerminalColor, fBackgroundTerminalColor, fBold, fBlink, fUnderline, reverse);
    +	}
    +
    +	public TerminalColor getForegroundTerminalColor() {
    +		return fForegroundTerminalColor;
    +	}
    +
    +	public TerminalColor getBackgroundTerminalColor() {
    +		return fBackgroundTerminalColor;
    +	}
    +
    +	public boolean isBlink() {
    +		return fBlink;
    +	}
    +
    +	public boolean isBold() {
    +		return fBold;
    +	}
    +
    +	public boolean isReverse() {
    +		return fReverse;
    +	}
    +
    +	public boolean isUnderline() {
    +		return fUnderline;
    +	}
    +
    +	@Override
    +	public int hashCode() {
    +		final int prime = 31;
    +		int result = 1;
    +		result = prime * result + ((fBackgroundTerminalColor == null) ? 0 : fBackgroundTerminalColor.hashCode());
    +		result = prime * result + (fBlink ? 1231 : 1237);
    +		result = prime * result + (fBold ? 1231 : 1237);
    +		result = prime * result + ((fForegroundTerminalColor == null) ? 0 : fForegroundTerminalColor.hashCode());
    +		result = prime * result + (fReverse ? 1231 : 1237);
    +		result = prime * result + (fUnderline ? 1231 : 1237);
    +		return result;
    +	}
    +
    +	@Override
    +	public boolean equals(Object obj) {
    +		if (this == obj)
    +			return true;
    +		if (obj == null)
    +			return false;
    +		if (getClass() != obj.getClass())
    +			return false;
    +		TerminalStyle other = (TerminalStyle) obj;
    +		if (fBackgroundTerminalColor != other.fBackgroundTerminalColor)
    +			return false;
    +		if (fBlink != other.fBlink)
    +			return false;
    +		if (fBold != other.fBold)
    +			return false;
    +		if (fForegroundTerminalColor != other.fForegroundTerminalColor)
    +			return false;
    +		if (fReverse != other.fReverse)
    +			return false;
    +		if (fUnderline != other.fUnderline)
    +			return false;
    +		return true;
    +	}
    +
    +	@Override
    +	public String toString() {
    +		StringBuffer result = new StringBuffer();
    +		result.append("Style(foreground="); //$NON-NLS-1$
    +		result.append(fForegroundTerminalColor);
    +		result.append(", background="); //$NON-NLS-1$
    +		result.append(fBackgroundTerminalColor);
    +		if (fBlink)
    +			result.append(", blink"); //$NON-NLS-1$
    +		if (fBold)
    +			result.append(", bold"); //$NON-NLS-1$
    +		if (fBlink)
    +			result.append(", blink"); //$NON-NLS-1$
    +		if (fReverse)
    +			result.append(", reverse"); //$NON-NLS-1$
    +		if (fUnderline)
    +			result.append(", underline"); //$NON-NLS-1$
    +		result.append(")"); //$NON-NLS-1$
    +		return result.toString();
    +	}
    +
    +}
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/connector/TerminalConnectorPluginTest.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/connector/TerminalConnectorPluginTest.java
    index 68e98bb2606..b5899dcd8e1 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/connector/TerminalConnectorPluginTest.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/connector/TerminalConnectorPluginTest.java
    @@ -14,13 +14,13 @@
     
     package org.eclipse.tm.internal.terminal.connector;
     
    -import junit.framework.TestCase;
    -
     import org.eclipse.core.runtime.Platform;
     import org.eclipse.tm.internal.terminal.connector.TerminalConnectorTest.ConnectorMock;
     import org.eclipse.tm.internal.terminal.connector.TerminalConnectorTest.SimpleFactory;
     import org.eclipse.tm.internal.terminal.connector.TerminalConnectorTest.TerminalControlMock;
     
    +import junit.framework.TestCase;
    +
     /**
      * Testcase for TerminalConnector that must run as a JUnit plug-in test.
      */
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackendTest.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackendTest.java
    index 81f93c9c063..3be4b5209ca 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackendTest.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackendTest.java
    @@ -16,13 +16,16 @@
      *******************************************************************************/
     package org.eclipse.tm.internal.terminal.emulator;
     
    -import junit.framework.TestCase;
    +import static org.eclipse.tm.terminal.model.TerminalColor.BLACK;
    +import static org.eclipse.tm.terminal.model.TerminalColor.WHITE;
     
     import org.eclipse.tm.internal.terminal.model.TerminalTextDataStore;
     import org.eclipse.tm.internal.terminal.model.TerminalTextTestHelper;
     import org.eclipse.tm.terminal.model.ITerminalTextData;
     import org.eclipse.tm.terminal.model.ITerminalTextDataReadOnly;
    -import org.eclipse.tm.terminal.model.Style;
    +import org.eclipse.tm.terminal.model.TerminalStyle;
    +
    +import junit.framework.TestCase;
     
     public class VT100EmulatorBackendTest extends TestCase {
     
    @@ -592,10 +595,10 @@ public class VT100EmulatorBackendTest extends TestCase {
     	public void testGetDefaultStyle() {
     		ITerminalTextData term = makeITerminalTextData();
     		IVT100EmulatorBackend vt100 = makeBakend(term);
    -		Style style = Style.getStyle("white", "black");
    +		TerminalStyle style = TerminalStyle.getStyle(WHITE, BLACK);
     		vt100.setDefaultStyle(style);
     		assertSame(style, vt100.getDefaultStyle());
    -		Style style2 = style.setBold(true);
    +		TerminalStyle style2 = style.setBold(true);
     		vt100.setDefaultStyle(style2);
     		assertSame(style2, vt100.getDefaultStyle());
     	}
    @@ -603,10 +606,10 @@ public class VT100EmulatorBackendTest extends TestCase {
     	public void testGetStyle() {
     		ITerminalTextData term = makeITerminalTextData();
     		IVT100EmulatorBackend vt100 = makeBakend(term);
    -		Style style = Style.getStyle("white", "black");
    +		TerminalStyle style = TerminalStyle.getStyle(WHITE, BLACK);
     		vt100.setStyle(style);
     		assertSame(style, vt100.getStyle());
    -		Style style2 = style.setBold(true);
    +		TerminalStyle style2 = style.setBold(true);
     		vt100.setStyle(style2);
     		assertSame(style2, vt100.getStyle());
     	}
    @@ -668,7 +671,6 @@ public class VT100EmulatorBackendTest extends TestCase {
     		assertEqualsTerm("klmn\n" + "opqr\n" + "sABC\n" + "DEFG\n" + "HIJK\n" + "L   ", toMultiLineText(term));
     		assertEquals(2, vt100.getCursorLine());
     		assertEquals(1, vt100.getCursorColumn());
    -
     	}
     
     	public void testProcessNewline() {
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/AbstractITerminalTextDataTest.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/AbstractITerminalTextDataTest.java
    index ebff202f013..9a85f508043 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/AbstractITerminalTextDataTest.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/AbstractITerminalTextDataTest.java
    @@ -14,8 +14,8 @@ package org.eclipse.tm.internal.terminal.model;
     import org.eclipse.tm.terminal.model.ITerminalTextData;
     import org.eclipse.tm.terminal.model.ITerminalTextDataReadOnly;
     import org.eclipse.tm.terminal.model.LineSegment;
    -import org.eclipse.tm.terminal.model.Style;
    -import org.eclipse.tm.terminal.model.StyleColor;
    +import org.eclipse.tm.terminal.model.TerminalColor;
    +import org.eclipse.tm.terminal.model.TerminalStyle;
     
     import junit.framework.TestCase;
     
    @@ -199,9 +199,9 @@ abstract public class AbstractITerminalTextDataTest extends TestCase {
     	}
     
     	public void testGetLineSegments() {
    -		Style s1 = getDefaultStyle();
    -		Style s2 = s1.setBold(true);
    -		Style s3 = s1.setUnderline(true);
    +		TerminalStyle s1 = getDefaultStyle();
    +		TerminalStyle s2 = s1.setBold(true);
    +		TerminalStyle s3 = s1.setUnderline(true);
     		ITerminalTextData term = makeITerminalTextData();
     		term.setDimensions(8, 8);
     		LineSegment[] segments;
    @@ -273,7 +273,7 @@ abstract public class AbstractITerminalTextDataTest extends TestCase {
     
     	}
     
    -	void assertSegment(int col, String text, Style style, LineSegment segment) {
    +	void assertSegment(int col, String text, TerminalStyle style, LineSegment segment) {
     		assertEquals(col, segment.getColumn());
     		assertEqualsTerm(text, segment.getText());
     		assertEquals(style, segment.getStyle());
    @@ -333,26 +333,25 @@ abstract public class AbstractITerminalTextDataTest extends TestCase {
     
     	public void testGetStyle() {
     		ITerminalTextData term = makeITerminalTextData();
    -		Style style = getDefaultStyle();
    +		TerminalStyle style = getDefaultStyle();
     		term.setDimensions(6, 3);
     		for (int line = 0; line < term.getHeight(); line++) {
     			for (int column = 0; column < term.getWidth(); column++) {
     				char c = (char) ('a' + column + line);
    -				term.setChar(line, column, c, style.setForground(StyleColor.getStyleColor("" + c)));
    +				term.setChar(line, column, c, style.setForeground(TerminalColor.getForTest(c)));
     			}
     		}
     		for (int line = 0; line < term.getHeight(); line++) {
     			for (int column = 0; column < term.getWidth(); column++) {
     				char c = (char) ('a' + column + line);
    -				assertSame(style.setForground(StyleColor.getStyleColor("" + c)), term.getStyle(line, column));
    +				assertSame(style.setForeground(TerminalColor.getForTest(c)), term.getStyle(line, column));
     			}
     		}
     
     	}
     
    -	protected Style getDefaultStyle() {
    -		return Style.getStyle(StyleColor.getStyleColor("fg"), StyleColor.getStyleColor("bg"), false, false, false,
    -				false);
    +	protected TerminalStyle getDefaultStyle() {
    +		return TerminalStyle.getDefaultStyle();
     	}
     
     	public void testSetChar() {
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/SnapshotChangesTest.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/SnapshotChangesTest.java
    index da40878a373..9a95ba2f8e8 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/SnapshotChangesTest.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/SnapshotChangesTest.java
    @@ -12,10 +12,10 @@
      *******************************************************************************/
     package org.eclipse.tm.internal.terminal.model;
     
    -import junit.framework.TestCase;
    -
     import org.eclipse.tm.terminal.model.ITerminalTextData;
     
    +import junit.framework.TestCase;
    +
     public class SnapshotChangesTest extends TestCase {
     	/**
     	 * @param change
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataPerformanceTest.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataPerformanceTest.java
    index 1440900c69c..6bfbb44237c 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataPerformanceTest.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataPerformanceTest.java
    @@ -12,8 +12,7 @@ package org.eclipse.tm.internal.terminal.model;
     
     import org.eclipse.tm.terminal.model.ITerminalTextData;
     import org.eclipse.tm.terminal.model.ITerminalTextDataSnapshot;
    -import org.eclipse.tm.terminal.model.Style;
    -import org.eclipse.tm.terminal.model.StyleColor;
    +import org.eclipse.tm.terminal.model.TerminalStyle;
     
     import junit.framework.TestCase;
     
    @@ -46,8 +45,7 @@ public class TerminalTextDataPerformanceTest extends TestCase {
     	}
     
     	private void method0(ITerminalTextData term, String label) {
    -		Style style = Style.getStyle(StyleColor.getStyleColor("fg"), StyleColor.getStyleColor("bg"), false, false,
    -				false, false);
    +		TerminalStyle style = TerminalStyle.getDefaultStyle();
     		initPerformance(term);
     		String s = "This is a test string";
     		long n = 0;
    @@ -90,8 +88,7 @@ public class TerminalTextDataPerformanceTest extends TestCase {
     	}
     
     	private void method1(ITerminalTextData term, String label) {
    -		Style style = Style.getStyle(StyleColor.getStyleColor("fg"), StyleColor.getStyleColor("bg"), false, false,
    -				false, false);
    +		TerminalStyle style = TerminalStyle.getDefaultStyle();
     		initPerformance(term);
     		String s = "This is a test string";
     		long n = 0;
    @@ -115,8 +112,7 @@ public class TerminalTextDataPerformanceTest extends TestCase {
     
     	public void testPerformance2() {
     		TerminalTextData term = new TerminalTextData();
    -		Style style = Style.getStyle(StyleColor.getStyleColor("fg"), StyleColor.getStyleColor("bg"), false, false,
    -				false, false);
    +		TerminalStyle style = TerminalStyle.getDefaultStyle();
     		initPerformance(term);
     		TerminalTextData copy = new TerminalTextData();
     		copy.copy(term);
    @@ -144,8 +140,7 @@ public class TerminalTextDataPerformanceTest extends TestCase {
     	public void testPerformance2a() {
     		TerminalTextData term = new TerminalTextData();
     		ITerminalTextDataSnapshot snapshot = term.makeSnapshot();
    -		Style style = Style.getStyle(StyleColor.getStyleColor("fg"), StyleColor.getStyleColor("bg"), false, false,
    -				false, false);
    +		TerminalStyle style = TerminalStyle.getDefaultStyle();
     		initPerformance(term);
     		TerminalTextData copy = new TerminalTextData();
     		copy.copy(term);
    @@ -178,8 +173,7 @@ public class TerminalTextDataPerformanceTest extends TestCase {
     		ITerminalTextDataSnapshot snapshot = term.makeSnapshot();
     		N = 0;
     		snapshot.addListener(snapshot1 -> N++);
    -		Style style = Style.getStyle(StyleColor.getStyleColor("fg"), StyleColor.getStyleColor("bg"), false, false,
    -				false, false);
    +		TerminalStyle style = TerminalStyle.getDefaultStyle();
     		initPerformance(term);
     		TerminalTextData copy = new TerminalTextData();
     		copy.copy(term);
    @@ -207,8 +201,7 @@ public class TerminalTextDataPerformanceTest extends TestCase {
     
     	public void testPerformance3() {
     		TerminalTextData term = new TerminalTextData();
    -		Style style = Style.getStyle(StyleColor.getStyleColor("fg"), StyleColor.getStyleColor("bg"), false, false,
    -				false, false);
    +		TerminalStyle style = TerminalStyle.getDefaultStyle();
     		initPerformance(term);
     		TerminalTextData copy = new TerminalTextData();
     		copy.copy(term);
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataSnapshotTest.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataSnapshotTest.java
    index c5e8fb2abcf..775f4d2e703 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataSnapshotTest.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataSnapshotTest.java
    @@ -13,8 +13,8 @@ package org.eclipse.tm.internal.terminal.model;
     import org.eclipse.tm.terminal.model.ITerminalTextData;
     import org.eclipse.tm.terminal.model.ITerminalTextDataReadOnly;
     import org.eclipse.tm.terminal.model.ITerminalTextDataSnapshot;
    -import org.eclipse.tm.terminal.model.Style;
    -import org.eclipse.tm.terminal.model.StyleColor;
    +import org.eclipse.tm.terminal.model.TerminalColor;
    +import org.eclipse.tm.terminal.model.TerminalStyle;
     
     import junit.framework.TestCase;
     
    @@ -317,13 +317,12 @@ public class TerminalTextDataSnapshotTest extends TestCase {
     	//
     	public void testGetStyle() {
     		ITerminalTextData term = makeITerminalTextData();
    -		Style style = Style.getStyle(StyleColor.getStyleColor("fg"), StyleColor.getStyleColor("bg"), false, false,
    -				false, false);
    +		TerminalStyle style = TerminalStyle.getDefaultStyle();
     		term.setDimensions(6, 3);
     		for (int line = 0; line < term.getHeight(); line++) {
     			for (int column = 0; column < term.getWidth(); column++) {
     				char c = (char) ('a' + column + line);
    -				term.setChar(line, column, c, style.setForground(StyleColor.getStyleColor("" + c)));
    +				term.setChar(line, column, c, style.setForeground(TerminalColor.getForTest(c)));
     			}
     		}
     		ITerminalTextDataSnapshot snapshot = term.makeSnapshot();
    @@ -332,7 +331,7 @@ public class TerminalTextDataSnapshotTest extends TestCase {
     		for (int line = 0; line < term.getHeight(); line++) {
     			for (int column = 0; column < term.getWidth(); column++) {
     				char c = (char) ('a' + column + line);
    -				assertSame(style.setForground(StyleColor.getStyleColor("" + c)), snapshot.getStyle(line, column));
    +				assertSame(style.setForeground(TerminalColor.getForTest(c)), snapshot.getStyle(line, column));
     			}
     		}
     
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataSnapshotWindowTest.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataSnapshotWindowTest.java
    index b8c980d4cba..c0988c78369 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataSnapshotWindowTest.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataSnapshotWindowTest.java
    @@ -10,12 +10,12 @@
      *******************************************************************************/
     package org.eclipse.tm.internal.terminal.model;
     
    -import junit.framework.TestCase;
    -
     import org.eclipse.tm.terminal.model.ITerminalTextData;
     import org.eclipse.tm.terminal.model.ITerminalTextDataReadOnly;
     import org.eclipse.tm.terminal.model.ITerminalTextDataSnapshot;
     
    +import junit.framework.TestCase;
    +
     public class TerminalTextDataSnapshotWindowTest extends TestCase {
     	String toMultiLineText(ITerminalTextDataReadOnly term) {
     		return TerminalTextTestHelper.toMultiLineText(term);
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataWindowTest.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataWindowTest.java
    index 4dedebdc9ff..a0a12dd8313 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataWindowTest.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextDataWindowTest.java
    @@ -17,8 +17,8 @@ import java.util.ArrayList;
     
     import org.eclipse.tm.terminal.model.ITerminalTextData;
     import org.eclipse.tm.terminal.model.LineSegment;
    -import org.eclipse.tm.terminal.model.Style;
    -import org.eclipse.tm.terminal.model.StyleColor;
    +import org.eclipse.tm.terminal.model.TerminalColor;
    +import org.eclipse.tm.terminal.model.TerminalStyle;
     
     public class TerminalTextDataWindowTest extends AbstractITerminalTextDataTest {
     	int fOffset;
    @@ -137,9 +137,9 @@ public class TerminalTextDataWindowTest extends AbstractITerminalTextDataTest {
     
     	@Override
     	public void testGetLineSegments() {
    -		Style s1 = getDefaultStyle();
    -		Style s2 = s1.setBold(true);
    -		Style s3 = s1.setUnderline(true);
    +		TerminalStyle s1 = getDefaultStyle();
    +		TerminalStyle s2 = s1.setBold(true);
    +		TerminalStyle s3 = s1.setUnderline(true);
     		ITerminalTextData term = makeITerminalTextData();
     		term.setDimensions(8, 8);
     		LineSegment[] segments;
    @@ -209,20 +209,20 @@ public class TerminalTextDataWindowTest extends AbstractITerminalTextDataTest {
     	@Override
     	public void testGetStyle() {
     		ITerminalTextData term = makeITerminalTextData();
    -		Style style = getDefaultStyle();
    +		TerminalStyle style = getDefaultStyle();
     		term.setDimensions(6, 3);
     		for (int line = 0; line < term.getHeight(); line++) {
     			for (int column = 0; column < term.getWidth(); column++) {
     				char c = (char) ('a' + column + line);
    -				term.setChar(line, column, c, style.setForground(StyleColor.getStyleColor("" + c)));
    +				term.setChar(line, column, c, style.setForeground(TerminalColor.getForTest(c)));
     			}
     		}
     		for (int line = 0; line < term.getHeight(); line++) {
     			for (int column = 0; column < term.getWidth(); column++) {
     				char c = (char) ('a' + column + line);
    -				Style s = null;
    +				TerminalStyle s = null;
     				if (line >= fOffset && line < fOffset + fSize)
    -					s = style.setForground(StyleColor.getStyleColor("" + c));
    +					s = style.setForeground(TerminalColor.getForTest(c));
     				assertSame(s, term.getStyle(line, column));
     			}
     		}
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextTestHelper.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextTestHelper.java
    index 945f3299317..7acfc8d7d13 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextTestHelper.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/model/TerminalTextTestHelper.java
    @@ -15,8 +15,8 @@ package org.eclipse.tm.internal.terminal.model;
     
     import org.eclipse.tm.terminal.model.ITerminalTextData;
     import org.eclipse.tm.terminal.model.ITerminalTextDataReadOnly;
    -import org.eclipse.tm.terminal.model.Style;
    -import org.eclipse.tm.terminal.model.StyleColor;
    +import org.eclipse.tm.terminal.model.TerminalColor;
    +import org.eclipse.tm.terminal.model.TerminalStyle;
     
     public class TerminalTextTestHelper {
     	static public String toSimple(ITerminalTextDataReadOnly term) {
    @@ -62,12 +62,11 @@ public class TerminalTextTestHelper {
     	 * @param s each character is one line
     	 */
     	static public void fillSimple(ITerminalTextData term, String s) {
    -		Style style = Style.getStyle(StyleColor.getStyleColor("fg"), StyleColor.getStyleColor("bg"), false, false,
    -				false, false);
    +		TerminalStyle style = TerminalStyle.getDefaultStyle();
     		term.setDimensions(s.length(), 1);
     		for (int i = 0; i < s.length(); i++) {
     			char c = s.charAt(i);
    -			term.setChar(i, 0, c, style.setForground(StyleColor.getStyleColor("" + c)));
    +			term.setChar(i, 0, c, style.setForeground(TerminalColor.getForTest(c)));
     		}
     	}
     
    @@ -99,15 +98,14 @@ public class TerminalTextTestHelper {
     	static public void fill(ITerminalTextData term, int column, int line, String s) {
     		int xx = column;
     		int yy = line;
    -		Style style = Style.getStyle(StyleColor.getStyleColor("fg"), StyleColor.getStyleColor("bg"), false, false,
    -				false, false);
    +		TerminalStyle style = TerminalStyle.getDefaultStyle();
     		for (int i = 0; i < s.length(); i++) {
     			char c = s.charAt(i);
     			if (c == '\n') {
     				yy++;
     				xx = column;
     			} else {
    -				term.setChar(yy, xx, c, style.setForground(StyleColor.getStyleColor("" + c)));
    +				term.setChar(yy, xx, c, style.setForeground(TerminalColor.getForTest(c)));
     				xx++;
     			}
     		}
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/AbstractLineOrientedDataSource.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/AbstractLineOrientedDataSource.java
    index a16cc187c94..923b7f8387c 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/AbstractLineOrientedDataSource.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/AbstractLineOrientedDataSource.java
    @@ -11,7 +11,7 @@
     package org.eclipse.tm.internal.terminal.test.ui;
     
     import org.eclipse.tm.terminal.model.ITerminalTextData;
    -import org.eclipse.tm.terminal.model.Style;
    +import org.eclipse.tm.terminal.model.TerminalStyle;
     
     /**
      * Adds line by line
    @@ -20,7 +20,7 @@ import org.eclipse.tm.terminal.model.Style;
     abstract class AbstractLineOrientedDataSource implements IDataSource {
     	abstract public char[] dataSource();
     
    -	abstract public Style getStyle();
    +	abstract public TerminalStyle getStyle();
     
     	abstract public void next();
     
    @@ -28,7 +28,7 @@ abstract class AbstractLineOrientedDataSource implements IDataSource {
     	public int step(ITerminalTextData terminal) {
     		next();
     		char[] chars = dataSource();
    -		Style style = getStyle();
    +		TerminalStyle style = getStyle();
     		int len;
     		// keep the synchronized block short!
     		synchronized (terminal) {
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/FastDataSource.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/FastDataSource.java
    index ad91ee664f6..a2b38d1e0ab 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/FastDataSource.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/FastDataSource.java
    @@ -10,7 +10,7 @@
      *******************************************************************************/
     package org.eclipse.tm.internal.terminal.test.ui;
     
    -import org.eclipse.tm.terminal.model.Style;
    +import org.eclipse.tm.terminal.model.TerminalStyle;
     
     final class FastDataSource extends AbstractLineOrientedDataSource {
     	char lines[][] = new char[][] {
    @@ -25,7 +25,7 @@ final class FastDataSource extends AbstractLineOrientedDataSource {
     	}
     
     	@Override
    -	public Style getStyle() {
    +	public TerminalStyle getStyle() {
     		return null;
     	}
     
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/FileDataSource.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/FileDataSource.java
    index adcd3739add..669fe792c4e 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/FileDataSource.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/FileDataSource.java
    @@ -14,8 +14,7 @@ import java.io.BufferedReader;
     import java.io.FileReader;
     import java.io.IOException;
     
    -import org.eclipse.tm.terminal.model.Style;
    -import org.eclipse.tm.terminal.model.StyleColor;
    +import org.eclipse.tm.terminal.model.TerminalStyle;
     
     /**
      * Reads the file in an infinite loop.
    @@ -29,11 +28,11 @@ final class FileDataSource extends AbstractLineOrientedDataSource {
     
     	String line;
     
    -	Style style;
    +	TerminalStyle style;
     
    -	Style styleNormal = Style.getStyle(StyleColor.getStyleColor("black"), StyleColor.getStyleColor("white"));
    +	TerminalStyle styleNormal = TerminalStyle.getDefaultStyle();
     
    -	Style styleBold = styleNormal.setBold(true);
    +	TerminalStyle styleBold = styleNormal.setBold(true);
     
     	FileDataSource(String file) {
     		fFile = file;
    @@ -45,7 +44,7 @@ final class FileDataSource extends AbstractLineOrientedDataSource {
     	}
     
     	@Override
    -	public Style getStyle() {
    +	public TerminalStyle getStyle() {
     		return style;
     	}
     
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/LineCountingDataSource.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/LineCountingDataSource.java
    index 1747e23192a..5baef90f258 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/LineCountingDataSource.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/LineCountingDataSource.java
    @@ -10,16 +10,20 @@
      *******************************************************************************/
     package org.eclipse.tm.internal.terminal.test.ui;
     
    -import org.eclipse.tm.terminal.model.Style;
    -import org.eclipse.tm.terminal.model.StyleColor;
    +import static org.eclipse.tm.terminal.model.TerminalColor.BLACK;
    +import static org.eclipse.tm.terminal.model.TerminalColor.BLUE;
    +import static org.eclipse.tm.terminal.model.TerminalColor.RED;
    +import static org.eclipse.tm.terminal.model.TerminalColor.YELLOW;
    +
    +import org.eclipse.tm.terminal.model.TerminalStyle;
     
     final class LineCountingDataSource extends AbstractLineOrientedDataSource {
    -	Style styleNormal = Style.getStyle(StyleColor.getStyleColor("black"), StyleColor.getStyleColor("red"));
    +	TerminalStyle styleNormal = TerminalStyle.getStyle(BLACK, RED);
     
    -	Style styles[] = new Style[] { styleNormal, styleNormal.setBold(true), styleNormal.setForground("blue"),
    -			styleNormal.setForground("yellow"), styleNormal.setBold(true).setUnderline(true),
    -			styleNormal.setReverse(true), styleNormal.setReverse(true).setBold(true),
    -			styleNormal.setReverse(true).setUnderline(true) };
    +	TerminalStyle styles[] = new TerminalStyle[] { styleNormal, styleNormal.setBold(true),
    +			styleNormal.setForeground(BLUE), styleNormal.setForeground(YELLOW),
    +			styleNormal.setBold(true).setUnderline(true), styleNormal.setReverse(true),
    +			styleNormal.setReverse(true).setBold(true), styleNormal.setReverse(true).setUnderline(true) };
     
     	int pos;
     
    @@ -30,7 +34,7 @@ final class LineCountingDataSource extends AbstractLineOrientedDataSource {
     	}
     
     	@Override
    -	public Style getStyle() {
    +	public TerminalStyle getStyle() {
     		return styles[pos % styles.length];
     	}
     
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/RandomDataSource.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/RandomDataSource.java
    index 4ddb10a638c..a13bf7c3101 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/RandomDataSource.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/test/ui/RandomDataSource.java
    @@ -10,19 +10,23 @@
      *******************************************************************************/
     package org.eclipse.tm.internal.terminal.test.ui;
     
    +import static org.eclipse.tm.terminal.model.TerminalColor.BLACK;
    +import static org.eclipse.tm.terminal.model.TerminalColor.GREEN;
    +import static org.eclipse.tm.terminal.model.TerminalColor.RED;
    +import static org.eclipse.tm.terminal.model.TerminalColor.YELLOW;
    +
     import java.util.Random;
     
     import org.eclipse.tm.terminal.model.ITerminalTextData;
    -import org.eclipse.tm.terminal.model.Style;
    -import org.eclipse.tm.terminal.model.StyleColor;
    +import org.eclipse.tm.terminal.model.TerminalStyle;
     
     public class RandomDataSource implements IDataSource {
     	Random fRandom = new Random();
    -	Style styleNormal = Style.getStyle(StyleColor.getStyleColor("black"), StyleColor.getStyleColor("green"));
    -	Style styles[] = new Style[] { styleNormal, styleNormal.setBold(true), styleNormal.setForground("red"),
    -			styleNormal.setForground("yellow"), styleNormal.setBold(true).setUnderline(true),
    -			styleNormal.setReverse(true), styleNormal.setReverse(true).setBold(true),
    -			styleNormal.setReverse(true).setUnderline(true) };
    +	TerminalStyle styleNormal = TerminalStyle.getStyle(BLACK, GREEN);
    +	TerminalStyle styles[] = new TerminalStyle[] { styleNormal, styleNormal.setBold(true),
    +			styleNormal.setForeground(RED), styleNormal.setForeground(YELLOW),
    +			styleNormal.setBold(true).setUnderline(true), styleNormal.setReverse(true),
    +			styleNormal.setReverse(true).setBold(true), styleNormal.setReverse(true).setUnderline(true) };
     
     	@Override
     	public int step(ITerminalTextData terminal) {
    @@ -34,7 +38,7 @@ public class RandomDataSource implements IDataSource {
     				int line = fRandom.nextInt(h);
     				int col = fRandom.nextInt(w);
     				char c = (char) ('A' + fRandom.nextInt('z' - 'A'));
    -				Style style = styles[fRandom.nextInt(styles.length)];
    +				TerminalStyle style = styles[fRandom.nextInt(styles.length)];
     				terminal.setChar(line, col, c, style);
     			}
     		}
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/terminal/model/AllTests.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/terminal/model/AllTests.java
    index 0b38892b92f..2bde0a9c693 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/terminal/model/AllTests.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/terminal/model/AllTests.java
    @@ -12,6 +12,7 @@
      *******************************************************************************/
     package org.eclipse.tm.terminal.model;
     
    +import junit.framework.JUnit4TestAdapter;
     import junit.framework.Test;
     import junit.framework.TestCase;
     import junit.framework.TestSuite;
    @@ -31,7 +32,7 @@ public class AllTests extends TestCase {
     
     	public static Test suite() {
     		TestSuite suite = new TestSuite(AllTests.class.getName());
    -		suite.addTestSuite(StyleColorTest.class);
    +		suite.addTest(new JUnit4TestAdapter(TerminalColorUITest.class));
     		suite.addTestSuite(StyleTest.class);
     		return suite;
     	}
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/terminal/model/StyleColorTest.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/terminal/model/StyleColorTest.java
    deleted file mode 100644
    index e2a48e04fdb..00000000000
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/terminal/model/StyleColorTest.java
    +++ /dev/null
    @@ -1,35 +0,0 @@
    -/*******************************************************************************
    - * Copyright (c) 2007, 2018 Wind River Systems, Inc. and others.
    - * All rights reserved. This program and the accompanying materials
    - * are made available under the terms of the Eclipse Public License 2.0
    - * which accompanies this distribution, and is available at
    - * https://www.eclipse.org/legal/epl-2.0/
    - *
    - * Contributors:
    - * Michael Scharf (Wind River) - initial API and implementation
    - *******************************************************************************/
    -package org.eclipse.tm.terminal.model;
    -
    -import junit.framework.TestCase;
    -
    -public class StyleColorTest extends TestCase {
    -
    -	public void testEqualsObject() {
    -		assertEquals(StyleColor.getStyleColor("foo"), StyleColor.getStyleColor("foo"));
    -		assertFalse(StyleColor.getStyleColor("foox").equals(StyleColor.getStyleColor("foo")));
    -	}
    -
    -	public void testSameObject() {
    -		assertSame(StyleColor.getStyleColor("foo"), StyleColor.getStyleColor("foo"));
    -		assertNotSame(StyleColor.getStyleColor("foox"), StyleColor.getStyleColor("foo"));
    -	}
    -
    -	public void testToString() {
    -		assertEquals("xxx", StyleColor.getStyleColor("xxx").toString());
    -	}
    -
    -	public void testGetName() {
    -		assertEquals("xxx", StyleColor.getStyleColor("xxx").getName());
    -	}
    -
    -}
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/terminal/model/StyleTest.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/terminal/model/StyleTest.java
    index 7e25628af66..9520e614ab4 100644
    --- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/terminal/model/StyleTest.java
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/terminal/model/StyleTest.java
    @@ -13,13 +13,13 @@ package org.eclipse.tm.terminal.model;
     import junit.framework.TestCase;
     
     public class StyleTest extends TestCase {
    -	final StyleColor c1 = StyleColor.getStyleColor("c1");
    -	final StyleColor c2 = StyleColor.getStyleColor("c2");
    -	final StyleColor c3 = StyleColor.getStyleColor("c3");
    +	final TerminalColor c1 = TerminalColor.getForTest(1);
    +	final TerminalColor c2 = TerminalColor.getForTest(2);
    +	final TerminalColor c3 = TerminalColor.getForTest(3);
     
     	public void testGetStyle() {
    -		Style s1 = Style.getStyle(c1, c2, true, false, true, false);
    -		Style s2 = Style.getStyle(c1, c2, true, false, true, false);
    +		TerminalStyle s1 = TerminalStyle.getStyle(c1, c2, true, false, true, false);
    +		TerminalStyle s2 = TerminalStyle.getStyle(c1, c2, true, false, true, false);
     		assertEquals(s1, s2);
     		assertSame(s1, s2);
     		s1 = s1.setBlink(!s1.isBlink());
    @@ -29,37 +29,37 @@ public class StyleTest extends TestCase {
     		assertSame(s1, s2);
     	}
     
    -	public void testSetForground() {
    -		Style s1 = Style.getStyle(c1, c2, true, false, true, false);
    -		Style s2 = s1;
    -		s2 = s1.setForground(c3);
    +	public void testSetForeground() {
    +		TerminalStyle s1 = TerminalStyle.getStyle(c1, c2, true, false, true, false);
    +		TerminalStyle s2 = s1;
    +		s2 = s1.setForeground(c3);
     		assertNotSame(s1, s2);
     		assertFalse(s1.equals(s2));
    -		assertSame(s2.getForground(), c3);
    -		assertSame(s1.getForground(), c1);
    -		assertSame(s1.getBackground(), c2);
    -		assertSame(s2.getBackground(), c2);
    -		s2 = s2.setForground(c1);
    +		assertSame(s2.getForegroundTerminalColor(), c3);
    +		assertSame(s1.getForegroundTerminalColor(), c1);
    +		assertSame(s1.getBackgroundTerminalColor(), c2);
    +		assertSame(s2.getBackgroundTerminalColor(), c2);
    +		s2 = s2.setForeground(c1);
     		assertSame(s1, s2);
     	}
     
     	public void testSetBackground() {
    -		Style s1 = Style.getStyle(c1, c2, true, false, true, false);
    -		Style s2 = s1;
    +		TerminalStyle s1 = TerminalStyle.getStyle(c1, c2, true, false, true, false);
    +		TerminalStyle s2 = s1;
     		s2 = s1.setBackground(c3);
     		assertNotSame(s1, s2);
     		assertFalse(s1.equals(s2));
    -		assertSame(s2.getForground(), c1);
    -		assertSame(s1.getForground(), c1);
    -		assertSame(s1.getBackground(), c2);
    -		assertSame(s2.getBackground(), c3);
    +		assertSame(s2.getForegroundTerminalColor(), c1);
    +		assertSame(s1.getForegroundTerminalColor(), c1);
    +		assertSame(s1.getBackgroundTerminalColor(), c2);
    +		assertSame(s2.getBackgroundTerminalColor(), c3);
     		s2 = s2.setBackground(c2);
     		assertSame(s1, s2);
     	}
     
     	public void testSetBold() {
    -		Style s1 = getDefaultStyle();
    -		Style s2 = s1;
    +		TerminalStyle s1 = getDefaultStyle();
    +		TerminalStyle s2 = s1;
     		assertSame(s1, s2);
     		assertFalse(s2.isBold());
     		s2 = s2.setBold(true);
    @@ -71,8 +71,8 @@ public class StyleTest extends TestCase {
     	}
     
     	public void testSetBlink() {
    -		Style s1 = getDefaultStyle();
    -		Style s2 = s1;
    +		TerminalStyle s1 = getDefaultStyle();
    +		TerminalStyle s2 = s1;
     		assertSame(s1, s2);
     		assertFalse(s2.isBlink());
     		s2 = s2.setBlink(true);
    @@ -84,8 +84,8 @@ public class StyleTest extends TestCase {
     	}
     
     	public void testSetUnderline() {
    -		Style s1 = getDefaultStyle();
    -		Style s2 = s1;
    +		TerminalStyle s1 = getDefaultStyle();
    +		TerminalStyle s2 = s1;
     		assertSame(s1, s2);
     		assertFalse(s2.isUnderline());
     		s2 = s2.setUnderline(true);
    @@ -97,8 +97,8 @@ public class StyleTest extends TestCase {
     	}
     
     	public void testSetReverse() {
    -		Style s1 = getDefaultStyle();
    -		Style s2 = s1;
    +		TerminalStyle s1 = getDefaultStyle();
    +		TerminalStyle s2 = s1;
     		assertSame(s1, s2);
     		assertFalse(s2.isReverse());
     		s2 = s2.setReverse(true);
    @@ -109,8 +109,8 @@ public class StyleTest extends TestCase {
     		assertFalse(s2.isReverse());
     	}
     
    -	private Style getDefaultStyle() {
    -		return Style.getStyle(c1, c2, false, false, false, false);
    +	private TerminalStyle getDefaultStyle() {
    +		return TerminalStyle.getStyle(c1, c2, false, false, false, false);
     	}
     
     }
    diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/terminal/model/TerminalColorUITest.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/terminal/model/TerminalColorUITest.java
    new file mode 100644
    index 00000000000..588bcf63f4e
    --- /dev/null
    +++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/terminal/model/TerminalColorUITest.java
    @@ -0,0 +1,82 @@
    +/*******************************************************************************
    + * Copyright (c) 2020 Kichwa Coders Canada Inc. and others.
    + * All rights reserved. This program and the accompanying materials
    + * are made available under the terms of the Eclipse Public License 2.0
    + * which accompanies this distribution, and is available at
    + * https://www.eclipse.org/legal/epl-2.0/
    + *******************************************************************************/
    +package org.eclipse.tm.terminal.model;
    +
    +import static org.eclipse.tm.terminal.model.TerminalColor.BLACK;
    +import static org.eclipse.tm.terminal.model.TerminalColor.BLUE;
    +import static org.eclipse.tm.terminal.model.TerminalColor.CYAN;
    +import static org.eclipse.tm.terminal.model.TerminalColor.GREEN;
    +import static org.eclipse.tm.terminal.model.TerminalColor.MAGENTA;
    +import static org.eclipse.tm.terminal.model.TerminalColor.RED;
    +import static org.eclipse.tm.terminal.model.TerminalColor.WHITE;
    +import static org.eclipse.tm.terminal.model.TerminalColor.YELLOW;
    +import static org.junit.Assert.assertEquals;
    +import static org.junit.Assert.assertNotEquals;
    +
    +import org.eclipse.swt.widgets.Display;
    +import org.junit.AfterClass;
    +import org.junit.BeforeClass;
    +import org.junit.Test;
    +
    +/**
    + * This is a UI test because {@link TerminalColor#convertColor(boolean, boolean)
    + * requires a Display to operate the ColorRegistry.
    + */
    +public class TerminalColorUITest {
    +
    +	private static Display display = null;
    +
    +	@BeforeClass
    +	public static void createDisplay() {
    +		Display current = Display.getCurrent();
    +		if (current == null) {
    +			display = new Display();
    +		}
    +	}
    +
    +	@AfterClass
    +	public static void disposeDisplay() {
    +		if (display != null) {
    +			display.dispose();
    +		}
    +	}
    +
    +	@Test
    +	public void testInversionsStandard() {
    +
    +		assertEquals(BLACK.convertColor(false, false), WHITE.convertColor(true, false));
    +		assertNotEquals(BLACK.convertColor(false, false), WHITE.convertColor(false, false));
    +
    +		assertEquals(RED.convertColor(false, false), RED.convertColor(true, false));
    +		assertEquals(GREEN.convertColor(false, false), GREEN.convertColor(true, false));
    +		assertEquals(YELLOW.convertColor(false, false), YELLOW.convertColor(true, false));
    +		assertEquals(BLUE.convertColor(false, false), BLUE.convertColor(true, false));
    +		assertEquals(MAGENTA.convertColor(false, false), MAGENTA.convertColor(true, false));
    +		assertEquals(CYAN.convertColor(false, false), CYAN.convertColor(true, false));
    +
    +		assertEquals(WHITE.convertColor(false, false), BLACK.convertColor(true, false));
    +		assertNotEquals(WHITE.convertColor(false, false), BLACK.convertColor(false, false));
    +
    +	}
    +
    +	@Test
    +	public void testInversionsBright() {
    +		assertEquals(BLACK.convertColor(false, true), WHITE.convertColor(true, true));
    +		assertNotEquals(BLACK.convertColor(false, true), WHITE.convertColor(false, true));
    +
    +		assertEquals(RED.convertColor(false, true), RED.convertColor(true, true));
    +		assertEquals(GREEN.convertColor(false, true), GREEN.convertColor(true, true));
    +		assertEquals(YELLOW.convertColor(false, true), YELLOW.convertColor(true, true));
    +		assertEquals(BLUE.convertColor(false, true), BLUE.convertColor(true, true));
    +		assertEquals(MAGENTA.convertColor(false, true), MAGENTA.convertColor(true, true));
    +		assertEquals(CYAN.convertColor(false, true), CYAN.convertColor(true, true));
    +
    +		assertEquals(WHITE.convertColor(false, true), BLACK.convertColor(true, true));
    +		assertNotEquals(WHITE.convertColor(false, true), BLACK.convertColor(false, true));
    +	}
    +}