From b1733c7bb7395fb7dcabb61e148ec0c305c8fc88 Mon Sep 17 00:00:00 2001 From: Pete Williamson Date: Tue, 24 Aug 2021 23:42:18 +0000 Subject: [PATCH] Add a shadow to the follow accelerator button. Due to optical illusions, the shadow using android:elevation did not show up since the button was a darker color. Instead we now use a 9-patch based approach. Bug: b/188184619 Change-Id: I303f08c87d8b9c0eb20a56993f5c5a99401f8d2a be able to do the shadow. I have followed the instructions at and run tools/resources/optimize-png-files.sh to make the bitmaps as small as possible. Binary-Size: Size increase is unavoidable. We have added bitmaps to https: //chromium.googlesource.com/chromium/src/+/HEAD/docs/speed/binary_size/optimization_advice.md#optimizing-images Change-Id: I303f08c87d8b9c0eb20a56993f5c5a99401f8d2a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3072888 Commit-Queue: Peter Williamson Reviewed-by: Cathy Li Reviewed-by: Theresa Reviewed-by: Andrew Grieve Cr-Commit-Position: refs/heads/main@{#914970} --- chrome/browser/feed/android/BUILD.gn | 6 +++ .../follow_accelerator_shadow.9.png | Bin 0 -> 2229 bytes .../follow_accelerator_shadow.9.png | Bin 0 -> 1301 bytes .../follow_accelerator_shadow.9.png | Bin 0 -> 3017 bytes .../follow_accelerator_shadow.9.png | Bin 0 -> 7197 bytes .../webfeed/ShadowedClickableTextBubble.java | 41 +++++++++++++----- .../feed/webfeed/WebFeedFollowIntroView.java | 8 ++-- components/browser_ui/widget/android/BUILD.gn | 1 - .../res/layout/textbubble_text_with_image.xml | 2 +- .../widget/textbubble/TextBubble.java | 23 +++++++--- 10 files changed, 59 insertions(+), 22 deletions(-) create mode 100644 chrome/browser/feed/android/java/res/drawable-hdpi/follow_accelerator_shadow.9.png create mode 100644 chrome/browser/feed/android/java/res/drawable-mdpi/follow_accelerator_shadow.9.png create mode 100644 chrome/browser/feed/android/java/res/drawable-xhdpi/follow_accelerator_shadow.9.png create mode 100644 chrome/browser/feed/android/java/res/drawable-xxhdpi/follow_accelerator_shadow.9.png rename components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/textbubble/ClickableTextBubble.java => chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/ShadowedClickableTextBubble.java (72%) diff --git a/chrome/browser/feed/android/BUILD.gn b/chrome/browser/feed/android/BUILD.gn index 226a773babc13..e46340cc11796 100644 --- a/chrome/browser/feed/android/BUILD.gn +++ b/chrome/browser/feed/android/BUILD.gn @@ -16,6 +16,7 @@ android_library("java") { "java/src/org/chromium/chrome/browser/feed/VideoPreviewsType.java", "java/src/org/chromium/chrome/browser/feed/settings/FeedAutoplaySettingsFragment.java", "java/src/org/chromium/chrome/browser/feed/settings/RadioButtonGroupVideoPreviewsPreference.java", + "java/src/org/chromium/chrome/browser/feed/webfeed/ShadowedClickableTextBubble.java", "java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedBridge.java", "java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedDialogContents.java", "java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedDialogCoordinator.java", @@ -54,6 +55,7 @@ android_library("java") { "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_browser_browser_java", + "//third_party/androidx:androidx_core_core_java", "//third_party/androidx:androidx_preference_preference_java", "//ui/android:ui_no_recycler_view_java", "//url:gurl_java", @@ -65,6 +67,10 @@ android_library("java") { android_resources("web_feed_java_resources") { sources = [ "java/res/color/menu_footer_chip_background.xml", + "java/res/drawable-hdpi/follow_accelerator_shadow.9.png", + "java/res/drawable-mdpi/follow_accelerator_shadow.9.png", + "java/res/drawable-xhdpi/follow_accelerator_shadow.9.png", + "java/res/drawable-xxhdpi/follow_accelerator_shadow.9.png", "java/res/drawable/web_feed_post_follow_illustration.xml", "java/res/layout/feed_management_activity.xml", "java/res/layout/feed_management_list_item.xml", diff --git a/chrome/browser/feed/android/java/res/drawable-hdpi/follow_accelerator_shadow.9.png b/chrome/browser/feed/android/java/res/drawable-hdpi/follow_accelerator_shadow.9.png new file mode 100644 index 0000000000000000000000000000000000000000..28504d72c7f49a100875175c15cc65ef7e116c6f GIT binary patch literal 2229 zcmW+&c{r5a8=gocYu1dhlzmC|#=JB0zOy!%Aq)|+WEjjCLn?})FH$03d#RtuQbhGB zOR^+PWzW9*m}pZHS}eb}?_Ae8=Xvhux$pCw>pXv)bXNvdR$4*I|!ocu!V3k2E*7(_tlQ- zw`HD0MNil{9>5Zb+T1=IiKNSJHVi1Y@J!T*nFT?z7N_4hpcq3YYx2g7{0p==gI07t zTmS%3c81o$EIgiw;*A0j1ULm52NXgu9@d0~AnnL*JdvsyH3pH%$ml71dm;cpI08YF zFT!FWxPAa6;fX{Ho`~enAfqQy+!39K&Yi4!Q@>mXM{oFa44$ABHH0A&^;uPRP7we| z)Q;?dmCb!FV6QWbi#tR3=Wbn!a-zXpBz{m4M8}Fq#yhggM;t{ zvTpbr7z79e43PmV?{yAyAiKgP!F2uL3LFkJIe6X1nXMDv4&Vum_${lX6WkdDR^bgJ7EQC(WUVUjJvO_anE%bA zF7A02ZqpOl;=F2o*#zBVK{{f83-b&+fS*&dCM*!uNw(x~?}zI06WxE)`pLHsIk!_! zx(ouz0@r3BWQlPGO?4}9WHv$cgCik+4hM?7G9rZDX~PH8x;#0BLy>@oZ%D?2=CO~9 z?q2?foZU@8vSQ#51VUmTjRbid+cesyFD7oOjOcD?<$XySBnaagKNs)s)NH#kI~!kT zzpg66BIXgb^%Obj>}zBXqN_@v!At0N3u4!~Lf`O&B_DJ2JsxRp5}h&AWb9|uEO%-@ zLaS8l?s!joT;+&e<(%||<}rAn#*?^?TUK%;f4o~ocMD2Cq_UZVmQulSr$aPqOvLGv ziSlk{9p@To>a-F1@kGITc5cIpTiGp}?Q#k~e^@lOvNpSaKWz5hHH3MD&hc}&NE_(u z_wZuww8+pua$1ljTfg?HLIbU2>3?@0JSiB8x%n+~`B6Zlr1@^avfSX%Xy5sI=c6t$hM&SD39GlfzWPsZHjX-7 zTq&P)vo2BD=QwS0JYM39ZTG9;>f}bE(@HufqoJdd5XHhh!P z#S_-KEJ^z_%oXpN$*@=p+Ey5)hEhG!#!p$Qjn)h&iL13?yckn=OA=TxS~+1-^yFam z)amZ}==^O>=n}u_xoQ{R*!yo4<;-?Z;aTixoliVrwTq^Ct2io8q_R3&YPPFb{C01` z)Y*UYdM+XTn`OLF9k#|nwR7qDqQ~6DVTWy%b^V`MZ0zgot4bIWP^R6>3xxTR_M~__!6j@Qz{A10h=F0A$kIS@-$vk@D0c8Zo_pP3n%gK2h zQ)DP!=HEfqJXzEGbqI|)nrN4ERx692ayZ^v?dqpdQFBJ9qnOBX^U$}ehb7kolaCA4|QM8LlJGYAr|o<~u#x z$_m_cGMhdh-BydLReZ-fEv5IaFtE5fR%)l-HAbigJuA*J;h)l{asM2RC|RtID`#DA z`mq1o#->D_Gq}$DwWlf`3Uz%aIp>rlR2;s^3@$(XILx~#TX=!GX@@GtFEEZe$<}eN zGFl6$92wh zGMk>=iwXN#n=hW_SYT|s{j%F_)KkT-ri`~0l)QE0@gT?M?uE9MsADJe!fJ|@%RRwl zJz6Y(xHc|+yFN)wKUX$B(ji)XCUkZwcsBI7LQAH1dFzc@;>@|?s;bp5E8l;M$ckIF z8!5*JdQ$W)r@fl9J|ev)_)%p^s$MyPY}+CU>XPksi(gsA$aV`W)D--KzobZN zGnW*33myG?d>*zBhuI8VtH33HHoLRc!1Pj?0suK>%Ho#p_L*0;BO82Dc}G-Ugltn^ sY;Sz9p*fgT`UzjKtQB8>a;jITT{x945Z?01`}6ytkr|{iLO{y@0WxXZi~s-t literal 0 HcmV?d00001 diff --git a/chrome/browser/feed/android/java/res/drawable-mdpi/follow_accelerator_shadow.9.png b/chrome/browser/feed/android/java/res/drawable-mdpi/follow_accelerator_shadow.9.png new file mode 100644 index 0000000000000000000000000000000000000000..2006047fad81e6db9d13fc06b3d68a287f7c9f6e GIT binary patch literal 1301 zcmV+w1?u{VP)Ta_Vd%pGpn9dX?papM|t=T%izIyy!=LP9lEh#zdv z9C6?pbLcihLq0x6IZkaLYtBGGKsQNAH#b8%Izl96x*KxkJx518Lqi~J%^Gv*IYL4; zN@X5z*gZWxK0ZVrZ`eCQNFi&?C1kfZQfV7<qD6FjR*=L_{KJ!8}1n9&OV>K}H>K**rl(9B|=2LPkPDMjLbH9B|+sZ`dDg(jsNN zEmD9#Lqi;J-6LqjHBE6EbLKumLL+CtIZ0d_a^pWkLn&aVJV!@7KtLmCzdu7mJU~Mr zYtKJJNH|DWAZyS(Ktm#CyeeIy9CG74N?9Uiz8iDqIz>e{Pi!M+zZ`JfBWJ%oK}0=6 zLo-lyBxJTAYt0^R)g5o%IYC4|K}A18LO()9&y&B}0001lbW%=J0RI630|W&H1_ufY z4G$0z1Q8Y*9v~tk97c<`%;EJ379TpA-TxCEF_;Jr7b9}*877(j8!){YDZM9~bvW)P zokaF1p`bC}RVkG(zBAG{#d<3_5QgFUOA0eH(|Q;;!;JSi zxSKl|W}Z1==9r;dbu6`=jstByIo~euraFnO65So>{(1g5jz29#rZKW0$`Y4_Nr;I&&AYq_YTaszYTXEtz_TI>Q=THw#}u2Bjd7z+6#4YydrSIshBRIeF555LEmP z#9+-60J1GqU$H|(c1&Pu3W&`TY&p7FyV(A#DR6AInkwC9C}+R2wZygWMr>AqGrFrj zk$Xh!R(8)vP3nP%r$Ae}lbxa8zD+Sgdn~EN8tWUQUijShl6|tFN#3OfWqLYGIS~l79i%iE)G!ukF+#)^LC>qL#%N2= zYk(Yrnrl{yJYv;6r(h9deph(a2d%Q~&V${gbv(}G6+e!3kVBYfU&Qlp2*A2OS_eRy ztYUZ~K{UyslpjiQgy2-4AL?_4SiFzm_}e%-JA9FdSmccHMaHUoB5P*-(X3T&(yGBz zKISQy)%fv#EWih$@S{Y?h>RnPXB(Smk;S-(ag)NeQpnsGF^8qKP}~^-FpAynGn);} zi*))=HVj3;WJd*(V(v~h-OMQo!s??h<|mTT6U_T3V#GK^BtgG?!~ANJd6oGa z=?|oK!U`y#>Ae`^#RqqqH-KM@o9R$YZ2^FU`wW-m2|&MyZ@TfX&`jD01QbW ze+Ii@>BV<$Gw-}u3U`A)rD9ApBwkPpc-nLVUs8SVi)8p)dEnO5ZR_)m)8;PVQ;Pc- zVY<}+RlGiLS=6K5eG_nHs8d`!XQ}=AMXhVduqo@}X%X}L9jz-TgXkrZF`( z`ok+%0=f0_@iFNgZOUU*R3Tl`&D__#s00000 LNkvXXu0mjfoQEoy literal 0 HcmV?d00001 diff --git a/chrome/browser/feed/android/java/res/drawable-xhdpi/follow_accelerator_shadow.9.png b/chrome/browser/feed/android/java/res/drawable-xhdpi/follow_accelerator_shadow.9.png new file mode 100644 index 0000000000000000000000000000000000000000..8e8b7d21ea478160a9d28bd7a7e3f98b0837c78b GIT binary patch literal 3017 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 literal 0 HcmV?d00001 diff --git a/chrome/browser/feed/android/java/res/drawable-xxhdpi/follow_accelerator_shadow.9.png b/chrome/browser/feed/android/java/res/drawable-xxhdpi/follow_accelerator_shadow.9.png new file mode 100644 index 0000000000000000000000000000000000000000..1c942cfb0fb7dc02452e84b86d78061572131c71 GIT binary patch literal 7197 zcmXw82RK{p7mvM1Yp6sErP~ky z;9Antyl);(wDlQH2Vi8rhxGqjSipnB3gwH-4G{qV_Zrm;0_*MAX1z%7GeZ}*x3?#I zdRNobmL_YCZT3`7*4NK*E6glq8mhB(EyjtJUP~(S)zdVOIQoK>)%L}0jMKOvcN4y| z2mKCP@{smJkx_$4Dk?W7nsaX~UAhI%uwW$+g+qJnIP#ex;*oMFSmwo(i}-DegC~lxLJL)dKP;STzWpaT1#s6Hc17eGEpMARF3b;11tro zdun=Gqq;%ZD9XppVli~E&op{wFrs;^@T20tb zr!@0`((b4_omU$t-18dy$-LpAGv3;7eYqgv8t{0 z&<=Ei23C~f`_grxGf+-m$87J-)A&K}$B~HEmxAAXrgiP(Sup&|4##}H@T8_c*IuvA z!sLA4mSJ38S4JkTZT^RZ%Y(5<^Z9E0>Pq+f=C?z;pP-44A3vGC-Ou{UxtMV>ipu9s z%e*xs>u1-Zl<)fyZ&#&0M*jX-NnTrt##szE`R7#E%-=jzy>P_7qv*(qvB}X(Q>5|u z=%%`=RWd_ussE;4xaKN}s#FuaGsNrh4EQAD%d{Y2dK@rG0(PA}pb<}l<11UE ziSk&O(|zr>clX!C#J~)RP^+MgUmF+PI~e;2e^ zeah7yXSp0T#Ibi%#(*YlumE|P>fOtGGIH+#X>fPaymK#`ZrN_gcdcVFC9$*JuV$y~ zeD3Ve`HfoMaNIMhKRI2!^NR%w1ed-M3!OC7K! z4pN}-(8>?s;nJrMrUaj~Q5tI9RUz#;Uq8L*`WSW3ZJ5#K-aAtAQ(3U@`F@JDj#Rj@ z#%bAI{=7CTwUg*s6p2(X#|7vqumJ6`mmA$g+9#_Q-IH<>9*RZTTEjp|sk@a*m8S0kZ z^C|mxo`y}NHkMQ9(;X|W`@xfJ_M;Bzi4|TAh4G1Ix71711J8 z`>5G%8C?q>FmsBH zH37Y5U6JK79tut|)C<0De|8AZeSo*6%hskww+?r8V@&6DAH%|)J+sr8=NW%s^d?UJ zqa_ssEs7X~B2PnoufeA=BO)D=xF6PzcRv*As%Ri?sLEZ3#lp)rXXHupF>2$NC4M+G zo2EWCuJI!nOHc0PTxNq0b)rag7R8p;YmLbi7_e^UO`l?DDbxaLTHS8sb4{-9@t{` z#)g#TLYN(>V-4>4$WTl~B-2&ZGN*7MIv4P%u?+!PTx;rtjwmBhR*;}_-J4upjbPnd zt>zniK>0xA;dL%qEdZkNwBCF3d^>`VlhB!V3&nU_Q2CB!@q|_|ut1bXvTdTA%LiG} zrCrz`)60~O>E2pz?`o`f{&EOss3Xy+BQ>idb3NSj8AcoK7r}7XuXEiW`U<3Mnn+Q`;jK1MOfZ?-ZkTi)|J^&@hi~pC(_f<_0j?aIx}8zW@_l4Cc&lTC9qCZCI?{ z5sS=yWOz)i0CCGe(`(kQzGlg*5*TYqAupLcdzV87&9zf+o#TohmcH&px8mgA1j1>% z-U(ZU=ip|{DnPO8x`M#AIk}rkws8($?_(T}j|4jprQ0N!?odQ2LTMCZxRM7$YapCf zURuh@B|ou@I^W9^wwvK?t-mT|V>J@3UPuzm&Am0ooygRJ%opeG&9{AJTwO6*GcBSU zpg{}E-H{G-E==g|K6TA_^ame&@0jQa0$_s>D?muCAmH(!fKtmPCU3FEO<*pm{WT5u zm1v2cU!U~apU&-g6t53HS^!AmNd0iSLftj1GiKgJu{6e|@LP~G^AH5+fnC^f-Xzz2 z>i{BtnHMek4ddOP;}h66&5vPc@I#HpC#GiaNKFJHNQRK(1QiA zDYE79+^DbP{HlXzNV_FLu40^uA%F1U56rzUe2U|<7&+?Tx@G;Ko?jejz0pmziZLF7 zMQKkL=;;kf7CQTTZYe6k3PTkz`tHo5xcrX?UrFBnn4)Zv;p&D|*le1#=LIi_wOEHK zXy4jsHH~jtHIPVOw)6IgUY@>Xh31&4P{@AapPeeHsAQHsD^akc?t7Nu&wHSWwM22u zv~C3kRwHTr$~zG&rG@Qwo_Ypmrz-}k$&D-!@-XN2yp?MDC#`F-vMk<1ps}#Up09yr zzSwP`>v{HZB(b+FZg6H9XPLn=IF>z^L2@_t%4_cVUwOFn}x)PA(l z?|JslVGziGq?R1G{TN(XLHsp)eHk=&P^A#{%S#2vD7j!hLV>aVJfNY8ZZ&4zvZSny z7$3+q3h@YVwlh0T3{vxK4ehNZwZaklKG&MIjT};0yHKX9KXz4^Xq|4_>1QtUta) zepRNA(5jiA&_9i}$>2v|<{l^>@#+X0eKp|}NT>FWeFpk+T zsd6#+8+m$O15Ska^O?W0wvo~55m4#r5%$IQ9;v%5jx}R}b1>vWwVF2xoJXdR>HK4z zaZqFOvKf6Qu{H*pIv8n=2>i$aq4^5&Jzo3~Z}fuJgZoy?H4gH8`r%21Nclzjx0fu& zMnDq31#6F`;K*B*0g&t5J?|bZFk*MJoF6Mc9phC~nxt*X3ZV1`)ZW=vPSb_dE}2Ah zz%m5L0>J7g#;!w#e-tCM2{W+QgxFKjeR^$1$COvEk%fZ@N9S;ht&++R^d)WC;sRkRRB=kCxAQ(ep8-uy_ry&RA8>zakZFi<W*u@Q9rgEJ}_vWSmwF!?)8DHu2TBy+=%G3peGo z+;{I7Y@Y8t9bn2zhZ+z>t+5p{Jss2NH2)s9)Xu8F+qL2U-{BJaTbcA+s{U0#PQ#8> z!LFOT0PeaGEF#yCws!NECYqz4!GBLGYfw{_CL01j*=*C6`J%AdBCR%VzeH7qhicS6 z4dR`8@k`w5+o2ql@Xp!7x$6IY27E@`$~C+~P7Q(Gmaih{^Q4!_3PBV`@F(9o&6N|! zS16u6+M;dxh18Ke?GUa7x^4{{Jf%p2aD4VYfL*#UmX1wwsRMD}sxVNM(h(6y+SlK$ zctt;uUn1NIEYNYCs`>*|w#7`@aJlM*{ZFqPyZp}OApiYa1izd+<4Nqe{bpd?ikv}t zf^=I%(tggobDiAS&6m`k;L_2~qqVglJWZthz>Zt?^wD8hxQw>|j(Sk8+89R@2|K3_ z_Y@@sxVx$u630MT~a zHRB_0N{(iGU9Jc>AOy*Yp!~%f68mLt*}Ol$HTv(-*`KJl`=nM@D5@Eh>BM#!j32@c zW*q?gZ^hPQ;wEoW%`Wc?js?bLgzV21JnMzoI}iy&il^uXw`MVZ2@_y`ax0$;G7zE~chyd$cmfGw)}Ts& z$42|N+{7KfZ7`bE-lsk9ERb_!q;PP#4IJ=E5OSAChS6tnk-p%7#yDD;z=QaT0ar8# zE`};R^9$JWYr+-n1io<{6XY`FRZOhr5Z4k(*KEQ!;hs(O208R&<&S2f7uRC(Bm?Lh z^tjl+-E`cZVCpcq*xKu~1rSeYGdr1ry<^5=?@F2l`2ztd*+xmqyx~t4Y80H2JJD{z zs3Rh*6a5ibY>d)C8=aTiU7;~A5rNLtc;X;9D$WlgaW1pWX#271N!PS@g#Hn%TT+t;0;mXjy?_%%>azs!xcA@5B)k?J@Z-!`4 z6k^52q*~IX%I!Wf>agL1W3)eDFbElkUsNLS^TvB90&Zd>ob~~M*C}S2)_IhDqZxG0 zhQ*k8jpbR?WR0s-@K;A>wDNe=0*dNQY-JaPBIHA-!PugFa12bZ(-6pC0~tvfuWU!tsl0_g{9rPQu8FOQK!^RhOZH z3!x0HXIC=yVQhI(UKVQaMdLxFG&~m@c@I4+x9O^UF`WX+UI0Pm1{-|?4)w-XrpLWrGe#VD)2OOdNxlOZXc*33(xYh`N_`xYbL zIxN9Yxyt-5_bH+s*dEo!(ET&q3wTGqr%aES8^mnOqi}jXmVTH7*8vknO{~)U|SfrALCw@<|*WIpEku zxx9s6xObuLxd`=(6;%E#JOoK7h*UbzU1j*7AOP5FL*FN`*a^=E9KTXSizVMnxz!3< zcunsZ@rou$J+VLUF`wbP=Dfyf)2`r^1FrXemp{)Dk$!#lGzs!ZAhypI<3M*CMf#6Q z|E9OVJC>L?(21Wc1a&|H$fBR`M>JziX%5s9zmM{97w{WGOzHxa8}9`SEHiAd*%Do> ztnND?%KZNq6M-7!;RSH%u(QRV>@J?#OUuYBlD(Zp?Zsg!aMtq_Ixd+SKO3!$J%*Se;v z24h``m-p@Nb(>ZCN_?1+c0X@cpNqcu-e36}zcIA$qbe{|IVxI+6vFm$+K79D@lF6% zCztmoN~S^fSxpllbg7W?;kq0-Ecec)@=xOTCaJxCUokh~xq%;<2e{i~nDOEE+iC&0 zx;o4CqX8BQ2GG>yq7;y~Tx%E6n3k=lpkmYsYo8Y5%&!w(zCHqcos5+H=kbU70L93?5or24rk~z=SRMm zS+S{bFcxhtHkp#~z}r1i3)mUz!bWfHrxF-qxJdF&)UwBZ{a5aei<|1HLre8pGL4A6 zw11>~>$nGh^&5?}B_^60*Xc}hY4DM8B)(rfwxXvlm6d7iY*}k&m7->+9aY@V71X7j|L#0f zJX-5nmE-9;s>CIpVbVLA=U6CL7ntZ)&kLSZbeyBo1riJIM8C*1C^^2-z}zrObMi;$ zc~>~^J;wUj-q}qmR3=YyiBK1>sITjvZRzneX)JfpDK6Exv)IK{MyXHB$h6*ve94av z>tcvy{ZTzRHA`}Qv+|7q!*TVoH%}A2Z33PTN)ufF#6b!V}qh!8}_u5?QTt} zCY2*Y)wM)bo7qo_qV=;6ssXybfcp`@AM%-Q13rr|K`SF}kEhFjwO2p+B@0a!1ZUoU z`OPpRFspv%Ltz~F!zA-k%V)I!|01u(_?n$@dZrfsV1dS}j{NIC(LuLxBb1azm-Sx1vfc9P`exb)wb418@j3K|S-Cijj& z0^p6~k9vi7sZUD?W2B`x7y7Ine?z3zVF0wchTC?B8P zCcs%LgBJiA$j*;>ej3#Q_F36OvlT?A^1sP(vFckA`dXel^I>5f(2zMaRfVatb!vA& zk+oTPWy?&XgP5JN%W8*pchns&J0H3!SS=La)VBouz7U|4TZ8`4nB<6!7me7NTy+n^ z0yC@fmj7LC?0th%`zo&({2OA0+E7_s>DLk6=~k`7t(6O% zPLW+vo6d7tfHqO?4QlStq}mtvlW%4Wu)AWUvtOJnsz8%PL-}B^nI(34Si5|Q4g%nt zU+IfVFWkiO;EAMkMAc6em)|@fRd>|aR?8GywKBc?l{V((ueCx{p(lktt>V_@;Qo$s z@6~1$ha_KPVX~tSjIic|d4DgHUwZCJ)llsIW5szIYG(yj39pW28>`y2SUw=Ducd*S zYtL&2{5AoN++eSYxG%8zg3H@z<)BA+o(Kd&R=u|9D+05~d2hbUcRZbe+R;7I_qFJ_ z7A@Lt+C|OZL-qXo%mIVrPVDk5{dd723;_|9H3OHuDKfMFnwte?;xi3}FNx$2!|bWf zDu-Apk4Peu7nz0>jKoC_&V0k4;=pdbZl79-QcKs_#G%VuK2#q&H|@=oNv6qX1fk;= z{=Ct5xuBz3U8M0lDvTtq%mKY(=4n#ur>w=qLP<|vhRC-E{{Z58afg8_v9%;?C^>3& z8upl1rX}o9>nFDtH)b}>XpzcJ0)3H_c?3Fs4a0*G}hwT z<2D!|ZpFf%)+wPb#yTbsss5stew@9|yB5p^aXncf+G4b1Ct2!~sTpFhKY*t5PeWDs z0OHSAo%g~{puQ*!i6X<|r;zeN-a0zPTBPdZ=`H)Gmn8c#jHC0JoP_^*0DzvBk!H;U Hr`Z1iZsQ>? literal 0 HcmV?d00001 diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/textbubble/ClickableTextBubble.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/ShadowedClickableTextBubble.java similarity index 72% rename from components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/textbubble/ClickableTextBubble.java rename to chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/ShadowedClickableTextBubble.java index b6eed518d77e8..ea06e2533f67d 100644 --- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/textbubble/ClickableTextBubble.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/ShadowedClickableTextBubble.java @@ -1,19 +1,29 @@ // Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.components.browser_ui.widget.textbubble; + +package org.chromium.chrome.browser.feed.webfeed; import android.content.Context; +import android.graphics.drawable.Drawable; import android.view.View; import androidx.annotation.DrawableRes; import androidx.annotation.StringRes; +import androidx.core.content.res.ResourcesCompat; -import org.chromium.components.browser_ui.widget.R; +import org.chromium.components.browser_ui.widget.textbubble.TextBubble; import org.chromium.ui.widget.LoadingView; import org.chromium.ui.widget.RectProvider; /** + * Provides a text bubble with a dark shadow to support a medium dark color. We need a darker + * shadow than other images such as navigation_bubble_shadow provide to prevent the optical illusion + * of the shadow being a part of the bitmap. However, if we add the images for the new shadow to + * ClickableTextBubble, they also get used by WebLayer, which doesn't need this shadow. To prevent + * increasing the size of the chrome APK, we include the bitmaps and the class to use them here with + * the other feed code. + * * UI component that handles showing a clickable text callout bubble. * *

This has special styling specific to clickable text bubbles: @@ -21,7 +31,6 @@ *

  • No arrow *
  • Rounder corners *
  • Smaller padding - * //TODO(sophey): Implement shadow once 9-patches are available. *
  • Shadow *
  • Optional loading UI * @@ -34,7 +43,7 @@ * element). Example below: * *
    {@code
    - *      ClickableTextBubble clickableTextBubble;
    + *      ShadowedClickableTextBubble clickableTextBubble;
      *      OnTouchListener onTouchListener = (view, motionEvent) -> {
      *          performPotentiallyLongRequest();
      *          clickableTextBubble.showLoadingUI(loadingViewContentDescriptionId);
    @@ -49,11 +58,13 @@
      *      }
      *  }
    */ -public class ClickableTextBubble extends TextBubble { +public class ShadowedClickableTextBubble extends TextBubble { + private final Context mContext; private final LoadingView mLoadingView; + private final boolean mInverseColor; /** - * Constructs a {@link ClickableTextBubble} instance. + * Constructs a {@link ShadowedClickableTextBubble} instance. * * @param context Context to draw resources from. * @param rootView The {@link View} to use for size calculations and for display. @@ -65,17 +76,27 @@ public class ClickableTextBubble extends TextBubble { * text and dismiss UX. * @param onTouchListener The callback for all touch events being dispatched to the bubble. */ - public ClickableTextBubble(Context context, View rootView, @StringRes int stringId, + public ShadowedClickableTextBubble(Context context, View rootView, @StringRes int stringId, @StringRes int accessibilityStringId, RectProvider anchorRectProvider, @DrawableRes int imageDrawableId, boolean isAccessibilityEnabled, - View.OnTouchListener onTouchListener) { + View.OnTouchListener onTouchListener, boolean inverseColor) { super(context, rootView, stringId, accessibilityStringId, /*showArrow=*/false, - anchorRectProvider, imageDrawableId, /*isRoundBubble=*/true, /*inverseColor=*/false, - isAccessibilityEnabled); + anchorRectProvider, imageDrawableId, /*isRoundBubble=*/true, + /*inverseColor=*/inverseColor, isAccessibilityEnabled); + mContext = context; + mInverseColor = inverseColor; setTouchInterceptor(onTouchListener); mLoadingView = mContentView.findViewById(R.id.loading_view); } + /** Get the backgound to use. We use a color button with a dark shadow. */ + @Override + public Drawable getBackground(Context context, boolean showArrow, boolean isRoundBubble) { + Drawable background = ResourcesCompat.getDrawable( + context.getResources(), R.drawable.follow_accelerator_shadow, null); + return background; + } + /** * Replaces image with loading spinner. Dismisses the entire button when loading spinner is * hidden. diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroView.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroView.java index 14038f5d82f17..32965c885e85a 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroView.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroView.java @@ -16,7 +16,6 @@ import org.chromium.chrome.browser.user_education.UserEducationHelper; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter; -import org.chromium.components.browser_ui.widget.textbubble.ClickableTextBubble; import org.chromium.components.browser_ui.widget.textbubble.TextBubble; import org.chromium.components.feature_engagement.FeatureConstants; import org.chromium.components.feature_engagement.Tracker; @@ -45,7 +44,7 @@ class WebFeedFollowIntroView { private final Tracker mFeatureEngagementTracker; private final Runnable mIntroDismissedCallback; - private ClickableTextBubble mFollowBubble; + private ShadowedClickableTextBubble mFollowBubble; private final int mShowTimeoutMillis; /** @@ -76,9 +75,10 @@ void showAccelerator(View.OnTouchListener onTouchListener, Runnable introShownCa return; } - mFollowBubble = new ClickableTextBubble(mActivity, mMenuButtonAnchorView, + mFollowBubble = new ShadowedClickableTextBubble(mActivity, mMenuButtonAnchorView, R.string.menu_follow, R.string.menu_follow, createRectProvider(), R.drawable.ic_add, - ChromeAccessibilityUtil.get().isAccessibilityEnabled(), onTouchListener); + ChromeAccessibilityUtil.get().isAccessibilityEnabled(), onTouchListener, + /*inverseColor*/ false); mFollowBubble.addOnDismissListener(this::introDismissed); // TODO(crbug/1152592): Figure out a way to dismiss on outside taps as well. mFollowBubble.setAutoDismissTimeout(mShowTimeoutMillis); diff --git a/components/browser_ui/widget/android/BUILD.gn b/components/browser_ui/widget/android/BUILD.gn index 20a956b2bff57..f94b0cb38e5da 100644 --- a/components/browser_ui/widget/android/BUILD.gn +++ b/components/browser_ui/widget/android/BUILD.gn @@ -104,7 +104,6 @@ android_library("java") { "java/src/org/chromium/components/browser_ui/widget/text/TextViewWithCompoundDrawables.java", "java/src/org/chromium/components/browser_ui/widget/text/VerticallyFixedEditText.java", "java/src/org/chromium/components/browser_ui/widget/textbubble/ArrowBubbleDrawable.java", - "java/src/org/chromium/components/browser_ui/widget/textbubble/ClickableTextBubble.java", "java/src/org/chromium/components/browser_ui/widget/textbubble/TextBubble.java", "java/src/org/chromium/components/browser_ui/widget/tile/TileView.java", "java/src/org/chromium/components/browser_ui/widget/tile/TileViewBinder.java", diff --git a/components/browser_ui/widget/android/java/res/layout/textbubble_text_with_image.xml b/components/browser_ui/widget/android/java/res/layout/textbubble_text_with_image.xml index 3c5f31b567746..12b5ca02a3138 100644 --- a/components/browser_ui/widget/android/java/res/layout/textbubble_text_with_image.xml +++ b/components/browser_ui/widget/android/java/res/layout/textbubble_text_with_image.xml @@ -50,4 +50,4 @@ android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.TextMediumThick.Primary.Inverse" /> - \ No newline at end of file + diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/textbubble/TextBubble.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/textbubble/TextBubble.java index bbd3c8bc9f34f..df7b2d346a344 100644 --- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/textbubble/TextBubble.java +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/textbubble/TextBubble.java @@ -57,10 +57,11 @@ public class TextBubble implements AnchoredPopupWindow.LayoutObserver { private final AnchoredPopupWindow mPopupWindow; /** The {@link Drawable} that is responsible for drawing the bubble and the arrow. */ - private final ArrowBubbleDrawable mBubbleDrawable; + @Nullable + private ArrowBubbleDrawable mBubbleDrawable; /** The {@link Drawable} that precedes the text in the bubble. */ - private final Drawable mImageDrawable; + protected final Drawable mImageDrawable; private final Runnable mDismissRunnable = new Runnable() { @Override @@ -253,8 +254,9 @@ public TextBubble(Context context, View rootView, String contentString, mInverseColor = inverseColor; mIsAccessibilityEnabled = isAccessibilityEnabled; - mBubbleDrawable = new ArrowBubbleDrawable(context, isRoundBubble); - mBubbleDrawable.setShowArrow(showArrow); + // For round, arrowless bubbles, we use a specialized background instead of the + // ArrowBubbleDrawable. + Drawable backgroundDrawable = getBackground(mContext, showArrow, isRoundBubble); mContentView = createContentView(); // On some versions of Android, the LayoutParams aren't set until after the popup window @@ -264,7 +266,7 @@ public TextBubble(Context context, View rootView, String contentString, new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); mPopupWindow = new AnchoredPopupWindow( - context, rootView, mBubbleDrawable, mContentView, anchorRectProvider); + context, rootView, backgroundDrawable, mContentView, anchorRectProvider); mPopupWindow.setMargin( context.getResources().getDimensionPixelSize(R.dimen.text_bubble_margin)); mPopupWindow.setPreferredHorizontalOrientation( @@ -277,15 +279,21 @@ public TextBubble(Context context, View rootView, String contentString, addOnDismissListener(mDismissListener); if (mIsAccessibilityEnabled) setDismissOnTouchInteraction(true); + } + /** Get the background to use. May be overridden by subclasses. */ + protected Drawable getBackground(Context context, boolean showArrow, boolean isRoundBubble) { + mBubbleDrawable = new ArrowBubbleDrawable(mContext, isRoundBubble); + mBubbleDrawable.setShowArrow(showArrow); // Set predefined styles for the TextBubble. - if (inverseColor) { + if (mInverseColor) { mBubbleDrawable.setBubbleColor(ApiCompatibilityUtils.getColor( mContext.getResources(), R.color.default_bg_color)); } else { mBubbleDrawable.setBubbleColor(ApiCompatibilityUtils.getColor( mContext.getResources(), R.color.default_control_color_active)); } + return mBubbleDrawable; } /** Shows the bubble. Will have no effect if the bubble is already showing. */ @@ -399,6 +407,9 @@ public void setPreferredVerticalOrientation( @Override public void onPreLayoutChange( boolean positionBelow, int x, int y, int width, int height, Rect anchorRect) { + // mBubbleDrawable might not be in use if a subclass replaces the drawable. + if (mBubbleDrawable == null) return; + int arrowXOffset = 0; if (mBubbleDrawable.isShowingArrow()) { arrowXOffset = anchorRect.centerX() - x;