From 8f46d397acdf07e59c91a705d97ad1813db12f30 Mon Sep 17 00:00:00 2001 From: HUYNH Nghi Date: Tue, 23 Feb 2021 21:01:28 +0700 Subject: [PATCH] addresses #3061 --- .../src/msi/gama/common/interfaces/IGui.java | 3 +- .../msi/gama/runtime/HeadlessListener.java | 3 +- .../src/msi/gaml/operators/System.java | 95 ++++++++++++++++++- .../gama/ui/parameters/EditorsDialog.java | 8 +- .../src/ummisco/gama/ui/utils/SwtGui.java | 5 +- 5 files changed, 108 insertions(+), 6 deletions(-) diff --git a/msi.gama.core/src/msi/gama/common/interfaces/IGui.java b/msi.gama.core/src/msi/gama/common/interfaces/IGui.java index 71f0f3e72a..e1150eebf6 100644 --- a/msi.gama.core/src/msi/gama/common/interfaces/IGui.java +++ b/msi.gama.core/src/msi/gama/common/interfaces/IGui.java @@ -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; @@ -96,7 +97,7 @@ public interface IGui { IDisplaySurface getDisplaySurfaceFor(final LayeredDisplayOutput output, final Object... args); - Map openUserInputDialog(IScope scope, String title, List parameters); + Map openUserInputDialog(IScope scope, String title, List parameters, GamaFont font); void openUserControlPanel(IScope scope, UserPanelStatement panel); diff --git a/msi.gama.core/src/msi/gama/runtime/HeadlessListener.java b/msi.gama.core/src/msi/gama/runtime/HeadlessListener.java index 4a1c76cb13..30a7ae5b83 100644 --- a/msi.gama.core/src/msi/gama/runtime/HeadlessListener.java +++ b/msi.gama.core/src/msi/gama/runtime/HeadlessListener.java @@ -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; @@ -72,7 +73,7 @@ private static void log(final String s) { @Override public Map openUserInputDialog(final IScope scope, final String title, - final List parameters) { + final List parameters, final GamaFont font) { final Map initialValues = GamaMapFactory.create(); parameters.forEach(p -> { initialValues.put(p.getName(), p.getInitialValue(scope)); diff --git a/msi.gama.core/src/msi/gaml/operators/System.java b/msi.gama.core/src/msi/gaml/operators/System.java index 41b0e15240..b1e31b7f89 100644 --- a/msi.gama.core/src/msi/gaml/operators/System.java +++ b/msi.gama.core/src/msi/gaml/operators/System.java @@ -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; @@ -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; @@ -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 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 userInput(final IScope scope, final IMap 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 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 userInput(final IScope scope, final String title, + final IMap map, final GamaFont font) { + final IList 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 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 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 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 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 }, @@ -289,7 +382,7 @@ public static IMap userInput(final IScope scope, final String ti public static IMap 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 ( diff --git a/ummisco.gama.ui.shared/src/ummisco/gama/ui/parameters/EditorsDialog.java b/ummisco.gama.ui.shared/src/ummisco/gama/ui/parameters/EditorsDialog.java index 0bca77e42b..c89bdb6df3 100644 --- a/ummisco.gama.ui.shared/src/ummisco/gama/ui/parameters/EditorsDialog.java +++ b/ummisco.gama.ui.shared/src/ummisco/gama/ui/parameters/EditorsDialog.java @@ -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; @@ -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. @@ -45,13 +48,15 @@ public class EditorsDialog extends Dialog { private final IMap values = GamaMapFactory.createUnordered(); private final List parameters; private final String title; + private final GamaFont font; private final IScope scope; public EditorsDialog(final IScope scope, final Shell parentShell, final List 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 -> { @@ -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); diff --git a/ummisco.gama.ui.shared/src/ummisco/gama/ui/utils/SwtGui.java b/ummisco.gama.ui.shared/src/ummisco/gama/ui/utils/SwtGui.java index 9cdff6d915..a4612a6182 100644 --- a/ummisco.gama.ui.shared/src/ummisco/gama/ui/utils/SwtGui.java +++ b/ummisco.gama.ui.shared/src/ummisco/gama/ui/utils/SwtGui.java @@ -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; @@ -264,13 +265,13 @@ public IDisplaySurface getDisplaySurfaceFor(final LayeredDisplayOutput output, f @Override public Map openUserInputDialog(final IScope scope, final String title, - final List parameters) { + final List parameters, final GamaFont font) { final IMap 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()); }