diff options
| author | Stephan Wahlbrink | 2021-09-02 16:01:22 +0000 |
|---|---|---|
| committer | Stephan Wahlbrink | 2021-09-02 19:23:57 +0000 |
| commit | a33f8d70c299afce898e2aedca5d3a79b5402c6d (patch) | |
| tree | db046d129be1c9fa3f0035e9e617488abae7db0e | |
| parent | 547f872d7803e855c7dd5a773614c99697549793 (diff) | |
| download | org.eclipse.statet-r-a33f8d70c299afce898e2aedca5d3a79b5402c6d.tar.gz org.eclipse.statet-r-a33f8d70c299afce898e2aedca5d3a79b5402c6d.tar.xz org.eclipse.statet-r-a33f8d70c299afce898e2aedca5d3a79b5402c6d.zip | |
Bug 575763: [R-DataEditor] Add styling for dark theme
Change-Id: I424e308ba5b44468c184856f47a7bde056845742
14 files changed, 898 insertions, 10 deletions
diff --git a/r/org.eclipse.statet.r.ui/META-INF/MANIFEST.MF b/r/org.eclipse.statet.r.ui/META-INF/MANIFEST.MF index 83fc3432..6cf72944 100644 --- a/r/org.eclipse.statet.r.ui/META-INF/MANIFEST.MF +++ b/r/org.eclipse.statet.r.ui/META-INF/MANIFEST.MF @@ -44,6 +44,10 @@ Import-Package: com.ibm.icu.math;version="67.1.0", com.ibm.icu.util;version="67.1.0", javax.servlet;version="[4.0.0,5.0.0)", javax.servlet.http;version="[4.0.0,5.0.0)", + org.eclipse.e4.ui.css.core.dom, + org.eclipse.e4.ui.css.core.dom.properties, + org.eclipse.e4.ui.css.core.engine, + org.eclipse.e4.ui.css.swt.dom, org.eclipse.help, org.eclipse.jetty.servlet;version="[10.0.5,10.1.0)", org.eclipse.jetty.util;version="[10.0.5,10.1.0)", diff --git a/r/org.eclipse.statet.r.ui/css/e4_dark.css b/r/org.eclipse.statet.r.ui/css/e4_dark.css new file mode 100644 index 00000000..65a4f88d --- /dev/null +++ b/r/org.eclipse.statet.r.ui/css/e4_dark.css @@ -0,0 +1,37 @@ +/* + #=============================================================================# + # Copyright (c) 2021 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 + #=============================================================================*/ + +RDataTable, RDataTable Cell { + background-color: rgb(45, 45, 45); + color: '#org-eclipse-ui-workbench-DARK_FOREGROUND'; +} + +RDataTable Header Cell { + background-color: #383D3F; +} +RDataTable Header Cell:selected { + background-color: rgb(60, 85, 115); + color: rgb(250, 250, 255); +} + +RDataTable Body { + grid-line-color: rgb(85, 85, 85); +} +RDataTable Body Cell.BODY_EVEN_ROW { + background-color: rgb(52, 52, 52); +} +RDataTable Body Cell.SELECTION_ANCHOR { + border-color: rgb(195, 195, 205); +} diff --git a/r/org.eclipse.statet.r.ui/plugin.xml b/r/org.eclipse.statet.r.ui/plugin.xml index b6c6462f..e88a9571 100644 --- a/r/org.eclipse.statet.r.ui/plugin.xml +++ b/r/org.eclipse.statet.r.ui/plugin.xml @@ -2314,4 +2314,45 @@ </variable> </extension> + <extension + point="org.eclipse.e4.ui.css.core.elementProvider"> + <provider + class="org.eclipse.statet.internal.r.ui.intable.css.dom.DataTableElementProvider"> + <widget + class="org.eclipse.statet.internal.r.ui.intable.DataTable"/> + </provider> + </extension> + <extension + point="org.eclipse.e4.ui.css.core.propertyHandler"> + <handler + adapter="org.eclipse.statet.internal.r.ui.intable.css.dom.TableElement" + handler="org.eclipse.statet.internal.r.ui.intable.css.properties.TablePropertyHandler"> + <property-name + name="background-color"/> + <property-name + name="color"/> + </handler> + <handler + adapter="org.eclipse.statet.internal.r.ui.intable.css.dom.TableRegionElement" + handler="org.eclipse.statet.internal.r.ui.intable.css.properties.TableRegionPropertyHandler"> + <property-name + name="grid-line-color"/> + </handler> + <handler + adapter="org.eclipse.statet.internal.r.ui.intable.css.dom.TableCellElement" + handler="org.eclipse.statet.internal.r.ui.intable.css.properties.TableCellPropertyHandler"> + <property-name + name="background-color"/> + <property-name + name="color"/> + <property-name + name="border-color"/> + </handler> + </extension> + <extension + point="org.eclipse.e4.ui.css.swt.theme"> + <stylesheet + uri="css/e4_dark.css"/> + </extension> + </plugin> diff --git a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/DataTable.java b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/DataTable.java new file mode 100644 index 00000000..b2bb5d43 --- /dev/null +++ b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/DataTable.java @@ -0,0 +1,35 @@ +/*=============================================================================# + # Copyright (c) 2021 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.swt.widgets.Composite; + +import org.eclipse.statet.jcommons.lang.NonNullByDefault; + +import org.eclipse.statet.ecommons.ui.workbench.css.VirtualComposite; +import org.eclipse.statet.ecommons.waltable.NatTable; +import org.eclipse.statet.ecommons.waltable.core.layer.Layer; + + +@NonNullByDefault +public class DataTable extends NatTable implements VirtualComposite { + + + public DataTable(final Composite parent, final Layer layer) { + super(parent, layer, false); + } + + +} diff --git a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/PresentationConfig.java b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/PresentationConfig.java index 0ed3245b..eefa606b 100644 --- a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/PresentationConfig.java +++ b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/PresentationConfig.java @@ -15,6 +15,7 @@ package org.eclipse.statet.internal.r.ui.intable; import org.eclipse.jface.preference.JFacePreferences; +import org.eclipse.jface.preference.PreferenceConverter; import org.eclipse.jface.resource.ColorRegistry; import org.eclipse.jface.resource.FontRegistry; import org.eclipse.jface.resource.JFaceResources; @@ -25,7 +26,10 @@ 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.graphics.RGB; import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.editors.text.EditorsUI; +import org.eclipse.ui.texteditor.AbstractTextEditor; import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet; import org.eclipse.statet.jcommons.lang.Disposable; @@ -42,6 +46,8 @@ import org.eclipse.statet.ecommons.waltable.core.style.BasicStyle; import org.eclipse.statet.ecommons.waltable.core.style.BorderStyle; import org.eclipse.statet.ecommons.waltable.core.style.BorderStyle.LineStyle; import org.eclipse.statet.ecommons.waltable.core.style.CellStyling; +import org.eclipse.statet.ecommons.waltable.core.style.GridStyling; +import org.eclipse.statet.ecommons.waltable.core.style.GridStyling.ConfigGridLineColorSupplier; import org.eclipse.statet.ecommons.waltable.core.style.HorizontalAlignment; import org.eclipse.statet.ecommons.waltable.core.style.Style; import org.eclipse.statet.ecommons.waltable.core.style.VerticalAlignment; @@ -109,8 +115,6 @@ public class PresentationConfig extends AbstractRegistryConfiguration implements private LayerCellPainter headerSortedCellPainter; private LayerCellPainter headerCornerCellPainter; - private final BorderStyle bodyAnchorBorderStyle; - private Font baseFont; private Font infoFont; @@ -151,15 +155,15 @@ public class PresentationConfig extends AbstractRegistryConfiguration implements display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW), 0.25f ); this.headerFullSelectionForegroundColor= display.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); - this.bodySelectionBackgroundColor= display.getSystemColor(SWT.COLOR_LIST_SELECTION); + this.bodySelectionBackgroundColor= getSelectionBackgroundColor(); this.bodySelectionForegroundColor= display.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT); this.bodyFreezeSeparatorColor= colorRegistry.get(JFacePreferences.DECORATIONS_COLOR); - this.headerLayerPainter= new GridLineCellLayerPainter((configRegistry) -> this.headerGridColor); - this.headerLabelLayerPainter= new CornerGridLineCellLayerPainter((configRegistry) -> this.headerGridColor); - - this.bodyAnchorBorderStyle= new BorderStyle(2, this.bodyForegroundColor, LineStyle.SOLID, -1); + this.headerLayerPainter= new GridLineCellLayerPainter( + new ConfigGridLineColorSupplier(GridLabels.COLUMN_HEADER) ); + this.headerLabelLayerPainter= new CornerGridLineCellLayerPainter( + new ConfigGridLineColorSupplier(GridLabels.COLUMN_HEADER) ); updateFonts(); updateCellPainters(); @@ -168,6 +172,17 @@ public class PresentationConfig extends AbstractRegistryConfiguration implements fontRegistry.addListener(this); } + private Color getSelectionBackgroundColor() { + final var store= EditorsUI.getPreferenceStore(); + if (!store.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_SELECTION_BACKGROUND_SYSTEM_DEFAULT)) { + final RGB rgb= PreferenceConverter.getColor(store, AbstractTextEditor.PREFERENCE_COLOR_SELECTION_BACKGROUND); + if (rgb != null) { + return new Color(rgb); + } + } + return this.display.getSystemColor(SWT.COLOR_LIST_SELECTION); + } + @Override public void dispose() { final FontRegistry fontRegistry= JFaceResources.getFontRegistry(); @@ -244,6 +259,7 @@ public class PresentationConfig extends AbstractRegistryConfiguration implements configRegistry.registerAttribute(CellConfigAttributes.CELL_PAINTER, this.baseCellPainter); configRegistry.registerAttribute(CellConfigAttributes.CELL_STYLE, cellStyle); + configRegistry.registerAttribute(GridStyling.GRID_LINE_COLOR, this.bodyGridColor); configRegistry.registerAttribute(LayoutSizeConfig.CONFIG, this.baseSizeConfig); } @@ -263,6 +279,8 @@ public class PresentationConfig extends AbstractRegistryConfiguration implements DisplayMode.NORMAL, GridLabels.COLUMN_HEADER ); configRegistry.registerAttribute(CellConfigAttributes.CELL_PAINTER, this.headerCellPainter, DisplayMode.NORMAL, GridLabels.COLUMN_HEADER ); + configRegistry.registerAttribute(GridStyling.GRID_LINE_COLOR, this.headerGridColor, + DisplayMode.NORMAL, GridLabels.COLUMN_HEADER ); } { // column header label final Style cellStyle= new BasicStyle(); @@ -354,7 +372,8 @@ public class PresentationConfig extends AbstractRegistryConfiguration implements } { // body selection anchor final Style cellStyle= new BasicStyle(); - cellStyle.setAttributeValue(CellStyling.BORDER_STYLE, this.bodyAnchorBorderStyle); + cellStyle.setAttributeValue(CellStyling.BORDER_STYLE, + new BorderStyle(2, this.bodyForegroundColor, LineStyle.SOLID, -1) ); configRegistry.registerAttribute(CellConfigAttributes.CELL_STYLE, cellStyle, DisplayMode.NORMAL, SelectionStyleLabels.SELECTION_ANCHOR_STYLE ); diff --git a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/dom/DataTableElementProvider.java b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/dom/DataTableElementProvider.java new file mode 100644 index 00000000..a8fd3205 --- /dev/null +++ b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/dom/DataTableElementProvider.java @@ -0,0 +1,45 @@ +/*=============================================================================# + # Copyright (c) 2021 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.css.dom; + +import org.eclipse.e4.ui.css.core.dom.IElementProvider; +import org.eclipse.e4.ui.css.core.engine.CSSEngine; + +import org.w3c.dom.Element; + +import org.eclipse.statet.jcommons.lang.NonNullByDefault; +import org.eclipse.statet.jcommons.lang.Nullable; + +import org.eclipse.statet.internal.r.ui.intable.DataTable; + + +@NonNullByDefault +@SuppressWarnings("restriction") +public class DataTableElementProvider implements IElementProvider { + + + public DataTableElementProvider() { + } + + + @Override + public @Nullable Element getElement(final Object element, final CSSEngine engine) { + if (element instanceof DataTable) { + return new TableElement((DataTable)element, engine); + } + return null; + } + +} diff --git a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/dom/TableCellElement.java b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/dom/TableCellElement.java new file mode 100644 index 00000000..afd33b2e --- /dev/null +++ b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/dom/TableCellElement.java @@ -0,0 +1,53 @@ +/*=============================================================================# + # Copyright (c) 2021 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.css.dom; + +import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; + +import org.eclipse.statet.jcommons.collections.ImCollections; +import org.eclipse.statet.jcommons.collections.ImList; +import org.eclipse.statet.jcommons.lang.NonNullByDefault; +import org.eclipse.statet.jcommons.lang.Nullable; + +import org.eclipse.statet.ecommons.ui.workbench.css.dom.VirtualStylableElement; + + +@NonNullByDefault +@SuppressWarnings("restriction") +public class TableCellElement extends VirtualStylableElement<TableRegionElement> { + + + private final ImList<String> labels; + + + public TableCellElement(final TableRegionElement parent, + final @Nullable String label, + final CSSEngine engine) { + super(nonNullAssert(parent), "Cell", label, engine); //$NON-NLS-1$ + + this.labels= (label != null) ? + ImCollections.newIdentityList(label) : + ImCollections.emptyIdentityList(); + } + + + public ImList<String> getLabels() { + return this.labels; + } + + +} diff --git a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/dom/TableElement.java b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/dom/TableElement.java new file mode 100644 index 00000000..a090df5c --- /dev/null +++ b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/dom/TableElement.java @@ -0,0 +1,87 @@ +/*=============================================================================# + # Copyright (c) 2021 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.css.dom; + +import java.util.ArrayList; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; + +import org.eclipse.statet.jcommons.collections.ImCollections; +import org.eclipse.statet.jcommons.collections.ImList; +import org.eclipse.statet.jcommons.lang.NonNullByDefault; +import org.eclipse.statet.jcommons.lang.Nullable; + +import org.eclipse.statet.ecommons.ui.workbench.css.dom.VirtualCompositeStylableElement; +import org.eclipse.statet.ecommons.waltable.grid.AlternatingRowLabelContributor; +import org.eclipse.statet.ecommons.waltable.grid.core.GridLabels; +import org.eclipse.statet.ecommons.waltable.style.SelectionStyleLabels; + +import org.eclipse.statet.internal.r.ui.intable.DataTable; + + +@NonNullByDefault +@SuppressWarnings("restriction") +public class TableElement extends VirtualCompositeStylableElement<DataTable> { + + + private final static @Nullable String NO_CLASS= null; + + + public TableElement(final DataTable dataTable, final CSSEngine engine) { + super(dataTable, engine); + } + + @Override + protected String computeLocalName() { + return "RDataTable"; //$NON-NLS-1$ + } + + @Override + protected ImList<TableRegionElement> createChildren(final DataTable control) { + final var list= new ArrayList<TableRegionElement>(); + list.add(new TableRegionElement(this, TableRegionElement.BODY_NAME, null, + ImCollections.newList( + NO_CLASS, + AlternatingRowLabelContributor.EVEN_ROW_CONFIG_TYPE, + AlternatingRowLabelContributor.ODD_ROW_CONFIG_TYPE, + SelectionStyleLabels.SELECTION_ANCHOR_STYLE ), + ImCollections.newList("selected"), + this.engine )); + list.add(new TableRegionElement(this, TableRegionElement.HEADER_NAME, GridLabels.CORNER, + ImCollections.newList(NO_CLASS), + ImCollections.newList(), + this.engine )); + list.add(new TableRegionElement(this, TableRegionElement.HEADER_NAME, GridLabels.COLUMN_HEADER, + ImCollections.newList(NO_CLASS), + ImCollections.newList("selected"), + this.engine )); + list.add(new TableRegionElement(this, TableRegionElement.HEADER_NAME, GridLabels.ROW_HEADER, + ImCollections.newList(NO_CLASS), + ImCollections.newList("selected"), +// ImCollections.newList("selected", "fully-selected"), + this.engine )); + list.add(new TableRegionElement(this, TableRegionElement.HEADER_NAME, GridLabels.COLUMN_HEADER_LABEL, + ImCollections.newList(NO_CLASS), + ImCollections.newList(), + this.engine )); + list.add(new TableRegionElement(this, TableRegionElement.HEADER_NAME, GridLabels.ROW_HEADER_LABEL, + ImCollections.newList(NO_CLASS), + ImCollections.newList(), + this.engine )); + return ImCollections.toList(list); + } + + +} diff --git a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/dom/TableRegionElement.java b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/dom/TableRegionElement.java new file mode 100644 index 00000000..2a3d3739 --- /dev/null +++ b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/dom/TableRegionElement.java @@ -0,0 +1,64 @@ +/*=============================================================================# + # Copyright (c) 2021 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.css.dom; + +import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; + +import org.eclipse.statet.jcommons.collections.ImCollections; +import org.eclipse.statet.jcommons.collections.ImList; +import org.eclipse.statet.jcommons.lang.NonNull; +import org.eclipse.statet.jcommons.lang.NonNullByDefault; +import org.eclipse.statet.jcommons.lang.Nullable; + +import org.eclipse.statet.ecommons.ui.workbench.css.dom.VirtualStylableElement; + + +@NonNullByDefault +@SuppressWarnings("restriction") +public class TableRegionElement extends VirtualStylableElement<TableElement> { + + + public static final String BODY_NAME= "Body"; //$NON-NLS-1$ + public static final String HEADER_NAME= "Header"; //$NON-NLS-1$ + + + public TableRegionElement(final TableElement parent, + final String name, final @Nullable String label, + final ImList<@Nullable String> cellCssClasses, final @Nullable ImList<String> cellCssStaticPseudoClasses, + final CSSEngine engine) { + super(nonNullAssert(parent), name, label, engine); + + init(createChildren(cellCssClasses, (cellCssStaticPseudoClasses != null) ? + cellCssStaticPseudoClasses : ImCollections.newList() )); + } + + protected ImList<TableCellElement> createChildren( + final ImList<@Nullable String> cssClasses, final ImList<String> cssStaticPseudoClasses) { + final var children= new @NonNull TableCellElement[cssClasses.size()]; + int i= 0; + for (final String cssClass : cssClasses) { + final TableCellElement cellElement= new TableCellElement(this, cssClass, this.engine); + for (final String pseudoClass : cssStaticPseudoClasses) { + cellElement.addStaticPseudoInstance(pseudoClass); + } + children[i++]= cellElement; + } + return ImCollections.newList(children, 0, i); + } + + +} diff --git a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/properties/AbstractDataTablePropertyHandler.java b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/properties/AbstractDataTablePropertyHandler.java new file mode 100644 index 00000000..cec0fdad --- /dev/null +++ b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/properties/AbstractDataTablePropertyHandler.java @@ -0,0 +1,60 @@ +/*=============================================================================# + # Copyright (c) 2021 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.css.properties; + +import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; +import org.eclipse.e4.ui.css.core.engine.CSSEngine; + +import org.w3c.dom.css.CSSValue; + +import org.eclipse.statet.jcommons.lang.NonNullByDefault; +import org.eclipse.statet.jcommons.lang.Nullable; + +import org.eclipse.statet.internal.r.ui.intable.DataTable; + + +@NonNullByDefault +@SuppressWarnings("restriction") +public abstract class AbstractDataTablePropertyHandler implements ICSSPropertyHandler { + + + protected static final boolean DEBUG= false; + + + public AbstractDataTablePropertyHandler() { + } + + + @SuppressWarnings("unchecked") + protected static <T> @Nullable T toSWT(final CSSValue value, final Class<T> valueType, + final CSSEngine engine, final DataTable dataTable) throws Exception { + return (T)engine.convert(value, valueType, dataTable.getDisplay()); + } + + + protected static void print(final Object element, final @Nullable String pseudo, + final String property, final CSSValue value) { + final StringBuilder sb= new StringBuilder("CSSapply "); //$NON-NLS-1$ + sb.append(element); + if (pseudo != null) { + sb.append(':').append(pseudo); + } + sb.append(" { ").append(property).append(": "); //$NON-NLS-1$ //$NON-NLS-2$ + sb.append(value.getCssText()); + sb.append(" }"); //$NON-NLS-1$ + System.out.println(sb.toString()); + } + +} diff --git a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/properties/TableCellPropertyHandler.java b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/properties/TableCellPropertyHandler.java new file mode 100644 index 00000000..9101f2ef --- /dev/null +++ b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/properties/TableCellPropertyHandler.java @@ -0,0 +1,224 @@ +/*=============================================================================# + # Copyright (c) 2021 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.css.properties; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.swt.graphics.Color; + +import org.w3c.dom.css.CSSValue; + +import org.eclipse.statet.jcommons.lang.NonNullByDefault; +import org.eclipse.statet.jcommons.lang.Nullable; + +import org.eclipse.statet.ecommons.waltable.config.CellConfigAttributes; +import org.eclipse.statet.ecommons.waltable.core.config.ConfigAttribute; +import org.eclipse.statet.ecommons.waltable.core.config.DisplayMode; +import org.eclipse.statet.ecommons.waltable.core.style.BorderStyle; +import org.eclipse.statet.ecommons.waltable.core.style.CellStyling; +import org.eclipse.statet.ecommons.waltable.core.style.Style; +import org.eclipse.statet.ecommons.waltable.grid.core.GridLabels; +import org.eclipse.statet.ecommons.waltable.style.SelectionStyleLabels; + +import org.eclipse.statet.internal.r.ui.intable.css.dom.TableCellElement; + + +@NonNullByDefault +@SuppressWarnings("restriction") +public class TableCellPropertyHandler extends AbstractDataTablePropertyHandler { + + + public TableCellPropertyHandler() { + } + + + @Override + public @Nullable String retrieveCSSProperty(final Object element, + final String property, final @Nullable String pseudo, + final CSSEngine engine) throws Exception { + if (!(element instanceof TableCellElement)) { + return null; + } + final var cellElement= (TableCellElement)element; + final var displayMode= getDisplayMode(cellElement, pseudo); + final var label= getOverrideLabel(cellElement, pseudo); + + if (displayMode != null) { + switch (property) { + case "background-color": + return receiveCellStyleAttribute(cellElement, displayMode, label, + CellStyling.BACKGROUND_COLOR, Color.class, + engine ); + case "color": + return receiveCellStyleAttribute(cellElement, displayMode, label, + CellStyling.FOREGROUND_COLOR, Color.class, + engine ); + default: + break; + } + } + return null; + } + + @Override + public boolean applyCSSProperty(final Object element, + final String property, final CSSValue value, final @Nullable String pseudo, + final CSSEngine engine) throws Exception { + if (!(element instanceof TableCellElement)) { + return false; + } + if (DEBUG) { + print(element, pseudo, property, value); + } + final var cellElement= (TableCellElement)element; + final var displayMode= getDisplayMode(cellElement, pseudo); + final var label= getOverrideLabel(cellElement, pseudo); + + if (displayMode != null) { + switch (property) { + case "background-color": + applyCellStyleAttribute(cellElement, displayMode, label, + CellStyling.BACKGROUND_COLOR, Color.class, value, + engine ); + return true; + case "color": + applyCellStyleAttribute(cellElement, displayMode, label, + CellStyling.FOREGROUND_COLOR, Color.class, value, + engine ); + return true; + case "border-color": + applyCellStyleBorderAttribute(cellElement, displayMode, label, + CellStyling.BORDER_STYLE, Color.class, value, + engine ); + return true; + default: + break; + } + } + return true; + } + + + private static @Nullable DisplayMode getDisplayMode(final TableCellElement cellElement, + final @Nullable String pseudo) { + if (pseudo == null) { + return DisplayMode.NORMAL; + } + switch (pseudo) { + case "selected": + case "fully-selected": + return DisplayMode.SELECTED; + default: + return null; + } + } + + private static @Nullable String getOverrideLabel(final TableCellElement cellElement, + final @Nullable String pseudo) { + if (pseudo == null) { + return null; + } + if (pseudo.equals("fully-selected")) { + final String cssClass= cellElement.getParentNode().getCSSClass(); + if (cssClass != null) { + switch (cssClass) { + case GridLabels.COLUMN_HEADER_LABEL: + return SelectionStyleLabels.COLUMN_FULLY_SELECTED_STYLE; + case GridLabels.ROW_HEADER_LABEL: + return SelectionStyleLabels.ROW_FULLY_SELECTED_STYLE; + } + } + } + return null; + } + + + private static <T> @Nullable String receiveCellStyleAttribute(final TableCellElement cellElement, + final DisplayMode displayMode, @Nullable String label, + final ConfigAttribute<T> attribute, final Class<T> valueType, + final CSSEngine engine) throws Exception { + final var regionElement= cellElement.getParentNode(); + final var dataTable= regionElement.getParentNode().getNativeWidget(); + if (label == null) { + label= cellElement.getCSSClass(); + } + if (label == null) { + label= regionElement.getCSSClass(); + } + final Style style= dataTable.getConfigRegistry().getSpecificAttribute( + CellConfigAttributes.CELL_STYLE, displayMode, label ); + if (style != null) { + final var value= style.getAttributeValue(attribute); + return engine.convert(value, valueType, null); + } + return null; + } + + private static <T> void applyCellStyleAttribute(final TableCellElement cellElement, + final DisplayMode displayMode, @Nullable String label, + final ConfigAttribute<T> attribute, final Class<T> valueType, final CSSValue cssValue, + final CSSEngine engine) throws Exception { + final var regionElement= cellElement.getParentNode(); + final var dataTable= regionElement.getParentNode().getNativeWidget(); + if (label == null) { + label= cellElement.getCSSClass(); + } + if (label == null) { + label= regionElement.getCSSClass(); + } + final Style style= dataTable.getConfigRegistry().getSpecificAttribute( + CellConfigAttributes.CELL_STYLE, displayMode, label ); + final @Nullable T oldValue; + if (style != null + && (oldValue= style.getAttributeValue(attribute)) != null) { + @SuppressWarnings("unchecked") + final var value= (T)engine.convert(cssValue, valueType, dataTable.getDisplay()); + if (value != null && !value.equals(oldValue)) { + style.setAttributeValue(attribute, value); + } + } + } + + private static <T> void applyCellStyleBorderAttribute(final TableCellElement cellElement, + final DisplayMode displayMode, @Nullable String label, + final ConfigAttribute<BorderStyle> attribute, final Class<T> valueType, final CSSValue cssValue, + final CSSEngine engine) throws Exception { + final var regionElement= cellElement.getParentNode(); + final var dataTable= regionElement.getParentNode().getNativeWidget(); + if (label == null) { + label= cellElement.getCSSClass(); + } + if (label == null) { + label= regionElement.getCSSClass(); + } + final Style style= dataTable.getConfigRegistry().getSpecificAttribute( + CellConfigAttributes.CELL_STYLE, displayMode, label ); + final @Nullable BorderStyle oldBorderStyle; + if (style != null + && (oldBorderStyle= style.getAttributeValue(CellStyling.BORDER_STYLE)) != null) { + final var value= toSWT(cssValue, valueType, engine, dataTable); + BorderStyle borderStyle= null; + if (valueType == Color.class) { + if (value != null && !value.equals(oldBorderStyle.getColor())) { + borderStyle= new BorderStyle(oldBorderStyle.getThickness(), (Color)value, + oldBorderStyle.getLineStyle(), oldBorderStyle.getOffset() ); + } + } + if (borderStyle != null) { + style.setAttributeValue(CellStyling.BORDER_STYLE, borderStyle); + } + } + } + +} diff --git a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/properties/TablePropertyHandler.java b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/properties/TablePropertyHandler.java new file mode 100644 index 00000000..4ff47f0f --- /dev/null +++ b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/properties/TablePropertyHandler.java @@ -0,0 +1,86 @@ +/*=============================================================================# + # Copyright (c) 2021 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.css.properties; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.swt.graphics.Color; + +import org.w3c.dom.css.CSSValue; + +import org.eclipse.statet.jcommons.lang.NonNullByDefault; +import org.eclipse.statet.jcommons.lang.Nullable; + +import org.eclipse.statet.internal.r.ui.intable.css.dom.TableElement; + + +@NonNullByDefault +@SuppressWarnings("restriction") +public class TablePropertyHandler extends AbstractDataTablePropertyHandler { + + + public TablePropertyHandler() { + } + + + @Override + public @Nullable String retrieveCSSProperty(final Object element, + final String property, final @Nullable String pseudo, + final CSSEngine engine) throws Exception { + if (!(element instanceof TableElement)) { + return null; + } + final var tableElement= (TableElement)element; + + switch (property) { + case "background-color": + if (pseudo == null) { + final var color= tableElement.getNativeWidget().getBackground(); + return engine.convert(color, Color.class, null); + } + return null; + default: + break; + } + return null; + } + + @Override + public boolean applyCSSProperty(final Object element, + final String property, final CSSValue value, final @Nullable String pseudo, + final CSSEngine engine) throws Exception { + if (!(element instanceof TableElement)) { + return false; + } + if (DEBUG) { + print(element, pseudo, property, value); + } + final var tableElement= (TableElement)element; + final var dataTable= tableElement.getNativeWidget(); + + switch (property) { + case "background-color": + if (pseudo == null) { + final var color= (Color)engine.convert(value, Color.class, dataTable.getDisplay()); + dataTable.setBackground(color); + } + return true; + default: + break; + } + return true; + } + + +} diff --git a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/properties/TableRegionPropertyHandler.java b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/properties/TableRegionPropertyHandler.java new file mode 100644 index 00000000..cfb5eeeb --- /dev/null +++ b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/intable/css/properties/TableRegionPropertyHandler.java @@ -0,0 +1,133 @@ +/*=============================================================================# + # Copyright (c) 2021 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.css.properties; + +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.swt.graphics.Color; + +import org.w3c.dom.css.CSSValue; + +import org.eclipse.statet.jcommons.lang.NonNullByDefault; +import org.eclipse.statet.jcommons.lang.Nullable; + +import org.eclipse.statet.ecommons.waltable.core.config.ConfigAttribute; +import org.eclipse.statet.ecommons.waltable.core.config.DisplayMode; +import org.eclipse.statet.ecommons.waltable.core.style.GridStyling; + +import org.eclipse.statet.internal.r.ui.intable.css.dom.TableRegionElement; + + +@NonNullByDefault +@SuppressWarnings("restriction") +public class TableRegionPropertyHandler extends AbstractDataTablePropertyHandler { + + + public TableRegionPropertyHandler() { + } + + + @Override + public @Nullable String retrieveCSSProperty(final Object element, + final String property, final @Nullable String pseudo, + final CSSEngine engine) throws Exception { + if (!(element instanceof TableRegionElement)) { + return null; + } + final var regionElement= (TableRegionElement)element; + final var displayMode= getDisplayMode(regionElement, pseudo); + + if (displayMode != null) { + switch (property) { + case "grid-line-color": + return receiveStyleAttribute(regionElement, displayMode, null, + GridStyling.GRID_LINE_COLOR, Color.class, + engine ); + default: + break; + } + } + return null; + } + + @Override + public boolean applyCSSProperty(final Object element, + final String property, final CSSValue value, final @Nullable String pseudo, + final CSSEngine engine) throws Exception { + if (!(element instanceof TableRegionElement)) { + return false; + } + if (DEBUG) { + print(element, pseudo, property, value); + } + final var regionElement= (TableRegionElement)element; + final var displayMode= getDisplayMode(regionElement, pseudo); + + if (displayMode != null) { + switch (property) { + case "grid-line-color": + applyStyleAttribute(regionElement, displayMode, null, + GridStyling.GRID_LINE_COLOR, Color.class, value, + engine ); + return true; + default: + break; + } + } + return true; + } + + + private static @Nullable DisplayMode getDisplayMode(final TableRegionElement cellElement, + final @Nullable String pseudo) { + if (pseudo == null) { + return DisplayMode.NORMAL; + } + return null; + } + + + private static <T> @Nullable String receiveStyleAttribute(final TableRegionElement regionElement, + final DisplayMode displayMode, @Nullable String label, + final ConfigAttribute<T> attribute, final Class<T> valueType, + final CSSEngine engine) throws Exception { + final var dataTable= regionElement.getParentNode().getNativeWidget(); + if (label == null) { + label= regionElement.getCSSClass(); + } + final var value= dataTable.getConfigRegistry().getSpecificAttribute( + attribute, displayMode, label ); + return engine.convert(value, valueType, null); + } + + private static <T> void applyStyleAttribute(final TableRegionElement regionElement, + final DisplayMode displayMode, @Nullable String label, + final ConfigAttribute<T> attribute, final Class<T> valueType, final CSSValue cssValue, + final CSSEngine engine) throws Exception { + final var dataTable= regionElement.getParentNode().getNativeWidget(); + if (label == null) { + label= regionElement.getCSSClass(); + } + final var oldValue= dataTable.getConfigRegistry().getSpecificAttribute( + attribute, displayMode, label ); + if (oldValue != null) { + @SuppressWarnings("unchecked") + final var value= (T)engine.convert(cssValue, valueType, dataTable.getDisplay()); + if (value != null && !value.equals(oldValue)) { + dataTable.getConfigRegistry().registerAttribute(attribute, value); + } + } + } + +} diff --git a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/r/ui/dataeditor/RDataTableViewer.java b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/r/ui/dataeditor/RDataTableViewer.java index 8678a8e5..dbcc03a7 100644 --- a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/r/ui/dataeditor/RDataTableViewer.java +++ b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/r/ui/dataeditor/RDataTableViewer.java @@ -121,6 +121,7 @@ import org.eclipse.statet.internal.r.ui.dataeditor.RDataFrameDataProvider; import org.eclipse.statet.internal.r.ui.dataeditor.RMatrixDataProvider; import org.eclipse.statet.internal.r.ui.dataeditor.RVectorDataProvider; import org.eclipse.statet.internal.r.ui.dataeditor.ResolveCellIndexes; +import org.eclipse.statet.internal.r.ui.intable.DataTable; import org.eclipse.statet.internal.r.ui.intable.PresentationConfig; import org.eclipse.statet.internal.r.ui.intable.RDataLayer; import org.eclipse.statet.internal.r.ui.intable.TableLayers; @@ -453,8 +454,7 @@ public class RDataTableViewer extends BasicCustomViewer<RDataTableSelection> { layers.dataLayer.registerCommandHandler(commandHandler); } - layers.table= new NatTable(this.composite, gridLayer, false); - layers.table.addConfiguration(presentation); + layers.table= new DataTable(this.composite, gridLayer); layers.table.addConfiguration(new UIBindings.HeaderContextMenuConfiguration(layers.table, this.callbacks.getWorkbenchPart() )); layers.table.addConfiguration(new UIBindings.BodyContextMenuConfiguration(layers.table, |
