package org.basex.gui;
import static org.basex.gui.GUIMenuCmd.*;
import java.awt.*;
import javax.swing.*;
import org.basex.core.*;
import org.basex.gui.layout.*;
import org.basex.gui.view.*;
import org.basex.gui.view.map.*;
import org.basex.util.*;
/**
* GUI Constants used in different views.
*
* To add a new view, please proceed as follows:<br/>
* <br/>
* All views have unique names, which are defined below.
* The following steps are necessary to add a new view
* (the implementation of the existing views might help you):
*
* <ul>
* <li> define a unique name for your view (e.g. {@code map})</li>
* <li> add a string for your view, as shown below</li>
* <li> add the string in the {@link #VIEWS} string below</li>
* <li> create your view implementation in a new sub package
* (e.g. {@link MapView}).
* <li> add a new {@link View} instance in the {@link GUI} constructor.</li>
* </ul>
*
* Add some more code to allow switching on/off your view:
*
* <ul>
* <li> add a boolean visibility flag with the view name included
* in the {@link GUIOptions} class {@link GUIOptions#SHOWMAP})</li>
* <li> add strings for the menu text.</li>
* <li> optionally add localized translations in the .lang files
* (e.g. {@code c_showmap} and {@code c_showmaptt})</li>
* <li> add a corresponding command in the {@link GUIMenuCmd} class
* (e.g. {@link GUIMenuCmd#C_SHOWMAP})and add a reference in the
* {@link #MENUITEMS} menu structure</li>
* </ul>
*
* @author BaseX Team 2005-17, BSD License
* @author Christian Gruen
*/
public final class GUIConstants {
// DUMMY OBJECTS ============================================================
/** Dummy textfield. */
public static final JTextField TEXTFIELD = new JTextField();
/** Dummy label, used for size calculations. */
public static final JLabel LABEL = new JLabel();
// VIEW NAMES ===============================================================
/** Internal name of the Map View. */
public static final String MAPVIEW = "map";
/** Internal name of the Tree View. */
public static final String FOLDERVIEW = "folder";
/** Internal name of the Text View. */
public static final String TEXTVIEW = "text";
/** Internal name of the Table View. */
public static final String TABLEVIEW = "table";
/** Internal name of the Info View. */
public static final String INFOVIEW = "info";
/** Internal name of the Explore View. */
public static final String EXPLOREVIEW = "explore";
/** Internal name of the Plot View. */
public static final String PLOTVIEW = "plot";
/** Internal name of the Tree View. */
public static final String TREEVIEW = "tree";
/** Internal name of the Editor View. */
public static final String EDITORVIEW = "editor";
/**
* Default GUI Layout. The layout is formatted as follows:
* The character 'H' or 'V' adds a new horizontal or vertical level,
* and a level is closed again with the '-' character. All views are
* separated with spaces, and all views must be specified in this layout.
* This layout is displayed as soon as a database is opened.
*/
public static final String VIEWS = "V H " + EDITORVIEW + ' ' + FOLDERVIEW +
' ' + MAPVIEW + ' ' + PLOTVIEW + ' ' + " - H " + TEXTVIEW + ' ' + INFOVIEW +
' ' + TABLEVIEW + ' ' + TREEVIEW + ' ' + EXPLOREVIEW + " - -";
// TOOLBAR ==================================================================
/** Toolbar entries, containing the button commands. */
static final GUIMenuCmd[] TOOLBAR = {
C_CREATE, C_OPEN_MANAGE, C_INFO, C_CLOSE, null,
C_GOHOME, C_GOBACK, C_GOUP, C_GOFORWARD, null,
C_SHOWEDITOR, C_SHOWRESULT, C_SHOWINFO, null, C_SHOWMAP, C_SHOWTREE,
C_SHOWFOLDER, C_SHOWPLOT, C_SHOWTABLE, C_SHOWEXPLORE
};
// MENUBARS =================================================================
/** Top menu entries. */
static final String[] MENUBAR = {
Text.DATABASE, Text.EDITOR, Text.VIEW, Text.VISUALIZATION, Text.OPTIONS, Text.HELP
};
/**
* Two-dimensional menu entries, containing the menu item commands.
* {@link GUIPopupCmd#SEPARATOR} references serve as menu separators.
*/
static final GUICommand[][] MENUITEMS = { {
C_CREATE, C_OPEN_MANAGE, SEPARATOR,
C_INFO, C_EXPORT, C_CLOSE, SEPARATOR,
Prop.MAC ? null : C_EXIT
}, {
C_EDITNEW, C_EDITOPEN, C_EDITREOPEN, C_EDITSAVE, C_EDITSAVEAS, C_EDITCLOSE,
SEPARATOR, C_FORMAT, C_COMMENT, C_SORT, SEPARATOR, C_LOWERCASE, C_UPPERCASE, C_TITLECASE,
SEPARATOR, C_NEXTERROR, C_JUMPFILE
}, {
C_SHOWEDITOR, C_SHOWPROJECT, C_FILESEARCH, SEPARATOR,
C_SHOWRESULT, C_SHOWINFO, SEPARATOR, C_SHOWBUTTONS, C_SHOWINPUT, C_SHOWSTATUS,
GUIMacOSX.nativeFullscreen() ? null : C_FULL
}, {
C_SHOWMAP, C_SHOWTREE, C_SHOWFOLDER, C_SHOWPLOT, C_SHOWTABLE,
C_SHOWEXPLORE,
}, {
C_RTEXEC, C_RTFILTER, SEPARATOR,
C_COLOR, C_FONTS, Prop.MAC ? null : SEPARATOR,
C_PACKAGES, Prop.MAC ? null : C_PREFS
}, {
C_HELP, Prop.MAC ? null : SEPARATOR,
C_COMMUNITY, C_UPDATES, Prop.MAC ? null : SEPARATOR,
Prop.MAC ? null : C_ABOUT
}};
/** Context menu entries. */
public static final GUIMenuCmd[] POPUP = {
C_GOBACK, C_FILTER, null, C_COPY, C_PASTE, C_DELETE, C_INSERT, C_EDIT, null, C_COPYPATH
};
// CURSORS ==================================================================
/** Arrow cursor. */
public static final Cursor CURSORARROW = new Cursor(Cursor.DEFAULT_CURSOR);
/** Hand cursor. */
public static final Cursor CURSORHAND = new Cursor(Cursor.HAND_CURSOR);
/** Wait cursor. */
public static final Cursor CURSORWAIT = new Cursor(Cursor.WAIT_CURSOR);
/** Left/Right arrow cursor. */
public static final Cursor CURSORMOVEH = new Cursor(Cursor.E_RESIZE_CURSOR);
/** Move cursor. */
public static final Cursor CURSORMOVEV = new Cursor(Cursor.N_RESIZE_CURSOR);
/** Text cursor. */
public static final Cursor CURSORTEXT = new Cursor(Cursor.TEXT_CURSOR);
/** Move cursor. */
public static final Cursor CURSORMOVE = new Cursor(Cursor.MOVE_CURSOR);
/** Icon type. */
public enum Msg {
/** Warning message. */
WARN("warn", "warning"),
/** Error message. */
ERROR("error", "error"),
/** Success message. */
SUCCESS("ok", "information"),
/** Question message. */
QUESTION("warn", "question"),
/** Yes/no/cancel message. */
YESNOCANCEL("warn", "question");
/** Small icon. */
public final Icon small;
/** Large icon. */
public final Icon large;
/**
* Constructor.
* @param s small icon
* @param l large icon
*/
Msg(final String s, final String l) {
small = BaseXImages.icon(s);
large = UIManager.getIcon("OptionPane." + l + "Icon");
}
}
// COLORS ===================================================================
/** Background color. */
public static final Color BACK = new Color(TEXTFIELD.getBackground().getRGB());
/** Text color. */
public static final Color TEXT = new Color(TEXTFIELD.getForeground().getRGB());
/** Panel color. */
public static final Color PANEL = new Color(LABEL.getBackground().getRGB());
/** Dark theme. */
public static final boolean INVERT = BACK.getRed() + BACK.getGreen() + BACK.getBlue() < 384;
/** Color: red. */
public static final Color RED = color(224, 0, 0);
/** Color: light red. */
public static final Color LRED = color(255, 216, 216);
/** Color: green. */
public static final Color GREEN = color(0, 160, 0);
/** Color: blue. */
public static final Color BLUE = color(0, 64, 192);
/** Color: cyan. */
public static final Color CYAN = color(0, 160, 160);
/** Color: purple. */
public static final Color PURPLE = color(160, 0, 160);
/** Cell color. */
public static Color lgray;
/** Button color. */
public static Color gray;
/** Background color. */
public static Color dgray;
/** Cached color gradient. */
private static final Color[] COLORS = new Color[100];
/** Second bright GUI color. */
public static Color color1;
/** Middle color. */
public static Color color2;
/** Middle color. */
public static Color color3;
/** Dark color. */
public static Color color4;
/** Mark color. */
public static Color colormark1;
/** Second mark color. */
public static Color colormark2;
/** Third mark color. */
public static Color colormark3;
/** Fourth mark color. */
public static Color colormark4;
/** Alpha color. */
public static Color color1A;
/** Transparent background color. */
public static Color color2A;
/** Cursor background color. */
public static Color color3A;
/** Mark color, custom alpha value. */
public static Color colormark1A;
/** Second mark color, custom alpha value. */
public static Color colormark2A;
// FONTS ====================================================================
/** Standard font size (unscaled). */
public static final int FONTSIZE = 13;
/** Standard line height. */
private static int height = -1;
/** Standard scale factor (>= 1). */
public static double scale;
/** Adapted scale factor. */
public static double ascale;
/** Large font. */
public static Font lfont;
/** Font. */
public static Font font;
/** Bold Font. */
public static Font bfont;
/** Monospace font. */
public static Font mfont;
/** Default monospace font. */
public static Font dmfont;
/** Current font size. */
public static int fontSize;
/** Character widths. */
private static int[] fwidth;
/** Monospace character widths. */
private static int[] mfwidth;
/** Bold character widths. */
private static int[] bwidth;
/** Character large character widths. */
private static int[] lwidth;
/** Default monospace font widths. */
private static int[] dmwidth;
// KEYS =====================================================================
/** No modifier. */
public static final int NO_MOD = 0;
/** Shift key. */
public static final int SHIFT = Event.SHIFT_MASK;
/** Alt key. */
public static final int ALT = Event.ALT_MASK;
/** Control key. */
public static final int CTRL = Event.CTRL_MASK;
/** Shortcut key (CTRL/META). */
public static final int META = Prop.MAC ? Event.META_MASK : Event.CTRL_MASK;
/** Private constructor, preventing class instantiation. */
private GUIConstants() { }
/**
* Initializes UI settings.
* @param opts gui options
*/
public static synchronized void init(final GUIOptions opts) {
if(height < 0) {
// initialize scaling only once
final int h = FONTSIZE + 3;
height = opts.get(GUIOptions.SCALE) ? LABEL.getFontMetrics(LABEL.getFont()).getHeight() : h;
scale = Math.max(1, (height - h) / 10.0d + 1);
ascale = 1 + (scale - 1) / 2;
}
lgray = color(224, 224, 224);
gray = color(160, 160, 160);
dgray = color(64, 64, 64);
// create color array
final int r = opts.get(GUIOptions.COLORRED);
final int g = opts.get(GUIOptions.COLORGREEN);
final int b = opts.get(GUIOptions.COLORBLUE);
final int cl = COLORS.length;
for(int c = 1; c < cl + 1; ++c) {
COLORS[c - 1] = color(Math.max(255 - c * r, 0),
Math.max(255 - c * g, 0), Math.max(255 - c * b, 0));
}
color1 = color(darker(r, 24), darker(g, 25), darker(b, 40));
color2 = color(darker(r, 32), darker(g, 32), darker(b, 44));
color3 = color(darker(r, 48), darker(g, 50), darker(b, 40));
color4 = color(darker(r, 140), darker(g, 100), darker(b, 70));
colormark1 = color(darker(r, 16), darker(g, 120), darker(b, 240));
colormark2 = color(darker(r, 16), darker(g, 80), darker(b, 160));
colormark3 = color(darker(r, 32), darker(g, 160), darker(b, 320));
colormark4 = color(darker(r, 1), darker(g, 40), darker(b, 80));
final Color col = COLORS[16];
color1A = color(darker(r, 110), darker(g, 150), darker(b, 160), 100);
color2A = color(col.getRed(), col.getGreen(), col.getBlue(), 50);
color3A = color(col.getRed(), col.getGreen(), col.getBlue(), 30);
colormark1A = color(darker(r, 32), darker(g, 160), darker(b, 320), 100);
colormark2A = color(darker(r, 12), darker(g, 60), darker(b, 120), 100);
final String name = opts.get(GUIOptions.FONT);
final int type = opts.get(GUIOptions.FONTTYPE);
fontSize = (int) (opts.get(GUIOptions.FONTSIZE) * scale);
font = new Font(name, type, fontSize);
mfont = new Font(opts.get(GUIOptions.MONOFONT), type, fontSize);
bfont = new Font(name, Font.BOLD, fontSize);
lfont = new Font(name, type, (int) (FONTSIZE * ascale * 1.5 + fontSize / 2.0));
dmfont = new Font(opts.get(GUIOptions.MONOFONT), 0, (int) (height * 0.8));
dmwidth = LABEL.getFontMetrics(dmfont).getWidths();
fwidth = LABEL.getFontMetrics(font).getWidths();
lwidth = LABEL.getFontMetrics(lfont).getWidths();
mfwidth = LABEL.getFontMetrics(mfont).getWidths();
bwidth = LABEL.getFontMetrics(bfont).getWidths();
}
/**
* Indicates if images are to be scaled.
* @return result of check
*/
public static boolean large() {
return height > FONTSIZE + 3;
}
/**
* Returns the specified color from the color gradient.
* @param i color index
* @return color
*/
public static Color color(final int i) {
return COLORS[Math.min(COLORS.length - 1, i)];
}
/**
* Returns the character widths for the current font.
* @param f font reference
* @return character widths
*/
public static int[] fontWidths(final Font f) {
if(f == font) return fwidth;
if(f == mfont) return mfwidth;
if(f == bfont) return bwidth;
if(f == lfont) return lwidth;
if(f == dmfont) return dmwidth;
return LABEL.getFontMetrics(f).getWidths();
}
/**
* Combines the color value with specified factor and returns a new value.
* @param c color
* @param f factor
* @return converted color value
*/
private static int darker(final int c, final int f) {
return Math.max(0, 255 - c * f / 10);
}
/**
* Returns the specified color with the specified RGB values, or its inverted version
* if {@link #INVERT} is true.
* @param r red component
* @param g green component
* @param b blue component
* @return converted color
*/
private static Color color(final int r, final int g, final int b) {
return INVERT ? new Color(255 - r, 255 - g, 255 - b) : new Color(r, g, b);
}
/**
* Returns the specified color with the specified RGB and alpha values, or its inverted version
* if {@link #INVERT} is true.
* @param r red component
* @param g green component
* @param b blue component
* @param a alpha component
* @return converted color
*/
private static Color color(final int r, final int g, final int b, final int a) {
return INVERT ? new Color(255 - r, 255 - g, 255 - b, 255 - a) : new Color(r, g, b, a);
}
}