diff --git a/src/main/java/org/scijava/ItemVisibility.java b/src/main/java/org/scijava/ItemVisibility.java index 749e91ae3..6f8691aa3 100644 --- a/src/main/java/org/scijava/ItemVisibility.java +++ b/src/main/java/org/scijava/ItemVisibility.java @@ -61,6 +61,14 @@ public enum ItemVisibility { * intended as a message to the user (e.g., in the input harvester panel) * rather than an actual parameter to the module execution. */ - MESSAGE - + MESSAGE, + + /** + * Indicates that the item's value defines the name of a widget group + * (e.g., in the input harvester panel) rather than an actual parameter + * to the module execution. Widget groups organize related input widgets. + * Group members are added to a group by providing a group parameter annotation + * having the common group name. + */ + GROUP } diff --git a/src/main/java/org/scijava/command/CommandModuleItem.java b/src/main/java/org/scijava/command/CommandModuleItem.java index 7be4d3e9f..4210921f7 100644 --- a/src/main/java/org/scijava/command/CommandModuleItem.java +++ b/src/main/java/org/scijava/command/CommandModuleItem.java @@ -134,6 +134,16 @@ public String getCallback() { public String getWidgetStyle() { return getParameter().style(); } + + @Override + public String getWidgetGroup() { + return getParameter().group(); + } + + @Override + public boolean isExpanded() { + return getParameter().expanded(); + } @Override public T getMinimumValue() { diff --git a/src/main/java/org/scijava/module/AbstractModuleItem.java b/src/main/java/org/scijava/module/AbstractModuleItem.java index da260b12a..de98530a9 100644 --- a/src/main/java/org/scijava/module/AbstractModuleItem.java +++ b/src/main/java/org/scijava/module/AbstractModuleItem.java @@ -74,6 +74,8 @@ public String toString() { sm.append("persistKey", getPersistKey()); sm.append("callback", getCallback()); sm.append("widgetStyle", getWidgetStyle()); + sm.append("widgetGroup", getWidgetGroup()); + sm.append("expanded", isExpanded()); sm.append("default", getDefaultValue()); sm.append("min", getMinimumValue()); sm.append("max", getMaximumValue()); @@ -231,6 +233,16 @@ public void callback(final Module module) throws MethodCallException { public String getWidgetStyle() { return null; } + + @Override + public String getWidgetGroup() { + return null; + } + + @Override + public boolean isExpanded() { + return true; + } @Override public T getDefaultValue() { diff --git a/src/main/java/org/scijava/module/DefaultMutableModuleItem.java b/src/main/java/org/scijava/module/DefaultMutableModuleItem.java index 4c8354d14..5619b5b81 100644 --- a/src/main/java/org/scijava/module/DefaultMutableModuleItem.java +++ b/src/main/java/org/scijava/module/DefaultMutableModuleItem.java @@ -59,6 +59,8 @@ public class DefaultMutableModuleItem extends AbstractModuleItem private String validater; private String callback; private String widgetStyle; + private String widgetGroup; + private boolean expanded; private T defaultValue; private T minimumValue; private T maximumValue; @@ -94,6 +96,8 @@ public DefaultMutableModuleItem(final ModuleInfo info, final String name, validater = super.getValidater(); callback = super.getCallback(); widgetStyle = super.getWidgetStyle(); + widgetGroup = super.getWidgetGroup(); + expanded = super.isExpanded(); minimumValue = super.getMinimumValue(); maximumValue = super.getMaximumValue(); stepSize = super.getStepSize(); @@ -122,6 +126,8 @@ public DefaultMutableModuleItem(final ModuleInfo info, validater = item.getValidater(); callback = item.getCallback(); widgetStyle = item.getWidgetStyle(); + widgetGroup = item.getWidgetGroup(); + expanded = item.isExpanded(); minimumValue = item.getMinimumValue(); maximumValue = item.getMaximumValue(); softMinimum = item.getSoftMinimum(); @@ -185,6 +191,16 @@ public void setCallback(final String callback) { public void setWidgetStyle(final String widgetStyle) { this.widgetStyle = widgetStyle; } + + @Override + public void setWidgetGroup(final String widgetGroup) { + this.widgetGroup = widgetGroup; + } + + @Override + public void setExpanded(final boolean expanded) { + this.expanded = expanded; + } @Override public void setDefaultValue(final T defaultValue) { @@ -288,6 +304,16 @@ public String getCallback() { public String getWidgetStyle() { return widgetStyle; } + + @Override + public String getWidgetGroup() { + return widgetGroup; + } + + @Override + public boolean isExpanded() { + return expanded; + } @Override public T getDefaultValue() { diff --git a/src/main/java/org/scijava/module/ModuleItem.java b/src/main/java/org/scijava/module/ModuleItem.java index 4abd391ea..c9ca93191 100644 --- a/src/main/java/org/scijava/module/ModuleItem.java +++ b/src/main/java/org/scijava/module/ModuleItem.java @@ -153,6 +153,15 @@ public interface ModuleItem extends BasicDetails { * interface. */ String getWidgetStyle(); + + /** + * Gets the name of the group the widget belongs to so it can be displayed within + * the group. + */ + String getWidgetGroup(); + + /** Returns the state of the widget group, expanded and visible or not expanded and hidden. */ + boolean isExpanded(); /** Gets the default value. */ T getDefaultValue(); diff --git a/src/main/java/org/scijava/module/MutableModuleItem.java b/src/main/java/org/scijava/module/MutableModuleItem.java index 58c146a81..36381fb4c 100644 --- a/src/main/java/org/scijava/module/MutableModuleItem.java +++ b/src/main/java/org/scijava/module/MutableModuleItem.java @@ -61,6 +61,10 @@ public interface MutableModuleItem extends ModuleItem { void setCallback(String callback); void setWidgetStyle(String widgetStyle); + + void setWidgetGroup(String widgetGroup); + + void setExpanded(boolean expanded); void setDefaultValue(T defaultValue); diff --git a/src/main/java/org/scijava/plugin/Parameter.java b/src/main/java/org/scijava/plugin/Parameter.java index ac24dd5e6..6c110f5fe 100644 --- a/src/main/java/org/scijava/plugin/Parameter.java +++ b/src/main/java/org/scijava/plugin/Parameter.java @@ -92,6 +92,9 @@ * output, such as a "verbose" flag. *
  • MESSAGE: parameter value is intended as a message only, not editable by * the user nor included as an input or output parameter.
  • + *
  • GROUP: parameter value specifies a widget group, not editable by + * the user nor included as an input or output parameter. Members are added + * to the group using the group parameter annotation.
  • * */ ItemVisibility visibility() default ItemVisibility.NORMAL; @@ -142,6 +145,15 @@ *

    */ String style() default ""; + + /** Defines the widget group. */ + String group() default ""; + + /** + * Defines the state of the widget group. When true the group is expanded and visible. + * Otherwise, group members are hidden. + * */ + boolean expanded() default true; /** Defines the minimum allowed value (numeric parameters only). */ String min() default ""; diff --git a/src/main/java/org/scijava/script/process/ParameterScriptProcessor.java b/src/main/java/org/scijava/script/process/ParameterScriptProcessor.java index 0ed4d7212..b9028e6c0 100644 --- a/src/main/java/org/scijava/script/process/ParameterScriptProcessor.java +++ b/src/main/java/org/scijava/script/process/ParameterScriptProcessor.java @@ -277,6 +277,8 @@ private void assignAttribute(final DefaultMutableModuleItem item, else if (is(k, "softMin")) item.setSoftMinimum(as(v, item.getType())); else if (is(k, "stepSize")) item.setStepSize(as(v, double.class)); else if (is(k, "style")) item.setWidgetStyle(as(v, String.class)); + else if (is(k, "group")) item.setWidgetGroup(as(v, String.class)); + else if (is(k, "expanded")) item.setExpanded(as(v, boolean.class)); else if (is(k, "visibility")) item.setVisibility(as(v, ItemVisibility.class)); else if (is(k, "value")) item.setDefaultValue(as(v, item.getType())); else item.set(k, v.toString()); diff --git a/src/main/java/org/scijava/widget/DefaultWidgetModel.java b/src/main/java/org/scijava/widget/DefaultWidgetModel.java index 1a768d5d7..452e189fc 100644 --- a/src/main/java/org/scijava/widget/DefaultWidgetModel.java +++ b/src/main/java/org/scijava/widget/DefaultWidgetModel.java @@ -131,6 +131,11 @@ public String getWidgetLabel() { public boolean isStyle(final String style) { return WidgetStyle.isStyle(getItem(), style); } + + @Override + public String getGroup() { + return getItem().getWidgetGroup(); + } @Override public Object getValue() { diff --git a/src/main/java/org/scijava/widget/WidgetModel.java b/src/main/java/org/scijava/widget/WidgetModel.java index 80f033de0..fc85d633b 100644 --- a/src/main/java/org/scijava/widget/WidgetModel.java +++ b/src/main/java/org/scijava/widget/WidgetModel.java @@ -80,6 +80,13 @@ public interface WidgetModel extends Contextual { * {@code style.equals(getItem().getWidgetStyle())}. */ boolean isStyle(String style); + + /** + * Gets group that the widget belongs to. + * + * @return Group that the widget belongs to. + */ + String getGroup(); /** * Gets the current value of the module input. diff --git a/src/test/java/org/scijava/script/ScriptInfoTest.java b/src/test/java/org/scijava/script/ScriptInfoTest.java index 678996628..f1a4b0f61 100644 --- a/src/test/java/org/scijava/script/ScriptInfoTest.java +++ b/src/test/java/org/scijava/script/ScriptInfoTest.java @@ -266,18 +266,18 @@ public void testParameters() { final ModuleItem log = info.getInput("log"); assertItem("log", LogService.class, null, ItemIO.INPUT, false, true, null, - null, null, null, null, null, null, null, noChoices, log); + null, null, null, null, null, null, null, null, noChoices, log); final ModuleItem sliderValue = info.getInput("sliderValue"); assertItem("sliderValue", int.class, "Slider Value", ItemIO.INPUT, true, - true, null, " slidEr,", 11, null, null, 5, 15, 3.0, noChoices, sliderValue); + true, null, " slidEr,", null, 11, null, null, 5, 15, 3.0, noChoices, sliderValue); assertTrue("Case-insensitive trimmed style", WidgetStyle.isStyle(sliderValue, "slider")); final ModuleItem animal = info.getInput("animal"); final List animalChoices = // Arrays.asList("quick brown fox", "lazy dog"); assertItem("animal", String.class, null, ItemIO.INPUT, true, false, - null, null, null, null, null, null, null, null, animalChoices, animal); + null, null, null, null, null, null, null, null, null, animalChoices, animal); assertEquals(animal.get("family"), "Carnivora"); // test custom attribute final ModuleItem notAutoFilled = info.getInput("notAutoFilled"); @@ -288,7 +288,7 @@ public void testParameters() { final ModuleItem buffer = info.getOutput("buffer"); assertItem("buffer", StringBuilder.class, null, ItemIO.BOTH, true, true, - null, null, null, null, null, null, null, null, noChoices, buffer); + null, null, null, null, null, null, null, null, null, noChoices, buffer); int inputCount = 0; final ModuleItem[] inputs = { log, sliderValue, animal, notAutoFilled, msg, buffer }; @@ -367,7 +367,7 @@ private String id(final String path, final String script) { private void assertItem(final String name, final Class type, final String label, final ItemIO ioType, final boolean required, final boolean persist, final String persistKey, final String style, - final Object value, final Object min, final Object max, + final String group, final Object value, final Object min, final Object max, final Object softMin, final Object softMax, final Number stepSize, final List choices, final ModuleItem item) { @@ -379,6 +379,7 @@ private void assertItem(final String name, final Class type, assertEquals(persist, item.isPersisted()); assertEquals(persistKey, item.getPersistKey()); assertEquals(style, item.getWidgetStyle()); + assertEquals(group, item.getWidgetGroup()); assertEquals(value, item.getDefaultValue()); assertEquals(min, item.getMinimumValue()); assertEquals(max, item.getMaximumValue());