Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package org.csstudio.display.builder.model.widgets;

import static org.csstudio.display.builder.model.ModelPlugin.logger;
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.newBooleanPropertyDescriptor;
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propDirection;
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propFile;
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propFont;
Expand All @@ -26,6 +27,7 @@
import org.csstudio.display.builder.model.ArrayWidgetProperty;
import org.csstudio.display.builder.model.DisplayModel;
import org.csstudio.display.builder.model.MacroizedWidgetProperty;
import org.csstudio.display.builder.model.Messages;
import org.csstudio.display.builder.model.StructuredWidgetProperty;
import org.csstudio.display.builder.model.Widget;
import org.csstudio.display.builder.model.WidgetCategory;
Expand All @@ -47,7 +49,9 @@
*/
public class NavigationTabsWidget extends VisibleWidget
{
/** Widget descriptor */
private static final WidgetColor DEFAULT_SELECT_COLOR = new WidgetColor(236, 236, 236);
private static final WidgetColor DEFAULT_DESELECT_COLOR = new WidgetColor(200, 200, 200);
/** Widget descriptor */
public static final WidgetDescriptor WIDGET_DESCRIPTOR =
new WidgetDescriptor("navtabs", WidgetCategory.STRUCTURE,
"Navigation Tabs",
Expand All @@ -61,10 +65,17 @@ public Widget createWidget()
}
};

// 'state' structure that describes one state
// 'tab' structure that describes one tab
private static final StructuredWidgetProperty.Descriptor propTab =
new StructuredWidgetProperty.Descriptor(WidgetPropertyCategory.BEHAVIOR, "tab", "Tab");

// Elements of the 'tab' structure
private static final WidgetPropertyDescriptor<WidgetColor> propIndividualSelectedColor =
CommonWidgetProperties.newColorPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "selected_color", "Selected Color");

private static final WidgetPropertyDescriptor<WidgetColor> propIndividualDeselectedColor =
CommonWidgetProperties.newColorPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "deselected_color", "Deselected Color");

/** Structure for one tab item and its embedded display */
public static class TabProperty extends StructuredWidgetProperty
{
Expand All @@ -77,7 +88,9 @@ public TabProperty(final Widget widget, final int index)
Arrays.asList(propName.createProperty(widget, "Tab " + (index + 1)),
propFile.createProperty(widget, ""),
propMacros.createProperty(widget, new Macros()),
propGroupName.createProperty(widget, "")
propGroupName.createProperty(widget, ""),
propIndividualSelectedColor.createProperty(widget, DEFAULT_SELECT_COLOR),
propIndividualDeselectedColor.createProperty(widget, DEFAULT_DESELECT_COLOR)
));
}
/** @return Tab name */
Expand All @@ -88,6 +101,11 @@ public TabProperty(final Widget widget, final int index)
public WidgetProperty<Macros> macros() { return getElement(2); }
/** @return Optional sub-group of file */
public WidgetProperty<String> group() { return getElement(3); }
/** @return Tab color when selected */
public WidgetProperty<WidgetColor> individual_selected_color() { return getElement(4); }
/** @return Tab color when not selected */
public WidgetProperty<WidgetColor> individual_deselected_color() { return getElement(5); }

}

// 'tabs' array
Expand All @@ -101,15 +119,18 @@ public TabProperty(final Widget widget, final int index)
private static final WidgetPropertyDescriptor<Integer> propTabSpacing =
CommonWidgetProperties.newIntegerPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "tab_spacing", "Tab Spacing");

private static final WidgetPropertyDescriptor<WidgetColor> propDeselectedColor =
CommonWidgetProperties.newColorPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "deselected_color", "Deselected Color");

private static final WidgetPropertyDescriptor<Boolean> propEnablePerTabColors =
CommonWidgetProperties.newBooleanPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "enable_per_tab_colors", "Per Tab Colors");

private static final WidgetPropertyDescriptor<WidgetColor> propDeselectedColor =
CommonWidgetProperties.newColorPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "deselected_color", "Deselected Color");

private volatile ArrayWidgetProperty<TabProperty> tabs;
private volatile WidgetProperty<Direction> direction;
private volatile WidgetProperty<Integer> tab_width;
private volatile WidgetProperty<Integer> tab_height;
private volatile WidgetProperty<Integer> tab_spacing;
private volatile WidgetProperty<Boolean> enable_per_tab_colors;
private volatile WidgetProperty<WidgetColor> selected_color;
private volatile WidgetProperty<WidgetColor> deselected_color;
private volatile WidgetProperty<WidgetFont> font;
Expand All @@ -134,8 +155,9 @@ protected void defineProperties(final List<WidgetProperty<?>> properties)
properties.add(tab_width = propTabWidth.createProperty(this, ActionButtonWidget.DEFAULT_WIDTH));
properties.add(tab_height = propTabHeight.createProperty(this, ActionButtonWidget.DEFAULT_HEIGHT));
properties.add(tab_spacing = propTabSpacing.createProperty(this, 2));
properties.add(selected_color = propSelectedColor.createProperty(this, new WidgetColor(236, 236, 236)));
properties.add(deselected_color = propDeselectedColor.createProperty(this, new WidgetColor(200, 200, 200)));
properties.add(enable_per_tab_colors = propEnablePerTabColors.createProperty(this, false));
properties.add(selected_color = propSelectedColor.createProperty(this, DEFAULT_SELECT_COLOR));
properties.add(deselected_color = propDeselectedColor.createProperty(this, DEFAULT_DESELECT_COLOR));
properties.add(font = propFont.createProperty(this, WidgetFontService.get(NamedWidgetFonts.DEFAULT)));
properties.add(active = propActiveTab.createProperty(this, 0));
properties.add(embedded_model = runtimeModel.createProperty(this, null));
Expand Down Expand Up @@ -171,6 +193,12 @@ public WidgetProperty<Integer> propTabSpacing()
return tab_spacing;
}

/** @return 'enable_per_tab_colors' property */
public WidgetProperty<Boolean> propEnablePerTabColors()
{
return enable_per_tab_colors;
}

/** @return 'selected_color' property */
public WidgetProperty<WidgetColor> propSelectedColor()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
import java.util.concurrent.CopyOnWriteArrayList;

import org.csstudio.display.builder.model.properties.Direction;
import org.csstudio.display.builder.model.properties.WidgetColor;
import org.csstudio.display.builder.representation.javafx.JFXUtil;
import org.phoebus.ui.javafx.NonCachingScrollPane;

import javafx.collections.ObservableList;
import javafx.css.PseudoClass;
Expand All @@ -26,7 +28,6 @@
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import org.phoebus.ui.javafx.NonCachingScrollPane;

/** Navigation Tabs
*
Expand Down Expand Up @@ -72,10 +73,20 @@ public static interface Listener
private final Pane body = new Pane();

/** Labels for the tabs */
private final List<String> tabs = new CopyOnWriteArrayList<>();
private final List<String> tab_names = new CopyOnWriteArrayList<>();

/** Selected colors for the tabs */
private final List<WidgetColor> tab_selected_colors = new CopyOnWriteArrayList<>();

/** Deselected colors for the tabs */
private final List<WidgetColor> tab_deselected_colors = new CopyOnWriteArrayList<>();

/** Size and spacing for the tabs */
private int tab_width = 100, tab_height = 50, tab_spacing = 2;

/** Enable per tab colors */
private boolean enable_per_tab_colors = false;

/** Direction of tabs */
private Direction direction = Direction.VERTICAL;

Expand All @@ -84,6 +95,7 @@ public static interface Listener
deselected = Color.rgb(200, 200, 200);

private Font font = null;
private int selected_tab = -1;

/** Listener to selected tab
*
Expand Down Expand Up @@ -123,21 +135,33 @@ public void removeListener(final Listener listener)
}

/** @param tabs Tab labels */
public void setTabs(final List<String> tabs)
public void setTabNames(final List<String> tab_names)
{
this.tab_names.clear();
this.tab_names.addAll(tab_names);
updateTabs();
}

/** @param tabs Selected colors */
public void setTabSelectedColors(final List<WidgetColor> tab_selected_colors)
{
this.tabs.clear();
this.tabs.addAll(tabs);
this.tab_selected_colors.clear();
this.tab_selected_colors.addAll(tab_selected_colors);
updateTabs();
}

/** @param tabs Deselected colors */
public void setTabDeselectedColors(final List<WidgetColor> tab_deselected_colors)
{
this.tab_deselected_colors.clear();
this.tab_deselected_colors.addAll(tab_deselected_colors);
updateTabs();
}

/** @return Index of the selected tab. -1 if there are no buttons or nothing selected */
public int getSelectedTab()
{
final ObservableList<Node> siblings = buttons.getChildren();
for (int i=0; i<siblings.size(); ++i)
if (((ToggleButton) siblings.get(i)).isSelected())
return i;
return -1;
return selected_tab;
}

/** Select a tab
Expand Down Expand Up @@ -202,6 +226,15 @@ public void setTabSpacing(final int spacing)
updateTabs();
}

/** @param enable per tab colors */
public void setEnablePerTabColors(final boolean enabled)
{
if (enable_per_tab_colors == enabled)
return;
enable_per_tab_colors = enabled;
updateTabs();
}

/** @param color Color for selected tab */
public void setSelectedColor(final Color color)
{
Expand Down Expand Up @@ -250,17 +283,42 @@ private void updateTabs()
buttons.getStyleClass().add("navtab_tabregion");

// Create button for each tab
for (int i=0; i<tabs.size(); ++i)
{
final ToggleButton button = new ToggleButton(tabs.get(i));
Color tmpColor = deselected;
WidgetColor tmpWidgetColor = null;

for (int i = 0; i < tab_names.size(); ++i) {
final ToggleButton button = new ToggleButton(tab_names.get(i));
// Buttons without text vanish, creating a gap in the tab lineup.
if (button.getText().isEmpty())
button.setVisible(false);
if (direction == Direction.HORIZONTAL)
button.pseudoClassStateChanged(HORIZONTAL, true);

if (getSelectedTab() == i) {
button.setSelected(true);
// Set color to global "selected" color value
tmpColor = selected;
// If the per-tab colors are enabled, the color to apply is to be found in the tab_selected_colors list
if (enable_per_tab_colors == true) {
if (i < tab_selected_colors.size()) {
tmpWidgetColor = tab_selected_colors.get(i);
tmpColor = JFXUtil.convert(tmpWidgetColor);
}
}
} else {
// Set color to global "deselected" color value
tmpColor = deselected;
// If the per-tab colors are enabled, the color to apply is to be found in the tab_deselected_colors list
if (enable_per_tab_colors == true) {
if (i < tab_deselected_colors.size()) {
tmpWidgetColor = tab_deselected_colors.get(i);
tmpColor = JFXUtil.convert(tmpWidgetColor);
}
}
}

// base color, '-fx-color', is either selected or deselected
button.setStyle("-fx-color: " + JFXUtil.webRGB(deselected));
button.setStyle("-fx-color: " + JFXUtil.webRGB(tmpColor));
button.getStyleClass().add("navtab_button");
button.setMinSize(ButtonBase.USE_PREF_SIZE, ButtonBase.USE_PREF_SIZE);
button.setPrefSize(tab_width, tab_height);
Expand All @@ -277,27 +335,48 @@ private void updateTabs()
private void handleTabSelection(final ToggleButton pressed, final boolean notify)
{
final ObservableList<Node> siblings = buttons.getChildren();
int i = 0, selected_tab = -1;
int i = 0;
selected_tab = -1;
Color tmpColor = deselected;
WidgetColor tmpWidgetColor = null;
for (Node sibling : siblings)
{
final ToggleButton button = (ToggleButton) sibling;
if (button == pressed)
{
// Set color to global "selected" color value
tmpColor = selected;
// If user clicked a button that was already selected,
// it would now be de-selected, leaving nothing selected.
if (! pressed.isSelected())
{ // Re-select!
pressed.setSelected(true);
}
// Highlight active tab by setting it to the 'selected' color
pressed.setStyle("-fx-color: " + JFXUtil.webRGB(selected));
// If the per-tab colors are enabled, the color to apply is to be found in the tab_selected_colors list
if (enable_per_tab_colors == true) {
if(i < tab_selected_colors.size()) {
tmpWidgetColor = tab_selected_colors.get(i);
tmpColor = JFXUtil.convert(tmpWidgetColor);
}
}
pressed.setStyle("-fx-color: " + JFXUtil.webRGB(tmpColor));
selected_tab = i;
}
else if (button.isSelected())
{
// Radio-button behavior: De-select other tabs
button.setSelected(false);
button.setStyle("-fx-color: " + JFXUtil.webRGB(deselected));
// Set color to global "deselected" color value
tmpColor = deselected;
// If the per-tab colors are enabled, the color to apply is to be found in the tab_deselected_colors list
if (enable_per_tab_colors == true) {
if(i < tab_deselected_colors.size()) {
tmpWidgetColor = tab_deselected_colors.get(i);
tmpColor = JFXUtil.convert(tmpWidgetColor);
}
}
button.setStyle("-fx-color: " + JFXUtil.webRGB(tmpColor));
}
++i;
}
Expand Down
Loading