Bug 411724 - Hidden toolbar doesn't stay hidden
authorStefan Xenos <sxenos@google.com>
Fri, 8 May 2015 05:09:07 +0000 (22:09 -0700)
committerLars Vogel <lars.vogel@vogella.com>
Fri, 8 May 2015 19:44:49 +0000 (15:44 -0400)
CleanupAddon contained code to automatically make a UI element
visible when one of its children became visible. This is
appropriate for part stacks and sash containers but not for
toolbars, so we use instanceof checks to ensure we're using
it when appropriate.

Change-Id: I821b96ddffea10ed10840ed64fed7cc05e488bae
Signed-off-by: Stefan Xenos <sxenos@google.com>
bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/cleanupaddon/CleanupAddon.java

index fbb8b26..29ba353 100644 (file)
@@ -22,7 +22,9 @@ import org.eclipse.e4.ui.model.application.ui.MUIElement;
 import org.eclipse.e4.ui.model.application.ui.advanced.MArea;
 import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
 import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack;
+import org.eclipse.e4.ui.model.application.ui.basic.MCompositePart;
 import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer;
+import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
 import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar;
 import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
 import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
@@ -138,6 +140,23 @@ public class CleanupAddon {
                }
        }
 
+       /**
+        * Returns true if and only if the given element should make itself visible
+        * when its first child becomes visible and make itself invisible whenever
+        * its last child becomes invisible. Defaults to false for unknown element
+        * types
+        */
+       private static boolean shouldReactToChildVisibilityChanges(MUIElement theElement) {
+               // TODO: It may be possible to remove the instanceof checks and just use
+               // IPresentationEngine.HIDDEN_EXPLICITLY. However, that would require
+               // explicitly setting IPresentationEngine.HIDDEN_EXPLICITLY on every
+               // object where we want to keep it hidden even if it has a visible child
+               // (such as the main toolbar).
+               return (theElement instanceof MPartSashContainer || theElement instanceof MPartStack
+                               || theElement instanceof MCompositePart)
+                               && !theElement.getTags().contains(IPresentationEngine.HIDDEN_EXPLICITLY);
+       }
+
        @Inject
        @Optional
        private void subscribeVisibilityChanged(
@@ -149,14 +168,17 @@ public class CleanupAddon {
                if (changedObj.getWidget() instanceof Shell) {
                        ((Shell) changedObj.getWidget()).setVisible(changedObj.isVisible());
                } else if (changedObj.getWidget() instanceof Rectangle) {
+                       MElementContainer<MUIElement> parent = changedObj.getParent();
+                       if (!shouldReactToChildVisibilityChanges(parent)) {
+                               return;
+                       }
+
                        if (changedObj.isVisible()) {
                                // Make all the parents visible
-                               MUIElement parent = changedObj.getParent();
                                if (!parent.isVisible())
                                        parent.setVisible(true);
                        } else {
                                // If there are no more 'visible' children then make the parent go away too
-                               MElementContainer<MUIElement> parent = changedObj.getParent();
                                boolean makeInvisible = true;
                                for (MUIElement kid : parent.getChildren()) {
                                        if (kid.isToBeRendered() && kid.isVisible()) {
@@ -173,6 +195,7 @@ public class CleanupAddon {
                        if (parent == null || ((Object) parent) instanceof MToolBar) {
                                return;
                        }
+
                        if (changedObj.isVisible()) {
                                if (parent.getRenderer() != null) {
                                        Object myParent = ((AbstractPartRenderer) parent.getRenderer())
@@ -196,6 +219,10 @@ public class CleanupAddon {
                                                ctrl.getShell().layout(new Control[] { ctrl }, SWT.DEFER);
                                        }
 
+                                       if (!shouldReactToChildVisibilityChanges(parent)) {
+                                               return;
+                                       }
+
                                        // Check if the parent is visible
                                        if (!parent.isVisible())
                                                parent.setVisible(true);
@@ -223,6 +250,10 @@ public class CleanupAddon {
                                        }
                                }
 
+                               if (!shouldReactToChildVisibilityChanges(parent)) {
+                                       return;
+                               }
+
                                // Special check: If a perspective goes invisibe we need to make its
                                // PerspectiveStack invisible as well...see bug 369528
                                if (makeParentInvisible)