diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..ea5647b --- /dev/null +++ b/build.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugin-widget-digitroll.iml b/plugin-widget-digitroll.iml new file mode 100644 index 0000000..20fe623 --- /dev/null +++ b/plugin-widget-digitroll.iml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..fbbb73d --- /dev/null +++ b/plugin.xml @@ -0,0 +1,29 @@ + + + com.fr.plugin.widget.digitroll + + yes + 1.0 + 8.0 + 2017-8-05 + Felix + + [2018-07-13]Felix:首发

+ ]]>
+ + + + + + + + + + + + + + +
+ diff --git a/src/com/fr/plugin/widget/digitroll/Constants.java b/src/com/fr/plugin/widget/digitroll/Constants.java new file mode 100644 index 0000000..41ddfcf --- /dev/null +++ b/src/com/fr/plugin/widget/digitroll/Constants.java @@ -0,0 +1,6 @@ +package com.fr.plugin.widget.digitroll; + +public class Constants { + public static final String PLUGIN_ID = "com.fr.plugin.widget.digitroll"; + +} diff --git a/src/com/fr/plugin/widget/digitroll/CssFileHandler.java b/src/com/fr/plugin/widget/digitroll/CssFileHandler.java new file mode 100644 index 0000000..0ca2bdb --- /dev/null +++ b/src/com/fr/plugin/widget/digitroll/CssFileHandler.java @@ -0,0 +1,10 @@ +package com.fr.plugin.widget.digitroll; + +import com.fr.stable.fun.impl.AbstractCssFileHandler; + +public class CssFileHandler extends AbstractCssFileHandler { + @Override + public String[] pathsForFiles() { + return new String[]{""}; + } +} diff --git a/src/com/fr/plugin/widget/digitroll/JavaScriptFileLoader.java b/src/com/fr/plugin/widget/digitroll/JavaScriptFileLoader.java new file mode 100644 index 0000000..38f375d --- /dev/null +++ b/src/com/fr/plugin/widget/digitroll/JavaScriptFileLoader.java @@ -0,0 +1,15 @@ +package com.fr.plugin.widget.digitroll; + +import com.fr.stable.fun.Authorize; +import com.fr.stable.fun.impl.AbstractJavaScriptFileHandler; + +@Authorize( + callSignKey = Constants.PLUGIN_ID +) +public class JavaScriptFileLoader extends AbstractJavaScriptFileHandler { + @Override + public String[] pathsForFiles() { + return new String[]{ + "/com/fr/plugin/widget/digitroll/web/widget.digitRoll.js"}; + } +} diff --git a/src/com/fr/plugin/widget/digitroll/LocaleFinder.java b/src/com/fr/plugin/widget/digitroll/LocaleFinder.java new file mode 100644 index 0000000..dee40a8 --- /dev/null +++ b/src/com/fr/plugin/widget/digitroll/LocaleFinder.java @@ -0,0 +1,10 @@ +package com.fr.plugin.widget.digitroll; + +import com.fr.stable.fun.impl.AbstractLocaleFinder; + +public class LocaleFinder extends AbstractLocaleFinder { + @Override + public String find() {//查找字符串,类似于android的value + return "com/fr/plugin/widget/digitroll/locale/digitroll"; + } +} diff --git a/src/com/fr/plugin/widget/digitroll/OptionProvider.java b/src/com/fr/plugin/widget/digitroll/OptionProvider.java new file mode 100644 index 0000000..e48355a --- /dev/null +++ b/src/com/fr/plugin/widget/digitroll/OptionProvider.java @@ -0,0 +1,53 @@ +package com.fr.plugin.widget.digitroll; +import com.fr.design.fun.impl.AbstractFormWidgetOptionProvider; +import com.fr.form.ui.Widget; +import com.fr.general.Inter; +import com.fr.plugin.ExtraClassManager; +import com.fr.stable.fun.FunctionHelper; +import com.fr.stable.fun.FunctionProcessor; +import com.fr.stable.fun.impl.AbstractFunctionProcessor; + + +public class OptionProvider extends AbstractFormWidgetOptionProvider { + + private static FunctionProcessor ONEFUNCTION = new AbstractFunctionProcessor() { + public int getId() { + return FunctionHelper.generateFunctionID(Constants.PLUGIN_ID); + } + + public String toString() { + return Inter.getLocText("Plugin-DigitRoll_Widget"); + } + }; + + @Override + public Class classForWidget() { + FunctionProcessor processor = ExtraClassManager.getInstance().getFunctionProcessor(); + if (processor != null) { + processor.recordFunction(ONEFUNCTION); + } + + return Widget.class; + } + + @Override + public Class appearanceForWidget() { + //界面类 + return WidgetUI.class; + } + + @Override + public String iconPathForWidget() {//图标 + return "com/fr/plugin/widget/digitroll/images/digitroll_icon.png"; + } + + @Override + public String nameForWidget() {//插件名称 + return Inter.getLocText("Plugin-DigitRoll_Widget"); + } + + @Override + public boolean isContainer() {//是否容器 + return false; + } +} diff --git a/src/com/fr/plugin/widget/digitroll/Util.java b/src/com/fr/plugin/widget/digitroll/Util.java new file mode 100644 index 0000000..673fe73 --- /dev/null +++ b/src/com/fr/plugin/widget/digitroll/Util.java @@ -0,0 +1,33 @@ +package com.fr.plugin.widget.digitroll; + +import com.fr.base.FRContext; + +import java.math.BigDecimal; + +public class Util { + private Util() { + } + + public static String colorValueToHexString(int color) { + return '#' + Integer.toHexString(color).substring(2); + } + + public static int valueChangeToInt(Object o) { + int value = 0; + if (o instanceof Integer) { + value = ((Integer) o).intValue(); + } else if (o instanceof BigDecimal) { + value = ((BigDecimal) o).intValue(); + } else if (o instanceof Double) { + value = ((Double) o).intValue(); + } else if (o instanceof String) { + try { + value = Integer.parseInt(o.toString()); + } catch (Exception var4) { + FRContext.getLogger().error(var4.getMessage(), var4); + } + } + + return value; + } +} diff --git a/src/com/fr/plugin/widget/digitroll/Widget.java b/src/com/fr/plugin/widget/digitroll/Widget.java new file mode 100644 index 0000000..48628fc --- /dev/null +++ b/src/com/fr/plugin/widget/digitroll/Widget.java @@ -0,0 +1,321 @@ +package com.fr.plugin.widget.digitroll; + +import com.fr.base.FRContext; +import com.fr.base.Formula; +import com.fr.base.ParameterMapNameSpace; +import com.fr.form.data.DataBinding; +import com.fr.form.ui.DataControl; +import com.fr.form.ui.DirectWriteEditor; +import com.fr.form.ui.WidgetValue; +import com.fr.general.Inter; +import com.fr.general.ModuleContext; +import com.fr.json.JSONArray; +import com.fr.json.JSONException; +import com.fr.json.JSONObject; +import com.fr.plugin.PluginLicense; +import com.fr.plugin.PluginLicenseManager; +import com.fr.script.Calculator; +import com.fr.stable.ArrayUtils; +import com.fr.stable.CodeUtils; +import com.fr.stable.core.NodeVisitor; +import com.fr.stable.script.CalculatorProvider; +import com.fr.stable.web.Repository; +import com.fr.stable.xml.XMLPrintWriter; +import com.fr.stable.xml.XMLableReader; +import com.fr.web.core.SessionIDInfor; +import com.fr.web.utils.WebUtils; + +import javax.servlet.http.HttpServletRequest; +import java.awt.*; + + +public class Widget extends DirectWriteEditor implements DataControl { + public static final int TYPE_YEAR_NONE = 8; + public static final String ALIGN = "align"; + public static final String DURATION = "duration"; + public static final String FONT_SIZE = "fontSize"; + public static final String FONT_COLOR = "fontColor"; + public static final String BACKGROUND_COLOR = "backgroundColor"; + public static final String PREFIX = "prefix"; + public static final String SUFFIX = "suffix"; + public static final String CSS = "css"; + + private WidgetValue widgetValue = new WidgetValue(); + private String align = new String(); + private int duration = 0; + private int fontSize = 70; + private Object fontColor = new Color(204, 204, 204); + private Object backgroundColor = new Color(51, 51, 51); + private String prefix; + private String suffix; + + public Widget() { + } + + public String getAlign() { + return this.align; + } + + public void setAlign(String align) { + this.align = align; + } + + public int getDuration() { + return this.duration; + } + + public void setDuration(int duration) { + this.duration = duration; + } + + public WidgetValue getWidgetValue() { + return this.widgetValue; + } + + public void setWidgetValue(WidgetValue widgetValue) { + this.widgetValue = widgetValue; + } + + public int getFontSize() { + return fontSize; + } + + public void setFontSize(int fontSize) { + this.fontSize = fontSize; + } + + public Object getFontColor() { + return fontColor; + } + + public void setFontColor(Object fontColor) { + this.fontColor = fontColor; + } + + public Object getBackgroundColor() { + return backgroundColor; + } + + public void setBackgroundColor(Object backgroundColor) { + this.backgroundColor = backgroundColor; + } + + public String getPrefix() { + return prefix; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public String getSuffix() { + return suffix; + } + + public void setSuffix(String suffix) { + this.suffix = suffix; + } + + @Override + public String getXType() {//控件类型,参考其他的案例,返回的是文本框 + return "digitroll"; + } + + @Override + // 数据源类型:空置,公式,字段 + public int[] getValueType() { + return new int[]{TYPE_YEAR_NONE, TYPE_FORMULA, TYPE_DATABINDING}; + } + + @Override + public String[] dependence(CalculatorProvider calculatorProvider) { + return super.dependence(calculatorProvider); + } + + private int getWidgetValueFM(Calculator calculator) throws Exception { + int value = 0; + if (this.widgetValue.getValue() == null) { + value = 0; + } else if (this.widgetValue.getValue() instanceof Formula) { + Object v = calculator.eval((Formula) this.widgetValue.getValue()); + value = Util.valueChangeToInt(v); + } else if (this.widgetValue.getValue() instanceof DataBinding) { + value = this.getWidgetValueByBinding(calculator); + } + + return value; + } + + private int getWidgetValueByBinding(Calculator calculator) { + int value = 0; + WidgetValue.WidgetValueInfo valueInfo = new WidgetValue.WidgetValueInfo(this.getWidgetName()); + Object result = this.getWidgetValue().createAttrResult(valueInfo, calculator, new JSONObject()); + value = Util.valueChangeToInt(result); + return value; + } + + @Override + public void createValueResult(DataControl dataControl, Calculator calculator, + JSONObject jsonObject, JSONObject jsonObject1) { + if (this.getWidgetValue() != null) { + WidgetValue.WidgetValueInfo valueInfo = new WidgetValue.WidgetValueInfo(this.getWidgetName()); + Object result = this.getWidgetValue().createAttrResult(valueInfo, calculator, jsonObject1); + + try { + jsonObject.put(this.widgetName.toUpperCase(), result == null ? "" : result); + } catch (JSONException e) { + FRContext.getLogger().error(e.getMessage(), e); + } + } + } + + @Override + public String getFormatText() { + return ""; + } + + @Override + public JSONObject createJSONConfig(Repository repository, + Calculator calculator, + NodeVisitor visitor) throws JSONException { + // 许可证 + PluginLicense pluginLicense = PluginLicenseManager.getInstance().getPluginLicenseByID(Constants.PLUGIN_ID); + if (pluginLicense.isAvailable()) { + JSONObject jsonConfig = super.createJSONConfig(repository, calculator, visitor); + try { + Object value = jsonConfig.get("value"); + int v = Util.valueChangeToInt(value); + if (value == null) { + jsonConfig.remove("value"); + } else if (value instanceof String) { + jsonConfig.put("value", (new JSONObject()).put("digitroll", v)); + } else { + jsonConfig.put("value", v); + } + } catch (Exception e) { + e.printStackTrace(); + } + + if (this.align != null) { + jsonConfig.put(ALIGN, this.value2Config(this.align, calculator)); + } + + jsonConfig.put(DURATION, this.value2Config(this.duration, calculator)); + jsonConfig.put(PREFIX, getPrefix()); + jsonConfig.put(SUFFIX, getSuffix()); + jsonConfig.put(CSS, buildCss()); + + String[] dependence = this.dependence(calculator); + if (!ArrayUtils.isEmpty(dependence)) { + jsonConfig.put("dependence", dependence); + } + return jsonConfig; + } else { + return licenseErr(); + } + } + + private String buildCss() { + StringBuilder css = new StringBuilder(); + String fontClr = Util.colorValueToHexString(((Color) getFontColor()).getRGB()); + String bgClr = Util.colorValueToHexString(((Color) getBackgroundColor()).getRGB()); + css.append("color:" + fontClr + ';'); + css.append("font-size:" + getFontSize() + ';'); + css.append("background:" + bgClr + ";"); + css.append("position:absolute;"); + css.append("left:0px;"); + css.append("top:0px;"); + return css.toString(); + } + + @Override + public JSONArray createJSONData(SessionIDInfor sessionIDInfor, + Calculator calculator, HttpServletRequest request) throws Exception { + PluginLicense pluginLicense = PluginLicenseManager.getInstance().getPluginLicenseByID(Constants.PLUGIN_ID); + JSONArray errorMsg; + if (pluginLicense.isAvailable()) { + errorMsg = super.createJSONData(sessionIDInfor, calculator, request); + ParameterMapNameSpace parameterMapNameSpace = ParameterMapNameSpace.create(sessionIDInfor.getParameterMap4Execute()); + DependenceNameSpace dependenceNameSpace = new DependenceNameSpace(CodeUtils.cjkDecode(WebUtils.getHTTPRequestParameter(request, "dependence"))); + calculator.pushNameSpace(parameterMapNameSpace); + calculator.pushNameSpace(dependenceNameSpace); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("value", this.getWidgetValueFM(calculator)); + errorMsg.put(jsonObject); + calculator.removeNameSpace(parameterMapNameSpace); + calculator.removeNameSpace(dependenceNameSpace); + return errorMsg; + } else { + errorMsg = new JSONArray(); + errorMsg.put(licenseErr()); + return errorMsg; + } + } + + private JSONObject licenseErr() throws JSONException { + return (new JSONObject()).put("text", Inter.getLocText("Plugin-Flip_License_Expired")) + .put("value", Inter.getLocText("Plugin-Flip_License_Expired")); + } + + private boolean isDesign() { + return ModuleContext.isModuleStarted("com.fr.design.module.DesignerModule"); + } + + @Override + public String[] supportedEvents() { + return new String[0]; + } + + @Override + public void readXML(XMLableReader reader) { + super.readXML(reader); + if (reader.isChildNode()) { + String tagName = reader.getTagName(); + if (tagName.equals("DigitRollAttr")) { + String s = null; + if ((s = reader.getAttrAsString(ALIGN, null)) != null) { + this.setAlign(s); + } + if ((s = reader.getAttrAsString(DURATION, null)) != null) { + this.setDuration(Integer.parseInt(s)); + } + if ((s = reader.getAttrAsString(FONT_SIZE, null)) != null) { + setFontSize(Integer.parseInt(s)); + } + + int color; + if ((color = reader.getAttrAsInt(FONT_COLOR, -1)) != -1) { + setFontColor(new Color(color)); + } + if ((color = reader.getAttrAsInt(BACKGROUND_COLOR, -1)) != -1) { + setBackgroundColor(new Color(color)); + } + } else if ("widgetValue".equals(tagName)) { + this.widgetValue = new WidgetValue(); + reader.readXMLObject(this.widgetValue); + } + } + } + + @Override + public void writeXML(XMLPrintWriter writer) { + super.writeXML(writer); + writer.startTAG("DigitRollAttr"); + if (this.align != null) { + writer.attr(ALIGN, this.getAlign().toString()); + } + + if (this.duration != 0) { + writer.attr(DURATION, this.getDuration()); + } + + writer.attr(FONT_SIZE, getFontSize()); + writer.attr(FONT_COLOR, ((Color) getFontColor()).getRGB()); + writer.attr(BACKGROUND_COLOR, ((Color) getBackgroundColor()).getRGB()); + writer.end(); + + if (this.widgetValue != null) { + this.widgetValue.writeXML(writer); + } + } +} diff --git a/src/com/fr/plugin/widget/digitroll/WidgetUI.java b/src/com/fr/plugin/widget/digitroll/WidgetUI.java new file mode 100644 index 0000000..c372950 --- /dev/null +++ b/src/com/fr/plugin/widget/digitroll/WidgetUI.java @@ -0,0 +1,84 @@ +package com.fr.plugin.widget.digitroll; + +import com.fr.design.designer.creator.CRPropertyDescriptor; +import com.fr.design.designer.creator.XWidgetCreator; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.widget.editors.ColorEditor; +import com.fr.form.ui.Widget; +import com.fr.general.IOUtils; +import com.fr.general.Inter; +import com.fr.plugin.widget.digitroll.editor.DigitRollAlign; +import com.fr.plugin.widget.digitroll.editor.DigitRollDataSourceEditor; +import com.fr.stable.ArrayUtils; + +import javax.swing.*; +import java.awt.*; +import java.beans.IntrospectionException; + +public class WidgetUI extends XWidgetCreator { + private UITextField textField; + + public WidgetUI(Widget widget, Dimension dimension) { + super(widget, dimension); + } + + @Override + protected JComponent initEditor() { + //界面,就是在拖动到主面板上的时候,添加了一个LABLE控件,然后显示图标,并居中对齐 + if (this.editor == null) { + this.editor = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel label = new UILabel(); + label.setIcon(IOUtils.readIcon("/com/fr/plugin/widget/digitroll/images/digitroll_display.png")); + label.setHorizontalAlignment(0); + label.setVerticalAlignment(0); + this.editor.add(label, "Center"); + this.textField = new UITextField(5); + this.textField.setOpaque(false); + this.editor.add(this.textField, "South"); + this.editor.setBackground(Color.WHITE); + } + + return this.editor; + } + + public CRPropertyDescriptor[] supportedDescriptor() throws IntrospectionException { + return ArrayUtils.addAll(super.supportedDescriptor() + , new CRPropertyDescriptor[]{ + (new CRPropertyDescriptor("widgetValue", this.data.getClass())) + .setI18NName(Inter.getLocText("Plugin-DigitRoll_DataSource")) + .setEditorClass(DigitRollDataSourceEditor.class) + .putKeyValue("category", "Advanced"), + (new CRPropertyDescriptor("align", this.data.getClass())) + .setI18NName(Inter.getLocText("Plugin-DigitRoll_AlignType")) + .setEditorClass(DigitRollAlign.class) + .putKeyValue("category", "Advanced"), + (new CRPropertyDescriptor("duration", this.data.getClass())) + .setI18NName(Inter.getLocText("Plugin-DigitRoll_Duration")) + .putKeyValue("category", "Advanced"), + (new CRPropertyDescriptor("prefix", this.data.getClass())) + .setI18NName(Inter.getLocText("Plugin-DigitRoll_Prefix")) + .putKeyValue("category", "Advanced"), + (new CRPropertyDescriptor("suffix", this.data.getClass())) + .setI18NName(Inter.getLocText("Plugin-DigitRoll_Suffix")) + .putKeyValue("category", "Advanced"), + (new CRPropertyDescriptor("fontSize", this.data.getClass())) + .setI18NName(Inter.getLocText("Plugin-DigitRoll_FontSize")) + .putKeyValue("category", "Advanced"), + (new CRPropertyDescriptor("fontColor", this.data.getClass())) + .setI18NName(Inter.getLocText("Plugin-DigitRoll_ColorFont")) + .setEditorClass(ColorEditor.class) + .putKeyValue("category", "Advanced"), + (new CRPropertyDescriptor("backgroundColor", this.data.getClass())) + .setI18NName(Inter.getLocText("Plugin-DigitRoll_ColorBackground")) + .setEditorClass(ColorEditor.class) + .putKeyValue("category", "Advanced") + } + ); + } + + public String getIconPath() { + return "com/fr/plugin/widget/digitroll/images/digitroll_icon.png"; + } +} diff --git a/src/com/fr/plugin/widget/digitroll/editor/DigitRollAlign.java b/src/com/fr/plugin/widget/digitroll/editor/DigitRollAlign.java new file mode 100644 index 0000000..3944c31 --- /dev/null +++ b/src/com/fr/plugin/widget/digitroll/editor/DigitRollAlign.java @@ -0,0 +1,28 @@ +package com.fr.plugin.widget.digitroll.editor; + +import com.fr.design.mainframe.widget.editors.ComboEditor; +import com.fr.general.Inter; + +import javax.swing.*; +import java.util.Vector; + +public class DigitRollAlign extends ComboEditor { + public DigitRollAlign() { + } + + public ComboBoxModel model() { + Vector vector = new Vector(); + vector.add(Inter.getLocText("Plugin-DigitRoll_AlignLeft")); + vector.add(Inter.getLocText("Plugin-DigitRoll_AlignCenter")); + vector.add(Inter.getLocText("Plugin-DigitRoll_AlignRight")); + return new DefaultComboBoxModel(vector); + } + + /*public void setValue(Object o) { + this.comboBox.setSelectedItem(o); + }*/ + + /*public Object getValue() { + return this.comboBox.getSelectedItem(); + }*/ +} diff --git a/src/com/fr/plugin/widget/digitroll/editor/DigitRollDataSourceEditor.java b/src/com/fr/plugin/widget/digitroll/editor/DigitRollDataSourceEditor.java new file mode 100644 index 0000000..955852b --- /dev/null +++ b/src/com/fr/plugin/widget/digitroll/editor/DigitRollDataSourceEditor.java @@ -0,0 +1,88 @@ +package com.fr.plugin.widget.digitroll.editor; + +import com.fr.design.Exception.ValidationException; +import com.fr.design.editor.ValueEditorPane; +import com.fr.design.editor.editor.Editor; +import com.fr.design.editor.editor.FormulaEditor; +import com.fr.design.editor.editor.NoneEditor; +import com.fr.design.mainframe.widget.editors.AbstractPropertyEditor; +import com.fr.design.mainframe.widget.editors.DataBindingEditor; +import com.fr.design.mainframe.widget.editors.ServerDataBindingEditor; +import com.fr.form.ui.DataControl; +import com.fr.form.ui.WidgetValue; +import com.fr.general.Inter; + +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +public class DigitRollDataSourceEditor extends AbstractPropertyEditor { + private DataControl widget; + private ValueEditorPane wep; + + public DigitRollDataSourceEditor(Object o) { + this.widget = (DataControl) o; + Editor[] editors = createWidgetValueEditor(this.widget, false); + Editor[] editors1 = editors; + int length = editors.length; + + for (int i = 0; i < length; ++i) { + Editor e = editors1[i]; + e.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + DigitRollDataSourceEditor.this.firePropertyChanged(); + } + }); + } + + this.wep = new ValueEditorPane(editors); + this.wep.addPropertyChangeListener("value", new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + DigitRollDataSourceEditor.this.firePropertyChanged(); + } + }); + } + + public static Editor[] createWidgetValueEditor(DataControl data, boolean onlyServer) { + int[] types = data.getValueType(); + Editor[] editor = new Editor[types.length]; + + for (int i = 0; i < types.length; ++i) { + editor[i] = createWidgetValueEditorByType(types[i], onlyServer); + } + + return editor; + } + + public static Editor createWidgetValueEditorByType(int type, boolean onlyServer) { + switch (type) { + case 2: + return (Editor) (onlyServer ? new ServerDataBindingEditor() : new DataBindingEditor()); + case 3: + return new FormulaEditor(Inter.getLocText("Parameter-Formula")); + case 8: + return new NoneEditor((String) null, Inter.getLocText("Plugin-DigitRoll_None")); + default: + return null; + } + } + + public void validateValue() throws ValidationException { + } + + public Component getCustomEditor() { + return this.wep; + } + + public Object getValue() { + return new WidgetValue(this.wep.update()); + } + + public void setValue(Object value) { + if (value != null) { + this.wep.populate(((WidgetValue) value).getValue()); + } + } +} diff --git a/src/com/fr/plugin/widget/digitroll/images/digitroll_display.png b/src/com/fr/plugin/widget/digitroll/images/digitroll_display.png new file mode 100644 index 0000000..da530a2 Binary files /dev/null and b/src/com/fr/plugin/widget/digitroll/images/digitroll_display.png differ diff --git a/src/com/fr/plugin/widget/digitroll/images/digitroll_icon.png b/src/com/fr/plugin/widget/digitroll/images/digitroll_icon.png new file mode 100644 index 0000000..3ca516a Binary files /dev/null and b/src/com/fr/plugin/widget/digitroll/images/digitroll_icon.png differ diff --git a/src/com/fr/plugin/widget/digitroll/local/digitroll.properties b/src/com/fr/plugin/widget/digitroll/local/digitroll.properties new file mode 100644 index 0000000..c8daf03 --- /dev/null +++ b/src/com/fr/plugin/widget/digitroll/local/digitroll.properties @@ -0,0 +1,14 @@ +Plugin-DigitRoll_Widget=DigitRoll +Plugin-DigitRoll_License_Expired=Expired +Plugin-DigitRoll_DataSource=DataSource +Plugin-DigitRoll_AlignType=AlignType +Plugin-DigitRoll_Duration=Duration +Plugin-DigitRoll_Prefix=Prefix +Plugin-DigitRoll_Suffix=Suffix +Plugin-DigitRoll_None=NoneValue +Plugin-DigitRoll_AlignLeft=Left +Plugin-DigitRoll_AlignCenter=Center +Plugin-DigitRoll_AlignRight=Right +Plugin-DigitRoll_FontSize = FontSize +Plugin-DigitRoll_ColorFont=FontColor +Plugin-DigitRoll_ColorBackground=BackgroundColor diff --git a/src/com/fr/plugin/widget/digitroll/local/digitroll_zh_CN.properties b/src/com/fr/plugin/widget/digitroll/local/digitroll_zh_CN.properties new file mode 100644 index 0000000..d898e50 --- /dev/null +++ b/src/com/fr/plugin/widget/digitroll/local/digitroll_zh_CN.properties @@ -0,0 +1,14 @@ +Plugin-DigitRoll_Widget=\u6EDA\u52A8\u6570\u5B57 +Plugin-DigitRoll_License_Expired=\u8BB8\u53EF\u8BC1\u5DF2\u8FC7\u671F +Plugin-DigitRoll_DataSource=\u6570\u636E\u6E90 +Plugin-DigitRoll_AlignType=\u5BF9\u9F50\u65B9\u5F0F +Plugin-DigitRoll_Duration=\u6301\u7EED\u65F6\u95F4\uFF08\u79D2\uFF09 +Plugin-DigitRoll_Prefix=\u524D\u7F00 +Plugin-DigitRoll_Suffix=\u540E\u7F00 +Plugin-DigitRoll_None=\u7A7A\u503C +Plugin-DigitRoll_AlignLeft=\u5DE6\u5BF9\u9F50 +Plugin-DigitRoll_AlignCenter=\u5C45\u4E2D\u5BF9\u9F50 +Plugin-DigitRoll_AlignRight=\u53F3\u5BF9\u9F50 +Plugin-DigitRoll_FontSize = \u6587\u5B57\u5927\u5C0F +Plugin-DigitRoll_ColorFont=\u6587\u5B57\u989C\u8272 +Plugin-DigitRoll_ColorBackground=\u80CC\u666F\u989C\u8272 diff --git a/src/com/fr/plugin/widget/digitroll/web/countUp.js b/src/com/fr/plugin/widget/digitroll/web/countUp.js new file mode 100644 index 0000000..cf7523e --- /dev/null +++ b/src/com/fr/plugin/widget/digitroll/web/countUp.js @@ -0,0 +1,254 @@ +/* + + countUp.js + by @inorganik + +*/ + +// target = id of html element or var of previously selected html element where counting occurs +// startVal = the value you want to begin at +// endVal = the value you want to arrive at +// decimals = number of decimal places, default 0 +// duration = duration of animation in seconds, default 2 +// options = optional object of options (see below) + +var CountUp = function (target, startVal, endVal, decimals, duration, options) { + + var self = this; + self.version = function () { + return '1.9.3'; + }; + + // default options + self.options = { + useEasing: true, // toggle easing + useGrouping: true, // 1,000,000 vs 1000000 + separator: ',', // character to use as a separator + decimal: '.', // character to use as a decimal + easingFn: easeOutExpo, // optional custom easing function, default is Robert Penner's easeOutExpo + formattingFn: formatNumber, // optional custom formatting function, default is formatNumber above + prefix: '', // optional text before the result + suffix: '', // optional text after the result + numerals: [] // optionally pass an array of custom numerals for 0-9 + }; + + // extend default options with passed options object + if (options && typeof options === 'object') { + for (var key in self.options) { + if (options.hasOwnProperty(key) && options[key] !== null) { + self.options[key] = options[key]; + } + } + } + + if (self.options.separator === '') { + self.options.useGrouping = false; + } + else { + // ensure the separator is a string (formatNumber assumes this) + self.options.separator = '' + self.options.separator; + } + + // make sure requestAnimationFrame and cancelAnimationFrame are defined + // polyfill for browsers without native support + // by Opera engineer Erik Möller + var lastTime = 0; + var vendors = ['webkit', 'moz', 'ms', 'o']; + for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame']; + } + if (!window.requestAnimationFrame) { + window.requestAnimationFrame = function (callback, element) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currTime - lastTime)); + var id = window.setTimeout(function () { + callback(currTime + timeToCall); + }, timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + } + if (!window.cancelAnimationFrame) { + window.cancelAnimationFrame = function (id) { + clearTimeout(id); + }; + } + + function formatNumber(num) { + var neg = (num < 0), + x, x1, x2, x3, i, len; + num = Math.abs(num).toFixed(self.decimals); + num += ''; + x = num.split('.'); + x1 = x[0]; + x2 = x.length > 1 ? self.options.decimal + x[1] : ''; + if (self.options.useGrouping) { + x3 = ''; + for (i = 0, len = x1.length; i < len; ++i) { + if (i !== 0 && ((i % 3) === 0)) { + x3 = self.options.separator + x3; + } + x3 = x1[len - i - 1] + x3; + } + x1 = x3; + } + // optional numeral substitution + if (self.options.numerals.length) { + x1 = x1.replace(/[0-9]/g, function (w) { + return self.options.numerals[+w]; + }) + x2 = x2.replace(/[0-9]/g, function (w) { + return self.options.numerals[+w]; + }) + } + return (neg ? '-' : '') + self.options.prefix + x1 + x2 + self.options.suffix; + } + + // Robert Penner's easeOutExpo + function easeOutExpo(t, b, c, d) { + return c * (-Math.pow(2, -10 * t / d) + 1) * 1024 / 1023 + b; + } + + function ensureNumber(n) { + return (typeof n === 'number' && !isNaN(n)); + } + + self.initialize = function () { + if (self.initialized) return true; + + self.error = ''; + self.d = (typeof target === 'string') ? document.getElementById(target) : target; + if (!self.d) { + self.error = '[CountUp] target is null or undefined' + return false; + } + self.startVal = Number(startVal); + self.endVal = Number(endVal); + // error checks + if (ensureNumber(self.startVal) && ensureNumber(self.endVal)) { + self.decimals = Math.max(0, decimals || 0); + self.dec = Math.pow(10, self.decimals); + self.duration = Number(duration) * 1000 || 2000; + self.countDown = (self.startVal > self.endVal); + self.frameVal = self.startVal; + self.initialized = true; + return true; + } + else { + self.error = '[CountUp] startVal (' + startVal + ') or endVal (' + endVal + ') is not a number'; + return false; + } + }; + + // Print value to target + self.printValue = function (value) { + var result = self.options.formattingFn(value); + + if (self.d.tagName === 'INPUT') { + this.d.value = result; + } + else if (self.d.tagName === 'text' || self.d.tagName === 'tspan') { + this.d.textContent = result; + } + else { + this.d.innerHTML = result; + } + }; + + self.count = function (timestamp) { + + if (!self.startTime) { + self.startTime = timestamp; + } + + self.timestamp = timestamp; + var progress = timestamp - self.startTime; + self.remaining = self.duration - progress; + + // to ease or not to ease + if (self.options.useEasing) { + if (self.countDown) { + self.frameVal = self.startVal - self.options.easingFn(progress, 0, self.startVal - self.endVal, self.duration); + } else { + self.frameVal = self.options.easingFn(progress, self.startVal, self.endVal - self.startVal, self.duration); + } + } else { + if (self.countDown) { + self.frameVal = self.startVal - ((self.startVal - self.endVal) * (progress / self.duration)); + } else { + self.frameVal = self.startVal + (self.endVal - self.startVal) * (progress / self.duration); + } + } + + // don't go past endVal since progress can exceed duration in the last frame + if (self.countDown) { + self.frameVal = (self.frameVal < self.endVal) ? self.endVal : self.frameVal; + } else { + self.frameVal = (self.frameVal > self.endVal) ? self.endVal : self.frameVal; + } + + // decimal + self.frameVal = Math.round(self.frameVal * self.dec) / self.dec; + + // format and print value + self.printValue(self.frameVal); + + // whether to continue + if (progress < self.duration) { + self.rAF = requestAnimationFrame(self.count); + } else { + if (self.callback) self.callback(); + } + }; + // start your animation + self.start = function (callback) { + if (!self.initialize()) return; + self.callback = callback; + self.rAF = requestAnimationFrame(self.count); + }; + // toggles pause/resume animation + self.pauseResume = function () { + if (!self.paused) { + self.paused = true; + cancelAnimationFrame(self.rAF); + } else { + self.paused = false; + delete self.startTime; + self.duration = self.remaining; + self.startVal = self.frameVal; + requestAnimationFrame(self.count); + } + }; + // reset to startVal so animation can be run again + self.reset = function () { + self.paused = false; + delete self.startTime; + self.initialized = false; + if (self.initialize()) { + cancelAnimationFrame(self.rAF); + self.printValue(self.startVal); + } + }; + // pass a new endVal and start animation + self.update = function (newEndVal) { + if (!self.initialize()) return; + newEndVal = Number(newEndVal); + if (!ensureNumber(newEndVal)) { + self.error = '[CountUp] update() - new endVal is not a number: ' + newEndVal; + return; + } + self.error = ''; + if (newEndVal === self.frameVal) return; + cancelAnimationFrame(self.rAF); + self.paused = false; + delete self.startTime; + self.startVal = self.frameVal; + self.endVal = newEndVal; + self.countDown = (self.startVal > self.endVal); + self.rAF = requestAnimationFrame(self.count); + }; + + // format startVal on initialization + if (self.initialize()) self.printValue(self.startVal); +}; diff --git a/src/com/fr/plugin/widget/digitroll/web/widget.digitRoll.js b/src/com/fr/plugin/widget/digitroll/web/widget.digitRoll.js new file mode 100644 index 0000000..d337dcd --- /dev/null +++ b/src/com/fr/plugin/widget/digitroll/web/widget.digitRoll.js @@ -0,0 +1,43 @@ +; +(function ($) { + FR.DigitRoll = FR.extend(FR.Widget, { + _defaultConfig: function () { + return $.extend(FR.DigitRoll.superclass._defaultConfig.apply(), { + baseName: 'fr-digitRoll', + baseClass: 'fr-digitRoll' + }); + }, + + _init: function () { + FR.DigitRoll.superclass._init.apply(this, arguments); + FR.$defaultImport('/com/fr/plugin/widget/digitroll/web/countUp.js', 'js'); + var o = this.options; + var element = this.element; + var widget = '
'; + var widgetId = $(widget).appendTo(element); + o.options.prefix = o.prefix; + o.options.suffix = o.suffix; + var digitRoll = new CountUp(widgetId, 0, o.value, 0/*o.decimals*/, o.duration, o.options); + + var callback = function () { + $.ajax({ + type: "POST", + url: o.widgetUrl, + success: function (res) { + var data = FR.jsonDecode(res); + o.data = data[0]; + var v = data[0].value; + digitRoll.update(v); + } + }); + }; + if (!digitRoll.error) { + digitRoll.start(callback); + } else { + console.error(digitRoll.error); + } + } + }); + + $.shortcut("digitRoll", FR.DigitRoll); +})(jQuery); \ No newline at end of file