Unverified Commit 59de9e87 authored by Evan W. Patton's avatar Evan W. Patton Committed by GitHub

Fix multiselect issue when changing tabs/windows (#2108)

* Fix multiselect issue when changing tabs/windows

Change-Id: Ic015672436e5a1b25d022eacc14998081b4b195b
parent 175bbbb5
......@@ -13,6 +13,7 @@ import com.google.appinventor.client.output.OdeLog;
import com.google.appinventor.client.widgets.boxes.Box;
import com.google.appinventor.shared.settings.SettingsConstants;
import com.google.common.collect.Maps;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.resources.client.ImageResource;
......@@ -46,7 +47,7 @@ public final class BlockSelectorBox extends Box {
}
@Override
public void onSelected() {
public void onSelected(NativeEvent source) {
}
@Override
......@@ -167,7 +168,7 @@ public final class BlockSelectorBox extends Box {
+ getBuiltinDrawerNames(drawerName) + "</span>"));
SourceStructureExplorerItem sourceItem = new BlockSelectorItem() {
@Override
public void onSelected() {
public void onSelected(NativeEvent source) {
fireBuiltinDrawerSelected(drawerName);
}
};
......@@ -230,7 +231,7 @@ public final class BlockSelectorBox extends Box {
+ ComponentsTranslation.getComponentName(typeName) + "</span>"));
SourceStructureExplorerItem sourceItem = new BlockSelectorItem() {
@Override
public void onSelected() {
public void onSelected(NativeEvent source) {
fireGenericDrawerSelected(typeName);
}
};
......
......@@ -126,7 +126,7 @@ public final class SimpleNonVisibleComponentsPanel extends Composite implements
// Add component to this panel
addComponent(sourceComponent);
sourceComponent.select();
sourceComponent.select(null);
}
@Override
......
......@@ -198,7 +198,7 @@ public class MockCircle extends MockMapFeatureBaseWithFill {
if (!circle.clickHandler) {
while (el.lastChild) el.removeChild(el.lastChild); // clear the div
circle.clickHandler = function(e) {
this.@com.google.appinventor.client.editor.simple.components.MockCircle::select()();
this.@com.google.appinventor.client.editor.simple.components.MockCircle::select(*)(e);
if (e.originalEvent) e.originalEvent.stopPropagation();
};
circle.dragHandler = function(e) {
......
......@@ -12,7 +12,6 @@ import com.google.appinventor.client.editor.simple.SimpleComponentDatabase;
import com.google.appinventor.client.ComponentsTranslation;
import com.google.appinventor.client.Images;
import com.google.appinventor.client.Ode;
import com.google.appinventor.client.editor.ProjectEditor;
import com.google.appinventor.client.editor.simple.SimpleEditor;
import com.google.appinventor.client.editor.simple.components.utils.PropertiesUtil;
import com.google.appinventor.client.editor.youngandroid.YaBlocksEditor;
......@@ -35,8 +34,8 @@ import com.google.appinventor.shared.rpc.project.HasAssetsFolder;
import com.google.appinventor.shared.rpc.project.ProjectNode;
import com.google.appinventor.shared.rpc.project.youngandroid.YoungAndroidAssetsFolder;
import com.google.appinventor.shared.rpc.project.youngandroid.YoungAndroidProjectNode;
import com.google.appinventor.shared.settings.SettingsConstants;
import com.google.appinventor.shared.storage.StorageUtil;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DomEvent;
......@@ -79,7 +78,6 @@ import com.google.appinventor.shared.simple.ComponentDatabaseInterface.Component
import com.google.appinventor.shared.simple.ComponentDatabaseInterface.PropertyDefinition;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
......@@ -328,7 +326,7 @@ public abstract class MockComponent extends Composite implements PropertyChangeL
sourceStructureExplorerItem = new SourceStructureExplorerItem() {
@Override
public void onSelected() {
public void onSelected(NativeEvent source) {
// are we showing the blocks editor? if so, toggle the component drawer
if (Ode.getInstance().getCurrentFileEditor() instanceof YaBlocksEditor) {
YaBlocksEditor blocksEditor =
......@@ -336,7 +334,7 @@ public abstract class MockComponent extends Composite implements PropertyChangeL
OdeLog.log("Showing item " + getName());
blocksEditor.showComponentBlocks(getName());
} else {
select();
select(source);
}
}
......@@ -523,7 +521,33 @@ public abstract class MockComponent extends Composite implements PropertyChangeL
if (isPropertyforYail(name)) {
type |= EditableProperty.TYPE_DOYAIL;
}
properties.addProperty(name, defaultValue, caption, editor, type);
properties.addProperty(name, defaultValue, caption, editor, type, "", null);
}
/**
* Adds a new property for the component.
*
* @param name property name
* @param defaultValue default value of property
* @param caption property's caption for use in the ui
* @param editorType editor type for the property
* @param editorArgs additional editor arguments
* @param editor property editor
*/
public final void addProperty(String name, String defaultValue, String caption,
String editorType, String[] editorArgs, PropertyEditor editor) {
int type = EditableProperty.TYPE_NORMAL;
if (!isPropertyPersisted(name)) {
type |= EditableProperty.TYPE_NONPERSISTED;
}
if (!isPropertyVisible(name)) {
type |= EditableProperty.TYPE_INVISIBLE;
}
if (isPropertyforYail(name)) {
type |= EditableProperty.TYPE_DOYAIL;
}
properties.addProperty(name, defaultValue, caption, editor, type, editorType, editorArgs);
}
/**
......@@ -655,8 +679,8 @@ public abstract class MockComponent extends Composite implements PropertyChangeL
/**
* Selects this component in the visual editor.
*/
public final void select() {
getForm().setSelectedComponent(this);
public final void select(NativeEvent event) {
getForm().setSelectedComponent(this, event);
}
/**
......@@ -680,7 +704,7 @@ public abstract class MockComponent extends Composite implements PropertyChangeL
* Returns whether this component is selected.
*/
public boolean isSelected() {
return (getForm().getSelectedComponent() == this);
return (getForm().getSelectedComponents() == this);
}
/**
......@@ -868,7 +892,7 @@ public abstract class MockComponent extends Composite implements PropertyChangeL
case Event.ONTOUCHSTART:
case Event.ONTOUCHEND:
if (isForm()) {
select();
select(event);
}
case Event.ONTOUCHMOVE:
case Event.ONTOUCHCANCEL:
......@@ -887,7 +911,7 @@ public abstract class MockComponent extends Composite implements PropertyChangeL
case Event.ONCLICK:
cancelBrowserEvent(event);
select();
select(event);
break;
default:
......@@ -1095,7 +1119,7 @@ public abstract class MockComponent extends Composite implements PropertyChangeL
public void delete() {
this.editor.getProjectEditor().clearLocation(getName());
getForm().select();
getForm().select(null);
// Pass true to indicate that the component is being permanently deleted.
getContainer().removeComponent(this, true);
// tell the component its been removed, so it can remove children's blocks
......@@ -1183,7 +1207,7 @@ public abstract class MockComponent extends Composite implements PropertyChangeL
for (PropertyDefinition property : newProperties) {
if (toBeAdded.contains(property.getName())) {
PropertyEditor propertyEditor = PropertiesUtil.createPropertyEditor(property.getEditorType(), property.getDefaultValue(), (YaFormEditor) editor, property.getEditorArgs());
addProperty(property.getName(), property.getDefaultValue(), property.getCaption(), propertyEditor);
addProperty(property.getName(), property.getDefaultValue(), property.getCaption(), property.getEditorType(), property.getEditorArgs(), propertyEditor);
}
}
......
......@@ -300,7 +300,7 @@ public abstract class MockContainer extends MockVisibleComponent implements Drop
}
if (layout.onDrop(sourceComponent, x, y, offsetX, offsetY)) {
sourceComponent.select();
sourceComponent.select(null);
}
}
......
......@@ -8,6 +8,8 @@ package com.google.appinventor.client.editor.simple.components;
import static com.google.appinventor.client.Ode.MESSAGES;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
......@@ -22,14 +24,17 @@ import com.google.appinventor.client.output.OdeLog;
import com.google.appinventor.client.properties.BadPropertyEditorException;
import com.google.appinventor.client.widgets.properties.EditableProperties;
import com.google.appinventor.components.common.ComponentConstants;
import com.google.appinventor.components.common.PropertyTypeConstants;
import com.google.appinventor.shared.settings.SettingsConstants;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Style;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
......@@ -232,7 +237,7 @@ public final class MockForm extends MockContainer {
ScrollPanel scrollPanel;
private TitleBar titleBar;
private NavigationBar navigationBar;
private MockComponent selectedComponent;
private List<MockComponent> selectedComponents = new ArrayList<MockComponent>(Collections.singleton(this));
int screenWidth; // TEMP: Make package visible so we can use it MockHVLayoutBase
private int screenHeight;
......@@ -450,8 +455,10 @@ public final class MockForm extends MockContainer {
@Override
protected void addWidthHeightProperties() {
addProperty(PROPERTY_NAME_WIDTH, "" + PORTRAIT_WIDTH, null,
PropertyTypeConstants.PROPERTY_TYPE_LENGTH, null,
new YoungAndroidLengthPropertyEditor());
addProperty(PROPERTY_NAME_HEIGHT, "" + LENGTH_PREFERRED, null,
PropertyTypeConstants.PROPERTY_TYPE_LENGTH, null,
new YoungAndroidLengthPropertyEditor());
}
......@@ -904,48 +911,61 @@ public final class MockForm extends MockContainer {
}
}
private boolean shouldSelectMultipleComponents(NativeEvent e) {
if (e == null) {
return false;
}
if (Window.Navigator.getPlatform().toLowerCase().startsWith("mac")) {
return e.getMetaKey();
} else {
return e.getCtrlKey();
}
}
/**
* Changes the component that is currently selected in the form.
* <p>
* There will always be exactly one component selected in a form
* at any given time.
*/
public final void setSelectedComponent(MockComponent newSelectedComponent) {
MockComponent oldSelectedComponent = selectedComponent;
public final void setSelectedComponent(MockComponent newSelectedComponent, NativeEvent event) {
if (newSelectedComponent == null) {
throw new IllegalArgumentException("at least one component must always be selected");
}
YaFormEditor formEditor = (YaFormEditor) editor;
boolean shouldSelectMultipleComponents = formEditor.getShouldSelectMultipleComponents();
List<MockComponent> selectedComponents = formEditor.getSelectedComponents();
boolean shouldSelectMultipleComponents = shouldSelectMultipleComponents(event);
if (selectedComponents.size() == 1 && selectedComponents.contains(newSelectedComponent)) {
// Attempting to change the selection from old to new when they are the same breaks
// Marker drag. See https://github.com/mit-cml/appinventor-sources/issues/1936
return;
}
if (shouldSelectMultipleComponents && selectedComponents.size() > 1 && formEditor.isSelectedComponent(newSelectedComponent)) {
int index = selectedComponents.indexOf(newSelectedComponent);
selectedComponent = selectedComponents.get((index == 0) ? 1 : index - 1);
// Remove an previously selected component from the list of selected components, but only if
// there would still be something selected.
if (shouldSelectMultipleComponents && selectedComponents.contains(newSelectedComponent)
&& selectedComponents.size() > 1) {
selectedComponents.remove(newSelectedComponent);
newSelectedComponent.onSelectedChange(false);
return;
}
selectedComponent = newSelectedComponent;
Map<String, MockComponent> componentsMap = formEditor.getComponents();
if (oldSelectedComponent != null && !shouldSelectMultipleComponents) { // Can be null initially
for (MockComponent component : componentsMap.values()) {
if (component.getName() != selectedComponent.getName()) {
if (!shouldSelectMultipleComponents) {
for (MockComponent component : selectedComponents) {
if (component != newSelectedComponent) {
component.onSelectedChange(false);
}
}
selectedComponents.clear();
}
selectedComponents.add(newSelectedComponent);
newSelectedComponent.onSelectedChange(true);
}
public final MockComponent getSelectedComponent() {
return selectedComponent;
public final List<MockComponent> getSelectedComponents() {
return selectedComponents;
}
public final MockComponent getLastSelectedComponent() {
return selectedComponents.get(selectedComponents.size() - 1);
}
/**
......
......@@ -118,7 +118,7 @@ public class MockLineString extends MockMapFeatureBase {
if (!polyline.clickHandler) {
while (el.lastChild) el.removeChild(el.lastChild); // clear the div
polyline.clickHandler = function(e) {
this.@com.google.appinventor.client.editor.simple.components.MockLineString::select()();
this.@com.google.appinventor.client.editor.simple.components.MockLineString::select(*)(e);
if (e.originalEvent) e.originalEvent.stopPropagation();
};
polyline.dragHandler = function() {
......
......@@ -538,7 +538,7 @@ public final class MockMap extends MockContainer {
// This is not desirable because it causes issues with the selected component.
return;
} else if (el === background) {
this.owner.@com.google.appinventor.client.editor.simple.components.MockComponent::select()();
this.owner.@com.google.appinventor.client.editor.simple.components.MockComponent::select(*)(e);
return;
}
el = el.parentNode;
......
......@@ -420,7 +420,7 @@ public class MockMarker extends MockMapFeatureBaseWithFill {
map.addLayer(marker);
if (!marker.clickHandler) {
marker.clickHandler = function(e) {
self.@com.google.appinventor.client.editor.simple.components.MockMarker::select()();
self.@com.google.appinventor.client.editor.simple.components.MockMarker::select(*)(e);
if (e.originalEvent) e.originalEvent.stopPropagation();
};
marker.dragHandler = function(e) {
......
......@@ -168,7 +168,7 @@ public class MockPolygon extends MockPolygonBase {
if (!polygon.clickHandler) {
while (el.lastChild) el.removeChild(el.lastChild); // clear the div
polygon.clickHandler = function(e) {
this.@com.google.appinventor.client.editor.simple.components.MockMapFeatureBase::select()();
this.@com.google.appinventor.client.editor.simple.components.MockMapFeatureBase::select(*)(e);
if (e.originalEvent) {
if ((e.originalEvent.metaKey || e.originalEvent.ctrlKey) && polygon.editEnabled()) {
polygon.editor.newHole(e.latlng);
......
......@@ -164,7 +164,7 @@ public class MockRectangle extends MockPolygonBase {
if (!rect.clickHandler) {
while (el.lastChild) el.removeChild(el.lastChild); // clear the div
rect.clickHandler = function (e) {
this.@com.google.appinventor.client.editor.simple.components.MockMapFeatureBase::select()();
this.@com.google.appinventor.client.editor.simple.components.MockMapFeatureBase::select(*)(e);
if (e.originalEvent) e.originalEvent.stopPropagation();
};
rect.dragHandler = function () {
......
......@@ -11,6 +11,7 @@ import com.google.appinventor.client.editor.simple.SimpleEditor;
import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidLengthPropertyEditor;
import com.google.appinventor.client.widgets.properties.TextPropertyEditor;
import com.google.appinventor.components.common.ComponentConstants;
import com.google.appinventor.components.common.PropertyTypeConstants;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Widget;
......@@ -88,8 +89,10 @@ public abstract class MockVisibleComponent extends MockComponent {
protected void addWidthHeightProperties() {
addProperty(PROPERTY_NAME_WIDTH, "" + LENGTH_PREFERRED, MESSAGES.widthPropertyCaption(),
PropertyTypeConstants.PROPERTY_TYPE_LENGTH, null,
new YoungAndroidLengthPropertyEditor());
addProperty(PROPERTY_NAME_HEIGHT, "" + LENGTH_PREFERRED, MESSAGES.heightPropertyCaption(),
PropertyTypeConstants.PROPERTY_TYPE_LENGTH, null,
new YoungAndroidLengthPropertyEditor());
}
......
......@@ -30,6 +30,7 @@ import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroid
import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidLegoEv3SensorPortChoicePropertyEditor;
import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidLegoEv3UltrasonicSensorModeChoicePropertyEditor;
import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidLegoNxtSensorPortChoicePropertyEditor;
import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidLengthPropertyEditor;
import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidMapScaleUnitsPropertyEditor;
import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidMapTypePropertyEditor;
import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidScreenAnimationChoicePropertyEditor;
......@@ -98,6 +99,7 @@ public class PropertiesUtil {
for (ComponentDatabaseInterface.PropertyDefinition property : propertyDefintions) {
mockComponent.addProperty(property.getName(), property.getDefaultValue(),
ComponentsTranslation.getPropertyName(property.getCaption()),
property.getEditorType(), property.getEditorArgs(),
PropertiesUtil.createPropertyEditor(property.getEditorType(), property.getDefaultValue(), editor, property.getEditorArgs()));
/*OdeLog.log("Property Caption: " + property.getCaption() + ", "
+ TranslationComponentProperty.getName(property.getCaption()));*/
......@@ -220,6 +222,8 @@ public class PropertiesUtil {
} else if (editorType.equals(PropertyTypeConstants.PROPERTY_TYPE_LEGO_NXT_GENERATED_COLOR)) {
return new YoungAndroidColorChoicePropertyEditor(
YoungAndroidColorChoicePropertyEditor.NXT_GENERATED_COLORS, defaultValue);
} else if (editorType.equals(PropertyTypeConstants.PROPERTY_TYPE_LENGTH)) {
return new YoungAndroidLengthPropertyEditor();
} else if (editorType.equals(PropertyTypeConstants.PROPERTY_TYPE_LONGITUDE)) {
return new YoungAndroidFloatRangePropertyEditor(-180, 180);
} else if (editorType.equals(PropertyTypeConstants.PROPERTY_TYPE_MAP_TYPE)) {
......
......@@ -589,7 +589,7 @@ public final class YaBlocksEditor extends FileEditor
private void updateSourceStructureExplorer() {
MockForm form = getForm();
if (form != null) {
updateBlocksTree(form, form.getSelectedComponent().getSourceStructureExplorerItem());
updateBlocksTree(form, form.getLastSelectedComponent().getSourceStructureExplorerItem());
}
}
......
......@@ -7,10 +7,10 @@
package com.google.appinventor.client.explorer;
import com.google.appinventor.client.Ode;
import com.google.appinventor.client.output.OdeLog;
import com.google.appinventor.client.widgets.TextButton;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.event.logical.shared.*;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.*;
import java.util.Iterator;
......@@ -26,16 +26,38 @@ import static com.google.appinventor.client.Ode.MESSAGES;
*/
public class SourceStructureExplorer extends Composite {
// UI elements
private final Tree tree;
private final EventCaptureTree tree;
private final TextButton renameButton;
private final TextButton deleteButton;
/**
* This is a hack to work around the fact that for multiselect we need to have
* access to the state of the meta/ctrl key but the SelectionHandler doesn't
* provide access to the original event that caused the selection. We capture
* the most recent event before the selection event is triggered and then
* reset once the selection has been updated.
*/
static class EventCaptureTree extends Tree {
Event lastEvent = null;
public EventCaptureTree(Resources resources) {
super(resources);
}
@Override
public void onBrowserEvent(Event event) {
lastEvent = event;
super.onBrowserEvent(event);
}
}
/**
* Creates a new source structure explorer.
*/
public SourceStructureExplorer() {
// Initialize UI elements
tree = new Tree(Ode.getImageBundle());
tree = new EventCaptureTree(Ode.getImageBundle());
tree.setAnimationEnabled(true);
tree.setScrollOnSelectEnabled(false);
tree.addCloseHandler(new CloseHandler<TreeItem>() {
......@@ -74,7 +96,7 @@ public class SourceStructureExplorer extends Composite {
SourceStructureExplorerItem item = (SourceStructureExplorerItem) userObject;
enableButtons(item);
//showBlocks(item);
item.onSelected();
item.onSelected(tree.lastEvent);
} else {
disableButtons();
//hideComponent();
......@@ -82,6 +104,7 @@ public class SourceStructureExplorer extends Composite {
} else {
disableButtons();
}
tree.lastEvent = null;
}
});
tree.addKeyDownHandler(new KeyDownHandler() {
......
......@@ -6,6 +6,8 @@
package com.google.appinventor.client.explorer;
import com.google.gwt.dom.client.NativeEvent;
/**
* Defines an interface for an item in the source structure explorer.
*
......@@ -15,7 +17,7 @@ public interface SourceStructureExplorerItem {
/**
* Invoked when this item is selected.
*/
void onSelected();
void onSelected(NativeEvent source);
/**
* Invoked when this item is expanded or collapsed
......
......@@ -410,13 +410,13 @@ public final class DragSourceSupport implements MouseListener, TouchStartHandler
}
@Override
public void onTouchEnd(TouchEndEvent event) {
public void onTouchEnd(final TouchEndEvent event) {
final Widget src = (Widget) event.getSource();
if (src instanceof MockComponent) { // We only select on CLICK, which isn't generated on mobile
DeferredCommand.addCommand(new Command() {
@Override
public void execute() {
((MockComponent) src).select();
((MockComponent) src).select(event.getNativeEvent());
}
});
}
......
......@@ -50,8 +50,8 @@ public class EditableProperties extends Properties<EditableProperty> {
*/
public void addProperty(String name, String defaultValue, String caption,
PropertyEditor editor, int type) {
addProperty(new EditableProperty(this, name, defaultValue, caption, editor, type));
PropertyEditor editor, int type, String editorType, String[] editorArgs) {
addProperty(new EditableProperty(this, name, defaultValue, caption, editor, type, editorType, editorArgs));
}
@Override
......
......@@ -57,6 +57,12 @@ public final class EditableProperty extends Property {
// Property caption for use in properties panel
private final String caption;
// Editor type of the property (for creating new editors)
private final String editorType;
// Additional arguments for the editor
private final String[] editorArgs;
/**
* Creates a new property.
*
......@@ -70,17 +76,24 @@ public final class EditableProperty extends Property {
* @param type type of property; see {@code TYPE_*} constants
*/
public EditableProperty(EditableProperties properties, String name, String defaultValue,
String caption, PropertyEditor editor, int type) {
String caption, PropertyEditor editor, int type, String editorType, String[] editorArgs) {
super(name, defaultValue);
this.properties = properties;
this.type = type;
this.editor = editor;
this.caption = caption;
this.editorType = editorType;
this.editorArgs = editorArgs;
editor.setProperty(this);
}
public EditableProperty(EditableProperties properties, String name, String defaultValue,
int type) {
this(properties, name, defaultValue, name, new TextPropertyEditor(), type, "", null);
}
/**
* Creates a new property.
*
......@@ -92,8 +105,8 @@ public final class EditableProperty extends Property {
* @param type type of property; see {@code TYPE_*} constants
*/
public EditableProperty(EditableProperties properties, String name, String defaultValue,
int type) {
this(properties, name, defaultValue, name, new TextPropertyEditor(), type);
int type, String editorType, String[] editorArgs) {
this(properties, name, defaultValue, name, new TextPropertyEditor(), type, editorType, editorArgs);
}
/**
......@@ -150,6 +163,14 @@ public final class EditableProperty extends Property {
return caption;
}
public String getEditorType() {
return editorType;
}
public String[] getEditorArgs() {
return editorArgs;
}
/**
* Called when this property is being orphaned.
......
......@@ -42,4 +42,8 @@ public abstract class PropertyEditor extends Composite {
*/
public void orphan() {
}
public void refresh() {
this.updateValue();
}
}
......@@ -156,6 +156,12 @@ public class PropertyTypeConstants {
*/
public static final String PROPERTY_TYPE_CHOICES = "choices";
/**
* Length editor (e.g., width, height)
* @see com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidLengthPropertyEditor
*/
public static final String PROPERTY_TYPE_LENGTH = "length";
/**
* Floating-point values in the range of valid longitudes [-180, 180].
* @see com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidFloatRangePropertyEditor
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment