Browse Source

Fix grid details height calculation issue (#10453)

tags/7.7.13
Adam Wagner 6 years ago
parent
commit
54ade25d58

+ 20
- 0
client/src/main/java/com/vaadin/client/WidgetUtil.java View File

@@ -1881,6 +1881,26 @@ public class WidgetUtil {
return integerPart + ((int) nrFractions) / divisor;
}

/**
* Returns whether the given element is displayed.
* <p>
* This method returns false if either the given element or any of its
* ancestors has the style {@code display: none} applied.
*
* @param element
* the element to test for visibility
* @return {@code true} if the element is displayed, {@code false} otherwise
* @since 7.7.13
*/
public static native boolean isDisplayed(Element element)
/*-{
// This measurement is borrowed from JQuery and measures the visible
// size of the element. The measurement should return false when either
// the element or any of its ancestors has "display: none" style.
return !!(element.offsetWidth || element.offsetHeight
|| element.getClientRects().length);
}-*/;

/**
* Utility methods for displaying error message on components.
*

+ 29
- 3
client/src/main/java/com/vaadin/client/connectors/GridConnector.java View File

@@ -56,6 +56,8 @@ import com.vaadin.client.ui.layout.ElementResizeEvent;
import com.vaadin.client.ui.layout.ElementResizeListener;
import com.vaadin.client.widget.escalator.events.RowHeightChangedEvent;
import com.vaadin.client.widget.escalator.events.RowHeightChangedHandler;
import com.vaadin.client.widget.escalator.events.SpacerVisibilityChangedEvent;
import com.vaadin.client.widget.escalator.events.SpacerVisibilityChangedHandler;
import com.vaadin.client.widget.grid.CellReference;
import com.vaadin.client.widget.grid.CellStyleGenerator;
import com.vaadin.client.widget.grid.EditorHandler;
@@ -496,6 +498,8 @@ public class GridConnector extends AbstractHasComponentsConnector
private class CustomDetailsGenerator
implements HeightAwareDetailsGenerator {



private final Map<String, ComponentConnector> idToDetailsMap = new HashMap<String, ComponentConnector>();
private final Map<String, Integer> idToRowIndex = new HashMap<String, Integer>();
private final Map<Element, ScheduledCommand> elementToResizeCommand = new HashMap<Element, Scheduler.ScheduledCommand>();
@@ -544,9 +548,13 @@ public class GridConnector extends AbstractHasComponentsConnector
if (spacerCellBorderHeights != null
&& !getLayoutManager().isLayoutRunning()
&& hasDetailsOpen(rowIndex)) {
double height = getLayoutManager().getOuterHeightDouble(
element) + spacerCellBorderHeights;
getWidget().setDetailsHeight(rowIndex, height);
// Measure and set details height if element is visible
if (WidgetUtil.isDisplayed(element)) {
double height =
getLayoutManager().getOuterHeightDouble(
element) + spacerCellBorderHeights;
getWidget().setDetailsHeight(rowIndex, height);
}
}
}
};
@@ -874,6 +882,24 @@ public class GridConnector extends AbstractHasComponentsConnector
}
});

// When details element is shown, remeasure it in the layout phase.
// This is necessary because details might've been laid out incorrectly
// while they were out of view.
getWidget().addSpacerVisibilityChangedHandler(
new SpacerVisibilityChangedHandler() {
@Override
public void onSpacerVisibilityChanged(
SpacerVisibilityChangedEvent event) {
if (event.isVisible()) {
ComponentConnector connector = customDetailsGenerator.idToDetailsMap
.get(customDetailsGenerator
.getId(event.getRowIndex()));
getLayoutManager()
.setNeedsMeasureRecursively(connector);
}
}
});

layout();
}


+ 84
- 0
client/src/main/java/com/vaadin/client/widget/escalator/events/SpacerVisibilityChangedEvent.java View File

@@ -0,0 +1,84 @@
/*
* Copyright 2000-2014 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.widget.escalator.events;

import com.google.gwt.event.shared.GwtEvent;

/**
* Event fired when a spacer element is hidden or shown in Escalator.
*
* @author Vaadin Ltd
* @since 7.7.13
*/
public class SpacerVisibilityChangedEvent
extends GwtEvent<SpacerVisibilityChangedHandler> {

/**
* Handler type.
*/
public static final Type<SpacerVisibilityChangedHandler> TYPE = new Type<SpacerVisibilityChangedHandler>();

public static final Type<SpacerVisibilityChangedHandler> getType() {
return TYPE;
}

private final int rowIndex;
private final boolean visible;

/**
* Creates a spacer visibility changed event.
*
* @param rowIndex
* index of row to which the spacer belongs
* @param visible
* {@code true} if the spacer element is shown, {@code false} if the
* spacer element is hidden
*/
public SpacerVisibilityChangedEvent(int rowIndex, boolean visible) {
this.rowIndex = rowIndex;
this.visible = visible;
}

/**
* Gets the row index to which the spacer element belongs.
*
* @return the row index to which the spacer element belongs
*/
public int getRowIndex() {
return rowIndex;
}

/**
* Gets whether the spacer element is displayed.
*
* @return {@code true} if the spacer element is shown, {@code false} if the
* spacer element is hidden
*/
public boolean isVisible() {
return visible;
}

@Override
public Type<SpacerVisibilityChangedHandler> getAssociatedType() {
return TYPE;
}

@Override
protected void dispatch(SpacerVisibilityChangedHandler handler) {
handler.onSpacerVisibilityChanged(this);
}

}

+ 36
- 0
client/src/main/java/com/vaadin/client/widget/escalator/events/SpacerVisibilityChangedHandler.java View File

@@ -0,0 +1,36 @@
/*
* Copyright 2000-2014 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.widget.escalator.events;

import com.google.gwt.event.shared.EventHandler;

/**
* Event handler for a spacer visibility changed event.
*
* @author Vaadin Ltd
* @since 7.7.13
*/
public interface SpacerVisibilityChangedHandler extends EventHandler {

/**
* Called when a spacer visibility changed event is fired, when a spacer's
* visibility changes.
*
* @param event
* the spacer visibility changed event
*/
public void onSpacerVisibilityChanged(SpacerVisibilityChangedEvent event);
}

+ 5
- 0
client/src/main/java/com/vaadin/client/widgets/Escalator.java View File

@@ -85,6 +85,7 @@ import com.vaadin.client.widget.escalator.ScrollbarBundle.VerticalScrollbarBundl
import com.vaadin.client.widget.escalator.Spacer;
import com.vaadin.client.widget.escalator.SpacerUpdater;
import com.vaadin.client.widget.escalator.events.RowHeightChangedEvent;
import com.vaadin.client.widget.escalator.events.SpacerVisibilityChangedEvent;
import com.vaadin.client.widget.grid.events.ScrollEvent;
import com.vaadin.client.widget.grid.events.ScrollHandler;
import com.vaadin.client.widgets.Escalator.JsniUtil.TouchHandlerBundle;
@@ -4820,11 +4821,15 @@ public class Escalator extends Widget
public void show() {
getRootElement().getStyle().clearDisplay();
getDecoElement().getStyle().clearDisplay();
Escalator.this.fireEvent(
new SpacerVisibilityChangedEvent(getRow(), true));
}

public void hide() {
getRootElement().getStyle().setDisplay(Display.NONE);
getDecoElement().getStyle().setDisplay(Display.NONE);
Escalator.this.fireEvent(
new SpacerVisibilityChangedEvent(getRow(), false));
}

/**

+ 14
- 0
client/src/main/java/com/vaadin/client/widgets/Grid.java View File

@@ -109,6 +109,8 @@ import com.vaadin.client.widget.escalator.Spacer;
import com.vaadin.client.widget.escalator.SpacerUpdater;
import com.vaadin.client.widget.escalator.events.RowHeightChangedEvent;
import com.vaadin.client.widget.escalator.events.RowHeightChangedHandler;
import com.vaadin.client.widget.escalator.events.SpacerVisibilityChangedEvent;
import com.vaadin.client.widget.escalator.events.SpacerVisibilityChangedHandler;
import com.vaadin.client.widget.grid.AutoScroller;
import com.vaadin.client.widget.grid.AutoScroller.AutoScrollerCallback;
import com.vaadin.client.widget.grid.AutoScroller.ScrollAxis;
@@ -8463,6 +8465,18 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
return escalator.addHandler(handler, RowHeightChangedEvent.TYPE);
}

/**
* Adds a spacer visibility changed handler to the underlying escalator.
*
* @param handler
* the handler to be called when a spacer's visibility changes
* @return the registration object with which the handler can be removed
*/
public HandlerRegistration addSpacerVisibilityChangedHandler(
SpacerVisibilityChangedHandler handler) {
return escalator.addHandler(handler, SpacerVisibilityChangedEvent.TYPE);
}

/**
* Adds a low-level DOM event handler to this Grid. The handler is inserted
* into the given position in the list of handlers. The handlers are invoked

Loading…
Cancel
Save