diff --git a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/Messages.java b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/Messages.java index fc784ba6ac..69a2b45b61 100644 --- a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/Messages.java +++ b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/Messages.java @@ -37,6 +37,8 @@ public class Messages AddPV_PeriodTT, AppendSearchResults, AppendSearchResultsTT, + AreaOpacity, + AreaOpacityTT, ArchiveFetchDetailFmt, ArchiveFetchJobFmt, ArchiveFetchProgressFmt, diff --git a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/model/Model.java b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/model/Model.java index a47f544fa9..b97cdfe4b5 100644 --- a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/model/Model.java +++ b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/model/Model.java @@ -99,6 +99,11 @@ public class Model /** Background color */ private volatile Color background = Color.WHITE; + /** + * Area opacity, common for all plots. + */ + private volatile int areaOpacity = Preferences.opacity; + /** Title font */ private volatile Font title_font = Font.font("Liberation Sans", FontWeight.BOLD, 20); @@ -426,7 +431,7 @@ else if (j < i) { item.fireItemLookChanged(); // Prevents the "Axis" UI-setting (under the "Traces" tab) from sometimes not displaying in the UI when moving axes. } } - }; + } /** @return How should plot rescale after archived data arrived? */ public ArchiveRescale getArchiveRescale() @@ -1009,4 +1014,16 @@ public ModelItem getItemByUniqueId(String uniqueId){ } return items.stream().filter(item -> uniqueId.equals(item.getUniqueId())).findAny().orElse(null); } + + public int getAreaOpacity(){ + return areaOpacity; + } + + public void setAreaOpacity(int areaOpacity){ + this.areaOpacity = areaOpacity; + getItems().forEach(item -> { + for (ModelListener listener : listeners) + listener.changedItemLook(item); + }); + } } diff --git a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/model/ModelItem.java b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/model/ModelItem.java index 12cc766d2b..4f6cbb0fb7 100644 --- a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/model/ModelItem.java +++ b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/model/ModelItem.java @@ -57,6 +57,10 @@ abstract public class ModelItem */ private volatile Color color = null; + /** RGB for item's area color + */ + private volatile Color areaColor = null; + /** How to display the trace */ private volatile TraceType trace_type = Preferences.trace_type; diff --git a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/plot/ModelBasedPlot.java b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/plot/ModelBasedPlot.java index 7e974e9ab4..1ac3851b21 100644 --- a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/plot/ModelBasedPlot.java +++ b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/plot/ModelBasedPlot.java @@ -79,7 +79,7 @@ public class ModelBasedPlot public ModelBasedPlot(final boolean active) { plot = new RTTimePlot(active); - plot.setOpacity(Preferences.opacity); + plot.setAreaOpacity(Preferences.opacity); plot.showLegend(false); final Button time_config_button = @@ -368,6 +368,7 @@ public void updateTrace(final ModelItem item) // These happen to not cause an immediate redraw, so // set even if no change trace.setColor(item.getPaintColor()); + plot.setAreaOpacity(item.getModel().get().getAreaOpacity()); trace.setType(item.getTraceType()); trace.setWidth(item.getLineWidth()); trace.setLineStyle(item.getLineStyle()); diff --git a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/properties/FontButton.java b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/properties/FontButton.java index df92a230a8..d1c76f57fe 100644 --- a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/properties/FontButton.java +++ b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/properties/FontButton.java @@ -45,10 +45,13 @@ public class FontButton extends Button italic = new CheckBox(Messages.FontBtnItalics); private TextField example = new TextField(Messages.FontBtnExample); - private final PopOver popover; + private PopOver popover; private Font font; - private final Consumer on_font_selected; + private Consumer on_font_selected; + + public FontButton(){ + } /** @param initial_font Intiial font * @param on_font_selected Callback for selected font diff --git a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/properties/MiscTab.java b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/properties/MiscTab.java index fbc48efdd7..0c0885bfdf 100644 --- a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/properties/MiscTab.java +++ b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/properties/MiscTab.java @@ -7,21 +7,16 @@ ******************************************************************************/ package org.csstudio.trends.databrowser3.ui.properties; -import java.time.Duration; +import java.io.IOException; +import java.util.ResourceBundle; +import javafx.fxml.FXMLLoader; import org.csstudio.trends.databrowser3.Messages; import org.csstudio.trends.databrowser3.model.Model; -import org.csstudio.trends.databrowser3.model.ModelListener; +import org.phoebus.framework.nls.NLS; import org.phoebus.ui.undo.UndoableActionManager; -import javafx.geometry.Insets; -import javafx.scene.control.CheckBox; -import javafx.scene.control.ColorPicker; -import javafx.scene.control.Label; import javafx.scene.control.Tab; -import javafx.scene.control.TextField; -import javafx.scene.control.Tooltip; -import javafx.scene.layout.GridPane; /** Property tab for misc. items * @author Kay Kasemir @@ -29,191 +24,30 @@ @SuppressWarnings("nls") public class MiscTab extends Tab { - private final Model model; - - /** Flag to prevent recursion when this tab updates the model and thus triggers the model_listener */ - private boolean updating = false; - - private final TextField title = new TextField(), update_period = new TextField(), scroll_step = new TextField(); - private CheckBox save_changes = new CheckBox(), show_legend = new CheckBox(); - private ColorPicker foreground = new ColorPicker(), background = new ColorPicker(); - private FontButton title_font, label_font, scale_font, legend_font; - - /** Update Tab when model changes (undo, ...) */ - private ModelListener model_listener = new ModelListener() - { - @Override - public void changedSaveChangesBehavior(boolean do_save_changes) - { - if (updating) - return; - save_changes.setSelected(do_save_changes); - } - - @Override - public void changedLayout() - { - if (updating) - return; - show_legend.setSelected(model.isLegendVisible()); - } - - @Override - public void changedTitle() - { - if (updating) - return; - title.setText(model.getTitle().orElse("")); - } - - @Override - public void changedColorsOrFonts() - { - if (updating) - return; - foreground.setValue(model.getPlotForeground()); - background.setValue(model.getPlotBackground()); - title_font.selectFont(model.getTitleFont()); - label_font.selectFont(model.getLabelFont()); - scale_font.selectFont(model.getScaleFont()); - legend_font.selectFont(model.getLegendFont()); - } - - @Override - public void changedTiming() - { - if (updating) - return; - update_period.setText(Double.toString(model.getUpdatePeriod())); - scroll_step.setText(Double.toString(model.getScrollStep().toMillis() / 1000.0)); - } - }; - - MiscTab(final Model model, final UndoableActionManager undo) { - super(Messages.Miscellaneous); - this.model = model; - - final GridPane layout = new GridPane(); - layout.setHgap(5); - layout.setVgap(5); - layout.setPadding(new Insets(5)); - // layout.setGridLinesVisible(true); // Debug layout - - - layout.add(new Label(Messages.TitleLbl), 0, 0); - title.setTooltip(new Tooltip(Messages.TitleTT)); - title.setOnAction(event -> - { - updating = true; - new ChangeTitleCommand(model, undo, title.getText()); - updating = false; - }); - layout.add(title, 1, 0); - layout.add(new Label(Messages.UpdatePeriodLbl), 0, 1); - layout.add(update_period, 1, 1); - update_period.setOnAction(event -> - { - updating = true; - final double period = Double.parseDouble(update_period.getText().trim()); - new ChangeUpdatePeriodCommand(model, undo, period); - updating = false; - }); - - layout.add(new Label(Messages.ScrollStepLbl), 0, 2); - layout.add(scroll_step, 1, 2); - scroll_step.setOnAction(event -> - { - updating = true; - try - { - final Duration step = Duration.ofMillis( - Math.round( Double.parseDouble(scroll_step.getText().trim()) * 1000.0 ) ); - new ChangeScrollStepCommand(model, undo, step); - } - catch (Exception ex) - { - scroll_step.setText(Double.toString(model.getScrollStep().toMillis() / 1000.0)); + super(Messages.Miscellaneous); + ResourceBundle resourceBundle = NLS.getMessages(Messages.class); + FXMLLoader loader = new FXMLLoader(); + loader.setResources(resourceBundle); + loader.setLocation(this.getClass().getResource("MiscTab.fxml")); + + loader.setControllerFactory(clazz -> { + if(clazz.isAssignableFrom(MiscTabController.class)){ + try { + return clazz.getConstructor(Model.class, UndoableActionManager.class).newInstance(model, undo); + } catch (Exception e) { + throw new RuntimeException(e); + } } - updating = false; - }); - - layout.add(new Label(Messages.ForegroundColorLbl), 0, 3); - foreground.setStyle("-fx-color-label-visible: false ;"); - layout.add(foreground, 1, 3); - foreground.setValue(model.getPlotForeground()); - foreground.setOnAction(event -> - { - updating = true; - new ChangePlotForegroundCommand(model, undo, foreground.getValue()); - updating = false; - }); - - layout.add(new Label(Messages.BackgroundColorLbl), 0, 4); - background.setStyle("-fx-color-label-visible: false ;"); - layout.add(background, 1, 4); - background.setValue(model.getPlotBackground()); - background.setOnAction(event -> - { - updating = true; - new ChangePlotBackgroundCommand(model, undo, background.getValue()); - updating = false; - }); - - layout.add(new Label(Messages.SaveChangesLbl), 0, 5); - save_changes.setTooltip(new Tooltip(Messages.SaveChangesTT)); - save_changes.setOnAction(event -> - { - updating = true; - new ChangeSaveChangesCommand(model, undo, save_changes.isSelected()); - updating = false; + return null; }); - layout.add(save_changes, 1, 5); - layout.add(new Label(Messages.TitleFontLbl), 2, 0); - title_font = new FontButton(model.getTitleFont(), - font -> new ChangeFontCommand(model, undo, model.getTitleFont(), font, (m, f) -> m.setTitleFont(f))); - title_font.setMaxWidth(Double.MAX_VALUE); - layout.add(title_font, 3, 0); - - layout.add(new Label(Messages.LabelFontLbl), 2, 1); - label_font = new FontButton(model.getLabelFont(), - font -> new ChangeFontCommand(model, undo, model.getLabelFont(), font, (m, f) -> m.setLabelFont(f))); - label_font.setMaxWidth(Double.MAX_VALUE); - layout.add(label_font, 3, 1); - - layout.add(new Label(Messages.ScaleFontLbl), 2, 2); - scale_font = new FontButton(model.getScaleFont(), - font -> new ChangeFontCommand(model, undo, model.getScaleFont(), font, (m, f) -> m.setScaleFont(f))); - scale_font.setMaxWidth(Double.MAX_VALUE); - layout.add(scale_font, 3, 2); - - layout.add(new Label(Messages.LegendFontLbl), 2, 3); - legend_font = new FontButton(model.getLegendFont(), - font -> new ChangeFontCommand(model, undo, model.getLegendFont(), font, (m, f) -> m.setLegendFont(f))); - legend_font.setMaxWidth(Double.MAX_VALUE); - layout.add(legend_font, 3, 3); - - layout.add(new Label(Messages.LegendLbl), 2, 4); - show_legend.setOnAction(event -> - { - updating = true; - new ChangeShowLegendCommand(model, undo, show_legend.isSelected()); - updating = false; - }); - layout.add(show_legend, 3, 4); - - setContent(layout); - - model.addListener(model_listener); - - // Initial values - model_listener.changedTitle(); - model_listener.changedColorsOrFonts(); - model_listener.changedSaveChangesBehavior(model.shouldSaveChanges()); - model_listener.changedTiming(); - model_listener.changedLayout(); + try { + setContent(loader.load()); + } catch (IOException e) { + throw new RuntimeException(e); + } } } diff --git a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/properties/MiscTabController.java b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/properties/MiscTabController.java new file mode 100644 index 0000000000..0096866473 --- /dev/null +++ b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/properties/MiscTabController.java @@ -0,0 +1,221 @@ +/******************************************************************************* + * Copyright (c) 2018 Oak Ridge National Laboratory. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + ******************************************************************************/ +package org.csstudio.trends.databrowser3.ui.properties; + +import java.time.Duration; + +import javafx.scene.control.Slider; +import org.csstudio.trends.databrowser3.model.Model; +import org.csstudio.trends.databrowser3.model.ModelListener; +import org.phoebus.ui.undo.UndoableActionManager; + +import javafx.fxml.FXML; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ColorPicker; +import javafx.scene.control.TextField; + +/** + * Controller for MiscTab.fxml. + * Wire up via FXMLLoader: + * FXMLLoader loader = new FXMLLoader(getClass().getResource("MiscTab.fxml"), messages); + * MiscTabController ctrl = new MiscTabController(model, undo); + * loader.setController(ctrl); + * Tab tab = loader.load(); + */ +@SuppressWarnings({"nls", "unused"}) +public class MiscTabController +{ + // ----------------------------------------------------------------------- + // FXML-injected fields — names must match fx:id attributes in the FXML + // ----------------------------------------------------------------------- + + + @FXML private TextField title; + @FXML private TextField updatePeriod; + @FXML private TextField scrollStep; + @FXML private CheckBox saveChanges; + @FXML private CheckBox showLegend; + @FXML private ColorPicker foreground; + @FXML private ColorPicker background; + @FXML private FontButton titleFont; + @FXML private FontButton labelFont; + @FXML private FontButton scaleFont; + @FXML private FontButton legendFont; + @FXML private Slider opacitySlider; + + // ----------------------------------------------------------------------- + // Non-FXML state + // ----------------------------------------------------------------------- + + private final Model model; + private final UndoableActionManager undo; + + /** Prevents recursive updates when this controller writes to the model */ + private boolean updating = false; + + // ----------------------------------------------------------------------- + // Constructor + // ----------------------------------------------------------------------- + + public MiscTabController(final Model model, final UndoableActionManager undo) + { + this.model = model; + this.undo = undo; + } + + // ----------------------------------------------------------------------- + // Lifecycle — called automatically by FXMLLoader after injection + // ----------------------------------------------------------------------- + + @FXML + public void initialize() + { + + + // Seed ColorPickers with current model values + foreground.setValue(model.getPlotForeground()); + background.setValue(model.getPlotBackground()); + + // Register model listener so the tab stays in sync on undo/redo + model.addListener(modelListener); + + // Populate fields with initial model state + modelListener.changedTitle(); + modelListener.changedColorsOrFonts(); + modelListener.changedSaveChangesBehavior(model.shouldSaveChanges()); + modelListener.changedTiming(); + modelListener.changedLayout(); + + opacitySlider.valueProperty().setValue(model.getAreaOpacity()); + opacitySlider.valueProperty().addListener((observable, oldValue, newValue) -> { + updating = true; + model.setAreaOpacity((int)Math.round(opacitySlider.getValue())); + updating = false; + }); + } + + // ----------------------------------------------------------------------- + // onAction handlers — referenced from FXML via onAction="#..." + // ----------------------------------------------------------------------- + + @FXML + private void onTitleAction() + { + updating = true; + new ChangeTitleCommand(model, undo, title.getText()); + updating = false; + } + + @FXML + private void onUpdatePeriodAction() + { + updating = true; + final double period = Double.parseDouble(updatePeriod.getText().trim()); + new ChangeUpdatePeriodCommand(model, undo, period); + updating = false; + } + + @FXML + private void onScrollStepAction() + { + updating = true; + try + { + final Duration step = Duration.ofMillis( + Math.round(Double.parseDouble(scrollStep.getText().trim()) * 1000.0)); + new ChangeScrollStepCommand(model, undo, step); + } + catch (Exception ex) + { + scrollStep.setText(Double.toString(model.getScrollStep().toMillis() / 1000.0)); + } + updating = false; + } + + @FXML + private void onForegroundAction() + { + updating = true; + new ChangePlotForegroundCommand(model, undo, foreground.getValue()); + updating = false; + } + + @FXML + private void onBackgroundAction() + { + updating = true; + new ChangePlotBackgroundCommand(model, undo, background.getValue()); + updating = false; + } + + @FXML + private void onSaveChangesAction() + { + updating = true; + new ChangeSaveChangesCommand(model, undo, saveChanges.isSelected()); + updating = false; + } + + @FXML + private void onShowLegendAction() + { + updating = true; + new ChangeShowLegendCommand(model, undo, showLegend.isSelected()); + updating = false; + } + + // ----------------------------------------------------------------------- + // Model listener — keeps the tab in sync after undo / external changes + // ----------------------------------------------------------------------- + + private final ModelListener modelListener = new ModelListener() + { + @Override + public void changedSaveChangesBehavior(boolean do_save_changes) + { + if (!updating) + saveChanges.setSelected(do_save_changes); + } + + @Override + public void changedLayout() + { + if (!updating) + showLegend.setSelected(model.isLegendVisible()); + } + + @Override + public void changedTitle() + { + if (!updating) + title.setText(model.getTitle().orElse("")); + } + + @Override + public void changedColorsOrFonts() + { + if (updating) + return; + foreground.setValue(model.getPlotForeground()); + background.setValue(model.getPlotBackground()); + titleFont.selectFont(model.getTitleFont()); + labelFont.selectFont(model.getLabelFont()); + scaleFont.selectFont(model.getScaleFont()); + legendFont.selectFont(model.getLegendFont()); + } + + @Override + public void changedTiming() + { + if (updating) + return; + updatePeriod.setText(Double.toString(model.getUpdatePeriod())); + scrollStep.setText(Double.toString(model.getScrollStep().toMillis() / 1000.0)); + } + }; +} diff --git a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/properties/TracesTab.java b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/properties/TracesTab.java index 25888e768a..22d8e88581 100644 --- a/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/properties/TracesTab.java +++ b/app/databrowser/src/main/java/org/csstudio/trends/databrowser3/ui/properties/TracesTab.java @@ -13,7 +13,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.logging.Level; import java.util.stream.Collectors; import org.csstudio.javafx.rtplot.LineStyle; diff --git a/app/databrowser/src/main/resources/org/csstudio/trends/databrowser3/messages.properties b/app/databrowser/src/main/resources/org/csstudio/trends/databrowser3/messages.properties index 89a7537c48..c6cf31e00b 100644 --- a/app/databrowser/src/main/resources/org/csstudio/trends/databrowser3/messages.properties +++ b/app/databrowser/src/main/resources/org/csstudio/trends/databrowser3/messages.properties @@ -17,6 +17,8 @@ AddPV_PeriodTT=Enter scan period in seconds AddPVMsg=Enter PV name(s) and configure axis and scan period AppendSearchResults=Add... AppendSearchResultsTT=Append search results to list +AreaOpacity=Area Opacity (%) +AreaOpacityTT=Opacity of area in between min and max curves ArchiveFetchJobFmt=Read data: {0}, {1} - {2} ArchiveFetchStart=Reading data ArchiveFetchProgressFmt={0}, {1} sec diff --git a/app/databrowser/src/main/resources/org/csstudio/trends/databrowser3/ui/properties/MiscTab.fxml b/app/databrowser/src/main/resources/org/csstudio/trends/databrowser3/ui/properties/MiscTab.fxml new file mode 100644 index 0000000000..da5244a4ab --- /dev/null +++ b/app/databrowser/src/main/resources/org/csstudio/trends/databrowser3/ui/properties/MiscTab.fxml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + diff --git a/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/RTPlot.java b/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/RTPlot.java index 6223e69c99..3d1880e896 100644 --- a/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/RTPlot.java +++ b/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/RTPlot.java @@ -298,7 +298,7 @@ public void setBackground(final Color color) } /** Opacity (0 .. 100 %) of 'area' */ - public void setOpacity(final int opacity) + public void setAreaOpacity(final int opacity) { plot.setAreaOpacity(opacity); } @@ -456,18 +456,42 @@ public void removeYAxis(final int index) * @param units Units, may be null * @param data * @param color + * @param areaColor * @param type * @param width * @param y_axis * @return {@link Trace} that was added */ public Trace addTrace(final String name, final String units, - final PlotDataProvider data, - final Color color, - final TraceType type, final int width, - final LineStyle line_style, - final PointType point_type, final int size, - final int y_axis) + final PlotDataProvider data, + final Color color, + final Color areaColor, + final TraceType type, final int width, + final LineStyle line_style, + final PointType point_type, final int size, + final int y_axis) + { + final TraceImpl trace = new TraceImpl<>(name, units, data, color, areaColor, type, width, line_style, point_type, size, y_axis); + plot.addTrace(trace); + return trace; + } + + /** @param name Name, must not be null + * @param units Units, may be null + * @param data + * @param color + * @param type + * @param width + * @param y_axis + * @return {@link Trace} that was added + */ + public Trace addTrace(final String name, final String units, + final PlotDataProvider data, + final Color color, + final TraceType type, final int width, + final LineStyle line_style, + final PointType point_type, final int size, + final int y_axis) { final TraceImpl trace = new TraceImpl<>(name, units, data, color, type, width, line_style, point_type, size, y_axis); plot.addTrace(trace); diff --git a/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/Trace.java b/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/Trace.java index 17e786bce5..686c962231 100644 --- a/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/Trace.java +++ b/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/Trace.java @@ -68,6 +68,12 @@ default public String getLabel() /** @param color Color to use for this trace */ public void setColor(final Color color); + /** @return Color to use for this trace */ + public Color getAreaColor(); + + /** @param color Color to use for this trace */ + public void setAreaColor(final Color color); + /** @return How to draw this trace */ public TraceType getType(); diff --git a/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/Plot.java b/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/Plot.java index 9f06346629..7fd420a277 100644 --- a/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/Plot.java +++ b/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/Plot.java @@ -74,8 +74,8 @@ public class Plot> extends PlotCanvasBase private volatile Color background = Color.WHITE, grid = Color.DARK_GRAY; - /** Opacity (0 .. 100 %) of 'area' */ - private volatile int opacity = 20; + /** Opacity (0 .. 100) of 'area' */ + private volatile int areaOpacity = 20; public static final String FONT_FAMILY = "Liberation Sans"; @@ -109,9 +109,9 @@ public class Plot> extends PlotCanvasBase private AxisRange mouse_start_x_range; /** Initial range of the mouse_y_axis or all Y axes, depending on mouse mode */ - private List> mouse_start_y_ranges = new ArrayList<>(); + private final List> mouse_start_y_ranges = new ArrayList<>(); /** Initial autorange setting of the mouse_y_axis or all Y axes, depending on mouse mode */ - private List pre_pan_auto_scales = new ArrayList<>(); + private final List pre_pan_auto_scales = new ArrayList<>(); private int mouse_y_axis = -1; // Annotation-related info. If mouse_annotation is set, the rest should be set. @@ -202,12 +202,12 @@ public void setBackground(final Color color) background = color; } - /** Opacity (0 .. 100 %) of 'area' */ + /** Opacity (0 .. 255) of 'area' */ // 'setOpacity', as used in original SWT implementation, // is already used by JFX Node base class - public void setAreaOpacity(final int opacity) + public void setAreaOpacity(final int areaOpacity) { - this.opacity = opacity; + this.areaOpacity = areaOpacity; } /** @param color Grid color */ @@ -686,7 +686,7 @@ protected BufferedImage updateImageBuffer() for (YAxisImpl y_axis : y_axes) for (Trace trace : y_axis.getTraces()) - trace_painter.paint(gc, plot_area.getBounds(), opacity, x_transform, y_axis, trace); + trace_painter.paint(gc, plot_area.getBounds(), areaOpacity, x_transform, y_axis, trace); drawPlotMarkers(gc); gc.setClip(null); diff --git a/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/TraceImpl.java b/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/TraceImpl.java index e4afbc3826..1c140bfa44 100644 --- a/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/TraceImpl.java +++ b/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/TraceImpl.java @@ -37,6 +37,8 @@ public class TraceImpl> implements Trace private volatile Color color; + private volatile Color areaColor; + private volatile TraceType type; private volatile int width; @@ -52,10 +54,23 @@ public class TraceImpl> implements Trace private volatile Optional> selected_sample = Optional.empty(); + public TraceImpl(final String name, + final String units, + final PlotDataProvider data, + final Color color, + final TraceType type, final int width, + final LineStyle line_style, + final PointType point_type, final int size, + final int y_axis) + { + this(name, units, data, color, color, type, width, line_style, point_type, size, y_axis); + } + public TraceImpl(final String name, final String units, final PlotDataProvider data, final Color color, + final Color areaColor, final TraceType type, final int width, final LineStyle line_style, final PointType point_type, final int size, @@ -65,6 +80,7 @@ public TraceImpl(final String name, this.units = units == null ? "" : units; this.data = Objects.requireNonNull(data); this.color = Objects.requireNonNull(color); + this.areaColor = Objects.requireNonNull(areaColor); this.type = Objects.requireNonNull(type); this.width = width; this.line_style = line_style; @@ -148,6 +164,20 @@ public void setColor(final Color color) this.color = Objects.requireNonNull(color); } + /** {@inheritDoc} */ + @Override + public Color getAreaColor() + { + return areaColor; + } + + /** {@inheritDoc} */ + @Override + public void setAreaColor(final Color areaColor) + { + this.areaColor = Objects.requireNonNull(areaColor); + } + /** {@inheritDoc} */ @Override public TraceType getType() diff --git a/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/TracePainter.java b/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/TracePainter.java index ddba1f3fa4..4c402b5978 100644 --- a/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/TracePainter.java +++ b/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/TracePainter.java @@ -57,7 +57,7 @@ public class TracePainter> final private static int OUTSIDE = 1000; private int x_min, x_max, y_min, y_max; - final private int clipX(final double x) + private int clipX(final double x) { if (x < x_min) return x_min; @@ -66,7 +66,7 @@ final private int clipX(final double x) return (int)x; } - final private int clipY(final int y) + private int clipY(final int y) { if (y < y_min) return y_min; @@ -77,11 +77,11 @@ final private int clipY(final int y) /** @param gc GC * @param bounds Clipping bounds within which to paint - * @param opacity Opacity (0 .. 100 %) of 'area' + * @param areaOpacity The opacity (0..100) of the trace area. * @param x_transform Coordinate transform used by the x axis * @param trace Trace, has reference to its value axis */ - final public void paint(final Graphics2D gc, final Rectangle bounds, final int opacity, + final public void paint(final Graphics2D gc, final Rectangle bounds, final int areaOpacity, final ScreenTransform x_transform, final YAxisImpl y_axis, final Trace trace) { @@ -104,7 +104,7 @@ final public void paint(final Graphics2D gc, final Rectangle bounds, final int o final Stroke old_width = gc.getStroke(); final Color color = GraphicsUtils.convert(trace.getColor()); - final Color tpcolor = new Color(color.getRed(), color.getGreen(), color.getBlue(), opacity); + final Color tpcolor = GraphicsUtils.convert(trace.getColor(), (int)Math.round(2.55 * areaOpacity)); gc.setColor(color); // TODO Optimize drawing @@ -253,7 +253,7 @@ private static float[] scale_dash(final float[] dash, final int line_width) return scaled; } - private final static Stroke createStroke(final int line_width, final LineStyle line_style) + private static Stroke createStroke(final int line_width, final LineStyle line_style) { switch (line_style) { @@ -281,7 +281,7 @@ private final static Stroke createStroke(final int line_width, final LineStyle l * @param line_width * @param line_style */ - final private void drawValueStaircase(final Graphics2D gc, + private void drawValueStaircase(final Graphics2D gc, final ScreenTransform x_transform, final YAxisImpl y_axis, final PlotDataProvider data, final int start, final int end, @@ -329,7 +329,7 @@ final private void drawValueStaircase(final Graphics2D gc, * @param line_width * @param line_style */ - final private void drawValueLines(final Graphics2D gc, + private void drawValueLines(final Graphics2D gc, final ScreenTransform x_transform, final YAxisImpl y_axis, final PlotDataProvider data, final int line_width, final LineStyle line_style) { @@ -369,7 +369,7 @@ final private void drawValueLines(final Graphics2D gc, * @param start Start and .. * @param end .. end index of data to plot */ - final private void drawMinMaxArea(final Graphics2D gc, + private void drawMinMaxArea(final Graphics2D gc, final ScreenTransform x_transform, final YAxisImpl y_axis, final PlotDataProvider data, final int start, final int end) @@ -407,7 +407,7 @@ final private void drawMinMaxArea(final Graphics2D gc, * @param y_axis Value axis * @param data Data */ - final private void drawMinMaxLines(final Graphics2D gc, + private void drawMinMaxLines(final Graphics2D gc, final ScreenTransform x_transform, final YAxisImpl y_axis, final PlotDataProvider data, final int line_width) { @@ -449,7 +449,7 @@ final private void drawMinMaxLines(final Graphics2D gc, * @param end .. end index of data to plot * @param line_width */ - final private void drawStdDevLines(final Graphics2D gc, final ScreenTransform x_transform, final YAxisImpl y_axis, + private void drawStdDevLines(final Graphics2D gc, final ScreenTransform x_transform, final YAxisImpl y_axis, final PlotDataProvider data, final int start, final int end, final int line_width) { final IntList lower_poly_y = new IntList(INITIAL_ARRAY_SIZE); @@ -484,7 +484,7 @@ final private void drawStdDevLines(final Graphics2D gc, final ScreenTransform 1) * @param data Data * @param size */ - final private void drawErrorBars(final Graphics2D gc, + private void drawErrorBars(final Graphics2D gc, final ScreenTransform x_transform, final YAxisImpl y_axis, final PlotDataProvider data, final int size) { @@ -541,7 +541,7 @@ final private void drawErrorBars(final Graphics2D gc, * @param point_type * @param size */ - final private void drawPoints(final Graphics2D gc, + private void drawPoints(final Graphics2D gc, final ScreenTransform x_transform, final YAxisImpl y_axis, final PlotDataProvider data, PointType point_type, final int size) { @@ -551,7 +551,6 @@ final private void drawPoints(final Graphics2D gc, { final PlotDataItem item = data.get(i); final double value = item.getValue(); - final XTYPE loc = item.getPosition(); if (!Double.isNaN(value)) { final int x = clipX(Math.round(x_transform.transform(item.getPosition()))); @@ -643,7 +642,7 @@ final private void flushPolyFill(final Graphics2D gc, final IntList pos, final I * @param data Data * @param width Width of each bar */ - final private void drawBars(final Graphics2D gc, + private void drawBars(final Graphics2D gc, final ScreenTransform x_transform, final YAxisImpl y_axis, final PlotDataProvider data, int width) { @@ -673,7 +672,7 @@ final private void drawBars(final Graphics2D gc, * @param y_axis Value axis * @param data Data */ - final private void drawHistogram(final Graphics2D gc, + private void drawHistogram(final Graphics2D gc, final ScreenTransform x_transform, final YAxisImpl y_axis, final PlotDataProvider data) {