/* * Copyright 2014-2015 CyberVision, Inc. * * 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 org.kaaproject.avro.ui.gwt.client.widget; import static org.kaaproject.avro.ui.gwt.client.util.Utils.isBlank; import org.kaaproject.avro.ui.gwt.client.AvroUiResources.AvroUiStyle; import org.kaaproject.avro.ui.gwt.client.input.HasInputEventHandlers; import org.kaaproject.avro.ui.gwt.client.input.InputEvent; import org.kaaproject.avro.ui.gwt.client.input.InputEventHandler; import org.kaaproject.avro.ui.gwt.client.util.Utils; import org.kaaproject.avro.ui.shared.StringField.InputType; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.FocusEvent; import com.google.gwt.event.dom.client.FocusHandler; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyPressEvent; import com.google.gwt.event.dom.client.KeyPressHandler; import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.event.dom.client.KeyUpHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HasValue; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.PasswordTextBox; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.VerticalPanel; public class SizedTextBox extends VerticalPanel implements HasValue<String>, HasInputEventHandlers { private TextBox text; private HTML textLabel; private Label charactersLabel; private final int maxChars; private final boolean editable; private final AvroUiStyle style; private static AvroUiStyle getDefaultStyle() { return Utils.avroUiStyle; } public SizedTextBox(int maxChars, InputType inputType, String prompt) { this(getDefaultStyle(), inputType, prompt, maxChars); } public SizedTextBox(int maxChars, InputType inputType, String prompt, boolean editable) { this(getDefaultStyle(), inputType, prompt, maxChars, editable, true); } public SizedTextBox(int maxChars, InputType inputType, String prompt, boolean editable, boolean addNotes) { this(getDefaultStyle(), inputType, prompt, maxChars, editable, addNotes); } public SizedTextBox(AvroUiStyle style, InputType inputType, String prompt, int maxChars) { this(style, inputType, prompt, maxChars, true, true); } public SizedTextBox(AvroUiStyle style, InputType inputType, String prompt, int maxChars, boolean editable) { this(style, inputType, prompt, maxChars, editable, true); } public SizedTextBox(AvroUiStyle style, InputType inputType, String prompt, int maxChars, boolean editable, boolean addNotes) { // Inject the stylesheet. this.style = style; this.style.ensureInjected(); this.maxChars = maxChars; this.editable = editable; if (editable) { if (inputType == InputType.PASSWORD) { text = new ExtendedPasswordTextBox(); } else { text = new ExtendedTextBox(prompt); } add(text); } else { textLabel = new HTML(" "); textLabel.setHeight("100%"); textLabel.setStyleName(this.style.secondaryLabel()); add(textLabel); } if (editable && maxChars > -1) { charactersLabel = new Label(); charactersLabel.setStyleName(this.style.fieldNotes()); text.setMaxLength(maxChars); add(charactersLabel); updateCharactersLabel(); } else if (addNotes) { add(new HTML(" ")); } addValueChangeHandler(new ValueChangeHandler<String>() { @Override public void onValueChange(ValueChangeEvent<String> event) { fireInputEvent(); } }); if (editable) { text.addKeyUpHandler(new KeyUpHandler() { @Override public void onKeyUp(KeyUpEvent event) { updateCharactersLabel(); fireInputEvent(); } }); } } private void updateCharactersLabel() { if (editable && maxChars > -1) { int currentLength = text.getText().length(); charactersLabel.setText(Utils.messages.charactersLength(String.valueOf(currentLength), String.valueOf(maxChars))); } } @Override public HandlerRegistration addValueChangeHandler( ValueChangeHandler<String> handler) { if (editable) { return text.addValueChangeHandler(handler); } else { return null; } } @Override public String getValue() { if (editable) { return text.getValue(); } else { if (textLabel.getHTML().equals(" ")) { return ""; } else { return textLabel.getText(); } } } @Override public void setValue(String value) { if (editable) { text.setValue(value); } else { if (isBlank(value)) { textLabel.setHTML(" "); } else { textLabel.setText(value); } } updateCharactersLabel(); } @Override public void setValue(String value, boolean fireEvents) { if (editable) { text.setValue(value, fireEvents); } else { textLabel.setText(value); } } public void setFocus(boolean focused) { if (editable) { text.setFocus(focused); } } public void setWidth(String width) { super.setWidth(width); if (editable) { text.setWidth(width); } else { textLabel.setWidth(width); } } public void setHeight(String height) { super.setHeight(height); if (editable) { text.setHeight(height); } else { textLabel.setHeight(height); } } public void setEnabled(boolean enabled) { if (editable) { text.setEnabled(enabled); } } public void setReadOnly(boolean readOnly) { if (editable) { text.setReadOnly(readOnly); } } public void setInvalid(boolean invalid) { if (editable) { if (invalid) { text.addStyleName(style.invalidField()); } else { text.removeStyleName(style.invalidField()); } } } private class ExtendedTextBox extends TextBox implements BlurHandler, FocusHandler, ClickHandler, KeyPressHandler { private String promptText; public ExtendedTextBox(String promptText) { super(); this.promptText = promptText; sinkEvents(Event.ONPASTE); if (Utils.isNotBlank(promptText)) { this.addKeyPressHandler(this); this.addFocusHandler(this); this.addClickHandler(this); this.addBlurHandler(this); setPrompts(); } } @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); switch (DOM.eventGetType(event)) { case Event.ONPASTE: Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { ValueChangeEvent.fire(ExtendedTextBox.this, getText()); } }); break; } } @Override public void onBlur(BlurEvent event) { if (Utils.isBlank(super.getText())) { setPrompts(); } } @Override public void onFocus(FocusEvent event) { this.setSelectionRange(0, 0); } @Override public void onClick(ClickEvent event) { if (promptText.equals(super.getText())) { removePrompts(); } } @Override public void onKeyPress(KeyPressEvent event) { if (promptText.equals(super.getText()) && !(event.getNativeEvent().getKeyCode() == KeyCodes.KEY_TAB)) { removePrompts(); } } @Override public String getText() { String text = super.getText(); if (Utils.isNotBlank(promptText) && promptText.equals(text)) { return ""; } else { return text; } } @Override public void setText(String text) { if (Utils.isNotBlank(promptText)) { if (Utils.isBlank(text)) { setPrompts(); } else { removePrompts(); super.setText(text); } } else { super.setText(text); } } private void setPrompts() { this.addStyleName(style.prompt()); super.setText(promptText); } private void removePrompts() { this.removeStyleName(style.prompt()); super.setText(""); } } private class ExtendedPasswordTextBox extends PasswordTextBox { public ExtendedPasswordTextBox() { super(); sinkEvents(Event.ONPASTE); } @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); switch (DOM.eventGetType(event)) { case Event.ONPASTE: Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { ValueChangeEvent.fire(ExtendedPasswordTextBox.this, getText()); } }); break; } } } private void fireInputEvent() { InputEvent event = new InputEvent(this); fireEvent(event); } @Override public HandlerRegistration addInputHandler(InputEventHandler handler) { return this.addHandler(handler, InputEvent.TYPE); } }