ingo@41: package de.intevation.flys.client.client.ui;
ingo@41:
ingo@43: import java.util.LinkedHashMap;
ingo@53: import java.util.List;
ingo@41:
ingo@41: import com.google.gwt.core.client.GWT;
ingo@41:
ingo@41: import com.smartgwt.client.widgets.Canvas;
ingo@45: import com.smartgwt.client.widgets.IButton;
ingo@41: import com.smartgwt.client.widgets.Label;
ingo@41: import com.smartgwt.client.widgets.form.DynamicForm;
ingo@41: import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
ingo@41: import com.smartgwt.client.widgets.form.fields.events.BlurEvent;
ingo@41: import com.smartgwt.client.widgets.form.fields.events.ChangeHandler;
ingo@41: import com.smartgwt.client.widgets.form.fields.events.ChangeEvent;
ingo@41: import com.smartgwt.client.widgets.form.fields.FormItem;
ingo@41: import com.smartgwt.client.widgets.form.fields.RadioGroupItem;
ingo@41: import com.smartgwt.client.widgets.layout.HLayout;
ingo@41: import com.smartgwt.client.widgets.layout.VLayout;
ingo@41:
ingo@41: import de.intevation.flys.client.shared.model.Data;
ingo@46: import de.intevation.flys.client.shared.model.DataItem;
ingo@51: import de.intevation.flys.client.shared.model.DataList;
ingo@46: import de.intevation.flys.client.shared.model.DefaultData;
ingo@46: import de.intevation.flys.client.shared.model.DefaultDataItem;
ingo@41: import de.intevation.flys.client.client.FLYSMessages;
ingo@41:
ingo@41:
ingo@41: /**
ingo@41: * This UIProvider creates a widget to enter locations or a distance.
ingo@41: *
ingo@41: * @author Ingo Weinzierl
ingo@41: */
ingo@41: public class LocationDistancePanel
ingo@41: extends AbstractUIProvider
ingo@41: implements ChangeHandler, BlurHandler
ingo@41: {
ingo@41: /** The message class that provides i18n strings.*/
ingo@41: protected FLYSMessages MESSAGES = GWT.create(FLYSMessages.class);
ingo@41:
ingo@41:
ingo@41: /** The constant name of the input field to enter locations.*/
ingo@41: public static final String FIELD_LOCATION = "location";
ingo@41:
ingo@43: /** The constant name of the input field to enter distance.*/
ingo@43: public static final String FIELD_DISTANCE = "distance";
ingo@43:
ingo@41: /** The constant name of the input field to enter the start of a distance.*/
ingo@41: public static final String FIELD_FROM = "from";
ingo@41:
ingo@41: /** The constant name of the input field to enter the end of a distance.*/
ingo@41: public static final String FIELD_TO = "to";
ingo@41:
ingo@41: /** The constant name of the input field to enter the step width of a
ingo@41: * distance.*/
ingo@41: public static final String FIELD_WIDTH = "width";
ingo@41:
ingo@53: public static final int WIDTH = 250;
ingo@53:
ingo@41:
ingo@41: /** The radio group for input mode selection.*/
ingo@43: protected DynamicForm mode;
ingo@41:
ingo@41: /** A container that will contain the location or the distance panel.*/
ingo@41: protected HLayout container;
ingo@41:
ingo@43: /** The 'from' value entered in the distance mode.*/
ingo@43: protected double from;
ingo@43:
ingo@43: /** The 'to' value entered in the distance mode.*/
ingo@43: protected double to;
ingo@43:
ingo@43: /** The 'step' value entered in the distance mode.*/
ingo@43: protected double step;
ingo@43:
ingo@43: /** The values entered in the location mode.*/
ingo@43: protected double[] values;
ingo@43:
ingo@41:
ingo@41: /**
ingo@41: * Creates a new LocationDistancePanel instance.
ingo@41: */
ingo@41: public LocationDistancePanel() {
ingo@41: }
ingo@41:
ingo@41:
ingo@41: /**
ingo@41: * This method creates a widget that contains a label, a panel with
ingo@41: * checkboxes to switch the input mode between location and distance input,
ingo@41: * and a the mode specific panel.
ingo@41: *
ingo@41: * @param data The data that might be inserted.
ingo@41: *
ingo@41: * @return a panel.
ingo@41: */
ingo@51: public Canvas create(DataList data) {
ingo@41: VLayout layout = new VLayout();
ingo@41:
ingo@45: Label label = new Label(MESSAGES.location_distance_state());
ingo@45: Canvas widget = createWidget(data);
ingo@45: IButton submit = new IButton(MESSAGES.next(), this);
ingo@41:
ingo@41: label.setHeight(25);
ingo@41:
ingo@41: layout.addMember(label);
ingo@45: layout.addMember(widget);
ingo@45: layout.addMember(submit);
ingo@45:
ingo@45: return layout;
ingo@45: }
ingo@45:
ingo@45:
ingo@53: public Canvas createOld(DataList dataList) {
ingo@53: List items = dataList.getAll();
ingo@53:
ingo@53: Data dFrom = getData(items, "ld_from");
ingo@53: Data dTo = getData(items, "ld_to");
ingo@53: Data dStep = getData(items, "ld_step");
ingo@53:
ingo@53: DataItem[] from = dFrom.getItems();
ingo@53: DataItem[] to = dTo.getItems();
ingo@53: DataItem[] step = dStep.getItems();
ingo@53:
ingo@53: HLayout layout = new HLayout();
ingo@53: Label label = new Label(dataList.getLabel());
ingo@53:
ingo@53: label.setWidth("50%");
ingo@53:
ingo@53: StringBuilder sb = new StringBuilder();
ingo@53: sb.append(from[0].getLabel());
ingo@53: sb.append(" " + MESSAGES.unitFrom() + " ");
ingo@53: sb.append(to[0].getLabel());
ingo@53: sb.append(" " + MESSAGES.unitTo() + " ");
ingo@53: sb.append(step[0].getLabel());
ingo@53: sb.append(" " + MESSAGES.unitWidth());
ingo@53:
ingo@53: layout.addMember(label);
ingo@53: layout.addMember(new Label(sb.toString()));
ingo@53:
ingo@53: return layout;
ingo@53: }
ingo@53:
ingo@53:
ingo@53: /**
ingo@53: * This method greps the Data with name name from the list and
ingo@53: * returns it.
ingo@53: *
ingo@53: * @param items A list of Data.
ingo@53: * @param name The name of the Data that we are searching for.
ingo@53: *
ingo@53: * @return the Data with the name name.
ingo@53: */
ingo@53: protected Data getData(List data, String name) {
ingo@53: for (Data d: data) {
ingo@53: if (name.equals(d.getLabel())) {
ingo@53: return d;
ingo@53: }
ingo@53: }
ingo@53:
ingo@53: return null;
ingo@53: }
ingo@53:
ingo@53:
ingo@51: protected Canvas createWidget(DataList data) {
ingo@45: VLayout layout = new VLayout();
ingo@45: container = new HLayout();
ingo@45: Canvas checkboxPanel = createRadioButtonPanel();
ingo@45:
ingo@45: // the initial view will display the location input mode
ingo@45: Canvas locationPanel = new DoubleArrayPanel(
ingo@45: MESSAGES.unitLocation(),
ingo@45: getLocationValues(),
ingo@45: this);
ingo@45: container.addMember(locationPanel);
ingo@45:
ingo@41: layout.addMember(checkboxPanel);
ingo@41: layout.addMember(container);
ingo@41:
ingo@41: // TODO Add a table on the right to select locations by mouse click
ingo@41:
ingo@41: return layout;
ingo@41: }
ingo@41:
ingo@41:
ingo@41: /**
ingo@41: * This method returns the selected data.
ingo@41: *
ingo@41: * @return the selected/inserted data.
ingo@41: */
ingo@41: public Data[] getData() {
ingo@46: return new Data[] { getDataFrom(), getDataTo(), getDataStep() };
ingo@46: }
ingo@41:
ingo@46:
ingo@46: /**
ingo@46: * Returns the Data object for the 'from' attribute.
ingo@46: *
ingo@46: * @return the Data object for the 'from' attribute.
ingo@46: */
ingo@46: protected Data getDataFrom() {
ingo@46: String value = Double.valueOf(getFinalFrom()).toString();
ingo@46: DataItem item = new DefaultDataItem("ld_from", "ld_from", value);
ingo@46: return new DefaultData(
ingo@51: "ld_from", null, null, new DataItem[] { item });
ingo@46: }
ingo@46:
ingo@46:
ingo@46: /**
ingo@46: * Returns the Data object for the 'to' attribute.
ingo@46: *
ingo@46: * @return the Data object for the 'to' attribute.
ingo@46: */
ingo@46: protected Data getDataTo() {
ingo@46: String value = Double.valueOf(getFinalTo()).toString();
ingo@46: DataItem item = new DefaultDataItem("ld_to", "ld_to", value);
ingo@46: return new DefaultData(
ingo@51: "ld_to", null, null, new DataItem[] { item });
ingo@46: }
ingo@46:
ingo@46:
ingo@46: /**
ingo@46: * Returns the Data object for the 'step' attribute.
ingo@46: *
ingo@46: * @return the Data object for the 'step' attribute.
ingo@46: */
ingo@46: protected Data getDataStep() {
ingo@46: String value = Double.valueOf(getFinalStep()).toString();
ingo@46: DataItem item = new DefaultDataItem("ld_step","ld_step", value);
ingo@46: return new DefaultData(
ingo@51: "ld_step", null, null, new DataItem[] { item });
ingo@46: }
ingo@46:
ingo@46:
ingo@46: /**
ingo@46: * Returns the value of 'from' depending on the selected input mode.
ingo@46: *
ingo@46: * @return the value of 'from' depending on the selected input mode.
ingo@46: */
ingo@46: protected double getFinalFrom() {
ingo@46: if (isLocationMode()) {
ingo@46: double[] values = getLocationValues();
ingo@46: double value = Double.MAX_VALUE;
ingo@46:
ingo@46: for (double v: values) {
ingo@46: value = value < v ? value : v;
ingo@46: }
ingo@46:
ingo@46: return value;
ingo@46: }
ingo@46: else {
ingo@46: return getFrom();
ingo@46: }
ingo@46: }
ingo@46:
ingo@46:
ingo@46: /**
ingo@46: * Returns the value of 'to' depending on the selected input mode.
ingo@46: *
ingo@46: * @return the value of 'to' depending on the selected input mode.
ingo@46: */
ingo@46: protected double getFinalTo() {
ingo@46: if (isLocationMode()) {
ingo@46: double[] values = getLocationValues();
ingo@46: double value = Double.MIN_VALUE;
ingo@46:
ingo@46: for (double v: values) {
ingo@46: value = value > v ? value : v;
ingo@46: }
ingo@46:
ingo@46: return value;
ingo@46: }
ingo@46: else {
ingo@46: return getTo();
ingo@46: }
ingo@46: }
ingo@46:
ingo@46:
ingo@46: /**
ingo@46: * Returns the value of 'step' depending on the selected input mode.
ingo@46: *
ingo@46: * @return the value of 'step' depending on the selected input mode.
ingo@46: */
ingo@46: protected double getFinalStep() {
ingo@46: if (isLocationMode()) {
ingo@46: // we have no field to enter the 'step' attribute in the location
ingo@46: // mode
ingo@46: return 0.0;
ingo@46: }
ingo@46: else {
ingo@46: return getStep();
ingo@46: }
ingo@46: }
ingo@46:
ingo@46:
ingo@46: /**
ingo@46: * Determines the current input mode.
ingo@46: *
ingo@46: * @return true, if 'location' is the current input mode, otherwise false.
ingo@46: */
ingo@46: public boolean isLocationMode() {
ingo@46: String inputMode = mode.getValueAsString("mode");
ingo@46:
ingo@46: return inputMode.equals(FIELD_LOCATION) ? true : false;
ingo@41: }
ingo@41:
ingo@41:
ingo@41: /**
ingo@41: * This method switches the input mode between location and distance input.
ingo@41: *
ingo@41: * @param event The click event fired by a RadioButtonGroupItem.
ingo@41: */
ingo@41: public void onChange(ChangeEvent event) {
ingo@41: String value = (String) event.getValue();
ingo@41:
ingo@41: if (value == null) {
ingo@41: return;
ingo@41: }
ingo@41:
ingo@43: if (value.equals(FIELD_LOCATION)) {
ingo@43: Canvas locationPanel = new DoubleArrayPanel(
ingo@43: MESSAGES.unitLocation(),
ingo@43: getLocationValues(),
ingo@43: this);
ingo@43:
ingo@41: container.removeMembers(container.getMembers());
ingo@41: container.addMember(locationPanel);
ingo@41: }
ingo@43: else {
ingo@43: Canvas distancePanel = new DoubleRangePanel(
ingo@43: MESSAGES.unitFrom(), MESSAGES.unitTo(), MESSAGES.unitWidth(),
ingo@43: getFrom(), getTo(), getStep(),
ingo@43: 250,
ingo@43: this);
ingo@43:
ingo@41: container.removeMembers(container.getMembers());
ingo@41: container.addMember(distancePanel);
ingo@41: }
ingo@41: }
ingo@41:
ingo@41:
ingo@41: /**
ingo@41: * This method is used to validate the inserted data in the form fields.
ingo@41: *
ingo@41: * @param event The BlurEvent that gives information about the FormItem that
ingo@41: * has been modified and its value.
ingo@41: */
ingo@41: public void onBlur(BlurEvent event) {
ingo@41: FormItem item = event.getItem();
ingo@41: String field = item.getFieldName();
ingo@41:
ingo@41: if (field == null) {
ingo@41: return;
ingo@41: }
ingo@41:
ingo@43: if (field.equals(DoubleArrayPanel.FIELD_NAME)) {
ingo@43: DoubleArrayPanel p = (DoubleArrayPanel) event.getForm();
ingo@41:
ingo@43: if (p.validateForm(item)) {
ingo@43: setLocationValues(p.getInputValues(item));
ingo@41: }
ingo@41: }
ingo@43: else {
ingo@43: DoubleRangePanel p = (DoubleRangePanel) event.getForm();
ingo@41:
ingo@43: if (p.validateForm(item)) {
ingo@43: setFrom(p.getFrom());
ingo@43: setTo(p.getTo());
ingo@43: setStep(p.getStep());
ingo@43: }
ingo@41: }
ingo@41: }
ingo@41:
ingo@41:
ingo@41: /**
ingo@41: * This method creates the panel that contains the checkboxes to switch
ingo@41: * between the input mode 'location' and 'distance'.
ingo@41: *
ingo@41: * @return the checkbox panel.
ingo@41: */
ingo@41: protected Canvas createRadioButtonPanel() {
ingo@43: mode = new DynamicForm();
ingo@41:
ingo@43: RadioGroupItem radio = new RadioGroupItem("mode");
ingo@41: radio.setShowTitle(false);
ingo@41: radio.setVertical(false);
ingo@41:
ingo@43: LinkedHashMap values = new LinkedHashMap();
ingo@43: values.put(FIELD_LOCATION, MESSAGES.location());
ingo@43: values.put(FIELD_DISTANCE, MESSAGES.distance());
ingo@43:
ingo@45: LinkedHashMap initial = new LinkedHashMap();
ingo@45: initial.put("mode", FIELD_LOCATION);
ingo@45:
ingo@43: radio.setValueMap(values);
ingo@41: radio.addChangeHandler(this);
ingo@41:
ingo@43: mode.setFields(radio);
ingo@45: mode.setValues(initial);
ingo@41:
ingo@43: return mode;
ingo@41: }
ingo@41:
ingo@41:
ingo@43: protected double getFrom() {
ingo@43: return from;
ingo@41: }
ingo@41:
ingo@41:
ingo@43: protected void setFrom(double from) {
ingo@43: this.from = from;
ingo@43: }
ingo@41:
ingo@41:
ingo@43: protected double getTo() {
ingo@43: return to;
ingo@43: }
ingo@41:
ingo@41:
ingo@43: protected void setTo(double to) {
ingo@43: this.to = to;
ingo@43: }
ingo@41:
ingo@43:
ingo@43: protected double getStep() {
ingo@43: return step;
ingo@43: }
ingo@43:
ingo@43:
ingo@43: protected void setStep(double step) {
ingo@43: this.step = step;
ingo@43: }
ingo@43:
ingo@43:
ingo@43: protected double[] getLocationValues() {
ingo@43: return values;
ingo@43: }
ingo@43:
ingo@43:
ingo@43: protected void setLocationValues(double[] values) {
ingo@43: this.values = values;
ingo@41: }
ingo@41: }
ingo@41: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :