Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 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 @@ -481,8 +481,10 @@ private void updateGlobalParameters() {
} else if (questionListPane.isExpanded() && currentQuestion != null) {
final Class<? extends AnalyticAggregator<?>> questionAggregatorType = currentQuestion.getAggregatorType();
aggregators.add(new AnalyticAggregatorParameterValue(AnalyticUtilities.lookupAnalyticAggregator(questionAggregatorType)));
SingleChoiceParameterType.setOptionsData(aggregatorParameter, aggregators);
SingleChoiceParameterType.setChoiceData(aggregatorParameter, aggregators.get(0));
if (aggregators != null) {
SingleChoiceParameterType.setOptionsData(aggregatorParameter, aggregators);
SingleChoiceParameterType.setChoiceData(aggregatorParameter, aggregators.get(0));
}
}
pluginList.getItems().forEach(selectablePlugin
-> selectablePlugin.setUpdatedParameter(aggregatorParameter.getId(), aggregatorParameter.getStringValue()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,126 +15,97 @@
*/
package au.gov.asd.tac.constellation.plugins.gui;

import au.gov.asd.tac.constellation.plugins.parameters.ParameterChange;
import static au.gov.asd.tac.constellation.plugins.parameters.ParameterChange.ENABLED;
import static au.gov.asd.tac.constellation.plugins.parameters.ParameterChange.PROPERTY;
import static au.gov.asd.tac.constellation.plugins.parameters.ParameterChange.VALUE;
import static au.gov.asd.tac.constellation.plugins.parameters.ParameterChange.VISIBLE;
import au.gov.asd.tac.constellation.plugins.parameters.PluginParameter;
import au.gov.asd.tac.constellation.plugins.parameters.PluginParameterListener;
import au.gov.asd.tac.constellation.plugins.parameters.types.ParameterValue;
import au.gov.asd.tac.constellation.plugins.parameters.types.SingleChoiceParameterType;
import au.gov.asd.tac.constellation.plugins.parameters.types.SingleChoiceParameterType.SingleChoiceParameterValue;
import au.gov.asd.tac.constellation.utilities.gui.field.SingleChoiceInput;
import au.gov.asd.tac.constellation.utilities.gui.field.framework.ConstellationInputConstants.ChoiceType;
import au.gov.asd.tac.constellation.utilities.gui.field.framework.ConstellationInputListener;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.layout.HBox;
import org.controlsfx.control.SearchableComboBox;

/**
* A drop-down combo box which is the GUI element corresponding to a
* {@link PluginParameter} of
* A drop-down combo box which is the GUI element corresponding to a {@link PluginParameter} of
* {@link au.gov.asd.tac.constellation.plugins.parameters.types.SingleChoiceParameterType}.
* <p>
* Selecting an item from the drop-down will set the choice data for the
* underlying {@link PluginParameter}.
* Selecting an item from the drop-down will set the choice data for the underlying {@link PluginParameter}.
*
* @see
* au.gov.asd.tac.constellation.plugins.parameters.types.SingleChoiceParameterType
* @see au.gov.asd.tac.constellation.plugins.parameters.types.SingleChoiceParameterType
*
* @author ruby_crucis
*/
public class SingleChoiceInputPane extends HBox {
public class SingleChoiceInputPane extends ParameterInputPane<SingleChoiceParameterValue, ParameterValue> {

private static final Logger LOGGER = Logger.getLogger(SingleChoiceInputPane.class.getName());

public static final int DEFAULT_WIDTH = 300;

private final SearchableComboBox<ParameterValue> field;
private boolean initialRun = true;

public SingleChoiceInputPane(final PluginParameter<SingleChoiceParameterValue> parameter) {
field = new SearchableComboBox<>();
field.setPromptText(parameter.getDescription());

final ObservableList<ParameterValue> optionsList = FXCollections.observableArrayList();
optionsList.setAll(SingleChoiceParameterType.getOptionsData(parameter));
field.setItems(optionsList);

final ParameterValue initialValue = parameter.getParameterValue();
if (initialValue.getObjectValue() != null) {
field.getSelectionModel().select(initialValue);
}

field.setPrefWidth(DEFAULT_WIDTH);
field.setDisable(!parameter.isEnabled());
field.setManaged(parameter.isVisible());
field.setVisible(parameter.isVisible());
this.setManaged(parameter.isVisible());
this.setVisible(parameter.isVisible());

if (parameter.getParameterValue().getGuiInit() != null) {
parameter.getParameterValue().getGuiInit().init(field);
}

field.setOnAction(event -> SingleChoiceParameterType.setChoiceData(parameter, field.getSelectionModel().getSelectedItem()));

parameter.addListener((scParameter, change) -> Platform.runLater(() -> {
if (scParameter.getParameterValue() instanceof SingleChoiceParameterValue scParameterValue){
switch (change) {
case VALUE -> {
// Don't change the value if it isn't necessary.
final List<ParameterValue> param = scParameterValue.getOptionsData();
final ParameterValue value = field.getSelectionModel().getSelectedItem();

//Checks that the currently selected value is in the new parameters list
if (!param.contains(value)) {
field.getSelectionModel().select(scParameterValue.getChoiceData());
}

// give a visual indicator if a required parameter is empty
field.setId(scParameter.isRequired() && field.getSelectionModel().isEmpty() ? "invalid selection" : "");
field.setStyle("invalid selection".equals(field.getId()) ? "-fx-color: #8A1D1D" : "");
}
case PROPERTY -> {
final ObservableList<ParameterValue> options = FXCollections.observableArrayList();
final EventHandler<ActionEvent> handler = field.getOnAction();
field.setOnAction(null);

options.setAll(scParameterValue.getOptionsData());
field.setItems(options);
field.setOnAction(handler);
super(new SingleChoiceInput<ParameterValue>(ChoiceType.SINGLE_DROPDOWN), parameter);
final SingleChoiceParameterType.SingleChoiceParameterValue pv = parameter.getParameterValue();
((SingleChoiceInput) input).setOptions(pv.getOptionsData());
((SingleChoiceInput) input).setIcons(pv.getIcons());
setFieldValue(pv.getChoiceData());
}

if (initialRun) {
// This is a workaround to fix dynamically changing drop downs.
// Otherwise when the Constellation is loaded for the first time,
// such lists wouldn't populate until clicked twice on the arrow.
// E.g. `Type Category` drop down in `Select Top N` plugin
field.show();
field.hide();
field.requestFocus();
initialRun = false;
}
@Override
public ConstellationInputListener getFieldChangeListener(final PluginParameter<SingleChoiceParameterValue> parameter) {
return (ConstellationInputListener<ParameterValue>) (final ParameterValue newValue) -> {
if (newValue != null) {
SingleChoiceParameterType.setChoiceData(parameter, newValue);
}
};
}

// Only keep the value if it's in the new choices.
if (options.contains(scParameterValue.getChoiceData())) {
field.getSelectionModel().select(scParameter.getSingleChoice());
} else {
field.getSelectionModel().clearSelection();
}
}
@Override
public PluginParameterListener getPluginParameterListener() {
// The listener needs to be assigned and then returned otherwise it doesn't update as intended
final PluginParameterListener listener = (final PluginParameter<?> parameter, final ParameterChange change) -> {
final PluginParameter<SingleChoiceParameterValue> scParameterValue = (PluginParameter<SingleChoiceParameterValue>) parameter;
switch (change) {
case VALUE -> {
final List<ParameterValue> paramOptions = SingleChoiceParameterType.getOptionsData(scParameterValue);
((SingleChoiceInput) input).setOptions(paramOptions);

// Only keep the value if its in the new choices
if (paramOptions.stream().anyMatch(paramOptions::contains)) {
setFieldValue(SingleChoiceParameterType.getChoiceData(scParameterValue));
} else {
setFieldValue(null);
}
// Don't change the value if it isn't necessary
final ParameterValue selection = getFieldValue();
if (selection != null && !selection.equals(SingleChoiceParameterType.getChoiceData(scParameterValue))) {
setFieldValue(selection);
}
}

case ENABLED -> field.setDisable(!scParameter.isEnabled());
case VISIBLE -> {
field.setManaged(scParameter.isVisible());
field.setVisible(scParameter.isVisible());
this.setVisible(scParameter.isVisible());
this.setManaged(scParameter.isVisible());
case PROPERTY -> {
// Update the pane if the options have changed
final List<ParameterValue> paramOptions = (List<ParameterValue>) SingleChoiceParameterType.getChoiceData(scParameterValue);
if (paramOptions != null) {
((SingleChoiceInput) input).setOptions(paramOptions);
if (paramOptions.contains(SingleChoiceParameterType.getChoiceData(scParameterValue))) {
setFieldValue(SingleChoiceParameterType.getChoiceData(scParameterValue));
} else {
setFieldValue(null);
}
default -> LOGGER.log(Level.FINE, "ignoring parameter change type {0}.", change);
}
}
}));

getChildren().add(field);
case ENABLED ->
updateFieldEnablement();
case VISIBLE ->
updateFieldVisibility();
default ->
LOGGER.log(Level.FINE, "ignoring parameter change type {0}.", change);
}
};
return listener;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import org.openide.util.lookup.ServiceProvider;

/**
Expand Down Expand Up @@ -246,6 +247,14 @@ public static boolean isEditable(final PluginParameter<?> parameter) {
public static void setEditable(final PluginParameter<?> parameter, boolean editable) {
parameter.setProperty(EDITABLE, editable);
}

public static void setIcons(final PluginParameter<SingleChoiceParameterValue> parameter, final List<Image> icons) {
parameter.getParameterValue().setIcons(icons.stream().map(icon -> new ImageView(icon)).toList());
}

public static List<ImageView> getIcons(final PluginParameter<SingleChoiceParameterValue> parameter) {
return parameter.getParameterValue().getIcons();
}

/**
* Constructs a new instance of this type.
Expand All @@ -272,6 +281,7 @@ public static class SingleChoiceParameterValue extends ParameterValue {
// If it's a nested class, make sure it's a static nested class rather than an inner class,
// to avoid possible NoSuchMethodExceptions
private final List<ParameterValue> options;
private final List<ImageView> icons;
private ParameterValue choice;
private final Class<? extends ParameterValue> innerClass;

Expand All @@ -281,6 +291,7 @@ public static class SingleChoiceParameterValue extends ParameterValue {
*/
public SingleChoiceParameterValue() {
options = new ArrayList<>();
icons = new ArrayList<>();
choice = null;
innerClass = StringParameterValue.class;
}
Expand All @@ -294,6 +305,7 @@ public SingleChoiceParameterValue() {
*/
public SingleChoiceParameterValue(final Class<? extends ParameterValue> innerClass) {
options = new ArrayList<>();
icons = new ArrayList<>();
choice = null;
this.innerClass = innerClass;
}
Expand All @@ -310,6 +322,8 @@ public SingleChoiceParameterValue(final Class<? extends ParameterValue> innerCla
public SingleChoiceParameterValue(final SingleChoiceParameterValue sc) {
options = new ArrayList<>();
options.addAll(sc.options);
icons = new ArrayList<>();
icons.addAll(sc.icons);
choice = sc.choice != null ? sc.choice.copy() : null;
innerClass = sc.innerClass;
}
Expand Down Expand Up @@ -349,6 +363,26 @@ public void setOptions(final Iterable<String> options) {
}
choice = null;
}

/**
* Set the collection of icons from a list of InageIcons.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo InageIcons.

Also what is the use of icons here? If you meant to use it for icons in the dropdowns similar to Robot options in Test Parameters plugin, it doesn't seem to be working.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be working now

*
* @param icons A list of ImageIcons to set the collection of icons
* from.
*/
public void setIcons(final List<ImageView> icons) {
this.icons.clear();
this.icons.addAll(icons);
}

/**
* Get the collection of options from a list of Strings.
*
* @return A list of ImageIcons representing the icons.
*/
public List<ImageView> getIcons() {
return Collections.unmodifiableList(this.icons);
}

/**
* Get the collection of options as a list of {@link ParameterValue}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
import au.gov.asd.tac.constellation.utilities.gui.field.framework.RightButtonSupport;
import java.util.Map;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.input.MouseEvent;

/**
* A {@link ChoiceInput} for managing multiple choice selection. This input
Expand All @@ -59,12 +61,12 @@ public final class MultiChoiceInput<C extends Object> extends ChoiceInputField<L
private ChoiceInputDropDown choiceInputDropDown;

public MultiChoiceInput() {
initialiseDepedantComponents();
initialiseDependantComponents();
}

public MultiChoiceInput(final ObservableList<C> options) {
super(options);
initialiseDepedantComponents();
initialiseDependantComponents();
}

// <editor-fold defaultstate="collapsed" desc="Local Private Methods">
Expand Down Expand Up @@ -231,20 +233,20 @@ public List<MenuItem> getLocalMenuItems() {
@Override
public RightButton getRightButton() {
return new RightButton(
new Label(""), ButtonType.DROPDOWN) {
new Label("Select"), ButtonType.DROPDOWN) {

@Override
public void show() {
// show our menu instead
executeRightButtonAction();
executeRightButtonAction();
}

@Override
public void hide() {
// this is triggered when clicking away from button
setMenuShown(false);
}
};
};
}

@Override
Expand Down
Loading