/******************************************************************************* * 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.notification; import com.google.gwt.core.client.Scheduler; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; import com.google.inject.Inject; import com.google.inject.Singleton; import org.eclipse.che.ide.Resources; import org.eclipse.che.ide.api.notification.Notification; import org.eclipse.che.ide.api.notification.StatusNotification; import org.eclipse.che.ide.notification.NotificationManagerView.ActionDelegate; import org.eclipse.che.ide.notification.NotificationManagerView.NotificationActionDelegate; import javax.validation.constraints.NotNull; import java.util.LinkedList; /** * Stack for storing notifications that should be showed to user in future. Three notifications may be showed at once. If new notification * is pushed into stack it will wait when at least one notification will be release from the panel. To add new notification into stack to * show it in the future simply call {@link NotificationPopupStack#push(org.eclipse.che.ide.api.notification.StatusNotification)}. * * @author Andrey Plotnikov * @author Vlad Zhukovskyi * @see {@link StatusNotification} */ @Singleton public class NotificationPopupStack implements NotificationActionDelegate { public static final int POPUP_COUNT = 3; private ActionDelegate delegate; private LinkedList<StatusNotification> stack = new LinkedList<>(); private FlowPanel notificationContainer = new FlowPanel(); public static final String NOTIFICATION_CONTAINER_DBG_ID = "popup-container"; /** * Create message stack. * * @param resources * core resources */ @Inject public NotificationPopupStack(final Resources resources) { notificationContainer.ensureDebugId(NOTIFICATION_CONTAINER_DBG_ID); notificationContainer.setStyleName(resources.notificationCss().notificationPopupPlaceholder()); RootPanel.get().add(notificationContainer); Scheduler.get().scheduleFixedPeriod(new Scheduler.RepeatingCommand() { /** {@inheritDoc} */ @Override public boolean execute() { while (notificationContainer.getWidgetCount() < POPUP_COUNT && !stack.isEmpty()) { notificationContainer.add(new NotificationPopup(stack.pop(), resources, NotificationPopupStack.this)); } return true; } }, 1000); } /** * Sets the delegate for receiving events from this view. */ public void setDelegate(@NotNull ActionDelegate delegate) { this.delegate = delegate; } /** * Push notification to message stack. * * @param notification * notification that need to add */ public void push(@NotNull StatusNotification notification) { stack.push(notification); } /** * Remove notification from message stack. * * @param notification * notification that need to remove */ public void remove(@NotNull StatusNotification notification) { stack.remove(notification); onClose(notification); } /** {@inheritDoc} */ @Override public void onClick(Notification notification) { if (delegate != null) { delegate.onClick(notification); } } /** {@inheritDoc} */ @Override public void onDoubleClick(Notification notification) { if (delegate != null) { delegate.onDoubleClick(notification); } } /** {@inheritDoc} */ @Override public void onClose(Notification notification) { for (int i = 0; i < notificationContainer.getWidgetCount(); i++) { Widget child = notificationContainer.getWidget(i); if (child instanceof NotificationPopup && notification.equals(((NotificationPopup)child).getNotification())) { child.removeFromParent(); } } } /** * Remove all notifications from the stack and from notifications container. */ public void clear() { stack.clear(); for (int i = 0; i < notificationContainer.getWidgetCount(); i++) { Widget child = notificationContainer.getWidget(i); if (child instanceof NotificationPopup) { child.removeFromParent(); } } } }