/**
* Sencha GXT 3.0.0b - Sencha for GWT
* Copyright(c) 2007-2012, Sencha, Inc.
* licensing@sencha.com
*
* http://www.sencha.com/products/gxt/license/
*/
package com.sencha.gxt.explorer.client.view;
import java.util.Comparator;
import java.util.List;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.text.shared.AbstractSafeHtmlRenderer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.cell.core.client.SimpleSafeHtmlCell;
import com.sencha.gxt.cell.core.client.form.ComboBoxCell.TriggerAction;
import com.sencha.gxt.core.client.IdentityValueProvider;
import com.sencha.gxt.core.client.Style.SelectionMode;
import com.sencha.gxt.core.client.XTemplates;
import com.sencha.gxt.core.client.XTemplates.Formatter;
import com.sencha.gxt.core.client.XTemplates.FormatterFactories;
import com.sencha.gxt.core.client.XTemplates.FormatterFactory;
import com.sencha.gxt.core.client.resources.CommonStyles;
import com.sencha.gxt.core.client.resources.ThemeStyles;
import com.sencha.gxt.core.client.util.Format;
import com.sencha.gxt.core.client.util.Margins;
import com.sencha.gxt.data.client.loader.RpcProxy;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.data.shared.ModelKeyProvider;
import com.sencha.gxt.data.shared.SortDir;
import com.sencha.gxt.data.shared.Store;
import com.sencha.gxt.data.shared.Store.StoreSortInfo;
import com.sencha.gxt.data.shared.StringLabelProvider;
import com.sencha.gxt.data.shared.loader.ListStoreBinding;
import com.sencha.gxt.data.shared.loader.Loader;
import com.sencha.gxt.examples.resources.client.ExampleService;
import com.sencha.gxt.examples.resources.client.ExampleServiceAsync;
import com.sencha.gxt.examples.resources.client.model.Photo;
import com.sencha.gxt.explorer.client.model.Example.Detail;
import com.sencha.gxt.widget.core.client.Dialog;
import com.sencha.gxt.widget.core.client.Dialog.PredefinedButton;
import com.sencha.gxt.widget.core.client.ListView;
import com.sencha.gxt.widget.core.client.ListViewCustomAppearance;
import com.sencha.gxt.widget.core.client.button.TextButton;
import com.sencha.gxt.widget.core.client.container.BorderLayoutContainer;
import com.sencha.gxt.widget.core.client.container.BorderLayoutContainer.BorderLayoutData;
import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer;
import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData;
import com.sencha.gxt.widget.core.client.event.HideEvent;
import com.sencha.gxt.widget.core.client.event.HideEvent.HideHandler;
import com.sencha.gxt.widget.core.client.event.SelectEvent;
import com.sencha.gxt.widget.core.client.event.SelectEvent.SelectHandler;
import com.sencha.gxt.widget.core.client.form.SimpleComboBox;
import com.sencha.gxt.widget.core.client.form.StoreFilterField;
import com.sencha.gxt.widget.core.client.selection.SelectionChangedEvent;
import com.sencha.gxt.widget.core.client.selection.SelectionChangedEvent.SelectionChangedHandler;
import com.sencha.gxt.widget.core.client.toolbar.LabelToolItem;
import com.sencha.gxt.widget.core.client.toolbar.SeparatorToolItem;
import com.sencha.gxt.widget.core.client.toolbar.ToolBar;
@Detail(name = "Advanced ListView", icon = "advancedlistview", category = "Templates & Lists")
public class AdvancedListViewExample implements IsWidget, EntryPoint {
interface DetailRenderer extends XTemplates {
@XTemplate(source = "AdvancedListViewDetail.html")
public SafeHtml render(Photo photo);
}
@FormatterFactories(@FormatterFactory(factory = ShortenFactory.class, name = "shorten"))
interface Renderer extends XTemplates {
@XTemplate(source = "ListViewExample.html")
public SafeHtml renderItem(Photo photo, Style style);
}
interface Resources extends ClientBundle {
@Source("ListViewExample.css")
Style css();
}
static class Shorten implements Formatter<String> {
private int length;
public Shorten(int length) {
this.length = length;
}
@Override
public String format(String data) {
return Format.ellipse(data, length);
}
}
static class ShortenFactory {
public static Shorten getFormat(int length) {
return new Shorten(length);
}
}
interface Style extends CssResource {
String over();
String select();
String thumb();
String thumbWrap();
}
private Dialog chooser;
private HTML details;
private Image image;
private DetailRenderer renderer;
private SimpleComboBox<String> sort;
private ListStore<Photo> store;
private ListView<Photo, Photo> view;
private VerticalPanel vp;
public Widget asWidget() {
if (vp == null) {
renderer = GWT.create(DetailRenderer.class);
final ExampleServiceAsync service = GWT.create(ExampleService.class);
RpcProxy<Object, List<Photo>> proxy = new RpcProxy<Object, List<Photo>>() {
@Override
public void load(Object loadConfig, AsyncCallback<List<Photo>> callback) {
service.getPhotos(callback);
}
};
Loader<Object, List<Photo>> loader = new Loader<Object, List<Photo>>(proxy);
ModelKeyProvider<Photo> kp = new ModelKeyProvider<Photo>() {
@Override
public String getKey(Photo item) {
return item.getName();
}
};
store = new ListStore<Photo>(kp);
loader.addLoadHandler(new ListStoreBinding<Object, Photo, List<Photo>>(store));
store.addSortInfo(new StoreSortInfo<Photo>(new Comparator<Photo>() {
@Override
public int compare(Photo o1, Photo o2) {
String v = sort.getCurrentValue();
if (v.equals("Name")) {
return o1.getName().compareToIgnoreCase(o2.getName());
} else if (v.equals("File Size")) {
return o1.getSize() < o2.getSize() ? -1 : 1;
} else {
o1.getDate().compareTo(o2.getDate());
}
return 0;
}
}, SortDir.ASC));
loader.load();
chooser = new Dialog();
chooser.setId("img-chooser-dlg");
chooser.setHeadingText("Choose an Image");
chooser.setWidth(500);
chooser.setHeight(300);
chooser.setModal(true);
chooser.setBodyStyle("background: none");
chooser.setBodyBorder(false);
chooser.setPredefinedButtons(PredefinedButton.OK, PredefinedButton.CANCEL);
chooser.setHideOnButtonClick(true);
chooser.addHideHandler(new HideHandler() {
@Override
public void onHide(HideEvent event) {
Photo photo = view.getSelectionModel().getSelectedItem();
if (photo != null) {
if (chooser.getHideButton() == chooser.getButtonById(PredefinedButton.OK.name())) {
image.setUrl(photo.getPath());
image.setVisible(true);
}
}
}
});
BorderLayoutContainer con = new BorderLayoutContainer();
chooser.add(con);
VerticalLayoutContainer main = new VerticalLayoutContainer();
main.setBorders(true);
ToolBar bar = new ToolBar();
bar.add(new LabelToolItem("Filter:"));
StoreFilterField<Photo> field = new StoreFilterField<Photo>() {
@Override
protected boolean doSelect(Store<Photo> store, Photo parent, Photo item, String filter) {
String name = item.getName().toLowerCase();
if (name.indexOf(filter.toLowerCase()) != -1) {
return true;
}
return false;
}
@Override
protected void onFilter() {
super.onFilter();
view.getSelectionModel().select(0, false);
}
};
field.setWidth(100);
field.bind(store);
bar.add(field);
bar.add(new SeparatorToolItem());
bar.add(new LabelToolItem("Sort By:"));
sort = new SimpleComboBox<String>(new StringLabelProvider<String>());
sort.setTriggerAction(TriggerAction.ALL);
sort.setEditable(false);
sort.setForceSelection(true);
sort.setWidth(120);
sort.add("Name");
sort.add("File Size");
sort.add("Last Modified");
sort.setValue("Name");
sort.addSelectionHandler(new SelectionHandler<String>() {
@Override
public void onSelection(SelectionEvent<String> event) {
store.applySort(false);
}
});
bar.add(sort);
main.add(bar, new VerticalLayoutData(1, -1));
final Resources resources = GWT.create(Resources.class);
resources.css().ensureInjected();
final Style style = resources.css();
final Renderer r = GWT.create(Renderer.class);
ListViewCustomAppearance<Photo> appearance = new ListViewCustomAppearance<Photo>("." + style.thumbWrap(),
style.over(), style.select()) {
@Override
public void renderEnd(SafeHtmlBuilder builder) {
String markup = new StringBuilder("<div class=\"").append(CommonStyles.get().clear()).append("\"></div>").toString();
builder.appendHtmlConstant(markup);
}
@Override
public void renderItem(SafeHtmlBuilder builder, SafeHtml content) {
builder.appendHtmlConstant("<div class='" + style.thumbWrap() + "' style='border: 1px solid white'>");
builder.append(content);
builder.appendHtmlConstant("</div>");
}
};
view = new ListView<Photo, Photo>(store, new IdentityValueProvider<Photo>() {
@Override
public void setValue(Photo object, Photo value) {
}
}, appearance);
view.setCell(new SimpleSafeHtmlCell<Photo>(new AbstractSafeHtmlRenderer<Photo>() {
@Override
public SafeHtml render(Photo object) {
return r.renderItem(object, style);
}
}));
view.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
view.getSelectionModel().addSelectionChangedHandler(new SelectionChangedHandler<Photo>() {
@Override
public void onSelectionChanged(SelectionChangedEvent<Photo> event) {
AdvancedListViewExample.this.onSelectionChange(event);
}
});
view.setBorders(false);
main.add(view, new VerticalLayoutData(1, 1));
details = new HTML();
details.addStyleName(ThemeStyles.getStyle().border());
details.getElement().getStyle().setBackgroundColor("white");
BorderLayoutData eastData = new BorderLayoutData(150);
eastData.setSplit(true);
BorderLayoutData centerData = new BorderLayoutData();
centerData.setMargins(new Margins(0, 5, 0, 0));
con.setCenterWidget(main, centerData);
con.setEastWidget(details, eastData);
TextButton b = new TextButton("Choose");
b.addSelectHandler(new SelectHandler() {
@Override
public void onSelect(SelectEvent event) {
chooser.show();
view.getSelectionModel().select(0, false);
}
});
vp = new VerticalPanel();
vp.setSpacing(10);
vp.add(b);
image = new Image();
image.getElement().getStyle().setProperty("marginTop", "10px");
image.setVisible(false);
vp.add(image);
}
return vp;
}
public void onModuleLoad() {
RootPanel.get().add(asWidget());
}
private void onSelectionChange(SelectionChangedEvent<Photo> se) {
if (se.getSelection().size() > 0) {
details.setHTML(renderer.render(se.getSelection().get(0)).asString());
chooser.getButtonById(PredefinedButton.OK.name()).enable();
} else {
chooser.getButtonById(PredefinedButton.OK.name()).disable();
details.setHTML("");
}
}
}