/*
* Copyright 2011 Philippe Blanc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package me.l1k3.ui.client;
import java.util.ArrayList;
import me.l1k3.core.client.Core;
import me.l1k3.fx.client.FXOpen;
import me.l1k3.fx.client.channel.inter.DimensionConstant;
import me.l1k3.fx.client.inter.FXShowAndHide;
import me.l1k3.ui.client.event.ShowAndHidePanelEvent;
import me.l1k3.ui.client.event.ShowAndHidePanelEventHandler;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.ToggleButton;
public class ShowAndHidePanel extends BlockerPanel {
private ArrayList<ShowAndHideTab> buttons;
private EventBus bus;
private Command busCallback;
private FXShowAndHide effect;
private ClickHandler clickHandler;
private ShowAndHidePanelGroup group;
private boolean visible;
public ShowAndHidePanel() {
this(true);
}
public ShowAndHidePanel(boolean visible) {
this(visible, new FXOpen(DimensionConstant.Direction.VERTICAL));
}
public ShowAndHidePanel(boolean visible, FXShowAndHide effect) {
setStyleName("slide-panel");
this.visible = visible;
this.effect = effect;
if(isAttached()) {
lazyInitialization();
}
}
public void setGroup(ShowAndHidePanelGroup group) {
removeGroup();
this.group = group;
if(group!=null) group.add(this);
}
public void removeGroup() {
if(group!=null) {
group.remove(this);
group = null;
}
}
public boolean isVisible() {
return visible;
}
public final HandlerRegistration addShowAndHidePanelEventHandler(ShowAndHidePanelEventHandler handler) {
if(bus==null) {
bus = Core.getEventBus();
}
return bus.addHandlerToSource(ShowAndHidePanelEvent.TYPE, this, handler);
}
public void show() {
show(null);
}
public void show(Command callback) {
if(group!=null) {
group.hide();
}
visible = true;
if (buttons != null) {
for (ShowAndHideTab tab : buttons) {
tab.show();
}
}
if (bus != null) {
bus.fireEventFromSource(ShowAndHidePanelEvent.create(this), this);
}
if(effect!=null) {
if(bus!=null) {
effect.show(500).callback(getBusCallback(callback!=null? callback : null));
}
else {
if(callback!=null) {
effect.show(500).callback(callback);
}
else {
effect.show(500);
}
}
}
else {
if(callback!=null) Scheduler.get().scheduleDeferred(callback);
if(bus!=null) fireEventFromSource();
}
}
public void hide() {
hide(null);
}
public void hide(Command callback) {
visible = false;
if(buttons!=null) {
for (ShowAndHideTab tab : buttons) {
tab.hide();
}
}
if(effect!=null) {
if(bus!=null) {
effect.hide(500).callback(getBusCallback(callback!=null? callback : null));
}
else {
if(callback!=null) {
effect.hide(500).callback(callback);
}
else {
effect.hide(500);
}
}
}
else {
if(callback!=null) Scheduler.get().scheduleDeferred(callback);
if(bus!=null) fireEventFromSource();
}
}
private Command getBusCallback(final Command callback) {
if(callback!=null) {
return new Command() {
@Override
public void execute() {
callback.execute();
if(bus!=null) fireEventFromSource();
}
};
}
if(busCallback==null) {
busCallback = new Command() {
@Override
public void execute() {
fireEventFromSource();
}
};
}
return busCallback;
}
private void fireEventFromSource() {
bus.fireEventFromSource(ShowAndHidePanelEvent.create(this), this);
}
public void attachTab(ShowAndHideTab tab) {
if(buttons==null) {
buttons = new ArrayList<ShowAndHideTab>();
}
tab.attachPanelSlideDown(this);
buttons.add(tab);
}
public void detachTab(ShowAndHideTab tab) {
tab.detachPanelSlideDown(this);
if(buttons!=null) {
buttons.remove(tab);
}
}
public ClickHandler getClickHandler() {
if(clickHandler==null) {
clickHandler = new PanelSlideDownClickHandler();
}
return clickHandler;
}
public FXShowAndHide getEffect() {
return effect;
}
public Anchor createAnchor(String label, String tip) {
ShowAndHideTabAnchor tab = new ShowAndHideTabAnchor();
attachTab(tab);
if(visible) tab.show(); else tab.hide();
tab.setText(label);
tab.setTitle(tip);
return tab;
}
public ToggleButton createButton(String label, String tip) {
return createButton(label, tip, false);
}
public ToggleButton createButton(String label, String tip, boolean html) {
ShowAndHideTabButton tab = new ShowAndHideTabButton();
attachTab(tab);
if(visible) tab.show(); else tab.hide();
if(html) {
tab.getUpFace().setHTML(label);
}
else {
tab.getUpFace().setText(label);
}
tab.setTitle(tip);
return tab;
}
public ToggleButton createButton(String labelUp, String labelDown, String tip, boolean html) {
ToggleButton tab = createButton(labelUp, tip, false);
if(html) {
tab.getDownFace().setHTML(labelDown);
}
else {
tab.getDownFace().setText(labelDown);
}
return tab;
}
@Override
protected void onLoad() {
super.onLoad();
lazyInitialization();
}
protected void toggle() {
if(!visible) show(); else hide();
}
private class PanelSlideDownClickHandler implements ClickHandler {
@Override
public void onClick(ClickEvent event) {
toggle();
}
}
private void lazyInitialization() {
effect.init(getElement());
if(visible) {
effect.show();
if(buttons!=null) {
for (ShowAndHideTab tab : buttons) {
tab.show();
}
}
}
else {
effect.hide();
if(buttons!=null) {
for (ShowAndHideTab tab : buttons) {
tab.hide();
}
}
}
}
public interface ShowAndHideTab {
public void attachPanelSlideDown(ShowAndHidePanel panel);
public void detachPanelSlideDown(ShowAndHidePanel panel);
public boolean isVisible();
public void hide();
public void show();
}
protected class ShowAndHideTabAnchor extends Anchor implements ShowAndHideTab {
private HandlerRegistration handler;
public ShowAndHideTabAnchor() {
getElement().addClassName("slide-tab");
}
@Override
public void attachPanelSlideDown(ShowAndHidePanel panel) {
handler = addClickHandler(panel.getClickHandler());
}
@Override
public void detachPanelSlideDown(ShowAndHidePanel panel) {
handler.removeHandler();
}
@Override
public void hide() {
getElement().removeClassName("active");
}
@Override
public void show() {
getElement().addClassName("active");
}
}
protected class ShowAndHideTabButton extends ToggleButton implements ShowAndHideTab {
private HandlerRegistration handler;
public ShowAndHideTabButton() {
getElement().addClassName("slide-tab");
}
@Override
public void attachPanelSlideDown(ShowAndHidePanel panel) {
handler = addClickHandler(panel.getClickHandler());
}
@Override
public void detachPanelSlideDown(ShowAndHidePanel panel) {
handler.removeHandler();
}
@Override
public void hide() {
setDown(false);
getElement().removeClassName("active");
}
@Override
public void show() {
setDown(true);
getElement().addClassName("active");
}
}
}