package com.project.website.canvas.client.shared.widgets.media; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.KeyPressEvent; import com.google.gwt.event.dom.client.KeyPressHandler; 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.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Focusable; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.InlineLabel; import com.google.gwt.user.client.ui.RadioButton; import com.google.gwt.user.client.ui.ScrollPanel; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.Widget; import com.project.shared.client.events.SimpleEvent; import com.project.shared.client.handlers.RegistrationsManager; import com.project.shared.client.utils.NativeUtils; import com.project.shared.client.utils.widgets.TextBoxUtils; import com.project.website.canvas.client.resources.CanvasResources; import com.project.website.canvas.client.shared.searchProviders.interfaces.MediaInfo; import com.project.website.canvas.client.shared.searchProviders.interfaces.MediaResult; import com.project.website.canvas.client.shared.searchProviders.interfaces.MediaSearchProvider; import com.project.website.canvas.client.shared.searchProviders.interfaces.MediaSearchResult; import com.project.website.canvas.client.shared.widgets.RadioButtonPanel; public class MediaSearchPanel extends Composite implements Focusable { private static MediaSearchPanelUiBinder uiBinder = GWT.create(MediaSearchPanelUiBinder.class); interface MediaSearchPanelUiBinder extends UiBinder<Widget, MediaSearchPanel> { } @UiField Button searchButton; @UiField TextBox searchText; @UiField FlowPanel resultsPanel; @UiField ScrollPanel resultsPanelContainer; @UiField FlowPanel formPanel; @UiField FlowPanel photoSizesPanel; @UiField FlowPanel providersPanel; protected final SimpleEvent<MediaInfo> mediaPicked = new SimpleEvent<MediaInfo>(); protected final RegistrationsManager registrationsManager = new RegistrationsManager(); private MediaSearchProvider _selectedSearchProvider = null; private Image selectedThumbnail; private HashMap<MediaSearchProvider, RadioButtonPanel> _searchProviderMap = new HashMap<MediaSearchProvider, RadioButtonPanel>(); private HashMap<RadioButton, MediaInfo> _sizeSelectionMap = new HashMap<RadioButton, MediaInfo>(); public MediaSearchPanel() { initWidget(uiBinder.createAndBindUi(this)); TextBoxUtils.setPlaceHolder(this.searchText, "Search..."); this.searchText.addKeyPressHandler(new KeyPressHandler() { @Override public void onKeyPress(KeyPressEvent event) { if (NativeUtils.keyIsEnter(event)) { searchSubmitted(); } } }); } public void setSearchProviders(List<? extends MediaSearchProvider> searchProviders) { if (0 == searchProviders.size()) { return; } boolean allowSelect = (1 < searchProviders.size()); for (final MediaSearchProvider searchProvider : searchProviders) { addProvider(searchProvider, allowSelect); } this._selectedSearchProvider = searchProviders.get(0); if (allowSelect) { this._searchProviderMap.get(this._selectedSearchProvider).setValue(true); } } public void addProvider(final MediaSearchProvider searchProvider, boolean allowSelect) { HasWidgets providerPanel; Widget providerPanelWidget; if (allowSelect) { final RadioButtonPanel radioButtonPanel = new RadioButtonPanel(); radioButtonPanel.setName("searchProviders"); radioButtonPanel.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { if (false == radioButtonPanel.getValue()) { return; } _selectedSearchProvider = searchProvider; } }); this._searchProviderMap.put(searchProvider, radioButtonPanel); providerPanel = radioButtonPanel; providerPanelWidget = radioButtonPanel; } else { FlowPanel flowPanel = new FlowPanel(); providerPanel = flowPanel; providerPanelWidget = flowPanel; } providerPanelWidget.addStyleName( CanvasResources.INSTANCE.main().imageToolSearchProviderPanelStyle()); FlowPanel imagePanel = new FlowPanel(); imagePanel.addStyleName( CanvasResources.INSTANCE.main().imageToolSearchProviderIconStyle()); imagePanel.getElement().getStyle() .setBackgroundImage("url(" + searchProvider.getIconUrl() + ")"); providerPanel.add(imagePanel); providerPanel.add(new InlineLabel(searchProvider.getTitle())); this.providersPanel.add(providerPanelWidget); } @UiHandler("searchButton") void handleClick(ClickEvent e) { searchSubmitted(); } private void searchSubmitted() { String text = this.searchText.getText().trim(); if (text.isEmpty()) { return; } if (null == this._selectedSearchProvider) { return; } searchButton.setEnabled(false); this._selectedSearchProvider.search(text, new AsyncCallback<MediaSearchResult>() { @Override public void onSuccess(MediaSearchResult result) { setSearchResult(result); searchButton.setEnabled(true); } @Override public void onFailure(Throwable caught) { Window.alert("Search failed: " + caught); searchButton.setEnabled(true); } }); } protected void setSearchResult(MediaSearchResult result) { registrationsManager.clear(); resultsPanel.clear(); resultsPanelContainer.scrollToTop(); for (MediaResult imageResult : result.getMediaResults()) { Widget imageWidget = createPhoto(imageResult); if (null != imageWidget) { resultsPanel.add(imageWidget); } } } public Widget createPhoto(final MediaResult imageResult) { if (null == imageResult) { return null; } final Image image = new Image(); image.setTitle(imageResult.getTitle()); image.addStyleName(CanvasResources.INSTANCE.main().mediaSearchPanelResultImage()); image.setUrl(imageResult.getThumbnailUrl()); this.registrationsManager.add(image.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { imageSelected(imageResult, image); } })); return image; } public HandlerRegistration addMediaPickedHandler(SimpleEvent.Handler<MediaInfo> handler) { return this.mediaPicked.addHandler(handler); } public void imageSelected(final MediaResult imageResult, final Image image) { if (null != selectedThumbnail) { selectedThumbnail.removeStyleName(CanvasResources.INSTANCE.main().selected()); } this.selectedThumbnail = image; image.addStyleName(CanvasResources.INSTANCE.main().selected()); photoSizesPanel.clear(); imageResult.getMediaSizes(new AsyncCallback<ArrayList<MediaInfo>>() { @Override public void onSuccess(ArrayList<MediaInfo> result) { setPhotoSizes(result); } @Override public void onFailure(Throwable caught) { // TODO Auto-generated method stub } }); } protected void setPhotoSizes(ArrayList<MediaInfo> result) { this._sizeSelectionMap.clear(); photoSizesPanel.clear(); int defaultSelectionIndex = result.size() / 2; int i = 0; for (final MediaInfo mediaInfo : result) { RadioButton radioButton = new RadioButton("sizes", mediaInfo.getSizeDescription()); this._sizeSelectionMap.put(radioButton, mediaInfo); photoSizesPanel.add(radioButton); radioButton.addValueChangeHandler(new ValueChangeHandler<Boolean>() { @Override public void onValueChange(ValueChangeEvent<Boolean> event) { if (event.getValue()) { imageSizeSelected(mediaInfo); } } }); if (i == defaultSelectionIndex) { radioButton.setValue(true); imageSizeSelected(mediaInfo); } i++; } photoSizesPanel.setVisible(true); } public void imageSizeSelected(final MediaInfo selectedSize) { mediaPicked.dispatch(selectedSize); } public MediaInfo getSelectedMedia() { for (Entry<RadioButton, MediaInfo> entry : this._sizeSelectionMap.entrySet()) { if (entry.getKey().getValue()) { return entry.getValue(); } } return null; } public void clear() { //TODO: Set the "Search" text as watermark. this.searchText.setText(""); resultsPanel.clear(); resultsPanelContainer.scrollToTop(); photoSizesPanel.clear(); } @Override public int getTabIndex() { return this.searchText.getTabIndex(); } @Override public void setAccessKey(char key) { this.searchText.setAccessKey(key); } @Override public void setFocus(boolean focused) { this.searchText.setFocus(focused); } @Override public void setTabIndex(int index) { this.searchText.setTabIndex(index); } }