Ramesh N has uploaded a new change for review. Change subject: webadmin: UI plugins - control tab priority ......................................................................
webadmin: UI plugins - control tab priority When adding custom main or sub tab, UI plugins can now specify the priority of the tab, denoting its relative position within the tab panel. Standard main and sub tabs typically have their priority starting at 0 (left-most tab) and incremented by 1 for each next tab. For example, "DataCenter" main tab priority is 0, "Cluster" main tab priority is 1, and so on. Example usage: api.addMainTab('Test', 'test-tab', 'plugin/TestPlugin/tab.html', // tab options object, as documented at // http://www.ovirt.org/Features/UIPlugins#Main_and_sub_tabs { priority: -1 // position this tab before all standard ones } ); This patch also improves priority comparison in AbstractTabPanel to account for rounding procedure, e.g. representing real numbers in a floating point number system. Change-Id: I1251ccbe7b3cfbb378fa31ef6009184216409265 Bug-Url: https://bugzilla.redhat.com/1214624 Signed-off-by: Vojtech Szocs <vsz...@redhat.com> --- A frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/utils/FloatingPointHelper.java M frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/tab/AbstractTabPanel.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/api/PluginUiFunctions.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/api/TabOptions.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/DynamicUrlContentTabProxyFactory.java 5 files changed, 85 insertions(+), 5 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/32/41032/1 diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/utils/FloatingPointHelper.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/utils/FloatingPointHelper.java new file mode 100644 index 0000000..f7333b5 --- /dev/null +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/utils/FloatingPointHelper.java @@ -0,0 +1,64 @@ +package org.ovirt.engine.ui.common.utils; + +/** + * Helper class for working with floating point numbers, such as JavaScript {@code number} + * and its Java {@code double} equivalent. + */ +public class FloatingPointHelper { + + /** + * Machine epsilon for JavaScript {@code number} type, lazily initialized to value + * {@code pow(2, -53)}. This number represents an upper bound on the relative error + * due to rounding in floating point arithmetic. + */ + private static double epsilon; + + /** + * Returns {@code true} if {@code a} and {@code b} are numerically equal using + * {@linkplain #epsilon machine epsilon} to account for rounding procedure. + * + * @return {@code true} if {@code a} is numerically equal to {@code b}. + */ + public static native boolean epsEqual(Double a, Double b) /*-{ + var aValue = a...@java.lang.Double::doubleValue()(); + var bValue = b...@java.lang.Double::doubleValue()(); + + if (!@org.ovirt.engine.ui.common.utils.FloatingPointHelper::epsilon) { + @org.ovirt.engine.ui.common.utils.FloatingPointHelper::epsilon = Math.pow(2, -53); + } + + return Math.abs(aValue - bValue) < @org.ovirt.engine.ui.common.utils.FloatingPointHelper::epsilon; + }-*/; + + /** + * Compares {@code a} and {@code b} using {@linkplain #epsilon machine epsilon} + * to account for rounding procedure. + * + * @return {@code 0} if {@code a} is numerically equal to {@code b}, + * value less than {@code 0} if {@code a} is numerically less than {@code b}, + * value greater than {@code 0} if {@code a} is numerically greater than {@code b}. + */ + public static int epsCompare(Double a, Double b) { + if (epsEqual(a, b)) { + return 0; + } + + return (a < b) ? -1 : 1; + } + + /** + * {@link #epsCompare(Double, Double) epsCompare} method adapted for Float arguments. + * <p> + * In production mode, GWT implements all Java numeric types as JavaScript {@code number} + * so any operations on {@code float} are performed as on {@code double} and will result + * in more-than-expected precision. + * + * @return {@code 0} if {@code a} is numerically equal to {@code b}, + * value less than {@code 0} if {@code a} is numerically less than {@code b}, + * value greater than {@code 0} if {@code a} is numerically greater than {@code b}. + */ + public static int epsCompare(Float a, Float b) { + return epsCompare(a.doubleValue(), b.doubleValue()); + } + +} diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/tab/AbstractTabPanel.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/tab/AbstractTabPanel.java index 25f9e01..fd6ec88 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/tab/AbstractTabPanel.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/tab/AbstractTabPanel.java @@ -4,6 +4,7 @@ import java.util.List; import org.ovirt.engine.ui.common.presenter.DynamicTabContainerPresenter.DynamicTabPanel; +import org.ovirt.engine.ui.common.utils.FloatingPointHelper; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; @@ -38,7 +39,9 @@ int beforeIndex; for (beforeIndex = 0; beforeIndex < tabList.size(); ++beforeIndex) { - if (newTab.getPriority() < tabList.get(beforeIndex).getPriority()) { + TabDefinition currentTab = tabList.get(beforeIndex); + + if (FloatingPointHelper.epsCompare(newTab.getPriority(), currentTab.getPriority()) < 0) { break; } } diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/api/PluginUiFunctions.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/api/PluginUiFunctions.java index 7271fda..5eff9a5 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/api/PluginUiFunctions.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/api/PluginUiFunctions.java @@ -99,7 +99,8 @@ // Create and bind tab presenter proxy dynamicUrlContentTabProxyFactory.create( requestTabsEventType, changeTabEventType, slot, - label, historyToken, isMainTab, contentUrl, + label, options.getPriority().floatValue(), + historyToken, isMainTab, contentUrl, options.getAlignRight() ? Align.RIGHT : Align.LEFT); // Redraw the corresponding tab container diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/api/TabOptions.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/api/TabOptions.java index 91b653c..2d957fb 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/api/TabOptions.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/api/TabOptions.java @@ -19,4 +19,16 @@ return getValueAsBoolean("alignRight", false); //$NON-NLS-1$ } + /** + * Returns the priority of the tab, denoting its relative position within the tab panel. + * <p> + * Standard main and sub tabs typically have their priority starting at 0 (left-most tab) + * and incremented by 1 for each next tab. + * <p> + * Default return value: {@code Double.MAX_VALUE} + */ + public Double getPriority() { + return getValueAsDouble("priority", Double.MAX_VALUE); //$NON-NLS-1$ + } + } diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/DynamicUrlContentTabProxyFactory.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/DynamicUrlContentTabProxyFactory.java index afa5cab..c0c3654 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/DynamicUrlContentTabProxyFactory.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/DynamicUrlContentTabProxyFactory.java @@ -34,13 +34,13 @@ Type<RequestTabsHandler> requestTabsEventType, Type<ChangeTabHandler> changeTabEventType, Type<RevealContentHandler<?>> slot, - String label, String historyToken, boolean isMainTab, - String contentUrl, Align align) { + String label, float priority, String historyToken, + boolean isMainTab, String contentUrl, Align align) { return new DynamicUrlContentTabProxy( placeManager, eventBus, gatekeeper, requestTabsEventType, changeTabEventType, slot, viewProvider, - label, Float.MAX_VALUE, historyToken, + label, priority, historyToken, isMainTab, contentUrl, align); } -- To view, visit https://gerrit.ovirt.org/41032 To unsubscribe, visit https://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1251ccbe7b3cfbb378fa31ef6009184216409265 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: ovirt-engine-3.5-gluster Gerrit-Owner: Ramesh N <rnach...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches