From facb5dfa42c63e778dcac399cfa85d2aefc1a9c7 Mon Sep 17 00:00:00 2001 From: Yusuf Cihan <54748183+ysfchn@users.noreply.github.com> Date: Sat, 26 Dec 2020 18:58:06 +0300 Subject: [PATCH] Version - v2.2.0 (#37) * Fix indent to 4 spaces * Rework (#36) * Rewrite Signed-off-by: StormiFire <7520363-StormiFire@users.noreply.gitlab.com> * Remove .sh files from root Signed-off-by: StormiFire <7520363-StormiFire@users.noreply.gitlab.com> * Replace old icon.png for README Signed-off-by: StormiFire <7520363-StormiFire@users.noreply.gitlab.com> * Remove .placeholder Signed-off-by: StormiFire <7520363-StormiFire@users.noreply.gitlab.com> * Convert indentations to spaces (2) Signed-off-by: StormiFire <7520363-StormiFire@users.noreply.gitlab.com> * Reword description for GetName Signed-off-by: StormiFire <7520363-StormiFire@users.noreply.gitlab.com> * Change 'helpUrl' to README, reverse deprecation of 'SchemaCreated', and reverse package name change Signed-off-by: StormiFire <7520363-StormiFire@users.noreply.gitlab.com> Co-authored-by: StormiFire <7520363-StormiFire@users.noreply.gitlab.com> * Lower the version name due it is not a major release * Lower the version code because it is bumped twice * Update docs * Add information about thread to docs * Replace badge locations Co-authored-by: Nathan <43486313+StormiFire@users.noreply.github.com> Co-authored-by: StormiFire <7520363-StormiFire@users.noreply.gitlab.com> --- README.md | 93 +- assets/blocks/event_componentbuilt.png | Bin 0 -> 6182 bytes assets/blocks/event_componentcreated.png | Bin 5574 -> 0 bytes assets/blocks/method_generateid.png | Bin 0 -> 3155 bytes assets/blocks/method_getcomponentmeta.png | Bin 0 -> 4733 bytes assets/blocks/method_geteventmeta.png | Bin 0 -> 4391 bytes assets/blocks/method_getfunctionmeta.png | Bin 0 -> 4588 bytes assets/blocks/method_getname.png | Bin 4012 -> 0 bytes assets/blocks/method_getpropertymeta.png | Bin 0 -> 4582 bytes assets/blocks/method_listdetails.png | Bin 3798 -> 0 bytes assets/blocks/method_randomuuid.png | Bin 3117 -> 0 bytes assets/blocks/setget_async.png | Bin 2855 -> 0 bytes assets/blocks/setget_async_2.png | Bin 4876 -> 0 bytes assets/icon.png | Bin 2682 -> 2435 bytes assets/other/method_getdesignerproperties.png | Bin 55616 -> 0 bytes assets/other/thread_choice.png | Bin 0 -> 10823 bytes .../DynamicComponents/DynamicComponents.java | 1111 +++++++---------- .../DynamicComponents/aiwebres/icon.png | Bin 780 -> 2435 bytes 18 files changed, 482 insertions(+), 722 deletions(-) create mode 100644 assets/blocks/event_componentbuilt.png delete mode 100644 assets/blocks/event_componentcreated.png create mode 100644 assets/blocks/method_generateid.png create mode 100644 assets/blocks/method_getcomponentmeta.png create mode 100644 assets/blocks/method_geteventmeta.png create mode 100644 assets/blocks/method_getfunctionmeta.png delete mode 100644 assets/blocks/method_getname.png create mode 100644 assets/blocks/method_getpropertymeta.png delete mode 100644 assets/blocks/method_listdetails.png delete mode 100644 assets/blocks/method_randomuuid.png delete mode 100644 assets/blocks/setget_async.png delete mode 100644 assets/blocks/setget_async_2.png delete mode 100644 assets/other/method_getdesignerproperties.png create mode 100644 assets/other/thread_choice.png diff --git a/README.md b/README.md index 03cd302..c4a3fc4 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ # DynamicComponents-AI2 `Extension` +[![forthebadge](https://forthebadge.com/images/badges/its-not-a-lie-if-you-believe-it.svg)](https://forthebadge.com) + [![Maintainability](https://api.codeclimate.com/v1/badges/31e4cd31de1bd0e186c8/maintainability)](https://codeclimate.com/github/ysfchn/DynamicComponents-AI2/maintainability) Fully supported Dynamic Components extension for MIT App Inventor 2. It is based on Java's reflection feature, so it creates the components by searching for a class by just typing its name. So it doesn't have a limited support for specific components, because it supports every component which is ever added to your App Inventor distribution! @@ -10,7 +12,13 @@ So if you use Kodular, you will able to create all Kodular components, if you us > ⚠ The `beta` branch will be reset after every release. So stay on the `main` branch if you don't know what you do. -[![forthebadge](https://forthebadge.com/images/badges/its-not-a-lie-if-you-believe-it.svg)](https://forthebadge.com) +--- + +### Asynchronous support + +This extension can create components asynchronously or synchronously based on your choice. If you don't want to block the main app during creating a bunch of components, go to the Designer (after importing the extension) and select between "UI" (asynchronous) and "Main" (synchronous). + + ## 🧩 Blocks @@ -78,7 +86,10 @@ So if you use Kodular, you will able to create all Kodular components, if you us --> - Changes ID of one of created components to a new one. The old ID must be exist and new ID mustn't exist. + Changes ID of one of created components to a new one. The old ID must be exist and new ID mustn't exist.
+
+ When replacing an ID, it will loop through ALL IDs and replace each one that contains the old ID! Even if the ID you're wanting to replace is "Timmy", but there are IDs like "Timmy-truck". To be clear again, only "Timmy" from "Timmy-truck" will be replaced, the "-truck" part will stay the same! +
@@ -214,23 +225,6 @@ So if you use Kodular, you will able to create all Kodular components, if you us Component --> ID - - - - - - - - Returns the internal/class name of any component or object. The returned value can be also used in Create block. - - @@ -318,21 +312,40 @@ So if you use Kodular, you will able to create all Kodular components, if you us Get a property value of a component by typing its property name. Can be known as a Getter property block. It can be also used to get properties that only exists in Designer. - + - + - - Gives the information of the specified component with all properties, events, methods as JSON text. + Get meta data about the specified component. + + + + + + + + + Get meta data about events for the specified component. + + + + + + + + + Get meta data about properties for the specified component. + + + + + + + + + Get meta data about functions for the specified component. @@ -353,10 +366,10 @@ So if you use Kodular, you will able to create all Kodular components, if you us Returns all used IDs of current components as App Inventor list. - + - + Makes a random unique UUID. Use this block in Create block if component ID is not required for you. @@ -398,16 +411,6 @@ So if you use Kodular, you will able to create all Kodular components, if you us Returns the version name of the extension. - - - -
- - - - Sets whether component creation should work asynchronously or synchronously. - - @@ -417,13 +420,13 @@ So if you use Kodular, you will able to create all Kodular components, if you us Raises after Schema has been created with Schema block. - + - + - Raises after a component has been created using the Create block. It also will be raised for components that created with Schema. + Raises after a component has been created. diff --git a/assets/blocks/event_componentbuilt.png b/assets/blocks/event_componentbuilt.png new file mode 100644 index 0000000000000000000000000000000000000000..77bffe6177de27d147c276f704beed88ac62954c GIT binary patch literal 6182 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 F{{!5>J4gTk diff --git a/assets/blocks/method_generateid.png b/assets/blocks/method_generateid.png new file mode 100644 index 0000000000000000000000000000000000000000..afc3ee12538b1bd2366ca905704761a84cf5fd2d GIT binary patch literal 3155 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 literal 0 HcmV?d00001 diff --git a/assets/blocks/method_geteventmeta.png b/assets/blocks/method_geteventmeta.png new file mode 100644 index 0000000000000000000000000000000000000000..3ad366e97a9cbdba21a71a467c244a55c4c57a3a GIT binary patch literal 4391 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 W(YkBX9!vfKLSbTHsoxBBOZqoG*#(~f literal 0 HcmV?d00001 diff --git a/assets/blocks/method_getfunctionmeta.png b/assets/blocks/method_getfunctionmeta.png new file mode 100644 index 0000000000000000000000000000000000000000..87f373a5ecea369d3948f8a827cfa46da1e17420 GIT binary patch literal 4588 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 GiTWR0`GYY4 literal 0 HcmV?d00001 diff --git a/assets/blocks/method_getname.png b/assets/blocks/method_getname.png deleted file mode 100644 index 14ff7d7505e9d546c947ec55c163bae9b2db715e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4012 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 literal 0 HcmV?d00001 diff --git a/assets/blocks/method_listdetails.png b/assets/blocks/method_listdetails.png deleted file mode 100644 index 05de1a38f8a25704219cbc3e40deb55e007e1892..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3798 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 O1(=&!nUtP$i~bkG*8pt* diff --git a/assets/blocks/method_randomuuid.png b/assets/blocks/method_randomuuid.png deleted file mode 100644 index 94df1bbd25c78bad70bde56903a9ed68dc0b97b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3117 zcmZWsX*d*W8%D{#FJ-chK{H`U_AN6*iKf9!vd0*^G1g(S8wOFfiL41<6X)e=rJq8?;ssGacBlr%Sk)F$$$-mc_1rP+M+?5m__y% z*OQSO#jQbKmVWv5Zp6L%!?=By_~l@SXtME*lOutxp!u9`cS)|*koxMO|IxD?0QO8a zc=vrCOqUP~##_jr;r4-L^52|Fw>YPGSA^{n?WfWkZXXs?1a?l$j~qYd^_M7KsXU^& zB%$A~b%!_aXW6t+NNkuwB~CDb{4AlvW0;f;V23fS?RC#;hn>Sj9ob*a1qfI}&ATT^ zZCYPH_qxovFD|(8f8%S+blQv?s}UxM}l zA06XfzTMYabmIUo^O(g9LU#JzQGx`d%8GKiPRpJmm%~%^8)a6JGuq>Qh4=G&5~DaZ zbo_HFmVJjhp%GHQ?Nv{cm+h7e05kc9GSv`DbM~^vwfJvIlAF%ETNkhD#Yt6Gc|H>_ z?JFxI8&B8B45$5CO#cAF&3tmx?Ma_L*m!w!0_m@V6oXf2j%b@&CMOGJQaTKg-47mg zaXWf2DnVDb-Xruj%SIpVbpFx3SK-lRO8ZhT`#M1mDaT{(FVwrSTa!?KXN})VFh=*F zV+0z|?%SDT-^CvgTi$y@YjFVaV_Q*-*=w`ZM=5&1+-|ADuSIQ~6f9R(F5?Q7bOD^v z6$HhMe%+QL@2=8S47d*g}J-KPH#q>S20O=jJQN7$yiM9y!wEwEFr z?qUsKwHdD6kK3tOn9>?jd#rz5W^Z&97cYCyMN3f>Sdpt;YolQ3Xz!+g270wY>woN( zI=88y+V1Pj)2k|l*o|gA#(NdUtQw)hD~@mULb@dJ7+(3e!m%*u8eJ6F<|F6q?wgTGnpR?!LNuo;+Qb!w4L9N#PfwprB=X z(#j*&;pVgpI;#g?of_Ob{U1`iU0tOrEq-kGQLA7J8J1lfrKI5Gg7bnWX}x^&A-T2H zx!%bc(8{!f5V$U_+p84EfX?1J$(I}x z;Oslv#;s^#I(ycev5sn77r0B{dU1?ur~}B)$~x5x9?P$%FbovGc%3NJ7>YFYSl{|Y zGF7ch#GVHPww6eg&$VQ%@nslW91TVu#-_ON@?`-Z=rJh|(=0WX+=I(~C`^6t!wFi%Svf7n7L^>(3x&Sb_aUdQ8R zG3|g(EFx63E@7T5j+QI zjr(pN9K)n9@f34=KfUZMCKHReIoI*iMEQ07rzYk|HbE}G#NWu<`4+F~xK_*5k%J&7 zckf_{=HduGkffIE5-oM-TIZ?_3N)E#?VR8s1ZnwLD-8&P`|Y&>gk*t_Jl z1H}EGtxkL_@Jj{WxeJc9s(iH`46A%}WLqUid24;;v!LjeFm9%!hXh<(5&htZ)wXI3 zalSL~=W_KZ<<@Uu>DDyR>w`@Y+IpXGFH2W;WTL1TLx)SW5ar>u zh3uxBu(tjp6uq&h#ZK?s75zN$6_J`^Ulm=u$CNljCA35Bz>`9-D!t5MflZVvTQWuN ziDM{?7Sc<(wfDHr@s994I2)Wt+Pm0E*%L!OwgbmllLsCsJmjW|Yb3KjtTFx|3aP86 zHynwOluQ24bHM@=s7#LC^$(8FVS#enaDGy9#4B;k=giY+WI-|N36R{bM^s{p{^^nf1-H6y@1w0=LAH(&a2sBS=qQ)B6Z=P1{EQ!jj(Fg>QnS$QCJjVi(Mnt+QKWP*wi?z_gd^=&Kg zgGR8f+eHzZO@W8DxiyD2Dbn@sYvN+4f~=m*`jEhq=cr{Xa8o0gL_o};N#sNO7_d@4 zanq#Hj|hM-;Or1}&FU&RyQd609q;anm!^YOMb zv{>*q<0m{ptzKG(LCw-*+lbrZ%F@RdaD$E;2W!|;@MCLC$Ly@WK(9Mr3F|xKn-QDS zourwDC(!%JzZ|W`Y<5M2#hy{HhU6$mRopQU{op`tqO4MtWykBa0 zTp)3hxHCpi8J$O9^d7%XX(&Wh?B)@)>qW%8!pfYtck_;r&D-I zh2t&lQr92vjFSN+Dqj{~*xYO42pm7n5wp09T3-5PtCiCIX7+U)=H+Pusn|k3hx>Ec zmm8qM&8Bg0ZtYm%l{?yh=E8GA9EGUuqPrr0=06}gUU`h0y?Xf1C+3@!eZm3* zfF?#B0YO-Q`LHMg&KQUd3M2&KariK|KwOwlkSD7h7#`*x<{N~U|9|gqE+Pu=9_WjO z|04+n%Kt5LW7Sz+w(fY(pg;`95&@L=4R!Oz;c+3pSYx1{~^4ASnC+j^- UL@0PD>l?skX^uqH!LB9#7v%Q0O8@`> diff --git a/assets/blocks/setget_async.png b/assets/blocks/setget_async.png deleted file mode 100644 index f942f09f25f625b6264f00c07c513458194bb838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2855 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 BnDhVu literal 2682 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 diff --git a/assets/other/method_getdesignerproperties.png b/assets/other/method_getdesignerproperties.png deleted file mode 100644 index 034884a6fb8042c260c0f08cf6a57938730fa32e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55616 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 N>xjuB&<)Iv&@|BJZyfNJvD7Dw&av4Tib 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 diff --git a/assets/other/thread_choice.png b/assets/other/thread_choice.png new file mode 100644 index 0000000000000000000000000000000000000000..d1a026a3fe66407625c18e9425d85d0b517c6310 GIT binary patch literal 10823 zcmbt)byQpJvn~Y+rD$;1QlLnnw73)!pm@>X?pEC05};@aF2$j^yF;-Sin|lsDQ<`F zyXUO?yWjntbV`0NGR z(>oio>DJT7Gbd#!aip?g%AKbZRC6(TF(jnQXv{mq=TGMt_8&E!kdW}5|9U-JGNW-v zLSk8v28*e>>m4j&Yp9y8@f>R_p(%kU3`i0&+J9qBAoCI^6O4!Fey|;{^^2=fZjw&= z99F9TdDauokwSEU8Idewxw|=?Poe(O%FlwEi{QP)NA;iOfajqfmbUn}u(0%z2My6$ z{dAnT&VD94W$@EndJH=a|E$>^&5`1_lSN0Kb-G2drKpGkv zR*qM@wJh`0*G8J>g*kQKt;=+(CH-QY@Va4eaj}K=mP^O{Sm(SUsfPg=K=4`1|)gw=}4t}Gr= z|4dP{$TfbPe-MdFI1rcBSLLmz{`!7C)MmmgO@~mG-Gnvy?N>Z*%hx=$NhR3bH#7u* z{bw5ma^1S?6qT+w!yPx1<+L-~xgs1Kl9hKy8>qEC!GE4Fa(O17`j^R~nrVD)NQp8W zFS}W{JH4T)ROP67`8xN9tCU5{MTI(R#bX!v3g*>oq$#anq{$*z1fwDkzap+)QqR=q zt)y1Lz8KYwsRp13xJjBLcnHVW>Q)Oe?9U@UtRo70{bJ2>OFw zt?c-ReM_@%;Ek%Ry#)!6?OfE4KhAO*0w`it{6L z4^pwBXYIoUUk2oG`EJqy>Urth2sXjtXn`$9B>on86(LOl=Sf!PG>gxx7zH`U-e|ld zm|E|13tG*h^ktV+@ZT?Zw>tBBPXu`Ism~&~?*wauFWj)laD*$`9{il5H>(bVtoF~5 z=W~S*J;4TrQd_T0%H+GM!a=e?R1tC{x1gjcE(ZE+(?m%wN9DCj&g&R=Tf%Gx6MaY1 zyA0x>^e#0X*ihY<2>{Jn6g(o6D zQnV%YtUt}8JMkz(@c6&6ph!EMWZShRaq`L>WE3(N-w2FX%Jc2KGaVZz~Q=qH$l@Ap*o0$|}${*+)WRpW=7s28Bm5bj}W?oOaMRT&@C^ApUk zlP==P>ZqHHp&d!p*yF^n=u|ZIOO`(CjuW#t{bC{sqtat&!rW+@6()oS4fjU1SYSB{ zgx8{=F|^fd>3>y0>Oy!EjxW`@XH7kSJyl(3;o|#3Z3!x_jq5;6miz%`+BTu-SA5Al zp`n+6FmM$A(4eDd^gz83^mC!l>L*YoeXr7Vk;JN03bc7Xw^7>>U>F?DKA zV!cklD5LrOI^}_=Jh?ndRY_Hqf1{`rXwm(1DqnlNC`fbe9b5PyZX1OEaCQ(A2tP_L zog69kyWR&Xs1--6zFNAdhM%pBWt`5=@$I&s1N|;&(2FNQE@mTlr|4|mr2}I!#f|Z5 zzQ=O4}l1=QNkpAR)G4Bn1BWZ%V`;&GKA z4)cVoS*N0#q-xbl{UR^Dzk7ooXXl!X<=N`}zLX}_c~-Nz?I9r3w(^Z{^Q?w!OOo1@ z-z#NSt~o^R_B)LDeOovPxXxCXTn_%^TyaM;qBX@-Dk5P%I5LqmAc4@dX4@-nh`g7& z78~MJKPzLlj#S1qO-g|ShOS5sGD6by&&&JZ^O2PKRc+X*BlXk2hJmYEVQJpi%NS_W zCOvrw=1X*8t=Z-G>q??|aF=(cTs*qULnbuZW@GQL4i?Bj%OivbbSEhovW7d(8VN1f zJ3ABrK{NlkL>@bajig9AC5>zx<<59=C>M%=@duml7CB*tciskb#44r>zI11Ac2#s& z!q1afwK?;hYs=MI>^hP(Y=o>ri<_Y{C(XsB$m5zeDtbzy<%MpQ@49fys?-RJBb^3s zW&ErQzE$#K&LcEdFhE#ycIqL*T5g-tjbiG zke`}{Jr;CGI2XK1sg!sc_Gq(mHW}sgTTdd8PftOxg7PRvs<5u z_u`dmn(g8`VNwM6F%`b(7c_ificB}K_u@6dUx|$qd0_GFw&8_Cd~7gn{~6Q6j~c?b zozzDCe_qLbJ*z+a)C1#H-rs=2@-UJN?_JY{Rs!To)TT0@krFgx^Y zYlkKmJ0Hm!NL(6P<(}=FHo~5i4z;1xnPi}mme+P^WG`nbH>F&;q6-!fu<%1$M(h!sjvWkQ7BSyh;Vp^FnpK2^rt_G_c4U97c%M`mk!3W|ScKp_~qDw9_$XNNP8*KfG;fp~fAIlM&cJ$TeF1 z8ZZ&q`RUy8n}EkEe8B2b!ffo7P$?D8rd>+Vs7lWdrbCLLoZf)Xj4EbtiJALsnq%UN zCNx-58KO0vcEiX`K?6zr0>mti1x%ZMe}XBBr0|X4tB#c{ z>OY+{w-3wGX8w3GYM{0YrBbPIacI`}NA3*XonU%PBv{B9rBqra29v(#0r@B%9=fE_ z|C-*c9LdqB0izBN7H~CqxnV`ACa%jnyrpLrqFn6^T3NUA-?0d<;>OlB6E-7=%Cp5k zvLs1hCmjD0P7EE-)<9L4+mJi3zlkZFBJC-NNNK_m?-ANFrJK%_PAV%AZTuMFM{XR) zEz$U*0mEnn|GgMS{o2o3*u<0ft5Mg^49Q9Q*$l?g4PgtU5Pl!9*ZZJ8?_=b%G4ges!EZud|| z#f>-{@re;A(aWx)$jy=(;7$QQ*mOU)&k9WgNl)@bndDM_B{=qnto)ipX-trv(18zq z6Q79fWY|#A!5hk7BNqN>vv7)G4FATN%DQDRy29aznG4gy++NNqjP7DSk zmU`D`cc-Gtkl-Ep)dM|-Q=BqR5x2KP+R81ocsWN+tM8X&jWgm;`d!zFBs@eIIRe?F zJ4>U6wZv=t9#5y#&kG!%IVQtCJOKV~ffzIfKxjl8v__h-aD%0!XkR3&mEl>mxEDtB z!Is3x;Oiv3DxXlZyCeDP_G0dTnF|`y(Ctyf&TlV`+Z_dIaS(3CmavuuMjDm~27o3a z=?#g~+IT!%=0eT%71R3`BG!@`o1Xy~8gKcr3=O$sDnyazloSbudVgLK=9T?8KA(9U z)se%&?EXR|Xup!W9S$<-ff|K7CNV-~doGzSjnAYoK7RbzaYJR~yRY|M&o@uA&OK-B z^x}nPBn>Z6sV}*LrWp>}OJUNrOKK_f-NGqJ0)!4YiFQ3Ko{qip2u=&`HA0rxism=k zVj+oCM0GvX2p}`k`I>0+BVdyL)m0!K?d(=h}dHW zQ4Bni-a8N8euSqdmx;W1i6Q0g&KHPI);rpeL_=ZBWgBpz=O*8GWhvcHxc&!^9m6!O z3KOiCNXm;bZk24#OV1?yoWCrH(?O3uK@!^0r>0j=4wW8HC@LL%UE0SXB>b9~#YoH@ zD+T6Zq$AslX5*~9>}8TGv-kG!^M(xKBPvgV8*Ng9 zSS2^@_0>t*4oZte;p9~Q>3|3#+axE+*R~$>)JTY&X;i&m8TeK8b2^{;=vSf6)M+=3 z8U*v88}M7?_;-xU6f0iz8=ASsho?K-MHlZ$7uYk5KAUyb((50d325dz|x?v@?vK-kzy0CX!%~qM@2#M zZlH*Yo?f@MLqwB4J0T~;g#-^!%Z8;%Pfx{V684`$0N_bS_$c*njinpF-&U7TqCl9M zcZs^M^HjE4vHD!=cf@H0vLR*B0kkrD+310Lz&v1 zq=wvJwq|4)>`!OHzfmX{ZgFO(7*@tsUH67Ettt-b=O&`xON28s3zuVqoo_3v4+Hx~%k?>hsDAce`&L?1 zwuPQeSAji;YgG+ zb)H2TxYsv+**`l{Lk$QT*I!wrZg8$e8nz2s3Hi$B`@oRKz5`RBV(OePWeDeZ!0ZE- zkLT0rmgB(Jg+31kIweZQTW*FsY!LgFVJm&TNkIlEGp(*&yzq2EJq6N;Wt4cq4Z*q* zSjSB{scNk^9eKvNg~eC;aUuH=^!wrCwGhj*jcHYrL}#cu$u;#^jCPDx-tbHQ=!L+Q z#jKke_OtVM9EM0YeEO2ZaAndoFNWhoYR;`(T87UgzHgiZ66cYUFwMfQ3tB$ml^9cH-a}{K8+Fly6%N%azE~)J%tsaNUjTTckT~h%J^q zbITX}f+%}S>mQx14>PP8N3Zf9&XJbBi!3(f?uIbmE zvH<2%^>HZ_7#=H5RN7!Jz&N2U2)|6qkB69h$QONV<(cmJBTKj0Tqww4{MhEe_bCm+ zuXnu^j&08()5`=^F#h&PV_zRp*j}ipX{|&P)bMyFTDjS8o$Wg(1n6Xu#E75JGncCW ziJIu9y_BQNAu%3u8>qSy@={?MevgzFXB{A; zx(_$1b(?gb1mLZYkp3u|I^vP`2TO)N+!rM$&nPexEA1o zH%xW=qWB`r()S*t%J=z~rP%FUVMtJH1kF-|^tt+Jml--3o1h-vfkJ8h;MuTCg z>m#57$7n8dpCXD13XM3)rA1#nj`=KPLe1(c90?pp+@AD?(gaoPYV!jFS{RfxTujs_ z)hjJJFZNlH>uTL2HHcGjphn|uMOUX^l5kO$KD6^>Q|*m{e(pHUoGsd)EDX(DfCO+z z(#G`^Cmd(h`cq^l*JVHy4tyTEYrhv&YSzlA#UyE-Cx_;D;*_azaMqz_Gi>?@!2>A<)bEQ)s4+MpR3xg`qbR> z45IaY2ISi`(k+aQWNhYU(r~qAQ86u%-_`oBGCb^op?uTz)r?hsu0&PLzPMg~#A4gT z!N+>#6JtKdoSrw{FOQ~*`oCK4FOlf&5~NtTH--7pUvcQE$o|Q3qY}tg@!E?y0YehY z*8Ic{*!$xc_#TU47aTstuAmw+RK-Saywa=i^neJaCJQ&U`$;NEhi9jlr{I=|4=qVB zU{tXBg6r0P7q1k3j2pwzfO5SxQ>@whVPKSBXwYo6{mQ9j%^qH~h(adA*)iTL=0yUk z(Z{mJ^L?AJ{Y;;b5(@-^S{F*wlT{pXISxC1Bor1D3Ujs1?>MW^q-Q&}6*6%K*!GOX zy2w!LxpsqsraHzeaVfPF#b}lbM%!D-_>IF=n9u>KA*Vm2A&-jFzOM5@& zSQKSQ_nl}_)I^*tIyhV%ynSKVHuSrwwlI2KpK~L_fYd=Vcvhfzs#q<(mlNeyG(f~w zBHigBBzx$w$L-VvvJA1;hkoEX_~5)#MYetv(bM4jdC_3o(uF{91h3p;H2V-mYO9`e z?2$1TS1T&RR`T13t{CZVI~H!kz@>KJ+eNoH@UQM+arK5eQm-~mn5|}k(nJ=Jnp}uv z1j`R2%k5Gk(YnClcpgkiLSZo5%j|u30MK!!_Wzwlal8OaJYJzPGcj$00)0nsR9*5v zQw^_fSbkeRTJCUSSpHC`2qE0eH8_iXlF6&|1*ihfMbji_sXE=Qf(u7}i+*d*Nis)Y ztGEoG)VzscikZ|Zt|m3BNX;A03}b?$D(FYSJt{MUVf>p}hGcbsM=Oq8q0N2`86 z&{@s9r3jZFXEeT~Uom|-bq((9C1^i5Ax-eRd1gdIFk(j2d(F`exb4JwCCm_bQ9oXJ zcaThq(4@~0z$Ix9)2K1VHtKQrHl8v#%N8}hN=G~CfBxY2z#VGQ{#_pIyaz4e$JI9K zTaEU^>RoPsA7NH1`a_F6b<<`)?ON&!CKWXD@*V@!l+nG!+ec?KjNHO^Nad|<;J+Mv zO?t6RbY*OSL`}&{u7jxx>TZOLw+vsYEnapDCeXn#OL zMrQC&9_QMq_n6^yX;9|z1l8SScOmCZ?$QS~D3g#<);5Ek=c^<3Or)ZzBfSnA(c2$x zSiQYXqAlfB3KS*}C+W;0Eet&w&eA`CEl7HQlniu$i=VD$f5eXnB{b-p_>>l1bfW_` zkE>W8@nybt1^kd-e6b)(F|4Tml ze0Hp6gQ`dTYxWpnjVG8}JQnh4+NFxd`#8Wg8fJso9?h|suVZh!JrvxZsRXgwdh+1T zUY~6-Ffu-$ot^C;7!dRDXmqr$*-9|nTi4^OdP@oPvtpSG?`w@RFufXzkpPi+e|cQ@ zBhnwq2$YRg%S4%DaG$~#;@x*EY{*~fQoNe>s??YjAwOz&78S7Wg_P-tL2;sXYu?iI zr8;EF{8?vc#divYf zXEq)F&t70+c6Wtf){f;HSI5A0Q6c4ey@!j<2h0Xx+pe#;ZLf}3?HwJvhSL+qXXLxh znA%KeO7`guI`Csl2Poq_-r28wD9zoOVKYHUmn|&l8~^~Zw&?;cFHKEN=W_mD69T9p zk_BIgZz}0Rco(r!^_Yg9y3bx&5bBfe7ys3-?&kp2Y1iA43c8j!CPQ4R%r#J{?AJ}?AFiCzlI+-I-(1~$H?>HA07vV=) z!XBr&>N4Q^s-B*nH_w`F=XvtHms&iC!~|{U-u+DDS7E8=btS8MydLqZa68hgv7W{$ zZ#fNri-I_qgy^eXSlwP6bU)nR)@FrmtG{kW+qkf!svu7Ic7L;1esa=BW1V-=YZu*$ zz*?*_#S{_}s<0TPN4)lnmU>u8ZqfhLvAp=YiK^cKE>$^+G9`|7prR-oGG3r)&3Msk zCMwF{SNZpv^%R45 zr$azKhqYk!xpy{Gaf^*k1*a-YzP`RXE8t&pJT@~8N&|O|mrGs%Lc(Cb$J=Es%kfHS z*{Ldfx1*&}Zv~Ag#S3VX-0QqFSjzOl)bH3Mh?(Z);o|DiQMtEh_}v8Y^K>`g$5Yg-DP}hzf-eoV5Wwa zbQ*kW3)YVM3QLJzNEpcwj);rHFWtDnoZTEN@u`~Bt~}i!K}jgQ9zcr{IMV6LIGsl>X1Z>+d0vSb1Okg>0v-;kniX!n{~9&K!Fd~&rOZ9G?FsnP1` z5;={hG}IB(`b_lhIA|;d?o&M#7#O&+y$ySEg4#9X?@HsowS)TQANQBb<$v7nH+kDT z|Llx&`L)eaaojpQky)uTnTBXW_ZJFY1+s$udY^~ut&;-Ldug&zm=;>74a2}O8#8l9 zGPikr3_O7Od~X`}{`L|wi1;;EsFV{w-T%pFx2Pb#BEEaU>!@{bZ6|E10g#i2m$%)> zSRM=#7`^>4Ut@`4ZfaMyJv7`BS!5rY89NnZ?j?C_mkpvom#U zJQhRBjh+xNXlz|2>N@#d?P@dibA`zOKEknduhyVk%9ZNLPn|KXVyEH$nZ7sD{Lgqi zPE8QO)6t?2uvV{2E0AhEKC&}Otp?qPL)2lt_R67 zP+S^y5w-Qz)hr!$+FP^rwKe<8MK@~@-e~C;Ixm8a^NLgObb0&3_d6gP+eAjutD&hU zg3QjQ&(k(MTxi^$uP+~)Tv=PocIJKhN-;b&RXa#D#e^pnP5|URo!#8c^pA`7dLkI% zCgFZo%-p#qBACtU)yewZA#(bYaB63arFmc3?El}%rvEc!wbO163m#2S17g|J1YE-P z@p8ETKXJ?d#1nRHuI+kH^!t=ZEvkSq+Y?1!UCT{L`5j;VmnP_@z^W#nAw>4% zGn(Nv{-CD-Cyx%>kJU-Me$I7cBwGjY_VM`(iSC}BR*dk&_D5f#;|`SVxmxSe=&H->JqM(@Z+tIZYjOj)}V3mFAmb_v^?KbT`_X3vv?)cy9K_DcU3cl|#f`TvyE zW98dJo)Dxr$3R~dvfdYcrrqHD;~xrm;jDPVy%6{!dfsxp+EP~ip@#=BE9u}+=^FjV zWITqQnfdSh-|Tt*{eM|n-B0K*^T9l{^@5G}u@5%HRS9jGPem8PycY4k0h|kLOdmLq zw{ye4H8`KPp^>bpc=!~Ec&N3Wj;8?Zl)LOr4a!$7C6G1TR9N=QB=nv7oo~SkEeC9; ztM1j8qsXdmEG}Z;R+uViY)WT^wzsAoyM3?eSh-Zg_EAvO^?8I(dP8JQ1Q*a!q4L1h zI5x}_%+!y53ri`PznY$=3hmH&K0i$kE)M=<4Dny)1^@SK;y;aOSC5U^seWabc5j}B PKar#*6u@QT27&(pN9!q5 literal 0 HcmV?d00001 diff --git a/src/com/yusufcihan/DynamicComponents/DynamicComponents.java b/src/com/yusufcihan/DynamicComponents/DynamicComponents.java index 09743bc..db387a9 100644 --- a/src/com/yusufcihan/DynamicComponents/DynamicComponents.java +++ b/src/com/yusufcihan/DynamicComponents/DynamicComponents.java @@ -14,17 +14,21 @@ import com.google.appinventor.components.runtime.Component; import com.google.appinventor.components.runtime.ComponentContainer; import com.google.appinventor.components.runtime.EventDispatcher; +import com.google.appinventor.components.runtime.Form; import com.google.appinventor.components.runtime.errors.YailRuntimeError; -import com.google.appinventor.components.runtime.util.YailList; import com.google.appinventor.components.runtime.util.YailDictionary; +import com.google.appinventor.components.runtime.util.YailList; import org.json.JSONArray; -import org.json.JSONException; import org.json.JSONObject; -import android.app.Activity; +import android.os.Handler; +import android.os.Looper; import android.view.View; import android.view.ViewGroup; +import gnu.lists.FString; +import gnu.math.DFloNum; +import gnu.math.IntNum; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; @@ -32,803 +36,556 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.Objects; +import java.util.List; import java.util.Set; import java.util.UUID; @DesignerComponent( - description = "Dynamic Components is an extension that creates any component in your App Inventor distribution programmatically, instead of having pre-defined components. Made with ❤️ by Yusuf Cihan", + description = "Dynamic Components is an extension that creates any component in your App Inventor distribution programmatically, instead of having pre-defined components. Made with ❤️ by Yusuf Cihan.", category = ComponentCategory.EXTENSION, - helpUrl = "https://github.com/ysfchn/DynamicComponents-AI2", + helpUrl = "https://github.com/ysfchn/DynamicComponents-AI2/blob/main/README.md", iconName = "aiwebres/icon.png", nonVisible = true, - version = 6, - versionName = "2.1.0" + version = 7, + versionName = "2.2.0" ) @SimpleObject(external = true) public class DynamicComponents extends AndroidNonvisibleComponent { - private Activity activity; - private Internal internal = null; - private boolean isAsync = false; - - /** - * Contains the created components. Key is the ID of the components, and their values are the components - * that created with Create block. - */ - private final HashMap COMPONENTS = new HashMap<>(); - - /** - * Specifies the base package for creating the components. - */ - private final String BASE_PACKAGE = "com.google.appinventor.components.runtime"; - - /** - * Stores the component template. Needs to be cleared before rendering Schema operation. - */ - private JSONArray PROPERTIESARRAY = new JSONArray(); + // Base package name for components + private final String BASE = "com.google.appinventor.components.runtime."; + + // Whether component creation should happen on the UI thread + private boolean postOnUiThread = false; + + // Components created with Dynamic Components + private final HashMap COMPONENTS = new HashMap(); + + // IDs of components created with Dynamic Components + private final HashMap COMPONENT_IDS = new HashMap(); + + private Object lastUsedId = ""; + private ArrayList componentListeners = new ArrayList(); + private JSONArray propertiesArray = new JSONArray(); + private final Util UTIL_INSTANCE = new Util(); public DynamicComponents(ComponentContainer container) { super(container.$form()); - this.activity = container.$context(); - this.internal = new Internal(); } - /** - * Raises after a schema has created with the "Schema" block. - * - * @param name Name of the template. - * @param parameters The JSON parameters in the schema. - */ - @SimpleEvent(description = "Raises after a schema has created with the \"Schema\" block.") - public void SchemaCreated(String name, YailList parameters) { - EventDispatcher.dispatchEvent(this, "SchemaCreated", name, parameters); - } - - /** - * Raises after a component has been created using the Create block. - * - * @param id The ID of the created component. - * @param type Type type name of the created component. - */ - @SimpleEvent(description = "Raises after a component has been created using the Create block. It also will be raised for components that created with Schema.") - public void ComponentCreated(String id, String type) { - EventDispatcher.dispatchEvent(this, "ComponentCreated", id, type); + interface ComponentListener { + public void onCreation(Component component, String id); } - @DesignerProperty(defaultValue = "False", editorType = PropertyTypeConstants.PROPERTY_TYPE_BOOLEAN) - @SimpleProperty(description = "Sets whether component creation should rely on the UI thread.") - public void Async(boolean async) { - isAsync = async; - } - - @SimpleProperty(category = PropertyCategory.BEHAVIOR, description = "Gets whether component creation should rely on the UI thread.") - public boolean Async() { - return isAsync; - } - - /** - * Creates a new dynamic component. It supports all component that added to your - * current AI2 distribution. In componentName, you can type the component's name - * like "Button", or you can pass a static component then it can create a new - * instance of it. - * - * @param in Layout/Component where the created component will be placed. - * @param componentName Name/FQCN of the component that will be created. - * @param id A unique identifier for this component. - */ - @SimpleFunction(description = "Creates a new dynamic component. It supports all component that added to your current AI2 distribution. In componentName, you can type the component's name like 'Button', or you can pass a static component then it can create a new instance of it, or just type the full class name of component.") - public void Create(final AndroidViewComponent in, final Object componentName, final String id) { - if (isAsync) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - CreateMethod(in, componentName, id); - } - }); - } else { - CreateMethod(in, componentName, id); + class Util { + public boolean exists(Component component) { + return COMPONENTS.containsValue(component); } - } - public void CreateMethod(final AndroidViewComponent in, final Object componentName, final String id) { - String className = internal.checkId(componentName, id); + public boolean exists(String id) { + return COMPONENTS.containsKey(id); + } - try { - if (!"".equals(className)) { - // Create a Class object from class name. - Class classObject = Class.forName(className.trim().replace(" ", "")); + public Method getMethod(Method[] methods, String name, int parameterCount) { + name = name.replaceAll("[^a-zA-Z0-9]", ""); + for (Method method : methods) { + int methodParameterCount = method.getParameterTypes().length; + if (method.getName().equals(name) && methodParameterCount == parameterCount) { + return method; + } + } - // Create constructor object for creating a new instance. - Constructor constructor = classObject.getConstructor(ComponentContainer.class); + return null; + } - // Create a new instance of specified component. - Component component = (Component) constructor.newInstance((ComponentContainer) in); + public void newInstance(Constructor constructor, String id, AndroidViewComponent input) { + Component mComponent = null; - if (className.contains("ImageSprite") || className.contains("Sprite")) { - Invoke(component, "Initialize", new YailList()); + try { + mComponent = (Component) constructor.newInstance((ComponentContainer) input); + } catch(Exception e) { + throw new YailRuntimeError(e.getMessage(), "DynamicComponents"); + } finally { + if (mComponent != null) { + String mComponentClassName = mComponent.getClass().getSimpleName(); + if (mComponentClassName == "ImageSprite" || mComponentClassName == "Sprite") { + Invoke(mComponent, "Initialize", new YailList()); + } + + COMPONENT_IDS.put(mComponent, id); + COMPONENTS.put(id, mComponent); + this.notifyListenersOfCreation(mComponent, id); + ComponentBuilt(mComponent, id, mComponentClassName); } - - // Save the component. - COMPONENTS.put(id, component); - - // Finalize component creation. - ComponentCreated(id, classObject.getSimpleName()); } - } catch (Exception exception) { - throw new YailRuntimeError("DynamicComponents-AI2: " + exception.toString(), "Error"); } - } - - public void SchemaMethod(final AndroidViewComponent in, final YailList parameters, final String template) { - try { - // Remove the contents of the array by creating a new JSONArray. - PROPERTIESARRAY = new JSONArray(); - // Create a JSONObject from template for checking. - JSONObject j = new JSONObject(template); - // Save the template string to a new variable for editing. - String modifiedTemplate = internal.replaceKeys(j, parameters, template); - // Lastly parse the JSONObject. - internal.parseJson("", new JSONObject(modifiedTemplate)); - // Delete the first element, because it contains metadata instead of components. - PROPERTIESARRAY.remove(0); - - // Start creating the extensions (finally). - for (int i = 0; i < PROPERTIESARRAY.length(); i++) { - // Check if component has an ID key. - if (!PROPERTIESARRAY.getJSONObject(i).has("id")) { - throw new YailRuntimeError("One or more of the components has not an ID in template!", "Error"); - } - internal.createBySchema(in, i, PROPERTIESARRAY); + public void parse(String id, JSONObject json) { + JSONObject data = new JSONObject(json.toString()); + data.remove("components"); - // If JSONObject contains a "properties" section, then set its properties with - // Invoke block. - if (PROPERTIESARRAY.getJSONObject(i).has("properties")) { - internal.setPropertiesBySchema(i, PROPERTIESARRAY); - } + if (!"".equals(id)) { + data.put("in", id); } - SchemaCreated(j.optString("name"), parameters); - } catch (Exception e) { - throw new YailRuntimeError(e.getMessage(), "Error"); - } - } + propertiesArray.put(data); - /** - * Imports a JSON string that is a template for creating the dynamic components - * automatically with single block. Templates can also contain parameters that - * will be replaced with the values which defined in the "parameters" list. - * - * @param in Layout/Component where the created component will be placed. - * @param template A JSON string containing information for creating the component. - * @param parameters Data for parameters defined in the above JSON string. - */ - @SimpleFunction(description = "Imports a JSON string that is a template for creating the dynamic components automatically with single block. Templates can also contain parameters that will be replaced with the values which defined in the 'parameters' list.") - public void Schema(final AndroidViewComponent in, final String template, final YailList parameters) { - if (isAsync) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - SchemaMethod(in, parameters, template); + if (json.has("components")) { + for (int i = 0; i < json.getJSONArray("components").length(); i++) { + this.parse(data.optString("id", ""), json.getJSONArray("components").getJSONObject(i)); } - }); - } else { - SchemaMethod(in, parameters, template); + } } - } - /** - * Replaces the specified ID with the given new ID. The old ID must be bound to - * a component and the new ID must be unique, i.e., not used already. - * - * @param id Existing ID of the specified component. - * @param newId The ID to replace existing one with. - */ - @SimpleFunction(description = "Replaces the specified ID with the given new ID. The old ID must be bound to a component and the new ID must be unique, i.e., not used already.") - public void ChangeId(String id, String newId) { - if (COMPONENTS.containsKey(id) && !COMPONENTS.containsKey(newId)) { - Component component = COMPONENTS.remove(id); - COMPONENTS.put(newId, component); - } else { - throw new YailRuntimeError("Old ID must exist and new ID mustn't exist.", "Error"); + public void notifyListenersOfCreation(Component component, String id) { + for (ComponentListener listener : componentListeners) { + listener.onCreation(component, id); + } } } - /** - * Moves the specified component to the given arrangement. - * - * @param arrangement Target arrangement in which the specified component should be transferred. - * @param component Component that needs to be transferred. - */ - @SimpleFunction(description = "Moves the specified component to the given arrangement.") - public void Move(AndroidViewComponent arrangement, AndroidViewComponent component) { - View comp = component.getView(); - ViewGroup source = (ViewGroup)comp.getParent(); - source.removeView(comp); - - ViewGroup vg2 = (ViewGroup)arrangement.getView(); - ViewGroup target = (ViewGroup)vg2.getChildAt(0); - - target.addView(comp); - } - - /** - * Returns the position of the component with respect to other sibling components - * in it's parent arrangement. Index starts from 1. - * - * @param component Target component. - * @return Position index of the specified component in the parent arrangement. - */ - @SimpleFunction(description = "Returns the position of the component with respect to other sibling components in it's parent arrangement. Index starts from 1.") - public int GetOrder(AndroidViewComponent component){ - View comp = component.getView(); - View parent = (View) component.getView().getParent(); - - if (comp != null && parent != null) { - View v = component.getView(); - ViewGroup vg = (ViewGroup)v.getParent(); - int index = vg.indexOfChild(v); - return index + 1; - } else { - return 0; - } + @DesignerProperty( + defaultValue = "UI", + editorArgs = {"Main", "UI"}, + editorType = PropertyTypeConstants.PROPERTY_TYPE_CHOICES + ) + @SimpleProperty(userVisible = false) + public void Thread(String thread) { + postOnUiThread = (thread == "UI"); + } + + @Deprecated + @SimpleEvent(description = "Do NOT use this event. Use 'ComponentBuilt' as a replacement.") + public void ComponentCreated(String id, String type) { + EventDispatcher.dispatchEvent(this, "ComponentCreated", id, type); } - /** - * Sets the position of the specified component with respect to other sibling - * components in it's parent arrangement. Index starts from 1. Typing 0 (zero) - * will move the component to the end. - * - * @param component Target component. - * @param index Index at which the component should be placed in it's parent component. - */ - @SimpleFunction(description = "Sets the position of the specified component with respect to other sibling components in it's parent arrangement. Index starts from 1. Typing 0 (zero) will move the component to the end.") - public void SetOrder(AndroidViewComponent component, int index) { - View comp = component.getView(); - ViewGroup source = (ViewGroup)comp.getParent(); - source.removeView(comp); - - int i = index - 1; - int childCount = source.getChildCount(); - - if (i > childCount) { - i = childCount; - } - - source.addView(comp, i); + @SimpleEvent(description = "Is called after a component has been created.") + public void ComponentBuilt(Component component, String id, String type) { + EventDispatcher.dispatchEvent(this, "ComponentBuilt", component, id, type); } - /** - * Removes the component with specified ID from screen/layout and the component - * list. So you will able to use its ID again as it will be deleted. - * - * @param id The ID of the component that is supposed to be removed. - */ - @SimpleFunction(description = "Removes the component with specified ID from screen/layout and the component list so you can use its ID again after it's deleted.") - public void Remove(String id) { - if (internal.isIdTaken(id)) { - Object component = COMPONENTS.get(id); + @SimpleEvent(description = "Is called after a schema has/mostly finished component creation.") + public void SchemaCreated(String name, YailList parameters) { + EventDispatcher.dispatchEvent(this, "SchemaCreated", name, parameters); + } - try { - if (component != null) { - Method method = component.getClass().getMethod("getView"); - View componentView = (View) method.invoke(component); - ViewGroup parent = (ViewGroup) componentView.getParent(); - parent.removeView(componentView); + @SimpleFunction(description = "Assign a new ID to a previously created dynamic component.") + public void ChangeId(String id, String newId) { + if (UTIL_INSTANCE.exists(id) && !UTIL_INSTANCE.exists(newId)) { + for (String mId : UsedIDs().toStringArray()) { + if (mId.contains(id)) { + Component mComponent = (Component) GetComponent(mId); + String mReplacementId = mId.replace(id, newId); + COMPONENT_IDS.remove(mComponent); + COMPONENTS.put(mReplacementId, COMPONENTS.remove(mId)); + COMPONENT_IDS.put(mComponent, mReplacementId); } - } catch (Exception e) { - e.printStackTrace(); } - - COMPONENTS.remove(id); + } else { + throw new YailRuntimeError("The ID you used is either not a dynamic component, or the ID you've used to replace the old ID is already taken.", "DynamicComponents"); } } - /** - * Returns the ID of the last component created using the "Create" block. - * - * @return The last used ID. - */ - @SimpleFunction(description = "Returns the ID of the last component created using the \"Create\" block.") - public String LastUsedID() { - Object[] COMPONENT_IDS = COMPONENTS.keySet().toArray(); - return (COMPONENT_IDS.length > 0 ? COMPONENT_IDS[COMPONENT_IDS.length - 1].toString() : ""); + @SimpleFunction(description = "Creates a new dynamic component.") + public void Create(final AndroidViewComponent in, Object componentName, final String id) throws Exception { + componentName = componentName.toString().replaceAll("[^a-zA-Z0-9]", ""); + if (!COMPONENTS.containsKey(id)) { + lastUsedId = id; + + String mClassName = BASE + componentName; + Class mClass = Class.forName(mClassName); + final Constructor mConstructor = mClass.getConstructor(ComponentContainer.class); + + if (postOnUiThread) { + new Handler(Looper.getMainLooper()).post(new Runnable() { + @Override + public void run() { + UTIL_INSTANCE.newInstance(mConstructor, id, in); + } + }); + } else { + UTIL_INSTANCE.newInstance(mConstructor, id, in); + } + + ComponentCreated(id.toString(), mClass.getSimpleName()); + } else { + throw new YailRuntimeError("ID must be unique.", "DynamicComponents"); + } } - /** - * Returns a random UUID. - * - * @return A random UUID. - */ - @SimpleFunction(description = "Generates a unique ID that can be used to create a component.") - public String RandomUUID() { - String uuid = ""; + @SimpleFunction(description = "Generates a random ID to create a component with.") + public String GenerateID() { + String id = ""; do { - uuid = UUID.randomUUID().toString(); - } while (internal.isIdTaken(uuid)); + id = UUID.randomUUID().toString(); + } while (UTIL_INSTANCE.exists(id)); - return uuid; + return id; } - /** - * Returns a list of IDs of every created component. - * - * @return A list of IDs. - */ - @SimpleFunction(description = "Returns a list of IDs of every created component.") - public YailList UsedIDs() { - Set keys = COMPONENTS.keySet(); - return YailList.makeList(keys); - } - - /** - * Returns the component itself for setting properties. ID must be a valid ID - * which is added with Create block. ID --> Component - * - * @param id ID of the desired component. - * @return A component bound to the given ID. - */ - @SimpleFunction(description = "Returns the component itself for setting properties. ID must be a valid ID which is added with Create block.") + @SimpleFunction(description = "Returns the component associated with the specified ID.") public Object GetComponent(String id) { return COMPONENTS.get(id); } - /** - * Returns "true" if the specified component is created by Dynamic Components - * extension. Otherwise, "false". - * - * @param component Component that needs to be analysed. - * @return A boolean value indicating whether the specified component is dynamically created or not. - */ - @SimpleFunction(description = "Returns 'true' if component was created by the Dynamic Components extension. Otherwise, 'false'.") - public Object IsDynamic(Component component) { - return internal.isDynamicComponent(component); - } - - /** - * Returns the ID of the specified component. The desired component must created using the "Create" block, else it will return a blank string. Component --> ID - * - * @param component The component that its ID will be returned. - * @return ID of the specified component. - */ - @SimpleFunction(description = "Returns the ID of the specified component. The desired component must created using the \"Create\" block, else it will return a blank string. Component --> ID") - public String GetId(Component component) { - // Getting key from value, - for (String o : COMPONENTS.keySet()) { - if (COMPONENTS.get(o).equals(component)) { - return o; - } + @SimpleFunction(description = "Get meta data about the specified component.") + public YailDictionary GetComponentMeta(Component component) { + Class mClass = component.getClass(); + DesignerComponent mDesignerAnnotation = mClass.getAnnotation(DesignerComponent.class); + SimpleObject mObjectAnnotation = mClass.getAnnotation(SimpleObject.class); + YailDictionary mMeta = new YailDictionary(); + + if (mDesignerAnnotation != null) { + mMeta.put("androidMinSdk", mDesignerAnnotation.androidMinSdk()); + mMeta.put("category", mDesignerAnnotation.category()); + mMeta.put("dateBuilt", mDesignerAnnotation.dateBuilt()); + mMeta.put("description", mDesignerAnnotation.description()); + mMeta.put("designerHelpDescription", mDesignerAnnotation.designerHelpDescription()); + mMeta.put("external", mObjectAnnotation.external()); + mMeta.put("helpUrl", mDesignerAnnotation.helpUrl()); + mMeta.put("iconName", mDesignerAnnotation.iconName()); + mMeta.put("nonVisible", mDesignerAnnotation.nonVisible()); + mMeta.put("package", mClass.getName()); + mMeta.put("showOnPalette", mDesignerAnnotation.showOnPalette()); + mMeta.put("type", mClass.getSimpleName()); + mMeta.put("version", mDesignerAnnotation.version()); + mMeta.put("versionName", mDesignerAnnotation.versionName()); } - return ""; + return mMeta; } - /** - * Returns the internal name of any component or object. - * - * @param component The component that its internal name needs to be returned. - * @return Internal name of the specified component. - */ - @SimpleFunction(description = "Returns the internal name of any component or object.") - public String GetName(Object component) { - return internal.getClass(component).getName(); - } - - /** - * Sets the specified property of the component to the given value. It can be also - * used to set properties that only exists in Designer. Supported values are: - * "string", "boolean", "integer" and "float". For other values, you should use - * "Any Component" blocks. - * - * @param component The component that property will set for. - * @param name The name of the property that needs to be set. - * @param value The value that needs to be set of the specified property. - */ - @SimpleFunction(description = "Sets the specified property of the component to the given value. It can be also used to set properties that only exists in Designer. Supported values are; 'string', 'boolean', 'integer' and 'float'. For other values, you should use Any Component blocks.") - public void SetProperty(Component component, String name, Object value) { - // The method will be invoked. - try { - Invoke(component, name, YailList.makeList(new Object[] { value })); - } catch (Exception exception) { - throw new YailRuntimeError(exception.getMessage(), "Error"); - } - } - - /** - * Set multiple properties of a component by typing its property name and value. - * It behaves like a Setter property block. It can be also used to set properties - * that only exists in Designer. Supported values are; "string", "boolean", - * "integer" and "float". For other values, you should use Any Component blocks. - * - * @param component The component that property will set for. - * @param properties Properties and their respective values as a dictionary. - * @throws JSONException Creating new instance of JSONObject throws this exception. - */ - @SimpleFunction(description = "Set multiple properties of a component at once.") - public void SetProperties(Component component, YailDictionary properties) throws JSONException { - JSONObject propertyObject = new JSONObject(properties.toString()); - JSONArray names = propertyObject.names(); - - for (int i = 0; i < propertyObject.length(); i++) { - String name = names.getString(i); - Object value = propertyObject.get(name); - Invoke(component, name, YailList.makeList(new Object[] { value })); + @SimpleFunction(description = "Get meta data about events for the specified component.") + public YailDictionary GetEventMeta(Component component) { + Method[] mMethods = component.getClass().getMethods(); + YailDictionary mEvents = new YailDictionary(); + + for (Method mMethod : mMethods) { + SimpleEvent mAnnotation = mMethod.getAnnotation(SimpleEvent.class); + String mName = mMethod.getName(); + YailDictionary mEventMeta = new YailDictionary(); + + if (mAnnotation != null) { + mEventMeta.put("description", mAnnotation.description()); + mEventMeta.put("isDeprecated", (mMethod.getAnnotation(Deprecated.class) != null)); + mEventMeta.put("userVisible", mAnnotation.userVisible()); + mEvents.put(mName, mEventMeta); + } } - } - /** - * Returns the specified properties value of the given component. Can be known - * as a Getter property block. It can be also used to get properties that only - * exists in Designer. - * - * @param component The component that property will get from. - * @param name Name of the desired property. - * @return Value of the specified property of the specified component. - */ - @SimpleFunction(description = "Returns the specified properties value of the given component. Can be known as a Getter property block. It can be also used to get properties that only exists in Designer.") - public Object GetProperty(Component component, String name) { - // The method will be invoked. - try { - return Invoke(component, name, YailList.makeEmptyList()); - } catch (Exception exception) { - // Throw an error when something goes wrong. - throw new YailRuntimeError("" + exception, "Error"); - } + return mEvents; } - /** - * Invokes the specified method of the specified component. - * - * @param component The component that method will be executed for. - * @param name Name of the method that needs to be invoked. - * @param parameters Parameters to pass to the specified method. - * @return Return value of the invoked method. - */ - @SimpleFunction(description = "Invokes a method with parameters.") - public Object Invoke(Component component, String name, YailList parameters) { - // The method will be invoked. - name = name.trim().replace(" ", ""); - - try { - if (component == null) { - throw new YailRuntimeError("Component is not specified.", "Error"); + @SimpleFunction(description = "Get meta data about functions for the specified component.") + public YailDictionary GetFunctionMeta(Component component) { + Method[] mMethods = component.getClass().getMethods(); + YailDictionary mFunctions = new YailDictionary(); + + for (Method mMethod : mMethods) { + SimpleFunction mAnnotation = mMethod.getAnnotation(SimpleFunction.class); + String mName = mMethod.getName(); + YailDictionary mFunctionMeta = new YailDictionary(); + + if (mAnnotation != null) { + mFunctionMeta.put("description", mAnnotation.description()); + mFunctionMeta.put("isDeprecated", (mMethod.getAnnotation(Deprecated.class) != null)); + mFunctionMeta.put("userVisible", mAnnotation.userVisible()); + mFunctions.put(mName, mFunctionMeta); } + } - Method method = internal.findMethod(internal.getClass(component).getMethods(), name.replace(" ", ""), parameters.toArray().length); + return mFunctions; + } - if (method == null) { - throw new YailRuntimeError("Method can't found with that name.", "Error"); - } + @SimpleFunction(description = "Returns the ID of the specified component.") + public String GetId(Component component) { + if (component != null || COMPONENT_IDS.containsKey(component)) { + return COMPONENT_IDS.get(component); + } - Object[] typed_params = parameters.toArray(); - Class[] requested_params = method.getParameterTypes(); - ArrayList params = new ArrayList<>(); - for (int i = 0; i < requested_params.length; i++) { - if ("int".equals(requested_params[i].getName())) { - // Integer - params.add(Integer.parseInt(typed_params[i].toString())); - } else if ("float".equals(requested_params[i].getName())) { - // Float - params.add(Float.parseFloat(typed_params[i].toString())); - } else if ("double".equals(requested_params[i].getName())) { - // Double - params.add(Double.parseDouble(typed_params[i].toString())); - } else if ("java.lang.String".equals(requested_params[i].getName())) { - // String - params.add(typed_params[i].toString()); - } else if ("boolean".equals(requested_params[i].getName())) { - // Boolean - params.add(Boolean.parseBoolean(typed_params[i].toString())); - } else { - params.add(typed_params[i]); - } - } + return ""; + } - Object m = method.invoke(component, params.toArray()); - if (m == null) { - return ""; - } else { - return m; - } - } catch (Exception exception) { - throw new YailRuntimeError(exception.toString(), "Error"); - } + @Deprecated + @SimpleFunction(description = "Do NOT use this function. Use 'GetComponentMeta' as a replacement.") + public String GetName(Component component) { + return component.getClass().getName(); } - /** - * Returns a JSON string with the information of the specified component containing - * all of it's properties, events and methods. - * - * @param component The component that information will be returned for. - * @return Information of the specified component. - * @throws JSONException Thrown by "put()" method from the JSONObject class. - */ - @SimpleFunction(description = "Gives the information of the specified component with all properties, events, methods as JSON text.") - public String ListDetails(Component component) { - Class componentClass = internal.getClass(component); - DesignerComponent designerComponentAnnotation = internal.getAnnotation(DesignerComponent.class, component, null); - JSONObject specifications = new JSONObject(); - - try { - // Alphabetical order - specifications.put("androidMinSdk", designerComponentAnnotation.androidMinSdk()); - specifications.put("category", designerComponentAnnotation.category()); - specifications.put("dateBuilt", designerComponentAnnotation.dateBuilt()); - specifications.put("description", designerComponentAnnotation.description()); - specifications.put("helpUrl", designerComponentAnnotation.helpUrl()); - specifications.put("iconName", designerComponentAnnotation.iconName()); - specifications.put("name", componentClass.getSimpleName()); - specifications.put("nonVisible", designerComponentAnnotation.nonVisible()); - specifications.put("showOnPalette", designerComponentAnnotation.showOnPalette()); - specifications.put("type", componentClass.getName()); - specifications.put("version", designerComponentAnnotation.version()); - specifications.put("versionName", designerComponentAnnotation.versionName()); - } catch(JSONException e) { - e.printStackTrace(); - } + @SimpleFunction(description = "Returns the position of the specified component according to its parent view. Index begins at one.") + public int GetOrder(AndroidViewComponent component) { + View mComponent = (View) component.getView(); + int mIndex = 0; + ViewGroup mParent = (mComponent != null ? (ViewGroup) mComponent.getParent() : null); - Method[] allMethods = componentClass.getMethods(); - JSONArray blockProperties = new JSONArray(); - JSONArray events = new JSONArray(); - JSONArray methods = new JSONArray(); - JSONArray properties = new JSONArray(); - - // Get the component's class and return all methods from it. - // Search for methods. - for (Method mMethod : allMethods) { - JSONObject data = new JSONObject(); - - DesignerProperty designerPropertyAnnotation = internal.getAnnotation(DesignerProperty.class, null, mMethod); - SimpleEvent simpleEventAnnotation = internal.getAnnotation(SimpleEvent.class, null, mMethod); - SimpleFunction simpleFunctionAnnotation = internal.getAnnotation(SimpleFunction.class, null, mMethod); - SimpleProperty simplePropertyAnnotation = internal.getAnnotation(SimpleProperty.class, null, mMethod); - - internal.putInJsonObject(data, "name", mMethod.getName()); - - if (internal.methodHasAnnotation(DesignerProperty.class, mMethod)) { - internal.putInJsonObject(data, "editorType", designerPropertyAnnotation.editorType()); - internal.putInJsonObject(data, "defaultValue", designerPropertyAnnotation.defaultValue()); - internal.putInJsonObject(data, "editorArgs", new JSONArray(Arrays.asList(designerPropertyAnnotation.editorArgs()))); - internal.putInJsonArray(properties, data); - } - - if (internal.methodHasAnnotation(SimpleEvent.class, mMethod)) { - internal.putInJsonObject(data, "description", simpleEventAnnotation.description()); - internal.putInJsonObject(data, "visible", simpleEventAnnotation.userVisible()); + if (mComponent != null && mParent != null) { + mIndex = mParent.indexOfChild(mComponent) + 1; + } - JSONArray params = new JSONArray(); - for (Class param : mMethod.getParameterTypes()) { - internal.putInJsonArray(params, param.getName()); - } + return mIndex; + } - internal.putInJsonObject(data, "parameterTypes", params); - // Missing: "deprecated" - // Missing: "params" - } + @SimpleFunction(description = "Get a properties value.") + public Object GetProperty(Component component, String name) { + return Invoke(component, name, YailList.makeEmptyList()); + } - if (internal.methodHasAnnotation(SimpleFunction.class, mMethod)) { - internal.putInJsonObject(data, "description", simpleFunctionAnnotation.description()); - internal.putInJsonObject(data, "visible", simpleFunctionAnnotation.userVisible()); - internal.putInJsonObject(data, "returnType", mMethod.getReturnType().getSimpleName()); - - JSONArray params = new JSONArray(); - for (Class param : mMethod.getParameterTypes()) { - internal.putInJsonArray(params, param.getName()); + @SimpleFunction(description = "Get meta data about properties for the specified component, including their values.") + public YailDictionary GetPropertyMeta(Component component) { + Method[] mMethods = component.getClass().getMethods(); + YailDictionary mProperties = new YailDictionary(); + + for (Method mMethod : mMethods) { + DesignerProperty mDesignerAnnotation = mMethod.getAnnotation(DesignerProperty.class); + SimpleProperty mPropertyAnnotation = mMethod.getAnnotation(SimpleProperty.class); + String mName = mMethod.getName(); + YailDictionary mPropertyMeta = new YailDictionary(); + Object mValue = Invoke(component, mName, new YailList());; + + if (mPropertyAnnotation != null) { + mPropertyMeta.put("description", mPropertyAnnotation.description()); + mPropertyMeta.put("category", mPropertyAnnotation.category()); + + if (mDesignerAnnotation != null) { + YailDictionary mDesignerMeta = new YailDictionary(); + mDesignerMeta.put("defaultValue", mDesignerAnnotation.defaultValue()); + mDesignerMeta.put("editorArgs", mDesignerAnnotation.editorArgs()); + mDesignerMeta.put("editorType", mDesignerAnnotation.editorType()); + mPropertyMeta.put("designer", mDesignerMeta); } - internal.putInJsonObject(data, "parameterTypes", params); - // Missing: "deprecated" - // Missing: "params" + mPropertyMeta.put("isDeprecated", (mMethod.getAnnotation(Deprecated.class) != null)); + mPropertyMeta.put("isDesignerProperty", (mDesignerAnnotation != null)); + mPropertyMeta.put("userVisible", mPropertyAnnotation.userVisible()); + mPropertyMeta.put("value", mValue); + mProperties.put(mName, mPropertyMeta); } + } - if (internal.methodHasAnnotation(SimpleProperty.class, mMethod)) { - internal.putInJsonObject(data, "category", simplePropertyAnnotation.category()); - internal.putInJsonObject(data, "description", simplePropertyAnnotation.description()); - internal.putInJsonObject(data, "visible", simplePropertyAnnotation.userVisible()); - - String rw = "read-write"; + return mProperties; + } - boolean setter = internal.findMethod(allMethods, mMethod.getName(), 1) != null; - boolean getter = internal.findMethod(allMethods, mMethod.getName(), 0) != null; + @SimpleFunction(description = "Invokes a method with parameters.") + public Object Invoke(Component component, String name, YailList parameters) { + if (component != null) { + Object mInvokedMethod = null; + Method[] mMethods = component.getClass().getMethods(); - if (getter && !setter) { - rw = "read-only"; - internal.putInJsonObject(data, "type", Objects.requireNonNull(internal.findMethod(allMethods, mMethod.getName(), 0)).getReturnType().getSimpleName()); - } else { - rw = (setter && !getter ? "write-only" : "read-write"); - internal.putInJsonObject(data, "type", Objects.requireNonNull(internal.findMethod(allMethods, mMethod.getName(), 1)).getParameterTypes()[0].getSimpleName()); + try { + Object[] mParameters = parameters.toArray(); + Method mMethod = UTIL_INSTANCE.getMethod(mMethods, name, mParameters.length); + + Class[] mRequestedMethodParameters = mMethod.getParameterTypes(); + ArrayList mParametersArrayList = new ArrayList(); + for (int i = 0; i < mRequestedMethodParameters.length; i++) { + if ("int".equals(mRequestedMethodParameters[i].getName())) { + mParametersArrayList.add(Integer.parseInt(mParameters[i].toString())); + } else if ("float".equals(mRequestedMethodParameters[i].getName())) { + mParametersArrayList.add(Float.parseFloat(mParameters[i].toString())); + } else if ("double".equals(mRequestedMethodParameters[i].getName())) { + mParametersArrayList.add(Double.parseDouble(mParameters[i].toString())); + } else if ("java.lang.String".equals(mRequestedMethodParameters[i].getName())) { + mParametersArrayList.add(mParameters[i].toString()); + } else if ("boolean".equals(mRequestedMethodParameters[i].getName())) { + mParametersArrayList.add(Boolean.parseBoolean(mParameters[i].toString())); + } else { + mParametersArrayList.add(mParameters[i]); + } } - boolean isDeprecated = simplePropertyAnnotation.category() == PropertyCategory.DEPRECATED; - internal.putInJsonObject(data, "rw", rw); - internal.putInJsonObject(data, "deprecated", isDeprecated); - - if (simplePropertyAnnotation.category() != PropertyCategory.UNSET) { - internal.putInJsonArray(blockProperties, data); + mInvokedMethod = mMethod.invoke(component, mParametersArrayList.toArray()); + } catch (Exception e) { + throw new YailRuntimeError(e.getMessage(), "DynamicComponents"); + } finally { + if (mInvokedMethod != null) { + return mInvokedMethod; + } else { + return ""; } } + } else { + throw new YailRuntimeError("Component cannot be null.", "DynamicComponents"); } - - internal.putInJsonObject(specifications, "blockProperties", blockProperties); - internal.putInJsonObject(specifications, "events", events); - internal.putInJsonObject(specifications, "methods", methods); - internal.putInJsonObject(specifications, "properties", properties); - - return specifications.toString(); } - /** - * Returns the version number of the extension. - * - * @return Version number of the extension. - */ - @SimpleProperty(description = "Returns the version number of the extension.") - public int Version() { - return DynamicComponents.class.getAnnotation(DesignerComponent.class).version(); + @SimpleFunction(description = "Returns if the specified component was created by the Dynamic Components extension.") + public boolean IsDynamic(Component component) { + return COMPONENTS.containsValue(component); } - /** - * Returns the version name of the extension. - * - * @return Version name of the extension. - */ - @SimpleProperty(description = "Returns the extension version name.") - public String VersionName() { - return DynamicComponents.class.getAnnotation(DesignerComponent.class).versionName(); + @SimpleFunction(description = "Returns the last used ID.") + public Object LastUsedID() { + return lastUsedId; } - protected class Internal { - public Internal() {} + @Deprecated + @SimpleFunction(description = "Do NOT use this function. Use 'GetComponentMeta', 'GetEventMeta', 'GetFunctionMeta', and 'GetPropertyMeta' as replacements.") + public String ListDetails(Component component) { + return ""; + } - public String checkId(Object componentName, String id) { - // Check if ID is used by another Dynamic Component - if (id == null || id.trim().isEmpty()) { - throw new YailRuntimeError("DynamicComponents-AI2: ID can't be blank.", "Invalid ID"); - } else { - if (internal.isIdTaken(id)) { - throw new YailRuntimeError("DynamicComponents-AI2: ID must be unique for all components.", "Duplicate ID"); - } - } + @SimpleFunction(description = "Moves the specified component to the specified view.") + public void Move(AndroidViewComponent arrangement, AndroidViewComponent component) { + View mComponent = (View) component.getView(); + ViewGroup mParent = (mComponent != null ? (ViewGroup) mComponent.getParent() : null); - return internal.getClassName(componentName); - } + mParent.removeView(mComponent); - public void createBySchema(AndroidViewComponent in, int i, JSONArray properties) { - if (!properties.getJSONObject(i).has("in")) { - // If a component JSONObject doesn't contain an "in" key then insert it in the main // component that specified as this method's "in" parameter. - Create(in, properties.getJSONObject(i).getString("type"), properties.getJSONObject(i).getString("id")); - } else { - // Else, insert it in the another component that is specified with an ID. - Create((AndroidViewComponent) GetComponent(properties.getJSONObject(i).getString("in")), properties.getJSONObject(i).getString("type"), properties.getJSONObject(i).getString("id")); - } - } + ViewGroup mArrangement = (ViewGroup) arrangement.getView(); + ViewGroup mTarget = (ViewGroup) mArrangement.getChildAt(0); - public Method findMethod(Method[] methods, String name, Integer paramCount) { - for (Method method : methods) { - // Check for one parameter (setter) method. - if ((method.getName().equals(name.trim())) && (method.getParameterTypes().length == paramCount)) { - return method; - } - } + mTarget.addView(mComponent); + } - return null; - } + @Deprecated + @SimpleFunction(description = "Do NOT use this function. Use 'GenerateID' as a replacement.") + public String RandomUUID() { + return GenerateID(); + } - public Class getClass(Object instance) { - return instance.getClass(); - } + @SimpleFunction(description = "Removes the component with the specified ID from the layout/screen so the ID can be reused.") + public void Remove(String id) { + Object component = COMPONENTS.get(id); - public String getClassName(Object componentName) { - if ((componentName instanceof String) && componentName.toString().contains(".")) { - // Is the componentName a String with package name? - return componentName.toString().replace(" ", ""); - } else if (componentName instanceof String) { - // Is the componentName a String with no pacakge name? - return BASE_PACKAGE + "." + componentName.toString().replace(" ", ""); - } else if (componentName instanceof Component) { - // Is the componentName a Component instance? - return componentName.getClass().getName(); - } else { - // Throw an error if componentName is neither Component or String - throw new YailRuntimeError("DynamicComponents-AI2: Not a Component block or a String.", "Invalid Component"); + if (component != null) { + try { + Method mMethod = component.getClass().getMethod("getView"); + final View mComponent = (View) mMethod.invoke(component); + final ViewGroup mParent = (ViewGroup) mComponent.getParent(); + + if (postOnUiThread) { + new Handler(Looper.getMainLooper()).post(new Runnable() { + @Override + public void run() { + mParent.removeView(mComponent); + } + }); + } else { + mParent.removeView(mComponent); + } + } catch (Exception e) { + e.printStackTrace(); } + + COMPONENTS.remove(id); + COMPONENT_IDS.remove(component); } + } - public T getAnnotation(Class mClass, Component component, Method mMethod) { - if (component != null) { - return internal.getClass(component).getAnnotation(mClass); - } + @SimpleFunction(description = "Sets the order of the specified component according to its parent view. Typing zero will move the component to the end, index begins at one.") + public void SetOrder(AndroidViewComponent component, int index) { + index = index - 1; + View mComponent = (View) component.getView(); + ViewGroup mParent = (ViewGroup) mComponent.getParent(); - return mMethod.getAnnotation(mClass); - } + mParent.removeView(mComponent); - public boolean methodHasAnnotation(Class mClass, Method mMethod) { - return mMethod.isAnnotationPresent(mClass); - } + int mChildCount = mParent.getChildCount(); + int mIndex = (index > mChildCount ? mChildCount : index); - public boolean isDynamicComponent(Component component) { - return COMPONENTS.containsValue(component); - } + mParent.addView(mComponent, mIndex); + } - public boolean isIdTaken(String id) { - return COMPONENTS.containsKey(id); - } + @SimpleFunction(description = "Set a property of the specified component, including those only available from the Designer.") + public void SetProperty(Component component, String name, Object value) { + Invoke(component, name, YailList.makeList(new Object[] { + value + })); + } - public String loopReplace(JSONObject json, YailList parameters, String template) { - String modified = template; - - for (int i = 0; i < json.optJSONArray("keys").length(); i++) { - modified = modified.replace("{" + json.optJSONArray("keys").getString(i) + "}", parameters.getString(i).replace("\"", "")); - } + @SimpleFunction(description = "Set multiple properties of the specified component using a dictionary, including those only available from the Designer.") + public void SetProperties(Component component, YailDictionary properties) throws Exception { + JSONObject mProperties = new JSONObject(properties.toString()); + JSONArray mPropertyNames = mProperties.names(); - return modified; + for (int i = 0; i < mProperties.length(); i++) { + String name = mPropertyNames.getString(i); + Object value = mProperties.get(name); + Invoke(component, name, YailList.makeList(new Object[] { value })); } + } - public void parseJson(String id, JSONObject json) throws JSONException { - JSONObject data = new JSONObject(json.toString()); - String KEY = "components"; - - data.remove(KEY); + @SimpleFunction(description = "Uses a JSON Object to create dynamic components. Templates can also contain parameters that will be replaced with the values which are defined from the parameters list.") + public void Schema(AndroidViewComponent in, final String template, final YailList parameters) throws Exception { + JSONObject mScheme = new JSONObject(template); + String newTemplate = template; - if (!"".equals(id)) { - data.put("in", id); - } + if (!template.replace(" ", "").isEmpty() && mScheme.has("components")) { + propertiesArray = new JSONArray(); - PROPERTIESARRAY.put(data); + JSONArray mKeys = (mScheme.has("keys") ? mScheme.getJSONArray("keys") : null); - if (json.has(KEY)) { - for (int i = 0; i < json.getJSONArray(KEY).length(); i++) { - parseJson(data.optString("id", ""), json.getJSONArray(KEY).getJSONObject(i)); + if (mKeys != null && mKeys.length() == parameters.length() - 1) { + for (int i = 0; i < mKeys.length(); i++) { + String keyPercent = "%" + mKeys.getString(i); + String keyBracket = "{" + mKeys.getString(i) + "}"; + String value = parameters.getString(i).replace("\"", ""); + newTemplate = newTemplate.replace(keyPercent, value); + newTemplate = newTemplate.replace(keyBracket, value); } } - } - public void putInJsonArray(JSONArray json, Object value) { - try { - json.put(value); - } catch (JSONException e) { - e.printStackTrace(); - } - } + mScheme = new JSONObject(newTemplate); + UTIL_INSTANCE.parse("", mScheme); + propertiesArray.remove(0); - public void putInJsonObject(JSONObject json, String key, Object value) { - try { - json.put(key, value); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - public String replaceKeys(JSONObject json, YailList parameters, String template) { - String modified = template; - - // Check if JSON contains "keys". - if (json.has("keys")) { - // Throw a runtime error if parameter count is lower than required parameter count. - if (json.optJSONArray("keys").length() > parameters.length()) { - throw new YailRuntimeError("Input parameter count is lower than the requirement!", "Error"); - } else { - /* Replace the template keys with their values. - * For example; - * {0} --> "a value" */ - loopReplace(json, parameters, template); + for (int i = 0; i < propertiesArray.length(); i++) { + if (!propertiesArray.getJSONObject(i).has("id")) { + throw new YailRuntimeError("One or multiple components do not have a specified ID in the template.", "DynamicComponents"); } + + final JSONObject mJson = propertiesArray.getJSONObject(i); + final String mId = mJson.getString("id"); + AndroidViewComponent mRoot = (!mJson.has("in") ? in : (AndroidViewComponent) GetComponent(mJson.getString("in"))); + final String mType = mJson.getString("type"); + + ComponentListener listener = new ComponentListener() { + @Override + public void onCreation(Component component, String id) { + if (id == mId && mJson.has("properties")) { + JSONObject mProperties = mJson.getJSONObject("properties"); + JSONArray keys = mProperties.names(); + + for (int k = 0; k < keys.length(); k++) { + Invoke( + (Component) GetComponent(mId), + keys.getString(k), + YailList.makeList(new Object[] { + mProperties.get(keys.getString(k)) + }) + ); + } + + componentListeners.remove(this); + } + } + }; + + componentListeners.add(listener); + + Create(mRoot, mType, mId); } - return modified; + SchemaCreated(mScheme.getString("name"), parameters); + } else { + throw new YailRuntimeError("The template is empty, or is does not have any components.", "DynamicComponents"); } + } - public void setPropertiesBySchema(int i, JSONArray properties) { - JSONArray keys = properties.getJSONObject(i).getJSONObject("properties").names(); + @SimpleFunction(description = "Returns all IDs of components created with the Dynamic Components extension.") + public YailList UsedIDs() { + Set mKeys = COMPONENTS.keySet(); + return YailList.makeList(mKeys); + } - for (int k = 0; k < keys.length(); k++) { - Invoke( - (Component) GetComponent(properties.getJSONObject(i).getString("id")), - keys.getString(k), - YailList.makeList(new Object[] { properties.getJSONObject(i).getJSONObject("properties").get(keys.getString(k)) }) - ); - } - } + @SimpleProperty(description = "Returns the version of the Dynamic Components extension.") + public int Version() { + return DynamicComponents.class.getAnnotation(DesignerComponent.class).version(); + } + + @SimpleProperty(description = "Returns the version name of the Dynamic Components extension.") + public String VersionName() { + return DynamicComponents.class.getAnnotation(DesignerComponent.class).versionName(); } -} \ No newline at end of file +} diff --git a/src/com/yusufcihan/DynamicComponents/aiwebres/icon.png b/src/com/yusufcihan/DynamicComponents/aiwebres/icon.png index ddca7eaf6c5931ee5086b40fbcf52b40d675c615..1c688f65aadc7730f8e0bc65f85cb7325facbd6f 100644 GIT binary patch literal 2435 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 BnDhVu literal 780 zcmV+n1M~ceP)nTD4em9CJTMfkdY7_2&u#vTZl!G zqnjeA8JBI+cC~UO$VCek(s_UP-R^s#7>#t{!n=?2^ZlHIu+PcGkE_*eE5}?*?2x1P+O=>E+T+4%_({?&(VsvRQ$w1wbh}K&P)iU3fRY^nJOr_3%6=rAd$y z1H$;(@Im9v(%L5jF7N4tAwHVJf6w!y3n1T zQ-Sjw3La5}xe0>nkH!){ojbjw$$(qdq%$Gr8b$8d3GGSNZ-D3SF3pi}mS2n<(|w+| z7g7xQ0C~Y+FEU{P6Gl{VrLC|%l*#t{MIZF^CsA69v3uWEq`xXjk8J^o{7ASIPrp@} z>lS3PDvN-GT~zolpO)uZ5S*MWC|xsGu|2(_1{D}baALCS2Dy&@I@9WRiTAxvDrn)< z!w&y_QL%~)wi3G30000< KMNUMnLSTX*-fSQM