From a526c3f838808d270d457dc9d978c5cd548cfce3 Mon Sep 17 00:00:00 2001 From: Marc Englund Date: Fri, 10 Oct 2008 13:45:38 +0000 Subject: [PATCH] More for Sampler; view mode switcher etc svn changeset:5628/svn branch:trunk --- .../ITMILL/themes/example/sampler/flow.gif | Bin 0 -> 269 bytes .../ITMILL/themes/example/sampler/grid.gif | Bin 0 -> 248 bytes .../ITMILL/themes/example/sampler/icons.xcf | Bin 0 -> 1091 bytes .../ITMILL/themes/example/sampler/left-on.gif | Bin 0 -> 1181 bytes .../ITMILL/themes/example/sampler/left.gif | Bin 0 -> 1202 bytes .../ITMILL/themes/example/sampler/list.gif | Bin 0 -> 250 bytes .../ITMILL/themes/example/sampler/mid-on.gif | Bin 0 -> 1013 bytes .../ITMILL/themes/example/sampler/mid.gif | Bin 0 -> 1037 bytes .../themes/example/sampler/right-on.gif | Bin 0 -> 1181 bytes .../ITMILL/themes/example/sampler/right.gif | Bin 0 -> 1202 bytes WebContent/ITMILL/themes/example/styles.css | 46 ++ .../itmill/toolkit/demo/sampler/Feature.java | 7 +- .../toolkit/demo/sampler/ModeSwitch.java | 105 +++++ .../demo/sampler/SamplerApplication.java | 408 ++++++++++++++---- .../demo/sampler/features/DummyFeature.gif | Bin 8417 -> 2005 bytes .../demo/sampler/features/DummyFeature.java | 4 + 16 files changed, 476 insertions(+), 94 deletions(-) create mode 100644 WebContent/ITMILL/themes/example/sampler/flow.gif create mode 100644 WebContent/ITMILL/themes/example/sampler/grid.gif create mode 100644 WebContent/ITMILL/themes/example/sampler/icons.xcf create mode 100644 WebContent/ITMILL/themes/example/sampler/left-on.gif create mode 100644 WebContent/ITMILL/themes/example/sampler/left.gif create mode 100644 WebContent/ITMILL/themes/example/sampler/list.gif create mode 100644 WebContent/ITMILL/themes/example/sampler/mid-on.gif create mode 100644 WebContent/ITMILL/themes/example/sampler/mid.gif create mode 100644 WebContent/ITMILL/themes/example/sampler/right-on.gif create mode 100644 WebContent/ITMILL/themes/example/sampler/right.gif create mode 100644 src/com/itmill/toolkit/demo/sampler/ModeSwitch.java diff --git a/WebContent/ITMILL/themes/example/sampler/flow.gif b/WebContent/ITMILL/themes/example/sampler/flow.gif new file mode 100644 index 0000000000000000000000000000000000000000..02d1233de268b35b70fca4a1a23ca8ed74e19aed GIT binary patch literal 269 zcmZ?wbhEHb~T{?UG%K6h*E}pw_ z<-(m?H{Lvd^yc~FH_xBEeewA1%O~$%K7IG<+56YeKfHPQ@!hLW?_Pg;|K{_Dw_iTK z`||Pq*H1w7;oIkr-@X9Rr|(~Z=<|XoPd+6{n rIxQCZ>8&^WkVet1maw_u*;{s`=5^lH`z|%FZM9d?trIcL%?#E6F+9ar literal 0 HcmV?d00001 diff --git a/WebContent/ITMILL/themes/example/sampler/grid.gif b/WebContent/ITMILL/themes/example/sampler/grid.gif new file mode 100644 index 0000000000000000000000000000000000000000..b245a171c73b37a71002328f60f4a7a16e9a73d6 GIT binary patch literal 248 zcmZ?wbhEHb~T{?UG%K6h*E}pw_ z<-(m?H{Lvd^yc~FH_xBEeewA1%O~$%K7IG<+56YeKfHPQ@!hLW?_Pg;|K{_Dw_iTK z`||Pq*H1w7;oIkr-@X9Rr|(~Z=<|(9&xc}j7 Vb$x7bGRJEEsV9Y=B5aHd)&OT!x-b9$ literal 0 HcmV?d00001 diff --git a/WebContent/ITMILL/themes/example/sampler/icons.xcf b/WebContent/ITMILL/themes/example/sampler/icons.xcf new file mode 100644 index 0000000000000000000000000000000000000000..3800aa41ce75ce83e5dd6b999d8ad829892e30de GIT binary patch literal 1091 zcmZ`%OK;Oa5Z}vW#R>~=9X-Sr+8Do(arqckY z1&{?Mt((`EjJXH5&E-4x%AY?C{Pgw9np67bl-8Zn zM&;*vrM%&mzq^}1s#~R+Q?9$44R@W%IV+6=?APS5FCj(A?C*VH`eMG}`lKMhQQP$sHL%rh~01gwBo#4fmzJ35DjYY)a7$O}cPC zJWx#JM;QZKa?#Lj6tCP+sp?!NowiiFTOdsNVUus^52bzt!iA8bKjEXtU=y#Yx1_77 zylRpIeFKs)fI9C1@qkn3_XQk^i9LLO4?obu5BBiG;B;0f^s1DDBz$SAC=mX_C*5jM z8(&4p1aKCZ>EGvn850mMAg6#IB3y!xles@cjPlVU50T exGL~7!(E6yX9WPV0~{g(xeL%Mkz4{gf9O9=03?S1 literal 0 HcmV?d00001 diff --git a/WebContent/ITMILL/themes/example/sampler/left-on.gif b/WebContent/ITMILL/themes/example/sampler/left-on.gif new file mode 100644 index 0000000000000000000000000000000000000000..83348dfb5b1e9368fda54fb6c888ceadbc19324b GIT binary patch literal 1181 zcmcJ~{WIGK0LSrf%h2j}x*FD{YR91xyWZ)kZM~aaU8|_}R@b_owN_4p*xabP&TT;& zik3DlS`SeV5lIk25)u-no+9F*B`T6{p1%2h^B^G+OzGM`VxN2c{JDFdzi=+>``>K) zP(X_>kc~^an|ZtNuPj2|okvCZ@&^SKC4>JF0x#4AFQ*#TY zwPfFyUoqM{I+C(Gp z*@|2NDphKY7Sh3pej4ytHCxu!t+oyO=GOMVJMVY*J^&5}QIX7sp+c7BNiuEy7;ULk2X$MAx&a-Xv$s0-cA6QsZ^w1kQ77E#s7q{-R~EQ+`$EK4uj?(*G} zki!cP9*gRs&NfAof<8OoQ!w9pxhbkHs+abb9?wc!ne3%6b|wy&9E)Z%mRQ(%+OIqA z0D+UKo~(=Jbgb}lt@;%ar&A%oJGgqsaGA>C;v?uAQ(oWUohy8!>tp)5wW8{fboo>t zODAbKTk3tWzXzG8UZLL*_uokdKEEZZzsO^ombqC5xtPZ>D};rv$7A{2HT5_NeRG=M zm$k$sN0Va*`Zo+xR=Q$(UG zKWpG_0El<=z=HWM{#3BwP-vJp@O4C>lHh(7tGw@(LRAt`dpWSO$cGrHD)y_ysvZPV zsHzeS8*U^3SRZxSsRgY1VHiYJKRRQF)#c$%Co~li9;uqgk^XI(Co!Rjh7_`&IrKE{ zYO3~Gd`g?PG9d@iRwWWoK-I~WsnByQr44$4VXoL@ zO>9|?!NdWH=vA(!GJUmg0H)Aa`;BbFD$g>CHuG(_TmhFYh;ANyZ#S3)fHTG-bo9ho zhFk&|mRE;P8!f|b=P_#|?$>Jn0FDwG)<#ixjca2*MVR$*zbf4NL|`jpeGi%v*H2a_O2Sx7X&>JwzNpgEws>ikJD~)g_5|W$Uv9QOOXM98oDWYPkkfXu*9g zq}0JGJpvlEkWmX8b%;r?F&ngIgYLk1N^db4Eap>2>%l3L&0;?JAM!f1LpcM#0BGQ} z|DFJc-U;L0m1t6o>v)YjF%d7F#6^h0w?Yg>CqXID4Ar?;=4KqQeV z1A{}(4~s(ixX4v7^+z*|PHij|8K`a&FDlnD*HBw0(Zl^^6_CdwSY5aHH(X z-7y9zBHSlG5{`|)8`LNK_PcDRW^*(P-Vw4{x?Maf#XXKQYLN5l10FAN-kVe__?V8k z@v#F~LeJP;8fRN|(pN6u+?(JWn$#llC*BkLUMM$^5?i7!Vs6TG`TIeBsdIQU8n z>@H%Yg-$*MY0J>pXdd+iZSx45G6tW`nE+auMTzaQ`CfAe5$C8^dTzhVuL|NeSElIZxs-hy#F>a zmAK!KlmqTJCgc2+O(_jemG3ZpL}fFU2`XEj&-B|(l2o#Wxs?NJ zSW;Yoc2v>Of(F*yddS)_gb8ce`uPAI$Go1Q8@DORx`}@*ux=7?MC+&Q+_2O!Ah}aN zbM7XhpLLBu8$Mh}z#8V<(mTp@S({iX|pm`>=iET+R`y1wbvsuzVBN{L28N;TRC?K@C2r4bdu7)KZL-Rn KKi+W#e*PCD(DZZw literal 0 HcmV?d00001 diff --git a/WebContent/ITMILL/themes/example/sampler/list.gif b/WebContent/ITMILL/themes/example/sampler/list.gif new file mode 100644 index 0000000000000000000000000000000000000000..802ae56df361847410244a76cbde6a22b96d4161 GIT binary patch literal 250 zcmZ?wbhEHb~T{?UG%K6h*E}pw_ z<-(m?H{Lvd^yc~FH_xBEeewA1%O~$%K7IG<+56YeKfHPQ@!hLW?_Pg;|K{_Dw_iTK z`||Pq*H1w7;oIkr-@X9Rr|(~Z=<|50z_QH}Yn7HCQDCqJ0Pgv`SO5S3 literal 0 HcmV?d00001 diff --git a/WebContent/ITMILL/themes/example/sampler/mid-on.gif b/WebContent/ITMILL/themes/example/sampler/mid-on.gif new file mode 100644 index 0000000000000000000000000000000000000000..ceb6645f162b2b49c41f2d301c57322359abff8a GIT binary patch literal 1013 zcmVKGw;^5}v z;OFGw=;h+*<>Tq*F4F?=;i6?=IZI@>gng}>F59e00000000000000000000 z000000000000000A^8LW3IHDfEC2ui0Q3PI000I4ARvxpX`X1Ru59bRa4gSsZQppV z?|kq7B!h5BEE41ejE#0PICJX!IH0G` zpFo2O9ZIyQ(W6L{DqYI7sne%Wqe`7hwW`&tShH&VDWI#@uVBN99ZR;X*|TWVs$I*r zt=qS7(BTJr4xw7TUm@{kM z%(=7Y&!9t#9!C=T5s9w#wwd>cgW6PdRySDAyxO3~?&AYen-@tNG7S| zl1w(~0+o_zM{=bwNED(Iku7Ha6Bh$gD&qKr1`=%bKED(R$@<|)CYm}aW!rkr-_ z>8GHED(a}DmTKy$sHUpws;su^>Z`EED(kGYW;(&GxaO+suDtf@>#x8DE9|hu7HjOW z$R?}ovdlK??6c5DEA6z@b>>RJwb*8>?Y7)@>+QGThAZy4+ZYo z#w+i<^k!SZz4+#<@4o!@>+in+2Q2Ww1Q%@Z!3Za;@WKo??C`@7M=bHg6jyBV#TaL- j@x~l??D5AShx{)PB$sUR$tb6+^2#i??DESdga80LiQ`;L literal 0 HcmV?d00001 diff --git a/WebContent/ITMILL/themes/example/sampler/mid.gif b/WebContent/ITMILL/themes/example/sampler/mid.gif new file mode 100644 index 0000000000000000000000000000000000000000..eca0884b2df025a4e77ed35bf6c4969a85dad71d GIT binary patch literal 1037 zcmV+o1oHbwNk%w1Ve|nU0E8C+b82Ah=i=<=E-U~=I`t0@a*aF?&|XH z>+41ejByl?kdcy;l$Dm3n30PICJXU$+M@= zpFo2O9ZIyQ(W6L{DqYGnrh}(Yqe`7hwW`&tShH%~%C)Q4uVBN99ZR;X*|TWVs$I)A zYJ<0MC>oFt6t5zwd>cgW6PdRySDAyxN~0)z`M8a-@tNG7S| zl1w(~0+o_zM{=bwNED(Iku7HTM&2qdcLqKr1`=%bKED(R$@R%+>`m}aW!rkr-_ z>8GHED(a}DmTKyv3Z$y)s;su^>Z`EED(kGY)@tjmxaO+suDtf@>#x8DE9|hu7HjOP z3nZ)TvdlK??6c5DEA6z@jaF;zwb*8>?Y7)@>+QGThAZy4+ZYo z#w+i<^ww+dz4+#<@4o!@>+in+2Q2Ww1Q%@Zx~C?r@WKo??C`@7M=bHg6gPUn#TaL- z@x~l??D5AShb;2QB$sUR$tb6+^2#i??DESn$1L;AG-nLN%{b?*^Ugf??DNk+2Q9P- HApih7n6iWz literal 0 HcmV?d00001 diff --git a/WebContent/ITMILL/themes/example/sampler/right-on.gif b/WebContent/ITMILL/themes/example/sampler/right-on.gif new file mode 100644 index 0000000000000000000000000000000000000000..cd9ffba5f88bbcbe3efbe11a827c191b2a9598db GIT binary patch literal 1181 zcmb`?{V&@I0LSq!Gd0{rGBLNXS+-bF7r8Asx8#~kFwBQfFw*TQidHwuJ-oZD5{D1u2WZ?od zy8~%SF&Qb3bN^1w%X<16pI!1Yx3n;iJIEU0vL;43{IL-MpC=d}6AJkAvqI^bSh}_X zu8YBq71_oonPgQiT~kOmKoC^QB#=xB$)zd<2rFf)b*aANTn6Iy2n*i%$EG{JkbGBr>>CcIzfVx>?T4?+IPBA52pnJx#7zTgws1m|G z&!+!iNes-ah|X309{agafAATXo#S9*Y3qc4Sy)v3>UBx!o3~}|&k*VNY4 zH+*btYQ~>B=}aP1+B-U_UEQ>vUOI!>*Uw@P405X5FFqeaeFzPH3SH1bQ_t{1x8=x&-QL*F4qO>{R4Dtuxlt8dU+rmOr@ z)u!<$t;fPTY_6?qXb*9&F{JFdl}|(4LhJ3u(3;R*(h~U|En$7Kmn`ax<`uez(J3pm zxCPQvTWroMBSk)06UOLRXJs1I>jFlngo8U_cP^Ys1$p?>UJnkPuzCE_i($3lecehy z<(0&ZsXm%YSbx3f+|B+TWPx~x{9yX*4>%MxMo@c`Mc1t|Q#BjYEQVgf&9yrp!DepB z$IHAP&anT|ie?(a>LLdEcQj&JqGaYbU)(oRUeWnmgY11Hyg+^^92_{X1G z2YW`1M96uur$0W4mg20O;-uL&?nG&heIW`!IRv4>Jjcj5@E_+`BAD-ToDPEpZuw{# z{t_Wh_7dGfloev=&KCgJ5wyJc>T;a?l|Mw3zrJRM#Rg(#| zscN&#h^h`}?FrZCIVHdicy|)~vDjA)H+?O;#3n+5 zx{cUEQj;ijwVF&FyYB&9SWM8gGa-_ugKbu8I=R+fTIz^XqPA*#Cg8XZHL@3qNP5E3{02H+O*X1|uM*<=~Uy!335rO)ud9z@m;9-1|J z4uHZKxK?M93_~`TDTZNtKdpi15RBOxag^Hur<@;Cw#HmCv|D_)0?hXKrHZ8O33MxE zdlJLYZVP<)7~|AcQSlR$MR~n(=Gv~-D8!vDIo1lo@S z8A)+jY4OyD_w#cy%Zqa>N~lju^TksWQt`wqnMg4wU6e}}=jWCe6|3)-5uFOrsS%w9 z1=XltW6*CIAgvMBnGijSqGkhRF~Alhf|*dO* zdGGA7ANTt;L;a_s&hh0i;o{y{37kNd+C8duZKPfA(cv_kHIpJ7M?en_&hQ_Am z7cH%A?X(U$gUModc6D=ldi%KjHQo+>LjvLO$mrPk#N^AVX_0tlRw9+n$rbaj78YN> zSrP!gE30ek8_G?UTC=6qfqDo=P=nEAwqRBpzHMIxj(+^KvkN%w_l)2)k5gUTiLqkN zi^)Pa-^luio|dW7!>4g4x0Y5>na|H9o)>!CW-0@&Fk@$W+a=Yf?#|X<=%dN%LNXw$ z3y{AfZwjUE_lo4w=UXExi8p7tjD?Pv*2sp)e&%b|jlQI{f856kyW=KHyrOvQw|(RV z=1mE&b7df1J=+j9(6uIbfI({#4-)Vt#mUt>n$OvsEOHOLCFS?1MdiLxjnRX>Taud7 z$?MX=j5xsSr&8~WLtOm={R-=rY^Wbz;@p)qUKH@q6@CW1E)xv=F%N{e9JwUqo7LjV zz}s`eK}@G;jcU3yJY<8H`;s^2h6UTkNhSJbaxjZ1Sl!ahserY7k|1k??5o9q+$-hc>cj_P!iu0K_WcA|^EnWTO91g0>LJ21{<>wD2YAPc98Jefj!Fo+) zOxUl!fcw?Nt!Fn97+Y1bS^BN&xPlYfn)s?jZ7rF`&^}M$>9uv~(zXJ8BG{aNC<%N~ew^b!U z3_6VoG1)u_VsWO4Fq`{(Qer1x%Y?gxI0Sc(5dslTtz-IlkJz7u^h$$aq)!nRh;kRN zC8Pbz2`rSingyc+%7Q=xUvt!zLU;wzScV~l2O9*Y=|H2<`X<>pY}c}kBOh_tI120| znZ}$w>Q4e+`>{2TTV4B*X>^o^! W=6j^sH;ayU+1>AWQhsy;zW)~>MDI=j literal 0 HcmV?d00001 diff --git a/WebContent/ITMILL/themes/example/styles.css b/WebContent/ITMILL/themes/example/styles.css index 426cfade50..441e40a9cd 100644 --- a/WebContent/ITMILL/themes/example/styles.css +++ b/WebContent/ITMILL/themes/example/styles.css @@ -43,3 +43,49 @@ text-align: right; } +/****************************************************************************** + * For Sampler + ******************************************************************************/ +#sampler { + background-color: white; +} +#sampler .i-expandlayout-topbar { + border-bottom: 1px solid #999; +} + +#sampler .feature-info { + background-color: #999; + color: white; + padding: 20px; + line-height: 30px; +} +#sampler .feature-name { + font-size: 18px; + font-weight: bold; +} +.i-customcomponent-ModeSwitch .i-button { + height: 28px; + border: none; + border-right: 1px solid #736a60; + margin: 0px; +} +.i-customcomponent-ModeSwitch .i-button-first-on { + background: transparent url(sampler/left-on.gif) no-repeat; +} +.i-customcomponent-ModeSwitch .i-button-first { + background: transparent url(sampler/left.gif) no-repeat; +} +.i-customcomponent-ModeSwitch .i-button-mid-on { + background: transparent url(sampler/mid-on.gif) no-repeat; +} +.i-customcomponent-ModeSwitch .i-button-mid { + background: transparent url(sampler/mid.gif) no-repeat; +} +.i-customcomponent-ModeSwitch .i-button-last-on { + border: none; + background: transparent url(sampler/right-on.gif) no-repeat right top; +} +.i-customcomponent-ModeSwitch .i-button-last { + border: none; + background: transparent url(sampler/right.gif) no-repeat right top; +} diff --git a/src/com/itmill/toolkit/demo/sampler/Feature.java b/src/com/itmill/toolkit/demo/sampler/Feature.java index 44eaa1bdb1..8772c0afd9 100644 --- a/src/com/itmill/toolkit/demo/sampler/Feature.java +++ b/src/com/itmill/toolkit/demo/sampler/Feature.java @@ -17,10 +17,13 @@ abstract public class Feature { protected Example example = null; + public String getPathName() { + return getClass().getSimpleName(); + } + /** Get the name of the feature. Override if needed. */ public String getName() { - String[] cn = this.getClass().getName().split("\\."); - return cn[cn.length - 1]; + return getClass().getSimpleName(); } abstract public String getDescription(); diff --git a/src/com/itmill/toolkit/demo/sampler/ModeSwitch.java b/src/com/itmill/toolkit/demo/sampler/ModeSwitch.java new file mode 100644 index 0000000000..100679e73e --- /dev/null +++ b/src/com/itmill/toolkit/demo/sampler/ModeSwitch.java @@ -0,0 +1,105 @@ +package com.itmill.toolkit.demo.sampler; + +import java.util.HashMap; +import java.util.Iterator; + +import com.itmill.toolkit.terminal.Resource; +import com.itmill.toolkit.ui.Button; +import com.itmill.toolkit.ui.CustomComponent; +import com.itmill.toolkit.ui.OrderedLayout; +import com.itmill.toolkit.ui.Button.ClickEvent; + +public class ModeSwitch extends CustomComponent { + + OrderedLayout layout = new OrderedLayout( + OrderedLayout.ORIENTATION_HORIZONTAL); + + HashMap idToButton = new HashMap(); + Object mode = null; + + public ModeSwitch() { + setCompositionRoot(layout); + setStyleName("ModeSwitch"); + } + + public Object getMode() { + return mode; + } + + public void setMode(Object mode) { + if (idToButton.containsKey(mode)) { + this.mode = mode; + updateStyles(); + fireEvent(new ModeSwitchEvent()); + } + } + + public void addListener(ModeSwitchListener listener) { + super.addListener(listener); + } + + public void addMode(Object id, String caption, String description, + Resource icon) { + if (idToButton.containsKey(id)) { + removeMode(id); + } + Button b = new Button(); + if (caption != null) { + b.setCaption(caption); + } + if (description != null) { + b.setDescription(description); + } + if (icon != null) { + b.setIcon(icon); + } + b.setData(id); + b.addListener(new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + setMode(event.getButton().getData()); + } + }); + idToButton.put(id, b); + layout.addComponent(b); + updateStyles(); + } + + public void removeMode(Object id) { + Button b = (Button) idToButton.remove(id); + layout.removeComponent(b); + updateStyles(); + } + + private void updateStyles() { + boolean first = true; + for (Iterator it = layout.getComponentIterator(); it.hasNext();) { + Button b = (Button) it.next(); + String isOn = (b.getData() == mode ? "-on" : ""); + if (first) { + first = false; + b.setStyleName("first" + isOn); + } else if (!it.hasNext()) { + b.setStyleName("last" + isOn); + } else { + b.setStyleName("mid" + isOn); + } + } + } + + public interface ModeSwitchListener extends Listener { + + } + + public class ModeSwitchEvent extends Event { + private static final long serialVersionUID = -576318750089478453L; + + public ModeSwitchEvent() { + super(ModeSwitch.this); + } + + public Object getMode() { + return ModeSwitch.this.getMode(); + } + } + +} diff --git a/src/com/itmill/toolkit/demo/sampler/SamplerApplication.java b/src/com/itmill/toolkit/demo/sampler/SamplerApplication.java index 1c61706ea4..cf91d7f758 100644 --- a/src/com/itmill/toolkit/demo/sampler/SamplerApplication.java +++ b/src/com/itmill/toolkit/demo/sampler/SamplerApplication.java @@ -1,23 +1,31 @@ package com.itmill.toolkit.demo.sampler; +import java.net.URL; +import java.util.Collection; import java.util.Collections; +import java.util.Iterator; import java.util.LinkedList; import com.itmill.toolkit.Application; -import com.itmill.toolkit.data.Container; import com.itmill.toolkit.data.Item; import com.itmill.toolkit.data.Property; import com.itmill.toolkit.data.Property.ValueChangeEvent; import com.itmill.toolkit.data.util.HierarchicalContainer; import com.itmill.toolkit.data.util.ObjectProperty; +import com.itmill.toolkit.demo.sampler.ModeSwitch.ModeSwitchEvent; import com.itmill.toolkit.demo.sampler.features.DummyFeature; import com.itmill.toolkit.terminal.ClassResource; +import com.itmill.toolkit.terminal.DownloadStream; +import com.itmill.toolkit.terminal.ExternalResource; import com.itmill.toolkit.terminal.Resource; import com.itmill.toolkit.terminal.ThemeResource; import com.itmill.toolkit.ui.Button; import com.itmill.toolkit.ui.Component; +import com.itmill.toolkit.ui.CustomComponent; import com.itmill.toolkit.ui.Embedded; import com.itmill.toolkit.ui.ExpandLayout; +import com.itmill.toolkit.ui.GridLayout; +import com.itmill.toolkit.ui.Label; import com.itmill.toolkit.ui.SplitPanel; import com.itmill.toolkit.ui.Table; import com.itmill.toolkit.ui.Tree; @@ -27,6 +35,7 @@ import com.itmill.toolkit.ui.Button.ClickListener; public class SamplerApplication extends Application { + // Main structure, root is always a FeatureSet that is not shown private static final FeatureSet features = new FeatureSet("All", new Feature[] { // Main sets @@ -74,55 +83,181 @@ public class SamplerApplication extends Application { }); - SplitPanel split = null; - - FeatureList currentList = null; - FeatureView featureView = null; - - Container.Ordered allFeatures = null; - Property currentFeature = new ObjectProperty(null, Feature.class); + // All features in one container + private static final HierarchicalContainer allFeatures = features + .getContainer(true); public void init() { setTheme("example"); - setMainWindow(new MainWindow()); + setMainWindow(new SamplerWindow()); } - private class MainWindow extends Window { + // Supports multiple browser windows + public Window getWindow(String name) { + Window w = super.getWindow(name); + if (w == null) { + w = new SamplerWindow(); + w.setName(name); + addWindow(w); + // secondary windows will support normal reload if this is + // enabled, but the url gets ugly: + // w.open(new ExternalResource(w.getURL())); - MainWindow() { - allFeatures = (Container.Ordered) features.getContainer(true); + } + return w; + } - ExpandLayout main = new ExpandLayout(); - setLayout(main); - main.setSizeFull(); + /** + * Gets absolute path for given Feature + * + * @param f + * the Feature whose path to get, of null if not found + * @return the path of the Feature + */ + String getPathFor(Feature f) { + if (allFeatures.containsId(f)) { + String path = f.getPathName(); + f = (Feature) allFeatures.getParent(f); + while (f != null) { + path = f.getPathName() + "/" + path; + } + return path; + } + return null; + } + /** + * The main window for Sampler, contains the full application UI. + * + */ + private class SamplerWindow extends Window { + private FeatureList currentList = new FeatureGrid(); + private FeatureView featureView = new FeatureView(); + private Property currentFeature = new ObjectProperty(null, + Feature.class); + + private MainArea mainArea = new MainArea(); + + SamplerWindow() { + // Main top/expanded-bottom layout + ExpandLayout mainExpand = new ExpandLayout(); + setLayout(mainExpand); + mainExpand.setSizeFull(); + + // topbar (navigation) ExpandLayout nav = new ExpandLayout( ExpandLayout.ORIENTATION_HORIZONTAL); - main.addComponent(nav); + mainExpand.addComponent(nav); nav.setHeight("40px"); nav.setWidth("100%"); nav.setStyleName("topbar"); - split = new SplitPanel(SplitPanel.ORIENTATION_HORIZONTAL); + // Upper left logo + Component logo = createLogo(); + nav.addComponent(logo); + nav.setComponentAlignment(logo, ExpandLayout.ALIGNMENT_LEFT, + ExpandLayout.ALIGNMENT_VERTICAL_CENTER); + nav.expand(logo); + + // Previous sample + Button b = createPrevButton(); + nav.addComponent(b); + nav.setComponentAlignment(b, ExpandLayout.ALIGNMENT_LEFT, + ExpandLayout.ALIGNMENT_VERTICAL_CENTER); + // Next sample + b = createNextButton(); + nav.addComponent(b); + nav.setComponentAlignment(b, ExpandLayout.ALIGNMENT_LEFT, + ExpandLayout.ALIGNMENT_VERTICAL_CENTER); + + // Main left/right split; hidden menu tree + SplitPanel split = new SplitPanel(SplitPanel.ORIENTATION_HORIZONTAL); split.setSizeFull(); split.setSplitPosition(0, SplitPanel.UNITS_PIXELS); - main.addComponent(split); - main.expand(split); + mainExpand.addComponent(split); + mainExpand.expand(split); + + // Menu tree, initially hidden + Tree tree = createMenuTree(); + split.addComponent(tree); + + // Main Area + split.addComponent(mainArea); + + // List/grid/coverflow + Component mode = createModeSwitch(); + nav.addComponent(mode); + nav.setComponentAlignment(mode, ExpandLayout.ALIGNMENT_RIGHT, + ExpandLayout.ALIGNMENT_VERTICAL_CENTER); + + } + + /** + * Displays a Feature(Set) + * + * @param f + * the Feature(Set) to show + */ + public void setFeature(Feature f) { + currentFeature.setValue(f); + } + + /** + * Displays a Feature(Set) matching the given path, or the main view if + * no matching Feature(Set) is found. + * + * @param path + * the path of the Feature(Set) to show + */ + public void setFeature(String path) { + Feature f = features.getFeatureByPath(path); + setFeature(f); + } + // Handle REST -style urls + public DownloadStream handleURI(URL context, String relativeUri) { + Feature f = features.getFeatureByPath(relativeUri); + if (f != null) { + setFeature(f); + open(new ExternalResource(context)); + } + return super.handleURI(context, relativeUri); + } + + /* + * SamplerWindow helpers + */ + + private Component createLogo() { Button logo = new Button("", new Button.ClickListener() { public void buttonClick(ClickEvent event) { currentFeature.setValue(null); } }); - logo.setDescription("Home"); + logo.setDescription("↶ Home"); logo.setStyleName(Button.STYLE_LINK); logo.setIcon(new ThemeResource("sampler/logo.png")); logo.setWidth("160px"); - nav.addComponent(logo); - nav.setComponentAlignment(logo, ExpandLayout.ALIGNMENT_LEFT, - ExpandLayout.ALIGNMENT_VERTICAL_CENTER); + return logo; + } + + private Button createNextButton() { + Button b = new Button("Next sample →", new ClickListener() { + public void buttonClick(ClickEvent event) { + Object curr = currentFeature.getValue(); + Object next = allFeatures.nextItemId(curr); + while (next != null && next instanceof FeatureSet) { + next = allFeatures.nextItemId(next); + } + currentFeature.setValue(next); + } + }); + b.setStyleName(Button.STYLE_LINK); + return b; + } - Button b = new Button("< Previous", new ClickListener() { + private Button createPrevButton() { + Button b = new Button("← Previous sample", new ClickListener() { public void buttonClick(ClickEvent event) { Object curr = currentFeature.getValue(); Object prev = allFeatures.prevItemId(curr); @@ -130,37 +265,35 @@ public class SamplerApplication extends Application { prev = allFeatures.prevItemId(prev); } currentFeature.setValue(prev); - } }); - nav.addComponent(b); - nav.setComponentAlignment(b, ExpandLayout.ALIGNMENT_LEFT, - ExpandLayout.ALIGNMENT_VERTICAL_CENTER); + b.setStyleName(Button.STYLE_LINK); + return b; + } - b = new Button("Next >", new ClickListener() { - public void buttonClick(ClickEvent event) { - Object curr = currentFeature.getValue(); - Object next = allFeatures.nextItemId(curr); - while (next != null && next instanceof FeatureSet) { - next = allFeatures.nextItemId(next); + private Component createModeSwitch() { + ModeSwitch m = new ModeSwitch(); + m.addMode(currentList, "", "View as Icons", new ThemeResource( + "sampler/grid.gif")); + m.addMode(new FeatureGrid(), "", "View as Icons", + new ThemeResource("sampler/flow.gif")); + m.addMode(new FeatureTable(), "", "View as List", + new ThemeResource("sampler/list.gif")); + m.addListener(new ModeSwitch.ModeSwitchListener() { + public void componentEvent(Event event) { + if (event instanceof ModeSwitchEvent) { + updateFeatureList((FeatureList) ((ModeSwitchEvent) event) + .getMode()); } - currentFeature.setValue(next); - } }); - nav.addComponent(b); - nav.setComponentAlignment(b, ExpandLayout.ALIGNMENT_LEFT, - ExpandLayout.ALIGNMENT_VERTICAL_CENTER); - - b = new Button(":: | \\⊡/ | ≣"); - nav.addComponent(b); - nav.expand(b); - nav.setComponentAlignment(b, ExpandLayout.ALIGNMENT_RIGHT, - ExpandLayout.ALIGNMENT_VERTICAL_CENTER); + m.setMode(currentList); + return m; + } + private Tree createMenuTree() { Tree tree = new Tree(); tree.setImmediate(true); - split.addComponent(tree); tree.setContainerDataSource(allFeatures); tree.setPropertyDataSource(currentFeature); for (int i = 0; i < features.getFeatures().length; i++) { @@ -169,42 +302,65 @@ public class SamplerApplication extends Application { tree.expandItemsRecursively(features); tree.addListener(new Table.ValueChangeListener() { public void valueChange(ValueChangeEvent event) { - Feature val = (Feature) event.getProperty().getValue(); - if (val == null) { - currentList.setFeatureContainer(features - .getContainer(true)); - if (currentList.getParent() != split) { - split.replaceComponent(featureView, currentList); - } - - } else if (val instanceof FeatureSet) { - currentList.setFeatureContainer(((FeatureSet) val) - .getContainer(false)); - if (currentList.getParent() != split) { - split.replaceComponent(featureView, currentList); - } - } else { - if (featureView.getParent() != split) { - split.replaceComponent(currentList, featureView); - } - featureView.setFeature(val); - } + updateFeatureList(currentList); } }); + return tree; + } - FeatureTable tbl = new FeatureTable(); - tbl.setFeatureContainer(allFeatures); - currentList = tbl; + private void updateFeatureList(FeatureList list) { + currentList = list; + Feature val = (Feature) currentFeature.getValue(); + if (val == null) { + currentList.setFeatureContainer(allFeatures); + mainArea.show(currentList); + } else if (val instanceof FeatureSet) { + currentList.setFeatureContainer(((FeatureSet) val) + .getContainer(true)); + mainArea.show(currentList); + } else { + mainArea.show(featureView); + featureView.setFeature(val); + } + + } - split.addComponent(tbl); + } - featureView = new FeatureView(); + /** + * Main area used to show Feature of FeatureList. In effect a one-component + * container, to minimize repaints. + */ + private class MainArea extends CustomComponent { + MainArea() { + setSizeFull(); + setCompositionRoot(new Label()); + } - Feature f = features.getFeatureByPath("Components/c/DummyFeature"); - tree.setValue(f); + public void show(Component c) { + if (getCompositionRoot() != c) { + setCompositionRoot(c); + } } } + /** + * Components capable of listing Features should implement this. + * + */ + interface FeatureList extends Component { + /** + * Shows the given Features + * + * @param c + * Container with Features to show. + */ + public void setFeatureContainer(HierarchicalContainer c); + } + + /** + * Table -mode FeatureList. Displays the features in a Table. + */ private class FeatureTable extends Table implements FeatureList { FeatureTable() { alwaysRecalculateColumnWidths = true; @@ -229,14 +385,14 @@ public class SamplerApplication extends Application { addGeneratedColumn("", new Table.ColumnGenerator() { public Component generateCell(Table source, Object itemId, Object columnId) { + final Feature feature = (Feature) itemId; Button b = new Button( - itemId instanceof FeatureSet ? "See samples ‣" + feature instanceof FeatureSet ? "See samples ‣" : "See sample ‣"); - b.setData(itemId); b.addListener(new Button.ClickListener() { public void buttonClick(ClickEvent event) { - currentFeature - .setValue(event.getButton().getData()); + ((SamplerWindow) getWindow()).setFeature(feature); + } }); b.setStyleName(Button.STYLE_LINK); @@ -246,7 +402,7 @@ public class SamplerApplication extends Application { }); } - public void setFeatureContainer(Container c) { + public void setFeatureContainer(HierarchicalContainer c) { setContainerDataSource(c); setVisibleColumns(new Object[] { Feature.PROPERTY_ICON, Feature.PROPERTY_NAME, Feature.PROPERTY_DESCRIPTION, "" }); @@ -257,16 +413,83 @@ public class SamplerApplication extends Application { } + private class FeatureGrid extends GridLayout implements FeatureList { + + FeatureGrid() { + super(5, 1); + setWidth("100%"); + } + + private void newRow() { + while (getCursorX() > 0) { + space(); + } + } + + @Override + public void setFeatureContainer(HierarchicalContainer c) { + removeAllComponents(); + Collection features = c.getItemIds(); + for (Iterator it = features.iterator(); it.hasNext();) { + final Feature f = (Feature) it.next(); + if (f instanceof FeatureSet) { + newRow(); + addComponent(new Label(f.getName())); + if (c.isRoot(f)) { + newRow(); + } + } else { + Button b = new Button(); + b.setWidth("130px"); + b.setHeight("130px"); + b.setSizeFull(); + b.setStyleName(Button.STYLE_LINK); + b.setIcon(new ClassResource(f.getClass(), f.getIconName(), + SamplerApplication.this)); + b.setDescription("

" + f.getName() + "

" + + f.getDescription()); + b.addListener(new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + ((SamplerWindow) getWindow()).setFeature(f); + } + }); + addComponent(b); + } + } + } + } + + /** + * A set of features. + */ static class FeatureSet extends Feature { - String name; + private String pathname; + + private String name; - Feature[] content; + private String desc; - HierarchicalContainer container = null; + private String icon = "FeatureSet.png"; - FeatureSet(String name, Feature[] content) { + private Feature[] content; + + private HierarchicalContainer container = null; + + private boolean containerRecursive = false; + + FeatureSet(String pathname, Feature[] content) { + this(pathname, pathname, "", content); + } + + FeatureSet(String pathname, String name, Feature[] content) { + this(pathname, name, "", content); + } + + FeatureSet(String pathname, String name, String desc, Feature[] content) { + this.pathname = pathname; this.name = name; + this.desc = desc; this.content = content; } @@ -283,7 +506,7 @@ public class SamplerApplication extends Application { f = null; // break while if no new found String part = parts.remove(0); for (int i = 0; i < fs.length; i++) { - if (fs[i].getName().equals(part)) { + if (fs[i].getPathName().equals(part)) { if (parts.isEmpty()) { return fs[i]; } else if (fs[i] instanceof FeatureSet) { @@ -298,8 +521,8 @@ public class SamplerApplication extends Application { return null; } - Container.Hierarchical getContainer(boolean recurse) { - if (container == null) { + HierarchicalContainer getContainer(boolean recurse) { + if (container == null || containerRecursive != recurse) { container = new HierarchicalContainer(); container.addContainerProperty(PROPERTY_NAME, String.class, ""); container.addContainerProperty(PROPERTY_DESCRIPTION, @@ -310,7 +533,7 @@ public class SamplerApplication extends Application { return container; } - private void addFeatures(FeatureSet f, Container.Hierarchical c, + private void addFeatures(FeatureSet f, HierarchicalContainer c, boolean recurse) { Feature[] features = f.getFeatures(); for (int i = 0; i < features.length; i++) { @@ -333,7 +556,12 @@ public class SamplerApplication extends Application { @Override public String getDescription() { - return null; + return desc; + } + + @Override + public String getPathName() { + return pathname; } @Override @@ -343,13 +571,9 @@ public class SamplerApplication extends Application { @Override public String getIconName() { - return "FeatureSet.png"; + return icon; } } - interface FeatureList extends Component { - public void setFeatureContainer(Container c); - } - } diff --git a/src/com/itmill/toolkit/demo/sampler/features/DummyFeature.gif b/src/com/itmill/toolkit/demo/sampler/features/DummyFeature.gif index fa6b38b4c91fa17cdf59fdef2fc0ef46160bd2cf..ad9b6639a0a267cdb0d8bb0897539e8371127869 100644 GIT binary patch delta 1260 zcmVt;72^>hUpuvL(6DlmI4wfZ8Y0~hq6l>kWix@L%+{iH_qyzv$iX2I@Bmf1HI;vdB zvZXSUFk`}O*0QF}nzUr<+-VZm&7VLKg5XKCXh;%4limzqv}sWRN~3PX<+N(kUQ)Av z9^7TMYg1rawc_zgwyB@6O3SKkiuPxRwQ!4uXxlQb-J*0mI=jo4=d`>T`wHd>c;Vo~ zItw2>hPZJ|nu-NFa!lEzrN}xeYbF__u!PN^MOw%kx^&0@Z8IPaz^|Wc0;WfL2ulR9 z>)W>l#16?M>!!mha0~DEWH$g(QK21wPBDCV@!i(a4rbomx$&gSt5<&>8z_Rq+O_^0 zUvM+s^zh-G>~3chJo@yzYo33PUVZnKNCZ=-kG@H4DJ$v6AAkOtrcwoc?Kj|i1%|dk zM}jT5;C&h;D4~QU7+4`+7hb3#MtmvQA%B*9sE|Dzj_6@&AlfCOiu_TSkc%*Xb|~XP zqu5oWji#}pP+TbN$fJn`c@vkA7y7YVIS9cOB$5&u2SAf+K`9{wQXZsQSx;ISqm%&5 zRZx{ex-(KY@2vo4NCv5eBuwF{x#pB(devo(GF2z%oCW1U)|)adFdQUviZlp8b^@x? za7N|fPCvsqhGQsktM3vHi9AcAJRjE!N;5H9W;UzKHK!sSfhLA>)f$5_D=$YEr zBLWRz6{|+&^J+|A@`Zpvl;YXca1-!4pa*>cdn=4iRR?F3d@1XxicUqN-7+Id(jg(y z{uAtwMOo`5qjyQ`R0ZG?HLkPedi(8w)vmi~yMMyll(_Ql8kf1tz87zQzU11)Z@=Q* z3-EARbW0|?M&Wz#ZOOW;mN3KV@$bX8*{U#@4r6?(#JhF;aIu0792%0wkQ5%LAeSa` zhZ&Z{@W;DBBV;zl>RWQlo7ueM1~NGy991lv=5viW!+IN*MTgdmkQ$JRo1{ED_QcKV z;>HxqAZ;cj&^&=495#r5MIaENn)$M0(o*ZpS0)2_jdW4)%=@v)?x_fN{@Zp(jQ3zL zYEx7?=-vI#A)4u3RIheLQYU3sUnn?Hgfk9Tn~6)f_f9MB`*>vwPR>*13x4J~K`emA zpXfW04((bs9CR{zn=73zSyZa79qT%|-nm)`nHkzUeRD3XTJy|*XxcBgkxcoHmnWo4 zp~ly!n_9#eMtw}aj~M-r+ndyVhf;hGe)uAde__|aw}?If>PyJW=@-3^B>U|L7XBVW z;-A0%)a#$XIFh)&62KbuqFo(%L!oMvz_Q?hB@L`>YFWHh0?8b$h1d0|yV8p6mj;>j*KF!G@Oyq zG^6sle&64J&+GO4`Mh4wEMbYtZfb6#spZuJc@8dA201*2PhX4QzkpCY8 z|1SYF3-}KsWX34&i$`-FcN<}p3?zdR77xtoONY|=RQ*4U)Rzt4CK;v)721Dn_F|ZX zH0;Stk@O=zl@q6ZtOPV84zU*Smky8Z>r=eWnl@BTm6_!ncOPw%?ewYUnSe}7CSx!V zfad#gw7Gh|?kvoTTvBGvr=97d9x&hZ?0swS%4nwC&v(_PK@Zw|ftI?(9(t>OBm`k2 z=`yu8;XdA0zcPHK{>cu^*oZk+p!yd_F&GtfS|Fv1Sa*bPMs$%P$f;a6AZ!B303 zEX+u3bBCd6?nnQC=a+DU}*=lP0XB&Ni&r^vVPaVVZQ3SQ1oqd`x^ z@^`jXt=!_+KA)7Rj+B*j;i-aPZ<|SLfm#W4@@kGY9YIAPpRS>EWnQe8gk^>e z!{Sant%S!E#BY>aQ&)^3w=O=VRYES<8E!r{UOJypS-$YZNU6ATVM^{`Q&ut;x|j-7AxR+rzeOWR#vjkEtb!^myC{-Ie!2 zSo=(sylTED_*o^a#EiWA%FZ=-bfU8`2mac~5R<4)$(K&QVXUFxjck|1@$30(UfItI z`5>Ww;Z=F?{yepVJTVtaQ;w5;>-##TSJJyv{T1jpY+c52y5-r7y!P0$R#qxc)8$rs zdSurD6T=2I&erUyEYf9Tq0%HQB;vzBv z?X`3t{P+`VP+rzyG#9z`=lfwQW8xb@7$*6n_x?3%beEEMI<)T?Eyx2_#d8~!h07>) zUqx0ecTsOy)!n!XaS8p8a_zFx%@BGF;l<$wA=zYmkDSf=%dqyk{pH&R@bAA`MC{qs zWxI@j{|aJb%UMpiT*wwZcIx5BTiF_L?MWpbQqhcmY!}Lvp@d^5&X^Fp*`v1PW?}cF z_09V0;GSHHVTl0EV#J^pq*xJQFCeaFhRz8st=^0qdq zwvev=Z8j6jR0K`{Mkw~xDSr!52yZ^G%9@27(M@xDNvE|Ss**hqE1u%^!?z6 zY_G(|JeF55&EG7#Wh(lozc=KM9Qlx2clyl{7m_MaydaQP}U*!@|`i7so z)J*D$LwqWV@XnyZ-uSqF<-Jkh2x_od{K}@}-fTIt5q244$64e$*Al2+;DpYSdb{A% z8hSUU_|R5ed%mq~PQ5zFS_&3%P!!$kSwpkF?5ULsJKTcQr=I@i4)H@Dn8l|j>;`z# zzTX>#q4#w(svca_7&~LbV(Mgp3TMpEE|~h4>MXjjDCeBV7UrIBLq13175Ft47FgV( z0XNFI9vG&*`}3=<_p`TLK^dNHE3akvzbnCu1(0idN$jsPYa?>l%~ZEu@V=Y<5%Ku_ zP}*AM>G-eDBF)D>Dt@A96pqM;&v(B2B~BwIR$NC-?^SyIY4|0wTCs$DD|Jt+d|rrU zO{OotMZNJ}xg2T z%9xa5MZz%MPdxj{`rCR{rw8oRUWoXHD&Go=S&qoaP7?RE@=vr{m3EF-Qj7WSM%xf` zYU*x#sa2H7)PDUrpQv^b3#j+CRdruLWnSWIfcb&fetg($5o$jA;k0O_X z5?ajsCsgBfgkB%@ZV1A_+N{ZvWn7PDBCFy*vy&a4#u z8S3C9!hd(1X}!z&_`;Z3LceJjWG`u=Yu);np#rKm@RqKVkEvbeDT-ceJ z3jE4#R1QK|tbNY#)&Bk+n&IQ-y&01)S)mR2?p>}7X@J#Bq};gtHRv&!`YbgrQ|Q9C z>p`K4LbBI|Kw5Qjf znK8tR)jF09d)`gu7s*w3rD$Q0QFDLi_Ujfc(2D1=v+s-gH$a;owD$9dX)+IgRiA9t zb%UVf4twE50D>>gO0rGSs_qlL>5ONY5(P>BzW<;b5y$uQ1&&Gt%O{@yY7ccyt18?0 z_*AcF-3vW@E(!1>nVz5Rxp^_vReY#fY3Ewt5g8+JAb_Tzb|#&U=4of^-8f_2|ESPE zN)znugca#G?PuvUd=t_AI;F9}PQtJ) zjB0b7JQ{e1B<}JkNsL_XBc0u#0zG60?Y8&|9-`P)MXKgy!vayREgZ1|-`^VVp$sQZ z;S+diDw+ZIkt8KDft5f2lM_Acfs_`oiLPkd7T`roAw@B5z3E9ergZVyD4WB?YMx|t z18`~2+VW!ZIb}2$lEj+bN%AyH;De$Tx$wTGDQ;pR_&(=}(v%w`DSV;8GTGXLlZlR>mAoLi+{0%1#KZTx)OD(yW#=i_3X|i?ehhEQOpJn2mPZ2)Q z$k^K?c)`AQJ`?;9ni>=xblU zHec~7l4T<(r9@$$4#%C^((W7v-%rZpJ#iI$nW_$`hEqseacBj_crzCp9HwoZ4=St6 zL&)rZ4<+46mP0&}Ucm%`Aq;qtrZv|H%1X&6Ze`gTz#F`;sfh!($c_WS^t-AkY&~pX z2TuCUl9UH6kFv6*p^!HEDQ2)so+BJf6>nDo-jS|ux=4tEmb-QmLUi02b%LRz79Rs# zB+Fl*W{>lz2FQj4SkUI(RH^)oT{K($m39uC-}Sq;P;|p;ARjdUz7L^OU2`c9^oW-e z$||@TnovK;?uIESmnuvcIED5iFwKtpP{N{QB?(!ChFk)pKs4*j+0u3mbQU;4lCNci zR?A8{(XFngkZ6sYXPcjB%+tYQFn602+AS+tO1EMH)`!XuhJ6U83=NH|;1VmoaQsPu zeLv(E*&2D`VX>^ouSr-GCmOwUx$Vwf{QLuhQp{o#-v6TTjI77TWPtCAIcn)fTYnw` z^@yqht^IA?la(sRU zl20$CE`j!;p2DJbMaS}xeyRXU8P{Km+;%Eae*-%#w!b}@ST_Z`KI6SMS$wWh2r+f5 zT^zA~u}tj^B(}=F6}(?aMQUkZjLJF@sR`zgCLJw}4(+e7YtW;H!@-Yr3d+^g7u)*hE(9IqzQK3_lA2q32L6LDr4$j8$CPo96V{mZy(ons5l z#!WP!ho3&NEv*^*Vk-fh_@M@N56g2i=vR_zq~27&6R_X-tv+-NY_L-h)w;NPPi!r! z7UfgmTtR1Vp=W-rGsp+$KP}aZdc*P$>tL>wK6Q5LRV3dmj zG?-oM1p~vuAXwT0ztxj8!Hbg$AURj0vL4-EFMQwTzlvTbB}{%YYNunsy&~^-%AWFLHje8)Ga8W&Q}E|QqzKQ(_w6*X}Z-9dbN=R9PagG zW2ebJ;F+O8^Xd1N!fYpWC^XPHQqkki( z)9v#i?FH3llZ-UoMhG0zG7jy~lj@kGc2wLq%ekt~O#x3lQ92D4(d>uVYXl`5bULH< zu7#`sa4%(zVw&D*4EmmQpInz;IDu7oqE!|=U~MV$)3Ivm4Rr$5lj&CHi#4FZU7}$? zak2g9tlF+G-HURT*$fS`Hh6pm)=#nhQH(P1Klb|lbEhVDmuPi13it-2V#dIZ7!gvK z?H|W_M&LO0f)g~50?wmV47bo$*Ufh(*}Rx;g$+GeEKaCP1JD5XpQuPoB8w>OV<7$j zAk6i$mj$CuDL3ye_Z_kKXRO4*?0vsp8u-qRlM>R9q=121G5SZ{6gREo6tFEX+7#Pu z?xv+o0Tnz4zm4@4a1Gtv^?*@fHZem!t%R;IS67;wmL3KCXwg-5EMj^*#r>Swnhxxp6wA9*Dd5dLMj{IU|ke~?Y7OH}uvMh=-d=@f9t2C{B(se}D!JS_7wFeXL zV?@AS{GuA7?*gcnVe~H}d_RUp3L{$|^a8z{eF);DLer$){3L1_;CW{$iPU}I3{F`Y z@>z!oWRl8eSe7iLZnPU1;%q3@9r~_!fcMV5Ztu7{LnM+|FPS-kwVvi}fQ)$4>KxI? zY)jtn(|V6_JP%1A!IuLQ!LyVr;#+){9iZ-P0Ek?rJ_(++ekiseXgLY$9;1Uf-zYbF=M9!8>cjDU zhN+0{RNg%}ym0D- zZ0{{~BXl&KK^oUOg}J$K_lkJ4yya~`*E0cpm3Hz$@q0TcH0i8G>vwHpG3b#&8L@t6 z&kB7$-Sn((1;$2vj+R8d!AZ$72#b5j)&V4&atg3FuG0Pf7zg|246Z#utFRa>x=sOu zU*ZoI3_0F!u9nuq6fh-tbS^?JdC{OB&a}3@w60CtVStUvC-X_6$Mhr>D2=GkS0AZD zu_a;uB-nXPnbdyh$tb(;Ahc2rrmgC0tM5~9lg0;bvb@T-h4+%wm z$7fqwat+`HK!F7_*Yj4?8dmf^zq`u`{Cf=c9O=b; z(oTFn=J469nc(tD)1L{NWuD|6zwG&GShpSUtBE6}XX_xDg_89v_1KS61DK+~jXq&o0*63Vaq`iA28{(J}*`&{*-08tX4ATxYE z6p4Pi>DIN?BfA3S%8ojWhi??EKUCc0dJ$orqs=*$1caAp<^4FU|FIzDXT3sW=b{o| z*pry8xnt5>2h^?QidEfdfG6Z3Fjy{v+};q|UPcg>Sjy5i#GV^0if-}auS47GOWR+K zw^cb8xkGUHa)eQ>`|%(V`JQ5<6=@#o_k%`+`s>JFMPCl}FNWY$!lQ{NQz#TscMY1b z*3WYb3aS}&qRKyt8@QLfPurU#?z5WNbf!aiV?FS>`!z%RvrGFdsV6EqFaa+#ulKLB zC-+)B_TqR-kHatmkU7E(!d3LN?>QlVTd&_|l_BIGeDs533fc}q5$!=s2U=_+u>#Ko@n4fb>&MOCje_A(oU>X6^di!xY^j1 zBp>|r66;YSED&?;3^*9<5)}lvpj5l9*Zh5zA|~+%n99Ra1EQIq_hzs!FCINT8BqF9 z8OKQChrE;Gf+X4fsW-yyzLgsO=~a$bdGMXMxoE)6Krexof9TGAAQbRgcYc18hQJA&GPM|k12|#*1U~y^qcm;^!|a;fipecuy_;};j&gjuly#9& z;hRz{O~L(n0>9(Mag*a$J`EN+uD^PS)SmHmkjC?h%gbyTxf09FDy<*te;=`-I6OVA z;Cip{boF>RqUI(-(CM2?12Nyg_`cJ#7mhw3KUr-Be*MtyMEmq<=)QB^Y-7NGEFV{& zpPnh68zQfsrf;2pk-7g1A#`S^FThdwt5lLpm=!T!kH$h~a_)G)p?4?TtUkZ%pPz2m zlZ1;7_gnC5$EE1Ca0JZ#6j()y#QglWF!b;ak#!oX_o-%GGFjw5xsa7vDzZ`j;ju?+ zHGNBSA|ARHU*>2NLEiITU9Vv49gTAh9;}$; iWD;4{DnHMtzE`4r|2FVb*9v~> ziNHS>b|@7UCc&V5jifTEIe9Kw>aOyuTa9QbwOjdc?WU1@>>0;cBW~1RaB#uMEu@s+ z#yc~IFDSg)nAb9%XqsYGlHE**k-Srv5s}Ln7Kf002@c1EvvaLpO2vkUHWN!% zRVrkkz{f|$ok#98+jkgEmn!w`Rp%4i-72i+?95n=HYs!7jtUx`2~?XoyL#10{HvF{ zU3#6lL$-6SXtfFWJ=vKq!}cbs{hXU0m-Q*}=0FFI0v-1^>iQHn%g4Np$z14}H!HboU*4V3N=G%nKK=CTHFh zxT_F+&jciw_~~H#7hVpoa>Pfr_&mE4q*HG6VT9qn!x?`4f|omcPso8%WO})m$ES$; zc`EPDm0fEc)!qE&V^E&SQ*qM^tt0XrYu17=zE8BD=IHZ!Y*VM@@cZW2_b;x* zGj9=Tuxo2SZsm5yOPKt;d3Y-9+#u;2+d%j6XGB8+>D9LCr8~L z;jeVnU<)1{VH_wK>F|F)WQ3cY9fGu{DQ@TNlHO7|S1!$(&p-|kb@rauUSomv)kU4l z%ri^>jSWV=e(^T)H{SHR{y<_y&}HBEuw`syPu@X#x>2WChLZXfKAp1Utq2xn5N_LwU zEw8kAplb^>(#KBn#1%+It)|Q3aLz6r&zh2Q#tdcy}4Mk61=4VFkmSw#e1)L2|)3Kv+Bw^$V z+x*2B%q2p#7T}836NvsAKTiQlfNA_5niUWc)R@F0U z-*+oe8TAbMs6wr3Zq zdmeKS*jToQx86+0kTU}|R_$2x?wewDuMLNwhXOLFuI0LS_mj?`(xtgQR~W0&!@qdg zrQ}9d>W?H6^o~WBL9qJ`M*|3|MrSG8gYS)~JtW?wx>TfUze(=f0L|XHQxpm=H(LrJ z(HG@N9Fi+7&N0ag5jvvEF27nY$RiAs1&h#wn{6>iNJ5^Ruvo@Qdzs|mQRRI>xcqWQ zR}E6V^{)WQd!=)}d@$(6-$K;o<*wgY6z5!Yp=|C-H%2cJv1ZAKYg>NK?}Os|Rh_Sz zvfab~afl81EsystZL3%FVS+F3<-2U&%Y9Zprh=ndUPWAE!m5{iP zwY{7N^xdorOYsxpL`uU_mo^>IhgdUiw%X_I~Py(-eFa_Ai47Gc92NX7yahj6U z{$ndnu%puo=7(>kYO5*3-{l1YrW-~&S$f~wi&r?T4$D^fw&2!T_ZAi_$MizQlCL^s zBCb|Rw#{}I2EF%O#$eF}uyO`wzV`j6n$1L!n}CmuED3$%e;)Be)LZjB+quj;$fp3t z2m4`(x?mzR&WO8s(ic!PgUNPn2j3cdA~L!GrwJtl=K^Qw=+HyBYR%h_yv9+XHWwpa zPatSRjeT7G3hFIjtG+zab`8A=RC z$8&}U$6-#nNkNMNwg@I%c}9%*AaY1KLgZ@8VzBVXHl$jva)!rSD9;m8;xUyaj6)R< al&5uLh@1<_42WFWykZ)&Y$*%^I{yb-+^VPm diff --git a/src/com/itmill/toolkit/demo/sampler/features/DummyFeature.java b/src/com/itmill/toolkit/demo/sampler/features/DummyFeature.java index 8e7e9e8895..60136709b1 100644 --- a/src/com/itmill/toolkit/demo/sampler/features/DummyFeature.java +++ b/src/com/itmill/toolkit/demo/sampler/features/DummyFeature.java @@ -4,6 +4,10 @@ import com.itmill.toolkit.demo.sampler.Feature; public class DummyFeature extends Feature { + public String getName() { + return "A placeholder feature"; + } + public String getDescription() { return "A description"; } -- 2.39.5