From 74b6897a12ec603ef835aaa77a01f0c32f49aa1c Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka" <takaoka@google.com>
Date: Thu, 30 Jun 2011 10:09:21 +0900
Subject: [PATCH] Adaptive suggestions strip

Bug: 4903845
Change-Id: I9e2e17a9eee72df5c92414dcd4796ed7fe1655e1
---
 .../btn_close_candidates_pane.9.png           | Bin 936 -> 0 bytes
 .../btn_expand_candidates_pane.9.png          | Bin 1123 -> 0 bytes
 .../keyboard_suggest_strip_divider.png        | Bin 2946 -> 0 bytes
 .../btn_close_candidates_pane.9.png           | Bin 713 -> 0 bytes
 .../btn_expand_candidates_pane.9.png          | Bin 681 -> 0 bytes
 .../keyboard_suggest_strip_divider.png        | Bin 2812 -> 0 bytes
 .../btn_close_candidates_pane.9.png           | Bin 1027 -> 0 bytes
 .../btn_expand_candidates_pane.9.png          | Bin 1350 -> 0 bytes
 .../keyboard_suggest_strip_divider.png        | Bin 2951 -> 0 bytes
 java/res/layout/candidate_divider.xml         |   9 +-
 java/res/layout/candidate_word.xml            |   5 +-
 java/res/layout/candidates_strip.xml          |  88 ++--
 java/res/values-sw600dp-land/dimens.xml       |   1 +
 java/res/values-sw768dp-land/dimens.xml       |   1 +
 java/res/values/attrs.xml                     |   4 +-
 java/res/values/dimens.xml                    |   2 +
 java/res/values/donottranslate.xml            |   7 +
 java/res/values/styles.xml                    |  10 +-
 .../inputmethod/latin/CandidateView.java      | 430 ++++++++++++------
 .../android/inputmethod/latin/Settings.java   |   2 +-
 .../inputmethod/latin/SuggestedWords.java     |  19 +-
 21 files changed, 359 insertions(+), 219 deletions(-)
 delete mode 100644 java/res/drawable-hdpi/btn_close_candidates_pane.9.png
 delete mode 100644 java/res/drawable-hdpi/btn_expand_candidates_pane.9.png
 delete mode 100644 java/res/drawable-hdpi/keyboard_suggest_strip_divider.png
 delete mode 100644 java/res/drawable-mdpi/btn_close_candidates_pane.9.png
 delete mode 100644 java/res/drawable-mdpi/btn_expand_candidates_pane.9.png
 delete mode 100644 java/res/drawable-mdpi/keyboard_suggest_strip_divider.png
 delete mode 100644 java/res/drawable-xhdpi/btn_close_candidates_pane.9.png
 delete mode 100644 java/res/drawable-xhdpi/btn_expand_candidates_pane.9.png
 delete mode 100644 java/res/drawable-xhdpi/keyboard_suggest_strip_divider.png

diff --git a/java/res/drawable-hdpi/btn_close_candidates_pane.9.png b/java/res/drawable-hdpi/btn_close_candidates_pane.9.png
deleted file mode 100644
index bdd949577df94729947f2afdd78face65e669ca7..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 936
zcmV;Z16TZsP)<h;3K|Lk000e1NJLTq001=r001=z1^@s6;pU@o00004b3#c}2nYxW
zd<bNS00009a7bBm000Y#000Y#0XNCZtpET6N=ZaPRA_<in#*rhRTRd5ALV5*$itW#
zvBaq)Mg~ZO!hodu2RJcm3OZ=gk{Co1V9=2c97qEp0pkekbK=CI12Fia)dUlwP9#l$
z2;pTx)P|<{9CV#_TYB$3=k_+xd(W5b^xOOHwbr+@*S%-&b&72OM_b4+;8@RsU(8)t
zbgu=JC{dzBiAF*5;nennK{o)825$o<f?ooD0g!aN(czo&In}V8vfUZ<Wngpgwkjss
zt_=a70!TXD2q|+~l<hS^`+=>&ZvrQRe-DfV9|x8Me*)MNd^_+^@Na;(0VLh1S5}#R
zDQrIu9F6WHz+mv>lKw8>X9ch`y4}E);C+%V)FZ9%qHM1WdK_3Ce7~fjIt0x0y%~5n
zx_=Ujm2|6!n=<_XY#$8zEYJ%e=}e;p+1?oR81P;Af2)X#q5(T?{}ipKka0oS?nz>G
z*0z{7ZOZg3x~Nxx(P$s#F|fTZTEFdf+wD1H4JNT(Eh2JpPGQ+u?it_<07?JmuzLy^
zi0&%jxftIq>9=aOlE!R*72Ovz4SCLrEuDT(Mr#9xqg90MF56we`%E5>#(~2TZxQf;
z?QOQV)rgzLYD+ZKM6UD$)+PLWwTZT01Nx$S4%iJK>9XyUF@6|$FXj(O`n-a>G}dD|
zwKiw^<=v^J37_=`!uCr+ck%!8+tg`W(#4qD3w#{Idu{&{pMN>SZ5nG?POZ5YHJ0$@
zGe5NbJn&|8F9L5s<?Dl_E4H%~Jp>#GKckXPB~u@$prI;SI{p4g`1<%el8l{Y@`4BO
zj-=6A4ki5#Q$H;GV))k?(>f|>sEWLc${v&xz^33|Cju`4d-DcOA?a!r+bq^ZqM;^Q
zH~l321z>v!cp>-^Nx8qgMPYk+77O?>(~t*6cj_}H&v2`lyn4?kx|3L+6ftbw^vfXW
z2iw_m<aOJ_G5&L-1lfK%^ADWL;ug|bN6^^{FMAqsrH`w8c2y}0FDd3y_v>J~?)Na$
zb-xemsQc}RZZ~i(c%P)IH-bto=UR4N8?>Le)iSrT^S4Zwov+s`t4zOYXqvYk6}`^>
z(rqblC-{86bZgFsZ;28mO0+J@e_~t+kZq)z2aEe*H*=kSZ1W#A%1oeyR*5|T0000<
KMNUMnLSTY*-?b<J

diff --git a/java/res/drawable-hdpi/btn_expand_candidates_pane.9.png b/java/res/drawable-hdpi/btn_expand_candidates_pane.9.png
deleted file mode 100644
index 63015ec5bbd67239e9ac423c755806e59dadc97d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1123
zcmV-p1f2VcP)<h;3K|Lk000e1NJLTq001%o001%w1^@s69zTe&00004b3#c}2nYxW
zd<bNS00009a7bBm000Y#000Y#0XNCZtpET71xZ9fRA_<inoo#Tbri=xM{BgQvce34
zYKn=-nnj@5%wo!E)glVPHf<&a0|^rfGDvV`6odxR9~v!?7Da-(FeoTzm|odH<SLn{
zbW`9)$4O<%zAf%~&966i?*0AldoOzNzMJ2@=bm%E=iK|={hf2(LlS`KT*!0i=p?%6
zqKhs%6xL4Xl9mHKemZMrXWB*8(nKWP4m=F32Ks<y4JtFh6z~o3nVJ3AD(aRbB545F
z1oS7G9tTFvY@*o^no2~{O~7_wFc4n=YQQnzXW%!NUj^I-tN|VXt_W-<fL&(xYt>LH
zCn9ML@G@|Xi%tP=0biKeY>90T@F4IsaEptlffvl|Se0-p*np&Ul4_DBB~3_rLek<2
zeipm!g!`&VT302cbPH)!Kzu~fstUw;K92-9=I&G%se~&6!o!kQCK49;Ug<vTH)utQ
zc`Dg%CmNU3n-*%6|6cb!DQS0#X$r}p6HH24pB`p3&-#F8u-qauTa>`D(bp5efwb_F
zZ~*wefwL4*iAd^WZnGOTv$l1W?t7n~_Di}m#xC}WJml*cU@S4VDmdy~knK06h)ra*
zuQfCKqw!)hZ!bwVHp-l%*1%ne*hKn#J)RRtKk%`nkw{;4JCpP*@R6iDa#ZSEeL2_W
zp)?UM#p_k<$sCnufTh3|NjqY8cu7mh%9|(2YOu{YYIUw<9z!8wp2*d~@!6c~+sFz;
zfJcGXB{i1se?!uBz}vvEi;e<2a#W`mh#?m-iTqh~(adImt-xUy-4E>Z%J?7fP4qqB
z9v6K8Ja1+fb6kgS#=;mNE|Hnw_}V-LGyC1lb^>pD0KLHbVI3yvKHy#8X5bR=ikZD;
zW(x%wa-Ay+vNRDhJIh=$x0dLR0xtoxzzx7Vl7=Kb0=(hDT>zdlvkyzC>s&KtHeIMm
z{99|v*L%wp&Fm9k3)%N+3Ggbg6Sy2W4Qw*A@d(a3*HodFBQ}vqUk75|N@n&gFhbUB
zEg~Co`~ZxY*@-fHNtXd@8@LM*o5-iWE(eBU49x5l@D%VJ@HMb8p_Ls1uJ_~5BW>a!
zX|GqL`=$66SyE3*_vjnte&^a7YnD>|)}7u3JRWOgX0v8?DS_uP=Lk7l3rTzYPK~v(
zu^MxZJt?NCL}9CYFtHtt@qO@LX?2}296lUs#gp+TaVQu*qz*JHkAsGTanQJ=4NZ)L
zHUuB1nxx@!%lWRF8PKf-b}?7bog^y;QwDUKncKn70o%>&t198NVr2RvFc65tk?Bvs
zd6!>FR)gh@Our->nf_8WlvWL~2gwEnojJsw=dII!R#?z`*4Zuf(~E8Vp{I*3y6B<<
p@xS<+lS#s?a69=gBw8Gx#9ylpY%_ild}06q002ovPDHLkV1h{^|G5AF

diff --git a/java/res/drawable-hdpi/keyboard_suggest_strip_divider.png b/java/res/drawable-hdpi/keyboard_suggest_strip_divider.png
deleted file mode 100644
index a62daf90c49f7e80643f672fe5beeff96f8c00e8..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2946
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

diff --git a/java/res/drawable-mdpi/btn_close_candidates_pane.9.png b/java/res/drawable-mdpi/btn_close_candidates_pane.9.png
deleted file mode 100644
index 5ea56925dd62dc57218671ba37c00519e59efe6a..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 713
zcmV;)0yh1LP)<h;3K|Lk000e1NJLTq001KZ001Kh1^@s69@(>500004b3#c}2nYxW
zd<bNS00009a7bBm000Y#000Y#0XNCZtpET5Ye_^wR9J=Wm_2AyVHAd+qgW&TvFM`M
zMjWjm?NAd$9R%&Bt2l^Ril&ob2Zv6AlP!o2;-rYWb+J<s9sHrKZlaSQNYPSJ6a|A)
zUWa>v*Ld&k%}q)i@-83bp7VZBa`?V;Zjb~ZS}Qq6%R$;|E3+(XqNFZh53n6r53B$m
zfLCVrJ&R@CFp`SENub~mwORq@fxBilw<a)>wg3~rLEtO!5O@Z>1%3e=fL*|T;4rWm
zcnn-Lv(IU^NDI<0>As|SNn?^aSBdZRxOva(Zwid09!b-Z9!V;sqW_ay@VseBJ<Wib
zlr$%4s2-3|{*dQSHUuN7DCvcy(JUY#pHcTIHUe{1(gR7G5@Px!O-S075R-GCYf0O!
zOEBmH_5rhI_9G@{FK`n$4&0KoJ1Wl1D!?o-?7oqTg#iW#?vaHUkR!l#f@6Kfy>3W4
z6yvwxegj!x`h0yC0a5}k`LmLl-3Cg)GH_Yai3q={&yFlG9lrimBHw5X_z0BEYze^3
z7J;+C7vQ|4V>NzNpN&~yD!%4IAV-07z#?#__GUG+WuOc!0T*gYRy_n2Vw42)-q)R>
z&t4K-@u$t~pYl1-8-kKO1zv|9<!gM?OH#LA=i_xJNBfPtUw2$c>@Q<x-w3+zh@@Ox
zTuP7}FakVx-$*5u3E&>k3!G{M#`AlDI}N!=n)2Q<m@$9Q^QTq|O=A}B+I2NcZ<5XH
z+HRVcG~?f}oN}Hid;E-~d{TTht)5A5E5W39fb^5z6M{+aQ&V9=P_3VVBcQ@>2OYpq
v8hblvtF27>Z~mV#Nti_*s<ncQ-b~^*d#IM&U=wKY00000NkvXXu0mjf)}J;L

diff --git a/java/res/drawable-mdpi/btn_expand_candidates_pane.9.png b/java/res/drawable-mdpi/btn_expand_candidates_pane.9.png
deleted file mode 100644
index 83cb653055a39c24b26c65458a6f4f779d89cdbe..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 681
zcmV;a0#^NrP)<h;3K|Lk000e1NJLTq001KZ001Kh1^@s69@(>500004b3#c}2nYxW
zd<bNS00009a7bBm000Y#000Y#0XNCZtpET5OG!jQR9J=Wn7vDuQ5c7>Q)GspBz;i|
zIogm0eno*a6b(&n{Q(X(J2q6%ra@V@WLq@3Xao{D6r$qV9JDkQ1VK{B)!=PCyu6>!
z`-%<T%Yk!#_wQUU&wK83KMyK^>}?nvdk(T6`;j|R-bA$(I0u{p4gy=i7vN(`=|>*R
znqkxt;1)0(5QVV?tN|}mN~^m9qaFqB0GEO9z&l_C_yqh04gqI@i@+7219%VIPbqz?
zW{YY;y43}BO}(wQRM5ACZY}b<8v>)YtMlrzI$Ra~zue)-n^)T#0W+npsspuvWby|h
zf2uARbwu4z$Mb+>e8$6Pq#l^Z>Ra_loiNSeGgD4>po~E)Fa#{6lz!F&lTz9QmVm+V
zEgB_ZfIhbC$a)6wn0mLIVdy&5dum5!dOiI5^1z&l@pEQw2)GW+sV7T-^Z;|fHQ+*K
zX~*Yu9+;*W|30FW(re%u&<o6}Z3Q5mz*C?Hc$iXJ&Mfcv9L@u?8Dn$7{0rbY&<)I}
zT>)|&m<3J%Pf|*+3i5Ui!6vnaIuyroti<|_s2>aJP4$hsqFybb9}B;sQd^dTX^V0`
zSw=G$6?P+z?)fs>$?$6{B`FCL29IKs!bg?W^r{ca-9OdVnMyFD4X(hWxnaU+I{q8|
zIYIg(f4Y*i8nf)JUDIV5mt^B^?J(_87vmRBRN2o=gnls!Va07~>GZnT?({BEeW&+<
z?N0A&Lt!#dd*1^Wfy%xeGy%V;@9khe_9IvPH{WNHN=ii!)owu+-%R-fAJysIiKm53
P00000NkvXXu0mjfeu65S

diff --git a/java/res/drawable-mdpi/keyboard_suggest_strip_divider.png b/java/res/drawable-mdpi/keyboard_suggest_strip_divider.png
deleted file mode 100644
index 363936362f40906afd59b09cdbcd70693ab1b004..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2812
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
O0000<MNUMnLSTX_t2HhF

diff --git a/java/res/drawable-xhdpi/btn_close_candidates_pane.9.png b/java/res/drawable-xhdpi/btn_close_candidates_pane.9.png
deleted file mode 100644
index 9d797ed0d25a556ad6499dde6f4841fa4024e9aa..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1027
zcmV+e1pNDnP)<h;3K|Lk000e1NJLTq002Y)002Y?1^@s6I1`hy00004b3#c}2nYxW
zd<bNS00009a7bBm000Y#000Y#0XNCZtpET6rAb6VRCt{2oJ)vKVHn5%k8zFMQ!>aB
zB^E9*Qi@qwDapcZp=L;Kg=8TX7Kju@3At@-WMzTIeJm)sEJ!gS*I`^H(qrNO*7=_K
zX1?>D?|d^f&#&}<&iUT+yie1=bI$vmH&9goQ2y(#C;;W(qFetV+R&q`3ve9AaU92S
z{vw?@nW_$8IFUM%T1EX$eNBA`03!0W^3?$V)ZbJM6?KTJ&S1ENI-OcoWOy-xWA0GT
z0Dy?xF2A~>xI-+tIz&~6GTcs`P5n&0Oub2cPW?sgMIA?-Nu5g_M7>7c2>>GUF?-bo
zxI-+tI7C%PGdx5cK|M)54gezZEo1)v43|@vQr}YRng3;${K=`@A%?OXqN)QK9;XhW
zZUF!hxnr-%162)AtKHO3)a9J_OV-rx5JR~R*~@SiwGIG8<X$;>Bj%sN@G$iT=iit$
zr8~sXGs{JZH_$oMBS7alBM|0O)nh!hDp_BaH(GayA=5oXRSz;8Ph9{2BJv|LPc_38
z)T7MvCNfW7h8L+%m}gB)9{4?^Em8N7L_cF1^*oTt8Iu_9qYkFl@b`7h`#4QL5ozUh
zmw0Mnvfh|}iaW#*`;?hL4gHM9n2S|)9>X2funImv4QrGm9KQ_!M5H0*6rr9)rry+b
zx<d@H4yiWBFVbA3s^KY8PklxW_lh?hcZKJJWA^a;K8`zAVk%qDs5JE@afcXU9n#wz
zcldNs)x``~Q*HmEpwlHHO}ws-r%q8f@%(p=yU@;*ww^v6)mIF6h#}S?t>(CIu|cXj
zpW%9H6Ll?6x(6yEZ<#0DbM{lW@_aML*{4sx67`nE9b$-e$SZR^mipYBe?Sf0@m&BQ
zBF!<AiO5r+;3>74`ly{t#+YMUZ%N!ChFFJ$wMF=%HkEocIY>mpx7khE$|^)e-lfbJ
z>IwCwS_>s{hZv$9A|fpSpsJypUd!Wy{5|@vo(GA3NG<g)>uHJ2<qk1q>Zt-aOAVc~
zf>ml45athkmD5=hxkC(@93mpO06<m4o8n3yH}d!Uxl~sIRh^uiA3#I0zAU&y43+w}
zy8)=&cbdc(yU>&MZ@ZNuul*rm4H5Q-45x<uAt!)b_J=H^hNsGVYUr<|>fm)Wl{>_c
z_a3uh48tC?8fxBq%&t?z9<vYGt1iGDV)1>dg}6g3|H@wX(9Qoz?W(=*{-)|Uj^j9v
x^Dp85e@Fs<Q#FXHLL~K)=6`cj)LKnd@duitF@F+Wuu1>`002ovPDHLkV1n-o*S7!w

diff --git a/java/res/drawable-xhdpi/btn_expand_candidates_pane.9.png b/java/res/drawable-xhdpi/btn_expand_candidates_pane.9.png
deleted file mode 100644
index 88d01c9c865e1a60a93ca404e9e8489bce70199a..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1350
zcmV-M1-bf(P)<h;3K|Lk000e1NJLTq002P%002P<1^@s6j`zt$00004b3#c}2nYxW
zd<bNS00009a7bBm000Y#000Y#0XNCZtpET7=t)FDRCt{2n_q|)RT##9PnKG3rG@>I
z{#Y17C>Us_LZ#gnb)#1WT4oU98X>t*P!JU=Y+a?KQb89<UI#_xpKYUrKq#^zOEL>@
z)HKc9o-XE{zH!?9oSARdO?Dm_&YUynyzevbcg~q}-uHai1~8)&j`tt6258WrL4yVj
z8Z<a7G*XIfPXNYdicU#7JQ7sSi4kny0^A48ilV7N*C17o0pG>_7r=*-ei&|g7Ywt4
z^8&-x6Ku}~9*gXZ4n*yVbd#jM&R7kKdWVDUYvXneFfaG`1kfM%p94Pv$1~3_1#Sjr
zNB%D0;+%{=;3WV_zt+K-I*nj^Ht=#}FOPJ8q^|>?NIF$Q-dNxs;E5=@G18-vJ|pS#
z%7injnmM5^*j`|}-}dgf`fM+@J;wH!4rPytYjMa;b@ba_PzU{vhJ)?f<8~u34mcF~
zrzL&WiR?D|)<t#_@F%bgK+@M$#a1?g?Mc8}8A1n%uYsiBs>&^(_nNqU1GtWs;UAH7
zXz*6;MK*H+9jp^<_X6`HdxGSb*jEdyV*00$^u+Wtx=T`b6;YLXg6(;<3;@u3E)4(>
z`g$`(^MhAuR2>eFM!GkyZ58EoifzC*aY2h$DKv8eaABFswx`Bzx)<04AZbKm7m{py
zOJrXGX4t+ho_$+XPAMY*_h#-713OB#9}aAf^e`}iWT_2M*a&5Z!z@}pfqqG+C7m9u
zV&;2Z3v6FKSb2s+x;e{oEQDrGpu7>L#s#f?{(oS52JoKkCAODTC1+c<yKQ#^TW#Ok
zrh3XJ%drp&&k5lZ%(}#WYEyj$Fdld^+TH-XC~2UCzHz_{z`{)Na$xlkO;SExDc_<#
z%Q8LTvRwX1o4Tt=949Fr0A91*WqUB+;=iyx(e^}O17{jwJMdharbl!6Jl`Qv=Iiix
z(Tb9e*<K0sMA7}goxm0V+bah148>A7T?I~#^qok1CAH&_|4bL=+f0m<>j}ql`77F0
zmh>0!Jb>+=N!(;p;_;idpUV0iY~KN_&Bz@9)=PS~Aiq4H-wU=YZUjk3Y^R3k0&e2W
zao?`(Cff&Sjp?g^jkbG89IOD(0vD0&NCA2z?JUYK_(1$vlJaxJkSM!iOamh`f$6~3
zq75azZ##9itRwm5*3#O}i^M_F9rgE?<TgFWu`rrBf$}|Jcce3cxv3Mi==WdJmjJPV
z>ZRpI2lyW7E*np<oxa1I9LK^aYlIIXT}HB5xjXV7l@TIozwM>Kdf;Rfua<PYO|zkp
za=0?mkIM?E<X*GAnPfYiIx`-wvYn0q%K#MbO}X|0-j3`vV2`AwWyLge0@WwR&5=%v
z>!B(_B%P8pP^A|H9?Wpa@+yT&Mv%0NBsiL)JC?lX454pTrl>D?l}4SxmjkqdFI9pd
zW%NQ4e3?uWe5nU@$0C1;{L0~oL&OkxHL}-}#3COD=pgo4kCWK;!dz5(r|m^GN2M3p
z-jRz+FFd=1v#Y4{kj5P16bUVdM(XX^K=nf!%cCgWAf>y*HIhE7OgN*enG>k_;8y0$
zQV%dU_c(uMX&>-M=J_Qg{)TpEmOiC*X6ax(tcUR&V+2Rj*x=|ny*8wl<}l~~A0vIX
zd3>hm<OrQ@ZqT4Xg9Z&6G-!)a|F3!3Mk=&$Jl~8}?4@k}0Y8Tj6yA5+)&Kwi07*qo
IM6N<$f=SVNC;$Ke

diff --git a/java/res/drawable-xhdpi/keyboard_suggest_strip_divider.png b/java/res/drawable-xhdpi/keyboard_suggest_strip_divider.png
deleted file mode 100644
index cd7c2c7a2b4cc5a482fc5fb7a1a4297fa1d37b0b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2951
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

diff --git a/java/res/layout/candidate_divider.xml b/java/res/layout/candidate_divider.xml
index 7481630745..a1059dc2fe 100644
--- a/java/res/layout/candidate_divider.xml
+++ b/java/res/layout/candidate_divider.xml
@@ -18,12 +18,13 @@
 */
 -->
 
-<ImageView
+<TextView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="wrap_content"
     android:layout_height="match_parent"
-    android:src="@drawable/keyboard_suggest_strip_divider"
+    android:text="@string/label_candidate_divider"
+    android:textSize="@dimen/candidate_text_size"
+    android:gravity="center"
     android:padding="0dp"
     android:focusable="false"
-    android:clickable="false"
-    android:gravity="center_vertical|center_horizontal" />
+    android:clickable="false" />
diff --git a/java/res/layout/candidate_word.xml b/java/res/layout/candidate_word.xml
index 7b6db2fe8e..b711e8f291 100644
--- a/java/res/layout/candidate_word.xml
+++ b/java/res/layout/candidate_word.xml
@@ -18,16 +18,19 @@
 */
 -->
 
-<Button
+<TextView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:minWidth="@dimen/candidate_min_width"
     android:textSize="@dimen/candidate_text_size"
+    android:gravity="center"
     android:paddingLeft="@dimen/candidate_padding"
     android:paddingTop="0dp"
     android:paddingRight="@dimen/candidate_padding"
     android:paddingBottom="0dp"
+    android:focusable="false"
+    android:clickable="false"
     android:singleLine="true"
     android:ellipsize="none"
     style="?attr/suggestionBackgroundStyle" />
diff --git a/java/res/layout/candidates_strip.xml b/java/res/layout/candidates_strip.xml
index ea6708ee72..0f542c0a25 100644
--- a/java/res/layout/candidates_strip.xml
+++ b/java/res/layout/candidates_strip.xml
@@ -25,73 +25,39 @@
     <LinearLayout
         android:id="@+id/candidates_strip"
         android:orientation="horizontal"
-        android:layout_width="match_parent"
+        android:layout_weight="1.0"
+        android:layout_width="0dp"
         android:layout_height="match_parent"
     >
-        <RelativeLayout
-            android:layout_weight="1.0"
-            android:layout_width="0dp"
-            android:layout_height="match_parent"
+    </LinearLayout>
+    <LinearLayout
+        android:id="@+id/candidates_pane_control"
+        android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+    >
+        <TextView
+            android:id="@+id/expand_candidates_pane"
+            android:text="@string/label_expand_candidates_pane"
             android:gravity="center"
-        >
-            <include
-                android:id="@+id/word_left"
-                layout="@layout/candidate_word" />
-            <include
-                android:id="@+id/info_left"
-                layout="@layout/candidate_info" />
-        </RelativeLayout>
-        <include
-            layout="@layout/candidate_divider" />
-        <RelativeLayout
-            android:layout_weight="1.0"
-            android:layout_width="0dp"
+            android:layout_width="wrap_content"
             android:layout_height="match_parent"
+            android:minWidth="30dp"
+            android:textSize="@dimen/candidate_text_size"
+            android:padding="0dp"
+            android:visibility="visible"
+            style="?attr/suggestionBackgroundStyle"  />
+        <TextView
+            android:id="@+id/close_candidates_pane"
+            android:text="@string/label_close_candidates_pane"
             android:gravity="center"
-        >
-            <include
-                android:id="@+id/word_center"
-                layout="@layout/candidate_word" />
-            <include
-                android:id="@+id/info_center"
-                layout="@layout/candidate_info" />
-        </RelativeLayout>
-        <include
-            layout="@layout/candidate_divider" />
-        <LinearLayout
-            android:orientation="horizontal"
-            android:layout_weight="1.0"
-            android:layout_width="0dp"
+            android:layout_width="wrap_content"
             android:layout_height="match_parent"
-            android:gravity="center_vertical"
-        >
-            <RelativeLayout
-                android:layout_weight="1.0"
-                android:layout_width="0dp"
-                android:layout_height="match_parent"
-                android:gravity="center"
-            >
-                <include
-                    android:id="@+id/word_right"
-                    layout="@layout/candidate_word" />
-                <include
-                    android:id="@+id/info_right"
-                    layout="@layout/candidate_info" />
-            </RelativeLayout>
-            <!-- Image drawables are set in CandidateView constructor -->
-            <ImageButton
-                android:id="@+id/expand_candidates_pane"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:visibility="gone"
-                android:background="@null" />
-            <ImageButton
-                android:id="@+id/close_candidates_pane"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:visibility="gone"
-                android:background="@null" />
-        </LinearLayout>
+            android:minWidth="30dp"
+            android:textSize="@dimen/candidate_text_size"
+            android:padding="0dp"
+            android:visibility="gone"
+            style="?attr/suggestionBackgroundStyle"  />
     </LinearLayout>
     <LinearLayout
         android:id="@+id/touch_to_save"
diff --git a/java/res/values-sw600dp-land/dimens.xml b/java/res/values-sw600dp-land/dimens.xml
index 5016f4247b..d732c87893 100644
--- a/java/res/values-sw600dp-land/dimens.xml
+++ b/java/res/values-sw600dp-land/dimens.xml
@@ -53,4 +53,5 @@
     <fraction name="key_uppercase_letter_ratio">29%</fraction>
 
     <dimen name="candidate_strip_padding">40.0mm</dimen>
+    <integer name="candidate_count_in_strip">5</integer>
 </resources>
diff --git a/java/res/values-sw768dp-land/dimens.xml b/java/res/values-sw768dp-land/dimens.xml
index 8cbd37e174..45a3d40b92 100644
--- a/java/res/values-sw768dp-land/dimens.xml
+++ b/java/res/values-sw768dp-land/dimens.xml
@@ -58,4 +58,5 @@
     <dimen name="key_preview_offset_ics">0.05in</dimen>
 
     <dimen name="candidate_strip_padding">40.0mm</dimen>
+    <integer name="candidate_count_in_strip">5</integer>
 </resources>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index c5897c853c..fb99336e87 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -120,8 +120,8 @@
         <attr name="colorTypedWord" format="color" />
         <attr name="colorAutoCorrect" format="color" />
         <attr name="colorSuggested" format="color" />
-        <attr name="iconExpandPane" format="reference" />
-        <attr name="iconClosePane" format="reference" />
+        <attr name="colorDivider" format="color" />
+        <attr name="candidateCountInStrip" format="integer" />
     </declare-styleable>
 
     <declare-styleable name="Keyboard">
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
index 36074b3b8d..6cf5fe99cb 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -82,6 +82,8 @@
     <dimen name="candidate_min_width">44dip</dimen>
     <dimen name="candidate_padding">6dip</dimen>
     <dimen name="candidate_text_size">18dip</dimen>
+    <integer name="candidate_count_in_strip">3</integer>
+
     <!-- If the screen height in landscape is larger than the below value, then the keyboard
          will not go into extract (fullscreen) mode. -->
     <dimen name="max_height_for_fullscreen">2.5in</dimen>
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index 21e6c55c6a..f88d2df1c4 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -43,6 +43,13 @@
     <!-- Label for "switch to phone symbols" key.  Must be short to fit on key! -->
     <string name="label_to_phone_symbols_key">\uff0a\uff03\uff08</string>
 
+    <!-- Character for candidate divider (BOX DRAWINGS LIGHT VERTICAL) -->
+    <string name="label_candidate_divider">\u2502</string>
+    <!-- Character for expand candidates pane (BLACK DOWN-POINTING TRIANGLE) -->
+    <string name="label_expand_candidates_pane">\u25bc</string>
+    <!-- Character for close candidates pane (BLACK UP-POINTING TRIANGLE) -->
+    <string name="label_close_candidates_pane">\u25b2</string>
+
     <!-- Option values to show/hide the settings key in onscreen keyboard -->
     <!-- Automatically decide to show or hide the settings key -->
     <string name="settings_key_mode_auto">0</string>
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
index 29b9d589cd..c0cc8fbda5 100644
--- a/java/res/values/styles.xml
+++ b/java/res/values/styles.xml
@@ -92,8 +92,8 @@
         <item name="colorTypedWord">#FFFFFFFF</item>
         <item name="colorAutoCorrect">#FFFCAE00</item>
         <item name="colorSuggested">#FFFCAE00</item>
-        <item name="iconExpandPane">@drawable/btn_expand_candidates_pane</item>
-        <item name="iconClosePane">@drawable/btn_close_candidates_pane</item>"
+        <item name="colorDivider">#20FFFFFF</item>
+        <item name="candidateCountInStrip">@integer/candidate_count_in_strip</item>
     </style>
     <!-- Theme "Basic high contrast" -->
     <style name="KeyboardView.HighContrast" parent="KeyboardView">
@@ -189,12 +189,12 @@
         <item name="android:background">@drawable/keyboard_popup_panel_background_holo</item>
     </style>
     <style name="CandidateViewStyle.IceCreamSandwich" parent="SuggestionsStripBackgroundStyle.IceCreamSandwich">
-        <item name="autoCorrectHighlight">autoCorrectUnderline|autoCorrectInvert</item>
+        <item name="autoCorrectHighlight">autoCorrectBold|autoCorrectInvert</item>
         <item name="colorTypedWord">#FFFFFFFF</item>
         <item name="colorAutoCorrect">#FFFFFFFF</item>
         <item name="colorSuggested">#FFFFFFFF</item>
-        <item name="iconExpandPane">@drawable/btn_expand_candidates_pane</item>
-        <item name="iconClosePane">@drawable/btn_close_candidates_pane</item>"
+        <item name="colorDivider">#20FFFFFF</item>
+        <item name="candidateCountInStrip">@integer/candidate_count_in_strip</item>
     </style>
     <style name="PopupMiniKeyboardAnimation">
         <item name="android:windowEnterAnimation">@anim/mini_keyboard_fadein</item>
diff --git a/java/src/com/android/inputmethod/latin/CandidateView.java b/java/src/com/android/inputmethod/latin/CandidateView.java
index a5bfea0f8f..ecabe6792b 100644
--- a/java/src/com/android/inputmethod/latin/CandidateView.java
+++ b/java/src/com/android/inputmethod/latin/CandidateView.java
@@ -30,6 +30,7 @@ import android.text.TextUtils;
 import android.text.style.BackgroundColorSpan;
 import android.text.style.CharacterStyle;
 import android.text.style.ForegroundColorSpan;
+import android.text.style.StyleSpan;
 import android.text.style.UnderlineSpan;
 import android.util.AttributeSet;
 import android.view.Gravity;
@@ -38,7 +39,6 @@ import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.View.OnLongClickListener;
 import android.view.ViewGroup;
-import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.PopupWindow;
 import android.widget.TextView;
@@ -57,24 +57,29 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
         public void pickSuggestionManually(int index, CharSequence word);
     }
 
+    private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD);
     private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan();
     // The maximum number of suggestions available. See {@link Suggest#mPrefMaxSuggestions}.
     private static final int MAX_SUGGESTIONS = 18;
-    private static final int MATCH_PARENT = MeasureSpec.makeMeasureSpec(
-            -1, MeasureSpec.UNSPECIFIED);
+    private static final int MATCH_PARENT = ViewGroup.LayoutParams.MATCH_PARENT;
+    private static final int WRAP_CONTENT = ViewGroup.LayoutParams.WRAP_CONTENT;
 
     private static final boolean DBG = LatinImeLogger.sDBG;
 
-    private final View mCandidatesStrip;
-    private static final int NUM_CANDIDATES_IN_STRIP = 3;
-    private final ImageView mExpandCandidatesPane;
-    private final ImageView mCloseCandidatesPane;
+    private final ViewGroup mCandidatesStrip;
+    private final int mCandidateCountInStrip;
+    private static final int DEFAULT_CANDIDATE_COUNT_IN_STRIP = 3;
+    private final ViewGroup mCandidatesPaneControl;
+    private final TextView mExpandCandidatesPane;
+    private final TextView mCloseCandidatesPane;
     private ViewGroup mCandidatesPane;
     private ViewGroup mCandidatesPaneContainer;
     private View mKeyboardView;
+
     private final ArrayList<TextView> mWords = new ArrayList<TextView>();
     private final ArrayList<TextView> mInfos = new ArrayList<TextView>();
     private final ArrayList<View> mDividers = new ArrayList<View>();
+
     private final int mCandidateStripHeight;
     private final CharacterStyle mInvertedForegroundColorSpan;
     private final CharacterStyle mInvertedBackgroundColorSpan;
@@ -85,6 +90,8 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
     private final int mColorTypedWord;
     private final int mColorAutoCorrect;
     private final int mColorSuggestedCandidate;
+    private final int mColorDivider;
+
     private final PopupWindow mPreviewPopup;
     private final TextView mPreviewText;
 
@@ -96,8 +103,9 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
     private boolean mShowingAutoCorrectionInverted;
     private boolean mShowingAddToDictionary;
 
-    private static final float MIN_TEXT_XSCALE = 0.4f;
-    private static final String ELLIPSIS = "\u2026";
+    private final CandidateViewLayoutParams mParams;
+    private static final int PUNCTUATIONS_IN_STRIP = 6;
+    private static final float MIN_TEXT_XSCALE = 0.8f;
 
     private final UiHandler mHandler = new UiHandler(this);
 
@@ -150,6 +158,114 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
         }
     }
 
+    private static class CandidateViewLayoutParams {
+        public final TextPaint mPaint;
+        public final int mPadding;
+        public final int mDividerWidth;
+        public final int mDividerHeight;
+        public final int mControlWidth;
+        private final int mAutoCorrectHighlight;
+
+        public final ArrayList<CharSequence> mTexts = new ArrayList<CharSequence>();
+
+        public int mCountInStrip;
+        // True if the mCountInStrip suggestions can fit in suggestion strip in equally divided
+        // width without squeezing the text.
+        public boolean mCanUseFixedWidthColumns;
+        public int mMaxWidth;
+        public int mAvailableWidthForWords;
+        public int mConstantWidthForPaddings;
+        public int mVariableWidthForWords;
+        public float mScaleX;
+
+        public CandidateViewLayoutParams(Resources res, View divider, View control,
+                int autoCorrectHighlight) {
+            mPaint = new TextPaint();
+            final float textSize = res.getDimension(R.dimen.candidate_text_size);
+            mPaint.setTextSize(textSize);
+            mPadding = res.getDimensionPixelSize(R.dimen.candidate_padding);
+            mDividerWidth = divider.getMeasuredWidth();
+            mDividerHeight = divider.getMeasuredHeight();
+            mControlWidth = control.getMeasuredWidth();
+            mAutoCorrectHighlight = autoCorrectHighlight;
+        }
+
+        public void layoutStrip(SuggestedWords suggestions, int maxWidth, int maxCount) {
+            final int size = suggestions.size();
+            setupTexts(suggestions, size, mAutoCorrectHighlight);
+            mCountInStrip = Math.min(maxCount, size);
+            mScaleX = 1.0f;
+
+            do {
+                mMaxWidth = maxWidth;
+                if (size > mCountInStrip) {
+                    mMaxWidth -= mControlWidth;
+                }
+
+                tryLayout();
+
+                if (mCanUseFixedWidthColumns) {
+                    return;
+                }
+                if (mVariableWidthForWords <= mAvailableWidthForWords) {
+                    return;
+                }
+
+                final float scaleX = mAvailableWidthForWords / (float)mVariableWidthForWords;
+                if (scaleX >= MIN_TEXT_XSCALE) {
+                    mScaleX = scaleX;
+                    return;
+                }
+
+                mCountInStrip--;
+            } while (mCountInStrip > 1);
+        }
+
+        public void tryLayout() {
+            final int maxCount = mCountInStrip;
+            final int dividers = mDividerWidth * (maxCount - 1);
+            mConstantWidthForPaddings = dividers + mPadding * maxCount * 2;
+            mAvailableWidthForWords = mMaxWidth - mConstantWidthForPaddings;
+
+            mPaint.setTextScaleX(mScaleX);
+            final int maxFixedWidthForWord = (mMaxWidth - dividers) / maxCount - mPadding * 2;
+            mCanUseFixedWidthColumns = true;
+            mVariableWidthForWords = 0;
+            for (int i = 0; i < maxCount; i++) {
+                final int width = getTextWidth(mTexts.get(i), mPaint);
+                if (width > maxFixedWidthForWord)
+                    mCanUseFixedWidthColumns = false;
+                mVariableWidthForWords += width;
+            }
+        }
+
+        private void setupTexts(SuggestedWords suggestions, int count, int autoCorrectHighlight) {
+            mTexts.clear();
+            for (int i = 0; i < count; i++) {
+                final CharSequence suggestion = suggestions.getWord(i);
+                if (suggestion == null) continue;
+
+                final boolean isAutoCorrect = suggestions.mHasMinimalSuggestion
+                        && ((i == 1 && !suggestions.mTypedWordValid)
+                                || (i == 0 && suggestions.mTypedWordValid));
+                // HACK: even if i == 0, we use mColorOther when this suggestion's length is 1
+                // and there are multiple suggestions, such as the default punctuation list.
+                // TODO: Need to revisit this logic with bigram suggestions
+                final CharSequence styled = getStyledCandidateWord(suggestion, isAutoCorrect,
+                        autoCorrectHighlight);
+                mTexts.add(styled);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return String.format(
+                    "count=%d width=%d avail=%d fixcol=%s scaleX=%4.2f const=%d var=%d",
+                    mCountInStrip, mMaxWidth, mAvailableWidthForWords, mCanUseFixedWidthColumns,
+                    mScaleX, mConstantWidthForPaddings, mVariableWidthForWords);
+        }
+    }
+
     /**
      * Construct a CandidateView for showing suggested words for completion.
      * @param context
@@ -173,6 +289,17 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
         setBackgroundDrawable(LinearLayoutCompatUtils.getBackgroundDrawable(
                 context, attrs, defStyle, R.style.CandidateViewStyle));
 
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.CandidateView, defStyle, R.style.CandidateViewStyle);
+        mAutoCorrectHighlight = a.getInt(R.styleable.CandidateView_autoCorrectHighlight, 0);
+        mColorTypedWord = a.getColor(R.styleable.CandidateView_colorTypedWord, 0);
+        mColorAutoCorrect = a.getColor(R.styleable.CandidateView_colorAutoCorrect, 0);
+        mColorSuggestedCandidate = a.getColor(R.styleable.CandidateView_colorSuggested, 0);
+        mColorDivider = a.getColor(R.styleable.CandidateView_colorDivider, 0);
+        mCandidateCountInStrip = a.getInt(
+                R.styleable.CandidateView_candidateCountInStrip, DEFAULT_CANDIDATE_COUNT_IN_STRIP);
+        a.recycle();
+
         Resources res = context.getResources();
         LayoutInflater inflater = LayoutInflater.from(context);
         inflater.inflate(R.layout.candidates_strip, this);
@@ -184,74 +311,52 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
         mPreviewPopup.setContentView(mPreviewText);
         mPreviewPopup.setBackgroundDrawable(null);
 
-        mCandidatesStrip = findViewById(R.id.candidates_strip);
+        mCandidatesStrip = (ViewGroup)findViewById(R.id.candidates_strip);
         mCandidateStripHeight = res.getDimensionPixelOffset(R.dimen.candidate_strip_height);
         for (int i = 0; i < MAX_SUGGESTIONS; i++) {
-            final TextView word, info;
-            switch (i) {
-            case 0:
-                word = (TextView)findViewById(R.id.word_left);
-                info = (TextView)findViewById(R.id.info_left);
-                break;
-            case 1:
-                word = (TextView)findViewById(R.id.word_center);
-                info = (TextView)findViewById(R.id.info_center);
-                break;
-            case 2:
-                word = (TextView)findViewById(R.id.word_right);
-                info = (TextView)findViewById(R.id.info_right);
-                break;
-            default:
-                word = (TextView)inflater.inflate(R.layout.candidate_word, null);
-                info = (TextView)inflater.inflate(R.layout.candidate_info, null);
-                break;
-            }
+            final TextView word = (TextView)inflater.inflate(R.layout.candidate_word, null);
             word.setTag(i);
             word.setOnClickListener(this);
             if (i == 0)
                 word.setOnLongClickListener(this);
             mWords.add(word);
-            mInfos.add(info);
-            if (i > 0) {
-                final View divider = inflater.inflate(R.layout.candidate_divider, null);
-                divider.measure(MATCH_PARENT, MATCH_PARENT);
-                mDividers.add(divider);
-            }
+            mInfos.add((TextView)inflater.inflate(R.layout.candidate_info, null));
+            mDividers.add(getDivider(inflater));
         }
 
         mTouchToSave = findViewById(R.id.touch_to_save);
         mWordToSave = (TextView)findViewById(R.id.word_to_save);
         mWordToSave.setOnClickListener(this);
 
-        final TypedArray a = context.obtainStyledAttributes(
-                attrs, R.styleable.CandidateView, defStyle, R.style.CandidateViewStyle);
-        mAutoCorrectHighlight = a.getInt(R.styleable.CandidateView_autoCorrectHighlight, 0);
-        mColorTypedWord = a.getColor(R.styleable.CandidateView_colorTypedWord, 0);
-        mColorAutoCorrect = a.getColor(R.styleable.CandidateView_colorAutoCorrect, 0);
-        mColorSuggestedCandidate = a.getColor(R.styleable.CandidateView_colorSuggested, 0);
         mInvertedForegroundColorSpan = new ForegroundColorSpan(mColorTypedWord ^ 0x00ffffff);
         mInvertedBackgroundColorSpan = new BackgroundColorSpan(mColorTypedWord);
 
-        mExpandCandidatesPane = (ImageView)findViewById(R.id.expand_candidates_pane);
-        mExpandCandidatesPane.setImageDrawable(
-                a.getDrawable(R.styleable.CandidateView_iconExpandPane));
+        mCandidatesPaneControl = (ViewGroup)findViewById(R.id.candidates_pane_control);
+        mExpandCandidatesPane = (TextView)findViewById(R.id.expand_candidates_pane);
         mExpandCandidatesPane.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View view) {
                 expandCandidatesPane();
             }
         });
-        mCloseCandidatesPane = (ImageView)findViewById(R.id.close_candidates_pane);
-        mCloseCandidatesPane.setImageDrawable(
-                a.getDrawable(R.styleable.CandidateView_iconClosePane));
+        mCloseCandidatesPane = (TextView)findViewById(R.id.close_candidates_pane);
         mCloseCandidatesPane.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View view) {
                 closeCandidatesPane();
             }
         });
+        mCandidatesPaneControl.measure(WRAP_CONTENT, WRAP_CONTENT);
 
-        a.recycle();
+        mParams = new CandidateViewLayoutParams(res, mDividers.get(0), mCandidatesPaneControl,
+                mAutoCorrectHighlight);
+    }
+
+    private View getDivider(LayoutInflater inflater) {
+        final TextView divider = (TextView)inflater.inflate(R.layout.candidate_divider, null);
+        divider.setTextColor(mColorDivider);
+        divider.measure(WRAP_CONTENT, WRAP_CONTENT);
+        return divider;
     }
 
     /**
@@ -279,15 +384,14 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
         }
     }
 
-    private CharSequence getStyledCandidateWord(CharSequence word, TextView v,
-            boolean isAutoCorrect) {
-        v.setTypeface(Typeface.DEFAULT);
+    private static CharSequence getStyledCandidateWord(CharSequence word, boolean isAutoCorrect,
+            int autoCorrectHighlight) {
         if (!isAutoCorrect)
             return word;
         final Spannable spannedWord = new SpannableString(word);
-        if ((mAutoCorrectHighlight & AUTO_CORRECT_BOLD) != 0)
-            v.setTypeface(Typeface.DEFAULT_BOLD);
-        if ((mAutoCorrectHighlight & AUTO_CORRECT_UNDERLINE) != 0)
+        if ((autoCorrectHighlight & AUTO_CORRECT_BOLD) != 0)
+            spannedWord.setSpan(BOLD_SPAN, 0, word.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+        if ((autoCorrectHighlight & AUTO_CORRECT_UNDERLINE) != 0)
             spannedWord.setSpan(UNDERLINE_SPAN, 0, word.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
         return spannedWord;
     }
@@ -313,91 +417,133 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
     private void updateSuggestions() {
         final SuggestedWords suggestions = mSuggestions;
         final List<SuggestedWordInfo> suggestedWordInfoList = suggestions.mSuggestedWordInfoList;
+        final int paneWidth = getWidth();
+        final CandidateViewLayoutParams params = mParams;
 
         clear();
-        final int paneWidth = getWidth();
-        final int dividerWidth = mDividers.get(0).getMeasuredWidth();
-        final int dividerHeight = mDividers.get(0).getMeasuredHeight();
-        int x = 0;
-        int y = 0;
-        int fromIndex = NUM_CANDIDATES_IN_STRIP;
-        final int count = Math.min(mWords.size(), suggestions.size());
         closeCandidatesPane();
-        mExpandCandidatesPane.setVisibility(count > NUM_CANDIDATES_IN_STRIP ? VISIBLE : GONE);
+        if (suggestions.size() == 0)
+            return;
+
+        params.layoutStrip(suggestions, paneWidth, suggestions.isPunctuationSuggestions()
+                ? PUNCTUATIONS_IN_STRIP : mCandidateCountInStrip);
+
+        final int count = Math.min(mWords.size(), suggestions.size());
+        if (count <= params.mCountInStrip) {
+            mCandidatesPaneControl.setVisibility(GONE);
+        } else {
+            mCandidatesPaneControl.setVisibility(VISIBLE);
+            mExpandCandidatesPane.setVisibility(VISIBLE);
+        }
+
+        final int countInStrip = params.mCountInStrip;
+        int fromIndex = countInStrip;
+        int x = 0, y = 0;
         for (int i = 0; i < count; i++) {
-            final CharSequence suggestion = suggestions.getWord(i);
+            final int pos;
+            if (i <= 1) {
+                final boolean willAutoCorrect = !suggestions.mTypedWordValid
+                        && suggestions.mHasMinimalSuggestion;
+                pos = willAutoCorrect ? 1 - i : i;
+            } else {
+                pos = i;
+            }
+            final CharSequence suggestion = suggestions.getWord(pos);
             if (suggestion == null) continue;
 
             final SuggestedWordInfo suggestionInfo = (suggestedWordInfoList != null)
-                    ? suggestedWordInfoList.get(i) : null;
+                    ? suggestedWordInfoList.get(pos) : null;
             final boolean isAutoCorrect = suggestions.mHasMinimalSuggestion
-                    && ((i == 1 && !suggestions.mTypedWordValid)
-                            || (i == 0 && suggestions.mTypedWordValid));
+                    && ((pos == 1 && !suggestions.mTypedWordValid)
+                            || (pos == 0 && suggestions.mTypedWordValid));
             // HACK: even if i == 0, we use mColorOther when this suggestion's length is 1
             // and there are multiple suggestions, such as the default punctuation list.
             // TODO: Need to revisit this logic with bigram suggestions
-            final boolean isSuggestedCandidate = (i != 0);
+            final boolean isSuggestedCandidate = (pos != 0);
             final boolean isPunctuationSuggestions = (suggestion.length() == 1 && count > 1);
 
-            final TextView word = mWords.get(i);
+            final TextView word = mWords.get(pos);
+            final TextPaint paint = word.getPaint();
             // TODO: Reorder candidates in strip as appropriate. The center candidate should hold
             // the word when space is typed (valid typed word or auto corrected word).
             word.setTextColor(getCandidateTextColor(isAutoCorrect,
                     isSuggestedCandidate || isPunctuationSuggestions, suggestionInfo));
-            final CharSequence text = getStyledCandidateWord(suggestion, word, isAutoCorrect);
-            if (i < NUM_CANDIDATES_IN_STRIP) {
-                final View parent = (View)word.getParent();
-                final int width = parent.getWidth() - word.getPaddingLeft()
-                        - word.getPaddingRight();
-                setTextWithAutoScaleAndEllipsis(text, width, word);
-            } else {
-                setTextWithAutoScaleAndEllipsis(text, paneWidth, word);
-            }
+            final CharSequence styled = params.mTexts.get(pos);
 
             final TextView info;
             if (DBG && suggestionInfo != null
                     && !TextUtils.isEmpty(suggestionInfo.getDebugString())) {
                 info = mInfos.get(i);
                 info.setText(suggestionInfo.getDebugString());
-                info.setVisibility(View.VISIBLE);
             } else {
                 info = null;
             }
 
-            if (i < NUM_CANDIDATES_IN_STRIP) {
+            final CharSequence text;
+            final float scaleX;
+            if (i < countInStrip) {
+                if (i == 0 && params.mCountInStrip == 1) {
+                    text = getEllipsizedText(styled, params.mMaxWidth, paint);
+                    scaleX = paint.getTextScaleX();
+                } else {
+                    text = styled;
+                    scaleX = params.mScaleX;
+                }
+                word.setText(text);
+                word.setTextScaleX(scaleX);
+                if (i != 0) {
+                    // Add divider if this isn't the left most suggestion in candidate strip.
+                    mCandidatesStrip.addView(mDividers.get(i));
+                }
+                mCandidatesStrip.addView(word);
+                if (params.mCanUseFixedWidthColumns) {
+                    setLayoutWeight(word, 1.0f);
+                } else {
+                    final int width = getTextWidth(text, paint) + params.mPadding * 2;
+                    setLayoutWeight(word, width);
+                }
                 if (info != null) {
-                    word.measure(MATCH_PARENT, MATCH_PARENT);
-                    info.measure(MATCH_PARENT, MATCH_PARENT);
+                    word.measure(WRAP_CONTENT, MATCH_PARENT);
                     final int width = word.getMeasuredWidth();
+                    info.measure(WRAP_CONTENT, WRAP_CONTENT);
                     final int infoWidth = info.getMeasuredWidth();
                     FrameLayoutCompatUtils.placeViewAt(
                             info, width - infoWidth, 0, infoWidth, info.getMeasuredHeight());
                 }
             } else {
-                word.measure(MATCH_PARENT, MATCH_PARENT);
-                final int width = word.getMeasuredWidth();
-                final int height = word.getMeasuredHeight();
-                // TODO: Handle overflow case.
-                if (dividerWidth + x + width >= paneWidth) {
+                paint.setTextScaleX(1.0f);
+                final int textWidth = getTextWidth(styled, paint);
+                int available = paneWidth - x - params.mPadding * 2;
+                if (textWidth >= available) {
+                    // Needs new row, centering previous row.
                     centeringCandidates(fromIndex, i - 1, x, paneWidth);
                     x = 0;
                     y += mCandidateStripHeight;
                     fromIndex = i;
                 }
                 if (x != 0) {
-                    final View divider = mDividers.get(i - NUM_CANDIDATES_IN_STRIP);
+                    // Add divider if this isn't the left most suggestion in current row.
+                    final View divider = mDividers.get(i);
                     mCandidatesPane.addView(divider);
                     FrameLayoutCompatUtils.placeViewAt(
-                            divider, x, y + (mCandidateStripHeight - dividerHeight) / 2,
-                            dividerWidth, dividerHeight);
-                    x += dividerWidth;
+                            divider, x, y + (mCandidateStripHeight - params.mDividerHeight) / 2,
+                            params.mDividerWidth, params.mDividerHeight);
+                    x += params.mDividerWidth;
                 }
+                available = paneWidth - x - params.mPadding * 2;
+                text = getEllipsizedText(styled, available, paint);
+                scaleX = paint.getTextScaleX();
+                word.setText(text);
+                word.setTextScaleX(scaleX);
                 mCandidatesPane.addView(word);
+                word.measure(WRAP_CONTENT, WRAP_CONTENT);
+                final int width = word.getMeasuredWidth();
+                final int height = word.getMeasuredHeight();
                 FrameLayoutCompatUtils.placeViewAt(
                         word, x, y + (mCandidateStripHeight - height) / 2, width, height);
                 if (info != null) {
                     mCandidatesPane.addView(info);
-                    info.measure(MATCH_PARENT, MATCH_PARENT);
+                    info.measure(WRAP_CONTENT, WRAP_CONTENT);
                     final int infoWidth = info.getMeasuredWidth();
                     FrameLayoutCompatUtils.placeViewAt(
                             info, x + width - infoWidth, y, infoWidth, info.getMeasuredHeight());
@@ -411,6 +557,16 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
         }
     }
 
+    private static void setLayoutWeight(View v, float weight) {
+        final ViewGroup.LayoutParams lp = v.getLayoutParams();
+        if (lp instanceof LinearLayout.LayoutParams) {
+            final LinearLayout.LayoutParams llp = (LinearLayout.LayoutParams)lp;
+            llp.weight = weight;
+            llp.width = 0;
+            llp.height = MATCH_PARENT;
+        }
+    }
+
     private void centeringCandidates(int from, int to, int width, int paneWidth) {
         final ViewGroup pane = mCandidatesPane;
         final int fromIndex = pane.indexOfChild(mWords.get(from));
@@ -436,38 +592,29 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
         }
     }
 
-    private static void setTextWithAutoScaleAndEllipsis(CharSequence text, int w, TextView v) {
-        // To prevent partially rendered character at the end of text, subtract few extra pixels
-        // from the width.
-        final int width = w - 4;
-
-        final TextPaint paint = v.getPaint();
-        final int textWidth = getTextWidth(text, paint, 1.0f);
-        if (textWidth < width || textWidth == 0 || width <= 0) {
-            v.setTextScaleX(1.0f);
-            v.setText(text);
-            return;
-        }
-
-        final float scaleX = Math.min((float)width / textWidth, 1.0f);
+    private static CharSequence getEllipsizedText(CharSequence text, int maxWidth,
+            TextPaint paint) {
+        paint.setTextScaleX(1.0f);
+        final int width = getTextWidth(text, paint);
+        final float scaleX = Math.min(maxWidth / (float)width, 1.0f);
         if (scaleX >= MIN_TEXT_XSCALE) {
-            v.setTextScaleX(scaleX);
-            v.setText(text);
-            return;
+            paint.setTextScaleX(scaleX);
+            return text;
         }
 
-        final int truncatedWidth = width - getTextWidth(ELLIPSIS, paint, MIN_TEXT_XSCALE);
-        final CharSequence ellipsized = getTextEllipsizedAtStart(text, paint, truncatedWidth);
-        v.setTextScaleX(MIN_TEXT_XSCALE);
-        v.setText(ELLIPSIS);
-        v.append(ellipsized);
+        // Note that TextUtils.ellipsize() use text-x-scale as 1.0 if ellipsize is needed. To get
+        // squeezed and ellipsezed text, passes enlarged width (maxWidth / MIN_TEXT_XSCALE).
+        final CharSequence ellipsized = TextUtils.ellipsize(
+                text, paint, maxWidth / MIN_TEXT_XSCALE, TextUtils.TruncateAt.MIDDLE);
+        paint.setTextScaleX(MIN_TEXT_XSCALE);
+        return ellipsized;
     }
 
-    private static int getTextWidth(CharSequence text, TextPaint paint, float scaleX) {
+    private static int getTextWidth(CharSequence text, TextPaint paint) {
         if (TextUtils.isEmpty(text)) return 0;
+        paint.setTypeface(getTextTypeface(text));
         final int len = text.length();
         final float[] widths = new float[len];
-        paint.setTextScaleX(scaleX);
         final int count = paint.getTextWidths(text, 0, len, widths);
         float width = 0;
         for (int i = 0; i < count; i++) {
@@ -476,33 +623,35 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
         return (int)Math.round(width + 0.5);
     }
 
-    private static CharSequence getTextEllipsizedAtStart(CharSequence text, TextPaint paint,
-            int maxWidth) {
-        final int len = text.length();
-        final float[] widths = new float[len];
-        final int count = paint.getTextWidths(text, 0, len, widths);
-        float width = 0;
-        for (int i = count - 1; i >= 0; i--) {
-            width += widths[i];
-            if (width > maxWidth)
-                return text.subSequence(i + 1, len);
+    private static Typeface getTextTypeface(CharSequence text) {
+        if (!(text instanceof SpannableString))
+            return Typeface.DEFAULT;
+
+        final SpannableString ss = (SpannableString)text;
+        final StyleSpan[] styles = ss.getSpans(0, text.length(), StyleSpan.class);
+        if (styles.length == 0)
+            return Typeface.DEFAULT;
+
+        switch (styles[0].getStyle()) {
+        case Typeface.BOLD: return Typeface.DEFAULT_BOLD;
+        // TODO: BOLD_ITALIC, ITALIC case?
+        default: return Typeface.DEFAULT;
         }
-        return text;
     }
 
     private void expandCandidatesPane() {
-        mExpandCandidatesPane.setVisibility(View.GONE);
-        mCloseCandidatesPane.setVisibility(View.VISIBLE);
+        mExpandCandidatesPane.setVisibility(GONE);
+        mCloseCandidatesPane.setVisibility(VISIBLE);
         mCandidatesPaneContainer.setMinimumHeight(mKeyboardView.getMeasuredHeight());
-        mCandidatesPaneContainer.setVisibility(View.VISIBLE);
-        mKeyboardView.setVisibility(View.GONE);
+        mCandidatesPaneContainer.setVisibility(VISIBLE);
+        mKeyboardView.setVisibility(GONE);
     }
 
     private void closeCandidatesPane() {
-        mExpandCandidatesPane.setVisibility(View.VISIBLE);
-        mCloseCandidatesPane.setVisibility(View.GONE);
-        mCandidatesPaneContainer.setVisibility(View.GONE);
-        mKeyboardView.setVisibility(View.VISIBLE);
+        mExpandCandidatesPane.setVisibility(VISIBLE);
+        mCloseCandidatesPane.setVisibility(GONE);
+        mCandidatesPaneContainer.setVisibility(GONE);
+        mKeyboardView.setVisibility(VISIBLE);
     }
 
     public void onAutoCorrectionInverted(CharSequence autoCorrectedWord) {
@@ -526,8 +675,8 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
     public void showAddToDictionaryHint(CharSequence word) {
         mWordToSave.setText(word);
         mShowingAddToDictionary = true;
-        mCandidatesStrip.setVisibility(View.GONE);
-        mTouchToSave.setVisibility(View.VISIBLE);
+        mCandidatesStrip.setVisibility(GONE);
+        mTouchToSave.setVisibility(VISIBLE);
     }
 
     public boolean dismissAddToDictionaryHint() {
@@ -543,12 +692,9 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
     public void clear() {
         mShowingAddToDictionary = false;
         mShowingAutoCorrectionInverted = false;
-        for (int i = 0; i < NUM_CANDIDATES_IN_STRIP; i++) {
-            mWords.get(i).setText(null);
-            mInfos.get(i).setVisibility(View.GONE);
-        }
-        mTouchToSave.setVisibility(View.GONE);
-        mCandidatesStrip.setVisibility(View.VISIBLE);
+        mTouchToSave.setVisibility(GONE);
+        mCandidatesStrip.setVisibility(VISIBLE);
+        mCandidatesStrip.removeAllViews();
         mCandidatesPane.removeAllViews();
     }
 
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index baad66d875..97ff3e4adb 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -288,7 +288,7 @@ public class Settings extends PreferenceActivity
                     builder.addWord(puncs.subSequence(i, i + 1));
                 }
             }
-            return builder.build();
+            return builder.setIsPunctuationSuggestions().build();
         }
     }
 
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index a8cdfc02e5..84db175047 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -24,15 +24,17 @@ import java.util.HashSet;
 import java.util.List;
 
 public class SuggestedWords {
-    public static final SuggestedWords EMPTY = new SuggestedWords(null, false, false, null);
+    public static final SuggestedWords EMPTY = new SuggestedWords(null, false, false, false, null);
 
     public final List<CharSequence> mWords;
     public final boolean mTypedWordValid;
     public final boolean mHasMinimalSuggestion;
+    public final boolean mIsPunctuationSuggestions;
     public final List<SuggestedWordInfo> mSuggestedWordInfoList;
 
     private SuggestedWords(List<CharSequence> words, boolean typedWordValid,
-            boolean hasMinimalSuggestion, List<SuggestedWordInfo> suggestedWordInfoList) {
+            boolean hasMinimalSuggestion, boolean isPunctuationSuggestions,
+            List<SuggestedWordInfo> suggestedWordInfoList) {
         if (words != null) {
             mWords = words;
         } else {
@@ -40,6 +42,7 @@ public class SuggestedWords {
         }
         mTypedWordValid = typedWordValid;
         mHasMinimalSuggestion = hasMinimalSuggestion;
+        mIsPunctuationSuggestions = isPunctuationSuggestions;
         mSuggestedWordInfoList = suggestedWordInfoList;
     }
 
@@ -59,10 +62,15 @@ public class SuggestedWords {
         return mHasMinimalSuggestion && ((size() > 1 && !mTypedWordValid) || mTypedWordValid);
     }
 
+    public boolean isPunctuationSuggestions() {
+        return mIsPunctuationSuggestions;
+    }
+
     public static class Builder {
         private List<CharSequence> mWords = new ArrayList<CharSequence>();
         private boolean mTypedWordValid;
         private boolean mHasMinimalSuggestion;
+        private boolean mIsPunctuationSuggestions;
         private List<SuggestedWordInfo> mSuggestedWordInfoList =
                 new ArrayList<SuggestedWordInfo>();
 
@@ -118,6 +126,11 @@ public class SuggestedWords {
             return this;
         }
 
+        public Builder setIsPunctuationSuggestions() {
+            mIsPunctuationSuggestions = true;
+            return this;
+        }
+
         // Should get rid of the first one (what the user typed previously) from suggestions
         // and replace it with what the user currently typed.
         public Builder addTypedWordAndPreviousSuggestions(CharSequence typedWord,
@@ -143,7 +156,7 @@ public class SuggestedWords {
 
         public SuggestedWords build() {
             return new SuggestedWords(mWords, mTypedWordValid, mHasMinimalSuggestion,
-                    mSuggestedWordInfoList);
+                    mIsPunctuationSuggestions, mSuggestedWordInfoList);
         }
 
         public int size() {
-- 
GitLab