Alexander Wels has uploaded a new change for review.

Change subject: webadmin: Double click collapse system tree
......................................................................

webadmin: Double click collapse system tree

- Added quick way to collapse the system tree with a double click
- Added ability for the client to remember the system tree width
  state.
- Added a collapse button to quickly collapse the tree.
- Added an expand button to expand the tree if it is hidden.

Change-Id: Ida98ac456d9dd325ba1bf5676671bf53b5c3173e
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=999713
Signed-off-by: Alexander Wels <aw...@redhat.com>
---
A 
frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/ui/common/css/TabbedSplitLayout.css
M 
frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/MainSectionView.java
A 
frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/widget/main/TabbedSplitLayoutPanel.java
A 
frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/webadmin/images/collapse_splitter.png
A 
frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/webadmin/images/expand_splitter.png
5 files changed, 324 insertions(+), 5 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/21/23521/1

diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/ui/common/css/TabbedSplitLayout.css
 
b/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/ui/common/css/TabbedSplitLayout.css
new file mode 100644
index 0000000..e0700d9
--- /dev/null
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/ui/common/css/TabbedSplitLayout.css
@@ -0,0 +1,10 @@
+.sliderButton {
+    border: 0px;
+    background: transparent;
+    width: 8px;
+    height: 16px;
+    z-index: 2;
+    padding: 0px 0px 0px 0px;
+    margin: 7px 0px 0px 0px;
+    position: absolute;
+}
\ No newline at end of file
diff --git 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/MainSectionView.java
 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/MainSectionView.java
index 166a283..f9082f2 100644
--- 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/MainSectionView.java
+++ 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/MainSectionView.java
@@ -23,10 +23,13 @@
 import org.ovirt.engine.ui.webadmin.uicommon.model.TaskModelProvider;
 import org.ovirt.engine.ui.webadmin.widget.bookmark.BookmarkList;
 import org.ovirt.engine.ui.webadmin.widget.footer.AlertsEventsFooterView;
+import org.ovirt.engine.ui.webadmin.widget.main.TabbedSplitLayoutPanel;
 import org.ovirt.engine.ui.webadmin.widget.tags.TagList;
 import org.ovirt.engine.ui.webadmin.widget.tree.SystemTree;
 
 import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
 import com.google.gwt.dom.client.Style.Overflow;
 import com.google.gwt.dom.client.Style.Unit;
 import com.google.gwt.event.logical.shared.SelectionEvent;
@@ -45,6 +48,7 @@
 public class MainSectionView extends AbstractView implements 
MainSectionPresenter.ViewDef {
 
     private static final int BOOKMARK_INDEX = 1;
+    private static final int SPLITTER_THICKNESS = 4;
 
     interface ViewUiBinder extends UiBinder<Widget, MainSectionView> {
         ViewUiBinder uiBinder = GWT.create(ViewUiBinder.class);
@@ -100,8 +104,8 @@
             ClientStorage clientStorage, CommonApplicationConstants 
commonConstants) {
         westStackPanel = createWestStackPanel(treeModelProvider, 
bookmarkModelProvider, tagModelProvider);
 
-        verticalSplitLayoutPanel = new SplitLayoutPanel(4);
-        horizontalSplitLayoutPanel = new SplitLayoutPanel(4);
+        verticalSplitLayoutPanel = new SplitLayoutPanel(SPLITTER_THICKNESS);
+        horizontalSplitLayoutPanel = new 
TabbedSplitLayoutPanel(SPLITTER_THICKNESS, clientStorage);
 
         initWidget(ViewUiBinder.uiBinder.createAndBindUi(this));
         initHeaders(constants);
@@ -121,6 +125,17 @@
                 clientStorage,
                 constants);
         
headerPanel.getElement().getParentElement().getStyle().setOverflow(Overflow.VISIBLE);
+        //Enable double clicking to collapse/expand the stack panel (with the 
treeview).
+        
horizontalSplitLayoutPanel.setWidgetToggleDisplayAllowed(westStackPanel, true);
+        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+            @Override
+            public void execute() {
+                //Manually call onResize() so the tabs at the top are 
positioned correctly. For some reason
+                //doing setWidgetSize doesn't trigger the onResize event. Also 
this need to be deferred
+                //otherwise the handlers haven't been added yet, and the 
resize won't do anything.
+                westStackPanel.onResize();
+            }
+        });
     }
 
     private void initHeaders(ApplicationConstants constants) {
@@ -135,9 +150,9 @@
             @Override
             public void onResize() {
                 super.onResize();
-
-                if (uiHandlers != null) {
-                    uiHandlers.setMainTabBarOffset(getOffsetWidth());
+                Double westStackWidth = 
horizontalSplitLayoutPanel.getWidgetSize(westStackPanel);
+                if (uiHandlers != null && westStackWidth != null) {
+                    uiHandlers.setMainTabBarOffset(westStackWidth.intValue());
                 }
             }
         };
diff --git 
a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/widget/main/TabbedSplitLayoutPanel.java
 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/widget/main/TabbedSplitLayoutPanel.java
new file mode 100644
index 0000000..6b23be3
--- /dev/null
+++ 
b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/widget/main/TabbedSplitLayoutPanel.java
@@ -0,0 +1,294 @@
+package org.ovirt.engine.ui.webadmin.widget.main;
+
+import org.ovirt.engine.ui.common.system.ClientStorage;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.CssResource;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.user.client.ui.Image;
+import com.google.gwt.user.client.ui.LayoutPanel;
+import com.google.gwt.user.client.ui.PushButton;
+import com.google.gwt.user.client.ui.SplitLayoutPanel;
+import com.google.gwt.user.client.ui.Widget;
+
+public class TabbedSplitLayoutPanel extends SplitLayoutPanel {
+
+    /**
+     * Style sheet interface.
+     */
+    public interface TabbedSplitLayoutCss extends CssResource {
+        String sliderButton();
+    }
+
+    /**
+     * Tabbed Split Layout panel resources interface.
+     */
+    public interface TabbedSplitLayoutResources extends ClientBundle {
+        @Source("org/ovirt/engine/ui/common/css/TabbedSplitLayout.css")
+        TabbedSplitLayoutCss taggedSplitLayoutCss();
+
+        @Source("org/ovirt/engine/ui/webadmin/images/collapse_splitter.png")
+        ImageResource collapeSplitterButton();
+
+        @Source("org/ovirt/engine/ui/webadmin/images/expand_splitter.png")
+        ImageResource expandSplitterButton();
+    }
+
+    private static final String WEST_SPLITTER_KEY = 
"MAIN_WEST_SPLITTER_WIDTH"; //$NON-NLS-1$
+    private static final Double DEFAULT_STACK_PANEL_WIDTH = 235.0;
+
+    /**
+     * Tabbed Split Layout panel resources.
+     */
+    private static final TabbedSplitLayoutResources SPLIT_LAYOUT_RESOURCES =
+            GWT.create(TabbedSplitLayoutResources.class);
+
+    /**
+     * The style.
+     */
+    private final TabbedSplitLayoutCss style;
+
+    /**
+     * Collapse button.
+     */
+    private final PushButton collapseLeft;
+    /**
+     * Expand button.
+     */
+    private final PushButton expandLeft;
+
+    /**
+     * {@code ScheduleCommand} that forces a layout when resizing the panel.
+     */
+    private ScheduledCommand layoutCommand;
+
+    /**
+     * Inserted WEST panel, that will contain the collapse button.
+     */
+    private LayoutPanel westPanel = null;
+    /**
+     * Inserted CENTER panel, that will contain the expand button.
+     */
+    private LayoutPanel centerPanel = null;
+
+    /**
+     * Client storage to store the current west panel width in.
+     */
+    final ClientStorage clientStorage;
+
+    /**
+     * Constructor
+     * @param splitterSize Size width of the splitter bar.
+     */
+    public TabbedSplitLayoutPanel(int splitterSize, ClientStorage storage) {
+        super(splitterSize);
+        clientStorage = storage;
+        style = SPLIT_LAYOUT_RESOURCES.taggedSplitLayoutCss();
+        style.ensureInjected();
+        collapseLeft = 
createButton(SPLIT_LAYOUT_RESOURCES.collapeSplitterButton());
+        expandLeft = 
createButton(SPLIT_LAYOUT_RESOURCES.expandSplitterButton());
+    }
+
+    /**
+     * If the direction is WEST and the west panel has not been inserted yet, 
then create a new {@code LayoutPanel},
+     * and insert the passed in {@code Widget} into that panel, and insert the 
panel into the {@code SplitLayoutPanel}.
+     * If the direction is CENTER and the center panel has not been inserted 
yet, then create a new {@code LayoutPanel},
+     * and insert the passed in {@code Widget} into that panel, and insert the 
panel into the {@code SplitLayoutPanel}.
+     */
+    @Override
+    public void insert(Widget child, Direction direction, double size, Widget 
before) {
+        Widget insertedWidget = child;
+        if (direction == Direction.WEST) {
+            if (westPanel == null) {
+                westPanel = new LayoutPanel();
+                collapseLeft.setVisible(true);
+                westPanel.add(collapseLeft);
+                size = getStoredStackPanelWidth();
+            }
+            westPanel.add(child);
+            insertedWidget = westPanel;
+        } else if (direction == Direction.CENTER) {
+            if (centerPanel == null) {
+                centerPanel = new LayoutPanel();
+                centerPanel.add(expandLeft);
+            }
+            centerPanel.add(child);
+            insertedWidget = centerPanel;
+        }
+        super.insert(insertedWidget, direction, size, before);
+    }
+
+    /**
+     * Create a new expand/collapse button.
+     * @param imageResource The {@code ImageResource} to use to style the 
button.
+     * @return A new {@code PushButton}.
+     */
+    private PushButton createButton(ImageResource imageResource) {
+        PushButton result = new PushButton(new Image(imageResource), new 
ClickHandler() {
+
+            @Override
+            public void onClick(ClickEvent event) {
+                toggleVisibleWestPanel();
+            }
+
+        });
+        result.setVisible(false);
+        result.addStyleName(style.sliderButton());
+        return result;
+    }
+
+    /**
+     * Toggle the west panel. If it is visible, hide it and vice versa.
+     */
+    private void toggleVisibleWestPanel() {
+        LayoutData layout = (LayoutData) westPanel.getLayoutData();
+        if (layout.size == 0) {
+            double size = layout.oldSize;
+            if (size == 0) {
+                //The old size is 0, so we should restore the default size.
+                size = DEFAULT_STACK_PANEL_WIDTH;
+            }
+            // Restore the old size.
+            setWestPanelSize(size);
+        } else {
+             //Collapse to size 0.
+            layout.oldSize = layout.size;
+            setWestPanelSize(0);
+        }
+    }
+
+    /**
+     * Set the west panel size.
+     * @param size The new size.
+     */
+    private void setWestPanelSize(double size) {
+        LayoutData layout = (LayoutData) westPanel.getLayoutData();
+        if (size == layout.size) {
+            return;
+        }
+
+        layout.size = size;
+        // Defer actually updating the layout, so that if we receive many
+        // mouse events before layout/paint occurs, we'll only update once.
+        if (layoutCommand == null) {
+            layoutCommand = new ScheduledCommand() {
+                @Override
+                public void execute() {
+                    layoutCommand = null;
+                    forceLayout();
+                }
+            };
+            Scheduler.get().scheduleDeferred(layoutCommand);
+        }
+    }
+
+    /**
+     * After load, set the the position of the collapse and expand buttons. 
Including visibility.
+     */
+    @Override
+    public void onLoad() {
+        super.onLoad();
+        Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
+
+            @Override
+            public void execute() {
+                determineButtonVisiblity();
+                positionLeftCollapseButton();
+            }
+        });
+    }
+
+    @Override
+    public void onResize() {
+        super.onResize();
+        double currentWidth = westPanel.getOffsetWidth();
+        setStoredSplitterWidth(currentWidth);
+        determineButtonVisiblity();
+        positionLeftCollapseButton();
+    }
+
+    /**
+     * Determine if the expand or collapse button should be visible.
+     */
+    private void determineButtonVisiblity() {
+        if (westPanel.getOffsetWidth() == 0) { // Completely collapsed.
+            expandLeft.setVisible(true);
+            collapseLeft.setVisible(false);
+        } else {
+            expandLeft.setVisible(false);
+            collapseLeft.setVisible(true);
+        }
+    }
+
+    /**
+     * Position the collapse button to be proper in relation to the splitter 
bar.
+     */
+    private void positionLeftCollapseButton() {
+        collapseLeft.getElement().getStyle().setLeft(
+                westPanel.getOffsetWidth() - collapseLeft.getOffsetWidth(), 
Unit.PX);
+    }
+
+    @Override
+    public void setWidgetToggleDisplayAllowed(Widget widget, boolean allowed) {
+        super.setWidgetToggleDisplayAllowed(getActualWidget(widget), allowed);
+    }
+
+    @Override
+    public void setWidgetSize(Widget widget, double size) {
+        super.setWidgetSize(getActualWidget(widget), size);
+    }
+
+    @Override
+    public Double getWidgetSize(Widget widget) {
+        return super.getWidgetSize(getActualWidget(widget));
+    }
+
+    /**
+     * Determine if the passed in widget is part of the west or center panel, 
if so return the center or west panel
+     * as the widget, so the super class will handle the operation properly.
+     * @param widget The {@code Widget} to use to determine if we should 
return the panel or the widget.
+     * @return A {@code Widget} that is either the original, or a panel that 
contains the widget.
+     */
+    private Widget getActualWidget(Widget widget) {
+        Widget checkedWidget = widget;
+        if (westPanel != null && widget.getParent() == westPanel) {
+            checkedWidget = westPanel;
+        } else if (centerPanel != null && widget.getParent() == centerPanel) {
+            checkedWidget = centerPanel;
+        }
+        return checkedWidget;
+    }
+
+    /**
+     * Retrieve the stored stack panel width.
+     * @return The west stack panel width as a {@code double}
+     */
+    private double getStoredStackPanelWidth() {
+        String widthString = clientStorage.getLocalItem(WEST_SPLITTER_KEY);
+        double width = DEFAULT_STACK_PANEL_WIDTH; //In case there was no 
stored width, use the default.
+        try {
+            if (widthString != null) {
+                width = Double.valueOf(widthString);
+            }
+        } catch (NumberFormatException nfe) {
+            //Do nothing.
+        }
+        return width;
+    }
+
+    /**
+     * Store the current width in the {@code ClientStorage} of the browser so 
we can recall it when we log in.
+     * @param width The current width in pixels.
+     */
+    private void setStoredSplitterWidth(Double width) {
+        clientStorage.setLocalItem(WEST_SPLITTER_KEY, width.toString());
+    }
+
+
+}
diff --git 
a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/webadmin/images/collapse_splitter.png
 
b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/webadmin/images/collapse_splitter.png
new file mode 100644
index 0000000..feebe9f
--- /dev/null
+++ 
b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/webadmin/images/collapse_splitter.png
Binary files differ
diff --git 
a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/webadmin/images/expand_splitter.png
 
b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/webadmin/images/expand_splitter.png
new file mode 100644
index 0000000..d61dd4a
--- /dev/null
+++ 
b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/webadmin/images/expand_splitter.png
Binary files differ


-- 
To view, visit http://gerrit.ovirt.org/23521
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ida98ac456d9dd325ba1bf5676671bf53b5c3173e
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: ovirt-engine-3.4
Gerrit-Owner: Alexander Wels <aw...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to