/* This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV This program is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, see http://www.gnu.org/licenses or write to the Free Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ package com.servoy.j2db.scripting.solutionmodel; import java.awt.Dimension; import java.awt.Point; import java.util.Map; import org.mozilla.javascript.annotations.JSFunction; import org.mozilla.javascript.annotations.JSGetter; import org.mozilla.javascript.annotations.JSSetter; import com.servoy.base.scripting.annotations.ServoyClientSupport; import com.servoy.j2db.IApplication; import com.servoy.j2db.documentation.ServoyDocumented; import com.servoy.j2db.persistence.BaseComponent; import com.servoy.j2db.persistence.IAnchorConstants; import com.servoy.j2db.persistence.ISupportName; import com.servoy.j2db.persistence.StaticContentSpecLoader.TypedProperty; import com.servoy.j2db.scripting.IJavaScriptType; import com.servoy.j2db.solutionmodel.ISMComponent; import com.servoy.j2db.solutionmodel.ISMHasDesignTimeProperty; import com.servoy.j2db.util.PersistHelper; import com.servoy.j2db.util.Utils; /** * @author jcompagner */ @ServoyDocumented(category = ServoyDocumented.RUNTIME, scriptingName = "JSComponent") public class JSComponent<T extends BaseComponent> extends JSBase<T> implements IJavaScriptType, ISMComponent, ISMHasDesignTimeProperty { protected JSComponent(IJSParent< ? > parent, T baseComponent, boolean isNew) { super(parent, baseComponent, isNew); } /** * Set the event handler for the method key, JSMethod may contain arguments. */ protected void setEventHandler(IApplication application, TypedProperty<Integer> methodProperty, JSMethod method) { JSForm.setEventHandler(application, getBaseComponent(true), methodProperty, method); } /** * Get the event handler for the method key, JSMethod may contain arguments. */ protected JSMethod getEventHandler(IApplication application, TypedProperty<Integer> methodProperty) { return JSForm.getEventHandler(application, getBaseComponent(false), methodProperty, getJSParent()); } /** * @clonedesc com.servoy.j2db.persistence.BaseComponent#getBackground() * * @sample * // This property can be used on all types of components. * // Here it is illustrated only for labels and fields. * var greenLabel = form.newLabel('Green',10,10,100,50); * greenLabel.background = 'green'; // Use generic names for colors. * var redField = form.newField('parent_table_text',JSField.TEXT_FIELD,10,110,100,30); * redField.background = '#FF0000'; // Use RGB codes for colors. */ @JSGetter public String getBackground() { return PersistHelper.createColorString(getBaseComponent(false).getBackground()); } @JSSetter public void setBackground(String arg) { getBaseComponent(true).setBackground(PersistHelper.createColor(arg)); } /** * @clonedesc com.servoy.j2db.persistence.BaseComponent#getBorderType() * * @sample * //HINT: To know exactly the notation of this property set it in the designer and then read it once out through the solution model. * var field = form.newField('my_table_text', JSField.TEXT_FIELD, 10, 10, 100, 20); * field.borderType = solutionModel.createLineBorder(1,'#ff0000'); */ @JSGetter public String getBorderType() { return getBaseComponent(false).getBorderType(); } @JSSetter public void setBorderType(String arg) { getBaseComponent(true).setBorderType(arg); } /** * @clonedesc com.servoy.j2db.persistence.BaseComponent#getFontType() * * @sample * var label = form.newLabel('Text here', 10, 50, 100, 20); * label.fontType = solutionModel.createFont('Times New Roman',1,14); */ @JSGetter public String getFontType() { return getBaseComponent(false).getFontType(); } @JSSetter public void setFontType(String arg) { getBaseComponent(true).setFontType(arg); } /** * @clonedesc com.servoy.j2db.persistence.BaseComponent#getForeground() * * @sample * // This property can be used on all types of components. * // Here it is illustrated only for labels and fields. * var labelWithBlueText = form.newLabel('Blue text', 10, 10, 100, 30); * labelWithBlueText.foreground = 'blue'; // Use generic names for colors. * var fieldWithYellowText = form.newField('parent_table_text', JSField.TEXT_FIELD, 10, 50, 100, 20); * fieldWithYellowText.foreground = '#FFFF00'; // Use RGB codes for colors. */ @JSGetter public String getForeground() { return PersistHelper.createColorString(getBaseComponent(false).getForeground()); } @JSSetter public void setForeground(String arg) { getBaseComponent(true).setForeground(PersistHelper.createColor(arg)); } /** * @clonedesc com.servoy.j2db.persistence.BaseComponent#getPrintSliding() * * @sample * var form = solutionModel.newForm('printForm', 'db:/example_data/parent_table', null, false, 400, 300); * var slidingLabel = form.newLabel('Some long text here', 10, 10, 5, 5); * slidingLabel.printSliding = SM_PRINT_SLIDING.GROW_HEIGHT | SM_PRINT_SLIDING.GROW_WIDTH; * slidingLabel.background = 'gray'; * forms['printForm'].controller.showPrintPreview(); */ @JSGetter public int getPrintSliding() { return getBaseComponent(false).getPrintSliding(); } @JSSetter public void setPrintSliding(int i) { getBaseComponent(true).setPrintSliding(i); } /** * @clonedesc com.servoy.base.persistence.IBaseComponent#getStyleClass() * * @sample * var form = solutionModel.newForm('printForm', 'db:/example_data/parent_table', null, false, 400, 300); * var field = form.newField('parent_table_text', JSField.TEXT_FIELD, 10, 10, 100, 20); * var style = solutionModel.newStyle('myStyle','field.fancy { background-color: yellow; }'); * form.styleName = 'myStyle'; // First set the style on the form. * field.styleClass = 'fancy'; // Then set the style class on the field. */ @JSGetter public String getStyleClass() { return getBaseComponent(false).getStyleClass(); } @JSSetter public void setStyleClass(String arg) { getBaseComponent(true).setStyleClass(arg); } /** * @clonedesc com.servoy.j2db.persistence.BaseComponent#getTransparent() * * @sample * // Load an image from disk an create a Media object based on it. * var imageBytes = plugins.file.readFile('d:/ball.jpg'); * var media = solutionModel.newMedia('ball.jpg', imageBytes); * // Put on the form a label with the image. * var image = form.newLabel('', 10, 10, 100, 100); * image.imageMedia = media; * // Put two fields over the image. The second one will be transparent and the * // image will shine through. * var nonTransparentField = form.newField('parent_table_text', JSField.TEXT_FIELD, 10, 20, 100, 20); * var transparentField = form.newField('parent_table_text', JSField.TEXT_FIELD, 10, 50, 100, 20); * transparentField.transparent = true; */ @JSGetter public boolean getTransparent() { return getBaseComponent(false).getTransparent(); } @JSSetter public void setTransparent(boolean arg) { getBaseComponent(true).setTransparent(arg); } /** * @clonedesc com.servoy.j2db.persistence.BaseComponent#getAnchors() * * @sample * var form = solutionModel.newForm('mediaForm', 'db:/example_data/parent_table', null, false, 400, 300); * var strechAllDirectionsLabel = form.newLabel('Strech all directions', 10, 10, 380, 280); * strechAllDirectionsLabel.background = 'red'; * strechAllDirectionsLabel.anchors = SM_ANCHOR.ALL; * var strechVerticallyLabel = form.newLabel('Strech vertically', 10, 10, 190, 280); * strechVerticallyLabel.background = 'green'; * strechVerticallyLabel.anchors = SM_ANCHOR.WEST | SM_ANCHOR.NORTH | SM_ANCHOR.SOUTH; * var strechHorizontallyLabel = form.newLabel('Strech horizontally', 10, 10, 380, 140); * strechHorizontallyLabel.background = 'blue'; * strechHorizontallyLabel.anchors = SM_ANCHOR.NORTH | SM_ANCHOR.WEST | SM_ANCHOR.EAST; * var stickToTopLeftCornerLabel = form.newLabel('Stick to top-left corner', 10, 10, 200, 100); * stickToTopLeftCornerLabel.background = 'orange'; * stickToTopLeftCornerLabel.anchors = SM_ANCHOR.NORTH | SM_ANCHOR.WEST; // This is equivalent to SM_ANCHOR.DEFAULT * var stickToBottomRightCornerLabel = form.newLabel('Stick to bottom-right corner', 190, 190, 200, 100); * stickToBottomRightCornerLabel.background = 'pink'; * stickToBottomRightCornerLabel.anchors = SM_ANCHOR.SOUTH | SM_ANCHOR.EAST; */ @JSGetter public int getAnchors() { int anchors = getBaseComponent(false).getAnchors(); if (anchors <= 0) return IAnchorConstants.DEFAULT; return anchors; } @JSSetter public void setAnchors(int arg) { int anchors = arg; // if default is set just reset it really back to 0 so that default is always used. if (arg == IAnchorConstants.DEFAULT) { anchors = 0; } getBaseComponent(true).setAnchors(anchors); } /** * The Z index of this component. If two components overlap, * then the component with higher Z index is displayed above * the component with lower Z index. * * @sample * var labelBelow = form.newLabel('Green', 10, 10, 100, 50); * labelBelow.background = 'green'; * labelBelow.formIndex = 10; * var fieldAbove = form.newField('parent_table_text', JSField.TEXT_FIELD, 10, 10, 100, 30); * fieldAbove.background = '#FF0000'; * fieldAbove.formIndex = 20; */ @JSGetter public int getFormIndex() { return getBaseComponent(false).getFormIndex(); } @JSSetter public void setFormIndex(int arg) { getBaseComponent(true).setFormIndex(arg); } /** * @sameas com.servoy.j2db.solutionmodel.ISMPortal#setX(int) */ @JSGetter public int getX() { return getBaseComponent(false).getLocation().x; } @JSSetter public void setX(int x) { getBaseComponent(true).setLocation(new Point(x, getBaseComponent(true).getLocation().y)); } /** * @clonedesc com.servoy.j2db.solutionmodel.ISMPortal#setY(int) * * @sampleas getX() */ @JSGetter public int getY() { return getBaseComponent(false).getLocation().y; } @JSSetter public void setY(int y) { getBaseComponent(true).setLocation(new Point(getBaseComponent(true).getLocation().x, y)); } /** * @clonedesc com.servoy.j2db.persistence.BaseComponent#getName() * * @sample * var form = solutionModel.newForm('someForm', 'db:/example_data/parent_table', null, false, 620, 300); * var label = form.newLabel('Label', 10, 10, 150, 150); * label.name = 'myLabel'; // Give a name to the component. * forms['someForm'].controller.show() * // Now use the name to access the component. * forms['someForm'].elements['myLabel'].text = 'Updated text'; */ @JSGetter public String getName() { return getBaseComponent(false).getName(); } @JSSetter public void setName(String arg) { getBaseComponent(true).setName(arg); } /** * @clonedesc com.servoy.j2db.persistence.BaseComponent#getPrintable() * * @sample * var form = solutionModel.newForm('printForm', 'db:/example_data/parent_table', null, false, 400, 300); * var printedField = form.newField('parent_table_text', JSField.TEXT_FIELD, 10, 10, 100, 20); * var notPrintedField = form.newField('parent_table_id', JSField.TEXT_FIELD, 10, 40, 100, 20); * notPrintedField.printable = false; // This field won't show up in print preview and won't be printed. * forms['printForm'].controller.showPrintPreview() */ @JSGetter @ServoyClientSupport(ng = false, wc = true, sc = true) public boolean getPrintable() { return getBaseComponent(false).getPrintable(); } @JSSetter @ServoyClientSupport(ng = false, wc = true, sc = true) public void setPrintable(boolean arg) { getBaseComponent(true).setPrintable(arg); } /** * @clonedesc com.servoy.j2db.persistence.BaseComponent#getEnabled() * * @sample * var form = solutionModel.newForm('printForm', 'db:/example_data/parent_table', null, false, 400, 300); * var field = form.newField('parent_table_text', JSField.TEXT_FIELD, 10, 10, 100, 20); * field.enabled = false; */ @JSGetter public boolean getEnabled() { return getBaseComponent(false).getEnabled(); } @JSSetter public void setEnabled(boolean arg) { getBaseComponent(true).setEnabled(arg); } /** * @clonedesc com.servoy.j2db.persistence.BaseComponent#getVisible() * * @sample * var form = solutionModel.newForm('printForm', 'db:/example_data/parent_table', null, false, 400, 300); * var field = form.newField('parent_table_text', JSField.TEXT_FIELD, 10, 10, 100, 20); * field.visible = false; */ @JSGetter public boolean getVisible() { return getBaseComponent(false).getVisible(); } @JSSetter public void setVisible(boolean arg) { getBaseComponent(true).setVisible(arg); } /** * The width in pixels of the component. * * @sample * var field = form.newField('parent_table_text', JSField.TEXT_FIELD, 10, 10, 100, 20); * application.output('original width: ' + field.width); * application.output('original height: ' + field.height); * field.width = 200; * field.height = 100; * application.output('modified width: ' + field.width); * application.output('modified height: ' + field.height); */ @JSGetter public int getWidth() { return getBaseComponent(false).getSize().width; } @JSSetter public void setWidth(int width) { getBaseComponent(true).setSize(new Dimension(width, getBaseComponent(true).getSize().height)); } /** * The height in pixels of the component. * * @sampleas getWidth() */ @JSGetter public int getHeight() { return getBaseComponent(false).getSize().height; } @JSSetter public void setHeight(int height) { getBaseComponent(true).setSize(new Dimension(getBaseComponent(true).getSize().width, height)); } /** * A String representing a group ID for this component. If several * components have the same group ID then they belong to the same * group of components. Using the group itself, all components can * be disabled/enabled or made invisible/visible. * The group id should be a javascript compatible identifier to allow access of the group in scripting. * * @sample * var form = solutionModel.newForm('someForm', 'db:/example_data/parent_table', null, false, 400, 300); * var label = form.newLabel('Green', 10, 10, 100, 20); * var field = form.newField('parent_table_text', JSField.TEXT_FIELD, 10, 40, 100, 20); * label.groupID = 'someGroup'; * field.groupID = 'someGroup'; * forms['someForm'].elements.someGroup.enabled = false; */ @JSGetter public String getGroupID() { return getBaseComponent(false).getGroupID(); } @JSSetter public void setGroupID(String arg) { getBaseComponent(true).setGroupID(arg); } /** Get a design-time property of an element. * * @sample * var frm = solutionModel.getForm('orders') * var fld = frm.getField('fld') * var prop = fld.getDesignTimeProperty('myprop') */ @JSFunction public Object getDesignTimeProperty(String key) { return Utils.parseJSExpression(getBaseComponent(false).getCustomDesignTimeProperty(key)); } /** Set a design-time property of an element. * * @sample * var frm = solutionModel.getForm('orders') * var fld = frm.getField('fld') * fld.putDesignTimeProperty('myprop', 'strawberry') */ @JSFunction public Object putDesignTimeProperty(String key, Object value) { return Utils.parseJSExpression(getBaseComponent(true).putCustomDesignTimeProperty(key, Utils.makeJSExpression(value))); } /** Clear a design-time property of an element. * * @sample * var frm = solutionModel.getForm('orders') * var fld = frm.getField('fld') * fld.removeDesignTimeProperty('myprop') */ @JSFunction public Object removeDesignTimeProperty(String key) { return putDesignTimeProperty(key, null); } /** Get the design-time properties of an element. * * @sample * var frm = solutionModel.getForm('orders') * var fld = frm.getField('fld') * var propNames = fld.getDesignTimePropertyNames() */ @JSFunction public String[] getDesignTimePropertyNames() { Map<String, Object> propsMap = getBaseComponent(false).getCustomDesignTimeProperties(); String[] designTimePropertyNames = new String[0]; if (propsMap != null) { designTimePropertyNames = propsMap.keySet().toArray(new String[propsMap.size()]); } return designTimePropertyNames; } /** * @see java.lang.Object#toString() */ @SuppressWarnings("nls") @Override public String toString() { T comp = getBaseComponent(false); Point loc = comp.getLocation(); Dimension dim = comp.getSize(); return getClass().getSimpleName() + "[name:" + comp.getName() + ",form:" + ((ISupportName)comp.getParent()).getName() + ",x:" + loc.x + ",y:" + loc.y + ",width:" + dim.width + ",height:" + dim.height + ']'; } /** * Returns the name of the form. (may be empty string as well) * * * @sample * var name = %%prefix%%%%elementName%%.getFormName(); * * @return The name of the form. */ @JSFunction public String getFormName() { IJSParent< ? > parent = getJSParent(); while (!(parent instanceof JSForm)) { parent = parent.getJSParent(); } return ((JSForm)parent).getName(); } }