/* * Copyright (c) 2009-2011 Lockheed Martin Corporation * * 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.eurekastreams.web.client.ui.common.stream.filters; import java.util.HashMap; import java.util.List; import org.eurekastreams.server.domain.stream.StreamFilter; import org.eurekastreams.web.client.events.HideNotificationEvent; import org.eurekastreams.web.client.events.Observer; import org.eurekastreams.web.client.events.UpdatedHistoryParametersEvent; import org.eurekastreams.web.client.ui.Session; import org.eurekastreams.web.client.ui.common.dialog.Dialog; import org.eurekastreams.web.client.ui.pages.master.StaticResourceBundle; import com.allen_sauer.gwt.dnd.client.PickupDragController; import com.allen_sauer.gwt.dnd.client.drop.IndexedDropController; import com.google.gwt.user.client.ui.AbsolutePanel; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.ClickListener; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; /** * Shows a list of views. * */ public class FilterListPanel extends FlowPanel { /** * The default drag sensitivity. */ private static final int DRAG_SENSITIVITY = 10; /** * The tab boundary panel. Absolute panel is needed because gwt-dnd only accepts them. */ private final AbsolutePanel viewBoundaryPanel = new AbsolutePanel(); /** * The active item. */ private FilterPanel activeItem = null; /** * The cache of the list, to look stuff up by ID on. */ private final HashMap<Long, FilterPanel> listCache = new HashMap<Long, FilterPanel>(); /** * Whether or not the list panel is hidden. */ private boolean hidden = true; /** * The show more show less container. */ private final FlowPanel showMore = new FlowPanel(); /** * Show more show less link. */ private final Anchor showMoreLink = new Anchor("show more"); /** * The panel to hold the views. */ private final VerticalPanel panel = new VerticalPanel(); /** * View drag controller. */ private final PickupDragController viewDragController; /** * The renderer. */ private final FilterRenderStrategy renderer; /** * Whether or not weve added the hidden line. */ private boolean addedHiddenLine = false; /** * Hidden line index. */ private final Integer hiddenLineIndex; /** * The views. */ private final List<StreamFilter> views; /** * Default constructor. * * @param inViews * the views. * @param inHiddenLineIndex * the hidden line index. * @param inRenderer * the renderer. * @param readOnly * flag indicating if this panel has no writable properties requiring a DialogContent. */ public FilterListPanel(final List<StreamFilter> inViews, final Integer inHiddenLineIndex, final FilterRenderStrategy inRenderer, final boolean readOnly) { views = inViews; hiddenLineIndex = inHiddenLineIndex; renderer = inRenderer; showMore.add(new HTML("")); showMore.add(showMoreLink); FlowPanel header = new FlowPanel(); Label headerLbl = new Label(renderer.getTitle()); header.addStyleName(StaticResourceBundle.INSTANCE.coreCss().header()); this.add(header); header.add(headerLbl); if (!readOnly) { Anchor addView = new Anchor("add"); FlowPanel addButton = new FlowPanel(); addButton.addStyleName(StaticResourceBundle.INSTANCE.coreCss().filterAddButton()); addButton.insert(new HTML(""), 0); addButton.add(addView); addView.addClickListener(new ClickListener() { public void onClick(final Widget arg0) { Session.getInstance().getEventBus().notifyObservers(new HideNotificationEvent()); Dialog.showCentered(renderer.getDialogContent()); } }); header.add(addButton); } renderer.setUpEvents(this); IndexedDropController tabDropController = new IndexedDropController(panel); viewDragController = new PickupDragController(viewBoundaryPanel, false); viewDragController.setBehaviorConstrainedToBoundaryPanel(true); viewDragController.setBehaviorMultipleSelection(false); viewDragController.setBehaviorDragStartSensitivity(DRAG_SENSITIVITY); viewDragController.addDragHandler(new FilterDragHandler(this, renderer.getReorderableModel())); viewDragController.registerDropController(tabDropController); int count = 0; for (StreamFilter view : views) { FilterPanel listItem = renderer.getFilterPanel(view); if (count > hiddenLineIndex) { ((Widget) listItem).addStyleName(StaticResourceBundle.INSTANCE.coreCss().hide()); } if (count == hiddenLineIndex + 1) { addHiddenLine(); } listCache.put(view.getId(), listItem); panel.add((Widget) listItem); viewDragController.makeDraggable((Widget) listItem, listItem.getMoveHandle()); count++; } if (!addedHiddenLine && views.size() > 0) { addedHiddenLine = true; addHiddenLine(); showMore.addStyleName(StaticResourceBundle.INSTANCE.coreCss().hideText()); } viewBoundaryPanel.add(panel); this.add(viewBoundaryPanel); Session.getInstance().getEventBus().addObserver(UpdatedHistoryParametersEvent.class, new Observer<UpdatedHistoryParametersEvent>() { public void update(final UpdatedHistoryParametersEvent event) { String filterId = event.getParameters().get(renderer.getFilterHistoryToken()); if (filterId != null) { listCache.get(Long.valueOf(filterId)).activate(); // checks if the item being navigated to is hidden below the hiddenLineIndex and expand. int i = 0; for (StreamFilter view : views) { if (view.getId() == Long.valueOf(filterId)) { if (i > hiddenLineIndex) { unhide(); } break; } i++; } } } }, true); } /** * Add the hidden line. */ private void addHiddenLine() { final FilterListPanel thisBuffered = this; addedHiddenLine = true; showMore.setStyleName(StaticResourceBundle.INSTANCE.coreCss().showMore()); showMoreLink.addClickListener(new ClickListener() { public void onClick(final Widget arg0) { if (hidden) { unhide(); } else { hidden = true; thisBuffered.removeStyleName(StaticResourceBundle.INSTANCE.coreCss().unhide()); showMoreLink.setText("show more"); showMore.removeStyleName(StaticResourceBundle.INSTANCE.coreCss().showLess()); } } }); panel.add(showMore); } /** * hides the text on the hidden line if its the last one. * * @param inHiddenLineIndex * the hidden line index. */ public void hideTextOnHiddenLine(final int inHiddenLineIndex) { if (inHiddenLineIndex == listCache.size()) { showMore.addStyleName(StaticResourceBundle.INSTANCE.coreCss().hideText()); } } /** * Show the text on the hidden line. */ public void showTextOnHiddenLine() { showMore.removeStyleName(StaticResourceBundle.INSTANCE.coreCss().hideText()); } /** * Activate a filter. * * @param filter * the filter. */ public void activateFilter(final StreamFilter filter) { listCache.get(filter.getId()).activate(); } /** * Unactivate all filters. */ public void unactivateAll() { if (activeItem != null) { activeItem.unActivate(); activeItem = null; } } /** * Adds a filter. * * @param filter * the filter. */ public void addFilter(final StreamFilter filter) { unhide(); FilterPanel listItem = renderer.getFilterPanel(filter); ((Widget) listItem).addStyleName(StaticResourceBundle.INSTANCE.coreCss().hide()); listCache.put(filter.getId(), listItem); panel.add((Widget) listItem); viewDragController.makeDraggable((Widget) listItem, listItem.getMoveHandle()); listItem.updateHistory(); if (!addedHiddenLine && listCache.size() > hiddenLineIndex) { addedHiddenLine = true; addHiddenLine(); showMore.addStyleName(StaticResourceBundle.INSTANCE.coreCss().hideText()); } else { showMore.removeStyleName(StaticResourceBundle.INSTANCE.coreCss().hideText()); } } /** * Activates the first item in the panel. */ public void activateFirst() { ((FilterPanel) panel.getWidget(0)).updateHistory(); } /** * Removes a filter. * * @param filter * the filter. */ public void removeFilter(final StreamFilter filter) { panel.remove((Widget) listCache.get(filter.getId())); listCache.remove(filter.getId()); if (panel.getWidgetCount() > 0) { fixHiddenLine(); } if (panel.getWidgetCount() > 0 && panel.getWidget(0) != null) { activateFirst(); } } /** * Updates the filter. * * @param filter * the filter. */ public void updateFilter(final StreamFilter filter) { listCache.get(filter.getId()).setFilter(filter); activateFilter(filter); } /** * Fix the hidden line. */ public void fixHiddenLine() { int itemIndex = panel.getWidgetIndex(showMore); if (itemIndex == 0) { panel.remove(showMore); addedHiddenLine = false; if (panel.getWidgetCount() > 0) { panel.insert(showMore, 1); panel.getWidget(0).removeStyleName(StaticResourceBundle.INSTANCE.coreCss().hide()); } } if (itemIndex == panel.getWidgetCount() - 1) { showMore.addStyleName(StaticResourceBundle.INSTANCE.coreCss().hideText()); } else { showMore.removeStyleName(StaticResourceBundle.INSTANCE.coreCss().hideText()); } } /** * Get drop panel. * * @return the drop panel. */ public VerticalPanel getDropPanel() { return panel; } /** * Gets the hidden line. * * @return the hidden line. */ public Integer getHiddenLineIndex() { return panel.getWidgetIndex(showMore); } /** * Unhide. */ public void unhide() { hidden = false; this.addStyleName(StaticResourceBundle.INSTANCE.coreCss().unhide()); showMoreLink.setText("show less"); showMore.addStyleName(StaticResourceBundle.INSTANCE.coreCss().showLess()); } /** * Get the views. * * @return the views. */ public List<StreamFilter> getViews() { return views; } }