| /*=============================================================================# |
| # Copyright (c) 2010, 2020 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(); |
| } |
| } |
| |
| } |