/* * Copyright 2009 Rodrigo Reyes reyes.rr at gmail dot com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package net.kornr.swit.site.buttoneditor; import java.awt.Color; import java.awt.Font; import java.awt.GradientPaint; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.regex.Pattern; import net.kornr.swit.button.AmazonianButton; import net.kornr.swit.button.ButtonResource; import net.kornr.swit.button.ButtonTemplate; import net.kornr.swit.button.GlassyButton; import net.kornr.swit.button.SoftShiningButton; import net.kornr.swit.button.VistafarianButton; import net.kornr.swit.button.WebTwoButton; import net.kornr.swit.button.effect.Effect; import net.kornr.swit.button.effect.ShadowBorder; import net.kornr.swit.site.BasePage; import net.kornr.swit.site.jquery.JQuery; import net.kornr.swit.site.jquery.colorpicker.ColorPickerField; import net.kornr.swit.site.util.MutableResourceReferenceLink; import net.kornr.swit.site.widget.EffectChoicePanel; import net.kornr.swit.util.Pair; import net.kornr.swit.wicket.border.TableImageBorder; import net.kornr.swit.wicket.border.graphics.GenericShadowBorder; import net.kornr.swit.wicket.border.graphics.RoundedBorderMaker; import net.kornr.swit.wicket.border.graphics.SizedBorder; import net.kornr.swit.wicket.layout.ColumnPanel; import net.kornr.swit.wicket.layout.LayoutInfo; import net.kornr.swit.wicket.layout.ThreeColumnsLayoutManager; import net.kornr.swit.wicket.layout.threecol.ThreeColumnsLayoutResource; import org.apache.wicket.Component; import org.apache.wicket.PageParameters; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormSubmitBehavior; import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; import org.apache.wicket.markup.html.IHeaderContributor; import org.apache.wicket.markup.html.IHeaderResponse; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.border.Border; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.ImageButton; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.image.Image; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.markup.html.panel.Fragment; import org.apache.wicket.model.IModel; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.protocol.http.WebRequest; import org.apache.wicket.protocol.http.WebRequestCycle; import org.apache.wicket.util.string.AppendingStringBuffer; import org.apache.wicket.util.value.ValueMap; public class ButtonEditor extends BasePage implements IHeaderContributor { static private Color s_blocColor = Color.white; static private Long s_border = RoundedBorderMaker.register(12, 3f, new Color(0xC5,0xC5,0xFF), s_blocColor); // new Color(0xF8,0xf8,0xf7)); static private Long s_shadow = GenericShadowBorder.register(s_border, 0, 0, 4f, null, Color.black); static private GradientPaint s_grad = new GradientPaint(new Point2D.Float(10,10), new Color(0xdaeaef), new Point2D.Float(10,80), Color.white); static private Long s_border2 = RoundedBorderMaker.register(5, 2, new Color(0xC5,0xC5,0xC5), s_grad); static private Long s_big = SizedBorder.register(s_border2, 1200, 800); static private Long s_border3 = RoundedBorderMaker.register(5, 2, new Color(0xC5,0xC5,0xC5), null); static private Font s_defaultButtonFont = new Font("Verdana", Font.BOLD, 24); static private net.kornr.swit.button.WebTwoButton s_buttonTemplate = new net.kornr.swit.button.WebTwoButton(new Color(0x7799DD)); static { s_buttonTemplate.setFont(new Font("Arial", Font.BOLD, 18)); s_buttonTemplate.setWidth(250); s_buttonTemplate.setHeight(24); s_buttonTemplate.setFontColor(new Color(0x000000)); s_buttonTemplate.setAutoExtend(Boolean.TRUE); s_buttonTemplate.setShadowDisplayed(Boolean.FALSE); s_buttonTemplate.addEffect(new ShadowBorder(3,0,0,Color.black)); s_buttonTemplate.setBaseColor(Color.white); s_buttonTemplate.setLineWidth(1); } static private ButtonTemplate s_logoTemplate = new VistafarianButton(new Color(0x7799DD)); static { s_logoTemplate.setFont(new Font("Verdana", Font.BOLD, 24)); s_logoTemplate.setWidth(600); s_logoTemplate.setHeight(24); s_logoTemplate.setFontColor(new Color(0xFFFFFF)); s_logoTemplate.setAutoExtend(Boolean.TRUE); s_logoTemplate.setShadowDisplayed(Boolean.TRUE); s_logoTemplate.addEffect(new ShadowBorder(6,0,0, new Color(0x222222))); } private LinkedList<Pair<String,WebMarkupContainer>> m_propertiesContainer = new LinkedList<Pair<String,WebMarkupContainer>>(); private List<ButtonDescriptor> s_buttons = Arrays.asList(new ButtonDescriptor[] { new ButtonDescriptor("Vistafarian 1", "Vistafarian with a single base color", VistafarianButton.class.getCanonicalName(), new ButtonProperty[] { new ButtonProperty("Base Color", "baseColor", "#999999", ButtonProperty.Type.TYPE_COLOR), new ButtonProperty("Round Size", "roundSize", new Float(5f), ButtonProperty.Type.TYPE_FLOAT) }), new ButtonDescriptor("Vistafarian 2", "Vistafarian with a two distinct colors", VistafarianButton.class.getCanonicalName(), new ButtonProperty[] { new ButtonProperty("Top Color", "topColor", "#9999DD", ButtonProperty.Type.TYPE_COLOR), new ButtonProperty("Bottom Color", "bottomColor", "#7744FF", ButtonProperty.Type.TYPE_COLOR), new ButtonProperty("Round Size", "roundSize", new Float(5f), ButtonProperty.Type.TYPE_FLOAT) }), new ButtonDescriptor("Amazonian", "Amazonian button", AmazonianButton.class.getCanonicalName(), new ButtonProperty[] { new ButtonProperty("Inner Color", "innerColor", "#fce000", ButtonProperty.Type.TYPE_COLOR), new ButtonProperty("Outer Color", "outerColor", "#fc8900", ButtonProperty.Type.TYPE_COLOR), new ButtonProperty("Invert Icon Position", "rightHanded", Boolean.FALSE, ButtonProperty.Type.TYPE_BOOLEAN) }), new ButtonDescriptor("WebTwo", "Web Two button", WebTwoButton.class.getCanonicalName(), new ButtonProperty[] { new ButtonProperty("Base Color", "baseColor", "#9855AA", ButtonProperty.Type.TYPE_COLOR) }), new ButtonDescriptor("Soft Shining", "Soft Shining Button", SoftShiningButton.class.getCanonicalName(), new ButtonProperty[] { new ButtonProperty("Base Color", "baseColor", "#DFDF77", ButtonProperty.Type.TYPE_COLOR), new ButtonProperty("Round Size", "roundSize", new Float(30f), ButtonProperty.Type.TYPE_FLOAT), new ButtonProperty("Border Size", "lineWidth", new Float(1.5f), ButtonProperty.Type.TYPE_FLOAT), new ButtonProperty("Border Color", "lineColor", "#DFDF77", ButtonProperty.Type.TYPE_COLOR) }), new ButtonDescriptor("GLASSY!", "Glassy Button", GlassyButton.class.getCanonicalName(), new ButtonProperty[] { new ButtonProperty("Base Color", "baseColor", "#666666", ButtonProperty.Type.TYPE_COLOR), new ButtonProperty("Round Size", "roundSize", new Float(30f), ButtonProperty.Type.TYPE_FLOAT), new ButtonProperty("Border Size", "lineWidth", new Float(1.5f), ButtonProperty.Type.TYPE_FLOAT), new ButtonProperty("Border Color", "lineColor", "#555555", ButtonProperty.Type.TYPE_COLOR) }) }); static private HashMap<String, ButtonTemplate> s_buttonsTemplates = new HashMap<String,ButtonTemplate>(); static private LayoutInfo s_layout = new LayoutInfo(LayoutInfo.UNIT_PERCENTAGE, 50, 50); static { ThreeColumnsLayoutResource.register(s_layout); s_layout.setRightColor(BasePage.getInnerColor()); s_layout.setLeftColor(BasePage.getInnerColor()); s_layout.setMiddleColor(BasePage.getInnerColor()); } final private ButtonProperty PROPERTY_FONT = new ButtonProperty("Font", "font", new Font("Arial", Font.BOLD, 18), ButtonProperty.Type.TYPE_FONT); final private ButtonProperty PROPERTY_WIDTH = new ButtonProperty("Width", "width", new Integer(300), ButtonProperty.Type.TYPE_INTEGER); final private ButtonProperty PROPERTY_HEIGHT = new ButtonProperty("Height", "height", new Integer(24), ButtonProperty.Type.TYPE_INTEGER); final private ButtonProperty PROPERTY_AUTO_EXTEND = new ButtonProperty("Auto-extend the button size", "autoExtend", Boolean.TRUE, ButtonProperty.Type.TYPE_BOOLEAN); final private ButtonProperty PROPERTY_FONT_COLOR = new ButtonProperty("Text Color", "fontColor", "#FFFFFF", ButtonProperty.Type.TYPE_COLOR); final private ButtonProperty PROPERTY_FONT_SHADOW = new ButtonProperty("Add a drop shadow to the text", "shadowDisplayed", Boolean.TRUE, ButtonProperty.Type.TYPE_BOOLEAN); final private static Pattern s_filenamePattern = Pattern.compile("[^a-zA-Z0-9]"); private ButtonDescriptor m_selectedDescriptor = s_buttons.get(0); private String m_text = "Your Text Here"; private Image m_sample; private FeedbackPanel m_feedback; private WebMarkupContainer m_properties; private WebMarkupContainer m_propEditors; private int m_shadowEffect = 1; private int m_mirrorEffect = 0; private ButtonCodeMaker m_codeEncoder; private MutableResourceReferenceLink m_downloadLink; private List<ButtonProperty> m_currentProperties = new LinkedList<ButtonProperty>(); private String bgcolor = "FFFFFF"; public List<ButtonDescriptor> getAvailableButtons() { return s_buttons; } public ButtonEditor(PageParameters params) { init(); } private void init() { this.innerAdd(new Image("logo", ButtonResource.getReference(), ButtonResource.getValueMap(s_logoTemplate, "The Swit Buttons Generator"))); m_codeEncoder = new ButtonCodeMaker(m_selectedDescriptor, m_currentProperties, new PropertyModel<String>(this, "text")); final Form form = new Form("form") { @Override protected void onSubmit() { if (((WebRequest)(WebRequestCycle.get().getRequest())).isAjax() == false) createButton(null); } }; this.innerAdd(form); Border sampleborder = new TableImageBorder("sampleborder", s_border3, Color.white); form.add(sampleborder); WebMarkupContainer samplecont = new WebMarkupContainer("samplecontainer"); sampleborder.add(samplecont); samplecont.add((m_sample = new Image("sample")).setOutputMarkupId(true)); sampleborder.add(new ColorPickerField("samplebgcolor", new PropertyModel<String>(this, "bgcolor"), samplecont)); ImageButton submit = new ImageButton("submit", ButtonResource.getReference(), ButtonResource.getValueMap(s_buttonTemplate, "Update that button, now!")); sampleborder.add(submit); submit.add(new AjaxFormSubmitBehavior(form, "onclick") { @Override protected void onError(AjaxRequestTarget arg0) { } @Override protected void onSubmit(AjaxRequestTarget target) { createButton(target); } @Override protected CharSequence getEventHandler() { return new AppendingStringBuffer(super.getEventHandler()).append("; return false;"); } }); sampleborder.add(m_downloadLink = new MutableResourceReferenceLink("downloadbutton", ButtonResource.getReference(), null)); m_downloadLink.setOutputMarkupId(true); // this.innerAdd(m_codeLabel = new Label("code", new PropertyModel(m_codeEncoder, "code"))); // m_codeLabel.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true).setEscapeModelStrings(false); // m_codeLabel.setVisible(true); final ModalWindow codewindow = new ModalWindow("code"); this.innerAdd(codewindow); Fragment codefrag = new Fragment(codewindow.getContentId(), "codepanel", this); Label lcode = new Label("code", new PropertyModel(m_codeEncoder, "code")); codefrag.add(lcode); codewindow.setContent(codefrag); codewindow.setTitle("Java Code"); codewindow.setCookieName("switjavacodewindow"); sampleborder.add(new AjaxLink("showwindowcode") { @Override public void onClick(AjaxRequestTarget target) { codewindow.show(target); } }); form.add((m_feedback = new FeedbackPanel("feedback")).setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true)); ThreeColumnsLayoutManager layout = new ThreeColumnsLayoutManager("2col-layout", s_layout); form.add(layout); ColumnPanel rightcol = layout.getRightColumn(); ColumnPanel leftcol = layout.getLeftColumn(); Border textborder = new TableImageBorder("textborder", s_shadow, s_blocColor); layout.add(textborder); textborder.add(new TextField<String>("button-text", new PropertyModel<String>(this, "text"))); Border buttonsborder = new TableImageBorder("buttonsborder", s_shadow, s_blocColor); layout.add(buttonsborder); buttonsborder.add(new ListView<ButtonDescriptor>("types", s_buttons) { @Override protected void populateItem(ListItem<ButtonDescriptor> item) { final IModel<ButtonDescriptor> model = item.getModel(); ButtonDescriptor bd = item.getModelObject(); ButtonTemplate tmpl = s_buttonsTemplates.get(bd.getName()); if (tmpl == null) { tmpl = bd.createTemplate(); try { List<ButtonProperty> props = bd.getProperties(); bd.applyProperties(tmpl, props); tmpl.setWidth(200); tmpl.setFont(s_defaultButtonFont); tmpl.setFontColor(Color.white); tmpl.setShadowDisplayed(true); tmpl.addEffect(new ShadowBorder(4, 0, 0, Color.black)); tmpl.setAutoExtend(true); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } s_buttonsTemplates.put(bd.getName(), tmpl); } ImageButton button = new ImageButton("sample", ButtonResource.getReference(), ButtonResource.getValueMap(tmpl, bd.getName())); item.add(button); button.add(new AjaxFormSubmitBehavior(form, "onclick") { @Override protected void onError(AjaxRequestTarget arg0) { } @Override protected void onSubmit(AjaxRequestTarget target) { m_selectedDescriptor = model.getObject(); m_currentProperties = m_selectedDescriptor.getProperties(); if (target != null) { // target.addComponent(m_properties); } createButton(target); } @Override protected CharSequence getEventHandler() { String hider = getJQueryCodeForPropertiesHiding(model.getObject()); return new AppendingStringBuffer(hider+";"+super.getEventHandler()).append("; return false;"); } }); } }); m_properties = new TableImageBorder("propertiesborder", s_shadow, s_blocColor); layout.add(m_properties); m_properties.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true); m_currentProperties = m_selectedDescriptor.getProperties(); m_propEditors = new ListView<ButtonDescriptor>("property", s_buttons) { @Override protected void populateItem(ListItem<ButtonDescriptor> item) { ButtonDescriptor desc = item.getModelObject(); WebMarkupContainer container = new WebMarkupContainer("container"); item.add(container); PropertyListEditor lst = new PropertyListEditor("lst", desc.getProperties()); container.add(lst); container.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true); m_propertiesContainer.add(new Pair(desc.getName(), container)); } }; m_properties.add(m_propEditors); // Border fontborder = new TableImageBorder("fontborder", s_shadow, s_blocColor); // form.add(fontborder); // fontborder.add(new ButtonPropertyEditorPanel("fontselector", PROPERTY_FONT, false)); // fontborder.add(new ButtonPropertyEditorPanel("fontcolor", PROPERTY_FONT_COLOR, false)); // fontborder.add(new ButtonPropertyEditorPanel("fontshadow", PROPERTY_FONT_SHADOW, true)); rightcol.addContent(createFragment(ColumnPanel.CONTENT_ID, Arrays.asList(new Component[] { new ButtonPropertyEditorPanel("element", PROPERTY_WIDTH, true), new ButtonPropertyEditorPanel("element", PROPERTY_HEIGHT, true), new ButtonPropertyEditorPanel("element", PROPERTY_AUTO_EXTEND, true) }), "Button Size")); rightcol.addContent(createFragment(rightcol.CONTENT_ID, Arrays.asList(new Component[] { new ButtonPropertyEditorPanel("element", PROPERTY_FONT, false), new ButtonPropertyEditorPanel("element", PROPERTY_FONT_COLOR, true), new ButtonPropertyEditorPanel("element", PROPERTY_FONT_SHADOW, true) }), "Font Selection")); rightcol.addContent(createFragment(rightcol.CONTENT_ID, new EffectChoicePanel("element", new PropertyModel<Integer>(this, "shadowEffect"), EffectUtils.getShadowEffects()), "Shadow Effect")); rightcol.addContent(createFragment(rightcol.CONTENT_ID, new EffectChoicePanel("element", new PropertyModel<Integer>(this, "mirrorEffect"), EffectUtils.getMirrorEffects()), "Mirror Effect")); createButton(null); } public ButtonDescriptor getSelectedDescriptor() { return m_selectedDescriptor; } public void setSelectedDescriptor(ButtonDescriptor selectedDescriptor) { m_selectedDescriptor = selectedDescriptor; } public String getText() { return m_text; } public void setText(String text) { m_text = text; } private void createButton(AjaxRequestTarget target) { ButtonDescriptor desc = m_selectedDescriptor; if (desc == null) { error("Please select a template"); } else { ButtonTemplate bt = desc.createTemplate(); try { desc.applyProperties(bt, m_currentProperties); LinkedList<ButtonProperty> props = new LinkedList<ButtonProperty>(); props.add(PROPERTY_FONT); props.add(PROPERTY_WIDTH); props.add(PROPERTY_HEIGHT); props.add(PROPERTY_FONT_COLOR); props.add(PROPERTY_AUTO_EXTEND); props.add(PROPERTY_FONT_SHADOW); desc.applyProperties(bt, props); Effect e = EffectUtils.getShadowEffect(m_shadowEffect); if (e != null) bt.addEffect(e); e= EffectUtils.getMirrorEffect(m_mirrorEffect); if (e != null) bt.addEffect(e); LinkedList<String> effects = new LinkedList<String>(); String shadow = EffectUtils.getShadowJavaCode(m_shadowEffect); String mirror = EffectUtils.getMirrorJavaCode(m_mirrorEffect); if (shadow != null) effects.add(shadow); if (mirror != null) effects.add(mirror); m_codeEncoder.setClassProperties(m_currentProperties); m_codeEncoder.setDescriptor(desc); m_codeEncoder.setProperties(props); m_codeEncoder.setEffects(effects); } catch (Exception exc) { exc.printStackTrace(); } String text = m_text!=null?m_text:"(empty)"; String filename = s_filenamePattern.matcher(text).replaceAll(""); if (filename.length()==0) filename="image"; m_sample.setImageResourceReference(ButtonResource.getReference(), ButtonResource.getTemporaryValueMap(bt, text, false)); m_downloadLink.setResourceParameters(ButtonResource.getTemporaryValueMap(bt, text, true, filename)); } if (target != null) { target.addComponent(m_downloadLink); // target.addComponent(m_codeLabel); target.addComponent(m_sample); target.addComponent(m_feedback); } } public List<ButtonProperty> getCurrentProperties() { return m_currentProperties; } public void setCurrentProperties(List<ButtonProperty> currentProperties) { m_currentProperties = currentProperties; } public int getShadowEffect() { return m_shadowEffect; } public void setShadowEffect(int shadowEffect) { m_shadowEffect = shadowEffect; } public int getMirrorEffect() { return m_mirrorEffect; } public void setMirrorEffect(int mirrorEffect) { m_mirrorEffect = mirrorEffect; } public void renderHead(IHeaderResponse response) { super.renderHead(response); response.renderJavascriptReference(JQuery.getReference()); response.renderJavascript(JQuery.getOnReadyScript(getJQueryCodeForPropertiesHiding(m_selectedDescriptor)), null); } public String getJQueryCodeForPropertiesHiding(ButtonDescriptor desc) { StringBuffer buffer = new StringBuffer(); for (Pair<String, WebMarkupContainer>p : m_propertiesContainer) { if (p.getFirst().equals(desc.getName())) buffer.append("$('#" + p.getSecond().getMarkupId()+"').show();"); else buffer.append("$('#" + p.getSecond().getMarkupId()+"').hide();"); } return buffer.toString(); } private Fragment createFragment(String id, Component comp, String title) { ArrayList<Component> arr = new ArrayList<Component>(1); arr.add(comp); return createFragment(id, arr, title); } private Fragment createFragment(String id, List<Component> comps, String title) { Fragment frag = new Fragment(id, "logicalelementlist", this); Border border = new TableImageBorder("border", s_shadow, s_blocColor); frag.add(border); if (title == null) border.add(new Label("title", "").setVisible(false)); else border.add(new Label("title", title)); border.add(new ListView<Component>("list", comps) { @Override protected void populateItem(ListItem<Component> item) { item.add(item.getModelObject()); } }); return frag; } }