/*******************************************************************************
* Copyright (c) 2012-2017 Codenvy, S.A.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.ide.ui.dropdown;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import static com.google.gwt.user.client.ui.PopupPanel.AnimationType.ROLL_DOWN;
/** Menu for {@link DropdownList}. */
class DropdownMenu extends PopupPanel {
private static final DropdownListResources RESOURCES = GWT.create(DropdownListResources.class);
/** Maximum amount of widgets that should visible without scrolling. */
private static final int MAX_VISIBLE_WIDGETS = 7;
/** Amount of pixels reserved for displaying one widget. */
private static final int CHILD_WIDGET_HEIGHT = 22;
private final DropdownList dropdownList;
private final FlowPanel contentPanel;
/** Stores true if dropdown menu's width should be always synchronized with the dropdown header's width. */
private boolean widthsSynced;
/**
* Creates new dropdown menu.
*
* @param dropdownList
* a dropdown list to which the menu should be bound
* @param syncWidths
* specifies whether this dropdown menu's width always should be the same as the given {@code dropdownList}'s width
*/
DropdownMenu(DropdownList dropdownList, boolean syncWidths) {
super(true);
this.dropdownList = dropdownList;
widthsSynced = syncWidths;
if (syncWidths) {
Window.addResizeHandler(e -> setWidth(dropdownList.getElement().getClientWidth() + "px"));
}
removeStyleName("gwt-PopupPanel");
addStyleName(RESOURCES.dropdownListCss().menu());
addAutoHidePartner(dropdownList.getElement());
setAnimationEnabled(true);
setAnimationType(ROLL_DOWN);
contentPanel = new FlowPanel();
contentPanel.ensureDebugId("dropdown-list-content-panel");
add(new ScrollPanel(contentPanel));
}
void toggleMenuVisibility() {
if (isShowing()) {
hide();
} else {
if (widthsSynced) {
setWidth(dropdownList.getElement().getClientWidth() + "px");
}
showRelativeTo(dropdownList);
}
}
void addWidget(IsWidget widget) {
contentPanel.insert(widget, 0);
adaptMenuHeight();
}
void removeWidget(IsWidget widget) {
contentPanel.remove(widget);
adaptMenuHeight();
}
void removeAllWidgets() {
contentPanel.clear();
adaptMenuHeight();
}
/** Adapts menu's height depending on the amount of the child widgets. */
private void adaptMenuHeight() {
final int visibleRowsCount = Math.min(MAX_VISIBLE_WIDGETS, contentPanel.getWidgetCount());
final int dropdownPanelHeight = CHILD_WIDGET_HEIGHT * visibleRowsCount;
setHeight(dropdownPanelHeight + "px");
}
}