com.vaadin.client.ui.splitpanel.AbstractSplitPanelConnector Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vaadin-client Show documentation
Show all versions of vaadin-client Show documentation
Vaadin is a web application framework for Rich Internet Applications (RIA).
Vaadin enables easy development and maintenance of fast and
secure rich web
applications with a stunning look and feel and a wide browser support.
It features a server-side architecture with the majority of the logic
running
on the server. Ajax technology is used at the browser-side to ensure a
rich
and interactive user experience.
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* 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 com.vaadin.client.ui.splitpanel;
import java.util.LinkedList;
import java.util.List;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.DomEvent;
import com.google.gwt.event.dom.client.DomEvent.Type;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ConnectorHierarchyChangeEvent;
import com.vaadin.client.LayoutManager;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.AbstractComponentContainerConnector;
import com.vaadin.client.ui.ClickEventHandler;
import com.vaadin.client.ui.SimpleManagedLayout;
import com.vaadin.client.ui.VAbstractSplitPanel;
import com.vaadin.client.ui.VAbstractSplitPanel.SplitterMoveHandler;
import com.vaadin.client.ui.VAbstractSplitPanel.SplitterMoveHandler.SplitterMoveEvent;
import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.ui.ComponentStateUtil;
import com.vaadin.shared.ui.splitpanel.AbstractSplitPanelRpc;
import com.vaadin.shared.ui.splitpanel.AbstractSplitPanelState;
import com.vaadin.shared.ui.splitpanel.AbstractSplitPanelState.SplitterState;
public abstract class AbstractSplitPanelConnector extends
AbstractComponentContainerConnector implements SimpleManagedLayout {
@Override
protected void init() {
super.init();
// TODO Remove
getWidget().client = getConnection();
getWidget().addHandler(new SplitterMoveHandler() {
@Override
public void splitterMoved(SplitterMoveEvent event) {
String position = getWidget().getSplitterPosition();
float pos = 0;
if (position.indexOf("%") > 0) {
// Send % values as a fraction to avoid that the splitter
// "jumps" when server responds with the integer pct value
// (e.g. dragged 16.6% -> should not jump to 17%)
pos = Float.valueOf(
position.substring(0, position.length() - 1));
} else {
pos = Integer.parseInt(
position.substring(0, position.length() - 2));
}
getRpcProxy(AbstractSplitPanelRpc.class)
.setSplitterPosition(pos);
}
}, SplitterMoveEvent.TYPE);
}
@Override
public void updateCaption(ComponentConnector component) {
// TODO Implement caption handling
}
ClickEventHandler clickEventHandler = new ClickEventHandler(this) {
@Override
protected HandlerRegistration registerHandler(
H handler, Type type) {
if ((Event.getEventsSunk(getWidget().splitter)
& Event.getTypeInt(type.getName())) != 0) {
// If we are already sinking the event for the splitter we do
// not want to additionally sink it for the root element
return getWidget().addHandler(handler, type);
} else {
return getWidget().addDomHandler(handler, type);
}
}
@Override
protected boolean shouldFireEvent(DomEvent event) {
Element target = event.getNativeEvent().getEventTarget().cast();
if (!getWidget().splitter.isOrHasChild(target)) {
return false;
}
return super.shouldFireEvent(event);
}
@Override
protected com.google.gwt.user.client.Element getRelativeToElement() {
return DOM.asOld(getWidget().splitter);
}
@Override
protected void fireClick(NativeEvent event,
MouseEventDetails mouseDetails) {
getRpcProxy(AbstractSplitPanelRpc.class)
.splitterClick(mouseDetails);
}
};
@Override
public void onStateChanged(StateChangeEvent stateChangeEvent) {
super.onStateChanged(stateChangeEvent);
getWidget().setEnabled(isEnabled());
clickEventHandler.handleEventHandlerRegistration();
if (ComponentStateUtil.hasStyles(getState())) {
getWidget().componentStyleNames = getState().styles;
} else {
getWidget().componentStyleNames = new LinkedList<>();
}
// Splitter updates
SplitterState splitterState = getState().splitterState;
getWidget().setStylenames();
getWidget().minimumPosition = splitterState.minPosition
+ splitterState.minPositionUnit;
getWidget().maximumPosition = splitterState.maxPosition
+ splitterState.maxPositionUnit;
getWidget().position = splitterState.position
+ splitterState.positionUnit;
getWidget().setPositionReversed(splitterState.positionReversed);
getWidget().setLocked(splitterState.locked);
// This is needed at least for cases like #3458 to take
// appearing/disappearing scrollbars into account.
getConnection().runDescendentsLayout(getWidget());
getLayoutManager().setNeedsLayout(this);
getWidget().makeScrollable();
handleSingleComponentMove();
}
/**
* Handles the case when there is only one child component and that
* component is moved between first <-> second. This does not trigger a
* hierarchy change event as the list of children contains the same
* component in both cases.
*/
private void handleSingleComponentMove() {
if (getChildComponents().size() == 1) {
Widget stateFirstChild = null;
Widget stateSecondChild = null;
if (getState().firstChild != null) {
stateFirstChild = ((ComponentConnector) getState().firstChild)
.getWidget();
}
if (getState().secondChild != null) {
stateSecondChild = ((ComponentConnector) getState().secondChild)
.getWidget();
}
if (stateFirstChild == getWidget().getSecondWidget()
|| stateSecondChild == getWidget().getFirstWidget()) {
handleHierarchyChange();
}
}
}
@Override
public void layout() {
VAbstractSplitPanel splitPanel = getWidget();
splitPanel.setSplitPosition(splitPanel.position);
splitPanel.updateSizes();
// Report relative sizes in other direction for quicker propagation
List children = getChildComponents();
for (ComponentConnector child : children) {
reportOtherDimension(child);
}
}
private void reportOtherDimension(ComponentConnector child) {
LayoutManager layoutManager = getLayoutManager();
if (this instanceof HorizontalSplitPanelConnector) {
if (child.isRelativeHeight()) {
int height = layoutManager
.getInnerHeight(getWidget().getElement());
layoutManager.reportHeightAssignedToRelative(child, height);
}
} else {
if (child.isRelativeWidth()) {
int width = layoutManager
.getInnerWidth(getWidget().getElement());
layoutManager.reportWidthAssignedToRelative(child, width);
}
}
}
@Override
public VAbstractSplitPanel getWidget() {
return (VAbstractSplitPanel) super.getWidget();
}
@Override
public AbstractSplitPanelState getState() {
return (AbstractSplitPanelState) super.getState();
}
private ComponentConnector getFirstChild() {
return (ComponentConnector) getState().firstChild;
}
private ComponentConnector getSecondChild() {
return (ComponentConnector) getState().secondChild;
}
@Override
public void onConnectorHierarchyChange(
ConnectorHierarchyChangeEvent event) {
handleHierarchyChange();
}
private void handleHierarchyChange() {
/*
* When the connector gets detached, the state isn't updated but there's
* still a hierarchy change -> verify that the child from the state is
* still our child before attaching the widget. See #10150.
*/
Widget newFirstChildWidget = null;
ComponentConnector firstChild = getFirstChild();
if (firstChild != null && firstChild.getParent() == this) {
newFirstChildWidget = firstChild.getWidget();
}
getWidget().setFirstWidget(newFirstChildWidget);
Widget newSecondChildWidget = null;
ComponentConnector secondChild = getSecondChild();
if (secondChild != null && secondChild.getParent() == this) {
newSecondChildWidget = secondChild.getWidget();
}
getWidget().setSecondWidget(newSecondChildWidget);
}
}