Remove Theme class and code related to it

This is a preparation for loading themes from CSS files.
This commit is contained in:
Kai S. K. Engelbart 2020-06-08 09:14:57 +02:00
parent 0ba46f6d46
commit 4123abf24f
8 changed files with 13 additions and 538 deletions

View File

@ -6,8 +6,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.prefs.Preferences;
import envoy.client.ui.Color;
import envoy.client.ui.Theme;
import envoy.util.SerializationUtils;
/**
@ -28,18 +26,12 @@ public class Settings {
// Actual settings accessible by the rest of the application
private Map<String, SettingsItem<?>> items;
private Map<String, Theme> themes;
/**
* Settings are stored in this file.
*/
private static final File settingsFile = new File(ClientConfig.getInstance().getHomeDirectory(), "settings.ser");
/**
* User-defined themes are stored inside this file.
*/
private static final File themeFile = new File(ClientConfig.getInstance().getHomeDirectory(), "themes.ser");
/**
* Singleton instance of this class.
*/
@ -59,22 +51,6 @@ public class Settings {
items = new HashMap<>();
}
supplementDefaults();
// Load themes from theme file
try {
themes = SerializationUtils.read(themeFile, HashMap.class);
} catch (ClassNotFoundException | IOException e1) {
themes = new HashMap<>();
setCurrentTheme("dark");
}
// Load standard themes not defined in the themes file
themes.put("dark",
new Theme("dark", Color.black, Color.darkGray, Color.white, new Color(165, 60, 232), Color.white, Color.orange, Color.blue,
Color.white, Color.white));
themes.put("light",
new Theme("light", new Color(235, 235, 235), Color.white, Color.white, Color.darkGray, Color.black, Color.orange, Color.darkGray,
Color.black, Color.black));
}
/**
@ -95,9 +71,6 @@ public class Settings {
// Save settings to settings file
SerializationUtils.write(settingsFile, items);
// Save themes to theme file
SerializationUtils.write(themeFile, themes);
}
private void supplementDefaults() {
@ -107,40 +80,19 @@ public class Settings {
}
/**
* Adds new theme to the theme map.
*
* @param theme the {@link Theme} to add
* @since Envoy Client v0.2-alpha
*/
public void addNewThemeToMap(Theme theme) { getThemes().put(theme.getThemeName(), theme); }
/**
* @return the name of the currently active {@link Theme}
* @return the name of the currently active theme
* @since Envoy Client v0.2-alpha
*/
public String getCurrentThemeName() { return (String) items.get("currentTheme").get(); }
/**
* @return the currently active {@link Theme}
* @since Envoy Client v0.1-beta
*/
public Theme getCurrentTheme() { return getTheme(getCurrentThemeName()); }
/**
* Sets the name of the current {@link Theme}.
* Sets the name of the current theme.
*
* @param themeName the name to set
* @since Envoy Client v0.2-alpha
*/
public void setCurrentTheme(String themeName) { ((SettingsItem<String>) items.get("currentTheme")).set(themeName); }
/**
* @return whether the current {@link Theme} is one of the default themes.
* Currently checks for dark and light theme.
* @since Envoy Client v0.1-beta
*/
public boolean isUsingDefaultTheme() { return getCurrentThemeName().equals("dark") || getCurrentThemeName().equals("light"); }
/**
* @return {@code true}, if pressing the {@code Enter} key suffices to send a
* message. Otherwise it has to be pressed in conjunction with the
@ -182,25 +134,4 @@ public class Settings {
* @param items the items to set
*/
public void setItems(Map<String, SettingsItem<?>> items) { this.items = items; }
/**
* @return a {@code Map<String, Theme>} of all themes with their names as keys
* @since Envoy Client v0.2-alpha
*/
public Map<String, Theme> getThemes() { return themes; }
/**
* Sets the {@code Map<String, Theme>} of all themes with their names as keys
*
* @param themes the theme map to set
* @since Envoy Client v0.2-alpha
*/
public void setThemes(Map<String, Theme> themes) { this.themes = themes; }
/**
* @param themeName the name of the {@link Theme} to get
* @return the {@link Theme} with the specified name
* @since Envoy Client v0.3-alpha
*/
public Theme getTheme(String themeName) { return themes.get(themeName); }
}

View File

@ -22,7 +22,7 @@ public class SettingsItem<T> implements Serializable {
private T value;
private String userFriendlyName, description;
private transient Consumer<T> changeHandler;
private transient Consumer<T> changeHandler;
private static final long serialVersionUID = 1L;

View File

@ -1,6 +1,5 @@
package envoy.client.event;
import envoy.client.ui.Theme;
import envoy.event.Event;
/**
@ -11,16 +10,16 @@ import envoy.event.Event;
* @author Kai S. K. Engelbart
* @since Envoy Client v0.2-alpha
*/
public class ThemeChangeEvent extends Event<Theme> {
public class ThemeChangeEvent extends Event<String> {
private static final long serialVersionUID = 0L;
/**
* Initializes a {@link ThemeChangeEvent} conveying information about the change
* of the {@link Theme} currently in use
* of the theme currently in use.
*
* @param theme the new currently used {@link Theme} object
* @param theme the name of the new theme
* @since Envoy Client v0.2-alpha
*/
public ThemeChangeEvent(Theme theme) { super(theme); }
public ThemeChangeEvent(String theme) { super(theme); }
}

View File

@ -1,114 +0,0 @@
package envoy.client.ui;
import java.awt.color.ColorSpace;
/**
* This class further develops {@link java.awt.Color} by adding extra methods
* and more default colors.
*
* Project: <strong>envoy-client</strong><br>
* File: <strong>Color.java</strong><br>
* Created: <strong>23.12.2019</strong><br>
*
* @author Kai S. K. Engelbart
* @since Envoy Client v0.3-alpha
*/
@SuppressWarnings("javadoc")
public class Color extends java.awt.Color {
/**
* The color white. In the default sRGB space.
*/
public static final Color white = new Color(255, 255, 255);
/**
* The color light gray. In the default sRGB space.
*/
public static final Color lightGray = new Color(192, 192, 192);
/**
* The color gray. In the default sRGB space.
*/
public static final Color gray = new Color(128, 128, 128);
/**
* The color dark gray. In the default sRGB space.
*/
public static final Color darkGray = new Color(64, 64, 64);
/**
* The color black. In the default sRGB space.
*/
public static final Color black = new Color(0, 0, 0);
/**
* The color red. In the default sRGB space.
*/
public static final Color red = new Color(255, 0, 0);
/**
* The color pink. In the default sRGB space.
*/
public static final Color pink = new Color(255, 175, 175);
/**
* The color orange. In the default sRGB space.
*/
public static final Color orange = new Color(255, 200, 0);
/**
* The color yellow. In the default sRGB space.
*/
public static final Color yellow = new Color(255, 255, 0);
/**
* The color green. In the default sRGB space.
*/
public static final Color green = new Color(0, 255, 0);
/**
* The color magenta. In the default sRGB space.
*/
public static final Color magenta = new Color(255, 0, 255);
/**
* The color cyan. In the default sRGB space.
*/
public static final Color cyan = new Color(0, 255, 255);
/**
* The color blue. In the default sRGB space.
*/
public static final Color blue = new Color(0, 0, 255);
private static final long serialVersionUID = 0L;
public Color(java.awt.Color other) { this(other.getRGB()); }
public Color(int rgb) { super(rgb); }
public Color(int rgba, boolean hasalpha) { super(rgba, hasalpha); }
public Color(int r, int g, int b) { super(r, g, b); }
public Color(float r, float g, float b) { super(r, g, b); }
public Color(ColorSpace cspace, float[] components, float alpha) { super(cspace, components, alpha); }
public Color(int r, int g, int b, int a) { super(r, g, b, a); }
public Color(float r, float g, float b, float a) { super(r, g, b, a); }
/**
* @return the inversion of this {@link Color} by replacing the red, green and
* blue values by subtracting them form 255
* @since Envoy Client v0.3-alpha
*/
public Color invert() { return new Color(255 - getRed(), 255 - getGreen(), 255 - getBlue()); }
/**
* @return the hex value of this {@link Color}
* @since Envoy Client v0.3-alpha
*/
public String toHex() { return String.format("#%02x%02x%02x", getRed(), getGreen(), getBlue()); }
}

View File

@ -1,198 +0,0 @@
package envoy.client.ui;
import java.awt.Component;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
/**
* This class defines a menu that will be automatically called if
* {@link MouseEvent#isPopupTrigger()} returns true for the parent component.
* The user has the possibility to directly add actions to be performed when
* clicking on the element with the selected String. Additionally, for each
* element an {@link Icon} can be added, but it must not be.
* If the key(text) of an element starts with one of the predefined values, a
* special component will be called: either a {@link JRadioButtonMenuItem}, a
* {@link JCheckBoxMenuItem} or a {@link JMenu} will be created.<br>
* <br>
* Project: <strong>envoy-client</strong><br>
* File: <strong>ContextMenu.java</strong><br>
* Created: <strong>17 Mar 2020</strong><br>
*
* @author Leon Hofmeister
* @since Envoy Client v0.1-beta
*/
public class ContextMenu extends JPopupMenu {
private static final long serialVersionUID = 0L;
/**
* If a key starts with this String, a {@link JCheckBoxMenuItem} will be created
*/
public static final String checkboxMenuItem = "ChBoMI";
/**
* If a key starts with this String, a {@link JRadioButtonMenuItem} will be
* created
*/
public static final String radioButtonMenuItem = "RaBuMI";
/**
* If a key starts with this String, a {@link JMenu} will be created
*/
public static final String subMenuItem = "SubMI";
private Map<String, ActionListener> items = new HashMap<>();
private Map<String, Icon> icons = new HashMap<>();
private Map<String, Integer> mnemonics = new HashMap<>();
private ButtonGroup radioButtonGroup = new ButtonGroup();
private boolean built = false;
/**
* @param parent the component which will call this
* {@link ContextMenu}
* @since Envoy Client v0.1-beta
*/
public ContextMenu(Component parent) { setInvoker(parent); }
/**
* @param label the string that a UI may use to display as a title
* for the pop-up menu
* @param parent the component which will call this
* {@link ContextMenu}
* @param itemsWithActions a map of all strings to be displayed with according
* actions
* @param itemIcons the icons to be displayed before a name, if wanted.
* Only keys in here will have an Icon displayed. More
* precisely, all keys here not included in the first
* map will be thrown out.
* @param itemMnemonics the keyboard shortcuts that need to be pressed to
* automatically execute the {@link JMenuItem} with the
* given text
* @since Envoy Client v0.1-beta
*/
public ContextMenu(String label, Component parent, Map<String, ActionListener> itemsWithActions, Map<String, Icon> itemIcons,
Map<String, Integer> itemMnemonics) {
super(label);
setInvoker(parent);
this.items = (itemsWithActions != null) ? itemsWithActions : items;
this.icons = (itemIcons != null) ? itemIcons : icons;
this.mnemonics = (itemMnemonics != null) ? itemMnemonics : mnemonics;
}
/**
* Prepares the PopupMenu to be displayed. Should only be used once all map
* values have been set.
*
* @return this instance of {@link ContextMenu} to allow chaining behind the
* constructor
* @since Envoy Client v0.1-beta
*/
public ContextMenu build() {
items.forEach((text, action) -> {
// case radio button wanted
AbstractButton item;
if (text.startsWith(radioButtonMenuItem)) {
item = new JRadioButtonMenuItem(text.substring(radioButtonMenuItem.length()), icons.containsKey(text) ? icons.get(text) : null);
radioButtonGroup.add(item);
// case check box wanted
} else if (text.startsWith(checkboxMenuItem))
item = new JCheckBoxMenuItem(text.substring(checkboxMenuItem.length()), icons.containsKey(text) ? icons.get(text) : null);
// case sub-menu wanted
else if (text.startsWith(subMenuItem)) item = new JMenu(text.substring(subMenuItem.length()));
else // normal JMenuItem wanted
item = new JMenuItem(text, icons.containsKey(text) ? icons.get(text) : null);
item.addActionListener(action);
if (mnemonics.containsKey(text)) item.setMnemonic(mnemonics.get(text));
add(item);
});
if (getInvoker() != null) {
getInvoker().addMouseListener(getShowingListener());
built = true;
}
return this;
}
/**
* @param label the string that a UI may use to display as a title for the
* pop-up menu.
* @since Envoy Client v0.1-beta
*/
public ContextMenu(String label) { super(label); }
private MouseAdapter getShowingListener() {
return new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) { action(e); }
@Override
public void mousePressed(MouseEvent e) { action(e); }
@Override
public void mouseReleased(MouseEvent e) { action(e); }
private void action(MouseEvent e) {
if (!built) build();
if (e.isPopupTrigger()) // hides the menu if already visible
if (!isVisible()) show(e.getComponent(), e.getX(), e.getY());
else setVisible(false);
}
};
}
/**
* Removes all subcomponents of this menu.
*
* @since Envoy Client v0.1-beta
*/
public void clear() {
removeAll();
items = new HashMap<>();
icons = new HashMap<>();
mnemonics = new HashMap<>();
}
/**
* @return the items
* @since Envoy Client v0.1-beta
*/
public Map<String, ActionListener> getItems() { return items; }
/**
* @param items the items with the displayed text and the according action to
* take once called
* @since Envoy Client v0.1-beta
*/
public void setItems(Map<String, ActionListener> items) { this.items = items; }
/**
* @return the icons
* @since Envoy Client v0.1-beta
*/
public Map<String, Icon> getIcons() { return icons; }
/**
* @param icons the icons to set
* @since Envoy Client v0.1-beta
*/
public void setIcons(Map<String, Icon> icons) { this.icons = icons; }
/**
* @return the mnemonics (the keyboard shortcuts that automatically execute the
* command for a {@link JMenuItem} with corresponding text)
* @since Envoy Client v0.1-beta
*/
public Map<String, Integer> getMnemonics() { return mnemonics; }
/**
* @param mnemonics the keyboard shortcuts that need to be pressed to
* automatically execute the {@link JMenuItem} with the given
* text
* @since Envoy Client v0.1-beta
*/
public void setMnemonics(Map<String, Integer> mnemonics) { this.mnemonics = mnemonics; }
}

View File

@ -15,8 +15,11 @@ import envoy.event.EventBus;
/**
* Manages a stack of scenes. The most recently added scene is displayed inside
* a stage. When a scene is removed from the stack, its predecessor is
* displayed.<br>
* <br>
* displayed.
* <p>
* When a scene is loaded, the style sheet for the current theme is applied to
* it.
* <p>
* Project: <strong>envoy-client</strong><br>
* File: <strong>SceneContext.java</strong><br>
* Created: <strong>06.06.2020</strong><br>
@ -89,7 +92,7 @@ public final class SceneContext {
private void applyCSS() {
if (!sceneStack.isEmpty()) {
final var styleSheets = stage.getScene().getStylesheets();
final var themeCSS = "/css/" + (settings.isUsingDefaultTheme() ? settings.getCurrentThemeName() : "custom") + ".css";
final var themeCSS = "/css/" + settings.getCurrentThemeName() + ".css";
styleSheets.clear();
styleSheets.addAll(getClass().getResource("/css/base.css").toExternalForm(), getClass().getResource(themeCSS).toExternalForm());
}

View File

@ -1,146 +0,0 @@
package envoy.client.ui;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* Project: <strong>envoy-client</strong><br>
* File: <strong>Theme.java</strong><br>
* Created: <strong>23 Nov 2019</strong><br>
*
* @author Maximilian K&auml;fer
* @since Envoy Client v0.2-alpha
*/
public class Theme implements Serializable {
private static final long serialVersionUID = 0L;
private String themeName;
private Map<String, Color> colors = new HashMap<>();
/**
* Initializes a {@link Theme} with all colors relevant to the application GUI.
*
* @param themeName the name of the {@link Theme}
* @param backgroundColor the background color
* @param cellColor the cell color
* @param interactableForegroundColor the color of interactable foreground UI
* elements
* @param interactableBackgroundColor the color of interactable background UI
* elements
* @param textColor the color normal text should be displayed
* in
* @param dateColorChat the color of chat message metadata
* @param selectionColor the section color
* @param typingMessageColor the color of currently typed messages
* @param userNameColor the color of user names
* @since Envoy Client v0.2-alpha
*/
public Theme(String themeName, Color backgroundColor, Color cellColor, Color interactableForegroundColor, Color interactableBackgroundColor,
Color textColor, Color dateColorChat, Color selectionColor, Color typingMessageColor, Color userNameColor) {
this.themeName = themeName;
colors.put("backgroundColor", backgroundColor);
colors.put("cellColor", cellColor);
colors.put("interactableForegroundColor", interactableForegroundColor);
colors.put("interactableBackgroundColor", interactableBackgroundColor);
colors.put("textColor", textColor);
colors.put("dateColorChat", dateColorChat);
colors.put("selectionColor", selectionColor);
colors.put("typingMessageColor", typingMessageColor);
colors.put("userNameColor", userNameColor);
}
/**
* Initializes a {@link Theme} by copying all parameters except for the name
* from another {@link Theme} instance.
*
* @param name the name of the {@link Theme}
* @param other the {@link Theme} to copy
* @since Envoy Client v0.2-alpha
*/
public Theme(String name, Theme other) {
themeName = name;
colors.putAll(other.colors);
}
/**
* @return a {@code Map<String, Color>} of all colors defined for this theme
* with their names as keys
* @since Envoy Client v0.2-alpha
*/
public Map<String, Color> getColors() { return colors; }
/**
* @return name of the theme
* @since Envoy Client v0.2-alpha
*/
public String getThemeName() { return themeName; }
/**
* @return interactableForegroundColor
* @since Envoy Client v0.2-alpha
*/
public Color getInteractableForegroundColor() { return colors.get("interactableForegroundColor"); }
/**
* @return the {@link Color} in which the text content of a message should be
* displayed
* @since Envoy Client v0.2-alpha
*/
public Color getTextColor() { return colors.get("textColor"); }
/**
* @return the {@link Color} in which the creation date of a message should be
* displayed
* @since Envoy Client v0.2-alpha
*/
public Color getDateColor() { return colors.get("dateColorChat"); }
/**
* @return selectionColor
* @since Envoy Client v0.2-alpha
*/
public Color getSelectionColor() { return colors.get("selectionColor"); }
/**
* @return typingMessageColor
* @since Envoy Client v0.2-alpha
*/
public Color getTypingMessageColor() { return colors.get("typingMessageColor"); }
/**
* @return backgroundColor
* @since Envoy Client v0.2-alpha
*/
public Color getBackgroundColor() { return colors.get("backgroundColor"); }
/**
* @return cellColor
* @since Envoy Client v0.2-alpha
*/
public Color getCellColor() { return colors.get("cellColor"); }
/**
* @return interactableBackgroundColor
* @since Envoy Client v0.2-alpha
*/
public Color getInteractableBackgroundColor() { return colors.get("interactableBackgroundColor"); }
/**
* @return userNameColor
* @since Envoy Client v0.2-alpha
*/
public Color getUserNameColor() { return colors.get("userNameColor"); }
/**
* Sets the a specific {@link Color} in this theme to a new {@link Color}
*
* @param colorName the name of the {@link Color} to set
* @param newColor the new {@link Color} to be set
* @since Envoy 0.2-alpha
*/
public void setColor(String colorName, Color newColor) { colors.put(colorName, newColor); }
}