Unverified Commit 17b754f9 authored by Arin Modi's avatar Arin Modi Committed by GitHub

Implement a Project Properties Dialog (#2946)

parent ab109ff4
......@@ -628,7 +628,7 @@
<path refid="YaClientApp.classpath" />
</classpath>
<jvmarg value="-Xss2M"/> <!-- increase if you see a StackOverflowError -->
<jvmarg value="-Xmx2G"/>
<jvmarg value="-Xmx3G"/>
<jvmarg line="${XstartOnFirstThread}"/>
<jvmarg value="-Dfile.encoding=UTF-8" />
<arg value="-war"/>
......@@ -648,7 +648,7 @@
<path refid="YaClientApp.classpath" />
<pathelement location="${gwt.sdk}/gwt-codeserver.jar" />
</classpath>
<jvmarg value="-Xmx1G" />
<jvmarg value="-Xmx3G" />
<arg line="-style PRETTY -logLevel INFO" />
<arg value="com.google.appinventor.YaClient-dev" />
<arg value="-bindAddress"/>
......
......@@ -577,6 +577,14 @@ public interface OdeMessages extends Messages, AutogeneratedOdeMessages {
@Description("Caption for component Name Label in rename wizard.")
String componentNameLabel();
@DefaultMessage("Project Properties...")
@Description("Text On Project Properties Dialog Menuitem")
String projectPropertiesMenuItem();
@DefaultMessage("Project Properties")
@Description("Text On Project Properties Button")
String projectPropertiesText();
@DefaultMessage("Import Extension Failed!")
@Description("Error message reported when the component import failed")
String componentImportError();
......@@ -5493,4 +5501,16 @@ public interface OdeMessages extends Messages, AutogeneratedOdeMessages {
@DefaultMessage("Shared")
@Description("")
String fileScopeShared();
@DefaultMessage("General")
@Description("Text to Display General Project Property Category in Project Property Dialog")
String projectPropertyGeneralCategoryTitle();
@DefaultMessage("Theming")
@Description("Text to Display Theming Project Property Category in Project Property Dialog")
String projectPropertyThemingCategoryTitle();
@DefaultMessage("Publishing")
@Description("Text to Display Publishing Project Property Category in Project Property Dialog")
String projectPropertyPublishingCategoryTitle();
}
......@@ -65,6 +65,7 @@ public class TopToolbar extends Composite {
private static final String WIDGET_NAME_IMPORTPROJECT = "ImportProject";
private static final String WIDGET_NAME_IMPORTTEMPLATE = "ImportTemplate";
private static final String WIDGET_NAME_EXPORTPROJECT = "ExportProject";
private static final String WIDGET_NAME_PROJECTPROPERTIES = "ProjectProperties";
private static final String WIDGET_NAME_ADMIN = "Admin";
private static final String WIDGET_NAME_USER_ADMIN = "UserAdmin";
......@@ -311,6 +312,7 @@ public class TopToolbar extends Composite {
}
} else { // We have to be in the Designer/Blocks view
fileDropDown.setItemEnabled(MESSAGES.deleteProjectButton(), true);
fileDropDown.setItemEnabled(MESSAGES.projectPropertiesMenuItem(), true);
fileDropDown.setItemEnabled(MESSAGES.trashProjectMenuItem(), true);
fileDropDown.setItemEnabled(MESSAGES.exportAllProjectsMenuItem(), projectCount > 0);
fileDropDown.setItemEnabledById(WIDGET_NAME_EXPORTPROJECT, true);
......
......@@ -43,6 +43,9 @@
<ai:DropDownItem name="Checkpoint" caption="{messages.checkpointMenuItem}" visible="{hasWriteAccess}">
<actions:CheckpointAction />
</ai:DropDownItem>
<ai:DropDownItem name="ProjectProperties" caption="{messages.projectPropertiesMenuItem}">
<yaactions:ProjectPropertiesAction />
</ai:DropDownItem>
<hr />
<ai:DropDownItem name="ExportProject" caption="{messages.exportProjectMenuItem}">
<actions:ExportProjectAction />
......
......@@ -762,7 +762,7 @@ public final class MockForm extends MockContainer {
case PROPERTY_NAME_ACCENT_COLOR:
case PROPERTY_NAME_THEME:
case PROPERTY_NAME_DEFAULTFILESCOPE: {
return editor.isScreen1();
return false;
}
default: {
......@@ -1441,6 +1441,10 @@ public final class MockForm extends MockContainer {
}
}
public void projectPropertyChanged() {
((YaFormEditor) editor).refreshCurrentPropertiesPanel();
}
@Override
public EditableProperties getProperties() {
// Before we return the Properties object, we make sure that the
......
......@@ -110,6 +110,7 @@ public class DesignToolbar extends Toolbar {
private static final String WIDGET_NAME_SWITCH_TO_BLOCKS_EDITOR = "SwitchToBlocksEditor";
private static final String WIDGET_NAME_SWITCH_TO_FORM_EDITOR = "SwitchToFormEditor";
private static final String WIDGET_NAME_SENDTOGALLERY = "SendToGallery";
private static final String WIDGET_NAME_PROJECT_PROPERTIES_DIALOG = "ProjectPropertiesDialog";
// Enum for type of view showing in the design tab
public enum View {
......@@ -144,6 +145,7 @@ public class DesignToolbar extends Toolbar {
@UiField ToolbarItem removeFormItem;
@UiField ToolbarItem switchToDesign;
@UiField ToolbarItem switchToBlocks;
@UiField ToolbarItem projectPropertiesDialog;
/**
* Initializes and assembles all commands into buttons in the toolbar.
......
......@@ -30,6 +30,10 @@
align="center">
<ya:RemoveFormAction />
</ai:ToolbarItem>
<ai:ToolbarItem name="ProjectPropertiesDialog" caption="{messages.projectPropertiesText}" ui:field="projectPropertiesDialog"
align="center">
<ya:ProjectPropertiesAction />
</ai:ToolbarItem>
<ai:ToolbarItem name="switchToDesign" caption="{messages.switchToFormEditorButton}"
ui:field="switchToDesign" align="right">
<ya:SwitchToFormEditorAction />
......
......@@ -12,7 +12,6 @@ import static com.google.appinventor.client.editor.simple.components.MockCompone
import com.google.appinventor.client.ErrorReporter;
import com.google.appinventor.client.Ode;
import com.google.appinventor.client.OdeAsyncCallback;
import com.google.appinventor.client.boxes.AssetListBox;
import com.google.appinventor.client.boxes.PaletteBox;
import com.google.appinventor.client.boxes.PropertiesBox;
import com.google.appinventor.client.boxes.SourceStructureBox;
......@@ -754,6 +753,10 @@ public final class YaFormEditor extends SimpleEditor implements FormChangeListen
Ode.getInstance().showComponentDesigner();
}
public void refreshCurrentPropertiesPanel() {
PropertiesBox.getPropertiesBox().show(this, true);
}
private void onFormStructureChange() {
Ode.getInstance().getEditorManager().scheduleAutoSave(this);
......
......@@ -20,6 +20,7 @@ import com.google.appinventor.client.editor.simple.SimpleComponentDatabase;
import com.google.appinventor.client.editor.simple.components.MockComponent;
import com.google.appinventor.client.editor.simple.components.MockFusionTablesControl;
import com.google.appinventor.client.editor.youngandroid.i18n.BlocklyMsg;
import com.google.appinventor.client.explorer.dialogs.ProjectPropertiesDialogBox;
import com.google.appinventor.client.explorer.project.ComponentDatabaseChangeListener;
import com.google.appinventor.client.explorer.project.Project;
import com.google.appinventor.client.explorer.project.ProjectChangeListener;
......@@ -122,6 +123,20 @@ public final class YaProjectEditor extends ProjectEditor implements ProjectChang
private boolean screen1BlocksLoaded = false;
private boolean screen1Added = false;
// variable which open the ProjectPropertyDialog(per project)
private ProjectPropertiesDialogBox propertyDialogBox = null;
/**
* Opens the project property dialog
*/
public void openProjectPropertyDialog() {
if (propertyDialogBox == null) {
propertyDialogBox = new ProjectPropertiesDialogBox(this);
}
String curScreen = Ode.getInstance().getDesignToolbar().getCurrentProject().currentScreen;
propertyDialogBox.showDialog(curScreen);
}
/**
* Returns a project editor factory for {@code YaProjectEditor}s.
*
......
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2020-2023 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package com.google.appinventor.client.editor.youngandroid.actions;
import com.google.appinventor.client.Ode;
import com.google.appinventor.client.editor.youngandroid.YaProjectEditor;
import com.google.gwt.user.client.Command;
public class ProjectPropertiesAction implements Command {
@Override
public void execute() {
YaProjectEditor projectEditor = (YaProjectEditor)Ode.getInstance().getEditorManager()
.getOpenProjectEditor(Ode.getInstance().getCurrentYoungAndroidProjectId());
projectEditor.openProjectPropertyDialog();
}
}
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2023 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package com.google.appinventor.client.explorer.dialogs;
import com.google.appinventor.client.ComponentsTranslation;
import com.google.appinventor.client.editor.simple.components.MockForm;
import com.google.appinventor.client.editor.youngandroid.YaProjectEditor;
import com.google.appinventor.client.Ode;
import com.google.appinventor.client.widgets.properties.EditableProperties;
import com.google.appinventor.client.widgets.properties.EditableProperty;
import com.google.appinventor.client.widgets.properties.PropertyEditor;
import com.google.appinventor.client.wizards.Dialog;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DeckPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
/**
* A dialog for updating project properties that can be open from any screen
*/
public class ProjectPropertiesDialogBox {
private static final ProjectPropertiesDialogBoxUiBinder UI_BINDER = GWT.create(ProjectPropertiesDialogBoxUiBinder.class);
interface ProjectPropertiesDialogBoxUiBinder extends UiBinder<Widget, ProjectPropertiesDialogBox> {
}
@UiField
Dialog projectProperties;
@UiField
ListBox categoryList;
@UiField
DeckPanel propertiesDeckPanel;
@UiField
Button closeDialogBox;
/**
* List Of project properties category, which will be used to group properties in the dialog
* properties category are : General, Theming, Publishing
*/
private static final List<String> projectPropertyCategoryTitle = Arrays.asList(
new String[] {
Ode.MESSAGES.projectPropertyGeneralCategoryTitle(),
Ode.MESSAGES.projectPropertyThemingCategoryTitle(),
Ode.MESSAGES.projectPropertyPublishingCategoryTitle()
}
);
/**
* Maps the project property category to List of EditableProperty which
* belongs to that particular project property category
*/
private HashMap<String, List<EditableProperty>> categoryToProperties = new HashMap<>();
/* Object for storing reference of project editor in which the dialog opened */
private YaProjectEditor projectEditor;
/* refers to the screen name in which dialog opened */
private String currentScreen = "";
/**
* Show the project property dialog
*
* @param screenName name of the screen in which dialog needs to open
*/
public void showDialog(String screenName) {
currentScreen = screenName;
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
@Override
public void execute() {
projectProperties.center();
}
});
}
public ProjectPropertiesDialogBox(YaProjectEditor projectEditor) {
UI_BINDER.createAndBindUi(this);
projectProperties.setAutoHideEnabled(false);
projectProperties.setModal(true);
projectProperties.setCaption(Ode.MESSAGES.projectPropertiesText());
categoryList.getElement().getStyle().setProperty("height", "400px");
// Get current instance of YaProjectEditor
this.projectEditor = projectEditor;
MockForm form = projectEditor.getFormFileEditor("Screen1").getForm();
// Get project properties from the screen1 MockForm
EditableProperties editableProperties = form.getProperties();
Iterator<EditableProperty> properties = editableProperties.iterator();
// Iterate and put the editable property to the corresponding category in categoryToProperties
while (properties.hasNext()) {
EditableProperty property = properties.next();
if (!categoryToProperties.containsKey(property.getCategory())) {
categoryToProperties.put(property.getCategory(), new ArrayList<EditableProperty>());
}
categoryToProperties.get(property.getCategory()).add(property);
}
// Add the Categories to ListBox - categoryList
for (String categoryTitle : projectPropertyCategoryTitle) {
categoryList.addItem(categoryTitle);
propertiesDeckPanel.add(getPanel(categoryTitle));
}
// When category is changed by the user, display related properties
categoryList.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
propertiesDeckPanel.showWidget(categoryList.getSelectedIndex());
}
});
categoryList.setVisibleItemCount(projectPropertyCategoryTitle.size());
// When dialog is opened, properties related to the General category is shown
propertiesDeckPanel.showWidget(0);
}
/**
* Build vertical panel for each categories
*
* @param category indicates the category for which we need to build the vertical panel
* @return vertical panel which contains the all the Editable Property belongs to the particualt category passed as argument
*/
private FlowPanel getPanel(String category) {
// Main
FlowPanel propertiesContainer = new FlowPanel();
propertiesContainer.setStyleName("ode-propertyDialogVerticalPanel");
List<EditableProperty> properties = categoryToProperties.get(category);
for (EditableProperty property : properties) {
// container for displaing one editable property
FlowPanel propertyContainer = new FlowPanel();
propertyContainer.setStyleName("ode-propertyDialogPropertyContainer");
// name of the EditableProperty
Label name = new Label(ComponentsTranslation.getPropertyName(property.getName()));
name.setStyleName("ode-propertyDialogPropertyTitle");
// Description of the property
Label description = new Label(ComponentsTranslation.getPropertyDescription(property.getDescription()));
description.setStyleName("ode-propertyDialogPropertyDescription");
// editor of the editor
PropertyEditor editor = property.getEditor();
editor.setStyleName("ode-propertyDialogPropertyEditor");
// add to the container
propertyContainer.add(name);
propertyContainer.add(description);
propertyContainer.add(editor);
// add to the main container
propertiesContainer.add(propertyContainer);
}
return propertiesContainer;
}
void applyPropertyChanges() {
if (!"Screen1".equals(currentScreen)) {
MockForm currentform = projectEditor.getFormFileEditor(currentScreen).getForm();
if (currentform != null) {
currentform.projectPropertyChanged();
}
}
}
@UiHandler("closeDialogBox")
void handleClose(ClickEvent e) {
projectProperties.hide();
applyPropertyChanges();
}
}
<!-- Copyright 2023 MIT, All rights reserved -->
<!-- Released under the Apache License, Version 2.0 -->
<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:wiz="urn:import:com.google.appinventor.client.wizards"
ui:generateFormat="com.google.gwt.i18n.server.PropertyCatalogFactory"
ui:generateKeys="com.google.gwt.i18n.server.keygen.MethodNameKeyGenerator"
ui:baseMessagesInterface="com.google.appinventor.client.OdeMessages"
ui:generateLocales="default">
<ui:with type="com.google.appinventor.client.Images" field="res" />
<wiz:Dialog ui:field="projectProperties" styleName="ode-DialogBox">
<g:VerticalPanel>
<g:HorizontalPanel styleName='ode-propertyDialogContainer'>
<g:ListBox ui:field="categoryList" styleName='ode-projectPropertyCategoryTitlePanel'></g:ListBox>
<g:ScrollPanel styleName='ode-propertyDialogPropertiesScrollPanel'>
<g:DeckPanel ui:field="propertiesDeckPanel"></g:DeckPanel>
</g:ScrollPanel>
</g:HorizontalPanel>
<g:FlowPanel styleName="ode-bottomRow">
<g:Button ui:field='closeDialogBox' styleName='ode-closeDialogBox'>
<ui:msg key="closeButton" description="Text of the button to close the dialog box"
>Close</ui:msg>
</g:Button>
</g:FlowPanel>
</g:VerticalPanel>
</wiz:Dialog>
</ui:UiBinder>
......@@ -1092,6 +1092,7 @@ select.ode-PropertyEditor[disabled] {
color: black;
border: 1px solid gray;
padding: 2px;
z-index: 1000;
}
.ode-ColorChoicePropertyEditor {
......@@ -1648,6 +1649,75 @@ path.ode-SimpleMockMapFeature-selected {
/* End of NoProjectsDialogBox. */
/* Start Of ProjectPropertiesDialogBox. */
.ode-propertyDialogContainer {
margin-bottom: 10px;
overflow: hidden;
}
.ode-projectPropertyCategoryTitlePanel {
margin-top: 18px;
width: 180px;
border-radius: 0px;
border: 0px;
border-right: 2px solid black;
padding-right: 20px;
outline: none;
}
.ode-propertyDialogPropertiesScrollPanel {
height: 400px;
width: 600px;
padding-bottom: 40px;
padding-right: 30px;
}
.ode-propertyDialogPropertyContainer {
display: flex;
flex-flow: column;
width: 100%;
}
.ode-propertyDialogPropertyTitle {
font-size: 16px;
font-weight: bold;
color: #413f3f;
margin-top: 18px;
}
.ode-propertyDialogPropertyDescription {
font-size: 14px;
font-weight: 400;
color: #797575;
margin-top: 18px;
}
.ode-propertyDialogPropertyEditor {
min-height: 30px;
height: 10%;
width: 100%;
margin-top: 18px;
}
.ode-projectPropertyCategoryTitlePanel option {
font-size: 14px;
font-weight: 500;
padding: 10px;
margin-bottom: 20px;
border-radius: 10px;
}
.ode-projectPropertyCategoryTitlePanel:focus {
outline: none;
}
.ode-propertyDialogVerticalPanel {
display: flex;
flex-flow: column;
}
/* End of Project ProjectPropertiesDialogBox. */
.ode-DialogBox {
background-color: white;
border-left: 4px solid #8fc202;
......
......@@ -52,7 +52,13 @@ public enum PropertyCategory {
* Token property of CloudDB, where App Inventor autopopulates the token and that should be
* sufficient for most users.
*/
ADVANCED("Advanced");
ADVANCED("Advanced"),
GENERAL("General"),
THEMING("Theming"),
PUBLISHING("Publishing");
private final String name;
......
......@@ -1373,7 +1373,7 @@ public class Form extends AppInventorCompatActivity
*/
@DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_FILESCOPE,
defaultValue = "App")
@SimpleProperty(category = PropertyCategory.BEHAVIOR, userVisible = false)
@SimpleProperty(category = PropertyCategory.GENERAL, userVisible = false)
public void DefaultFileScope(FileScope scope) {
this.defaultFileScope = scope;
}
......@@ -1851,7 +1851,7 @@ public class Form extends AppInventorCompatActivity
*/
@DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_ASSET,
defaultValue = "")
@SimpleProperty(userVisible = false, category = PropertyCategory.APPLICATION)
@SimpleProperty(userVisible = false, category = PropertyCategory.GENERAL)
public void Icon(String name) {
// We don't actually need to do anything.
}
......@@ -1867,7 +1867,7 @@ public class Form extends AppInventorCompatActivity
@SimpleProperty(userVisible = false,
description = "An integer value which must be incremented each time a new Android "
+ "Application Package File (APK) is created for the Google Play Store.",
category = PropertyCategory.APPLICATION)
category = PropertyCategory.PUBLISHING)
public void VersionCode(int vCode) {
// We don't actually need to do anything.
}
......@@ -1883,7 +1883,7 @@ public class Form extends AppInventorCompatActivity
@SimpleProperty(userVisible = false,
description = "A string which can be changed to allow Google Play "
+ "Store users to distinguish between different versions of the App.",
category = PropertyCategory.APPLICATION)
category = PropertyCategory.PUBLISHING)
public void VersionName(String vName) {
// We don't actually need to do anything.
}
......@@ -1905,7 +1905,7 @@ public class Form extends AppInventorCompatActivity
"If set to responsive, screen layouts will use the actual resolution of the device. " +
"See the documentation on responsive design in App Inventor for more information. " +
"This property appears on Screen1 only and controls the sizing for all screens in the app.",
category = PropertyCategory.APPLICATION)
category = PropertyCategory.GENERAL)
public void Sizing(String value) {
// This is used by the project and build server.
// We also use it to adjust sizes
......@@ -1942,7 +1942,7 @@ public class Form extends AppInventorCompatActivity
@DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_BOOLEAN,
defaultValue = "True", alwaysSend = true)
@SimpleProperty(category = PropertyCategory.APPEARANCE, userVisible = false,
@SimpleProperty(category = PropertyCategory.GENERAL, userVisible = false,
// This description won't appear as a tooltip, since there's no block, but we'll keep it with the source.
description = "If false, lists will be converted to strings using Lisp "
+ "notation, i.e., as symbols separated by spaces, e.g., (a 1 b2 (c "
......@@ -1967,7 +1967,7 @@ public class Form extends AppInventorCompatActivity
* **Note:** This property appears only in Screen1 and the value for Screen1 determines the
* behavior for all screens in the app.
*/
@SimpleProperty(category = PropertyCategory.APPEARANCE, userVisible = false)
@SimpleProperty(category = PropertyCategory.GENERAL, userVisible = false)
public boolean ShowListsAsJson() {
return showListsAsJson;
}
......@@ -1983,7 +1983,7 @@ public class Form extends AppInventorCompatActivity
@SimpleProperty(userVisible = false,
description = "This is the display name of the installed application in the phone." +
"If the AppName is blank, it will be set to the name of the project when the project is built.",
category = PropertyCategory.APPLICATION)
category = PropertyCategory.GENERAL)
public void AppName(String aName) {
// We don't actually need to do anything.
}
......@@ -1991,7 +1991,7 @@ public class Form extends AppInventorCompatActivity
@DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_COLOR,
defaultValue = ComponentConstants.DEFAULT_PRIMARY_COLOR)
@SimpleProperty(userVisible = false, description = "This is the primary color used for " +
"Material UI elements, such as the ActionBar.", category = PropertyCategory.APPEARANCE)
"Material UI elements, such as the ActionBar.", category = PropertyCategory.THEMING)
public void PrimaryColor(final int color) {
setPrimaryColor(color);
}
......@@ -2009,7 +2009,7 @@ public class Form extends AppInventorCompatActivity
@DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_COLOR,
defaultValue = ComponentConstants.DEFAULT_PRIMARY_DARK_COLOR)
@SimpleProperty(userVisible = false, description = "This is the primary color used for darker " +
"elements in Material UI.", category = PropertyCategory.APPEARANCE)
"elements in Material UI.", category = PropertyCategory.THEMING)
public void PrimaryColorDark(int color) {
primaryColorDark = color;
}
......@@ -2027,7 +2027,7 @@ public class Form extends AppInventorCompatActivity
@DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_COLOR,
defaultValue = ComponentConstants.DEFAULT_ACCENT_COLOR)
@SimpleProperty(userVisible = false, description = "This is the accent color used for " +
"highlights and other user interface accents.", category = PropertyCategory.APPEARANCE)
"highlights and other user interface accents.", category = PropertyCategory.THEMING)
public void AccentColor(int color) {
accentColor = color;
}
......@@ -2057,7 +2057,7 @@ public class Form extends AppInventorCompatActivity
@DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_THEME,
defaultValue = ComponentConstants.DEFAULT_THEME)
@SimpleProperty(userVisible = false, description = "Sets the theme used by the application.",
category = PropertyCategory.APPLICATION)
category = PropertyCategory.THEMING)
public void Theme(String theme) {
if (SdkLevel.getLevel() < SdkLevel.LEVEL_HONEYCOMB) {
backgroundColor = Component.COLOR_WHITE;
......@@ -2120,7 +2120,7 @@ public class Form extends AppInventorCompatActivity
@SimpleProperty(userVisible = false,
description = "A URL to use to populate the Tutorial Sidebar while "
+ "editing a project. Used as a teaching aid.",
category = PropertyCategory.APPLICATION)
category = PropertyCategory.GENERAL)
public void TutorialURL(String url) {
// We don't actually do anything This property is stored in the
// project properties file
......@@ -2132,7 +2132,7 @@ public class Form extends AppInventorCompatActivity
description = "A JSON string representing the subset for the screen. Authors of template apps "
+ "can use this to control what components, designer properties, and blocks are available "
+ "in the project.",
category = PropertyCategory.APPLICATION)
category = PropertyCategory.GENERAL)
public void BlocksToolkit(String json) {
// We don't actually do anything. This property is stored in the
// project properties file
......
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