package com.google.collide.client.code;
import com.google.collide.client.history.Place;
import com.google.collide.client.util.AnimationUtils;
import com.google.collide.client.util.ResizeController;
import elemental.css.CSSStyleDeclaration;
import elemental.events.Event;
import elemental.events.EventListener;
import elemental.html.Element;
/**
* Class responsible for managing resizing of the Navigation Section.
*/
class NavigatorAreaResizeController extends ResizeController
implements NavigationAreaExpansionEvent.Handler {
private static final double DURATION = 0.2;
int oldNavWidth;
int oldSplitterLeft;
private final Element splitter;
private final Element navigatorArea;
private final Element contentArea;
private final int splitterWidth;
private final int splitterOverlap;
private final Place currentPlace;
public NavigatorAreaResizeController(Place currentPlace,
CodePerspective.Resources resources,
Element splitter,
Element navigatorArea,
Element contentArea,
int splitterWidth,
int splitterOverlap) {
super(resources, splitter, new ElementInfo(navigatorArea, ResizeProperty.WIDTH),
new ElementInfo(splitter, ResizeProperty.LEFT),
new ElementInfo(contentArea, ResizeProperty.LEFT));
this.currentPlace = currentPlace;
this.splitter = splitter;
this.navigatorArea = navigatorArea;
this.contentArea = contentArea;
this.splitterWidth = splitterWidth;
this.splitterOverlap = splitterOverlap;
}
@Override
public void onNavAreaExpansion(NavigationAreaExpansionEvent evt) {
int targetNavWidth = oldNavWidth;
int targetSplitterLeft = oldSplitterLeft;
int targetContentAreaLeft = oldSplitterLeft + splitterWidth;
// If we are asked to collapse.
if (!evt.shouldExpand()) {
// Remember the old sizes if we happen to be expanded.
if (!isCollapsed(splitter)) {
oldNavWidth = navigatorArea.getClientWidth();
oldSplitterLeft = splitter.getOffsetLeft();
}
// We want to collapse.
targetNavWidth = 0;
targetSplitterLeft = 0;
targetContentAreaLeft = 0;
}
// If we ask to expand, but we are already expanded, do nothing.
if (evt.shouldExpand() && !isCollapsed(splitter)) {
return;
}
splitter.getStyle().setLeft(targetSplitterLeft, CSSStyleDeclaration.Unit.PX);
splitter.getStyle().setDisplay("none");
AnimationUtils.backupOverflow(navigatorArea.getStyle());
AnimationUtils.animatePropertySet(navigatorArea, "width",
targetNavWidth + CSSStyleDeclaration.Unit.PX, DURATION, new EventListener() {
@Override
public void handleEvent(Event evt) {
splitter.getStyle().setDisplay("");
AnimationUtils.restoreOverflow(navigatorArea.getStyle());
}
});
AnimationUtils.animatePropertySet(
contentArea, "left", targetContentAreaLeft + CSSStyleDeclaration.Unit.PX, DURATION);
}
@Override
public void start() {
super.start();
attachDblClickListener();
currentPlace.registerSimpleEventHandler(NavigationAreaExpansionEvent.TYPE, this);
}
@Override
protected void resizeStarted() {
// Make sure the content area is to the right of the splitter in the
// case where we drag after collapsing.
String contentAreaOffset =
(splitterOverlap + getSplitter().getOffsetLeft()) + CSSStyleDeclaration.Unit.PX;
contentArea.getStyle().setLeft(contentAreaOffset);
super.resizeStarted();
}
private void attachDblClickListener() {
// Double clicking animates the splitter to hide and show the nav area.
// Equivalent to an automated resize.
splitter.setOnDblClick(new EventListener() {
@Override
public void handleEvent(Event evt) {
// We just want to toggle. If it is collapsed, we want to expand.
currentPlace.fireEvent(new NavigationAreaExpansionEvent(isCollapsed(splitter)));
}
});
}
private boolean isCollapsed(Element splitter) {
return splitter.getOffsetLeft() == 0;
}
}