/*
* Copyright (C) 2013 Red Hat, Inc. and/or its affiliates.
*
* 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.jboss.errai.demo.grocery.client.local;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import org.jboss.errai.ui.shared.api.annotations.DataField;
import org.jboss.errai.ui.shared.api.annotations.Templated;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
/**
* A container that can hold a widget and show and hide itself on demand. The
* appearance is based on (and depends on) the Twitter Bootstrap stylesheet
* collection. It does not require jQuery or the Bootstrap jquery.popup.js
* plugin (it is a GWT-based replacement for that plugin).
* <p>
* Usage Example:
* <pre>
* final StoreForm storeForm = beanManager.lookupBean(StoreForm.class).getInstance();
* final PopoverContainer popover = beanManager.lookupBean(PopoverContainer.class).getInstance();
* popover.setTitleHtml(new SafeHtmlBuilder().appendEscaped("New Store").toSafeHtml());
* popover.setBodyWidget(storeForm);
* popover.show(addStoreButton);
* storeForm.grabKeyboardFocus();
*
* // hide store form when new store is saved
* storeForm.setAfterSaveAction(new Runnable() {
* {@code @Override}
* public void run() {
* popover.hide();
* beanManager.destroyBean(popover);
* beanManager.destroyBean(storeForm);
* }
* });
* </pre>
*
* @author Jonathan Fuerth <jfuerth@gmail.com>
*/
@Templated
@Dependent
public class PopoverContainer extends Composite {
/**
* This is the widget that contains the user-supplied title we show in the popover.
*/
@DataField
private DivElement popoverTitle = Document.get().createDivElement();
/**
* This is the widget that contains the user-supplied content we show in the popover.
*/
@Inject
@DataField
private VerticalPanel popoverContent;
/**
* Positions the popover so that its arrow points at the centre of the given widget Makes the popover visible
*
* @param positionNear
*/
public void show(Widget positionNear) {
getElement().getStyle().setDisplay(Display.BLOCK);
getElement().getStyle().setLeft(positionNear.getAbsoluteLeft() + positionNear.getOffsetWidth(), Unit.PX);
getElement().getStyle().setTop(
positionNear.getAbsoluteTop() + positionNear.getOffsetHeight() / 2
- getElement().getOffsetHeight() / 2, Unit.PX);
}
/**
* Causes this popover to become invisible.
*/
public void hide() {
getElement().getStyle().setDisplay(Display.NONE);
}
/**
* Sets the widget that will be displayed as the title of this popover, replacing any existing title widget.
*/
public void setTitleHtml(SafeHtml html) {
popoverTitle.setInnerHTML(html.asString());
}
/**
* Sets the widget that will be displayed as the title of this popover, replacing any existing body widget.
*/
public void setBodyWidget(Widget bodyWidget) {
popoverContent.clear();
popoverContent.add(bodyWidget);
}
/**
* Adds this popover to the document so it can be made visible. This method is called automatically when this bean is
* created.
*/
@PostConstruct
private void init() {
RootPanel.get().add(this);
}
/**
* Removes this popover from the document so it does not leak resources. This method is called automatically when this bean
* is destroyed.
*/
@PreDestroy
private void destroy() {
RootPanel.get().remove(this);
}
}