]> source.dussan.org Git - vaadin-framework.git/commitdiff
Show declarative output for component selected in debug window (#17960)
authorArtur Signell <artur@vaadin.com>
Fri, 22 May 2015 17:38:35 +0000 (20:38 +0300)
committerVaadin Code Review <review@vaadin.com>
Thu, 28 May 2015 14:04:46 +0000 (14:04 +0000)
Change-Id: I975eef2f06db4395925f76e40c044078028b0e66

client/src/com/vaadin/client/debug/internal/HierarchySection.java
client/src/com/vaadin/client/debug/internal/Icon.java
client/src/com/vaadin/client/debug/internal/theme/font.eot
client/src/com/vaadin/client/debug/internal/theme/font.svg
client/src/com/vaadin/client/debug/internal/theme/font.ttf
client/src/com/vaadin/client/debug/internal/theme/font.woff
client/src/com/vaadin/client/ui/ui/UIConnector.java
server/src/com/vaadin/ui/UI.java
shared/src/com/vaadin/shared/ui/ui/DebugWindowServerRpc.java

index c772a9d267b7efc5a4e2be6efdf0788ae5ab7222..ffb4042e69944c129362232cda0b6dbea2130d2f 100644 (file)
@@ -66,9 +66,69 @@ public class HierarchySection implements Section {
             "Show used connectors and how to optimize widgetset");
     private final Button showHierarchy = new DebugButton(Icon.HIERARCHY,
             "Show the connector hierarchy tree");
+    private final Button generateDesign = new DebugButton(Icon.SHOW_DESIGN,
+            "Generate a declarative design for the given component sub tree");
 
     private HandlerRegistration highlightModeRegistration = null;
 
+    public interface FindHandler {
+
+        /**
+         * Called when the user hovers over a connector, which is highlighted.
+         * Also called when hovering outside the tree, e.g. over the debug
+         * console, but in this case the connector is null
+         * 
+         * @param connector
+         */
+        void onHover(ComponentConnector connector);
+
+        /**
+         * Called when the user clicks on a highlighted connector.
+         * 
+         * @param connector
+         */
+        void onSelected(ComponentConnector connector);
+
+    }
+
+    private FindHandler inspectComponent = new FindHandler() {
+
+        @Override
+        public void onHover(ComponentConnector connector) {
+            if (connector == null) {
+                infoPanel.clear();
+            } else {
+                printState(connector, false);
+            }
+        }
+
+        @Override
+        public void onSelected(ComponentConnector connector) {
+            stopFind();
+            printState(connector, true);
+        }
+
+    };
+    private FindHandler showComponentDesign = new FindHandler() {
+
+        @Override
+        public void onHover(ComponentConnector connector) {
+            Highlight.showOnly(connector);
+        }
+
+        @Override
+        public void onSelected(ComponentConnector connector) {
+            stopFind();
+            connector.getConnection().getUIConnector()
+                    .showServerDesign(connector);
+            content.setWidget(new HTML(
+                    "Design file for component sent to server log"));
+        }
+
+    };
+
+    private FindHandler activeFindHandler;
+
     public HierarchySection() {
         controls.add(showHierarchy);
         showHierarchy.setStylePrimaryName(VDebugWindow.STYLENAME_BUTTON);
@@ -84,7 +144,7 @@ public class HierarchySection implements Section {
         find.addClickHandler(new ClickHandler() {
             @Override
             public void onClick(ClickEvent event) {
-                toggleFind();
+                toggleFind(inspectComponent);
             }
         });
 
@@ -107,6 +167,17 @@ public class HierarchySection implements Section {
             }
         });
 
+        controls.add(generateDesign);
+        generateDesign.setStylePrimaryName(VDebugWindow.STYLENAME_BUTTON);
+        generateDesign.addClickHandler(new ClickHandler() {
+            @Override
+            public void onClick(ClickEvent event) {
+                content.setWidget(new HTML(
+                        "Select a layout or component to generate the declarative design"));
+                toggleFind(showComponentDesign);
+            }
+        });
+
         hierarchyPanel.addListener(new SelectConnectorListener() {
             @Override
             public void select(ServerConnector connector, Element element) {
@@ -132,7 +203,8 @@ public class HierarchySection implements Section {
                 + showHierarchy.getTitle() + "<br/>" + find.getHTML() + " "
                 + find.getTitle() + "<br/>" + analyze.getHTML() + " "
                 + analyze.getTitle() + "<br/>" + generateWS.getHTML() + " "
-                + generateWS.getTitle() + "<br/>");
+                + generateWS.getTitle() + "<br/>" + generateDesign.getHTML()
+                + " " + generateDesign.getTitle() + "<br/>");
         info.setStyleName(VDebugWindow.STYLENAME + "-info");
         helpPanel.add(info);
     }
@@ -189,33 +261,62 @@ public class HierarchySection implements Section {
         // NOP
     }
 
+    private boolean isFindMode(FindHandler handler) {
+        return activeFindHandler == handler;
+    }
+
     private boolean isFindMode() {
-        return (highlightModeRegistration != null);
+        return (activeFindHandler != null);
     }
 
-    private void toggleFind() {
+    private void toggleFind(FindHandler handler) {
         if (isFindMode()) {
-            stopFind();
+            // Currently finding something
+            if (isFindMode(handler)) {
+                // Toggle off, stop finding
+                stopFind();
+                return;
+            } else {
+                // Stop finding something else, start finding this
+                stopFind();
+                startFind(handler);
+            }
         } else {
-            startFind();
+            // Not currently finding anything
+            startFind(handler);
         }
     }
 
-    private void startFind() {
+    private void startFind(FindHandler handler) {
+        if (isFindMode()) {
+            stopFind();
+        }
         Highlight.hideAll();
-        if (!isFindMode()) {
-            highlightModeRegistration = Event
-                    .addNativePreviewHandler(highlightModeHandler);
+
+        highlightModeRegistration = Event
+                .addNativePreviewHandler(highlightModeHandler);
+        activeFindHandler = handler;
+        if (handler == inspectComponent) {
             find.addStyleDependentName(VDebugWindow.STYLENAME_ACTIVE);
+        } else if (handler == showComponentDesign) {
+            generateDesign.addStyleDependentName(VDebugWindow.STYLENAME_ACTIVE);
         }
+
     }
 
+    /**
+     * Stop any current find operation, regardless of the handler
+     */
     private void stopFind() {
-        if (isFindMode()) {
-            highlightModeRegistration.removeHandler();
-            highlightModeRegistration = null;
-            find.removeStyleDependentName(VDebugWindow.STYLENAME_ACTIVE);
+        if (!isFindMode()) {
+            return;
         }
+
+        highlightModeRegistration.removeHandler();
+        highlightModeRegistration = null;
+        find.removeStyleDependentName(VDebugWindow.STYLENAME_ACTIVE);
+        generateDesign.removeStyleDependentName(VDebugWindow.STYLENAME_ACTIVE);
+        activeFindHandler = null;
     }
 
     private void printState(ServerConnector connector, boolean serverDebug) {
@@ -244,7 +345,9 @@ public class HierarchySection implements Section {
                 Element eventTarget = WidgetUtil.getElementFromPoint(event
                         .getNativeEvent().getClientX(), event.getNativeEvent()
                         .getClientY());
+
                 if (VDebugWindow.get().getElement().isOrHasChild(eventTarget)) {
+                    // Do not prevent using debug window controls
                     infoPanel.clear();
                     return;
                 }
@@ -258,21 +361,21 @@ public class HierarchySection implements Section {
                                 RootPanel.get(), eventTarget);
                     }
                     if (connector != null) {
-                        printState(connector, false);
+                        activeFindHandler.onHover(connector);
                         event.cancel();
                         event.consume();
                         event.getNativeEvent().stopPropagation();
                         return;
                     }
                 }
-                infoPanel.clear();
+                // Not over any connector
+                activeFindHandler.onHover(null);
             }
             if (event.getTypeInt() == Event.ONCLICK) {
                 Highlight.hideAll();
                 event.cancel();
                 event.consume();
                 event.getNativeEvent().stopPropagation();
-                stopFind();
                 Element eventTarget = WidgetUtil.getElementFromPoint(event
                         .getNativeEvent().getClientX(), event.getNativeEvent()
                         .getClientY());
@@ -286,10 +389,12 @@ public class HierarchySection implements Section {
                     }
 
                     if (connector != null) {
-                        printState(connector, true);
+                        activeFindHandler.onSelected(connector);
                         return;
                     }
                 }
+                // Click on something else -> stop find operation
+                stopFind();
             }
             event.cancel();
         }
index d05eca2f6f6f24eac8bf7a3d70958f595b3b4bb7..a30dc05fcb5234d641b7346ea1105d9b8cafed21 100644 (file)
@@ -18,6 +18,7 @@ package com.vaadin.client.debug.internal;
 
 public enum Icon {
 
+    // Font can be updated using e.g. http://icomoon.io/
     SEARCH("&#xf002;"), //
     OK("&#xf00c;"), //
     REMOVE("&#xf00d;"), //
@@ -46,6 +47,7 @@ public enum Icon {
     RESET("&#xf021;"), //
     PERSIST("&#xf02e"), //
     TESTBENCH("&#xe600"), //
+    SHOW_DESIGN("&#xf1c9"), //
     ;
 
     private String id;
index cf38942e0a7f779e96391a916fde65f8dc0240b8..0244d9afcca8345e97de4d884ce0a131e8e21e57 100755 (executable)
Binary files a/client/src/com/vaadin/client/debug/internal/theme/font.eot and b/client/src/com/vaadin/client/debug/internal/theme/font.eot differ
index c5a97a6c8b80af47063737730b9f356c679e87f8..313645c78fc4197b189efc58cf5387671e5680c9 100755 (executable)
@@ -33,4 +33,5 @@
 <glyph unicode="&#xf10c;" d="M731.428 448q0 59.428-23.144 113.428t-62.572 93.428-93.428 62.572-113.428 23.142-113.428-23.142-93.43-62.572-62.57-93.428-23.144-113.428 23.144-113.428 62.57-93.428 93.43-62.572 113.428-23.144 113.428 23.144 93.428 62.572 62.572 93.428 23.144 113.428zM877.714 448q0-119.428-58.856-220.286t-159.714-159.714-220.286-58.856-220.286 58.856-159.714 159.714-58.856 220.286 58.856 220.286 159.714 159.714 220.286 58.856 220.286-58.856 159.714-159.714 58.856-220.286z" horiz-adv-x="878" />
 <glyph unicode="&#xf110;" d="M283.428 192q0-34.286-24.286-58.286t-58-24q-34.286 0-58.286 24t-24 58.286 24 58.286 58.286 24q33.714 0 58-24t24.286-58.286zM530.286 82.286q0-30.286-21.428-51.714t-51.714-21.428-51.714 21.428-21.428 51.714 21.428 51.714 51.714 21.428 51.714-21.428 21.428-51.714zM182.856 448q0-37.714-26.856-64.572t-64.57-26.856-64.57 26.856-26.856 64.572 26.856 64.572 64.57 26.856 64.57-26.856 26.856-64.572zM777.144 192q0-26.286-18.856-45.144t-45.144-18.856-45.144 18.856-18.856 45.144 18.856 45.144 45.144 18.856 45.144-18.856 18.856-45.144zM301.714 704q0-41.714-29.428-71.144t-71.144-29.428-71.144 29.428-29.43 71.144 29.43 71.144 71.144 29.428 71.144-29.428 29.428-71.144zM566.856 813.714q0-45.714-32-77.714t-77.714-32-77.714 32-32 77.714 32 77.714 77.714 32 77.714-32 32-77.714zM877.714 448q0-22.856-16-38.856t-38.856-16-38.856 16-16 38.856 16 38.856 38.856 16 38.856-16 16-38.856zM758.856 704q0-18.856-13.428-32.286t-32.286-13.428-32.286 13.428-13.428 32.286 13.428 32.286 32.286 13.428 32.286-13.428 13.428-32.286z" horiz-adv-x="896" />
 <glyph unicode="&#xf111;" d="M877.714 448q0-119.428-58.856-220.286t-159.714-159.714-220.286-58.856-220.286 58.856-159.714 159.714-58.856 220.286 58.856 220.286 159.714 159.714 220.286 58.856 220.286-58.856 159.714-159.714 58.856-220.286z" horiz-adv-x="878" />
+<glyph unicode="&#xf1c9;" d="M838.857 733.714q16-16 27.429-43.429t11.429-50.286v-658.286q0-22.857-16-38.857t-38.857-16h-768q-22.857 0-38.857 16t-16 38.857v914.286q0 22.857 16 38.857t38.857 16h512q22.857 0 50.286-11.429t43.429-27.429zM585.143 873.143v-214.857h214.857q-5.714 16.571-12.571 23.429l-178.857 178.857q-6.857 6.857-23.429 12.571zM804.571 0v585.143h-237.714q-22.857 0-38.857 16t-16 38.857v237.714h-438.857v-877.714h731.429zM274.286 512q4.571 6.286 12 7.143t13.714-3.714l29.143-21.714q6.286-4.571 7.143-12t-3.714-13.714l-104-138.857 104-138.857q4.571-6.286 3.714-13.714t-7.143-12l-29.143-21.714q-6.286-4.571-13.714-3.714t-12 7.143l-129.143 172q-8 10.857 0 21.714zM732.571 340q8-10.857 0-21.714l-129.143-172q-4.571-6.286-12-7.143t-13.714 3.714l-29.143 21.714q-6.286 4.571-7.143 12t3.714 13.714l104 138.857-104 138.857q-4.571 6.286-3.714 13.714t7.143 12l29.143 21.714q6.286 4.571 13.714 3.714t12-7.143zM378.286 76.571q-7.429 1.143-11.714 7.429t-3.143 13.714l78.857 474.857q1.143 7.429 7.429 11.714t13.714 3.143l36-5.714q7.429-1.143 11.714-7.429t3.143-13.714l-78.857-474.857q-1.143-7.429-7.429-11.714t-13.714-3.143z" />
 </font></defs></svg>
\ No newline at end of file
index 734e69ac3f2ed7b8f90e248ca6295627f1189539..56ed0cfbfffaaa19a06489445b06570432410d59 100755 (executable)
Binary files a/client/src/com/vaadin/client/debug/internal/theme/font.ttf and b/client/src/com/vaadin/client/debug/internal/theme/font.ttf differ
index a9e6d5576bbe729f4fe20e8545bef6dcd07df060..9f5ed668ecbd33230d4049953c5b2487aec2f054 100755 (executable)
Binary files a/client/src/com/vaadin/client/debug/internal/theme/font.woff and b/client/src/com/vaadin/client/debug/internal/theme/font.woff differ
index e7c252f26aad104851bcf2abeb507e9d6d8b3f9c..26ccff11914e41dc86db647071ec13dac4ae41d8 100644 (file)
@@ -810,6 +810,18 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
                 serverConnector);
     }
 
+    /**
+     * Sends a request to the server to print a design to the console for the
+     * given component.
+     * 
+     * @since
+     * @param connector
+     *            the component connector to output a declarative design for
+     */
+    public void showServerDesign(ServerConnector connector) {
+        getRpcProxy(DebugWindowServerRpc.class).showServerDesign(connector);
+    }
+
     @OnStateChange("theme")
     void onThemeChange() {
         final String oldTheme = activeTheme;
@@ -1061,5 +1073,4 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
     private static Logger getLogger() {
         return Logger.getLogger(UIConnector.class.getName());
     }
-
 }
index 8dd600ddd0a76296f2c2681e5514158310a074c6..b16d7e32d3791030883f04095655106655e4858f 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.vaadin.ui;
 
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -67,6 +69,7 @@ import com.vaadin.shared.ui.ui.UIConstants;
 import com.vaadin.shared.ui.ui.UIServerRpc;
 import com.vaadin.shared.ui.ui.UIState;
 import com.vaadin.ui.Component.Focusable;
+import com.vaadin.ui.declarative.Design;
 import com.vaadin.util.ConnectorHelper;
 import com.vaadin.util.CurrentInstance;
 
@@ -211,6 +214,32 @@ public abstract class UI extends AbstractSingleComponentContainer implements
                     json.toString());
         }
 
+        @Override
+        public void showServerDesign(Connector connector) {
+            if (!(connector instanceof Component)) {
+                getLogger().severe(
+                        "Tried to output declarative design for " + connector
+                                + ", which is not a component");
+                return;
+            }
+            if (connector instanceof UI) {
+                // We want to see the content of the UI, so we can add it to
+                // another UI or component container
+                connector = ((UI) connector).getContent();
+            }
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            try {
+                Design.write((Component) connector, baos);
+                getLogger().info(
+                        "Design for " + connector
+                                + " requested from debug window:\n"
+                                + baos.toString("UTF-8"));
+            } catch (IOException e) {
+                getLogger().log(Level.WARNING,
+                        "Error producing design for " + connector, e);
+            }
+
+        }
     };
 
     /**
index cb94a9b081d4c29989002367cbb5010d3f69056e..9ca0a0a1bb9e8a40158d52e31c6599766b139306 100644 (file)
@@ -47,4 +47,14 @@ public interface DebugWindowServerRpc extends ServerRpc {
      */
     public void analyzeLayouts();
 
+    /**
+     * Sends a request to the server to print a design to the console for the
+     * given component.
+     * 
+     * @since
+     * @param connector
+     *            the component connector to output a declarative design for
+     */
+    public void showServerDesign(Connector connector);
+
 }