blob: c4e96cad235c94c91c241b951dd137f7a319d19f [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2010, 2019 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.internal.r.ui.intable;
import org.eclipse.jface.preference.JFacePreferences;
import org.eclipse.jface.resource.ColorRegistry;
import org.eclipse.jface.resource.FontRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.themes.ColorUtil;
import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
import org.eclipse.statet.jcommons.lang.Disposable;
import org.eclipse.statet.ecommons.waltable.config.AbstractRegistryConfiguration;
import org.eclipse.statet.ecommons.waltable.config.CellConfigAttributes;
import org.eclipse.statet.ecommons.waltable.config.IConfigRegistry;
import org.eclipse.statet.ecommons.waltable.config.LayoutSizeConfig;
import org.eclipse.statet.ecommons.waltable.freeze.IFreezeConfigAttributes;
import org.eclipse.statet.ecommons.waltable.grid.GridRegion;
import org.eclipse.statet.ecommons.waltable.grid.cell.AlternatingRowConfigLabelAccumulator;
import org.eclipse.statet.ecommons.waltable.grid.labeled.CornerGridLineCellLayerPainter;
import org.eclipse.statet.ecommons.waltable.painter.cell.DiagCellPainter;
import org.eclipse.statet.ecommons.waltable.painter.cell.ICellPainter;
import org.eclipse.statet.ecommons.waltable.painter.cell.decorator.LineBorderDecorator;
import org.eclipse.statet.ecommons.waltable.painter.layer.GridLineCellLayerPainter;
import org.eclipse.statet.ecommons.waltable.painter.layer.ILayerPainter;
import org.eclipse.statet.ecommons.waltable.sort.config.DefaultSortConfiguration;
import org.eclipse.statet.ecommons.waltable.sort.painter.SortableHeaderTextPainter;
import org.eclipse.statet.ecommons.waltable.style.BorderStyle;
import org.eclipse.statet.ecommons.waltable.style.BorderStyle.LineStyle;
import org.eclipse.statet.ecommons.waltable.style.CellStyleAttributes;
import org.eclipse.statet.ecommons.waltable.style.DisplayMode;
import org.eclipse.statet.ecommons.waltable.style.HorizontalAlignment;
import org.eclipse.statet.ecommons.waltable.style.SelectionStyleLabels;
import org.eclipse.statet.ecommons.waltable.style.Style;
import org.eclipse.statet.ecommons.waltable.style.VerticalAlignment;
import org.eclipse.statet.ecommons.workbench.ui.IWaThemeConstants;
import org.eclipse.statet.internal.r.ui.RUIPlugin;
public class PresentationConfig extends AbstractRegistryConfiguration implements Disposable,
IPropertyChangeListener {
private static PresentationConfig gInstance;
public static PresentationConfig getInstance(final Display display) {
if (gInstance == null) {
gInstance= new PresentationConfig(display);
RUIPlugin.getInstance().registerPluginDisposable(gInstance);
}
return gInstance;
}
private final Display display;
private final Color headerGridColor;
private final Color headerBackgroundColor;
private final Color headerForegroundColor;
private final Color bodyGridColor;
private final Color bodyBackgroundColor;
private final Color bodyEvenRowBackgroundColor;
private final Color bodyOddRowBackgroundColor;
private final Color bodyForegroundColor;
private final Color headerSelectionBackgroundColor;
private final Color headerSelectionForegroundColor;
private final Color headerPlaceholderColor;
private final Color headerFullSelectionBackgroundColor;
private final Color headerFullSelectionForegroundColor;
private final Color bodySelectionBackgroundColor;
private final Color bodySelectionForegroundColor;
private final Color bodyFreezeSeparatorColor;
private final ILayerPainter headerLayerPainter;
private final ILayerPainter headerLabelLayerPainter;
private ICellPainter baseCellPainter;
private ICellPainter headerCellPainter;
private ICellPainter headerSortedCellPainter;
private ICellPainter headerCornerCellPainter;
private final BorderStyle bodyAnchorBorderStyle;
private Font baseFont;
private Font infoFont;
private LayoutSizeConfig baseSizeConfig;
private final CopyOnWriteIdentityListSet<Runnable> listeners= new CopyOnWriteIdentityListSet<>();
public PresentationConfig(final Display display) {
this.display= display;
final ColorRegistry colorRegistry= JFaceResources.getColorRegistry();
this.headerGridColor= display.getSystemColor(SWT.COLOR_DARK_GRAY);
this.headerBackgroundColor= display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
this.headerForegroundColor= display.getSystemColor(SWT.COLOR_WIDGET_FOREGROUND);
this.bodyGridColor= display.getSystemColor(SWT.COLOR_GRAY);
this.bodyBackgroundColor= display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
this.bodyEvenRowBackgroundColor= this.bodyBackgroundColor;
this.bodyOddRowBackgroundColor= new Color(display, ColorUtil.blend(
display.getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW).getRGB(),
this.bodyEvenRowBackgroundColor.getRGB(), 20 ));
this.bodyForegroundColor= display.getSystemColor(SWT.COLOR_LIST_FOREGROUND);
this.headerSelectionBackgroundColor= new Color(display, ColorUtil.blend(
display.getSystemColor(SWT.COLOR_LIST_SELECTION).getRGB(),
this.headerBackgroundColor.getRGB(), 25 ));
this.headerSelectionForegroundColor= this.headerForegroundColor;
this.headerPlaceholderColor= new Color(display, ColorUtil.blend(
this.bodyGridColor.getRGB(),
this.headerBackgroundColor.getRGB(), 25 ));
this.headerFullSelectionBackgroundColor= new Color(display, ColorUtil.blend(
display.getSystemColor(SWT.COLOR_LIST_SELECTION).getRGB(),
display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW).getRGB(), 25 ));
this.headerFullSelectionForegroundColor= display.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
this.bodySelectionBackgroundColor= display.getSystemColor(SWT.COLOR_LIST_SELECTION);
this.bodySelectionForegroundColor= display.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT);
this.bodyFreezeSeparatorColor= colorRegistry.get(JFacePreferences.DECORATIONS_COLOR);
this.headerLayerPainter= new GridLineCellLayerPainter(this.headerGridColor);
this.headerLabelLayerPainter= new CornerGridLineCellLayerPainter(this.headerGridColor);
this.bodyAnchorBorderStyle= new BorderStyle(2, this.bodyForegroundColor, LineStyle.SOLID, -1);
updateFonts();
updateCellPainters();
final FontRegistry fontRegistry= JFaceResources.getFontRegistry();
fontRegistry.addListener(this);
}
@Override
public void dispose() {
final FontRegistry fontRegistry= JFaceResources.getFontRegistry();
if (fontRegistry != null) {
fontRegistry.removeListener(this);
}
this.bodyOddRowBackgroundColor.dispose();
this.headerSelectionBackgroundColor.dispose();
this.headerFullSelectionBackgroundColor.dispose();
this.headerPlaceholderColor.dispose();
}
private void updateFonts() {
final FontRegistry fontRegistry= JFaceResources.getFontRegistry();
this.baseFont= fontRegistry.get(IWaThemeConstants.TABLE_FONT);
this.infoFont= fontRegistry.getItalic(IWaThemeConstants.TABLE_FONT);
{ final GC gc= new GC(this.display);
gc.setFont(this.baseFont);
final FontMetrics fontMetrics= gc.getFontMetrics();
final int textHeight= fontMetrics.getHeight();
final int charWidth= (gc.textExtent("1234567890.-120").x + 5) / 15;
gc.dispose();
final int textSpace= 3;
this.baseSizeConfig= new LayoutSizeConfig(textSpace, textHeight, charWidth);
}
}
private void updateCellPainters() {
this.baseCellPainter= new LineBorderDecorator(
new RTextPainter(this.baseSizeConfig.getDefaultSpace()) );
this.headerCellPainter= new RTextPainter(this.baseSizeConfig.getDefaultSpace());
this.headerSortedCellPainter= new SortableHeaderTextPainter(
new RTextPainter(this.baseSizeConfig.getDefaultSpace()), true, true );
this.headerCornerCellPainter= new DiagCellPainter(this.headerGridColor);
}
@Override
public void propertyChange(final PropertyChangeEvent event) {
switch (event.getProperty()) {
case IWaThemeConstants.TABLE_FONT:
updateFonts();
updateCellPainters();
notifyListeners();
return;
default:
return;
}
}
public ILayerPainter getHeaderLayerPainter() {
return this.headerLayerPainter;
}
public ILayerPainter getHeaderLabelLayerPainter() {
return this.headerLabelLayerPainter;
}
public LayoutSizeConfig getBaseSizeConfig() {
return this.baseSizeConfig;
}
@Override
public void configureRegistry(final IConfigRegistry configRegistry) {
// base
{ final Style cellStyle= new Style();
cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, this.bodyBackgroundColor);
cellStyle.setAttributeValue(CellStyleAttributes.FOREGROUND_COLOR, this.bodyForegroundColor);
cellStyle.setAttributeValue(CellStyleAttributes.HORIZONTAL_ALIGNMENT, HorizontalAlignment.RIGHT);
cellStyle.setAttributeValue(CellStyleAttributes.VERTICAL_ALIGNMENT, VerticalAlignment.MIDDLE);
cellStyle.setAttributeValue(CellStyleAttributes.BORDER_STYLE, null);
cellStyle.setAttributeValue(CellStyleAttributes.FONT, this.baseFont);
cellStyle.setAttributeValue(CellStyleAttributes.CONTROL_FONT, this.infoFont);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, this.baseCellPainter);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle);
configRegistry.registerConfigAttribute(LayoutSizeConfig.CONFIG, this.baseSizeConfig);
}
// headers
{ // column header
final Style cellStyle= new Style();
cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, this.headerBackgroundColor);
cellStyle.setAttributeValue(CellStyleAttributes.FOREGROUND_COLOR, this.headerForegroundColor);
cellStyle.setAttributeValue(CellStyleAttributes.HORIZONTAL_ALIGNMENT, HorizontalAlignment.CENTER);
cellStyle.setAttributeValue(CellStyleAttributes.VERTICAL_ALIGNMENT, VerticalAlignment.MIDDLE);
cellStyle.setAttributeValue(CellStyleAttributes.BORDER_STYLE, null);
cellStyle.setAttributeValue(CellStyleAttributes.FONT, this.baseFont);
cellStyle.setAttributeValue(CellStyleAttributes.CONTROL_FONT, this.infoFont);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,
DisplayMode.NORMAL, GridRegion.COLUMN_HEADER );
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, this.headerCellPainter,
DisplayMode.NORMAL, GridRegion.COLUMN_HEADER );
}
{ // column header label
final Style cellStyle= new Style();
cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, this.headerBackgroundColor);
cellStyle.setAttributeValue(CellStyleAttributes.FOREGROUND_COLOR, this.headerForegroundColor);
cellStyle.setAttributeValue(CellStyleAttributes.HORIZONTAL_ALIGNMENT, HorizontalAlignment.RIGHT);
cellStyle.setAttributeValue(CellStyleAttributes.VERTICAL_ALIGNMENT, VerticalAlignment.MIDDLE);
cellStyle.setAttributeValue(CellStyleAttributes.BORDER_STYLE, null);
cellStyle.setAttributeValue(CellStyleAttributes.FONT, this.baseFont);
cellStyle.setAttributeValue(CellStyleAttributes.CONTROL_FONT, this.infoFont);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,
DisplayMode.NORMAL, GridRegion.COLUMN_HEADER_LABEL );
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, this.headerCellPainter,
DisplayMode.NORMAL, GridRegion.COLUMN_HEADER_LABEL );
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,
DisplayMode.NORMAL, GridRegion.CORNER );
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, this.headerCornerCellPainter,
DisplayMode.NORMAL, GridRegion.CORNER );
}
{ // row header
final Style cellStyle= new Style();
cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, this.headerBackgroundColor);
cellStyle.setAttributeValue(CellStyleAttributes.FOREGROUND_COLOR, this.headerForegroundColor);
cellStyle.setAttributeValue(CellStyleAttributes.HORIZONTAL_ALIGNMENT, HorizontalAlignment.RIGHT);
cellStyle.setAttributeValue(CellStyleAttributes.VERTICAL_ALIGNMENT, VerticalAlignment.MIDDLE);
cellStyle.setAttributeValue(CellStyleAttributes.BORDER_STYLE, null);
cellStyle.setAttributeValue(CellStyleAttributes.FONT, this.baseFont);
cellStyle.setAttributeValue(CellStyleAttributes.CONTROL_FONT, this.infoFont);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,
DisplayMode.NORMAL, GridRegion.ROW_HEADER );
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, this.headerCellPainter,
DisplayMode.NORMAL, GridRegion.ROW_HEADER );
}
{ // row header
final Style cellStyle= new Style();
cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, this.headerBackgroundColor);
cellStyle.setAttributeValue(CellStyleAttributes.FOREGROUND_COLOR, this.headerForegroundColor);
cellStyle.setAttributeValue(CellStyleAttributes.HORIZONTAL_ALIGNMENT, HorizontalAlignment.LEFT);
cellStyle.setAttributeValue(CellStyleAttributes.VERTICAL_ALIGNMENT, VerticalAlignment.MIDDLE);
cellStyle.setAttributeValue(CellStyleAttributes.BORDER_STYLE, null);
cellStyle.setAttributeValue(CellStyleAttributes.FONT, this.baseFont);
cellStyle.setAttributeValue(CellStyleAttributes.CONTROL_FONT, this.infoFont);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,
DisplayMode.NORMAL, GridRegion.ROW_HEADER_LABEL );
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, this.headerCellPainter,
DisplayMode.NORMAL, GridRegion.ROW_HEADER_LABEL );
}
{ // placeholder header
final Style cellStyle= new Style();
cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, this.headerPlaceholderColor);
cellStyle.setAttributeValue(CellStyleAttributes.FOREGROUND_COLOR, this.headerForegroundColor);
cellStyle.setAttributeValue(CellStyleAttributes.HORIZONTAL_ALIGNMENT, HorizontalAlignment.RIGHT);
cellStyle.setAttributeValue(CellStyleAttributes.VERTICAL_ALIGNMENT, VerticalAlignment.MIDDLE);
cellStyle.setAttributeValue(CellStyleAttributes.BORDER_STYLE, null);
cellStyle.setAttributeValue(CellStyleAttributes.FONT, this.baseFont);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,
DisplayMode.NORMAL, GridRegion.HEADER_PLACEHOLDER );
}
// alternating rows
{ // body even row
final Style cellStyle= new Style();
cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, this.bodyEvenRowBackgroundColor);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,
DisplayMode.NORMAL, AlternatingRowConfigLabelAccumulator.EVEN_ROW_CONFIG_TYPE );
}
{ // body odd row
final Style cellStyle= new Style();
cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, this.bodyOddRowBackgroundColor);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,
DisplayMode.NORMAL, AlternatingRowConfigLabelAccumulator.ODD_ROW_CONFIG_TYPE );
}
// selection
{ // body selected cell
final Style cellStyle= new Style();
cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, this.bodySelectionBackgroundColor);
cellStyle.setAttributeValue(CellStyleAttributes.FOREGROUND_COLOR, this.bodySelectionForegroundColor);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,
DisplayMode.SELECT );
}
{ // body selection anchor
final Style cellStyle= new Style();
cellStyle.setAttributeValue(CellStyleAttributes.BORDER_STYLE, this.bodyAnchorBorderStyle);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,
DisplayMode.NORMAL, SelectionStyleLabels.SELECTION_ANCHOR_STYLE );
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,
DisplayMode.SELECT, SelectionStyleLabels.SELECTION_ANCHOR_STYLE );
}
{ // header with selection
final Style cellStyle= new Style();
cellStyle.setAttributeValue(CellStyleAttributes.FOREGROUND_COLOR,
this.headerSelectionForegroundColor );
cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR,
this.headerSelectionBackgroundColor );
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,
DisplayMode.SELECT, GridRegion.COLUMN_HEADER );
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,
DisplayMode.SELECT, GridRegion.CORNER );
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,
DisplayMode.SELECT, GridRegion.ROW_HEADER );
}
{ // header fully selected
final Style cellStyle= new Style();
cellStyle.setAttributeValue(CellStyleAttributes.FOREGROUND_COLOR,
this.headerFullSelectionForegroundColor );
cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR,
this.headerFullSelectionBackgroundColor );
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,
DisplayMode.SELECT, SelectionStyleLabels.COLUMN_FULLY_SELECTED_STYLE );
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,
DisplayMode.SELECT, SelectionStyleLabels.ROW_FULLY_SELECTED_STYLE );
}
// sorting
{ // header column sorted
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER,
this.headerSortedCellPainter,
DisplayMode.NORMAL, DefaultSortConfiguration.SORT_DOWN_CONFIG_TYPE);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER,
this.headerSortedCellPainter,
DisplayMode.NORMAL, DefaultSortConfiguration.SORT_UP_CONFIG_TYPE);
}
// freezing
{ // body freezed
configRegistry.registerConfigAttribute(IFreezeConfigAttributes.SEPARATOR_COLOR,
this.bodyFreezeSeparatorColor );
}
}
public void addListener(final Runnable listener) {
this.listeners.add(listener);
}
public void removeListener(final Runnable listener) {
this.listeners.remove(listener);
}
private void notifyListeners() {
for (final Runnable listener : this.listeners) {
listener.run();
}
}
}