From 88db0ee2afbae38b53a0527506f0890914a7f115 Mon Sep 17 00:00:00 2001 From: Deepanshu Gupta Date: Wed, 19 Jun 2013 17:29:12 -0700 Subject: [PATCH] Fix layout rendering for RTL locales This changeset adds the framework resources for RTL locales and mirrors the layout if the application is RTL aware. Use ICU to check the character orientation of the locale - right to left or left to right. Set the layout direction on the top level layout accordingly. Also, load the RTL resources for Nav Bar when the locale is RTL. Change-Id: I1ed0d516ab64120a0abca413ba678036661508f8 --- tools/layoutlib/bridge/.classpath | 1 + tools/layoutlib/bridge/Android.mk | 1 + .../bars/ldrtl-hdpi/ic_sysbar_back.png | Bin 0 -> 904 bytes .../bars/ldrtl-hdpi/ic_sysbar_recent.png | Bin 0 -> 533 bytes .../bars/ldrtl-mdpi/ic_sysbar_back.png | Bin 0 -> 617 bytes .../bars/ldrtl-mdpi/ic_sysbar_recent.png | Bin 0 -> 423 bytes .../bars/ldrtl-xhdpi/ic_sysbar_back.png | Bin 0 -> 1250 bytes .../bars/ldrtl-xhdpi/ic_sysbar_recent.png | Bin 0 -> 552 bytes .../com/android/layoutlib/bridge/Bridge.java | 20 +++++++++++++- .../bridge/android/BridgeContext.java | 6 +++- .../layoutlib/bridge/bars/CustomBar.java | 26 ++++++++++++++---- .../layoutlib/bridge/bars/NavigationBar.java | 13 +++++---- .../layoutlib/bridge/bars/StatusBar.java | 5 +++- .../layoutlib/bridge/impl/RenderAction.java | 3 +- .../bridge/impl/RenderSessionImpl.java | 25 +++++++++++++---- 15 files changed, 81 insertions(+), 19 deletions(-) create mode 100644 tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_back.png create mode 100644 tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_recent.png create mode 100644 tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_back.png create mode 100644 tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_recent.png create mode 100644 tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_back.png create mode 100644 tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_recent.png diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath index 3c124d90aaaed..2e4274da5afd2 100644 --- a/tools/layoutlib/bridge/.classpath +++ b/tools/layoutlib/bridge/.classpath @@ -7,5 +7,6 @@ + diff --git a/tools/layoutlib/bridge/Android.mk b/tools/layoutlib/bridge/Android.mk index 687a91feeb6f5..e3d48fca5eb23 100644 --- a/tools/layoutlib/bridge/Android.mk +++ b/tools/layoutlib/bridge/Android.mk @@ -22,6 +22,7 @@ LOCAL_JAVA_RESOURCE_DIRS := resources LOCAL_JAVA_LIBRARIES := \ kxml2-2.3.0 \ + icu4j \ layoutlib_api-prebuilt \ tools-common-prebuilt diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_back.png new file mode 100644 index 0000000000000000000000000000000000000000..782ebfe3f2ba73a6af893fcc62b25d47c21c970e GIT binary patch literal 904 zcmV;319$w1P)7l65Lz4(LBx>TWlcdS)J|1>9V5@1(e54b7e{)#a!^`)~^Zwg! z!7vQNFbu;m48t%C!!QiP_#bgaI*b}05gy^FQ4fDaS4JwlOC)A3hU@&Qe1Qggbd?(CaaRxX*RM>MA?RdqqFLhf~t z{Hdy%P@)kbUs%a%J}&1I3!T=2CY0#wf>!dX)VNV~${%Y)RZXg*{&13AD6v^I*H{*a zDCdmrSz!xjd7njE>0=B}-4#RdGjiYLFg?7-+r&A;dX_2CMvXEFC-^0Vr+aVl|gOspC zI7aAYmN&T0C2nz#1$+*lBbMmmJe`P?{xEVwb>~Rv6D?{=(>fKRo5~4AI;V>6X->xq zHJIdtO1iEY&Fc%HNU?m*IUETMYe5sLYOr8)I9vGt)U0l3TXXl-db6dOF<&XsA4)V- zxV1yE(8rqBV||xz)z9R{LLaH32_^b5+uDN3^?~ASr$oe5BcfY(?*lw3y$tb)9b9Fw zc?}S%UB%%#7ZBwhaGpB7jIx!8n+)&-Pd(%XKq$cvSi$oSPzSC5fOTLO-;z+~GWVM| z9>x06;Dz?|xA&jf59DzcctjR6 zFmMZjFyp1Wb$@_@>?NMQuIzVsSVfdXyW9>fU|?We=IP=XQgQ3;jq|?EhCJ;Lud6zF z#0LsG^&F5e;43ajVAktljxI=KY+0~~MGA`8Uto-^J|Qa|=d6IQZ!t z_UX9Yf6s-2Pakbi*>>o)%%+3E9wxSOmZ?FT52bQSpHrKjW1QM1e(a@6-i^n6#_OjR z{QUkr#xU`iS=gLU`W+b-*=vj+&2X<`jIR1~i+A?pXBGGL|J>5w^ZtjB$#sz(lP2Ej zws!uv&N<4NGks3ZJ}c3>=r%s?zkIyUe_TEDP#j`5G8?0-6^6o2<9{p($MXq_Qj z&cwsl=B-ch&3k!t-?@}!ci7fm*R^ul%z6I$-lq+UD>VX?jUV*PO`CnqT3PN?n~V9J zt;=?QS#G)a&74&RYp(g+5I-DoQ&GHT)AtBNLC*A|7b|c7Sd#i?lXHG#Tx!tAaI0q> zeZP-xeOG_Koj2jo$#%2P^}==Evu1`rh}h(B9+CeqVpS#I_nCWbIRDgad86-sXlCE$ z4X2&+tP_mdKI;Vst09F6zQUCw| literal 0 HcmV?d00001 diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_back.png new file mode 100644 index 0000000000000000000000000000000000000000..a1b806266959124745d646d6291d212fda386a02 GIT binary patch literal 617 zcmV-v0+#)WP)(W9A}Ca)`}p3lAIR1nBfH>tLm~A1J*cDagjSrvchM|nje^T?*>ZNV)kDyo^{!d zvmWz+ZFk$QarTJU?AY=ArrE@^jLcWAd3g{TgLv9ce)XzYM0>>s@rX;lc3iryR?lXR zx?t(;$Tnjxo>3pvHw%M!$oJ|)F$`|hp}}|!^_zl9EYk4-wYc%TunCXB&T~Zi7yeioiT?xWGv!nV>}#cL#00EI>hv{HMn1 zEAc=0Y1-B5)u*;Mi<`!Ay`;C{gGI_00000NkvXXu0mjf D`O+F+ literal 0 HcmV?d00001 diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_recent.png new file mode 100644 index 0000000000000000000000000000000000000000..fcdbefe9f5065e5578ab3132548b6fc347b329a9 GIT binary patch literal 423 zcmV;Y0a*TtP)7x0XRuSK~z}7 z?UzAP!!Qg*pMsao49SJ)4A+K5FO+mz!U`-Fp%B_GB!@5o^w!Q;`quxkAqavX2!h}@ zBerGgT7CJcgo5MR4RR9GtlxmnQ81YsQ8ql%lBvwaC3?0T+-*&$Txz#8b2eL2!BLS+ z#~phTYCJV%KtQF`G|8>^k!M77jS7C+O4M!`J)7hwpK1IBDv+spa2W<5Q_*qH(KE+Y zaXfhqqX-SHH*r#7fnN<{Y3PMpcBnT45_1B|Y#0@k8^oX3$vuCUhOq{{EbroUrC>EF zc&)t!g1Rr=X89acU|>U4n1zP%_3+fI~$Dc^Z^mJYgrKGmP+jY@p;jg?&zUhVcA6|Ju5ClQs;|+cYZaw!H RS2X|t002ovPDHLkV1hP2tWN*{ literal 0 HcmV?d00001 diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_back.png new file mode 100644 index 0000000000000000000000000000000000000000..633d864829381188283ec39fd3774d3f712abc86 GIT binary patch literal 1250 zcmV<81ReW{P)003YJ1ONa4FfOqY00002VoOIv0RM-N z%)bBt010qNS#tmY3labT3lag+-G2N4000McNliru+zS&H6Ej-CK+*sJ1anD5K~#9! z?VCYpTvZf?zkA zT)7ab3pZlbjaIOVg&Hi@iY7BjlQB~#ohET6@4er}n;BCPos@ac%=CP3H;~+%Z_d5< z+;d;RFbu;m48t%C!!QiPFbu;m48t%C!!QiPFbu;m)*P<4|9s)l$|&Sera|TUA`P@6 zAw;GMT_2bmA|Px=vVtk3nkiYlq5m*o}omBJ(x{gpA@eUg=MyH06N zMU^zKC;MnKX=@9Tl_|w%hkjOBB~5Ei549Bb^hrdmkvviR0GUr|uz)4*<82~Dj%D_7 zf`BN!KwU=qk^@$Oo$O+iZCsOLM0E$ z#sCXMj4;R|b(T{L$ZQ;(1gk=YFd?^?+pr}yuMLcMOF2@NXqDLujng|a@Xr*`yBFY z&!0o&h3?XfrZlT@ZAj~I-`01vj;X4mimK_=<^qzszBJ1T=U^uTL=19_YLa@c>+(ph zk_LH`+o=H?_<+OsG{(zVAaE@MMCAD%hfggW54^%&<`L`pil=FyZ1!HC^6wuZKm<&u zc-NRC;sp*;L9FKo9%B)oMfRnB5?N7a=2A?7kTG6lfjsM&W{jEE)h2x)utJCHRhK!aP8CB5tOI0jB|3lR=SL>-reGgURA8CCR-MlZKXuvP_T(ayS!4;f~WfDz7foNxJ& zS*o1txS{2!yGUztYG%_=y_dJxM2(OE3WU@NSJBoF*~FvnW93}9_5|kA{cZ#?o=>@- zBiuv40&@g-90RQDSl~#q`K(2J24lo{PP30E_=JmWVFSYq_Q|`kX@}8V)#P z+{7r`8KS_p_IsuOm4O%AH_BJi8u+)h5PZA4>F{{+9dE2x<|gtF5*;3hFQ+2O`tAEQ zCa@*(lDfrp{DUt0e_t>R!!QiPFbu;m48t%C!!QiPFbu;m45JJD2^x1jZULZWyZ`_I M07*qoM6N<$f?Je8UjP6A literal 0 HcmV?d00001 diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_recent.png new file mode 100644 index 0000000000000000000000000000000000000000..4665e2a6fef938d840c431d45c1affa6096e61ea GIT binary patch literal 552 zcmeAS@N?(olHy`uVBq!ia0vp^3xGI*g9S($=xr1NQcOwS?k)`f+xyS#2l6-zJR*x3 z7`TBl+(L|(?$-SQ3bL1Y`ns~;;b9fg;1FK#_L+f!ai^z?V@SoVx3?Vg4jBlvJ~ZEG z9(d((!GGogxfZR&W!yryR+R+KlH7jnzpj9jh8X|t$(~A#K%)@g!}A;e+Dm5Iytu*7 zHu+?5Th*Fl|8{&l%4(thx9Rf?#&cF#f!wjt>lRJst5xpd_^^#tuj*pzZNBCy{>o*B zt+G2`E?Ra>?#CY+lbK6`KM1{xS(mi>!+Fq5eg{q%I%de*JyUo^L~pn9sZp*mg0iX8EN3E%~xttlu1N zTj(7vclybAtX$)E+Qwd!h=z}{T_>;aHCuS^JBPty=be4kQj;$)obr)*Pr1f#`5SjG z`(0CSWZ;~@uzzog!JoBfcPIsg7_ENj!T76c-uHj6SbhYj%f5R*qtV~ZL-6LqO$R?@ zx#Ydh<^TWV`Tps{bqf8?{p`D(cn`M!i{1`sutf3sz=cGpv{rdA(=zg+C0j zdebvG<(}{AGl^+%4VC0yBDyo{kIb5t#rdy&jq extends FrameworkReso // build the context mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources, - mParams.getProjectCallback(), getConfiguration(), mParams.getTargetSdkVersion()); + mParams.getProjectCallback(), getConfiguration(), mParams.getTargetSdkVersion(), + mParams.isRtlSupported()); setUp(); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java index c14af4add0192..9ddbbf140df4c 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java @@ -225,13 +225,15 @@ public class RenderSessionImpl extends RenderAction { SessionParams params = getParams(); HardwareConfig hardwareConfig = params.getHardwareConfig(); BridgeContext context = getContext(); - + boolean isRtl = Bridge.isLocaleRtl(params.getLocale()); + int direction = isRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR; // the view group that receives the window background. ViewGroup backgroundView = null; if (mWindowIsFloating || params.isForceNoDecor()) { backgroundView = mViewRoot = mContentRoot = new FrameLayout(context); + mViewRoot.setLayoutDirection(direction); } else { if (hasSoftwareButtons() && mNavigationBarOrientation == LinearLayout.VERTICAL) { /* @@ -253,12 +255,14 @@ public class RenderSessionImpl extends RenderAction { the bottom */ LinearLayout topLayout = new LinearLayout(context); + topLayout.setLayoutDirection(direction); mViewRoot = topLayout; topLayout.setOrientation(LinearLayout.HORIZONTAL); try { NavigationBar navigationBar = new NavigationBar(context, - hardwareConfig.getDensity(), LinearLayout.VERTICAL); + hardwareConfig.getDensity(), LinearLayout.VERTICAL, isRtl, + params.isRtlSupported()); navigationBar.setLayoutParams( new LinearLayout.LayoutParams( mNavigationBarSize, @@ -290,6 +294,7 @@ public class RenderSessionImpl extends RenderAction { LinearLayout topLayout = new LinearLayout(context); topLayout.setOrientation(LinearLayout.VERTICAL); + topLayout.setLayoutDirection(direction); // if we don't already have a view root this is it if (mViewRoot == null) { mViewRoot = topLayout; @@ -301,13 +306,22 @@ public class RenderSessionImpl extends RenderAction { // this is the case of soft buttons + vertical bar. // this top layout is the first layout in the horizontal layout. see above) - mViewRoot.addView(topLayout, 0); + if (isRtl && params.isRtlSupported()) { + // If RTL is enabled, layoutlib will mirror the layouts. So, add the + // topLayout to the right of Navigation Bar and layoutlib will draw it + // to the left. + mViewRoot.addView(topLayout); + } else { + // Add the top layout to the left of the Navigation Bar. + mViewRoot.addView(topLayout, 0); + } } if (mStatusBarSize > 0) { // system bar try { - StatusBar systemBar = new StatusBar(context, hardwareConfig.getDensity()); + StatusBar systemBar = new StatusBar(context, hardwareConfig.getDensity(), + direction, params.isRtlSupported()); systemBar.setLayoutParams( new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, mStatusBarSize)); @@ -366,7 +380,8 @@ public class RenderSessionImpl extends RenderAction { // system bar try { NavigationBar navigationBar = new NavigationBar(context, - hardwareConfig.getDensity(), LinearLayout.HORIZONTAL); + hardwareConfig.getDensity(), LinearLayout.HORIZONTAL, isRtl, + params.isRtlSupported()); navigationBar.setLayoutParams( new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, mNavigationBarSize));