From: Artur Signell Date: Fri, 22 May 2015 17:38:35 +0000 (+0300) Subject: Show declarative output for component selected in debug window (#17960) X-Git-Tag: 7.5.0.beta2~2 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=9f6cfbce67583dd5c5133d1de5c1fedc58916de0;p=vaadin-framework.git Show declarative output for component selected in debug window (#17960) Change-Id: I975eef2f06db4395925f76e40c044078028b0e66 --- diff --git a/client/src/com/vaadin/client/debug/internal/HierarchySection.java b/client/src/com/vaadin/client/debug/internal/HierarchySection.java index c772a9d267..ffb4042e69 100644 --- a/client/src/com/vaadin/client/debug/internal/HierarchySection.java +++ b/client/src/com/vaadin/client/debug/internal/HierarchySection.java @@ -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() + "
" + find.getHTML() + " " + find.getTitle() + "
" + analyze.getHTML() + " " + analyze.getTitle() + "
" + generateWS.getHTML() + " " - + generateWS.getTitle() + "
"); + + generateWS.getTitle() + "
" + generateDesign.getHTML() + + " " + generateDesign.getTitle() + "
"); 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(); } diff --git a/client/src/com/vaadin/client/debug/internal/Icon.java b/client/src/com/vaadin/client/debug/internal/Icon.java index d05eca2f6f..a30dc05fcb 100644 --- a/client/src/com/vaadin/client/debug/internal/Icon.java +++ b/client/src/com/vaadin/client/debug/internal/Icon.java @@ -18,6 +18,7 @@ package com.vaadin.client.debug.internal; public enum Icon { + // Font can be updated using e.g. http://icomoon.io/ SEARCH(""), // OK(""), // REMOVE(""), // @@ -46,6 +47,7 @@ public enum Icon { RESET(""), // PERSIST(""), // TESTBENCH(""), // + SHOW_DESIGN(""), // ; private String id; diff --git a/client/src/com/vaadin/client/debug/internal/theme/font.eot b/client/src/com/vaadin/client/debug/internal/theme/font.eot index cf38942e0a..0244d9afcc 100755 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 diff --git a/client/src/com/vaadin/client/debug/internal/theme/font.svg b/client/src/com/vaadin/client/debug/internal/theme/font.svg index c5a97a6c8b..313645c78f 100755 --- a/client/src/com/vaadin/client/debug/internal/theme/font.svg +++ b/client/src/com/vaadin/client/debug/internal/theme/font.svg @@ -33,4 +33,5 @@ + \ No newline at end of file diff --git a/client/src/com/vaadin/client/debug/internal/theme/font.ttf b/client/src/com/vaadin/client/debug/internal/theme/font.ttf index 734e69ac3f..56ed0cfbff 100755 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 diff --git a/client/src/com/vaadin/client/debug/internal/theme/font.woff b/client/src/com/vaadin/client/debug/internal/theme/font.woff index a9e6d5576b..9f5ed668ec 100755 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 diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java index e7c252f26a..26ccff1191 100644 --- a/client/src/com/vaadin/client/ui/ui/UIConnector.java +++ b/client/src/com/vaadin/client/ui/ui/UIConnector.java @@ -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()); } - } diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java index 8dd600ddd0..b16d7e32d3 100644 --- a/server/src/com/vaadin/ui/UI.java +++ b/server/src/com/vaadin/ui/UI.java @@ -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); + } + + } }; /** diff --git a/shared/src/com/vaadin/shared/ui/ui/DebugWindowServerRpc.java b/shared/src/com/vaadin/shared/ui/ui/DebugWindowServerRpc.java index cb94a9b081..9ca0a0a1bb 100644 --- a/shared/src/com/vaadin/shared/ui/ui/DebugWindowServerRpc.java +++ b/shared/src/com/vaadin/shared/ui/ui/DebugWindowServerRpc.java @@ -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); + }