package org.sigmah.client.ui.widget.form;
/*
* #%L
* Sigmah
* %%
* Copyright (C) 2010 - 2016 URD
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import java.util.ArrayList;
import java.util.List;
import org.sigmah.client.i18n.I18N;
import org.sigmah.client.ui.res.icon.IconImageBundle;
import org.sigmah.client.ui.widget.Loadable;
import org.sigmah.client.ui.widget.button.Button;
import org.sigmah.client.util.ClientUtils;
import com.extjs.gxt.ui.client.widget.form.AdapterField;
import com.extjs.gxt.ui.client.widget.form.MultiField;
import com.extjs.gxt.ui.client.widget.form.TextField;
/**
* <p>
* Custom field implementation composed of one (or multiple) {@link TextField} and a {@link Button} (horizontally
* aligned).
* </p>
*
* @author Denis Colliot (dcolliot@ideia.fr) (v2.0)
*/
public class TextButtonField extends MultiField<String> implements Loadable {
private final List<TextField<String>> textFields;
private final Button button;
private final AdapterField buttonAdapter;
/**
* Initializes a new {@code TextButtonField} field instance with <b>one</b> text field.<br>
* To initialize multiple text fields, see {@link #TextButtonField(String, int)} constructor.
*
* @param fieldLabel
* The field label.
*/
public TextButtonField(String fieldLabel) {
this(fieldLabel, 1);
}
/**
* Initializes a new {@code TextButtonField} field instance with multiple text fields.
*
* @param fieldLabel
* The field label.
* @param fieldsNumber
* The number of text fields.
*/
public TextButtonField(String fieldLabel, int fieldsNumber) {
if (fieldsNumber < 1) {
fieldsNumber = 1;
}
textFields = new ArrayList<TextField<String>>(fieldsNumber);
button = Forms.button(I18N.CONSTANTS.addItem(), IconImageBundle.ICONS.add()); // Default configuration.
buttonAdapter = Forms.adapter(fieldLabel, button);
if (ClientUtils.isNotBlank(fieldLabel)) {
setFieldLabel(fieldLabel);
} else {
setLabelSeparator("");
}
setSpacing(7);
for (int i = 0; i < fieldsNumber; i++) {
final TextField<String> textField = Forms.text(null, false);
textFields.add(textField);
add(textField);
}
add(buttonAdapter);
}
/**
* {@inheritDoc}
*/
@Override
protected void onResize(int width, int height) {
super.onResize(width, height);
int buttonWidth = buttonAdapter.el().getParent().getWidth();
if (buttonWidth <= 0) {
// TODO Try to 'always' determine dynamic button width (see 'EditFlexibleElementAdminView' problem).
buttonWidth = 70; // Arbitrary width considering all i18n translations widths.
button.setWidth(buttonWidth);
}
final int textFieldsNumber = textFields.size();
final int textFieldsTotalWidth = width - buttonWidth - (textFieldsNumber * spacing);
final int textFieldWidth = textFieldsTotalWidth / textFieldsNumber;
for (final TextField<String> textField : textFields) {
textField.setSize(textFieldWidth, height);
}
}
/**
* {@inheritDoc}
*/
@Override
public void setLoading(boolean loading) {
button.setLoading(loading);
}
/**
* {@inheritDoc}
*/
@Override
public boolean isLoading() {
return button.isLoading();
}
/**
* Returns the given {@code index} corresponding inner {@link TextField} field.
*
* @param index
* The text field index (starting at {@code 0}).
* @return The inner {@link TextField} field.
* @throws IndexOutOfBoundsException
* If the given {@code index} is out of bounds.
*/
public TextField<String> getTextField(final int index) {
return textFields.get(index);
}
/**
* Returns the inner {@link Button}.
*
* @return The inner {@link Button} (never {@code null}).
*/
public Button getButton() {
return button;
}
}