Skip to content

Commit

Permalink
addresses #3061
Browse files Browse the repository at this point in the history
  • Loading branch information
hqnghi88 committed Feb 23, 2021
1 parent 7005274 commit 8f46d39
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 6 deletions.
3 changes: 2 additions & 1 deletion msi.gama.core/src/msi/gama/common/interfaces/IGui.java
Expand Up @@ -25,6 +25,7 @@
import msi.gama.outputs.LayeredDisplayOutput;
import msi.gama.runtime.IScope;
import msi.gama.runtime.exceptions.GamaRuntimeException;
import msi.gama.util.GamaFont;
import msi.gama.util.GamaMapFactory;
import msi.gama.util.file.IFileMetaDataProvider;
import msi.gaml.architecture.user.UserPanelStatement;
Expand Down Expand Up @@ -96,7 +97,7 @@ public interface IGui {

IDisplaySurface getDisplaySurfaceFor(final LayeredDisplayOutput output, final Object... args);

Map<String, Object> openUserInputDialog(IScope scope, String title, List<IParameter> parameters);
Map<String, Object> openUserInputDialog(IScope scope, String title, List<IParameter> parameters, GamaFont font);

void openUserControlPanel(IScope scope, UserPanelStatement panel);

Expand Down
3 changes: 2 additions & 1 deletion msi.gama.core/src/msi/gama/runtime/HeadlessListener.java
Expand Up @@ -37,6 +37,7 @@
import msi.gama.outputs.display.NullDisplaySurface;
import msi.gama.runtime.exceptions.GamaRuntimeException;
import msi.gama.util.GamaColor;
import msi.gama.util.GamaFont;
import msi.gama.util.GamaMapFactory;
import msi.gama.util.file.IFileMetaDataProvider;
import msi.gama.util.file.IGamaFileMetaData;
Expand Down Expand Up @@ -72,7 +73,7 @@ private static void log(final String s) {

@Override
public Map<String, Object> openUserInputDialog(final IScope scope, final String title,
final List<IParameter> parameters) {
final List<IParameter> parameters, final GamaFont font) {
final Map<String, Object> initialValues = GamaMapFactory.create();
parameters.forEach(p -> {
initialValues.put(p.getName(), p.getInitialValue(scope));
Expand Down
95 changes: 94 additions & 1 deletion msi.gama.core/src/msi/gaml/operators/System.java
Expand Up @@ -21,6 +21,7 @@

import msi.gama.common.interfaces.IKeyword;
import msi.gama.common.interfaces.IValue;
import msi.gama.common.preferences.GamaPreferences;
import msi.gama.kernel.experiment.IParameter;
import msi.gama.kernel.experiment.InputParameter;
import msi.gama.metamodel.agent.IAgent;
Expand All @@ -35,6 +36,7 @@
import msi.gama.precompiler.ITypeProvider;
import msi.gama.runtime.IScope;
import msi.gama.runtime.exceptions.GamaRuntimeException;
import msi.gama.util.GamaFont;
import msi.gama.util.GamaListFactory;
import msi.gama.util.GamaMapFactory;
import msi.gama.util.IList;
Expand Down Expand Up @@ -218,6 +220,97 @@ public static Object opCopy(final IScope scope, final Object o) throws GamaRunti
return o;
}

@operator (
value = IKeyword.USER_INPUT,
category = { IOperatorCategory.SYSTEM, IOperatorCategory.USER_CONTROL },
concept = { IConcept.SYSTEM, IConcept.GUI })
@doc (
deprecated = "Use a list of `enter()` or `choose()` operators rather than a map",
value = "Asks the user for some values. Takes a string (optional) and a map as arguments. The string is used to specify the message of the dialog box. The map is to specify the parameters you want the user to change before the simulation starts, with the name of the parameter in string key, and the default value as value.",
masterDoc = true,
comment = "This operator takes a map [string::value] as argument, displays a dialog asking the user for these values, and returns the same map with the modified values (if any). "
+ "The dialog is modal and will interrupt the execution of the simulation until the user has either dismissed or accepted it. It can be used, for instance, in an init section to force the user to input new values instead of relying on the initial values of parameters :",
examples = {
@example ("map<string,unknown> values <- user_input([enter(\"Number\",100), enter(\"Location\",{10, 10})], font('Helvetica', 18));"),
@example (
value = "(values at \"Number\") as int",
equals = "100",
returnType = "int",
isTestOnly = true),
@example (
value = " (values at \"Location\") as point",
equals = "{10,10}",
returnType = "point",
isTestOnly = true),
@example (
value = "create bug number: int(values at \"Number\") with: [location:: (point(values at \"Location\"))];",
isExecutable = false) })
@no_test
public static IMap<String, Object> userInput(final IScope scope, final IMap<String, Object> map,final GamaFont font) {
final IAgent agent = scope.getAgent();
return userInput(scope, agent.getSpeciesName() + " #" + agent.getIndex() + " request", map,font);
}

@operator (
value = IKeyword.USER_INPUT,
category = { IOperatorCategory.SYSTEM, IOperatorCategory.USER_CONTROL },
concept = {})
@doc (
deprecated = "Use a list of `enter()` or `choose()` operators rather than a map",
value = "Asks the user for some values. Takes a string (optional) and a map as arguments. The string is used to specify the message of the dialog box. The map is to specify the parameters you want the user to change before the simulation starts, with the name of the parameter in string key, and the default value as value.",
examples =

{ @example ("map<string,unknown> values2 <- user_input(\"Enter numer of agents and locations\",[enter(\"Number\",100), enter(\"Location\",{10, 10})], font('Helvetica', 18));"),
@example (
value = "create bug number: int(values2 at \"Number\") with: [location:: (point(values2 at \"Location\"))];",
isExecutable = false) })
@no_test
public static IMap<String, Object> userInput(final IScope scope, final String title,
final IMap<String, Object> map, final GamaFont font) {
final IList<IParameter> parameters = GamaListFactory.create();
map.forEach((k, v) -> {
parameters.add(enterValue(scope, k, v));
});
return userInput(scope, title, parameters,font);
}

@SuppressWarnings ("unchecked")
@operator (
value = IKeyword.USER_INPUT,
category = { IOperatorCategory.SYSTEM, IOperatorCategory.USER_CONTROL },
concept = {})
@doc (
value = "Asks the user for some values and returns a map containing these values. Takes a string and a list of calls to the `enter()` or `choose()` operators as arguments. The string is used to specify the message of the dialog box. The list is to specify the parameters the user can enter",
masterDoc = true,
examples = {
@example ("map<string,unknown> values2 <- user_input('Enter number of agents and locations',[enter('Number',100), enter('Location',point, {10, 10})], font('Helvetica', 18));"),
@example (
value = "create bug number: int(values2 at \"Number\") with: [location:: (point(values2 at \"Location\"))];",
isExecutable = false) })
@no_test
public static IMap<String, Object> userInput(final IScope scope, final String title, final IList parameters,final GamaFont font) {
parameters.removeIf(p -> !(p instanceof IParameter));
return GamaMapFactory.createWithoutCasting(Types.STRING, Types.NO_TYPE,
scope.getGui().openUserInputDialog(scope, title, parameters,font));
}

@operator (
value = IKeyword.USER_INPUT,
category = { IOperatorCategory.SYSTEM, IOperatorCategory.USER_CONTROL },
concept = {})
@doc (
value = "Asks the user for some values and returns a map containing these values. Takes a string and a list of calls to the `enter()` or `choose()` operators as arguments. The string is used to specify the message of the dialog box. The list is to specify the parameters the user can enter",
examples = {
@example ("map<string,unknown> values_no_title <- user_input([enter('Number',100), enter('Location',point, {10, 10})], font('Helvetica', 18));"),
@example (
value = "create bug number: int(values2 at \"Number\") with: [location:: (point(values2 at \"Location\"))];",
isExecutable = false) })
@no_test
public static IMap<String, Object> userInput(final IScope scope, final IList parameters,final GamaFont font) {
final IAgent agent = scope.getAgent();
return userInput(scope, agent.getSpeciesName() + " #" + agent.getIndex() + " request", parameters,font);
}

@operator (
value = IKeyword.USER_INPUT,
category = { IOperatorCategory.SYSTEM, IOperatorCategory.USER_CONTROL },
Expand Down Expand Up @@ -289,7 +382,7 @@ public static IMap<String, Object> userInput(final IScope scope, final String ti
public static IMap<String, Object> userInput(final IScope scope, final String title, final IList parameters) {
parameters.removeIf(p -> !(p instanceof IParameter));
return GamaMapFactory.createWithoutCasting(Types.STRING, Types.NO_TYPE,
scope.getGui().openUserInputDialog(scope, title, parameters));
scope.getGui().openUserInputDialog(scope, title, parameters, GamaPreferences.Modeling.EDITOR_BASE_FONT.getValue()));
}

@operator (
Expand Down
Expand Up @@ -17,6 +17,7 @@
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
Expand All @@ -27,11 +28,13 @@

import msi.gama.kernel.experiment.IParameter;
import msi.gama.runtime.IScope;
import msi.gama.util.GamaFont;
import msi.gama.util.GamaMapFactory;
import msi.gama.util.IMap;
import ummisco.gama.ui.interfaces.EditorListener;
import ummisco.gama.ui.resources.GamaColors;
import ummisco.gama.ui.resources.IGamaColors;
import ummisco.gama.ui.utils.WorkbenchHelper;

/**
* The class EditorsDialog.
Expand All @@ -45,13 +48,15 @@ public class EditorsDialog extends Dialog {
private final IMap<String, Object> values = GamaMapFactory.createUnordered();
private final List<IParameter> parameters;
private final String title;
private final GamaFont font;
private final IScope scope;

public EditorsDialog(final IScope scope, final Shell parentShell, final List<IParameter> parameters,
final String title) {
final String title, final GamaFont font) {
super(parentShell);
this.scope = scope;
this.title = title;
this.font = font;
setShellStyle(SWT.RESIZE | SWT.BORDER);
this.parameters = parameters;
parameters.forEach(p -> {
Expand Down Expand Up @@ -92,6 +97,7 @@ protected Control createDialogArea(final Composite parent) {
final var text = new Label(composite, SWT.None);
text.setBackground(IGamaColors.OK.inactive());
text.setForeground(GamaColors.getTextColorForBackground(text.getBackground()).color());
text.setFont(new Font(WorkbenchHelper.getDisplay(), font.getFontName(), font.getSize(), font.getStyle()));
text.setText(title);
var data = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
text.setLayoutData(data);
Expand Down
5 changes: 3 additions & 2 deletions ummisco.gama.ui.shared/src/ummisco/gama/ui/utils/SwtGui.java
Expand Up @@ -60,6 +60,7 @@
import msi.gama.runtime.IScope;
import msi.gama.runtime.ISimulationStateProvider;
import msi.gama.runtime.exceptions.GamaRuntimeException;
import msi.gama.util.GamaFont;
import msi.gama.util.GamaMapFactory;
import msi.gama.util.IMap;
import msi.gama.util.file.IFileMetaDataProvider;
Expand Down Expand Up @@ -264,13 +265,13 @@ public IDisplaySurface getDisplaySurfaceFor(final LayeredDisplayOutput output, f

@Override
public Map<String, Object> openUserInputDialog(final IScope scope, final String title,
final List<IParameter> parameters) {
final List<IParameter> parameters, final GamaFont font) {
final IMap<String, Object> result = GamaMapFactory.createUnordered();
for (final IParameter p : parameters) {
result.put(p.getName(), p.getInitialValue(scope));
}
WorkbenchHelper.run(() -> {
final EditorsDialog dialog = new EditorsDialog(scope, WorkbenchHelper.getShell(), parameters, title);
final EditorsDialog dialog = new EditorsDialog(scope, WorkbenchHelper.getShell(), parameters, title, font);
if (dialog.open() == Window.OK) {
result.putAll(dialog.getValues());
}
Expand Down

0 comments on commit 8f46d39

Please sign in to comment.