From 9f6cfbce67583dd5c5133d1de5c1fedc58916de0 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Fri, 22 May 2015 20:38:35 +0300 Subject: [PATCH] Show declarative output for component selected in debug window (#17960) Change-Id: I975eef2f06db4395925f76e40c044078028b0e66 --- .../debug/internal/HierarchySection.java | 141 +++++++++++++++--- .../vaadin/client/debug/internal/Icon.java | 2 + .../client/debug/internal/theme/font.eot | Bin 7388 -> 7752 bytes .../client/debug/internal/theme/font.svg | 1 + .../client/debug/internal/theme/font.ttf | Bin 7224 -> 7588 bytes .../client/debug/internal/theme/font.woff | Bin 7300 -> 7664 bytes .../com/vaadin/client/ui/ui/UIConnector.java | 13 +- server/src/com/vaadin/ui/UI.java | 29 ++++ .../shared/ui/ui/DebugWindowServerRpc.java | 10 ++ 9 files changed, 177 insertions(+), 19 deletions(-) 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 cf38942e0a7f779e96391a916fde65f8dc0240b8..0244d9afcca8345e97de4d884ce0a131e8e21e57 100755 GIT binary patch delta 1324 zcmZuwOKcle6us{=?~P|7&p7@i{$*k(HYg}{VrML>q>0q3C8Yro1yBKrn8dY%Vmmkq zq*7I@2oR#1wj&BiWrMOTEZRl7U=bk}bO{TJM1+6^UA0nC5fa1+cVcJ9lb+tW=bU?w zJ$i5F>F>tHGYNpr_*G%^B5h7womy)e-QIHm@HOuFg=%r-<)br$03?R>Zn?O+f~N^U zd+=1t%jeIHAB8!rEr6cQN~yRgjx1gThT|q*A!_gnv#d@GpUE5f^PLcpo^uvYa z`a7%=jN%QV;f{qIB zi`YP%OY|w{3iUW&(&y&VFa!9FNIsnzCPQQ_n;s%r5htmnkX{n>2SVWl$qkO$g=1ul zF)tZWlCE`(8zS&1(r{}^4f$HHxn1cs`wZiT=23L<*f1=Xq^Ur{(jy|EbIr5| zTD{CA2-h%&-rs#7C^4nhP3Zk#Hy2blqC^C`4yaZyQn!!uy~FCe+kzhaNJDTO zUWGdT`%pL(^aZ3y^(QmwF<-u5=lVy(p|A|*(nm--~VWeqtBwKDWUj;gA#t z5gFG~=tn|G;kxsa1gF@O#KsXUokDzgT6|f^OjD%kHp{f`K=6TsK`M zbTbdH>qL_lUpL180-fWH1o-~LD++*i2==#}N+d`7 zxbu1Bozra#x-V|t4%vp@Ko{0BuFh_jB#Z%azKnU+wyFs8Z+rb(>&dsHTdbM7!!4fRs<*VYZL+zzf zV|A%svqpxqPBs>j9g}l1mO3$8Dz7gW8#twe(d)1bMQHr*l#}(^npG~#qmK9OG3SM-Abu!<`^md{KtY@~(&2-d>K$;|9D`f32GpjReySI!MT zN^f9{T+Q|DL}r|Av7Z3`BIY}?NXXB*6XQ1+*Jtx{^CP!N4C5ad&*utbnW6gwD*ypg zwp!Qu~q}ojnAtoiUxXN-?{woweDC)|5Bl zOLZnX4v|#SZbJc6${1ylMa5gCM_m_X_hw**#=Uxtq9}xGvRAK)x~Kywr%BOa)xG^) zb4rq+5+j^(g{kft;rSAnQIVCYL}`T`@mH6!{^~lXv#2^GO?-7aqbx?_o{EkZ5FU-I zimytqb8Y)sugw$WDm$U;zds2|B*ql3x(Ho2)ddw)3libkv&(P$E&j2_|9BhiL+DEf z`$wJK-$3K|zX8@Rynpu3@05(CV2Vb-coDojSSe8Pa3b)UG>}u|Hm#*^*%DXz4ZbBc zOLxUlQ53)AGx8H9qRcC0$63d!dQ~lJMeQYao9{#|FsBoT5>L^+sKWz$APDHlTKl4i zkJ*?ZuD3BqeA31e_%O2S1;{uo7FMAR#>^?<4rEMC3tO5NwlonRz#>c3N?4*67TDZn tH(R3TQMdqkTm_girouksS~wnp<2Zqna0zmdff@L}XfxbNf#Ih{{sOAKn<@YR 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 734e69ac3f2ed7b8f90e248ca6295627f1189539..56ed0cfbfffaaa19a06489445b06570432410d59 100755 GIT binary patch delta 1351 zcmXw3QD|FL82q6!&)ap!NxXgCTUXB z)^#uz6%lbSy5Lk8DALCP)J?euKEMi~W(}t6Ys7>pClJvmI`Tp>!H?q7q90lmvC>09}Vszm$K1#6eHo6xXB6*H9IX_VieEnO_>W?0fFCYbS5|4GG$J3UJaE49>GtuH zclq|gHk{xziB|vUa70@`m8jWEx%SFis$S6GH{!F@N&{bG5=YphyNxnt)$%o_h3ge6 zz{V~fY5ajtG#u>3dIF|_jtH}fLpQTz(SAId|ch z9#_(Fo>kOX#!mS&`BZKKGifEI3L$wa;l`x;Nr`?;`2*?PaZKe#kzdeEcYg3~>HRZQ zV*_@i9!1UR$`3LJMSW3r*7P?2w!NCp(Jf7HP52&#YAR;TEng2>+ohn@?{;4|9lBFI zcDtiI&IWvaQD;c_oSJFn2Ae^y2y7X#`+E-rLra?7$nM+SnqbZ_3SU=?X$Ec9t=;~L z@7r|&aIncMd=q-;_=e$Gcnzv_F8+Yu_V}b2h{cnMaZfg%%f!+Fe?Z!q#3&|`Ue5p} zCNSoSVJ@HRR|Rei_@!{8NGeG_Mud<;sk6tCy3k?ds0B|X6M1jDs7@7}L`iC*&>Z*?CCh{uJA3KG3BhA_7q>l{7?xhSc9P40g&e-q#E%BC?&5 z5g`q2S86(*Mk(Z=p=pGKFxanFZ#dAbw0!CTew9F%(@Ng+$lF5fea@!H{^8zL24th# z%J9k+)y%Jx;SDE^8!F>hc9fwF*ebI>t-9kcWXW`8xj&>l4=?gWofY12ANvcO8r@ZZ zA3pj-2QUx8!Di!5FvI$_#y`Oevuz2fOz=S;+(d?HdLac zlg!F%@?T@t*m6udzA)#^E$6!Po35FbaX&P`X!$X^{@%I^Zgw_=Ac=3kGDdi=gE`?` z2Wy1aI#{Rgi`~J3_!m0Zgb;kJo|onz#zmPnW`q|zm=m5*_(>9J6kO^gbnw%yYZnOO zXFAxV$Gp+_Hf+bv6l*KztCi^3ND9tC5o)jk=jn!4sBR2KAf;4l+B3z)wQ`|GJ&I(! s24yHfO=UvQRV%B}#bTvcE36h5qHkV|PR&=RtJTU#V>g^fPAAj%KUjv|KmY&$ delta 961 zcmY*XOH30{6us{=pU%)3Y^Q~OEENzo21{G01_ezNV>D`qbO#GG!6<$r;+@VABe`^8W+l-NK*GpZGwG=U&b0tk##zpcU%NQ?WOxNRYIQfW zqv;E5o&5v|lri3!ML~MSb>wf6H)nIxrJ;MI5%~|~rSbg8!F2z8-yA^DGVac$O9g0! zyT~6Sk4~g>qh|t-J|kbmO&l)dr>1eE_=M}NI4}-(Dm^{hSY;DmR)GU3TPNCjqE$d~ zw9*V5t*8MU-s2oc3l1K$m$aEzNYb1qaq}ZdnE~48j>9O-pjon|wT+mQ)Ho(-#OF2q zbrFIsu`}M8>L%Da7}H3*&}gm0*1?iapgrM>`4g#F=YEoiJ85VjqL2B4MrLK7TZ?)o zCGVGDkv93XI$4$pS0$h3j(VsICEb$fpyJ*5uIhpyQh^c9xXcu9Q8dns2^|Im;RPn2>M_D6nGO9jmP&8Do$bPrh;MoYU9!DprRd+&{e}57w5g3!X z;vsa|au=yc)esSlnk{`JVCzpa?2oV2x$L9Eq2uTDecwRkc&`A9mp;7wH*Z$V)nI}~ zz}ykKda}Ae!JiO;H>8COko&ZrzGJt!!f)|)VVCeg>=n!6FX^oGT#m>kdC7I&wV>Qk zmejKP8ndl$q8C_2h_z>~5wE!!s+rZ0+54fO!4U^D#LW)oh)+9M06#K&y$BK(gN+qP z!iZHU+=YteX=B^d#7%Q6n^uwGwWR|UdL;1VmpqLICdoHn0yqX9g4v!o+;Q6X;p0}**V}VGU&&nnASKM~s(AV6{Ae-PK#nfq zTJMHcEMGd0Tp6HmL&ellSS%HCsEJsp$*2$qm)1*2BKIt=6Ds7F+$vR8){w(mxU6F7 zIvFn4@~4&X7bK3WIQ`vOtCCwo~?Hc~8Zs&w2j2P;0E-O`GBt)c zopE=l%~2v;AB!FFWfO18!0+KY9SIJ^2{(JP3F^T`EKbiFf!1Ha0M{7tNh44f_D;C2 z)|C3ByUzNjVsSGpY?B*SCei9=BX$g17}%5E-+dq`v82&U=>1?X7u1XpVSC$5s~?$L zzp}kxQvmF5vMSqzKHTYJ@D#iPHQY+b2?hPO6eB~!spMgQI-8jsns7pn3{EBwl4L62 zAHl>l8S)R2Og1y93Vg%~N#P?Rr6k!QB!m=7ot`1sB{M@Z*n%Zf$!wrg)Wiygq7*w} znO@6sTHshX912b(YMs0*~gIrfY>K=^%HX313|7NKj>f4KetfP%=T@B7e}EtjvDqZ}4w4U0WB! zVoiK2)AG9fTVK?-JjXnr80U;FbIttByU;cs1h;)_@v`DQ54eL7Z&PAlb;OYa3Fo?) zA!xZiUk^k@U(Rb z1SS@`*ueX?v7E0}YPBjXLmrP}1)~PlGlhC%xmJyjj~#+DP=Go#P=E>SGY(^Ls9WW3 zM@F7rC=^%AxjMEj;Jd6s8FEnn-?p>0>Poy=s21wEmBLc|^-J-&d~F`x$J{5PS;Fw6 G#r_3!MBvf@ delta 1007 zcmY*XOH30{6us}gndx)}rr0n2(ok$;AkDN>enG(n)|eO!f+z`5DppFQ6bpvBfelMz zl!-0~D;KU@$<7c%ShyxGj0+N%uu!8W;wK>9`4Hpuo%hZ?@80ufUhkKlRGG!J(bZc69a<9PNxLB*Qn`W$i3yZ)7x| z>eo8ejx$8d+GS{9S}`^0A}M21g(jl<16e)9RsA{(4x2S{Nbt&>B>L-> zCih{GCA_9gP%;mty9b{HN_fUZPI42vYZwVspmLZ9-nwJ`Flg!P>+Fv&Wnce=@$khP zuG8N^=J2Kgw(op+{ckkb?=M6F4U-hNs0XPm5cg7PmZ+_hW%&YHbKu+-(