From 0a78aa8d786a5884752248ab7c84f21ce30f784a Mon Sep 17 00:00:00 2001 From: limuzi013 <128580527+limuzi013@users.noreply.github.com> Date: Thu, 1 Oct 2026 20:19:52 +0800 Subject: [PATCH 01/12] wip: visual language refinement, reference emoji and design scripts Local UI iteration on top of the v1 visual language: updated design tokens, key/panel renderers, icon set (new delete/download/floating/pin/return/shield/ text-cursor/undo vectors), zh resources, reference emoji assets and the reference capture/review scripts. Known state: :app:testDebugUnitTest has 12 failing tests (IconLintTest, KeyboardLayoutMetricsTest, NoDecorativeGlyphTest, NoRawColorTest, NoRawTextSizeTest, ProductionKeyPolicyTest, TokenDriftTest) that guard the design-token/metrics contracts; these need follow-up. output/ (screenshot artifacts) is intentionally not committed. Co-Authored-By: Claude Sonnet 5.5 --- .gitignore | 2 + app/src/main/assets/emoji/reference/1f600.png | Bin 0 -> 10659 bytes app/src/main/assets/emoji/reference/1f601.png | Bin 0 -> 10563 bytes app/src/main/assets/emoji/reference/1f602.png | Bin 0 -> 11035 bytes app/src/main/assets/emoji/reference/1f603.png | Bin 0 -> 10909 bytes app/src/main/assets/emoji/reference/1f604.png | Bin 0 -> 10490 bytes app/src/main/assets/emoji/reference/1f605.png | Bin 0 -> 10872 bytes app/src/main/assets/emoji/reference/1f606.png | Bin 0 -> 10572 bytes app/src/main/assets/emoji/reference/1f607.png | Bin 0 -> 11839 bytes app/src/main/assets/emoji/reference/1f609.png | Bin 0 -> 11148 bytes app/src/main/assets/emoji/reference/1f60a.png | Bin 0 -> 10446 bytes app/src/main/assets/emoji/reference/1f60c.png | Bin 0 -> 10689 bytes app/src/main/assets/emoji/reference/1f60d.png | Bin 0 -> 11037 bytes app/src/main/assets/emoji/reference/1f60e.png | Bin 0 -> 11208 bytes app/src/main/assets/emoji/reference/1f60f.png | Bin 0 -> 10469 bytes app/src/main/assets/emoji/reference/1f612.png | Bin 0 -> 10419 bytes app/src/main/assets/emoji/reference/1f614.png | Bin 0 -> 10659 bytes app/src/main/assets/emoji/reference/1f615.png | Bin 0 -> 10007 bytes app/src/main/assets/emoji/reference/1f617.png | Bin 0 -> 10666 bytes app/src/main/assets/emoji/reference/1f618.png | Bin 0 -> 11448 bytes app/src/main/assets/emoji/reference/1f619.png | Bin 0 -> 9847 bytes app/src/main/assets/emoji/reference/1f61a.png | Bin 0 -> 10936 bytes app/src/main/assets/emoji/reference/1f61b.png | Bin 0 -> 10870 bytes app/src/main/assets/emoji/reference/1f61c.png | Bin 0 -> 11143 bytes app/src/main/assets/emoji/reference/1f61d.png | Bin 0 -> 10305 bytes app/src/main/assets/emoji/reference/1f61e.png | Bin 0 -> 9920 bytes app/src/main/assets/emoji/reference/1f61f.png | Bin 0 -> 11013 bytes app/src/main/assets/emoji/reference/1f633.png | Bin 0 -> 10664 bytes app/src/main/assets/emoji/reference/1f641.png | Bin 0 -> 10185 bytes app/src/main/assets/emoji/reference/1f642.png | Bin 0 -> 10640 bytes app/src/main/assets/emoji/reference/1f643.png | Bin 0 -> 10463 bytes app/src/main/assets/emoji/reference/1f913.png | Bin 0 -> 11769 bytes app/src/main/assets/emoji/reference/1f923.png | Bin 0 -> 11442 bytes app/src/main/assets/emoji/reference/1f929.png | Bin 0 -> 10998 bytes app/src/main/assets/emoji/reference/1f92a.png | Bin 0 -> 11298 bytes app/src/main/assets/emoji/reference/1f970.png | Bin 0 -> 12504 bytes app/src/main/assets/emoji/reference/1f973.png | Bin 0 -> 12087 bytes app/src/main/assets/emoji/reference/1f978.png | Bin 0 -> 12040 bytes app/src/main/assets/emoji/reference/1f979.png | Bin 0 -> 10937 bytes app/src/main/assets/emoji/reference/1f97a.png | Bin 0 -> 10888 bytes .../main/assets/emoji/reference/263a_fe0f.png | Bin 0 -> 10845 bytes .../llc/slacker/openime/AboutDataActivity.kt | 76 ++-- .../slacker/openime/CandidateBarController.kt | 29 +- .../openime/ClipboardPanelController.kt | 248 ++++------- .../llc/slacker/openime/EmojiCellFactory.kt | 8 +- .../openime/FloatingKeyboardController.kt | 24 +- .../openime/FloatingWindowController.kt | 2 +- .../openime/FluentEmojiAssetRepository.kt | 13 +- .../llc/slacker/openime/ImeDesignTokens.kt | 31 +- .../java/llc/slacker/openime/ImeKeyView.kt | 30 +- .../llc/slacker/openime/ImeKeyboardView.kt | 192 +++++---- .../llc/slacker/openime/ImePanelRenderer.kt | 211 ++++++---- .../slacker/openime/ImeSettingsActivity.kt | 10 +- .../slacker/openime/ImeSettingsRepository.kt | 18 +- .../main/java/llc/slacker/openime/ImeState.kt | 9 +- .../llc/slacker/openime/ImeThemeApplier.kt | 194 +++++---- .../java/llc/slacker/openime/ImeTopZone.kt | 102 ++--- .../slacker/openime/InlineVoicePresenter.kt | 10 +- .../llc/slacker/openime/KeyboardGeometry.kt | 30 +- .../java/llc/slacker/openime/MainActivity.kt | 103 +++-- .../openime/NineKeySymbolRailController.kt | 38 +- .../openime/NumericKeyboardRenderer.kt | 20 +- .../llc/slacker/openime/PanelHeaderFactory.kt | 6 +- .../openime/Pinyin26KeyboardRenderer.kt | 18 +- .../openime/Pinyin9KeyboardRenderer.kt | 32 +- .../slacker/openime/ProductionKeyPolicy.kt | 18 +- .../openime/QuickPhraseEditActivity.kt | 119 ++---- .../openime/SettingsPanelController.kt | 270 ++++++------ .../main/java/llc/slacker/openime/SetupUi.kt | 67 ++- .../slacker/openime/SymbolManagerActivity.kt | 140 ++++--- .../llc/slacker/openime/SymbolRailRenderer.kt | 24 +- .../openime/TextEditorPanelController.kt | 109 ++--- .../llc/slacker/openime/UserDataArchive.kt | 2 +- .../slacker/openime/VoicePanelController.kt | 8 +- .../llc/slacker/openime/VoicePanelView.kt | 186 ++++----- app/src/main/res/drawable/bg_setup_card.xml | 3 - app/src/main/res/drawable/ic_arrow_back.xml | 10 +- app/src/main/res/drawable/ic_backspace.xml | 10 +- app/src/main/res/drawable/ic_brand_mark.xml | 14 +- app/src/main/res/drawable/ic_clipboard.xml | 2 +- app/src/main/res/drawable/ic_delete.xml | 1 + app/src/main/res/drawable/ic_download.xml | 1 + app/src/main/res/drawable/ic_edit.xml | 2 +- app/src/main/res/drawable/ic_emoji.xml | 2 +- app/src/main/res/drawable/ic_floating.xml | 1 + app/src/main/res/drawable/ic_grid.xml | 10 +- app/src/main/res/drawable/ic_keyboard.xml | 2 +- app/src/main/res/drawable/ic_mic.xml | 2 +- app/src/main/res/drawable/ic_pin.xml | 1 + app/src/main/res/drawable/ic_return.xml | 8 + app/src/main/res/drawable/ic_settings.xml | 2 +- app/src/main/res/drawable/ic_shield.xml | 1 + app/src/main/res/drawable/ic_shift.xml | 10 +- app/src/main/res/drawable/ic_symbols.xml | 2 +- app/src/main/res/drawable/ic_text_cursor.xml | 1 + app/src/main/res/drawable/ic_undo.xml | 1 + app/src/main/res/layout/activity_main.xml | 384 +++--------------- app/src/main/res/values-night/colors.xml | 10 +- app/src/main/res/values-zh/strings.xml | 36 ++ app/src/main/res/values/colors.xml | 16 +- app/src/main/res/values/strings.xml | 10 +- scripts/design_reference_e2e.py | 301 ++++++++++++++ scripts/extract_reference_emoji.py | 42 ++ scripts/reference_phone_capture.py | 102 +++++ scripts/reference_visual_review.py | 126 ++++++ 105 files changed, 1891 insertions(+), 1621 deletions(-) create mode 100644 app/src/main/assets/emoji/reference/1f600.png create mode 100644 app/src/main/assets/emoji/reference/1f601.png create mode 100644 app/src/main/assets/emoji/reference/1f602.png create mode 100644 app/src/main/assets/emoji/reference/1f603.png create mode 100644 app/src/main/assets/emoji/reference/1f604.png create mode 100644 app/src/main/assets/emoji/reference/1f605.png create mode 100644 app/src/main/assets/emoji/reference/1f606.png create mode 100644 app/src/main/assets/emoji/reference/1f607.png create mode 100644 app/src/main/assets/emoji/reference/1f609.png create mode 100644 app/src/main/assets/emoji/reference/1f60a.png create mode 100644 app/src/main/assets/emoji/reference/1f60c.png create mode 100644 app/src/main/assets/emoji/reference/1f60d.png create mode 100644 app/src/main/assets/emoji/reference/1f60e.png create mode 100644 app/src/main/assets/emoji/reference/1f60f.png create mode 100644 app/src/main/assets/emoji/reference/1f612.png create mode 100644 app/src/main/assets/emoji/reference/1f614.png create mode 100644 app/src/main/assets/emoji/reference/1f615.png create mode 100644 app/src/main/assets/emoji/reference/1f617.png create mode 100644 app/src/main/assets/emoji/reference/1f618.png create mode 100644 app/src/main/assets/emoji/reference/1f619.png create mode 100644 app/src/main/assets/emoji/reference/1f61a.png create mode 100644 app/src/main/assets/emoji/reference/1f61b.png create mode 100644 app/src/main/assets/emoji/reference/1f61c.png create mode 100644 app/src/main/assets/emoji/reference/1f61d.png create mode 100644 app/src/main/assets/emoji/reference/1f61e.png create mode 100644 app/src/main/assets/emoji/reference/1f61f.png create mode 100644 app/src/main/assets/emoji/reference/1f633.png create mode 100644 app/src/main/assets/emoji/reference/1f641.png create mode 100644 app/src/main/assets/emoji/reference/1f642.png create mode 100644 app/src/main/assets/emoji/reference/1f643.png create mode 100644 app/src/main/assets/emoji/reference/1f913.png create mode 100644 app/src/main/assets/emoji/reference/1f923.png create mode 100644 app/src/main/assets/emoji/reference/1f929.png create mode 100644 app/src/main/assets/emoji/reference/1f92a.png create mode 100644 app/src/main/assets/emoji/reference/1f970.png create mode 100644 app/src/main/assets/emoji/reference/1f973.png create mode 100644 app/src/main/assets/emoji/reference/1f978.png create mode 100644 app/src/main/assets/emoji/reference/1f979.png create mode 100644 app/src/main/assets/emoji/reference/1f97a.png create mode 100644 app/src/main/assets/emoji/reference/263a_fe0f.png create mode 100644 app/src/main/res/drawable/ic_delete.xml create mode 100644 app/src/main/res/drawable/ic_download.xml create mode 100644 app/src/main/res/drawable/ic_floating.xml create mode 100644 app/src/main/res/drawable/ic_pin.xml create mode 100644 app/src/main/res/drawable/ic_return.xml create mode 100644 app/src/main/res/drawable/ic_shield.xml create mode 100644 app/src/main/res/drawable/ic_text_cursor.xml create mode 100644 app/src/main/res/drawable/ic_undo.xml create mode 100644 app/src/main/res/values-zh/strings.xml create mode 100644 scripts/design_reference_e2e.py create mode 100644 scripts/extract_reference_emoji.py create mode 100644 scripts/reference_phone_capture.py create mode 100644 scripts/reference_visual_review.py diff --git a/.gitignore b/.gitignore index c70d5c04..cb57c6cf 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,8 @@ artifacts/ !app/src/main/assets/emoji/ !app/src/main/assets/emoji/fluent/ !app/src/main/assets/emoji/fluent/*.png +!app/src/main/assets/emoji/reference/ +!app/src/main/assets/emoji/reference/*.png # Optional local test evidence (the canonical evidence in docs is curated) .local/ diff --git a/app/src/main/assets/emoji/reference/1f600.png b/app/src/main/assets/emoji/reference/1f600.png new file mode 100644 index 0000000000000000000000000000000000000000..ee94eef4fb5a6f6c8ea102a98ff1e8726a99d785 GIT binary patch literal 10659 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 JPDHLkV1k3jNX`HN literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f601.png b/app/src/main/assets/emoji/reference/1f601.png new file mode 100644 index 0000000000000000000000000000000000000000..e99b87e77da950e7cd2d55b79d876407519ed4a1 GIT binary patch literal 10563 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 Rd7S_N002ovPDHLkV1gukTR{K- literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f602.png b/app/src/main/assets/emoji/reference/1f602.png new file mode 100644 index 0000000000000000000000000000000000000000..7cec94e673a685bfd66e8d84f925ee2577a96e0a GIT binary patch literal 11035 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 V04`r@!VCZa002ovPDHLkV1oO=MAZNQ literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f603.png b/app/src/main/assets/emoji/reference/1f603.png new file mode 100644 index 0000000000000000000000000000000000000000..ef06a2ccb07aae2cec6d0f85e53a87d01772040c GIT binary patch literal 10909 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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f604.png b/app/src/main/assets/emoji/reference/1f604.png new file mode 100644 index 0000000000000000000000000000000000000000..60c923228c6c3e4d279ca2c26ba89984431adc54 GIT binary patch literal 10490 zcmV4Tx0C=2ZU|>AK00b-s3=Fw>B}GB*P6`o`Q3~u27#M*N3=)%z3m9+%psH`z zAZjn`;!%eSaHgadCj;pZK&(;(v>a%p2#_t34q|UNx(bk&!}F0?^E2m*q1g$=>CHRRFD10I*Ye0apBeVfV040GhR7UiYAhW?V=+K7mV|&Uh}NT~BuGV&l1RCG z##G=cFrF%=d-olG?l*bJy(ItrZ=Cq|3(zM&eAnsvx?k;@t-I6g6sEa|4O({4)BToM{Lr+i-<{^ik?tgwUSuFMO05}|1*igsWQ1T0$qLCR7{wZc2#5&A zm<%ZS-wDB5i-<)rh*%O?$*KyfB`phdGA8IUt?b3c_Ma_=mp)lu^P7*$0XF_d0IJG} zhd%P|3%dWGYIABm&WlAIw~Pzx#`&b|!9mmOGA zQba6999gs-hyVsqI#Gf#gyac~=wykc2N^~_vUvWtJ|cI$bnf42K=sKZYhClJAK2J# zKhSMHO_)4KW#<%LDGKnW!w?`P0IYLh42T8eGN`?Dsu9F_l9>L}QwGu+tn|Q%0Srn$ ziwI!*-z6xNC;>%C>Itc$i+gFp5eUV-`@)w#Byaxc!{0YRzx;9hZU5kvT@zJ&{pi2A z=k&?1{A|4V*DSa#s-ne6z?mL55yU9QWGTb;Ac#SY?WHyANyKESlbvhYp9Rd$&t%|@ z%MvX@>ZKXe>s=Be+5=w@Qc0&n8eO99_90T-dyvolw{puLJoDWL^n>d8ZP^7-HyFt> z)2{(D{qp*S2jBd^ojvi`U4H&FtAh<(+Q5600TiEgpjeD?sL}qR`?D29%&soHynSsC zsP;hifZ7b`uAwr5O8*%BbrHd+=~X~~9ftxzl&BSTT&0T#Fmd>=2l4dpkCuM-K{@=L ztAX!m%jWCC>{RsI_rNs<6XvBXpm;)r=zrb+wocK)HY8{hvs zBHx+8a^E(XfBxaSj?ZrRT=V>&Qq<3}wmQf9j=2Vm@fa1X8jRT9P#BVcF+1Blp~k*k z!o(mdyRZ3*A5jEF5Dbc3Hb7aQp#43@6*EobT@e>gq%mkhe&ER{0~S7U6} zi4ql$%V6%luPg~79YTi?u-e-iwTL=IP5+?%{a08#k|Ol#w7*9b3<;8AQ$iGkl)-$N zdgxUO2DI1LMoA`uRcsM)MML4XDcz+JEPnWm`JMNFPb5_D`;qn2{+Eu|rynAme}w%@ z0V~@iZ5WS-AWCW@rmX11fi+kY5fc%UG72Jq2Pr@ti0`+qW~sD_NiNje~PLqb~;yOMd_&#FB1rsBq{cdNc-3DplC z88P^|e<&MIGe7wVdj?8uCMbro8q&0Z6ctkypxM}T27-731EP*0Ekay`G=yX!3M7*S zQgUF(OGpDm*F%BM#>w={&2YLg?BVu87%3HAA#Zgb?x0g9?*LK@+aQcIKYt**(8@ zHO$qwWaagbj;x*8Y<_R^)T4}L3l}G-EwSDr0)_L?Hn^olCX*@E;$A`;b7@lX)YE5q z^696T)eaFuRl>f#1K#%L*Ri~~KpARO5{5(!9k%ExP&Ijrs?E}uW6)j(47h^SDrySa z3Haebx-jA|{_<&_diE=9%w|mHHOotTx%Tire*7oi#%KY;e4F8T0n#>_0&O#+Tw2B3 z4m8puYr<`gXlb?O;$&>%Pp86t(t2s{Rbj~tbT0~NZ zlLjMmqO+vYLC#JGJpF?3$M-+M@iPs6yq9U$(Ge)U66V_!n)uPT-N@hnPwt?wXK~E& zJ~5qcG8_&`>arEbVFi$Ih5j`pJZ7*!qXsp5_=^Y6@X1fy&-n`-#bBABkknJ!MJ`=D z&v@AJcYg9H|HVK2+h9(iauz8S+#+;JJ)2T3lyqT+k&-YQGi&!#2lq)GKk{4a2fj6Z zYQHI%U-*&rW8IH_;?hfhzPM_(8Ee2B!B!4TK%@gYjDcCKI6GhB^ADcqzRw@$?A9`^ z9H6y(h~*No7!vFVQ?4=?9_H~UzrtUC>0#b*%dM1!fz&YYCE_fq3B)24h#G{r%TA#l zah^+)MDpu=>eG+#e|+LE5OWP}vx?{{m_qie7Oy3CjwhaYibo%PnA>lEJ)`|g z#Mu_cc<2JI@=#b(Xh94{Gm|yfh1=S0W&5Ka{iFL{6$uRw{__t!{?h6HF&=+_^`gPI zEyKcK77f#GgW(`M=B<`&g*E=q`;PP2i?B5vQ;rT2Q^BOINvpCub9#LIifn8Lnr<&A&JOus{@2eF!d_ydh;=#r z5fh>*ORFlx04YF#?TO*ufAb(uKR3a+g9KfqjY3mzu)XmD?d%xSOHZ*l-efj=i4dl= zop9k|B!<2Gi~spP+Ikgig$Sf(j?U)@2BU(c2507YzlkyP^+7mr)2rY%9oV;Z`nk2L zIm1Be?38;$G8Q^;W`Wc>=FN~ZTPytA2QNTz1m_PjuPshH(&QP2%@e%sNXxr!A9BZ9 z$00w#%r4?3(P?6|yw1k zg;@>SL23}0Q`#*GvxyDkqu;rekK?rqFMN?jX)$efjno<(Q_eVxDcmUR~Fj1(e4mN>QL`IrCZAx>_dz?bXHrC{vW`0|ryc+cP2 zk4q7w9!c3JPm&1@O<**UlIN+%&#<-S7_P2RN5_0N!RbZ*)A!!NkG5?Z&jQ6@OzFq`>F1y1C+@zRuG@lUo@v^Cg(H3n-syv*rz?Wn#B zFQ56w+0}0-p(n%IuSzp#Cnn2(EKONoopASE*E1?ELfXKUjy5=so!O){mO3R!0?CrUNVDQ z8_NqXo@L+{G11UWwkUOrx7@zQ-+RyPTz@FCf2rfT>sPsc-Ez%7^OoO-PI)3}T>)-a4*MIeoZ=Fr1M@>i=EpXxx z)f~N9p-po_m{1NqAs6TJP-WfsZ{tSq%GE+?F9Fdl5PvNYqS z>)`PIhLTHk+ou>79m@*^UFtASKqJI}+1>In=Zlg93=3mN;Tv3-vN{YbmX|pC`Xzig z1}7F$0UJ*-)N@>aV9t;K&^pyfAoMXkj>t;R?Rkpy zGIEKe(Vn)df@YSkHa>r zMU9sY3fo{SM{+HunuCYQJki7gEmqj9D^6WBSd&;^oUv~;k=jj4tE4Vc6cwE&C<$-2jvg6q&-HFMpHd7IrA17QDLR}H+7v(?29I|_(#T}% z6l*JM44uIl%WCE5wl7eX7As1lfuM<$3|<{$V;NSkc;Fm{O)9&DF&$}kj^Ut$E@r+2 z*Hd?jYKPF^MOhvcOy*~~aXqJ*7Z(P2$g#c#C78(P9FJLOg!g{??xNsoXMn#L6!t2atI9(MC7 zUJ@p>I25BEjfT`J7E3p48Mp$Qz*~60r-Yc1)++xY98gl+^VM)kxdcnT@lF zm=d#D&BD?$ZQGJix-Mc}h2qgIULZ=GdM9uys^~N zNtWpB@X1C5Q!-; z7+0Xeyq*vx11i2ES^CQ3pAxVpe^*khCUOek zY5_IlwW!m~asx>v>psn!CupY9x@JnyfGr(^@qoIXBE=+w849cxSNLbrr-^NEX!=4g zgoMcyo$R~>bNO#}&U!g_x04+~U%~6^^HA0n;5|y2`DvqA3n9)atk6z6d^tcvgH!{O z2&T>d8w#HjgQ6sjNa}e6Ricq)Rs7d0@O?!)rrp#cIat2eA5c}-70eo4I=#Z4( zUNdn_<`u+u`O;hYOv9P zb)c3=01{ENsB}$>Eew?(kXWQ`_A~aYq~z#Q#M$CypzLh_)SnH8v?GbSqZ=>lG_bqd z`Eo{Czcvz4ldtc5elDp%Vnj^d1$Yaoh15}+1hWW?A#GrmYDn8)ea`jMLTnHQNHUnH zB$F^Giju&y@!nOry7V7K0a^l@w@z_^_ZC`^>$c;+pFN zcmDV_Se=8;vqxb1ikGNhQ%^i8lCru>hT^ILU663%QW7)?qCImSH5Y*N6&~6pj4#k2 zI9Xs^E@7II3nzy#0tOydJj7v(2O@26MLkM~^hj8`S4QOuw6r$>a>ad-uP-TymJXakHGnP^XCA;P z8Y8Gs7)KXDJBxLO6a&r~FlDZ$n>XxTUZ5}+zz%r$Up@7{qwjzHJtS@=p=`N))0_aTQ3$v?F zfmlxzgFy+grLYc(hSX)H9ks&`tNi4#W@ROUo@1fh58aTH_Z{c-=T7ZLHam{KroKkA zH#SD|%d

j+#>*hCq^p(JQah|2rW`a=oXTuZgA&36mliNAd-Ao9`dGihb<@q(qbx zTz7aC^b$r|jEw}HBS!JA$lQS%QW7NDT*)p5oAm5Asw8=3K)q|l4T(}9(vecgx-)?W z#kk%QswH)S6l>f<%{A*KC!TJos92;T&V-a&tXQ10InGWIC$_Kok}E8>d3h8hVRt`g zAZ6DzOkbrXRPs$blAUYC1XZD#7>q6GV%{O+vSJcWV@Bs#zvf1;b5e@Aaz!;)TdQVY zl$~5wB1Hk~@WgXhA1SqAX3Hh!TW1;ClxZ^zDa4!tak=JlTF)5_hKNSe{1k7v^$_Qu zQJU$TK*zXT#F~n(>p(loqW`*-b|q9^fv1t(k{j8*M{?!p<*TZgmj$8O4HH$6Ko=U4 zf|ms}whXN$X=JN8Pcg2k_HR)fn1QQNRWyO6z)?a-`K?$brj!eUH5W^k5>8${+tksP z3wx=fp-oCcbEFiskHD0u3A5AsVgqU~uzuK6`NZDw0!!rpCozYoVTQzjb`9EfNDA2A zHo4s+;ROo7p?JOgyZp0a`%3vM&tHAb30M()=_soLZxsiGIK>%QSy-V?+Z=ww0xWET zoe=3j8;mAM1q8nvYF_qr`_MS`%+1wF=*Dby?I@ei6?6(#GLSp5a|i(`a%?zy}1afzrCuyZVJ_R4zCCVy^1(@q4I z0WE314GEpRI9)B{JzY6KvDoDL7&&Kj+oZ%M5}Sw@&{We+&mzMqZ+hE)e0c$H8!GE@ zDG+88w5u5v1%sZ5-jOcTZ)T_V3h7j=C=Tfl-M#LJc#Zh}Z2Pl8ajF;;YhYMa%%@ZK zEv=wk&Bo+B!;wMD39IV``(M8o+>E3RR&w<|DS|d2O|I9XZ#q#&q@rU8ZsWzP22_6G zQ|CBbJTP@7PDd1-r<-@Qp`j+C-cm?~nS-et3dv0Y$;i+OwDbGIB8hu~2>2~VPsNFhoo8GIwU+oJ>q={gpC0rLh+ zWTC7GvIT?V9R1-vV9t?rhBIK3%iBCTkQvx*kdCgYDWbuJl383r7Y=hWJbd+l0#JY9 z3rmNtBPI{QW3gH6eL>SHp;bHug?I=Nk`U4qM(23r5A7kEODHwYE2MxG!K6f}=L}1W zHvvb)O2kOS_UVp%C|)B@vh=yHlIBeM+1*w}bA=RJA_a+o!bpJFP`KRhRO@;69+_~< zTPkpy2$^fhmCrj>&Iu$NP3bG7V+6G;XyX3$qo4XV0e%1PzO=S>_?hiFBq?ZOW`klU zq}CETMG*pqrc0Ov5?k<>xaH1$4A&wutZB8z79I^kAteKA@M%U#Lm_iY=_pKxvkk`N z=+uiapkb(UD(Ubh<_5+|N|8-l8X>36q zawAnciC9XER5YE^wTcFT=&=HUi`b=2-u%uLW<14UDKKqj42H`%JIY%-ffp!&LL-GL zg({UA3JhK~7jcmAn(+NSPRZ6>1&_mNZlUo>`oD)l6^}B+;*&*;velenuy@K0Z!B3k zQp4yhxXH`nR+ZG}04+&v?g7Bi0=4moTkV#&p8lpaqTje!Y<1s0wY{qN=n_z*-`S;gYIPe(br4y_!v`AMoqNGZRibz4g*pB3Cy0W1jbTnl` zZ0_JNJ(*&Rp*KKA8Tr%$Q-Ctp~*`F7@ZfVzr#-QvBcjR7N$ zwh4qTVQfhoAj}g4p_LXLO~F6IJOADh%C)Dd%|p22G~RDxO}6G%B)dFD`(lEKn9v`o zm)KlrU?lsUX2+uMdIh<$%=UkyZpyrTiTU_(-u?48!nJ3BW55<}vB)Z-kA74VNX%SC z6l~07vf}7;NS*ev<}dvU2mavXtJei`?{B^PFaPS~rQa8M|O?VMwZnnOxw2pZ6!6xQb; zxbCR^fJt#Jap|oOAAIZk-ukVMG5XfJkJ)3WP3_ zqM;CnFBhoWmU1+r?P}_cXBn?9a_vtZ=9-&FJp1qlC!V~Bk9#T70O>5T^LVWox(e?H zOuB7E@&pHC%x*(n>LM|U?+)y#zY);sAwd(Y4O`D4$0qPTdR za=O7#I-Inqo8x@MIR`OOs;3-OG$w+J6h*=pf|C-Ghgd)wlg>NNyijxUi5c^go?)}f zAnn7<7U^1HFenHbkl@I%l*bwaCK2tN?Rbv3IAvCzW#6t zn}oDQvJqE!QV@s*t|%c)P#cNF-45m$0(3%cme?+iVAkHuf$_%<%Pp^BC!MM;i^v9h z4n6bMYv;f5P}_ZYYf|HFi7|7cB!rd{gEfX2Els1C!sc>7$s}bfQz9+S3BDL&{D6Z8 zRylabwQve9JUiv$u@~tsjd0zNS!^?@n$CDKNsD%Lq938Ae?MII#6bdG5pU{`Kp-(vG2x%uh_ zYF%A7^1uDVqc5G<{MfO_A3eI*Oc=`?F;iTcQfY&A1~qvkMr8#f9aa+RX1Jopl=&+| zbU42kOnJE{ekY#p79m!!H7Cv*ruCE!h0owtAkRq-a z^bq4W* z_!i@{b?%ecpha%~R>}UN>D?t8`>bB1SK_(2cBjd~7;p}3Nvb1lY7jdklkmBs#n^$eH}3zgPjt|Cz2I5@$aP=3;|)*8lP|K= z)GWC`jF*VEB@PSP)KFQlro)&Cq&cM*24#id>0-bSENT;KIwZ%G7$=tp8SD&UF?}z+ zF+FjS!^D(!Cf@8!-0AP{0&Uk)6n%ZCOJEH#6trC=5%C60in;JtEe%7q%nHrmdWy9- zoxA1-e(y~(y1do(eqEEhNMojRPu)4hR)j7QyNCusgN0y8L5QsqyFf|-O)V+bq}YpS|$n^UHSg5_?L=NQAcCKn5+* z%y1^+z2YQ+hU}cXgmHQM=474b$jAuRN+y7$&+GKj50>4LLrD_3S|-zMJ89`Wrme5( z6T6$LNhv4b^6x>D#h4+J#xhR}nAIC8_usOyZ}qA7$SuG5!1sKJ%Py#2{L^**;N!z5 ze&B7N-9CQmI={Wmk|s(MP&*@;%!Z>ah8E*Gj0CLha6U&tSVbiD^X)WO72Ak2ib!^8 z#Ddz?7u{-~k59eY%%Q3F_4io?7($n8QngR3DiD$oqRoxIwITSuRC`~?+P*{g5BEL% zD{|v^K56Vb9@VD*>>saj>wE6H`0VrVe*V(t`jj*gC7);%u zvBCD+-rImkjnZOWKx~V+h?=ekHP0%^17E^r=1KAhOc6yiGwQiMKBu*f>F40>RO*Q( zipyM561pf^r@IktvBa!gV)5G7Z!C{4{dcQ({x`qRtGHg>>5LD)@DBd3PoJCaU;CM7 z=Jjv-xl)2Nc4VYqpnv!`i%(TLc*BGzAjw9oXzsT_ay^kk9bwd8Zt2=7=yD~pipG@!O z?76pYKKAIX&(6;MOnqsSG6pJ9h9m|866RR4PL*ClrT012CXlWl*s8m8M3I!saQfkb zft*TKo6B`tjfAKK6h9cU)dZU4s8$ZJa`3v1!~V=KvUlZ0KJg0=%Wr>oW;TCUC*0}- z=WgX}y>If|7mvO;mVerwxrm=P45Bg+&28Kyl0?)5qS@*8h!`SP!)_ykL3jPmB$+Rb zL=s9A=rp%6S?7pV!KI{>Yx~$UuI@b$Uit`omtT~-e&t2J%jl8ONV(w0%pM%}Gs% zNwF_*O_ys&B;^RHpBw526?WjeqU-M4zrFdd_dNU97r0@0#w`cn$&C&9;BRbvKc4OT zHpl*J06uVXjrI0sJZltb#8fwcm)8-+W=7#4byK$D22YnaP;l)nHO96%=I0wt=HCT>sws^KkbX!kfevQ6#xJL07*qoM6N<$f-cG(xc~qF literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f605.png b/app/src/main/assets/emoji/reference/1f605.png new file mode 100644 index 0000000000000000000000000000000000000000..bff9745f7578cb549c300a995a7b8a8780a09976 GIT binary patch literal 10872 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 t*_##UjVF literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f609.png b/app/src/main/assets/emoji/reference/1f609.png new file mode 100644 index 0000000000000000000000000000000000000000..ece3de3b1d126b21924befa76b585c81d54a4319 GIT binary patch literal 11148 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 ey70ICv;Dse;Sy`P28d$-0000xrVL) literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f60a.png b/app/src/main/assets/emoji/reference/1f60a.png new file mode 100644 index 0000000000000000000000000000000000000000..a4a09efdf3137609d2568161dca66067f4a52a6a GIT binary patch literal 10446 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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f60c.png b/app/src/main/assets/emoji/reference/1f60c.png new file mode 100644 index 0000000000000000000000000000000000000000..37874aa038fb1039c17993176f808877997bf651 GIT binary patch literal 10689 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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f60d.png b/app/src/main/assets/emoji/reference/1f60d.png new file mode 100644 index 0000000000000000000000000000000000000000..40de8e5f1660d39f3000403febe1ed9d2be0a25b GIT binary patch literal 11037 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�!38&R21unT&#myb6b$tjZO; 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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f60e.png b/app/src/main/assets/emoji/reference/1f60e.png new file mode 100644 index 0000000000000000000000000000000000000000..1241532d7ee543c3dd42034ba4907320e1479aee GIT binary patch literal 11208 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 JPDHLkV1m#*XIuaP literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f615.png b/app/src/main/assets/emoji/reference/1f615.png new file mode 100644 index 0000000000000000000000000000000000000000..c8633b933e5b36888442a9aac59da9271d18ca31 GIT binary patch literal 10007 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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f61a.png b/app/src/main/assets/emoji/reference/1f61a.png new file mode 100644 index 0000000000000000000000000000000000000000..1ede2e03d103f8af78bc418b21f7b2638571dc9d GIT binary patch literal 10936 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

F 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 Z{{q8(Qi%aOE$aXP002ovPDHLkV1gl12zCGf literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f61d.png b/app/src/main/assets/emoji/reference/1f61d.png new file mode 100644 index 0000000000000000000000000000000000000000..bcf151ca1de1c5eb2631f001386c55fa2c112355 GIT binary patch literal 10305 zcmV-HD8AQ;P)4Tx0C=2ZU|>AK00b-s3=Fw>B}GB*P6`o`Q3~u27#M*N3=)%z3m9+%psH`z zAZjn`;!%eSaHgadCj;pZK&(;(v>a%p2#_t34q8<|YwvT;ef49yr{{s0!3;ov1OWmZK1D$g2|gex zCT)qSSSd46%C1B%TT-R0N}LCkL`f-PIhI|K?KoADToPl;lq^QJ#E3LW5E4iVpacRW z2pSNG7XfkxnD_K__r3Q#_TDRh>~njDQfx~DfK(hD)Ts;H+qZAuwb$cY-}?3jymGyA zy>h*By>h*By>h*By>h*By>h*By>fl)CEv*px5pX(u_sS~+{yG6gZ_z(_aoQ9>u#wT zAB)LvMBIiTMMB1kO#!@Fmn5Fu_Tj8AE9!_89ANic_!}X8|OlV*MZD07XOyQs71_1Q{SAXA28o9Qx*qOSbcY93uHPQILWz6(n_-29gTqm83%w%S2hB@GFm2HvPz+_ER5`;;y z20D#IfgmNVj0m<&)cr*E0@eM)F#YIy_Xi)BxBinS|G#a}hyLyd&c@L{ot}G`G<%*= z*-;h_Qp0#?Ktx1PF+>beLvWao4T^$Z_DaNI>TnWKIuHXXK}!&isgOkJ#4|S|%80}g zkv$muD9k>wkuH6d?lPpZ81WY4Q6HyaMJRuE; zHo?*=W_uv*Az}ARvGw73_29inuKV_S?Vrk^)6e}cKXkg-_!l~Rn)=)$?5S$TBB-@E z4fqPo1wx9HZh(jbk$mGoC4Zs-&S4^$F7Eugi2#as14J}`@b3E(kVpdR9nl1%z>+7W z5=#|WK_kmd{XT-)NA`7}{U3)nefx~+|3seo+ebH;{EhdXkmX;tGY`^i|10(_%_wb- zvms6kP$30FNL0>468hK%)qI;~YpQ@~UQLngz5S1)U?L=igaLiJ=<{w)9S%%Ubzp!? z;9ATYED12DtD>Kp&dGux;BMsx0A zhUpZm;|`S;Rl~eu&LeodcoYHY*GYZ87hbB8!&?NLUGZG%9|c@?=BNqOQ1xJnX@*pb zJezZ|_THbp{PK6GXv2ucR%p{2!G;g3JpWVI-1xyyd`Cmxp8ng%>lfDk<_qV(`2oB5 z5X=5FD^-h11HQtXl6=mCBJK)<=3FSwVd8p2^dF_}veycrcG;L$7}Q+13#m{CmVZ|+ zV*T$_mwi|T5!o$vn8QLvNCW0n)V4;)>XS|{eCW`zpZxH5#Gv;0&)@#S+4cM8XCA~Z zJ;4$eS*qp?D$9kz6__g!8z4^mP)vwMlA|}YAfkP!<}aVI=E5NPb)+{)Zx~U%!pN>K zT5`ps^!b+EysN4?U#LKGU2Ncmp1Lk`>mh6=I~Ga! zep@`$e(jD!{Jd+paB7H7)lJTjF*&W1oQv&oxSLt8xfJnj! zC`}kM?+(y)drz+NwI80`@U!>7ydHY|mK9DN|KT$ypFF0`2}W{}NfB_8Fv|r(y#q6_ z1Y$TW!^K6&q6mtn5|;`zIV3qGI>bC`ikRe;OqTD3s~Wk~FWi?yh2DN*CaD(Zqk3V&ipT2bVIYtu! z*P?OGfWVRtsPKp-tcXyy;A_x?CUB;>q?j2ILGg%HkbDkb`Y&#_KohyTO8`QC)D~z# z1Cb7+1L-hoOdF5}(|~EhH0R!oWx<@0iViDULebI{M$p`eOzwz-?nX{Lzcu z|Mr((J`Y{{i+63+8~xbQ^Fd2+Wv7-9jnOnA7Y`Ab|G z(y90A{ub+9vS*vJ*Y%a(3?=_Av0QA#`dq9LlSBfdC{dK;1e1um2);#KL?rf=-{)>i zJUB&NWawv9dba4o@(1IyKYiy*YEXOJ3IOKyd(S_9-|BGt88*r}BL$U$gzs}(uHyN- z7hn}e)vrkc4Pf1(nE{JHmv0H62_%BX%a0^5!SI-sx$7|x$swJhokyAyYbs*ri2-7a zbSco02nmuIDMc)`SZa~jp()@k;xWVqAS045iG?E-5iO>S{TU{5cH>fa?1T3BkKFi@ z8B}hP&hGg?Z`?ey{Q=!M#n`s--4@;&gxF^?PeMrxOxVMp-DI}wUAkL=kzDn!K->Le z4{tKIf>a>M<+N;uSt6y77sO&-t0)=!CqqKOr4APY5<|Z>x|^pnDsZSJG^O3{EQyi? zl8cD8c&#b*5~h0BS^wRC@uh7&<@~YJC!fLBJ1k8cjt;Lgya-B>JyIM=Lho@2q3vn5 z9^!})aU`vJK;9yfFmi>?k=+-ZB>AIFum!}ifLTJc!?YtxL?}^FNCE8xETOT^@0SQ# zK~&5Yn5zgXi1TC~tLfRQ08$_%L@Yxr098~C=eDTRc%jrQC^rI14o~e%v5I_4#WjH_5EY^banYAUW|UGN)~Ppsa=VSYnPdYc zLo7n-Z!@qQ%2=153lRd)B?uja8bUxqLV}{vX9LGY+DQ-tq%Qw^iioA%u1sCR`5kb2 z`}l?b?D$LLp|||!cb)&*%f}4u10P!Ec37s zF>^U>35fJLJm;4F_XJ$AMZpl#-tPhKe$gI!K5YEL{Or?=i;hAA+I6{xkg2fTIxa#d zf3uud)C5Z&(E>5);aS_mxjw2?FpD|&+hTEi-}<+Bo#AMX zNA~{^$B#Y?SD#CD>-4iMml3rFA>p+*% z6R-^acfC>~LIV;qwoD)?=enFbBUqOWmb%`?LW+i2HhxM8Bj!gl%#;)gVw}*0y>xLO zZMUDgJ4ln(Y2$K64}E5k1TGpHuJClrU7DIv&{DWfVj6sa=It-4d-AT`rl83=#z~*m z5-lyG;Q$M>ocIS7+A4{4cETEe?-xJA6VGk2vVMTKzUgM(dB;%>tTs4KBi16$_bhuy zj9rfwN-R3W4&#PP5(D&ZkEVxX}-F?VGvY09OrR5UWHd51Fo8k_S)5`?=C}1 z5t13DFKFu-L$5hS#t1T`iDQ2A|9+6io@}tuYnZXYr|v(+7an|s_uTO+-tm@e*;rXe zEYQp^FqmzDQy~r>N<4O{oCQ7!5 zY|;72p%>+$MeNW8#kQD8nouQ2mjZaf`td`po@p$2?CFzexj~R6HZKW-@j$=~5p_Z}ypDhVu?P7Vzx@T0E;9`S+-NU@;h2lt4MRp0X-o_*d!zO+$x?O-?OR~A z9uq6h0#4?5wwb%VuYXYnt$G?w7E5P}5Qtr%7*(16vV@a@m=Z?E@i)Gf=kGbm_Ra;Q z+#qxn#xjH99=5y4r#}AzpS$l%yz`D5`R?0q;LtUD!7ebJou@FPjBSpF)U!mUkbJ+G zJ$ce}NI9fygcO&FEOYn0kMX;oznc?h0@dVNX0=ibC!j_O4HkB2FSV@i1q}gn5wj+f zmt7Od8S((19V(}bg=p*U{$GQL`Ul`llWJc&#=V0nI?31I>AI8m&PRD~n5#T{=x z!ZS~w<||)2!?fv`##KxTx^~E9JSNBrbCgftcZ$#4|0r*M;}O39UAJ&>?_pwhkw8nK zeSz2|m3@!5^N2*s5=#@dr^`I>mFM}`r+;Q%$midStB4Cm-Dj?)$C4pc>ac}7k{LJm}-`{<8IW+Z{GUZW)S-`2H z-sqZ!q8fuQ>Dn#IVaXs)*)vG|_+Ne(4}JAKzyIYEeCg3|(CLKOPS~~@Ukq_>iLxBC zRPN=WN6zrouY8Q}yYpt=_kFh!<}ct~hgjFM^RmmpV@5E?=FIroGcWL~zy2}KoG)=p z*J8zxSuiGhmNIEvZxh-bMt;VjRk-uL-^KBp53sUS<3iV$_>dhVmU;19E_N2dG-N>q z2`Eq;Ml;^h^|xFt$oC{8i9;kI0x9JdQ!HT?NwGswv{!^wE)nV-q}k$)M<*P=?s^`3 z!y5NI@Dz_c@eJGbI&ORbsxi!k%`M0J=rA!>0t5@I4 zhYodl(3L`{QAQmGv7X^wrtd-j$ zcwCXf9PkW>71{)%%~;zzCNT%*sB{_orc65LrZi%y;n4bkaOrup8_`-v;}U*c5JF;k zc^PdI&pf-yKl^8&=bdkR6>q=eI^cO)J4HDNm^oZ1Ar`$5qNfCV{x(Z8q-XLKkroRz zq{L_tpJnH{*;N^Ix4I`o>BqeWWig^{@}yM?MXQn&BPn{MT%%(jPk*!HQ}^7*0}r3V z^bq(}+Gvc&BV3^%9Yxj9?VOCk5v(&G`6d9_A09dYret?J&0;KS-B0sW5y>nQJh5 zVmn=?{!*TO^|Jw-rc98VA(8f~Jyb-HWV`H;Y3`2&MPk5JffQ>b4TwoeHez!+;g^5q zbA0v5nt5D9tLx}QsGFLlJ!?oz#I0>c)tst0!_CK6_T_^t&Ojpxc0G;978l z0yJVFLK_h`qHZfbcmEUo;nxF=9U&AGnvf`mFdhn}--bA4xoWxjReQMeo$uh-QHR)R zmIg{8BkFUT465bcprNPd7IdDcAfc{hxK^;ab&S*e2cKqZwgZC- z=Srq?!|4*mU>{qvIbZqeDfaLA2FKoaElIXe@jYSE6Dz3)qiKOfV~kkpI-fBaf^Q)?aBeDQ4EISN|>KRJ#mW z$|IM|`^p%Oj^MfJpWdLhP;D3~^~&PKh&GYuG-U}*q$?t$q38PR5AghjhK6m1g;1nT z+O19AaLWPSbn8)$>?;`BdDfO4gUax(K)rxhTxel_DTm%-kS7aBBN&Eg?%u-13yel% z7?gzR7EAkwT$*3x``&hhJHPifKJ)oUdH9jjoWJl4Ue<7B2~4^1HEW1$YC3)DBYNPHpdr=D@u|zeGUVtdT?K6`Jx4! zC~6MBvJN{n%v-#bV8WP=qDt(fZ}R8AcOQS@U9aQ*`@hCR4?NA8GiNxscgXwR{TFby zjal4f@fS|BV7e8<;$qYsc5|wky|@vGnIM*{oy3HxkxaAtf`CaR1*0g2P%6{ec@D0v z^I!b6_i_4cOHp~2M#5xRW9DnJ-2XS^CCyDUm>RRIGQW^_iQLx zs7#DqfS*U%J*^kh0`PQKU6k4`F)TGxXijme#25+DP@hOzgHsX%XoO)g!RpAW+h+Bk zN32CS-(g58NQzlWozm{sp0GHX%`VuPfAm~tmp4x(Sm8p@Ts4I?y_A*iVj?b5YNg@S4rQ6q?D#TN0AUOgb?wCgSZgH z=75mctJ{c>I=VDO!Vx;H=(?6DMpQ6Y5~JWuzg0qIdWDd_*U2Nhl~@Tm|4JmrhJ?rB z7_0&e>%Cnq;a!$R`s9eI!Nn5d7T5(SVh`vu91`)DK|FGK)Z8mmOq67rNg}O?AzrKR=8$L@p%~+SO+$bl>HV z=@oVWQWZH*OhAVt7?p?=Sl#70&sK}IT@hsyiycxFNLixgD8Fy9&!PeKtJqRkYFg#e z)^xsl;zynPBBh^SA&I14h=qasknckyS9K+s5k)`;#JGL+25p0(g(t=qBT|?rCh%S% z2)LBNuDD(r0?|1-Rgzo6aqPpq?t62q=2+G21V{0IM8~ODMBbIs<+S@;(f`b-e=Pb+ zF~%r%-HH=GRv7@pT{Ez|yHKwX$zBQZ z;=e`ZuUzh@?TUrSO38u}Xc^G~n}D9Cj_&qkH8Hk%k6ABT`_`*hk4PjX%jy!9T`^qc z?8%9pyXswdUbG~IIjM9wHBy4YRT-M}hIOJj--u*=Qc^rZn$DPpt-Hn#KKod$ONTs5 z(>$P!MOKzbr!?e&`>x`+P{5gWLTI5SS?aQ-d>%DZ(kiP;!ZRmVr7Xb+CbML5YGz%c zVUTnaePJ}{9)B(z+8hsxfOp!5cJ6@86le7C$i9U;Fk6hyA!$LW-F;qv?y;*6`FX%O zAxLD})$ASZWj>!%4m?pJNu<{^^)f{(&|r)MXdQX{559EEJsC?bw|bGDrxcfqpb9BP#4-fM97zTwO$4211xV-c-czS7(%=R5 zz3MD~<*&Ud7t=aIl|>e@-+`h@F4K6u*w-TXvSQjMC@Z8Kv80#ozS;_(5%yqA)69{i zl;wcwbWZ8AwA)hl$Pn{h0+Pd`B9e%+hM_oazGj6lcF!O)N5MJ)N8E-fJntW4X|PlZP%mvo1piDwt*Az>m z+|-B>V%{n!Q8GKDSx)1nz`~sBU}Sl3M?5p2*;a;?5>rb%eIBny;RJDp5HX9r)Y}-1 z3%vJupPMQ}2q6$cq78w0H%CbnF5noFk|*Hll3>wO7$i$nen3m$#+#R*I+fLUy;>y8 zhsw-TxP=0{$HB>RZ_(|Ld`V;LXt8gzt)D#eq71tCrdLlNKl$W%6-e`d_THJ*9F8Dh zDWXY9$+C)A4Dp^sKsd$CuV3ep&rB&DNT?YW5$_^{(ijX&%F<`iMhe;cNTd{T8cFg(wLl zQ7nLcUz|cpw9ylXhZ(c;bCb#c@!~vmW9`HbKXJ{qAD@2xY0BvEIII!brqJUm^S@RzLfVvncEdMq(zt1x16Fz z3LQa98d;(!*B)K*|HCiJO>Dj>gYsQZeP!*;_pqQKPa}Hf-4zgSe&`f0XQb)tn zq|Buk3o-71UMKJA81d}0J6Ly))r04_ct0G1FPG2l!EXgJzn`Av8?` zoe|Rxx4dbIwS(vI{ygi;B|{=3fw2fn&avzrOI{g?QN@Ihks>9^1XX}4CaPczqA-ZY zN>Q=uN=8~SR7d4%27Vh~UcwJ9vb3*ZuyK*s-%-H+Gmz$3Dtqd00f{1}9VQJf28!7A z%zfUm(wb+k2au&3DBQjGzI2-w-t+2*2hW^jXSzw%Rg{)U7BeQ-zV}Tj^A)CuCFWtq zWU|7Ai`z{6gmU>jx4n6pFMsL;!@&_o!E%L`EM$;m`QQNSJ#Vp_#Iz@^auIR;K`u?( zVd79N(ZXX@imv_>A=0hJn^2WC?_hV*hKpiTg6glcK3azlh>aTG-LlUM={v~*+Ha1wZqXOsYYXsBj94}H)y5&-~Du4E%muN;xr=Gk|f|O zPdOgpMg@blA+j{*rngPt;6>1LL~5W$dTpsnmh?czzLo;S7GlIAbg5t~tdd5@Sgy8z zQm%dJ4t&`)=!N@#Z}U}$cHZgtA7RHWQx{8wVnS`kyl#m>5k`=Pgiw&ufUZ+Q2#5%? zc|#X!s*MhvY!YP?V~*2Y<;~_mjk5-|8nqTp4bo3OMFUA&qI8(nB&m_AqZlbV@Gu!7 z%OhB+U^ruNy}?k*i8ckBgVd1bIO|XikeX~z4LAvibR=yt?Z5?+3j{x>Tz0tS62=ZHf#nk7 zd2~1hcaap%V!p+f{iq{l^@sMJ8DpM@nJFzLGb@>;C2HBnaP3yE+xzqni@Z3P^#5Lz z*qu*z_RL%Eu9`oXeQA64W9PTeurd?c;@|b_Wm-zZ)CpyUWum8y4 zy6ZlA=-7>4wB@~AoGUwB3A%#mn9dwcH0l8Ah7>xaZ4xO8DkV)a%)?|drf^2Grr!yY z3j&MX9v09ZzGTC8pb_D)5@UxYMO_6c(Y7tA zOIYV1IGR?Ob&e^^#PRj)*|YkKa?5}Ho8OirG63X`yY4-D^vKU2y5Y5(!#zisw-tdg z&M(s?C7F;+a9Wb0L!u{!K;5;VL+Vx->{+F({O%?%?RR*P@}@Ak0@$l6uJE|h;VX|0 zOLS18;{kbl-yFg=+tX95?-i)#(9KC*A_XIMsTU^;O&jUjL~Qep#I}JhIJ8`0ymmdh zdgzPe*Z=5`zg$OT{Oiwc`b+Qrtz#d%f8SCUfAHCFoVatg-D1`vv7#sxqalSz8#;zX zMd}*5E-)A@VYR?&Ng5@(w!=v#R(!l-$|yYxt%~y=DI8QD89Lm+<(d6p0F_|%d7ADb z^KgpgYsL^S!a#7&5hU*xvEYzIo@MzlF%>jHsAEAVD^!!~nQXk~l_U19st;(|k^4oJo!$gv3CdYR0}q4pl^U z*t)pQk{?q_mAT4P_M_%3&%r5DLMjc)2vvn>39|@W=h?1L!f1>A*H+*fP@#(*wM04# zSX3+sMJg!5fUfq`e#FI2N!31<_us^U)$&8wFZ}N>brJfbm-{!p`03|9{pqwE~xDd@SDbYcrOJBDcpZbXU^sYFrTNb6h-c6 zLJI>=m$o=#7w`v_eYfpH_6zfLj!ve`W?L*xMtC=3)+A<~1HVKpMog`w+<$~>?cnC& z(dJK4eEn{D{r~!%IjZg7XjHQ?@Bg6<-u>_2{J5r%Prvy*!=`3W<&jV`pKUQ54yfY{ zUnw@LS&k(uZHb+lQa`_i?F6hgigHL&m(L3UoEN-0yh7B-RHkg{l+m@ztlqdmv(nI1 zHChDPZp!LtLS47S&eLecHUnnmfWgK=Rt{csa^GO#ktfMM5_t_y)6%k(5-yAv=*`nuzD;OwVlLn}jo^ zaGs(n=`_)$nD^8UVZPL`{;GXc>qDBNLxvEvC3JI2=V^9Yq!`dj#ncb5jceF*VD;|3 z`%e5E?!hO&Q>Wg(=p%y-3V!bI9)EPtH4p5Zc!6?OGtxwxwh;@Icn0PeCeJXIRGlER z4w(h&OEa4JoM@J1_GQ7++A4#M3GH&r%+Jw*r?HN$b_cB-Wmz(tHJ8yp%` zAJ$3wDF6JgepWvGojqavB{_rHPMp1&!yC_W?*s4P>^5K8JoyXV=H{WYu8~t#E3-G1d0cX43jF24HI=CkACXVcCc+CW#gv>{+l@|jEhIm}KZ?|zAb zS%;rEk{WJMQVq+K*G{MZi0iLC!=BCm-QTb`=9ULpsGstk5`a+ z$*>sZ1CdokGbo_3yp?5VGJ{Q6OC#8U3+0Ti>$vC9P5I4Tx0C=2ZU|>AK00b-s3=Fw>B}GB*P6`o`Q3~u27#M*N3=)%z3m9+%psH`z zAZjn`;!%eSaHgadCj;pZK&(;(v>a%p2#_t34qCoJ#EX5-JswXXm{#d1Z_f7pXYUcz}nk6!R>Dg+W46 zYi>2&>f3$iGwi+BTEF+l+IMIHMlFP6Ct6jz&N=t&d(J-J{ae4``y1ee^}>2#y|7+b zFRT~V3+sjT!g^u7uwGa%tQXc_r6qq^F2sz2^S2)&9w=}ZIxh5YY@KTJ;}a7;Oe_Bf z-3x$zJ1`$$X}SBkP`Y!2BF*U^4Ar`PWK{TT35%s84h?bam zlKO6;>h4zJX{9}>Zu0mbuAO!~xeT9JlM_!Y{|^hOed+dNY52z1Y{dOeZStUJV4lbghDqdG~l(P zaDhT2UO*K@{U`qEZ~vtP)IRz1*PoT|`@-g#PcFIkF-Fx47so7BilzX7ItRrzhyo`0 zxhOaxsUY4+YM2_RL##%m*pbfdt)4-R;1wk0n*#Z>!~sQq-QO5+M1-J9Ya?dq5KTPF zVm$N4g`57j5B#M9)IN9D@uy~g(7(^Jax3DG*Z%}1)6k} zWYq@_hL8Tj;KcLi4Lm16?Fa=Q{%5z{cXt0rIr|yr?F{?thN@@~4J1iOQ4^D4Ca5bY ziVAT)17ikG_ZS^R-1c_1ELf_0fGYB(_J+&0x4N)Lf_p$sv$WEK*$Xhv_mY|jQZa2u zw00Qn7VjR|nO|8t@s1DucLCHsch~V1_hbL;@dxjH>%5&|Xe$idgrORx8mdZiiLPu( zYKS=07pOQ)9f%;ZZEW1dTiQ|vP$OvS!SKD|@+9Z__xtmmqP?}x+kIOcdp#?FRz29B zgph!QfhMN0q-!o?magE6^uTR$;+H=2odT+ta`N~S|LP6r-Ch6oiANuJ>tg!|3*D0p zZG~DIoF-H~P@uRSH%G*PlqHXt^`3-$uze&*2Ie3t#O-bC`b+E$nCV52Wx0Lx~1|K{rsKK96g52odl9CTBLbX3|KTQ!h?(SXc=77>p#k6MYCN32AWN25cM zWOeyXFQ?am<}(P%Wq=XH1WQ0N#K0_OeGEX#yFpT~LULr4@FdIOtZ4)d;6kr59O@%w zF{Uh6Q0-oI_T;~M!*?Cf8;@S-mY;mlM=w0^Ne-665XV3&oR*j?NGcR5;%G>Iiutye zh#FE2X#lZ;ROP=}30CZGY17^yrQKs2T<8JK9G{qN%QSA=IY^1UHZ8kWA$wXjLTo;B z0UE$fGoX(AJucvUpz<9^4`P9;Uw?Zu~65E|^ zlZ}D)AJ&IK-tUT^X#ZSykA4ehUASu+jR-^x!-%B*Iizf`%(AYH5wVoPO9qjw9)k8d zShGJWn!&e(VhENElO2K8Q< zh<$({y}q?Q{%CSwRo>n@MqKLkatTsqXWym%yRx6`4OBPr#X885ng4>KPlqu5eehe;w}By}VdG0WRg0xA);fTW1xa8$^)t0RV3!YuB&W8@!~ zvb!X`8jxgYQd|%;3bF%M4_xfQ%uXew1R+3ZAU2R1NLxLa1;jeLV#z^@`T7z#6P)#a zhJvUfTB6!Aa+^1=v_JeSr{B-g^8%h=5;}e7Ef>yTcx{}nqSmuUBvcHKp<=jgr(La&UNWy~>b`L+ ze@nHp4JNx_n(ZFjKRA2u7rkd@SV~wAlts&+#qA^RzTN?^KR@*EZ6Ccl$@e@V+Tz`m zSRcCM^x0=GrQh^d+v_PN8!vkM?A&7vXeqQqG$P6HW@w5zb@9wk=t+!c3+6M^o;#1d z)L9SO4v0I_Xjl)LrG&+N?0^#!DaKvkwx3@Fb|UQonb>;~20}o!#rZMj>K~uX{>`1= znS{RmEyvGaSbu}ApJC3o6cRCuBuRMH9p6v4!^WNg%JQn2y!f{G*{<p&=Z6 zLtOnbi<&K>NhGO5od@&1?zCNyB=x#5BP)AcATizLElqZOP}wm|wu`vz@@;0;>$9Bs z%>N{NZiMYhvw(=hwmk>ygAD8WRR@-0rUymS2*3W{bWzDK%poNcHYM*2qSls$%CzJ;FM2C9E< z-{k#FknGtA+b%6BgOk!8CqJ`*nHH4(G6Zq?TG6apM0)VWdU`SIQ*|AlF`hBVaOt^8 z=ru>m<+JCHSCTELps2427-ry1Nim_N>@woyNJz0P2|YJVdIsZay{?RDM?J_6u(E@` zN%mjlB6VTUU~qLusI6DV+wyghMEAU@B-!Kp=4%(1cZjIw=vJjCS)}KtjY1m=8dMga zq zZEkwU&DAWirhQT{_RmAU_k!+Pbhj(P61U@M0~|RK6Y;4dr0V!{0yNs2Hb{&RU{0$C`sDZvA$a{^EU^x-w43RNCLs{w}*1ajC;4 zgFeM!W<={lN83(Q_??jOTS?}QWbGIh{RY2O?9Z3xi#~tv-=688Zu_jykVbl^emA<> zdwzbMQpjY1MKlFerfj(R*Ib%}PEOIq@4;g`M2EA4vqX^+!~ouU7clFZ9Rp<9U?ovf z*1Q+5bg>TIHP3t8&^@|xFSxSDQ0?VR(~dEh{wsEO!;W8>QeX67y)8{UdRow&7O}Kr z`SY$wm{?9hWu6dZLX?G@FWD%irbAQ2k&x}&%QviqOAbkj6Ybq21tLn^0Ty$)6wxH7 zb;&;{G9a;lQ4vK@vIO|lqL%u2I`x#F^eRR%@t9R4DpD#*C}@LPij{nw6n-K)I9v8@rQr( z8P?V}dFf48@)LJ`KLcCA%_cYrh%@4N6F0v=oVG|YAjyCx?dQI)t?UpdQFSALBje90je%Zj+Mg)6}o6?8(1 zE^mOcU}df2cmD7boL!k?Fn5SQ{`3=UG%Y`Q*Uh+KlmYPDPJ4rewomIj+61aKS`0vh zwrxm6>S2jXW7=j)Sr75*cDYvMVoP)Hr2ra^3_}Q5Qeqt92#9&Sfs+6lh{@4O!K@fD zi4}kLmB(1zzsUDoe+7 zJx$j(oL^o;?Q-Zk++YZ1ged5&q^K8ZyD{UfExH72lQkGFu@MsL4)dk^H#oHKB)7fn za)yoSA7@t* zAN#~fKJoE;F@r&6-0|0Lfi;*mQ+`qn0ZU%yH{WZ=eY0@()RtL&DfcG+l?&Y^3I@$m?G7 z{rvt%mnqBrtc_=k=8te;BE086e}Stn8*<&T%lMuvj&kV8e)b>T$Li*cdp`9rpT6fL zr_Ur*uA?rLmG!6i^yeSuZ~XP!QC-bW|9A$a=45D!*)0>pl0(cU+?Rp5?}~ zq6?hUIo1aUSoa4wKO3>u)Fhq91e(bz-fc1{H@NvFm!mRaILIVWPEGf6)~Bp3g;I^BVsKY6Sx{i;VOt;o?zGP~S^;XzwJzc7>;0VnOO2 z<|Ews!#7g1PC09P=iO0Q1;LZl(-NUH)JG(YafRl}k2r%AsiOndc(_Azr z9<<10r71=riju5DQ-hb3EBHd{%cKO=2yu;3p?v?1`?&7-Yk2Bh%VSS&a_Z>~9{Kt? zRyW6xgoFF{apceet~fl$iR%t=!;ALQ&CalIG-I~80@~oq0cJ*`$)w3PX@(M$0yWw# zKYqy-%=X@Q|MbVc_Ry~%9baIH3C;)9cc@Qj3BGiw2VV=VH3S!ssz9m=>wP`vE2Q)U z>xi_Vfuc&NL|ilqF+>8yE*B$UKt)g`5D9%jt|Xzb0VP#-vfG$J_uHYY5Q5Pqhq?-* zBE(#=oV*hITvIM{jKB=LqoNZE71Jp`l6R>Gy zFjs*zgxKKwRBs9eQq4h|_SC`WQXQu`mEpu8=6W?FJ@6?Pn^ck|yRZJ#WOeL)8<^Na8RGO5#1m zJ@0<}lF1Q{-Y_1Vp3*HpLP$-n0n$Df)E8nU6?|FKPFmWo!xvDM1sXeuAycX45VpoJ z0AH6dYtTZ_TA*3WRG%wBs-A#}NSfiI5G}XWsDasx*mbBDs4sINS`><6kXv%X7Eu}; zWnY_=Z+M{&+7|Utmp+@{&=5mJoTKzZNIqBN#hCewAvN4mU5;uX=b^tr@H!!&*5x@&cM0+e%JLK zAZ4G2$|W;Km-~}sgx3+Y1*jr!3a;%LK9|$$DL~gz6pHs5yj(t-h~x?vq3>gg0a8bD zpk8n;*Nx&UX!>eC>B;BVfpvKCJK2bs3@u6qv`;*zLI*kV!;jzKw|+Slo*<5p3c6Gg zV?~MuDGCx2x=IAS^*kvKpTmKcY9Oxeel&9M=MP962!fO_O`X@*Q%m>LoVR}{Fqr1goG7Al3I zCsvA;0#${nGHW_g(-2Y%MaWE;n_xDfi@kK_q&{YXcQr+5&OP^n+e7>Bi}f5`Xh|XA zlJx0;oH4K{xT?&?BpPMmNa~0wkb;0qxU!;~%oRN<`l#; zZH1N9j54&_K;Xi*?dAjU552CbN-5$g9rIDPWD1N!7=?pZu` zg0-*y2}^W@w&}Nv(3&FxnvB9CMe1@XOOC=4ep>sTbW}UOEW6HriO#o6~=BOpk3#3Tw))=@=_6;BB4$!s>JEQ(x+yIl;?1tb%wCIz>9qtuH&utAF4)*Bu?=Z5?Yivedd39E2ue&ZEA_O?uuz z+w`7A0uNDhhlpBVX@bx=ShLIM=3mWagXxq>uk-0IKFIQx!>aFN zN+borih{ODjEa3(#Z0$Y7|anmXp>RZC2i=~*cjsr!LdlKBR=)TEx!DfFLC1yBi`_1 zFX!O?iV&Wrj4`LYOU-$(Fw6dEuaZo&w-Pnv7TeHQv6v@n&9rkwe}F+fdc3yJKI;Jn z?pwX_i!Zr*t$NYl`QE1=J$3zp7%5GV0rFBh41 zb4#T|m@`?Ix9OF<)=8IB2-? z$P!l^Szu|OXK|@!)&Vi?_=UzWd(i z1yF#q|M`8ZkAD1*mM)VqBb$+IMp>5NeBVSNI3IBu@jg+wmmTpY7*A{r

+bTgEUrhq-Z&{3rJZp=_*d1TIbaAgpE+5!-^&(mgY-pTj9DZjJN!+w{ZFXNV|2Gd08cn z$IK6Enx+8qH?H090N*CxXpebRNNPRbP5+(IDmSJXeE>iiDwwY2_`)I;Cr3pp5!5y!@ zn!o<)D_JN`UvMGknp2jUi5Zf~J5Vc`*yq=&yEX27-7QR~=SW@&I6^d>B`WLiX@;gQ^K+r;>tG8e zZOPajW%1ZeC+Qx1P6G*^^#B6<;P1Tkp07Um8^!rE%*9P;*O?zG&2)?5sKhy?nQbvQ z9FVL7*O6RJES8wrh_5|%j)ZaI#g|jLF^lztTBe{K_zsGe=sQ9`gCx(yF|@BZA!%;n zO64x=G(VylkHIez>J$jv4@`e;9|4Re%H~BFEAJtbYY4I<_9Is zY=SR@vKHFdp=HV3!W^5E6#({Kb{XTvx-fyk!f*dM;@;Mw#0f9;XSPX734vcbUGoQ6`+uAva48Y;8dn0nxdX-Zip znr@BZz!=swg7kKFOteNX=DryqUvW*u+g+lB*Wh3}@MZi`|lSYH?AT!+^!ybCx>s6gTCzVjl1 zk4S&u^SlzYK(!>0Ne|K7sb?DdBU@!(2wm5p2woH&jY#WTxe<0WPi$L|4oTzO3Ysb+ z17fU*F``9cqcJw!0ft9k!SO3be^;*m`SF|899t^| zpy@UkC5H!`6J{xgjJ`@tx>ZJVo-Ryql69r%_G9YXMFZ+$4jjmHOKfMNSckd3Q$sy% zmojOro`exXOX(|Oo4Y-t28;mKk<1a&h^ZW)DUVYgys^9DvWIV#SN!vPf9WS#dguGU zJtO~JkUjCt~3-6TI|IEESkLx=h)%Jx8xA2iKjh@&)`_<+1XK$KqtW#UdoOQV+ zTysuJtizb$TplcF*5EXt&Jc;Y!c79AaeI(RZ-)d`@^CHP9+K5pH;e20Laiq@Y^V3h zo2QMAP77wfWNePs&og)ATCO=bco%D*dXL=s{LdGCeufFY{;`60RIlatzc_yQ2KS%V z&!0Q)$7>X!K`rGuNt%ZfsI@3v22%r~0nrYV*h^?mHH9$C^Q(5IIYQFDqFS=PO=f!< z$95kLr3pf+DyFGmA|-=ES8@FC(r*_F%kSaT{io%P-<@Ht&+Gh9`+pz1k;&E}*4K|e z63_ew>sw4GTM$|bfkG?~VYP^tytSQd4{qtQ@xl6Ow<)_#O5a;bKXD-UkVeaud8u#P zGZCWYvhJBWrh^e%qKx((JeMK_(Gv84zJPsF8&Cs7D!-=nQNzy&;6U#jK$cd_g)i5f|TU?~s5 z5v3*3Nsh2kWmcB>!^b#2nEk@SwMXycPv3h#e{%0we)YRQoB6vxgZV>tJz;Z+|M;o3 zCx0lseObd#H>>Lm3|usP7w{=}ns@{!iYFm4pegj79=RhWIYSB|c$lR?4Tx0C=2ZU|>AK00b-s3=Fw>B}GB*P6`o`Q3~u27#M*N3=)%z3m9+%psH`z zAZjn`;!%eSaHgadCj;pZK&(;(v>a%p2#_t34q?x$ar)Spg zcMMnHktL4&`60QE;ZHrFdao|Z4q5uH?_Wr!Z++|aO}TjES`%JFb&NDTNk+qHuuR#> z5K)W>MjRqSavrsbWEB;Mi+#W#CV(`kL{tqa^-$?y^J$Wlq-+Z3^4oQ7ZP&szuY2cD zy@aZ2Peg`qx%GzaZ~D1U9^|37-FW=?;+xjSYgdHfBbfRTX7Vvb^mKAaIz}e$#)w5I z5NlA=kZdAaLCA61!D3O{Ahtmz00wlLNJ*riP8l^0+u6V6`=Qi^$%~H z?k>J&`SATOw(I*ir}X&YG1NMW!cj_huY`%=dRjfq%{XWj-5Imt;B{vSr83+xH3%G7hV-koX(-u&X)Lza6 zP)wXiW&x5B1=JWsEFyw9q48ssnmo_I2r7=0a+2mWp-W_nMivRo>@9il*B5sD{;hv6 z0o8B4`MO62+izKZ_%;^pVM>3DZWhVQj6pQ0>r*#|ez&08@#tt3u{jvUYeUKe$z1Dv zC@|O-P!SN) zMd30qiNY#QDsnwZ)#QxAQ~v1i?sv^@F7N$>?D&)2KWaeD5BkIKt@r-X!w=m1#^%s% z%yN|ZvSc)fUrCiD zfk*%o5m6u^8W18vLdbv&k`h7yV^|wU>NLmlxX(B4JxrbVsg0YMiw;(L*b4ftVLCgI zm9yoW4|DljmLK`U8y`LKs*8W3fa-ydFX|WG@%lY?-~F22@IhwHG95dlu11J8tc}KG zosxAQIWbiJ=5P1V$O84)&@Z}N^X#jb?(`rk8Vq<#8P!m=AsYP8z$N zJnJIEeZ1m^XS3tNl3YfR09Qg(VrVcffhfo+V6|mU0-_cp*~E^Ti46^{QzCE0z#6=7 zXkw(>o9FJk_A?$UA!Hmre3YVyT)N{DVo+R>gR`XZI)cX(ig67gMMBtgabErGp11tF z&wTU8DxrGo4U5ZjH-6yQ!?%;kNmkYlVe>$PM~j?s%vcSx937s|*Y=cr_>+$k(15r$?()t*ClV~wXkYqpwQ2{lr|4h=F2O@Y+ zS@tkmQ`j*#{mS#O;V5|>sgGrR>ON~@Ii04IhE zAJlLD^DBO=JXCLc&)e_#<~Lqn)c3P-Hc+pxkQIFzH_fs2z#~g5oLCpWa{I$z7eVLg zb>|qaEzvKI@Vmct9n-}z!tezBUU%Xk0GCKki2@0W(+rD%31DeFb<80L}Gc_b8 zuy0Mr_rBzIXM22xCB!g+dXx@5m8Gr>9hidy<44@N$V@vSW z2w_4Birhk7VXZ(@ffzdd1;lu=RAZ&#mo{wR#V_2<{SP1Gj@|oMUQvc)%g9IOwiqtB zmt&AReL6K)<_q?dMir`?Q~*efK>-G@$ya8@8QXF5j-p2XTH#x05p-4(aqu zB&+!!|KXJ!IR+-{vT19Ven+W?ClSAjm4|_KQu2_xASGfl6wf#`NJbYaBE=e0W^{X9R5Gg38l60Ym>@wgpf;!IX1E1Iw_7nDk6B$? z<*AoCF1_^G*ldPD?XXiDx%632!Q{sgs}KZ8AQc@uW-YnvH&;783HQIau)4gf( ze40iZG>s^71wRILkQ}I^nZ)hJ1xSi&7xhXe2~!$KBhp|Dc}AHRq@al81Zzk*uoi5> zq>N}3HOlN%pMHuAheMoOWy{n&wi_w30~p(oBw)xUPEIhY6pVYRntrh!IRCHZoc&8b z9H1xj>qf_qF=ZmoC{0sQ<^@Kekeax5h>j+LB*+t^VTJ2&L8QmY;TSXQF*~!s;o zJB=%*$?`r~r^IyHThY>!`HHd{QIFS%VU;qo^omGtO3AuowD3d~lG+I+6A&;`Q>HbV zxcQ|k;n&^^XP@~$4XEDy{B8HFnzu-`PAL)VA`K0B)+JG6T*AizMd`4{ur#ir+{8-U zigeH8@@syE=}Rx&)gE&3v~!syv4tV5?q+4*ft^c(dnnW~BVe^vS&XHVgs2IlZFb(6 z1`U%q-#TIgD?>xw*?^llkHrh7-bVjvi)34Y-s7nCNecFn4jzByaBw6u<|J77(#awL)pS5SH6UWr(d@V=7HJoMH~(RTbbF$?6V%(HOmacJ;!#26NfR)Dp?pn z79lf8@~uRYP#?iFC9=aKv z3tUg{vgKXed)JN4(!SYh{a$ii2MfUjGM^Bn1vl?A9>AgH$cFQGF!TJ&cERPq79jU$ zobS}<*~fU-^yIY>yY=B+c0JCHj~u0v#jBwWu{d1lM zX9s8-ddBUu2S@oEyXtX%j6*5%*1kC$sZNjzmIul(&f+`g@w}J4hANeLe%sGuIUG44C?v6_;&W32}}Tx|qgcLxSib)oAo+^bi9!c`RYJ)|tzm zSS(-kyMv{J6sg9gNRD8lpmn4xIb|xKa+tJ%^=h8y|HGH>g=<#eLV&#!q-NW@)d|3U z+Hyu1dDQl)>_!%z`^;UKYk;j2sXM)9f&D+& zt!^jVzT*?gE)rr72^Ql6E;QKSF)6k*O$}Crj0z~Peqw;e-mG6;ri?X4J670NWpvj0ni$L}<27q?E_0<~^rP9oy+%bK$OJ7f7MN z#01IKC2@+Oh+R=K}L9z|wa<7*=R)fS(-y@!W9e~_O^{zPLPoh1r;G`z-2;=H8CnN7ASLEc*#>I zcB~7qdg{aDBH7X8=DUvr_0$76!-PK#>{fD_Cv&rHHot=5IHzWTP1jtr3pR6xYG;p= z(9szn&rHs-@;I$%TIVxN$2jJvyzz zGvDX9J%-%;Yd5|8g9r8>z~u!R8jcKy{D=GgJ%90m54`^`K6{I(>ic0DX09OGFJLmHEphfF)4O7o}J47Hrc3&m*qw< zsV$U66*4W5U`Po9N=2fxF!#N9=J%4+L;w3fef0+)eBd4m5^;S zIeFp>-}B)<#{7q^c5TFKLdBmh5URGRJW*{yO*JOfgj8%jJEydnJXTE`wUF>hF_K}u zqwp4kC5X0#%KQf^0dY(|qi_AeiyDFUgR7^Y?3_h;{W|Mz&< zkGHu%Mx-WC12t%arlvJ>v3;2o5b+3-pB4^d6OrkQ5QiXf(n~OHJ0@{9m_!QZWt{&2R{k(X#~|<6zxh zflR|gUwqqWZAh#Fh0Ca`5tVP~PW4$Ejqx#%Wf^zedHdsmT=`CQKeZxJTPLKcrE4Y% zHp--|9T91eMgYh+G z3gjsvQE<}5SC&vsa;c92c*-%Ja+DK>&;To>P@u7cB!Q?%ZW^2zN|(_whLt0S`93zvpW#*c_1E0gH!9?k6Pwr`S0cs< zCx#=25xUcJ%=bDIkvf2NP=yFt0Y>oEDvojc0B3l|^!yw{?`e_}lQJ5Os753FsA0B0 zNAiYCFa55-=1ktY_te9qKH56qq-~NrO?YUO)BONKK#6o>7@jq;kMS{@WW}HPdzOHjys=r)axZBe zkR&C>$4a^eOUJ=fo;ZBpZW!%36#y*)2OkUX&WM&&-|@x!?~rHz{Bs$*hR_WxjZg6W z7rcOP?Y&)I`p^E!EbN87-`<%G9-$M47>zjBfUB{&!TO2=-@NAvI0E<^KJ}L$ef2N> z)!mYcTK?C`Zzm!1|UbNzj@EjDZ4_JMo9E+YY!1< zPy$Lqlc3tFe-P6>t1_~F@!i+n{lMCn^q$+;%!opyZPF?Xk}EE6CB{3;@o{9}=INjN zOfI_VpX`Edr>=M9bl$U-hLwqgoXP-w;miN|##^s_`6pfsT-<)Y1pce6{+Cbeoaqc; zZLMwlwyn*LRm5Z)d33eI>;=zZ{%3#r%n%e2d9`Y|8tiX=pGfVLlbis25)OQ7`|5*V zyRIw8$+T&K6ag#XB2f&%qz?kzXi%Wl}`^?{b>klrWqtVFaT|yF)8j?>~+WvP< zmY57l999!u0`oHF_g>;;NFL%WG>h%| z9)ZzqEZ_R2oh}|Djh88$n-mBqEtM!FZKI^5?K9Jiq(wU#a8?=n?gC;9ucpXis!1ZG zFd4u?5o1Vk(gd3#B?)UmU0}}_KEeEv13S;Z{_0)ypAF2Q6wO{6R*hKd5uLMfzX%)YPOynSJHymR(>&zqQ=h3s+m za$?tqoCb66eK($X+F-31`nmo5uew}1TbPBv7NRPr7bKZl-SzP)Q&--ZQHMxf+RgU<)a7BPUQiv{DqC# zfsauShh$=j8gZ%^ASIp9G)1KyCIADz#+Dg#xiIGp!3v{hgl~qp>NwIwrc1?IkNSu; zIWEs21Jy9;RCa)ETNep!7fGA-CxwPwvPn;AGm)rBKR0x;M5d|DEBFDSQPgMH%pj(r zS1L_4X1-S-IcOLX8^vZhh$D>0xKcnOstHMgoa*e7{=nX|2h^m4GmD$4 z){f9M8D0Yxhe;9DHmyfU2#~B`tp(Qslb{|G>IT>AGTkkph%Gnx8U1?TCyyBOptG0bo>-CYrdJ-@ocVW3mJ<^M6>80>G{dWD!`u{*Ng_cLs3{4y zLofx67n-1?vIj*MKOPgBHOOk{W~fQTI0RQ=I|)~Y7HoXm>MZ~T(R65JieL(YUk4dO z0hAePJxvLy*cUeCRNP~1VN#}u)hT#M3j(WD7U21%{@o776z*f$^s zTjp)S&_j_svaCat5g{f}k1-B$(%P$f5@K6B0koCKXbg&JN4T+MnYL0C12IMrN15dy zkr)%Ir$!kk9{N;*Bevaiwk!z2ld2k*JIXveJqXdZnYYvs^{6C*nAS(A5Xnexn!ee8 z>l2eufbjW$-#zytjG4kz7V8a0!8eJZ8Ig<_!I7im1{pVW)L^5Md?H0bqrf;q4XMhp zI)%iXrjG4gyeYsJV0taFHjySR6SFlU>mZ)gL^29U1(1JeUr?t8ash^zyurG>9j);eV&3*NCDS@IGXmQXU1Dr3mE>s3(b!?yg+DHye)hAW zk9FTQf3W|eE${o#{r6BRv2wB|RSxGIWw&H*Zi=##6Mch?HC8;>3aBxs zDhSr#@}jK5KrWNoKP?MSgh-anUaJpP1c z?jHm62uwY5`<~8y`&oVH0XmY<&>-qjlVNg0RKqBN%M4BoCV}xvj*wDBoswKaR8ViI zha)FM*97=G*tHQav3(1L#YRTnp-7wo$Imd{?hK?ZcRBE_04v+cGPHnrs58LVrE zQ!@kBCBy~PMN$UFNjuLO1HKuMl_fq2wm-*MdffJn{ruG}dl~peqT7Pk9!7FfPzq~E z#zQBtwz|Y@kyC~NS{>#&S8n0@U)aIof}wPgR1Yvg@uQk-Y5_ux#xate;RipX&GJgw@mnAIp@$Y;`Affe(Z+KwT3s3S9pJp(s30V4b=knmeb-w=11B@EW=B*2;ACoKCZVtm^ z(6cQyvIaTbNNd1CbQNj>s6*5u2r)KTBdEftZV1IWxamu8?O*P&y&A7Mnw|igA$J*h;Bs5T~s#u>qI2AzYPB({wiS$jFKf%pvkn9BLQB)M+lJ^v>owFLWtT%LtfEwMU;%? zIK@YA-OGQu%X8FSL^C^2?E*!flLuugH1x(NSV&9Eq(_-eN9orGnGGkg%g2!AA*IjB zZHenl67#%IMwd;7srCT^>>$%L$Uq-Jd zY?z&<@rh$6Jyqp6d~l7s@7d4ZqbEpd3fweR>frJ|%VC9gec-S8^_O3ZbtS1egjQpU zd=loGHc&+slTM922@sLkj)phUGPYe}=K{p0cmA+Dn0?O;2;_yV=vN;3nWghD`4ao~ z6V_I6nh_#skuc5yp(XiIP)S4s25HAsqC=!dV1Zk{_!SzqP-#x)I=E(?PQA=?F0uUb zFJ8v{l%c8CDLOex$7J>pu}Dn!NY|Lp^O{B!p(Y%T!TCFKp{3=R)r z-?4`6bCG`0Z8gUlV)E^Dqa>2|;3Hx)9Fqi0N>s_R7N>}_7cez<&dr-Hd-dyoY}3fU zckwOjTP}aqH;$f2FAc+rey2nPnoyDD?FIlk>9$g7|4{@huH6w#4Z+QG^H(2Xq;vRC z(6f%I`UF>9(BWl2e*v2pM%d;EnXI?PIbFlaIvQ88SwoQx$lWS&c$kZyay|=l3w(X| z{n)Goo6u0|Y@x$XdG3~^N5t>vJV%4$^o44H4M`8qzWi50Gy^F~fuVPbq z%Zp_3?xi0V(C?ezm)~ZEyuas)u6@aPZjs~BQJWGmeKZsVDQKjm!Vyx2h73Z64-Ow8 zGREkTbLL7m8^dOwQyf0V1$LERz5W?&$|IaONmw6XMDc!v_cfRf&P?G_K{IHlm~$Jk z=_t>-Y?fbn(KG1zWJzU<__VRe0|J^j2336jl7 zVo|ZEI1C1(j$|xK8zChX&N=U?eEVB_$U?;h3x=I9xr)VN4XKWSG}t18+!0bBDP%4q z_(*ILWv>VI7z{L3h0Al!KmQ^$RIDC7M43+Tt1r8jb2bWH*Pwn#Xlk;eLyU@8KqDa} zLa=Bmi7{v07Yy7YvTzyO<@i64tNzW8Y_qH%XqzG3NpJA{cfIkh1IOMxy|zYAJ<&FZ z2^a}vCQzn;Gl^&-Y6H$Tn7p8o9v*{_fnH%L(wH)<$chmZ5misLLUK8JYO{e9Fb13j zvXoq#1;F~qFZb4N=vaBFQPfQg_s>yy%vox`!@xqW-azV7+kxacK6cgJe@pe!%bH3^GHsL72dmo}^u<4Gn`l)~!j zNv39|u`c5BNQ{9Z%NbXz?vRWnCIORESAkxq zz)-c+$aNqDd_BMxCG~{fS%u)oU>npF44OV`zKfmSO0jq;Gt1xtt+CSXrdas_Gc!}*mEdb!CM4@=%$Uw> zPKaZyfzoDV?PMS+wQ+Y|W_SWwufuq}O4LBV-zSDPvt`vzexGQuO>P&`#K47HE%o=djv*_?OYeb;c|+wKwh(Qk-#);o*ohi}!I;i@wX-PPo`m77npc#Tqi1 z>@5P;3P}T!6lW|>a#9pTgdm9~R+!uoBr+b4=}&E7G;kQxrH+YF60+H?^tNBlLU-TK z$dzyTGC!vE#I|aC+ZVTS#p3n*9=i8m9zS&OGFw&j1o9AYAyAkAGDd9My=QD{>rb{J z+PdAs(s+=Fm57lvc~^{?ly^y}k+$X|icwB?#DTOM8fYT4Q?DdrNhl#HUQ4Rfr=d?M zyL1<~u{hWH(A0&GzD>^k{oVW+*AKTL>zyZG%7cezA3VA5%}b9S+-61SRy$kR7SazYATe&A4f6vKd zOT9tUFhv*9)NUOjvE3a^115PS`gW%(1>wYxA|d^JDki{j5zN z2`2^@=XKk=Z$iXrBG*Vp!fL>(wm_fSj%|_|Op?y{E+N*mi9u=G5(4c2MG`|}v<a6aT#d^gF=ay}TVG*Ydu<+k4Mb$G^88n-{0G z0j}|sQ7B@fBZ5mhnX#MzD1ypl0Lvs)(geiVmV~SjGlRE6$Q*X6PrsB~FA6JvhPn4^ z4Tx0C=2ZU|>AK00b-s3=Fw>B}GB*P6`o`Q3~u27#M*N3=)%z3m9+%psH`z zAZjn`;!%eSaHgadCj;pZK&(;(v>a%p2#_t34qO2WznRvz60Gu`f4i6@Pcpa~%jI8DqVxCss{hhP&hHUf;X zWgAPD^{}p_`#O*PsH)%mQTs?Toq%NnNzb^n_Bu!RoU?cB@BY>A`TZ32=f(9-`pjLofZaBSO!Wwze)_~_NY<~c>w9Z^ z00G;#gkfXA#xTklAIlgnTOMD8&o0a52NwT-3#dN$$}R8{*N(#UKN@NNCew`j_#skP z&@>QhyeWyMK|~P~5etY##StXKxM@`SsGTDd?&+BFj=ovB2fum@_s0+aeF6M^0aQ!o zIQ+KF!xJyMe!1!IYW#4!ua1+khBad{9h2d41T2b?25}L@gNcYyjEP_@(PRWNqVx#b z!!wPiM>Nw!>7b^I3j1T;+^J@C&jr~%cbE%5@bLd<0M*0qxN7mq9XF5Hj$f_ggLJ|Q z9XoIgW3Sk&f-aYW+?;s~;i zD4T~y)HtFQ zg0TcEM5}-yBSX|6B8Vu)m=;vqs#%xb8zBl{l&A_432F&scxI^BOwA^|m0O$6@@@6j zeS44E|8(Goh2cMVK(%CU{LNc#TCJyk%P&2I4v*l=lUP|}rsL@r5l29SN5l{@2pM7x zY7}D=FbYVP0|rSV3u0O@ZF&{JnD)?g;6VeZ1E%rh)Z!>5qs(#|Ge;v^8}hYxU9$P6 z_lnT`g9TLg|Fdl?OF#0Sm9>*^3M>0Cqy0>|F`ZnnCSarjA|^99mlL88aTv)k#v!IX zQ41=jot;boG++|QNIPwj^j(P{liw(42224KwGFlL)D}wVQu)m^aWlDz@3rQ>J?CEZ zpC0%J2dLin$}La&pS{02`QThw-G{A?vT?S6P=R=iRh$Ey;MLO*$?`5phTsq~3>Faw zYQO}@nig1lS~`ui|4;f<1yo{E1x64v0Xu`3r}wr7iKu4O7#bX9oFd33YF!x4_$S^x zclod0{tpIF{hRByJ)!^f&+DUmcZTKr>APjt%~*(v6N9ly2S$krpv-`CCF*YF*d&!IA+HOqs5$d2+h|FFB>}QOAvhu&{R> zhu@ifmq3+g4QBJ>kF6fKi+TGb)A<^{T%nx{iitgMeOh)=6WNh zdI7IBd9O>2!5Bks9Yzeqh;IVMIE>4o(*=|!G-SO3CE#gL4S>Pf;*?5wiUb;q8U+zd zze71#!({~`4x4p}0aS##8PlEafNMYk5UB?ZdA6Gcp`k%Z`Vk_MEEN)y3<#2z^Pr?-i)5^pR8U@v~fJA|)pd=t-fXotoncj;M%No<2BGw8%r)j!mopT9cjx0YHHPh6!5`6;% z$N*vNbw(iKx@>sLuc08}*AfZ2z7wdHu@2+`cw=^<7VV?T&?W;sNIJ6Ie4u zGR601@FoW}7$?+>$a6JQzi=m{Y!| zo_3Qm1JOf&8b1!$d={mH>CQ18D2GloR1NI7{1S%4Mf$x8abs|bHZ_PL3aBWmpfMvh z9b(<53g^)H>fJNk{lV_#XQxx$(|3*Dv4!C!H$MK*y$c<`h{^zC1I8%iIhoC=y*kb{Sp7>vQW9;3mSi!VNxE3Q1BAN%oFp|VD|-$liP#N_IV zw1QBhRD=MPEL`jJOYe%0-N4!80-hG2dNX~NxBcYfYlC-GD+igLiij(yvVa9#gg6+H zWd&Jxj;f9XZ|F}?5p|3YV=NWeNY&Js*u~^MD0-YYev-MlIT~M4I0LRhn+A~#QJVxh zYLZS-&=fV9Vvcf6h;A#RdYa$(KR(10M{1VV9GTmKGXtVG7^XRJAmiaj9_5ZZ9_3xX zaU(WwD2kJaR1hVpBAZ;hU@HhCRPByZX19BHDZ~BOHT`WL+y8X1vQOtr@4ERncOE_2 z|1XP=+|9bqm`vAj)?-95*5RDPipBM3seHkgzy3Jicw~jy^%pQbzm6uvlmu~>XmX;P zW7y2{*b_rOch}e1wB-W2g&>R(jffN4)W~VgB(2If1~ry|!Al=;8~L5zy_JU_T4g-S z$n%1izIZ49_#Zu=m%sRV%uMw-dgLh0*fAQE+7q4T)Ko&Ff}R$ z@AFO!v)c&Sz=h7S-~PY;`rvnO$$LBZ_(Pv%V|IkD4#}wLNte(ViaaNZ5~RUNmy>Ib z5B>Q=RM{L~Irb3O{SQ}i@ww*{%9G??3BeLMmwUc;f{%Rki&(9}Jj@$ke+edsW;7=2 z^;%tcl<=}xMeChLFV=CXmRXetFQBIUdki*od#8^f}RYu~w*?MW*Mvj8&;Zpy>9nrbD-P4vmkv zED)sxQ(;YpFqOOpyVm-r9q`Hjt$mkqwUNe8-+j&_KlS>jF>#T?2BgS{F_3q2g0I_zlAtJPL?*tdf}5I#;gGWSc)&-?(xAk+IhNKe zjXMX^J(seXqV!!>hYeZb2r>W}VGkvcFYmbew^_J! zzs&F4{oxPn`SPgrS8Vw7$1i-{AKttjbMh4&{>qE?AGrVe8JAOrlCXA?{<<#B;3U>g zgJcAWpa!csXguvc9bbm-9K&HwEH>iJI<{@!awpp^-w!iw`mPHMfi++iR`<;vJCa>L zKU;%e2J68N(>bGWGhHQUip-2ej8j}(V(2!%0=WBGE%~L-{{H(9eEt)=HklK+Skvhw z{PSK$V`^L$$lZuCRE(peF4l9Rnc;a?{Wx;ji}%2}z#Py6o|4SXU<5n?JjCGs`*($< zee}&T&Mzgvv`7UxD<}p-jtzh|ph{>ACG#v+>)5vQg?Dn%tMEF5J^{a2&abWSB z-Fomr)>}{%YX#>5&O{2E;mZ;U4U$c<7^YcsTiNmY*YA-nuh|P1wqTAMC@PRnD=Pg{ zm@)%wAm6Zc?|5)yPF_17-L2A~5J zqxR&Go?6yEOq(vfna+G~uPMtbf*%u`wY2ng7D9n)o6OOGs0SLNX85pho|laW|K0E0 ze)ltq<$b;Ln(>Llbe&1*Nt-1LXbe$3by-sM`qUMiSQD1Q2A+4#wYM>QJ#cX=l?Is2 z&R7U@PrXV;lByldzvM^u(7lK%%z?}#iBW?DMWSMe1e7XThB0R~%yZGJU$zJLk`_po z+oJ|1Qq*g~90CW@`#x|9X4A!citaX|%n@Ri@(A7_J|-g=lWMUV$)zMSD^${Zo&NHv zhjn&@Er$Xg&|swpMJwtvf0TLETU zU>DQM*Z~`N>}goQ$1c7efgPY>2(d&%jruxyR-wVLM6~uA`FG#G4)wPJs=rJ>F1qWx zO^GA95GJLAsH4(o#5-6n$5h1>`G)PxU-6PX&_8g-QajMz+(bfle`NRX9r)n;_UyXt zeY;1j?0xrBueuJnfY}Q!TOQgOn&2RSi4f}s2_B8Y>R6fEbSZ3q#XYbv`EipjxwiNh zx4h@}kM929EB@>Mv**%B|L8aWr2YJY_VwWw;KNBpJdf#x&3ipFDSq%3h6b7ni6LdV zg5W~H$r@G$=$#iVoV}I5y*Xrox$sNFCxZ|`GZ-cGNx5?rY zyPA`$m^i{^AWa2QAkv|#GqzrK{%tV-6x|^*{q}$H6W8g9M@Dp94zAo@GWyh2UpdLI z|DXTF<{HuR;6L59AVh)@!Kj0j?#mu3`o0NYIP0EUe z2tkt;iHeC8MoR|yMOU4@4mIog_24+Usj(VU7_F&Z9!Vt%^_IHKShw*qU?Zn3t7H%+ z2I$UPKl&%Tq#DtsU}0*3dQ?+aB}K;&V#)3g{?U!VU!B%_o9JJ1=^n2U(K<x}8yZKUOzpStG1edjwrWoo4!t}!l;5;y_2!5G7EFyQXb-o>rIyL-9){p+vG zyR?990B--Y_wOp#mMK>Um|z*LjZ#6wWq9w2jmJdgw)gM83i!$y5e2Bj7?Tpyng|a* z3e&UGi%@WeuI4X4`4=>!iX!h)YeQoKrEeIGMxch-{yblQc>gb*VWj3xzwd*&h!|`e zGc=$94IohXv?^@hAry53@Idxq+y z*Xqq7kR5q^^>tDSy=;mQ6q6UMj>d^9(>OAERI3%s%l;VxEr7IXLq!y40X4SPY8OF@_OdYk~=sVf?q9W;2jof8)>WUao7rbEt(7D_rzsUTMmJ zj}FA~x|dz~vu8*+#N!xgGfXrX%Q$VAd<`O+727-5UX9eidI=jXrcoN-3Rg>$a zAkm(3Uo%mv)gy55&dCbuweCoN;)DMDzxjomfB3c6;5uCfWkp1ZHgIfkn3w+0OZlb$ z?HA8*@W;R*2H!Zc%f^yZHDm+ccueM5Svv&!jWbv5NLAneuYcjDTbpuBy}ClrK$dk` z8IG9WJkS4HeSH3mIUQ(U7bogvW${?%e8724p{JK*-DA?DQ3J$?YD6^6 z1CKq%p#FW%D{>>hCVO>g_@&2Rp>pOIVM^&5Kh;2~UZiVa)0^0t5Ti|+>BbB0K_OPvL% zVdblY(Frgk@+>9olin0CKKa0sj8lwp5`yPv1!yL6$V=Rk*liF|GM%stGZZ1u9pk2C zw#Ybk=zhXi?|zeg;Sb;1o?_TeeDWk8c;mmgVRs7oPKAL@3*>UEbAg7Xzj<(%RL4LX zqMEkeELPLfQ_j5h?6=%rp5}NT)nkwDDwiLjYX;a@C!e>yM^up*kr-M!Wa0y; z7@Ud2vjTLhEAKH;F)``Rs6s$bIrbV2!NY8?hw~NFW=ubx9S(tz~^Ru0~Wj-Q}s8e&snj3s)H;!_25Qf`T9g{DJ@ zSbY4u-KM`i+mz2@TR@``utGEr#p9bm(aF#NovZ)@O=wu(6UMrX*2)+D^h3L*Hhh{( zo_7_+j+g97vG?TJl}T{@!wmNx+_kj$09jaOzEHY05CnA1T-qzv7jF3 z8j5;E;RA<0`p3IE>+WLx#hY(q#}6*2e5YvvT}{X0L-Arpf& z4VkIPbcLQ+#!JU|^l$d#?!9}L>#Rfaev0D-GAgRk5vGeVQ)ZdD8Am8<#$`!wdLBO- zA+ZA8?y3>AZ@X=#ov2OuURG*NSEG6Xy97svLW9iX9F#&)Ue)x?310emD{ zMNJ@hMNCrQVl#|rTW5-7QqmQ{b~+5k$BE5x3OkMQb2K6KA$2+#6eFB%D5iUa@fxZP zy{Qi6aEVTTno!qmF4DBR%My(c)wU%W3r&TtuF-Qjy=ge&mTTJK;w95`g5$UK1nB! zh!Ko65Cc&S4UxRfkrLZREexWOj(8lArmC1JEJdz}j8aa(IIMGsleF}WQZElMu7k_^ z_*!wr3{|B#=_KzWotY@MRJ+lU~C}I3^2hq}QD$a(gcwuRF(xLS zQBs#2kqO~RDCoKzhq85H7MBkRqb2gff%;Y-Cc;@%3n3&cPE0)1r-0YeB~2@-tqMp> zUWr&R8M##Z&mPcU`rxv?`?a?>-TqbR5UnG4#Td{i)WMTU#KcrM6Sc&cqaws8*cg#< ziM0mXac!5|m>A1;((BOPR=)9s=a2vV%RGE&NZwn|a5$!Cl&OA~x@po)Xb04`K0@Nf z2LgztY*Mmf!?fdve&8Zr`>IPQ{0cO_mC6EK0a=DvMX9l-OeC=wQmtRzDc*mO8t-b1 zL|iCP3_&BRHZ`Z&4&ChJ*-NNEqo&wDwq0gTo+^S-+O|PUT?aBTXsfhiYZ-&4UQ8o` z7zd)L59qi-a*xSUDy;I6F*zUqi+kCBD8qJMz-kq79S1IQY;6sfb%|uDzX(asq!pVe z(8Nfd=ZJWYE+6L8ciqqPw{PUabp^I)=c^XPp$IXiCJJktB%RP2o;G$rCH1Xkk7=$Z zYWlsILhLkL_OJIov!;d7+@XzIwzFDBFgaCSV~k^5Dc1DRm_tY{hD``W-{4enu}yVp zgKE`=Y>pUns?edLN8_f6w#(rs7RjoNV$^|^oK8K@+DUL`J)!EMRe@BBsXS77q>5;1 zV4UIV8S0afPL}7ISz~au z#YCHa7Xp@oQrDr@-S(Nkx*&T-RGfER`NFmNnI4ZHdEyn*c+k|VX|n=VutM7~|QUV%w~CHxs zjfmPU zP6!n?3sl2Z@|jtP8I%oVE@h2QRomie&i)w*qtsG!I?t(X-ZNNFLzl76(49ITO850= z-L$at_gL2JKX&{4<*#G({=ZeicL!{3$GM0xGU_Fs|@-YWCwQkgz# zvbGAC+>PWmf%ur*y9hoijT$P2M%z4Ubm>Mz7krmcyTn(rwoMF0y!W6567#l+wo1k@ zHi>{h`>LK;4(N4rjF1?CwFldQT2i%s(uSis#BS?zW~W^vO{+$NAi+XR88l)lb@h7qEEH7O5Rn(3DGxXS)N)3L+T(_Nui+#XV(5xY;GgQILh%DDN{&M@8)>OfG%i&9TW5iz4K1>abFoe>&G^cgXvBlw)?bF_xcbwCZ; zG^xxGed@ym)Ckci(SjPE^r1|Sh(-uLkYzan|`Ik;22Q%ZZVv(u{6rj(V-a_=xcVyoV+vmZNWyG{idn zt!bbMNQkHpNbpFg(cm#bF;PxYwB^(i)fA6REPrU7aP_U89Rn4rp_RxIl~F1lnsM7j zl5!Jb4Kda*Z0PlF>How{@BN+tDwoSLz@J?H_CwpBxAo20dD}T& zTeO&?)*i#gqMbP!GsSomF)?p#M?`}XLm>Kes85`!7y{xGAQ}XTNur5@iGm3h>kTFt z%%mE5Mny95;HC8-+W+e$>Cu9zA%(!yC^a!QXz*xA^&w17t(LJjjOj24Q&e^nQyX_8 z`t{v%^z64GdPaMW=m*|$)!hfWUz{4PK|LThk-RWyJ)q-j`W;D9;Tnu>QcBOpcAF)G zSc5TuQ^W?uMT}9@2r}9A#2xPp>CC+iMw`h3=HdI9J3s&~qcn|}LyzN5pb@lS6$eD(U-x9Y-H#xg}@nriIO z(8IbZs@mXVhv2(}(82o*?;So^e6R#BG$BzMgU<*}PVgDpIAW`7@n?8RP5N6ad}wU- z;^dfQizYzpgo~B%jcxT-eZ)t_M`bh)M7oTs9?RoC(z%HKIahE_clD@e{YF?fzjpyY zxAWl4?E8)$KD1reR+!B!wjNNpB&AA)F&>vG&Ulm>V*}Dktr(Bm=2V(ZL@_RHcqQ#V zBVto34U?KD5|BwkO@c(SQf3!6-8r8fc`qON z)jPgZ57PGqPyl`O*cIHjZ}agdpSb=|)7)4eUu4>k=@4*6Ks*{7h!xg)To$n6Q7KU> zqBKcbGsRlPI@8vyCP^0BOL};!{kc4V?_YryON#sV6!#O3OErl!iOC6($f{PN$C^lXqxLhcz#( z#twFFBj=od$@10VzzWt1#zqJu4B?a!f|&GYOV2UJoFW4!B1>D(G6sxL0s|iy z;?U_irng+oMN@;Hr~LHo5A27XKlj}S^Lqm5Q^37_u$^D{znAZS`$ade*40mj)iwG) z&{fEqKprBQiOJnOW9v#)kG1uwE!IR7+a^e~{Z5DxaqWhzs?@;~S`E-xOWElVr>2=& zSQuWIExn!1gS+GdOgFzwzUVoy8S>L+*B>CQbZ*WqHn(F-G

4Tx0C=2ZU|>AK00b-s3=Fw>B}GB*P6`o`Q3~u27#M*N3=)%z3m9+%psH`z zAZjn`;!%eSaHgadCj;pZK&(;(v>a%p2#_t34q(){M9^LyF9y}$c;{XWmL;HCA_ zdTG71URp1$m)1+`rS;N!X}z>wS}(1a)_+S&{wkb=9j4g$<20q*$>=3O|6IWB-O)66 z?HJq3_Vg-O1Xm2(rkqdC4FN=@aL(GfYT=<%=N>w~=jKlx|NlLp_Tb(f^nPN0@H-FG zsoH1gpfSQs^_3yUp``|~fDuV40SOflRh%lO6=?q?#7DfdQR%~}Qo~6jEDh80 zk)nC(q}=quNB+A8)Qou^|JA#fNAquwVR8qP6IfU##FiLauoiWODu^1+2_pG{3Sxi? zP87ruC`bqi!|)&#;%6~8N0O~bWqO7( zTwum6;&pR1Cx_DTg3T<*N7)lbYMC!hyztfV)=)~ zGJwu!372(19U=x!0mY=kaF~=B5S$St(vXPKqt!VQmtnS>!or7kEj{>tx#KU-9LRU6 z*2VD?uiv@5dgI=wo_NJ?v3BNwTY8i#o?^z2=v9&6goNN-A50N7Alpe4R25U%PYyWShr|yOKeqFBr zi;Wn*Ye1j=%7;I{cHzl8-Rfb6T%cl1sWnbp3YXP6sRuV8b|9IgP8tR09O59^MF};L zd@3pk8BhubXm^&~YXYcY0ELk7Byl9G2-YK{f|za^$ZZ zp!K)@>77q5UHf@E|4`xA9%Eh>7!+%G%|IjpQIB^Xii(&7a}MVmwt~MH(A2VK=p1PC+0N&j zp_c!zf_dzp@8{I~Tc0{JdT+S!73Sh8=6ho*ouY;Bq(vYZZHkx*QuOdna+rjGMTqOy zp8w$-V%ABTAS#^%W=UKJ63xylgDIT}Ft7w_`O%pJQ7(R;K+jKbCe$&}aM|5w{H0nJ*!~ohRWynx|^e&M0@LOs&?;U%J$L-K4W*MHzychd4>)9-`XGyXQS?i4kPxY>q^qcJ~R3mP#^*-WS+ z>JU{5H7YluS1i*n&X8PtaN+O=f5kq%cgKqksED-dM1?)I@{Utaf9Wl{{2)DB!;4Z& zq;&ythSP*1s1vM+B%d&++3A>cYWZhb=q|da^Xw*=$wlCjU7%N;BoyJDC-=YmFs8GJRp^KAQ?e>D2e&)xi@IVJlC zdv|c<+kg1%ndyf|Cm&(HED*-P1lm{}N?bpzKasQ^Z-I5b&ya@i^S33+&W% z{l_M zqtHm@#*}Ualj`o}!CPMS;;4N8HFusm`NXYZ@hEd{1nq=U`&51ojk8b}Xe@z#_b9Ve zXaH?M+D>AmOC@EU3Areln{DMYPC=1%C)9x_7Qm)pBd{@MW6UOy8Z0J=0>MG+Agq5*VUX6nJ{RrBK_~_-(JVufBfI3ks%qLPl0!3mdYd<7y_frbLgz4aaUKqUXtuL&E z9(?D`=f3^r`EB6>GYYhZM5vsCMMA7e&S(`T7_Ilj4KYWkQHkXg$OM zn37V!Yzi(A)QAcspQX(LSR_Rurh*tN5(P~%0)~145^Wn0DUj&06=)k`Y>Bi4$;UK2 zMO0jnEC5ns(j(xB(qP4y!mm&jOL)J$CzdlmX7@Ayf&u#EnOD9)E}v$W2CHkt3@=Js zPw@qmeNWwv5jFb5K4JmqIw0EENti%N2$8}mQk3|rmpQxGf(6tIVg;d2UTGS_()q z#3^cuMF$c|g=Al331W?R;-O&QbY* z#f0Lp1cfhXnwD~yrJ-rpC})OH%yNDuGA(B4Uv@ondv0vqRa<@+_5fS5EuAb-o&L@% z;_8JvCad3Jtvy4*lu|>MnsyZ_dKeLim?U!U)p_h_kk-JLBr6$P$wanN+cswAu4R7z zzC*AZsDJ=00!QF%b8xzLlIipur3i%xh3lLj-Eq6xRnB4)-U5}32*{gPdF@-_Bmew) zks}Yj|L@ye{S-6p3PYFhg@I4>W-2Ce8TAv2pOdFJt3N2eY?FkU%EFRd_3lciGD1NJ}?Ff9;qXwYm1XfWU7!lcJYwzBQ& z+n9O9_a1_)fVorPIu38$nJfUufWvTsgG(#NaI!*A*C><>eo_#_6p|#I7^FZ7GmP6k zOyjnP2G#HXt>L~)XQbq7|LpJB6~zh~YkCEE4^kMdHuQ#y`WADZnjYt;J$k!d!;bH} z{SaGUckx4ufx*UwPVQ%X^vJ<_@lpEWNqSnd9wsCcOgy*}Ne*qZ52*{|iF0FS zw%x?b?zrs`{Won znB$G8Ilnl65lny`(ElL@2VQe%Fn>K$W@&=vAmU3L(E*e{@u2FZaM&q=Q#dS7SR%T4b_dWJyZ^F zAjmGF&45){DsWbz5!$+e6d6q;qqvJ}zW0_x%-#iD@$BR7?{46*JCEmxA@{-DYagE7 ze%(@&W~nC)ct<-Ok=iMk5!wVzgwP^V#;j#)y*RIA;}g7_d0$ zapkM;T!I@mpZf^-`g32*hEZFWs8bp9{S0n>^`TL_otS2T5=W8Akf5k}nl`akJ1*bz z8rXI>u4ib+$DWS$+bzWq?PnHzb3vFX^Sy1zHu?!A9Hj#S`#8D2j3*;X7W zbUZ*ZBxo+pSn7zE1Tm0O@v7%T>v@raU=fQE=QYP?mOv79+cH+i{_Ad9fXmmxe9rYx ze){iz=)}Z*`{Yx{=~s>&ySMQpfBUXa{LLTvsgoCV5a3GuWm^uVr;CFz8qQMYJd{{c;n6d+%NvZq3#2B{Ap?40mB>4 z*5NRfSJI@xiN{=~7%gSzgn7ggCVHSvFWV11bZLC3RJ17~G2un4%kGy@@>)~8r`TUs4;xfPd(EHzd@~J8Bc*i^5-$`&b zhF9E5I{e3kCg9RKKME-+4YTaJ;#!_1-S8jpe$U^2-|}L;HpQCAfP&KxALsP9PjKX+ zZyo%#kA3)komPxD+4jyf?83QWw%4hKHk0E~6Q*4SF$FZW6j~GP((S0C1+6)v36c!2 zO0>i%Mw-GCOhLDG_MgqQm@EZfy8k^N{oDTWeZ-113e1p7a zlV@3i0ximoDljClmSBMfL9gUc_fDq~YmfXd|0W%qu8wF{CzMv=qsK+TN8`z3kMp7b z=U3m^9e>?H4ljaRGMw2?Q(I=8LRN2*A?q1iieL?56P)-xwv;dUy9PAG+&AQ$Cxr;f zNO-1FGEF7Xd>0kD^^i4^ z9GJ2h$o2Kuw+>T^hX9k&l$qfcrqe(>P0%JJ!dJiaz_UDcqBX;CUERKh)Z!E*Win$k z34Qp{@9axa7>xtHnHffPLqJ#=kLVAF9VZa^k01G+o4fPd>>x)_LX+?aG+pM9I%>}n zl3LVSGzBEt^P}(jE+TPEGC_QwrUgwUWg4Qj$D4x-CpQDi=1^(UOlVT1P5~1L!HA|z zlMsE0y2yC4{A^FnbdqRIGs`Y1lhAcy&J}QC^=7zm(YDk9XBAFM+L&lbB#kt&Cblh3 z91@jUsyjCQ&Zq-+9wKS7Op(U<1{#hb>FjU$g(d$z)1w6DdT*BB=??RDC9+DU-DcF&aPe<3IW@ zyO4@a_7s>hUObCh*nAD0q~;0&iH%BX5*c2ygi6W;ti_bexgv-)I9A!xAES1Gg~v}F zgq8IQ+NsXA9Rb=mzWL72j%ZkI))1%64!01RhKa4ALkQmS1ApzVLl=MY9HXxvIas9@ zX=ARr$FAV!6|`pc+%q&{{;fZG@ZH0~9BPVdjG}=m3ia|DGu4pF5BT0!y#{3PH=mVO z&1XS9frSw{-amNf10VS9 z_rL$*N6#|)@)r-<=yCe2Qc4TX$Q=`cSxZqwG_7&`3-=y`6Tn#@@^}8%zkBwJkKA8= z&u!mB>MM)Q3OZZxeLwUDKKGSB`B4V$?OmAFWo|8S2EsR3JN2z1Oc(K+`hhfs3|=Rp zDN6Q*)&epQH(!#3%IW|8Emr!5=o4Bb`bB|iLsdp5u^|rTd15Ux9_(h<4X@+MH^1%B zvuL~ZV82T@(??0Vfbw(C%5vb?7vH>k^qxI#e3F6r919jXkw{WvqIh+zG!;wfa&}*L zds`m3>31`6y>I>Z=7A*<`FS(@@TTZtp|hFeto94QSC~Hdm4jjRDBc$7^@ZuQrRtXm zZP#4V1IrcZiOw*RJrpz79@)!Y(ATH)!N%Vccwt!@=P$#0}sQoKl$1NVpcoEFBt~FO&bVSx-hnalkv4cxz9;K&adS0Q9IV?(s zSx1U=jTe$)Zmcj*G8@4|m*(X|>KYQF2k>y}bst~9nVVm_YZ#5X?A!e>5l z5Ds_#X(Q8XFWRrRv$x*_9wt3@&%v`tzEG6SX^K>nrXg1!Rlz{lJETIwQo^Uez%^WR zS;_G)e__w+1NR)vR%X0@<2F%+u{(!VV09iw^YG2$!hiYN!Ijg8nV$i*DOOKO)0%29 zLkev!zgT=`V?|0N^QeVK;ED02RXy>9(4dt=6hcV3kd+d+3QG~660=35GGk~A9RAVtxI?v8HVfyX+nJheYu>bN`9Ot^1-;>KA+d5q9PI{Lh9D~DW4lX|ZI2sn1 zaVuC@BN6a;#Fa3f;=B;eFjb^&Km?@=9sQ6(>xV8i4)w81|I7@Fg7b=54!YGMnhG>U zN;RCz<1&3UR#V{2qyLE$N4|Q{4dwT+bMeer5R@@>pC0=tEZ9r z90MIQ?;Ao|1=nB}@-f#N{kwQN7Yqz1>wQuIM2IqA$P@QoGJO}tlafPX%yDR;xlcYt z)G5wNG#RRaLL$yLl-g4HL_AGl;dTTwz1I(iUG4(oDS3y^#wia=5{W%9&n zi&%qq%1n_E=SZYXPFp~INs?aXIopoevGuNvK#~AHVAAy;neQaCtFx0ORPtC-&h?$c zmjyG7slyt5^{7GN=|C5d2o{i3Z?sXWRb2~Z>cl^H^O;#!D9kSfAi4q}J|wci16%^2 zNr?zz`4J5W5%syX+fvHa*Cg2+n`F~a6q&JUTOi;x;gUgE_uvH~C0xqsEM0GsF~JC^ zdQwtC>IN5*>*$a~5+PCHi!u{kZOp%AhKkTv!K_AfyBe3g14&^H@G01nWAHjcz(vD1t|5+Z?TJz#(nE_f*Rd=@Y)G-ii4vNY02EFT%_R&4#0la( zgxqbHr%!y>GQMt$wab*d!3m39tA4^v^6*Mn?{!mJahUd*(aG}~z41{bxBo;#of3oL zq(GVyRYPrxNQ-L7CxjySd_gJYi_!>{hf+xvXk(y=W7G*j6VXDRKo-rNDZ$}w7ZwII z$%v9~oJzu>c+osBY9V8iEe@&$vflmCggo@stGZg4ky66rz&nhTZ6#fMxJHs1NgO7Y zS+o?pV|yYVEBegLjGk9Fv#(uAEs95QmdB}`Dk&;z38F`WVVW?tZb(aTHE89tU2Lb+ zv4$3;=kVU=jyqqFw4_OWO!|1&XF7?jEW(N7ODwG{ac+5$@-J?ouy4BX2Z-$io;|Mqsbk5QX^LL$@{;~ z6_?F&&DEE2`_223IQq!|uxteeqcTV1F{9sT=zJ9@FWRo-asA2qLKFJ1;3g zFr-MRgV5Ia^?`+Hf?kihZqdPIOz5+?syz6Ov)uFLFSFKer*+#%dM&l(_CrK-30ty5 ziPjLU&LoKwo*u)(BP-nh&>wNjbvt;|?Kg1coM%||pk1L&4du`?T3Mnu7!YC$rNU?e z<$7=%Nb6e}7&*PfNHL&gK})0#La}8J71NJid&TqYzVlc1zA$&y)d$13M}#)uG;TDo zCJ(KGGsAT=R?bq6S$m1lj`2g^b;}jhjc3xEWz=rt4<2}m`yV<%-B!5Xe%4G`n$?;{hwe&j(8>>F_RT{m(0Tpx)IqC&r_ zP{36lYZi%WI4L`SIL4ER20`-ht(t&2R7z4zB&*m~?Yyu0_PgKxeEUP)yMN^6h1+)B z9p|2WYUeBp^_XEDmG8NGREX2rWgaqmHNZQ#ZogU_($g`ejd5Xuv{PbJQTu6G%0t!Hsm z^VM%W%oTgCpe#N8%0p}zudPrN3JPv!m^+s-M8+U3rkY2=a|bGlVdfZz3Z1!@*&_Z! zdE>wT>hqrUv|nV%&F^~ESB}`d{e_dvHOrJz6TKncD4gP)p)TP(IG<40qB_O(g=m4s z^=XG!aB^Jnkx$>x+3AoA@iNrU5hgWT$_gKAsF%^W%$}Vkm+w;M=3x8wKEvSvLc#Ll zl!Y@R&abu{J+;Kd2CRi4R&8Zsd3<5(Y!9XjY%k99{kQDouGj5mu0IBuLTErLCXzHMvE61Zk@yT<~g+jzxk2>z^J&2sk;m>b6Dfp z;)MFbar$M={wwEr!)tHl`u$re{3;^Lprg$EM8)D(NP7qjSr|n=_rx!P=&06hv^vIZjKF*!D?Pge|OtPra@6T*xK_;5Z9*K^OX)uA>V9olZ-d={~ z!jH?_{@~>15zR}M(2b71fB)-m{=&m2K0kN*1Y2E0bTwXEN(*>RBxg`KT%mXel{NHc zDwZc}uw^Ho``QWadu)jd%`O_Y;ZqNZs|@^UuD{xI_YWQ5s@)E07m4i(&IxGD@pm^H zugL)gMnP~rTA5)q@!a!Yj`E-HJHyg+mRM|~s7mIB5g$&nYj~c2_|tb$a02Hh#7ToI zt1fqsL_Z~BsQJu$($b2uLXS~#HNDw89@<@e^9SWM|6+j`U|pP-?;U+;*Y!6YKexKP z&o|4IWRDoTX(22pLZY68(O5~nJY_Jym2;z(L2pPqK24HvlfQ& z_G)@F1;IjgmTise_h4G*_!uBL1jEH#gHMtO+GAw%#A+YAxBmX$lIuV9f`IvqNjmu( z|6<{~)%$*U*DbH+JSC<>#0CT{Nv=S}liHMLe}X5NXBr*Ra#HY`S6sv1tv&qoEEOl2 zb&v2j?%c-z@P?PM#hs_9SMkx%R6^`Qs7R?GMn^P9NJ_wAU6+az!L<{7yGRjFaQgxH zsULj>ufJ(PT74APo}lN?@B?qU2G={ww7G!x989{}J5y4cATd!ykkDXlLmiBX&7i{@ z>GyVh@>0qie=e0@Ur+zu2Y==K+0i?vk3Pn%O(?1cNh37Y%+CyIrY*?~KP>TuQ8z0@ zQL4F}EKG!No?PYp@_Fv~o-4TWvVzi&iS;7ABH)XznaLF-u{@Hk-Nc=AV+*!U#)qsD zDdZfzm<8Ly)60EMUud~7T4LLF$NsBJN?9hXEi&j2b6L6xL=D-jv;uXe1Y^--)%93N zJDJ(@1IMp8_J7?bZ+l|lMFrIEVHnQ-#?L+YwG;2%DS_4Hrx^Oc+(2okBfNM-AzH)C zY(?8HQw==h5UI9o<$R-vcWiMD!_xAsCR56uf@ZE#N{9IlNS9MuT_46>Z+>v0+Y!S- zE7?PrCDD5VLK}?XprV~D;ibmQgfN{@_!(MLV&O_3+J8Am?uGw4sj2!r-Pw^tGKXX?c`}BXhlcR_4 z{Nl-{{^>TCaMNY_-bisusZdIQIHo9CB01IbJ~y4!&6xhsqs~Z@Cz7Sqyk&?+L^F*i zn&HA`e&+A<|3>ALnp14Thf#$>9fcZf#nwnemL8cRlD3t?~t)$UiYb9?cg{!KsoZeGNt&-LQ( zTJ{X`zrF1UN5j2uxaIXfzf2$PT}FSnlSy4bZyRf=&*H?>ra7Em25}pc=?rb$!l2wi z#T-5jNUf(HHB3fRtZgU(ng(ej(kL_~sV#_YNgGOHD2Wq~O)9i5ak0Y19zII$hiZUn zK|AhIuX>Wr;EMru3(Z(5!VsN6n3jazwG_K=Z?D?6{DaR0rWwVtCttXE`9IgrV)mIM zcMunU`0$Z${nFBjC)qk%(zI)M0+ksBfy(l{y17K@BkI;@+EvsS6ukm8kaUW3HCU60 zeGyc1$A~#0dc%C)@2O8kjFDPfC_sGPp2J1Mn@3`atA?zNr$hv;9Bs@2eAh^g+p(YW z@*9urY<}+t<*w%rj~)(tcdR{m*N)q-d0{rm`g3p9W`B6%PEI_ri>pgLx-L>o&`=Za)#D(jI1!reoS; zX9^U-B~Pdmh4#Qony9qNk+dR;V}$|!+E>vl>i4|tkAL>P^2@aR1+DLHGr@1zD_J

&-DX&lqL?@;zL!yZ;{U|J)(@#lQG1hc9{m zP&>JF2k-jTrElKx%FnEwS=i@R$6QvH4Dqz1HN;0m*K0))C4vNmcrj?#2og6W(=_il zv5YB8*C!uYd zHzf3qBoHjnk}#B@in)S`^YnLK&i<|GUA*dLM;QFdeSaLc7jN42m$w=A3%3U|6nyU3 z0shIMg-3tt=3lE5KiFu25PrCPXG0sY}87 zB|0-e27PXh=YEpQXO6S$%7z>7df*W#5Ac`2UHktBYEniFHdIM700000NkvXXu0mjf D>{`O0 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f642.png b/app/src/main/assets/emoji/reference/1f642.png new file mode 100644 index 0000000000000000000000000000000000000000..8274f185fe5935c05a115ba82b1aa354ea3e2ed9 GIT binary patch literal 10640 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 VFs8z;R7wB<002ovPDHLkV1k$b<~INU literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f913.png b/app/src/main/assets/emoji/reference/1f913.png new file mode 100644 index 0000000000000000000000000000000000000000..9a94473d8baa9949d4f2989d72e66d4c7fea2055 GIT binary patch literal 11769 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

GF=BHXCn^1Yj)|5i2~nq@S|~k+_!?y< zBcKDho5xJ$ob>b4G-ei{d5B)v&seKLFYDp*677VBQq)CZV?;+!h&iPjU@TP;7ax!^ zV#+|`M&bfb2!U?aCDcn?ZH_Ruhttp5j5;<4eLp1q%CAc#23OTWh*c66-a#1RiXNg< zf|{UHu0a~xdE8NNeg1zYc~<{NH~i77UzXLI8;^M4;NfF!6p{eOXq@ttG2#)37UeB5 zjOu`B$g?3eBbWq^JZe3A_U%GzMUi_NwoS{_NJU}1N0pUfo#?7QNu=^4XaXsb6h%X7 zq#_s@fGV+#HZF`bC3I zm_jBW&&;@evpxD#U;U{UAc%M0de-gNUU$XZ%{Q>UmJ$a`P>+=4L`o8bhB6o%aCQi~ zpq5yo_ZUfV{Tj{W7;gE;2RLw>A?>fDR;-~B8l<9#(Nly1k4L2zo7O2yUnvpq5$~#? z1Lg6iptO;WIEJ+zYV87No__)yaWAO5Ko6lVca#PwMI?7|)Y+CAk~fA9cFe~z~H)U-o_t4t6Z5ZeQlljlQP zV=1;I82d}>N*-(30Yi;pC`nEGW02Q2WbZEL=8Pv zu=Po8l9Mf@w?U%=I?(O+FiC@2J)tafBnbEf@tTOIjDb8xGU_asZOr83Xv`e9YvcHh zza+>0&`5ugtOd+g~G-~XN8I;?ixV_U;{tnXlS#A%DC#F!p74YV3{78VatZv~Q6 zD4m0#X*VYbIaoDD=xVzA6|=i@miBt`PQV7i>KfivDl?b@)f`e=>zUb}GP9!zn>5%C z$ReaeFa<$MvfR@cU&q4X1sZ9BL{+&B14tO+LcmF#flQINPGov!^Um?9SG+-v{h_3> zpDmyO@!j7z`Tntk-*fx!$1m-tX2B#4oX@J{SQ{7?T_z@*l&*&lLrj_=Do~UI8cj{4 zAXRmA*+vzUXulR*gRtCXd43r%)LV6GYickNq1lIY0g_oTT~H+fU)79=ks{-VTBLW&ED5DT0#c-5wFHgNP&$6vxXE_|o_-lGTRPYx(AwEXisU%C6{8()0z z@PRX=*JE5I)O{dvC0b>a$q=V9tgfm!#NbG+U~FX?i5e9ZR0ct#ltqa_Nkl|2Vi1W$ zU1?^oO3(#SXP^U79xCPLLbabCL-igb23FInkF5u8AzSR%yzbJTKg$AyyX)4 zg-2(a|EB?cC^+KgQ@Q@z)8Aj;zGATV0L{|T7K;uU-t<69td+_i8UjiRL^)y@BFcd- zQQB7}h?FBJUzv)OXsOoSVn(HkRJA7+@l`n{G*vXUsccMCRTTn7j8rC^tub(hrP3hd z>shn)IM%mjUq<@C4RX?Z?&hb^{`18I&%b1vSDbkc*M7IWxn(}qJ2X!tdd4L}Hbi2m z041WNB(V{Zic68Q^7N<@(E&`AB&JossH#F^lz@wlxKhqdRUE9;N~uC!)gD=K7Q4Uz z&9L5NF%Kl|DUR57On=SV>@6%Fx|O*H_Q@~*=e7Ay4baufiub?kwE3HEKKfphyr;gH zp#~XNAWaN9dZN!!(Ie#4Y8GNyZLWzUMu(`X@)&ru3RV96h%-g1QbuTns4DEH^bsGS zj1WaVSo$(EH5O|vHg4Z`>((vd&zZmN*8bkaw$6RWxA`fzpGwK#_;=TzRvcJ-+1@aG z&C=XFxRRPuBr1|f1XmJ@467nm3q~spm2)=)M-WHQ9(2SgRdIKSgy8Vr6NnTNQMH7S zCJaNM>m4DrwAQS_OiuN;x4v}>SAArbuTaWO|A$q${js3F|Nc|i*f^C&*u>4dcip*W z=|f8g4kD!^Rk13gvIrpl4{1>#JNtN*U+}Py&awFq&M{@i9eFpQJZlB@LqR5fua6p;m zguL4CS45PmO1H&WnMDvWsm7)$X)W#R=yz@HE`LPN-hUm>c-AzN%*s>FydkcqDF^>+ b%dr2yr@Z)B08TOD00000NkvXXu0mjfYX@Re literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f923.png b/app/src/main/assets/emoji/reference/1f923.png new file mode 100644 index 0000000000000000000000000000000000000000..ffc1e616a4b3029e9dbe9aef76dbd639978968a2 GIT binary patch literal 11442 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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f92a.png b/app/src/main/assets/emoji/reference/1f92a.png new file mode 100644 index 0000000000000000000000000000000000000000..58138b61e74571d1e2be414d31ffec33ec4247a2 GIT binary patch literal 11298 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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f978.png b/app/src/main/assets/emoji/reference/1f978.png new file mode 100644 index 0000000000000000000000000000000000000000..192cac60a087c819b801cdc827569788231a1ef4 GIT binary patch literal 12040 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 bZm<6jZF055Lex7e00000NkvXXu0mjf0z5Nq literal 0 HcmV?d00001 diff --git a/app/src/main/assets/emoji/reference/1f97a.png b/app/src/main/assets/emoji/reference/1f97a.png new file mode 100644 index 0000000000000000000000000000000000000000..8ec9d266b76e8b62eecd97f0f2f52637c3b9765a GIT binary patch literal 10888 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 literal 0 HcmV?d00001 diff --git a/app/src/main/java/llc/slacker/openime/AboutDataActivity.kt b/app/src/main/java/llc/slacker/openime/AboutDataActivity.kt index 9f6bd606..1d1fb1cb 100644 --- a/app/src/main/java/llc/slacker/openime/AboutDataActivity.kt +++ b/app/src/main/java/llc/slacker/openime/AboutDataActivity.kt @@ -13,6 +13,10 @@ import android.widget.Toast import java.io.File class AboutDataActivity : Activity() { + override fun attachBaseContext(newBase: android.content.Context) { + super.attachBaseContext(SetupUi.appearanceContext(newBase)) + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -20,9 +24,9 @@ class AboutDataActivity : Activity() { val content = LinearLayout(this).apply { orientation = LinearLayout.VERTICAL setPadding( - dp(ImeSpacingTokens.XL_DP), dp(ImeSpacingTokens.LG_DP), - dp(ImeSpacingTokens.XL_DP), + 0, + dp(ImeSpacingTokens.LG_DP), dp(ImeSpacingTokens.XXL_DP), ) addView( @@ -34,23 +38,20 @@ class AboutDataActivity : Activity() { LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, dp(ImeGeometryTokens.TOP_BAR_HEIGHT_DP), - ), + ).apply { marginStart = -dp(16); marginEnd = -dp(16) }, ) addView( infoCard( - title = "openIME " + versionName(), + title = "隐私", body = "本应用不含联网权限,数据只存在本机。", ), - wrap().apply { topMargin = dp(ImeSpacingTokens.MD_DP) }, + wrap().apply { topMargin = dp(ImeSpacingTokens.LG_DP) }, ) - addView( - infoCard( - title = "用户数据", - body = "JSON 导出包含常用语、自定义符号、备用用户词条和设置项;剪贴板历史不导出。Rime 自动学习词库在已加载时一并导出,并在导入时按词库合并。", - ), - wrap().apply { topMargin = dp(ImeSpacingTokens.MD_DP) }, + val dataCard = infoCard( + title = "用户数据", + body = "JSON 导出包含常用语、自定义符号、备用用户词条和设置项;剪贴板历史不导出。Rime 自动学习词库在已加载时一并导出,并在导入时按词库合并。", ) - + addView(dataCard, wrap().apply { topMargin = dp(12) }) val actions = LinearLayout(this@AboutDataActivity).apply { orientation = LinearLayout.HORIZONTAL addView( @@ -59,7 +60,7 @@ class AboutDataActivity : Activity() { }, LinearLayout.LayoutParams( 0, - dp(ImeGeometryTokens.PRIMARY_ROW_HEIGHT_DP), + dp(44), 1f, ).apply { marginEnd = dp(ImeSpacingTokens.SM_DP) }, ) @@ -69,17 +70,17 @@ class AboutDataActivity : Activity() { }, LinearLayout.LayoutParams( 0, - dp(ImeGeometryTokens.PRIMARY_ROW_HEIGHT_DP), + dp(44), 1f, ), ) } - addView( + dataCard.addView( actions, LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, - dp(ImeGeometryTokens.PRIMARY_ROW_HEIGHT_DP), - ).apply { topMargin = dp(ImeSpacingTokens.LG_DP) }, + dp(44), + ).apply { topMargin = dp(12); marginStart = dp(44) }, ) addView( infoCard( @@ -88,6 +89,10 @@ class AboutDataActivity : Activity() { ), wrap().apply { topMargin = dp(ImeSpacingTokens.LG_DP) }, ) + addView(TextView(this@AboutDataActivity).apply { + text = "openIME · 版本 " + versionName(); textSize = 12f; gravity = android.view.Gravity.CENTER + setTextColor(getColor(R.color.setup_body)) + }, wrap().apply { topMargin = dp(18) }) } setContentView( @@ -329,24 +334,25 @@ class AboutDataActivity : Activity() { dp(ImeGeometryTokens.CARD_RADIUS_DP).toFloat(), getColor(R.color.setup_input_line), ) - addView( - TextView(this@AboutDataActivity).apply { - text = title - textSize = ImeTypographyTokens.TITLE_SP - setTextColor(getColor(R.color.setup_title)) - setTypeface(typeface, android.graphics.Typeface.BOLD) - }, - wrap(), - ) - addView( - TextView(this@AboutDataActivity).apply { - text = body - textSize = ImeTypographyTokens.BODY_SP - setTextColor(getColor(R.color.setup_body)) - setPadding(0, dp(ImeSpacingTokens.SM_DP), 0, 0) - }, - wrap(), - ) + addView(LinearLayout(this@AboutDataActivity).apply { + orientation = LinearLayout.HORIZONTAL + addView(android.widget.ImageView(this@AboutDataActivity).apply { + setImageResource(if (title == "用户数据") R.drawable.ic_download else if (title == "隐私") R.drawable.ic_shield else R.drawable.ic_info) + imageTintList = android.content.res.ColorStateList.valueOf(SetupUi.accent(this@AboutDataActivity)) + scaleType = android.widget.ImageView.ScaleType.FIT_CENTER + setPadding(dp(8), dp(8), dp(8), dp(8)) + background = SetupUi.rounded(ImeDrawableFactory.blend(SetupUi.accent(this@AboutDataActivity), getColor(R.color.setup_surface), 0.14f), dp(8).toFloat()) + }, LinearLayout.LayoutParams(dp(32), dp(32)).apply { marginEnd = dp(12) }) + addView(LinearLayout(this@AboutDataActivity).apply { + orientation = LinearLayout.VERTICAL + addView(TextView(this@AboutDataActivity).apply { + text = title; textSize = 14f; setTextColor(getColor(R.color.setup_title)); typeface = android.graphics.Typeface.create("sans-serif-medium", android.graphics.Typeface.NORMAL) + }, wrap()) + addView(TextView(this@AboutDataActivity).apply { + text = body; textSize = 14f; setTextColor(getColor(R.color.setup_body)); setLineSpacing(0f, 1.3f) + }, wrap().apply { topMargin = dp(4) }) + }, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)) + }, wrap()) } @Suppress("DEPRECATION") diff --git a/app/src/main/java/llc/slacker/openime/CandidateBarController.kt b/app/src/main/java/llc/slacker/openime/CandidateBarController.kt index 071e504a..6eb75e93 100644 --- a/app/src/main/java/llc/slacker/openime/CandidateBarController.kt +++ b/app/src/main/java/llc/slacker/openime/CandidateBarController.kt @@ -105,6 +105,7 @@ internal class CandidateBarController( compositionPreview: String, showCompositionWhenEmpty: Boolean, ) { + syncExpandControl(candidates.isNotEmpty()) val visibleCandidates = candidates.take(STRIP_LIMIT) if (renderedCandidates == visibleCandidates && renderedComposition == compositionPreview) return @@ -149,8 +150,8 @@ internal class CandidateBarController( createItem(index, candidate), LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), - ).apply { marginEnd = toPx(6) }, + toPx(42), + ).apply { marginEnd = toPx(4) }, ) } else { bindItem(existing, index, candidate) @@ -218,7 +219,7 @@ internal class CandidateBarController( } val previousScroll = if (renderedExpandedComposition == compositionPreview) { - (overlay.getChildAt(1) as? ScrollView)?.scrollY ?: 0 + (overlay.getChildAt(0) as? ScrollView)?.scrollY ?: 0 } else { 0 } @@ -238,14 +239,6 @@ internal class CandidateBarController( overlay.alpha = 0f overlay.translationY = toPx(8).toFloat() overlay.removeAllViews() - overlay.addView( - createHeader(), - LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), - ), - ) - val scroll = ScrollView(context) val column = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL @@ -265,12 +258,14 @@ internal class CandidateBarController( } chunk.forEach { candidate -> rowView.addView( - createExpandedCandidate(candidate), + createExpandedCandidate(candidate).apply { + tag = if (candidate == candidates.first()) "candidate-grid-first" else "candidate-grid" + }, LinearLayout.LayoutParams( 0, keyRowHeightPx(), candidateColumnSpan(candidate).toFloat(), - ).apply { marginEnd = toPx(5) }, + ), ) } val remaining = 4 - chunk.sumOf(::candidateColumnSpan) @@ -329,7 +324,7 @@ internal class CandidateBarController( LinearLayout(context).apply { orientation = LinearLayout.HORIZONTAL gravity = Gravity.CENTER_VERTICAL - minimumHeight = toPx(ImeGeometryTokens.TOUCH_TARGET_DP) + minimumHeight = toPx(42) isFocusable = true importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES isClickable = true @@ -360,9 +355,9 @@ internal class CandidateBarController( val palette = tokens() val normalBackground = - if (index == 0) ImeSurfacePolicy.selectedSurface(palette) else Color.TRANSPARENT + if (index == 0) palette.keyBackground else Color.TRANSPARENT word.setTextColor( - if (index == 0) ImeSurfacePolicy.selectedText(palette) else palette.candidateText, + palette.candidateText, ) item.background = statefulBackground( normalBackground, @@ -403,7 +398,7 @@ internal class CandidateBarController( dialog.setOnShowListener { SetupUi.styleDialog(dialog, context, destructivePositive = true) } - dialog.show() + SetupUi.showDialog(dialog, context, row) } private companion object { diff --git a/app/src/main/java/llc/slacker/openime/ClipboardPanelController.kt b/app/src/main/java/llc/slacker/openime/ClipboardPanelController.kt index ebeae88a..f5baaed3 100644 --- a/app/src/main/java/llc/slacker/openime/ClipboardPanelController.kt +++ b/app/src/main/java/llc/slacker/openime/ClipboardPanelController.kt @@ -13,6 +13,7 @@ import android.widget.HorizontalScrollView import android.widget.LinearLayout import android.widget.ScrollView import android.widget.TextView +import android.widget.ImageView /** * Owns clipboard/quick-phrase panel presentation and transient load state. @@ -56,41 +57,35 @@ internal class ClipboardPanelController( } fun render(reusePanel: Boolean = false) { - if (!reusePanel || expandedPanel.childCount == 0) { - expandedPanel.removeAllViews() - expandedPanel.addView( - createHeader("剪贴板"), - LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), - ), - ) - } else { - while (expandedPanel.childCount > 1) { - expandedPanel.removeViewAt(expandedPanel.childCount - 1) + expandedPanel.removeAllViews() + val header = createHeader("") + while (header.childCount > 1) header.removeViewAt(header.childCount - 1) + header.addView(LinearLayout(context).apply { + orientation = LinearLayout.HORIZONTAL; tag = "segmented-track" + setPadding(toPx(2), toPx(2), toPx(2), toPx(2)) + listOf("剪贴板", "常用语").forEachIndexed { index, label -> + addView(TextView(context).apply { + text = label; textSize = 14f; gravity = Gravity.CENTER; includeFontPadding = false + tag = if (tab == index) "segment-selected" else "segment-option" + contentDescription = label; isClickable = true; isFocusable = true + setOnClickListener { onFeedback(); tab = index; render(true) } + }, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1f)) } - } - + }, LinearLayout.LayoutParams(0, toPx(34), 1f).apply { marginStart = toPx(36); marginEnd = toPx(20) }) + header.addView(TextView(context).apply { + text = if (tab == 0) "↻" else "+ 新增" + tag = if (tab == 0) "clipboard-refresh" else "quick-phrase-add" + textSize = if (tab == 0) 24f else 12f; gravity = Gravity.CENTER + contentDescription = if (tab == 0) "重新读取剪贴板" else "新增常用语" + isClickable = true; isFocusable = true + setOnClickListener { onFeedback(); if (tab == 0) render(true) else onOpenQuickPhraseEditor(null) } + }, LinearLayout.LayoutParams(toPx(if (tab == 0) 48 else 70), toPx(34))) + expandedPanel.addView(header, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, toPx(48))) val body = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL - setPadding(toPx(10), toPx(10), toPx(10), toPx(10)) + setPadding(toPx(12), toPx(10), toPx(12), toPx(6)) tag = "clipboard-panel" } - val tabs = createChipScroll( - listOf("剪贴板", "常用语"), - if (tab == 0) "剪贴板" else "常用语", - ) { label -> - tab = if (label == "剪贴板") 0 else 1 - render(reusePanel = true) - } - body.addView( - tabs, - LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), - ).apply { bottomMargin = toPx(8) }, - ) - val column = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL } @@ -219,26 +214,12 @@ internal class ClipboardPanelController( }, LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), + toPx(36), ).apply { topMargin = toPx(8) }, ) } private fun renderQuickPhrases(column: LinearLayout) { - column.addView( - createPanelButton("新增常用语", ImeTypographyTokens.BODY_SP, true).apply { - tag = "quick-phrase-add" - setOnClickListener { - onFeedback() - onOpenQuickPhraseEditor(null) - } - }, - LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), - ).apply { bottomMargin = toPx(8) }, - ) - val phrases = QuickPhraseRepository.load(context) if (phrases.isEmpty()) { column.addView( @@ -251,14 +232,14 @@ internal class ClipboardPanelController( ) } + column.addView(createSectionTitle("${phrases.size} 条常用语 · 点选即输入"), wrapParams()) phrases.groupBy { it.category }.forEach { (category, grouped) -> - column.addView(createSectionTitle(category), wrapParams()) grouped.forEach { phrase -> column.addView( quickPhraseRow(phrase), LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), + toPx(60), ).apply { bottomMargin = toPx(7) }, ) } @@ -267,136 +248,43 @@ internal class ClipboardPanelController( private fun quickPhraseRow(phrase: QuickPhrase): LinearLayout = LinearLayout(context).apply { - orientation = LinearLayout.HORIZONTAL - tag = "phrase-card" - addView( - createKey(phrase.text, ImeTypographyTokens.BODY_SP) { - onCharacter(phrase.text) - }.apply { - setPadding(toPx(12), 0, toPx(12), 0) - tag = "phrase:${phrase.id}" - contentDescription = - if (phrase.inputCode.isBlank()) { - "常用语:${phrase.text}" - } else { - "常用语:${phrase.text},输入码${phrase.inputCode}" - } - }, - LinearLayout.LayoutParams(0, toPx(ImeGeometryTokens.TOUCH_TARGET_DP), 1f).apply { - marginEnd = toPx(5) - }, - ) - addView( - createPanelButton("编辑", ImeTypographyTokens.CAPTION_SP, true).apply { - tag = "phrase-edit:${phrase.id}" - setOnClickListener { - onFeedback() - onOpenQuickPhraseEditor(phrase) - } - }, - LinearLayout.LayoutParams(toPx(ImeGeometryTokens.TOUCH_TARGET_DP), toPx(ImeGeometryTokens.TOUCH_TARGET_DP)).apply { - marginEnd = toPx(5) - }, - ) - addView( - createPanelButton("删除", ImeTypographyTokens.CAPTION_SP, true).apply { - tag = "phrase-delete:${phrase.id}" - setOnClickListener { - onFeedback() - val dialog = AlertDialog.Builder(context) - .setTitle("删除常用语?") - .setMessage(phrase.text) - .setNegativeButton("取消", null) - .setPositiveButton("删除") { _, _ -> - QuickPhraseRepository.remove(context, phrase.id) - render(reusePanel = true) - } - .create() - dialog.setOnShowListener { - SetupUi.styleDialog( - dialog, - context, - destructivePositive = true, - ) - } - dialog.show() - } - }, - LinearLayout.LayoutParams(toPx(ImeGeometryTokens.TOUCH_TARGET_DP), toPx(ImeGeometryTokens.TOUCH_TARGET_DP)), - ) + orientation = LinearLayout.HORIZONTAL; gravity = Gravity.CENTER_VERTICAL + tag = "phrase-card"; setPadding(toPx(14), 0, toPx(4), 0) + addView(TextView(context).apply { + text = phrase.text; textSize = 16f; maxLines = 2; ellipsize = TextUtils.TruncateAt.END + tag = "phrase:${phrase.id}"; contentDescription = "常用语:${phrase.text}" + isClickable = true; isFocusable = true + setOnClickListener { onFeedback(); onCharacter(phrase.text) } + }, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1f)) + addView(iconButton(R.drawable.ic_edit, "编辑常用语", "phrase-edit:${phrase.id}") { onOpenQuickPhraseEditor(phrase) }, + LinearLayout.LayoutParams(toPx(40), toPx(48))) + addView(iconButton(R.drawable.ic_delete, "删除常用语", "phrase-delete:${phrase.id}") { + val dialog = AlertDialog.Builder(context).setTitle("删除常用语?").setMessage("“${phrase.text}” 将被移除。") + .setNegativeButton("取消", null).setPositiveButton("删除") { _, _ -> QuickPhraseRepository.remove(context, phrase.id); render(true) }.create() + dialog.setOnShowListener { SetupUi.styleDialog(dialog, context, destructivePositive = true) } + SetupUi.showDialog(dialog, context, expandedPanel) + }, LinearLayout.LayoutParams(toPx(40), toPx(48))) } private fun historyCard(entry: ClipboardEntry): LinearLayout = LinearLayout(context).apply { - orientation = LinearLayout.VERTICAL - setPadding(toPx(12), toPx(10), toPx(12), toPx(8)) - minimumHeight = toPx(70) - tag = "clip-card" - contentDescription = "剪贴板:${entry.text},点击使用" - if (Build.VERSION.SDK_INT >= 30) { - stateDescription = if (entry.pinned) "已置顶" else "未置顶" - } - isClickable = true - isFocusable = true - setOnClickListener { - onFeedback() - onCharacter(entry.text) - } - - addView( - TextView(context).apply { - text = entry.text - textSize = ImeTypographyTokens.PANEL_BODY_SP - maxLines = 2 - ellipsize = TextUtils.TruncateAt.END - }, - wrapParams(), - ) + orientation = LinearLayout.HORIZONTAL; gravity = Gravity.CENTER_VERTICAL + setPadding(toPx(14), toPx(4), toPx(4), toPx(4)); minimumHeight = toPx(56) + tag = "clip-card"; contentDescription = "剪贴板:${entry.text},点击使用" + isClickable = true; isFocusable = true + setOnClickListener { onFeedback(); onCharacter(entry.text) } + addView(TextView(context).apply { text = entry.text; textSize = 16f; maxLines = 1; ellipsize = TextUtils.TruncateAt.END }, + LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)) + addView(iconButton(R.drawable.ic_pin, if (entry.pinned) "取消置顶" else "置顶", "clip-pin:${entry.text}") { + ClipboardHistoryRepository.togglePin(context, entry.text); render(true) + }.apply { isSelected = entry.pinned }, LinearLayout.LayoutParams(toPx(40), toPx(48))) + } - val meta = LinearLayout(context).apply { - orientation = LinearLayout.HORIZONTAL - } - meta.addView( - TextView(context).apply { - text = if (entry.pinned) { - "已置顶" - } else { - DateUtils.getRelativeTimeSpanString( - entry.timestamp, - System.currentTimeMillis(), - DateUtils.MINUTE_IN_MILLIS, - ) - } - textSize = ImeTypographyTokens.CAPTION_SP - }, - LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f), - ) - meta.addView( - createPanelButton( - if (entry.pinned) "取消置顶" else "置顶", - ImeTypographyTokens.CAPTION_SP, - true, - ).apply { - tag = "clip-pin:${entry.text}" - setOnClickListener { - onFeedback() - ClipboardHistoryRepository.togglePin(context, entry.text) - render(reusePanel = true) - } - }, - wrapParams(), - ) - meta.addView( - createPanelButton("使用", ImeTypographyTokens.CAPTION_SP, true).apply { - tag = "clip-use:${entry.text}" - setOnClickListener { - onFeedback() - onCharacter(entry.text) - } - }, - wrapParams(), - ) - addView(meta, wrapParams()) + private fun iconButton(icon: Int, label: String, tagValue: String, onClick: () -> Unit): ImageView = + ImageView(context).apply { + setImageResource(icon); scaleType = ImageView.ScaleType.CENTER_INSIDE + tag = tagValue; contentDescription = label; isClickable = true; isFocusable = true + setOnClickListener { onFeedback(); onClick() } } private fun addRetentionControls(body: LinearLayout) { @@ -412,7 +300,7 @@ internal class ClipboardPanelController( render(reusePanel = true) focusEntryPoint() }, - LinearLayout.LayoutParams(0, toPx(ImeGeometryTokens.TOUCH_TARGET_DP), 1f).apply { + LinearLayout.LayoutParams(0, toPx(36), 1f).apply { marginEnd = toPx(6) }, ) @@ -420,13 +308,13 @@ internal class ClipboardPanelController( retentionAction("清空全部", destructive = true) { showClearConfirmation(body) }, - LinearLayout.LayoutParams(0, toPx(ImeGeometryTokens.TOUCH_TARGET_DP), 1f), + LinearLayout.LayoutParams(0, toPx(36), 1f), ) body.addView( row, LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), + toPx(36), ).apply { topMargin = toPx(6) }, ) applyTheme() @@ -445,7 +333,7 @@ internal class ClipboardPanelController( render(reusePanel = true) focusEntryPoint() }, - LinearLayout.LayoutParams(0, toPx(ImeGeometryTokens.TOUCH_TARGET_DP), 1f).apply { + LinearLayout.LayoutParams(0, toPx(36), 1f).apply { marginEnd = toPx(6) }, ) @@ -458,13 +346,13 @@ internal class ClipboardPanelController( tag = "clipboard-clear-confirm" contentDescription = "确认清空全部剪贴历史" }, - LinearLayout.LayoutParams(0, toPx(ImeGeometryTokens.TOUCH_TARGET_DP), 1f), + LinearLayout.LayoutParams(0, toPx(36), 1f), ) body.addView( row, LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), + toPx(36), ).apply { topMargin = toPx(6) }, ) applyTheme() @@ -479,8 +367,8 @@ internal class ClipboardPanelController( text = label textSize = ImeTypographyTokens.PANEL_NOTE_SP gravity = Gravity.CENTER - minHeight = toPx(ImeGeometryTokens.TOUCH_TARGET_DP) - minimumHeight = toPx(ImeGeometryTokens.TOUCH_TARGET_DP) + minHeight = 0 + minimumHeight = 0 isClickable = true isFocusable = true tag = if (destructive) { diff --git a/app/src/main/java/llc/slacker/openime/EmojiCellFactory.kt b/app/src/main/java/llc/slacker/openime/EmojiCellFactory.kt index db2515d5..8c6ce47e 100644 --- a/app/src/main/java/llc/slacker/openime/EmojiCellFactory.kt +++ b/app/src/main/java/llc/slacker/openime/EmojiCellFactory.kt @@ -18,6 +18,7 @@ import java.util.concurrent.Executors */ internal class EmojiCellFactory( private val context: Context, + private val toPx: (Int) -> Int = { (it * context.resources.displayMetrics.density).toInt() }, private val onFeedback: () -> Unit, private val onEmojiSelected: (String) -> Unit, ) { @@ -53,10 +54,7 @@ internal class EmojiCellFactory( } cell.addView( image, - FrameLayout.LayoutParams( - FrameLayout.LayoutParams.MATCH_PARENT, - FrameLayout.LayoutParams.MATCH_PARENT, - ), + FrameLayout.LayoutParams(toPx(28), toPx(28)).apply { gravity = Gravity.CENTER }, ) requestBitmap(context, assetPath) { bitmap -> if (image.tag == assetPath) { @@ -74,6 +72,8 @@ internal class EmojiCellFactory( return cell } + private fun dp(value: Int): Int = (value * context.resources.displayMetrics.density).toInt() + private companion object { private const val CACHE_BYTES = 4 * 1024 * 1024 diff --git a/app/src/main/java/llc/slacker/openime/FloatingKeyboardController.kt b/app/src/main/java/llc/slacker/openime/FloatingKeyboardController.kt index c3efa443..fc931652 100644 --- a/app/src/main/java/llc/slacker/openime/FloatingKeyboardController.kt +++ b/app/src/main/java/llc/slacker/openime/FloatingKeyboardController.kt @@ -71,6 +71,8 @@ internal class FloatingKeyboardController( fun applyTheme(tokens: ImeTheme.Tokens) { (handle as? DragHandleView)?.setDotColor(tokens.border) + handle.setBackgroundColor(tokens.toolbarBackground) + mainDock.elevation = if (enabled) toPx(10).toFloat() else 0f if (enabled) { mainDock.background = ImeDrawableFactory.rounded( tokens.keyboardBackground, @@ -104,21 +106,13 @@ internal class FloatingKeyboardController( override fun onDraw(canvas: Canvas) { super.onDraw(canvas) - val radius = toPx(2) - val gapX = toPx(7) - val gapY = toPx(7) - val startX = width / 2f - gapX - val startY = height / 2f - gapY / 2f - for (row in 0..1) { - for (column in 0..2) { - canvas.drawCircle( - startX + column * gapX, - startY + row * gapY, - radius.toFloat(), - dotPaint, - ) - } - } + val halfWidth = toPx(18).toFloat() + val halfHeight = toPx(2).toFloat() + canvas.drawRoundRect( + width / 2f - halfWidth, height / 2f - halfHeight, + width / 2f + halfWidth, height / 2f + halfHeight, + halfHeight, halfHeight, dotPaint, + ) } } } diff --git a/app/src/main/java/llc/slacker/openime/FloatingWindowController.kt b/app/src/main/java/llc/slacker/openime/FloatingWindowController.kt index 365dd65d..1f80ec0c 100644 --- a/app/src/main/java/llc/slacker/openime/FloatingWindowController.kt +++ b/app/src/main/java/llc/slacker/openime/FloatingWindowController.kt @@ -158,7 +158,7 @@ internal class FloatingWindowController( private fun floatingWidth(screenWidth: Int): Int { val landscape = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE - val percent = floatingWidthPercent().coerceIn(72, 96) + val percent = floatingWidthPercent().coerceIn(72, 100) val preferred = (screenWidth * percent / 100f).toInt() val maximum = dp( if (landscape) ImeGeometryTokens.FLOATING_LANDSCAPE_WIDTH_DP else 420, diff --git a/app/src/main/java/llc/slacker/openime/FluentEmojiAssetRepository.kt b/app/src/main/java/llc/slacker/openime/FluentEmojiAssetRepository.kt index d0d55eca..7f44066d 100644 --- a/app/src/main/java/llc/slacker/openime/FluentEmojiAssetRepository.kt +++ b/app/src/main/java/llc/slacker/openime/FluentEmojiAssetRepository.kt @@ -7,11 +7,11 @@ object FluentEmojiAssetRepository { private const val ROOT = "emoji/fluent" @Volatile - private var availableFiles: Set? = null + private var availableFiles: Map? = null fun pathFor(context: Context, emoji: String): String? { val fileName = fileNameFor(emoji) - return if (fileName in files(context)) "$ROOT/$fileName" else null + return files(context)[fileName] } internal fun fileNameFor(emoji: String): String = @@ -24,12 +24,15 @@ object FluentEmojiAssetRepository { * merely to probe whether a PNG existed. List the directory once per * process instead; actual bitmap decoding remains on the background pool. */ - private fun files(context: Context): Set { + private fun files(context: Context): Map { availableFiles?.let { return it } return synchronized(this) { availableFiles ?: runCatching { - context.applicationContext.assets.list(ROOT)?.toSet().orEmpty() - }.getOrDefault(emptySet()).also { availableFiles = it } + val assets = context.applicationContext.assets + val bundled = assets.list(ROOT).orEmpty().associateWith { "$ROOT/$it" } + val reference = "emoji/reference" + bundled + assets.list(reference).orEmpty().associateWith { "$reference/$it" } + }.getOrDefault(emptyMap()).also { availableFiles = it } } } } diff --git a/app/src/main/java/llc/slacker/openime/ImeDesignTokens.kt b/app/src/main/java/llc/slacker/openime/ImeDesignTokens.kt index 8dac18cc..4d45a746 100644 --- a/app/src/main/java/llc/slacker/openime/ImeDesignTokens.kt +++ b/app/src/main/java/llc/slacker/openime/ImeDesignTokens.kt @@ -25,7 +25,7 @@ internal object ImeGeometryTokens { const val FIELD_HEIGHT_DP = 56 const val PRIMARY_ROW_HEIGHT_DP = 56 const val SETTING_ROW_HEIGHT_DP = 56 - const val TOOL_CARD_HEIGHT_DP = 64 + const val TOOL_CARD_HEIGHT_DP = 92 const val VOICE_CONTROL_HEIGHT_DP = TOUCH_TARGET_DP const val SWITCH_WIDTH_DP = 48 const val SWITCH_HEIGHT_DP = 28 @@ -44,7 +44,7 @@ internal object ImeGeometryTokens { // The toolbar itself is compact; the top zone still reserves the larger // composed height so typing never moves the keyboard window. const val TOOLBAR_HEIGHT_DP = TOUCH_TARGET_DP - const val TOP_BAR_HEIGHT_DP = 56 + const val TOP_BAR_HEIGHT_DP = 48 const val ICON_SIZE_DP = 24 const val STEP_MARK_SIZE_DP = 28 const val HERO_MARK_SIZE_DP = 72 @@ -149,23 +149,24 @@ enum class ImeTheme(val key: String, val label: String) { } val base = if (useDark) { Tokens( - c("#6EC3F7"), c("#1C1C1E"), c("#242426"), c("#262628"), c("#F2F2F7"), + c("#6EC3F7"), c("#1C1C1E"), c("#242426"), c("#242426"), c("#F2F2F7"), c("#3A3A3C"), c("#F2F2F7"), c("#AEAEB2"), c("#2C2C2E"), c("#F2F2F7"), c("#4A4A4D"), - c("#242426"), c("#48484A"), c("#2C2C2E"), c("#202022"), c("#242426"), - c("#3A3A3C"), c("#F2F2F7"), c("#2C2C2E"), c("#F2F2F7"), c("#303033"), c("#242426"), + c("#242426"), c("#48484A"), c("#2C2C2E"), c("#1C1C1E"), c("#242426"), + c("#3A3A3C"), c("#F2F2F7"), c("#2C2C2E"), c("#F2F2F7"), c("#303032"), c("#242426"), success = c("#5BD08A"), ) } else { Tokens( - c("#1D9BF0"), c("#D5D8DE"), c("#EEF0F3"), c("#F7F8FA"), c("#1F2023"), - c("#FFFFFF"), c("#1C1C1E"), c("#6E6E73"), c("#C5C9D1"), c("#2C2D31"), c("#DDE1E7"), - c("#F2F3F5"), c("#B7BCC5"), c("#C5C9D1"), c("#F1F2F4"), c("#F8F9FA"), - c("#FFFFFF"), c("#1C1C1E"), c("#C5C9D1"), c("#2C2D31"), c("#FFFFFF"), c("#E4E7EB"), + c("#1D9BF0"), c("#D5D8DF"), c("#EFF0F4"), c("#EFF0F4"), c("#1F2023"), + c("#FFFFFF"), c("#1C1C1E"), c("#6D6D72"), c("#C5C9D2"), c("#2C2D31"), c("#DDE1E7"), + c("#F2F3F5"), c("#B7BCC5"), c("#C5C9D2"), c("#F1F2F4"), c("#F8F9FA"), + c("#FFFFFF"), c("#1C1C1E"), c("#C5C9D2"), c("#2C2D31"), c("#FFFFFF"), c("#E4E7EC"), success = c("#1F8A4C"), textSecondaryRole = c("#6D6D72"), ) } val accent = accentOverride ?: return base + if (accent == AccentPalette.parse(AccentPalette.DEFAULT)) return base return base.copy(primary = accent) } } @@ -184,18 +185,12 @@ internal object ImeSurfacePolicy { fun selectedSurface(tokens: ImeTheme.Tokens): Int = ImeDrawableFactory.blend( tokens.primary, - tokens.candidateBackground, - if (isDark(tokens)) 0.24f else 0.12f, + tokens.keyboardBackground, + if (isDark(tokens)) 0.24f else 0.14f, ) fun selectedText(tokens: ImeTheme.Tokens): Int = - if ( - ImeContrastPolicy.contrastRatio(tokens.primary, selectedSurface(tokens)) >= 4.5 - ) { - tokens.primary - } else { - tokens.keyText - } + if (isDark(tokens)) tokens.primary else Color.parseColor("#006AB1") fun pressedSurface(base: Int, tokens: ImeTheme.Tokens): Int = ImeDrawableFactory.blend( diff --git a/app/src/main/java/llc/slacker/openime/ImeKeyView.kt b/app/src/main/java/llc/slacker/openime/ImeKeyView.kt index c1649360..1d01df88 100644 --- a/app/src/main/java/llc/slacker/openime/ImeKeyView.kt +++ b/app/src/main/java/llc/slacker/openime/ImeKeyView.kt @@ -29,6 +29,7 @@ class ImeKeyView( iconRes: Int = 0, mainTextSize: Float = ImeTypographyTokens.KEY_LETTER_SP, fitMainText: Boolean = false, + private val toPx: (Int) -> Int = { (it * context.resources.displayMetrics.density).toInt() }, ) : FrameLayout(context) { private val density = resources.displayMetrics.density @@ -89,6 +90,7 @@ class ImeKeyView( private val mainTextView: TextView? private val secondaryTextView: TextView? private val iconView: ImageView? + private var returnIcon: ImageView? = null init { isClickable = true @@ -166,17 +168,17 @@ class ImeKeyView( addView( view, FrameLayout.LayoutParams( - dp(if (text.isEmpty()) 20 else 16), - dp(if (text.isEmpty()) 20 else 16), + dp(if (text.isEmpty()) { if (iconRes == R.drawable.ic_backspace) 24 else 20 } else 10), + dp(if (text.isEmpty()) { if (iconRes == R.drawable.ic_backspace) 24 else 20 } else 10), ).apply { gravity = if (text.isEmpty()) { Gravity.CENTER } else { - Gravity.BOTTOM or Gravity.END + Gravity.TOP or Gravity.END } if (text.isNotEmpty()) { rightMargin = dp(6) - bottomMargin = dp(4) + topMargin = dp(4) } }, ) @@ -207,12 +209,14 @@ class ImeKeyView( }, ) } + if (text == "↵") setMainText(text) } fun setColors(mainColor: Int = Color.BLACK, secondaryColor: Int = Color.GRAY, iconColor: Int = mainColor) { mainTextView?.setTextColor(mainColor) secondaryTextView?.setTextColor(secondaryColor) iconView?.imageTintList = ColorStateList.valueOf(iconColor) + returnIcon?.imageTintList = ColorStateList.valueOf(mainColor) } val currentMainText: String @@ -220,12 +224,26 @@ class ImeKeyView( fun setMainText(value: String) { mainTextView?.text = value + if (value == "↵" && returnIcon == null) { + returnIcon = ImageView(context).apply { + setImageResource(R.drawable.ic_return) + scaleType = ImageView.ScaleType.FIT_CENTER + imageTintList = ColorStateList.valueOf(mainTextView?.currentTextColor ?: Color.BLACK) + importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO + }.also { addView(it, FrameLayout.LayoutParams(dp(24), dp(24), Gravity.CENTER)) } + } + returnIcon?.visibility = if (value == "↵") View.VISIBLE else View.GONE + mainTextView?.visibility = if (value == "↵") View.INVISIBLE else View.VISIBLE contentDescription = value } /** Update key typography without rebuilding the keyboard hierarchy. */ fun applyMainTextScale(scale: Float) { - mainTextView?.textSize = baseMainTextSize * scale.coerceAtLeast(0.5f) + mainTextView?.apply { + setAutoSizeTextTypeWithDefaults(TextView.AUTO_SIZE_TEXT_TYPE_NONE) + textSize = baseMainTextSize * scale.coerceAtLeast(0.4f) + } + secondaryTextView?.textSize = ImeTypographyTokens.CAPTION_SP * (toPx(100) / (100f * density)) } /** @@ -254,5 +272,5 @@ class ImeKeyView( iconView.setImageResource(value) } - private fun dp(value: Int): Int = (value * density).toInt() + private fun dp(value: Int): Int = toPx(value) } diff --git a/app/src/main/java/llc/slacker/openime/ImeKeyboardView.kt b/app/src/main/java/llc/slacker/openime/ImeKeyboardView.kt index 9f4bf482..980d5be7 100644 --- a/app/src/main/java/llc/slacker/openime/ImeKeyboardView.kt +++ b/app/src/main/java/llc/slacker/openime/ImeKeyboardView.kt @@ -226,16 +226,19 @@ open class ImeKeyboardView( } // Only these configuration values change the derived row and IME heights. private var appliedOrientation = resources.configuration.orientation + private var appliedScreenWidthDp = resources.configuration.screenWidthDp private var appliedFontScale = resources.configuration.fontScale private var appliedDensityDpi = resources.displayMetrics.densityDpi private var keyboardHandedness = ImeSettingsRepository.loadHandedness(context) private var keyboardHeightPercent = ImeSettingsRepository.loadKeyboardHeightPercent(context) private var floatingWidthPercent = ImeSettingsRepository.loadFloatingWidthPercent(context) private var floatingOpacityPercent = ImeSettingsRepository.loadFloatingOpacityPercent(context) + private var referenceScale = ImeReferenceSizing.scale(context) private var layoutMetrics = KeyboardLayoutMetrics( landscape = appliedOrientation == android.content.res.Configuration.ORIENTATION_LANDSCAPE, fontScale = appliedFontScale, heightPercent = keyboardHeightPercent, + availableWidthDp = resources.configuration.screenWidthDp, ) private var lastTextMode = KeyboardMode.PINYIN_26 private var preferredChineseMode = ImeSettingsRepository.loadPreferredChineseMode(context) @@ -247,6 +250,11 @@ open class ImeKeyboardView( fun currentPanel(): Panel = panel /** Persist the standalone settings panel's viewport across Activity recreation. */ + internal fun editAccentColor() { + showPanel(Panel.SKIN_SETTINGS) + settingsPanelController.showCustomAccentDialog() + } + internal fun settingsScrollPosition(): Int = settingsPanelController.scrollPosition() @@ -277,13 +285,13 @@ open class ImeKeyboardView( } private var shiftState = ShiftState.LOWERCASE - private var soundEnabled = true - private var hapticEnabled = true + private var soundEnabled = ImeSettingsRepository.loadSound(context) + private var hapticEnabled = ImeSettingsRepository.loadHaptic(context) private val audioManager by lazy { context.getSystemService(Context.AUDIO_SERVICE) as? AudioManager } - private var popupEnabled = false - private var fuzzyEnabled = false + private var popupEnabled = ImeSettingsRepository.loadPopup(context) + private var fuzzyEnabled = ImeSettingsRepository.loadFuzzy(context) private var skinRadius = ImeSettingsRepository.loadSkinRadius(context) private var skinOpacity = ImeSettingsRepository.loadSkinOpacity(context) private var skinFontSize = ImeSettingsRepository.loadSkinFont(context) @@ -311,13 +319,14 @@ open class ImeKeyboardView( onDock = { listener.onFloatingKeyboardChanged(false) }, ) } - private var contentInsetPx = dp(5) + private var contentInsetPx = dp(0) private var navigationBottomInsetPx = 0 private val themeApplier: ImeThemeApplier by lazy { ImeThemeApplier( toPx = ::dp, statefulRounded = ::statefulRounded, keyMainTextScale = ::skinFontScale, + referenceScale = { referenceScale }, skinRadiusPx = { dp(skinRadius) }, skinOpacity = { skinOpacity }, skinPrimaryColor = { skinPrimaryColor }, @@ -428,16 +437,16 @@ open class ImeKeyboardView( onEnter = listener::onEnter, ) } + private var floatingWindowMode = false private var systemBottomInsetPx = 0 private val maxContentWidthDp = 600 - // Portrait keeps the historical 296dp total. Landscape uses a compact - // keyboard, and key rows grow with the system font scale so sp labels are - // never clipped inside a fixed-height key. + // Portrait row height follows the available screen width. Landscape stays + // compact; larger system fonts and the height preference grow the rows. private fun keyRowHeightDp(): Int = layoutMetrics.keyRowHeightDp private fun nineGridHeightDp(): Int = layoutMetrics.nineGridHeightDp private fun nineBodyHeightDp(): Int = layoutMetrics.nineBodyHeightDp private fun doubleKeyHeightDp(): Int = layoutMetrics.doubleKeyHeightDp - private fun imeHeightDp(): Int = layoutMetrics.imeHeightDp + private fun imeHeightDp(): Int = layoutMetrics.imeHeightDp + if (floatingWindowMode) 20 else 0 /** The top zone is reserved at its composed height in every state. */ private fun topZoneHeightDp(): Int = layoutMetrics.topZoneHeightDp @@ -461,6 +470,7 @@ open class ImeKeyboardView( private val emojiCellFactory: EmojiCellFactory by lazy { EmojiCellFactory( context = context, + toPx = ::dp, onFeedback = ::feedback, onEmojiSelected = listener::onEmojiSelected, ) @@ -566,7 +576,7 @@ open class ImeKeyboardView( toPx = ::dp, createHeader = panelHeaderFactory::create, createSectionTitle = ::sectionTitle, - createChipScroll = panelRenderer::panelChipScroll, + createChipScroll = { labels, selected, onSelected -> panelRenderer.panelChipScroll(labels, selected, onSelected) }, currentTheme = { theme }, currentAppearance = { appearance }, currentSound = { soundEnabled }, @@ -604,6 +614,7 @@ open class ImeKeyboardView( onKeyboardHeightChanged = ::setKeyboardHeightPercent, onFloatingStyleChanged = ::setFloatingStyle, onShowFuzzySettings = { showPanel(Panel.FUZZY_SETTINGS) }, + onShowSkinSettings = { showPanel(Panel.SKIN_SETTINGS) }, onOpenAboutData = listener::onOpenAboutData, onFeedback = ::feedback, applyTheme = ::applyTheme, @@ -628,7 +639,7 @@ open class ImeKeyboardView( }, createPanelButton = ::button, createSectionTitle = ::sectionTitle, - createChipScroll = panelRenderer::panelChipScroll, + createChipScroll = { labels, selected, onSelected -> panelRenderer.panelChipScroll(labels, selected, onSelected) }, createVerticalScroll = panelRenderer::panelVerticalScroll, rememberVerticalScroll = panelRenderer::rememberPanelVerticalScroll, onCharacter = listener::onCharacter, @@ -696,20 +707,6 @@ open class ImeKeyboardView( init { tag = "ime_root" - setOnApplyWindowInsetsListener { _, insets -> - val reported = if (Build.VERSION.SDK_INT >= 30) { - insets.getInsets(WindowInsets.Type.navigationBars()).bottom - } else { - @Suppress("DEPRECATION") - insets.systemWindowInsetBottom - } - val next = ImeBottomInsetPolicy.clampInset(reported, dp(32)) - if (next != navigationBottomInsetPx) { - navigationBottomInsetPx = next - requestLayout() - } - insets - } // Some IME windows inherit the host's disabled sound-effect flag. // Keep the view channel enabled; the preference still gates feedback(). isSoundEffectsEnabled = true @@ -745,7 +742,7 @@ open class ImeKeyboardView( } keyboardBody.orientation = LinearLayout.VERTICAL keyboardBody.tag = "keyboard-body" - keyboardBody.setPadding(dp(5), dp(6), dp(5), dp(16)) + keyboardBody.setPadding(dp(0), dp(6), dp(0), dp(10)) expandedPanel.orientation = LinearLayout.VERTICAL expandedPanel.tag = "panel-overlay" expandedPanel.visibility = View.GONE @@ -767,12 +764,9 @@ open class ImeKeyboardView( FrameLayout.LayoutParams.MATCH_PARENT, ), ) - keyboardHost.addView( + mainDock.addView( floatingKeyboardController.handle, - FrameLayout.LayoutParams(dp(ImeGeometryTokens.TOUCH_TARGET_DP), dp(24)).apply { - gravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL - bottomMargin = dp(4) - }, + LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, dp(20)), ) buildTopZone() @@ -804,6 +798,12 @@ open class ImeKeyboardView( @Suppress("DEPRECATION") insets.systemWindowInsetBottom }.coerceAtMost(dp(32)) + val next = if (floatingWindowMode) 0 else ImeBottomInsetPolicy.clampInset(systemBottomInsetPx, dp(32)) + if (next != navigationBottomInsetPx) { + navigationBottomInsetPx = next + applyDynamicHeights() + requestLayout() + } updateResponsiveGeometry(width) insets } @@ -821,9 +821,11 @@ open class ImeKeyboardView( // font rows take effect. Unrelated configuration changes (locale, UI mode, // keyboard presence) do not alter the derived geometry, so they must not // tear down the key surface. - val geometryChanged = newConfig.orientation != appliedOrientation || + val geometryChanged = newConfig.screenWidthDp != appliedScreenWidthDp || + newConfig.orientation != appliedOrientation || newConfig.fontScale != appliedFontScale || newConfig.densityDpi != appliedDensityDpi + appliedScreenWidthDp = newConfig.screenWidthDp appliedOrientation = newConfig.orientation appliedFontScale = newConfig.fontScale appliedDensityDpi = newConfig.densityDpi @@ -831,6 +833,7 @@ open class ImeKeyboardView( landscape = appliedOrientation == android.content.res.Configuration.ORIENTATION_LANDSCAPE, fontScale = appliedFontScale, heightPercent = keyboardHeightPercent, + availableWidthDp = resources.configuration.screenWidthDp, ) if (!geometryChanged) return // Do not yank the user out of an open panel. @@ -918,8 +921,8 @@ open class ImeKeyboardView( val totalPx = dp(imeHeightDp()) val bodyPx = dp(keyboardBodyHeightDp()) (layoutParams as? FrameLayout.LayoutParams)?.let { - if (it.height != totalPx) { - it.height = totalPx + if (it.height != totalPx + navigationBottomInsetPx) { + it.height = totalPx + navigationBottomInsetPx layoutParams = it } } @@ -944,7 +947,7 @@ open class ImeKeyboardView( } /** - * The 390dp prototype is a design reference only. Runtime geometry is + * The 390dp prototype is a design reference only. Runtime content width is * derived from the measured IME width, with a 600dp maximum on tablets and * foldables. The bottom inset is added only when the system reports one so * the last row cannot sit underneath a gesture/navigation bar. @@ -961,6 +964,18 @@ open class ImeKeyboardView( .coerceAtMost(measuredWidthPx) } + val nextScale = ImeReferenceSizing.scale(context, dockWidthPx) + if (kotlin.math.abs(nextScale - referenceScale) > 0.001f) { + val ratio = nextScale / referenceScale + referenceScale = nextScale + rescaleTopZone(topZone, ratio) + applyDynamicHeights() + if (!standalonePanel) { + if (panel == Panel.NONE) renderModeBody() else renderPanel(panel) + } + applyTheme() + } + (mainDock.layoutParams as? FrameLayout.LayoutParams)?.let { params -> if (dockWidthPx == measuredWidthPx) { params.width = FrameLayout.LayoutParams.MATCH_PARENT @@ -980,16 +995,16 @@ open class ImeKeyboardView( // A configuration pass can briefly report the physical display // width before WindowManager applies the floating window bounds. // Keep the normal keyboard's content inset local to its window. - contentInsetPx = dp(5) - keyboardBody.setPadding(contentInsetPx, dp(6), contentInsetPx, dp(16)) + contentInsetPx = dp(0) + keyboardBody.setPadding(contentInsetPx, dp(6), contentInsetPx, dp(10)) keyboardBody.findViewWithTag("key-row-secondary")?.let { row -> // The portrait layout narrows this row to 90% of the full // display for optical centering. A floating window can be // narrower than the display, so that cached width would clip // the first and last keys. Let the row fill its local window. (row.layoutParams as? LinearLayout.LayoutParams)?.let { params -> - params.width = LinearLayout.LayoutParams.MATCH_PARENT - params.gravity = Gravity.NO_GRAVITY + params.width = (dockWidthPx * 0.9f).toInt() + params.gravity = Gravity.CENTER_HORIZONTAL row.layoutParams = params } } @@ -999,14 +1014,14 @@ open class ImeKeyboardView( requestLayout() return } - val minimumInset = dp(5) - val maxWidth = dp(maxContentWidthDp) + val minimumInset = dp(0) + val maxWidth = (minOf(maxContentWidthDp.toFloat(), 390f * referenceScale) * resources.displayMetrics.density).toInt() contentInsetPx = maxOf(minimumInset, (dockWidthPx - maxWidth) / 2) keyboardBody.setPadding( contentInsetPx, dp(6), contentInsetPx, - dp(16), + dp(10), ) keyboardBody.findViewWithTag("key-row-secondary")?.let { row -> val rowWidth = ((dockWidthPx - contentInsetPx * 2) * 0.9f).toInt() @@ -1023,6 +1038,21 @@ open class ImeKeyboardView( requestLayout() } + private fun rescaleTopZone(view: View, ratio: Float) { + view.layoutParams?.let { params -> + if (params.width > 0) params.width = kotlin.math.round(params.width * ratio).toInt() + if (params.height > 0) params.height = kotlin.math.round(params.height * ratio).toInt() + if (params is ViewGroup.MarginLayoutParams) { + params.setMargins((params.leftMargin * ratio).toInt(), (params.topMargin * ratio).toInt(), (params.rightMargin * ratio).toInt(), (params.bottomMargin * ratio).toInt()) + } + view.layoutParams = params + } + view.minimumHeight = (view.minimumHeight * ratio).toInt() + view.minimumWidth = (view.minimumWidth * ratio).toInt() + view.setPadding((view.paddingLeft * ratio).toInt(), (view.paddingTop * ratio).toInt(), (view.paddingRight * ratio).toInt(), (view.paddingBottom * ratio).toInt()) + if (view is ViewGroup) for (i in 0 until view.childCount) rescaleTopZone(view.getChildAt(i), ratio) + } + /** Keep the top zone at one height so composing never relayouts the keyboard. */ private fun buildTopZone() { topZone = ImeTopZone( @@ -1035,6 +1065,7 @@ open class ImeKeyboardView( onClipboard = { showPanel(Panel.CLIPBOARD) }, onEmoji = { showPanel(Panel.EMOJI) }, onSymbols = { showPanel(Panel.SYMBOLS) }, + onTextEditor = { showPanel(Panel.TEXT_EDITOR) }, onHideKeyboard = ::hideKeyboard, onTools = { showPanel(Panel.TOOLS) }, onExpandCandidates = { @@ -1047,7 +1078,7 @@ open class ImeKeyboardView( updateTopZone(composition.text?.isNotEmpty() == true) listener.onCandidateExpanded(open) }, - onUndoClear = { listener.onUndoClear() }, + onUndoClear = { if (!listener.onUndoClear()) listener.onTextEdit("undo") }, onUndoClearExpired = listener::onUndoClearExpired, ) candidateBarController = CandidateBarController( @@ -1061,7 +1092,7 @@ open class ImeKeyboardView( keyRowHeightPx = { dp(keyRowHeightDp()) }, createHeader = { panelHeaderFactory.create("候选字词") }, createExpandedCandidate = { candidate -> - key(candidate, false, null, 1f, 15f) { + key(candidate, false, null, 1f, ImeTypographyTokens.CANDIDATE_SP) { listener.onCandidateSelected(candidate) }.apply { allowTwoLineLabel() @@ -1091,7 +1122,7 @@ open class ImeKeyboardView( topZone, LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, - dp(64), + dp(topZoneHeightDp()), ), ) candidateBarController.syncExpandControl( @@ -1216,10 +1247,13 @@ open class ImeKeyboardView( /** Keep content geometry local when the service changes the window bounds. */ fun setFloatingWindowMode(enabled: Boolean) { + floatingWindowMode = enabled + navigationBottomInsetPx = if (enabled) 0 else ImeBottomInsetPolicy.clampInset(systemBottomInsetPx, dp(32)) floatingKeyboardController.setEnabled(enabled) + applyDynamicHeights() if (enabled) { - contentInsetPx = dp(5) - keyboardBody.setPadding(contentInsetPx, dp(6), contentInsetPx, dp(16)) + contentInsetPx = dp(0) + keyboardBody.setPadding(contentInsetPx, dp(6), contentInsetPx, dp(10)) expandedPanel.setPadding(contentInsetPx, 0, contentInsetPx, 0) candidateOverlay.setPadding(contentInsetPx, 0, contentInsetPx, 0) topZone.setContentInset(contentInsetPx) @@ -1370,8 +1404,10 @@ open class ImeKeyboardView( private fun syncEnterKeyPresentation(imeOptions: Int?) { val options = imeOptions ?: return val enter = findViewWithTag("key-enter") ?: return - val label = enterKeyPresentationFor(options).label + val composing = composition.text?.isNotEmpty() == true + val label = if (composing) "确定" else if (mode == KeyboardMode.PINYIN_9 || mode == KeyboardMode.DIGITS) "↵" else enterKeyPresentationFor(options).label enter.setMainText(label) + enter.applyMainTextScale(skinFontScale()) enter.contentDescription = label } @@ -1430,11 +1466,12 @@ open class ImeKeyboardView( ).apply { marginEnd = dp(5) }, ) } + topZone.showAssociations(candidates.isNotEmpty()) applyAssociationTheme() } fun clearAssociationCandidates() { - if (::topZone.isInitialized) associationRow.removeAllViews() + if (::topZone.isInitialized) { associationRow.removeAllViews(); topZone.showAssociations(false) } } fun setTheme(newTheme: ImeTheme) { @@ -1475,7 +1512,7 @@ open class ImeKeyboardView( } private fun setKeyboardHeightPercent(percent: Int) { - val bounded = percent.coerceIn(92, 120) + val bounded = percent.coerceIn(80, 120) if (keyboardHeightPercent == bounded) return keyboardHeightPercent = bounded ImeSettingsRepository.saveKeyboardHeightPercent(context, bounded) @@ -1485,6 +1522,7 @@ open class ImeKeyboardView( landscape = appliedOrientation == android.content.res.Configuration.ORIENTATION_LANDSCAPE, fontScale = appliedFontScale, heightPercent = keyboardHeightPercent, + availableWidthDp = resources.configuration.screenWidthDp, ) applyDynamicHeights() if (!standalonePanel && panel == Panel.NONE) { @@ -1541,6 +1579,7 @@ open class ImeKeyboardView( landscape = appliedOrientation == android.content.res.Configuration.ORIENTATION_LANDSCAPE, fontScale = appliedFontScale, heightPercent = keyboardHeightPercent, + availableWidthDp = resources.configuration.screenWidthDp, ) applyDynamicHeights() if (!standalonePanel && panel == Panel.NONE) { @@ -1647,6 +1686,10 @@ open class ImeKeyboardView( internal fun findTestTarget(query: String): View? { findViewWithTag(query)?.let { return it } + // Replay scripts address letters independently of the visible shift/case. + if (query.length == 1 && query[0].lowercaseChar() in 'a'..'z') { + findViewWithTag("key:${query.lowercase()}")?.let { return it } + } fun deep(view: View): View? { val description = view.contentDescription?.toString() if (view.isClickable && (description == query || description?.substringBefore(',') == query)) return view @@ -1707,8 +1750,10 @@ open class ImeKeyboardView( } internal fun normalizedBoundsReport(): String { - val out = StringBuilder() + val origin = IntArray(2).also(::getLocationOnScreen) + val out = StringBuilder("window=${origin[0]},${origin[1]},$width,$height\n") fun deep(view: View) { + if (view.visibility != View.VISIBLE) return if (view.tag is String || (view.isClickable && !view.contentDescription.isNullOrEmpty())) { val normalized = NormalizedBounds.fromView(view, this) out.append( @@ -1747,7 +1792,7 @@ open class ImeKeyboardView( contentInsetPx, dp(6), contentInsetPx, - dp(16), + dp(10), ) val state = when { inlineVoicePresenter.active -> ImeTopZoneState.VOICE_INLINE @@ -1755,6 +1800,12 @@ open class ImeKeyboardView( composing -> ImeTopZoneState.COMPOSING else -> ImeTopZoneState.IDLE } + syncEnterKeyPresentation((context as? android.inputmethodservice.InputMethodService)?.currentInputEditorInfo?.imeOptions) + findViewWithTag("key-enter")?.let(::applyThemeToSubtree) + findViewWithTag("key-retype")?.apply { + isEnabled = composing + alpha = if (composing) 1f else ImeSurfacePolicy.DISABLED_ALPHA + } topZone.renderState( state = state, showCompositionEditor = (composing || candidateBarController.expandedOpen) && @@ -1852,7 +1903,7 @@ open class ImeKeyboardView( } private fun renderPinyin9() { - pinyin9Renderer.render(enterLabel = enterKeyLabel(false)) + pinyin9Renderer.render(enterLabel = if (composition.text?.isNotEmpty() == true) "确定" else "↵") } private fun requireNineKeySymbolRailController(): NineKeySymbolRailController { @@ -1861,6 +1912,8 @@ open class ImeKeyboardView( composition = composition, onCommit = listener::onCharacter, onFeedback = ::feedback, + cellHeightDp = ::keyRowHeightDp, + toPx = ::dp, onRailChanged = ::applyThemeToSubtree, ).also { nineKeySymbolRailController = it } } @@ -1870,7 +1923,7 @@ open class ImeKeyboardView( ?.currentInputEditorInfo numericKeyboardRenderer.render( editorKind = EditorInfoAdapter.kind(info), - enterLabel = enterKeyLabel(false, "换行"), + enterLabel = "↵", ) } @@ -2012,6 +2065,7 @@ open class ImeKeyboardView( Panel.TEXT_EDITOR -> textEditorPanelController.render() Panel.SETTINGS -> settingsPanelController.renderSettings() Panel.FUZZY_SETTINGS -> settingsPanelController.renderFuzzySettings() + Panel.SKIN_SETTINGS -> settingsPanelController.renderSettings(skinOnly = true) else -> closePanelToKeyboard() } applyTheme() @@ -2074,9 +2128,9 @@ open class ImeKeyboardView( private fun sectionTitle(textValue: String): TextView = TextView(context).apply { text = textValue - textSize = ImeTypographyTokens.TITLE_SP + textSize = 12f includeFontPadding = false - setPadding(dp(4), dp(2), 0, dp(8)) + setPadding(dp(16), dp(4), 0, dp(8)) tag = "panel-section-title" } @@ -2540,7 +2594,7 @@ open class ImeKeyboardView( } /** Key main-text size is scaled around the 17sp default from the skin font slider. */ - private fun skinFontScale(): Float = skinFontSize / 17f.coerceAtLeast(1f) + private fun skinFontScale(): Float = skinFontSize / 21f * referenceScale private fun key( text: String, @@ -2562,6 +2616,7 @@ open class ImeKeyboardView( ImeTypographyTokens.KEY_LETTER_SP }, fitMainText = func || text.length > 2, + toPx = ::dp, ).apply { tag = "key:$text" setTag(MARK_FUNCTION_KEY, func) @@ -2651,11 +2706,11 @@ open class ImeKeyboardView( mainDock.setBackgroundColor(t.keyboardBackground) keyboardBody.setBackgroundColor(t.keyboardBackground) topZone.setBackgroundColor(t.toolbarBackground) - expandedPanel.setBackgroundColor(t.expandedBackground) + expandedPanel.setBackgroundColor(if (standalonePanel) t.toolbarBackground else t.keyboardBackground) candidateOverlay.setBackgroundColor(t.expandedBackground) themeApplier.apply(this, t) - composition.setTextColor(t.keySecondaryText) - topZone.candidateExpandButton.imageTintList = android.content.res.ColorStateList.valueOf(t.keySecondaryText) + composition.setTextColor(if (ImeSurfacePolicy.isDark(t)) t.primary else android.graphics.Color.parseColor("#006AB1")) + topZone.candidateExpandButton.imageTintList = android.content.res.ColorStateList.valueOf(t.keyText) topZone.candidateEmojiButton.imageTintList = android.content.res.ColorStateList.valueOf(t.keySecondaryText) floatingKeyboardController.applyTheme(t) inlineVoicePresenter.refreshPalette() @@ -2690,23 +2745,16 @@ open class ImeKeyboardView( return ImeFocusRingPolicy.resolve(background, AccentPalette.parse(skinPrimaryColor)) } - private fun dp(value: Int): Int = (value * resources.displayMetrics.density).toInt() + private fun dp(value: Int): Int = kotlin.math.round(value * resources.displayMetrics.density * referenceScale).toInt() private fun gridCellParams( heightDp: Int, columns: Int, gapDp: Int, ): LinearLayout.LayoutParams { - val available = (width - contentInsetPx * 2 - dp(20)).coerceAtLeast(0) - val gap = dp(gapDp) - val cellWidth = if (width > 0) { - ((available - gap * (columns - 1)) / columns).coerceAtLeast(dp(1)) - } else { - 0 - } - return if (width > 0) { - LinearLayout.LayoutParams(cellWidth, dp(heightDp)).apply { marginEnd = gap } - } else { - LinearLayout.LayoutParams(0, dp(heightDp), 1f).apply { marginEnd = gap } + require(columns > 0) + return LinearLayout.LayoutParams(0, dp(heightDp), 1f).apply { + marginStart = dp(gapDp) / 2 + marginEnd = dp(gapDp) / 2 } } diff --git a/app/src/main/java/llc/slacker/openime/ImePanelRenderer.kt b/app/src/main/java/llc/slacker/openime/ImePanelRenderer.kt index 221efa85..4b97c950 100644 --- a/app/src/main/java/llc/slacker/openime/ImePanelRenderer.kt +++ b/app/src/main/java/llc/slacker/openime/ImePanelRenderer.kt @@ -3,6 +3,10 @@ package llc.slacker.openime import android.content.Context import android.content.Intent import android.graphics.Typeface +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Color +import android.widget.FrameLayout import android.os.Build import android.view.Gravity import android.view.View @@ -66,22 +70,9 @@ internal class ImePanelRenderer( addHeader("切换键盘") val body = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL - setPadding(toPx(12), toPx(10), toPx(12), toPx(10)) + setPadding(toPx(8), toPx(12), toPx(8), toPx(10)) tag = "keyboard-select-panel" } - body.addView( - TextView(context).apply { - text = "选择输入布局" - textSize = ImeTypographyTokens.PANEL_BODY_SP - setPadding(toPx(4), 0, 0, toPx(8)) - tag = "panel-section-title" - }, - LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - toPx(28), - ), - ) - val modes = listOf( KeyboardMode.PINYIN_26 to "拼音 26 键", KeyboardMode.PINYIN_9 to "拼音 9 键", @@ -92,28 +83,21 @@ internal class ImePanelRenderer( val row = LinearLayout(context).apply { orientation = LinearLayout.HORIZONTAL } chunk.forEach { (modeValue, label) -> row.addView( - createKey(label, true, ImeTypographyTokens.BODY_SP) { onModeSelected(modeValue) }.apply { - val selected = currentMode() == modeValue - tag = if (selected) "tab-active" else "keyboard-choice" - contentDescription = "$label,${if (selected) "已选中" else "未选中"}" - if (Build.VERSION.SDK_INT >= 30) { - stateDescription = if (selected) "已选中" else "未选中" - } - }, - LinearLayout.LayoutParams(0, toPx(50), 1f).apply { - marginEnd = toPx(7) + keyboardChoice(modeValue, label), + LinearLayout.LayoutParams(0, toPx(96), 1f).apply { + marginEnd = toPx(4); marginStart = toPx(4) }, ) } if (chunk.size == 1) { - row.addView(View(context), LinearLayout.LayoutParams(0, toPx(50), 1f)) + row.addView(View(context), LinearLayout.LayoutParams(0, toPx(96), 1f)) } body.addView( row, LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, - toPx(50), - ).apply { bottomMargin = toPx(7) }, + toPx(96), + ).apply { bottomMargin = toPx(8) }, ) } expandedPanel.addView( @@ -129,20 +113,18 @@ internal class ImePanelRenderer( addHeader("工具") val body = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL - setPadding(toPx(10), toPx(10), toPx(10), toPx(10)) + setPadding(toPx(12), toPx(12), toPx(4), 0) tag = "tools-panel" } val grid = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL } - val handwritingAvailable = - HandwritingFeaturePolicy.entryEnabled(UnavailableHandwritingProvider) val cards = listOf( - ToolEntry("表情", Panel.EMOJI, R.drawable.ic_emoji), ToolEntry("剪贴板", Panel.CLIPBOARD, R.drawable.ic_clipboard, enabled = !isPasswordField()), - ToolEntry("手写输入", Panel.HANDWRITING, R.drawable.ic_handwriting, enabled = handwritingAvailable), + ToolEntry("表情", Panel.EMOJI, R.drawable.ic_emoji), ToolEntry("符号", Panel.SYMBOLS, R.drawable.ic_symbols), - ToolEntry("切换键盘", Panel.KEYBOARD_SELECT, R.drawable.ic_grid), - ToolEntry("文本编辑", Panel.TEXT_EDITOR, R.drawable.ic_keyboard), - ToolEntry("浮动键盘", iconRes = R.drawable.ic_game, action = onEnableFloatingKeyboard), + ToolEntry("语音输入", Panel.VOICE, R.drawable.ic_mic), + ToolEntry("切换键盘", Panel.KEYBOARD_SELECT, R.drawable.ic_keyboard), + ToolEntry("文本编辑", Panel.TEXT_EDITOR, R.drawable.ic_text_cursor), + ToolEntry("浮动键盘", iconRes = R.drawable.ic_floating, action = onEnableFloatingKeyboard), ToolEntry("设置", Panel.SETTINGS, R.drawable.ic_settings), ).filter { it.enabled } @@ -242,7 +224,7 @@ internal class ImePanelRenderer( LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, toPx(ImeGeometryTokens.TOUCH_TARGET_DP), - ).apply { bottomMargin = toPx(7) }, + ).apply { bottomMargin = toPx(8) }, ) var undoButton: ImeKeyView? = null @@ -290,7 +272,7 @@ internal class ImePanelRenderer( LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, toPx(140), - ).apply { bottomMargin = toPx(7) }, + ).apply { bottomMargin = toPx(8) }, ) val actions = LinearLayout(context).apply { @@ -334,7 +316,7 @@ internal class ImePanelRenderer( addHeader("表情") val body = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL - setPadding(toPx(12), toPx(12), toPx(12), toPx(12)) + setPadding(0, toPx(8), 0, 0) tag = "emoji-panel" } expandedPanel.addView( @@ -351,6 +333,7 @@ internal class ImePanelRenderer( labels: List, selected: String, onSelected: (String) -> Unit, + heightDp: Int = ImeGeometryTokens.TOUCH_TARGET_DP, ): HorizontalScrollView = HorizontalScrollView(context).apply { isHorizontalScrollBarEnabled = false isFillViewport = false @@ -362,19 +345,25 @@ internal class ImePanelRenderer( } var selectedView: View? = null labels.forEach { label -> - val chip = filterChip(label, label == selected) { onSelected(label) } + val chip = filterChip(label, label == selected) { onSelected(label) }.apply { + minimumHeight = toPx(heightDp) + if (heightDp == 32) { + minWidth = toPx(if (label == selected) 56 else 52) + if (label == selected) typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL) + } + } if (label == selected) selectedView = chip row.addView( chip, LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), + toPx(heightDp), ).apply { marginEnd = toPx(6) }, ) } addView( row, - ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, toPx(ImeGeometryTokens.TOUCH_TARGET_DP)), + ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, toPx(heightDp)), ) setOnScrollChangeListener { _, scrollX, _, _, _ -> chipScrollPositions[scrollKey] = scrollX @@ -427,22 +416,23 @@ internal class ImePanelRenderer( val categories = listOf( "常用", "中文", "英文", "数学", "序号", "特殊", "网络颜文字", "单位", "编程", "自定义", ) - val tabs = panelChipScroll(categories, symbolCategory) { category -> - if (category != symbolCategory) { - symbolCategory = category - renderSymbolContent(body, notifyRebuilt = true) - } + body.orientation = LinearLayout.HORIZONTAL + body.setPadding(toPx(8), toPx(5), toPx(4), 0) + val categoryColumn = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL } + categories.forEach { category -> + categoryColumn.addView(filterChip(category, category == symbolCategory) { + if (category != symbolCategory) { + symbolCategory = category + renderSymbolContent(body, notifyRebuilt = true) + } + }, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, toPx(44))) } - body.addView( - tabs, - LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), - ).apply { bottomMargin = toPx(8) }, - ) - + body.addView(panelVerticalScroll(categoryColumn, "symbol-categories"), + LinearLayout.LayoutParams(toPx(74), LinearLayout.LayoutParams.MATCH_PARENT).apply { marginEnd = toPx(5) }) + val content = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL } + body.addView(content, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1f)) if (symbolCategory == "自定义") { - body.addView( + content.addView( createPanelButton("管理自定义符号", ImeTypographyTokens.BODY_SP, true).apply { contentDescription = "管理自定义符号" setOnClickListener { @@ -476,33 +466,33 @@ internal class ImePanelRenderer( ), ) } - items.chunked(6).forEach { chunk -> + items.chunked(5).forEach { chunk -> val row = LinearLayout(context).apply { orientation = LinearLayout.HORIZONTAL } chunk.forEach { symbol -> row.addView( createKey( symbol, false, - ImeTypographyTokens.BODY_SP, + ImeTypographyTokens.KEY_LETTER_SP, ) { onSymbolSelected(symbol) }, - gridCellParams(48, 6, 6), + gridCellParams(54, 5, 0), ) } - repeat(6 - chunk.size) { - row.addView(View(context), gridCellParams(48, 6, 6)) + repeat(5 - chunk.size) { + row.addView(View(context), gridCellParams(54, 5, 0)) } grid.addView( row, LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), - ).apply { bottomMargin = toPx(6) }, + toPx(54), + ), ) } val scroll = panelVerticalScroll(grid, "symbols-scroll") rememberPanelVerticalScroll(scroll, "symbols:$symbolCategory") - body.addView( + content.addView( scroll, LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, @@ -519,26 +509,43 @@ internal class ImePanelRenderer( notifyRebuilt: Boolean, ) { body.removeAllViews() - val categories = listOf("最近") + ImeData.emojiByCategory.keys.toList() - val tabs = panelChipScroll(categories, emojiCategory) { category -> + val categories = listOf("全部") + ImeData.emojiByCategory.keys.toList() + fun displayCategory(category: String): String = when (category) { + "人物/手势" -> "手势" + "动物/自然" -> "动物" + "食物/饮品" -> "食物" + else -> category + } + val tabs = panelChipScroll(categories.map(::displayCategory), displayCategory(emojiCategory), { label -> + val category = categories.first { displayCategory(it) == label } if (category != emojiCategory) { emojiCategory = category renderEmojiContent(body, notifyRebuilt = true) } - } + }, heightDp = 32) body.addView( tabs, LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), - ).apply { bottomMargin = toPx(10) }, + toPx(32), + ).apply { leftMargin = toPx(12); rightMargin = toPx(12); bottomMargin = toPx(4) }, ) - val grid = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL } - val items = if (emojiCategory == "最近") { - EmojiRecentRepository.load(context) + val grid = LinearLayout(context).apply { + orientation = LinearLayout.VERTICAL + setPadding(toPx(4), 0, toPx(4), 0) + } + val items = if (emojiCategory == "全部") { + (EmojiRecentRepository.load(context) + ImeData.emojiByCategory.values.flatten()).distinct() } else { - ImeData.emojiByCategory[emojiCategory].orEmpty() + val catalog = ImeData.emojiByCategory[emojiCategory].orEmpty() + if (emojiCategory == "笑脸") (listOf( + "😀", "😃", "😄", "😁", "😆", "😅", "😂", "🤣", + "🥹", "😊", "😇", "🙂", "🙃", "😉", "😌", "😍", + "🥰", "😘", "😗", "😙", "😚", "☺️", "😛", "😝", + "😜", "🤪", "😳", "🥺", "🤓", "😎", "🥸", "🤩", + "🥳", "😏", "😒", "😞", "😔", "😟", "😕", "🙁", + ) + catalog).distinct() else catalog } if (items.isEmpty() && emojiCategory == "最近") { grid.addView( @@ -559,15 +566,16 @@ internal class ImePanelRenderer( chunk.forEach { emoji -> row.addView( createEmojiCell(emoji), - gridCellParams(48, 8, 4), + gridCellParams(42, 8, 0), ) } + repeat(8 - chunk.size) { row.addView(View(context), gridCellParams(42, 8, 0)) } grid.addView( row, LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), - ).apply { bottomMargin = toPx(4) }, + toPx(42), + ), ) } @@ -601,7 +609,7 @@ internal class ImePanelRenderer( onTap: () -> Unit, ): TextView = TextView(context).apply { text = label - textSize = ImeTypographyTokens.CAPTION_SP + textSize = ImeTypographyTokens.BODY_SP gravity = Gravity.CENTER includeFontPadding = false minWidth = toPx(ImeGeometryTokens.TOUCH_TARGET_DP) @@ -647,14 +655,15 @@ internal class ImePanelRenderer( scaleType = ImageView.ScaleType.CENTER_INSIDE contentDescription = null }, - LinearLayout.LayoutParams(toPx(20), toPx(20)).apply { - bottomMargin = toPx(6) + LinearLayout.LayoutParams(toPx(24), toPx(24)).apply { + bottomMargin = toPx(10) }, ) card.addView( TextView(context).apply { text = label - textSize = ImeTypographyTokens.CAPTION_SP + typeface = android.graphics.Typeface.DEFAULT + textSize = ImeTypographyTokens.BODY_SP gravity = Gravity.CENTER includeFontPadding = false importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO @@ -667,8 +676,50 @@ internal class ImePanelRenderer( return card } + private fun keyboardChoice(mode: KeyboardMode, label: String): View { + val selected = currentMode() == mode + return LinearLayout(context).apply { + orientation = LinearLayout.VERTICAL + setPadding(toPx(14), toPx(12), toPx(14), toPx(8)) + tag = if (selected) "keyboard-choice-selected" else "keyboard-choice" + contentDescription = "$label,${if (selected) "已选中" else "未选中"}" + isClickable = true + isFocusable = true + setOnClickListener { onFeedback(); onModeSelected(mode) } + addView(object : View(context) { + private val paint = Paint(Paint.ANTI_ALIAS_FLAG) + override fun onDraw(canvas: Canvas) { + val dark = resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_NIGHT_MASK == android.content.res.Configuration.UI_MODE_NIGHT_YES + val tokens = ImeTheme.IOS.tokens(ImeSettingsRepository.loadAppearance(context), dark, AccentPalette.parse(ImeSettingsRepository.loadSkinColor(context))) + val h = height / 4f + paint.color = tokens.functionKeyBackground + for (i in 0..3) { + val y = i * h + val w = if (mode == KeyboardMode.PINYIN_9 || mode == KeyboardMode.DIGITS) width * 0.19f else width * (0.12f + 0.03f * i) + canvas.drawRoundRect(0f, y, w, y + h * 0.72f, toPx(2).toFloat(), toPx(2).toFloat(), paint) + if (mode != KeyboardMode.DIGITS || i == 0 || i == 3) { + paint.color = if (selected && i >= 2) tokens.primary else tokens.functionKeyBackground + canvas.drawRoundRect(width * 0.81f, y, width.toFloat(), y + h * 0.72f, toPx(2).toFloat(), toPx(2).toFloat(), paint) + paint.color = tokens.functionKeyBackground + } + } + } + }, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f)) + addView(LinearLayout(context).apply { + orientation = LinearLayout.HORIZONTAL + gravity = Gravity.CENTER_VERTICAL + addView(TextView(context).apply { text = label; textSize = 14f; typeface = Typeface.DEFAULT_BOLD }, LinearLayout.LayoutParams(0, toPx(28), 1f)) + addView(TextView(context).apply { + text = if (selected) "✓" else "○" + tag = if (selected) "keyboard-radio-selected" else "panel-note" + gravity = Gravity.CENTER; textSize = 20f + }, LinearLayout.LayoutParams(toPx(24), toPx(24))) + }, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, toPx(28))) + } + } + private fun symbolItems(category: String): List = when (category) { - "中文" -> ImeData.symbols["中文标点"].orEmpty() + "中文" -> listOf(",", "。", "、", ";", ":", "?", "!", "…", "—", "~", "·", "「", "」", "『", "』", "(", ")", "《", "》", "【", "】", "“", "”", "‘", "’") "英文" -> ImeData.symbols["英文标点"].orEmpty() "数学" -> listOf( ImeData.symbols["数学运算"].orEmpty(), diff --git a/app/src/main/java/llc/slacker/openime/ImeSettingsActivity.kt b/app/src/main/java/llc/slacker/openime/ImeSettingsActivity.kt index edece6d3..955501a9 100644 --- a/app/src/main/java/llc/slacker/openime/ImeSettingsActivity.kt +++ b/app/src/main/java/llc/slacker/openime/ImeSettingsActivity.kt @@ -10,6 +10,11 @@ import android.widget.FrameLayout import android.window.OnBackInvokedCallback class ImeSettingsActivity : Activity(), ImeKeyboardView.Listener { + companion object { const val EXTRA_EDIT_ACCENT = "edit_accent" } + override fun attachBaseContext(newBase: android.content.Context) { + super.attachBaseContext(SetupUi.appearanceContext(newBase)) + } + private lateinit var keyboardView: ImeKeyboardView private lateinit var host: FrameLayout private var backCallback: OnBackInvokedCallback? = null @@ -63,6 +68,9 @@ class ImeSettingsActivity : Activity(), ImeKeyboardView.Listener { ) setContentView(host) refreshWindowChrome() + if (savedInstanceState == null && intent.getBooleanExtra(EXTRA_EDIT_ACCENT, false)) { + host.post { keyboardView.editAccentColor() } + } if (Build.VERSION.SDK_INT >= 33) { backCallback = OnBackInvokedCallback { handleBack() } onBackInvokedDispatcher.registerOnBackInvokedCallback( @@ -168,8 +176,8 @@ class ImeSettingsActivity : Activity(), ImeKeyboardView.Listener { } override fun onAppearanceChanged(appearance: ImeAppearance) { ImeSettingsRepository.saveAppearance(this, appearance) - refreshWindowChrome() refreshLiveIme() + recreate() } override fun onShiftStateChanged(state: ShiftState) = Unit override fun onCandidateExpanded(open: Boolean) = Unit diff --git a/app/src/main/java/llc/slacker/openime/ImeSettingsRepository.kt b/app/src/main/java/llc/slacker/openime/ImeSettingsRepository.kt index d407ca7f..74004077 100644 --- a/app/src/main/java/llc/slacker/openime/ImeSettingsRepository.kt +++ b/app/src/main/java/llc/slacker/openime/ImeSettingsRepository.kt @@ -65,21 +65,21 @@ object ImeSettingsRepository { fun loadKeyboardHeightPercent(context: Context): Int = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE) .getInt(KEY_KEYBOARD_HEIGHT, 100) - .coerceIn(92, 120) + .coerceIn(80, 120) fun saveKeyboardHeightPercent(context: Context, percent: Int) { context.getSharedPreferences(PREFS, Context.MODE_PRIVATE) - .edit().putInt(KEY_KEYBOARD_HEIGHT, percent.coerceIn(92, 120)).apply() + .edit().putInt(KEY_KEYBOARD_HEIGHT, percent.coerceIn(80, 120)).apply() } fun loadFloatingWidthPercent(context: Context): Int = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE) - .getInt(KEY_FLOATING_WIDTH, 88) - .coerceIn(72, 96) + .getInt(KEY_FLOATING_WIDTH, 100) + .coerceIn(72, 100) fun saveFloatingWidthPercent(context: Context, percent: Int) { context.getSharedPreferences(PREFS, Context.MODE_PRIVATE) - .edit().putInt(KEY_FLOATING_WIDTH, percent.coerceIn(72, 96)).apply() + .edit().putInt(KEY_FLOATING_WIDTH, percent.coerceIn(72, 100)).apply() } fun loadFloatingOpacityPercent(context: Context): Int = @@ -127,7 +127,7 @@ object ImeSettingsRepository { fun loadSound(context: Context): Boolean = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE) - .getBoolean(KEY_SOUND, true) + .getBoolean(KEY_SOUND, false) fun saveSound(context: Context, enabled: Boolean) { context.getSharedPreferences(PREFS, Context.MODE_PRIVATE) @@ -145,7 +145,7 @@ object ImeSettingsRepository { fun loadPopup(context: Context): Boolean = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE) - .getBoolean(KEY_POPUP, false) + .getBoolean(KEY_POPUP, true) fun savePopup(context: Context, enabled: Boolean) { context.getSharedPreferences(PREFS, Context.MODE_PRIVATE) @@ -163,7 +163,7 @@ object ImeSettingsRepository { fun loadSkinOpacity(context: Context): Int = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE) - .getInt(KEY_SKIN_OPACITY, 95) + .getInt(KEY_SKIN_OPACITY, 100) fun loadSkinRadius(context: Context): Int = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE) @@ -171,7 +171,7 @@ object ImeSettingsRepository { fun loadSkinFont(context: Context): Int = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE) - .getInt(KEY_SKIN_FONT, 17) + .getInt(KEY_SKIN_FONT, 21) fun loadSkinColor(context: Context): String = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE) diff --git a/app/src/main/java/llc/slacker/openime/ImeState.kt b/app/src/main/java/llc/slacker/openime/ImeState.kt index ccbd2aab..98f443f2 100644 --- a/app/src/main/java/llc/slacker/openime/ImeState.kt +++ b/app/src/main/java/llc/slacker/openime/ImeState.kt @@ -21,6 +21,7 @@ enum class Panel { TEXT_EDITOR, SETTINGS, FUZZY_SETTINGS, + SKIN_SETTINGS, CANDIDATE_EXPANDED, } @@ -47,10 +48,10 @@ data class ImeState( val selectedPinyin9Filter: String = "", val theme: ImeTheme = ImeTheme.IOS, val appearance: ImeAppearance = ImeAppearance.SYSTEM, - val soundEnabled: Boolean = true, + val soundEnabled: Boolean = false, val hapticEnabled: Boolean = true, // Default off, matching ImeSettingsRepository.loadPopup and the View field. - val popupEnabled: Boolean = false, + val popupEnabled: Boolean = true, val fuzzyPinyinEnabled: Boolean = false, val editorInfo: EditorInfo? = null, val passwordField: Boolean = false, @@ -58,9 +59,9 @@ data class ImeState( // First real emoji category tab (see ImeData.emojiByCategory order). val emojiCategory: String = "笑脸", val voiceState: VoiceUiState = VoiceUiState(), - val skinOpacity: Int = 95, + val skinOpacity: Int = 100, val skinRadius: Int = 8, - val skinFontSize: Int = 17, + val skinFontSize: Int = 21, val skinPrimaryColor: String = AccentPalette.DEFAULT, ) diff --git a/app/src/main/java/llc/slacker/openime/ImeThemeApplier.kt b/app/src/main/java/llc/slacker/openime/ImeThemeApplier.kt index a009fd97..9a8cbcfe 100644 --- a/app/src/main/java/llc/slacker/openime/ImeThemeApplier.kt +++ b/app/src/main/java/llc/slacker/openime/ImeThemeApplier.kt @@ -23,6 +23,7 @@ internal class ImeThemeApplier( private val toPx: (Int) -> Int, private val statefulRounded: (Int, Int, Int) -> android.graphics.drawable.StateListDrawable, private val keyMainTextScale: () -> Float, + private val referenceScale: () -> Float, private val skinRadiusPx: () -> Int, private val skinOpacity: () -> Int, private val skinPrimaryColor: () -> String, @@ -63,6 +64,13 @@ internal class ImeThemeApplier( } private fun applyKey(view: ImeKeyView, t: ImeTheme.Tokens) { + if (view.tag == "candidate-grid" || view.tag == "candidate-grid-first") { + val selected = view.tag == "candidate-grid-first" + val fill = if (selected) ImeSurfacePolicy.selectedSurface(t) else t.expandedBackground + view.background = ImeDrawableFactory.rounded(fill, 0, ImeSurfacePolicy.divider(t), toPx(1).coerceAtLeast(1)) + view.setColors(if (selected) t.primary else t.keyText) + return + } val side = isSideKey(view) val label = view.contentDescription?.toString().orEmpty() val function = isFunctionKey(view) @@ -70,12 +78,8 @@ internal class ImeThemeApplier( isWhiteKey(view) || (!function && DIGITS_ONLY.matches(label)) ) - val primary = !side && ( - view.tag == "tab-active" || - view.tag == "key-shift-caps" || - view.tag == "key-shift-active" || - view.tag == "key-enter" - ) + val primary = view.tag == "tab-active" || + (view.tag == "key-enter" && (!side || label == "确定")) val color = when { primary -> t.primary @@ -109,7 +113,7 @@ internal class ImeThemeApplier( view.setColors(onPrimary, onPrimary, onPrimary) } white -> - view.setColors(t.lightKeyText, t.lightKeyText, t.lightKeyText) + view.setColors(t.lightKeyText, t.keySecondaryText, t.lightKeyText) side -> view.setColors(t.sideKeyText, t.sideKeyText, t.sideKeyText) function -> @@ -126,7 +130,7 @@ internal class ImeThemeApplier( private fun applyLinearLayout(view: LinearLayout, t: ImeTheme.Tokens) { when (view.tag) { "candidate-first-row" -> { - val selected = ImeSurfacePolicy.selectedSurface(t) + val selected = t.keyBackground view.background = statefulRounded( selected, ImeSurfacePolicy.pressedSurface(selected, t), @@ -147,20 +151,21 @@ internal class ImeThemeApplier( toPx(ImeGeometryTokens.CONTROL_RADIUS_DP), ) } - "nine-symbol-scroll-content", - "digits-symbol-scroll-content", - -> { - view.background = ImeDrawableFactory.rounded( - t.sideKeyBackground, - toPx(ImeGeometryTokens.CONTROL_RADIUS_DP), - ) + "nine-symbol-scroll-content", "digits-symbol-scroll-content" -> view.background = null + "keyboard-choice", "keyboard-choice-selected" -> { + val selected = view.tag == "keyboard-choice-selected" + view.background = ImeDrawableFactory.rounded(t.toolCardBackground, toPx(16), + if (selected) t.primary else Color.TRANSPARENT, if (selected) toPx(2) else 0) + view.invalidate() } + "segmented-track" -> view.background = ImeDrawableFactory.rounded(t.functionKeyBackground, toPx(12)) + "phrase-card" -> view.background = ImeDrawableFactory.rounded(t.toolCardBackground, toPx(14)) "setting-group" -> { view.background = ImeDrawableFactory.rounded( t.toolCardBackground, toPx(ImeGeometryTokens.CARD_RADIUS_DP), ImeSurfacePolicy.divider(t), - toPx(1).coerceAtLeast(1), + 0, ) } "clip-card" -> { @@ -168,25 +173,13 @@ internal class ImeThemeApplier( t.toolCardBackground, toPx(ImeGeometryTokens.CONTROL_RADIUS_DP), ImeSurfacePolicy.divider(t), - toPx(1).coerceAtLeast(1), - ) - } - "panel-head" -> { - view.background = ImeDrawableFactory.rounded( - t.panelHeadBackground, - toPx(ImeGeometryTokens.CARD_RADIUS_DP), - ImeSurfacePolicy.divider(t), - toPx(1).coerceAtLeast(1), + 0, ) } + "panel-head" -> view.setBackgroundColor(t.panelHeadBackground) "toolbar-row" -> view.setBackgroundColor(t.toolbarBackground) "compose-zone" -> view.setBackgroundColor(t.candidateBackground) - "candidate-field" -> { - view.background = ImeDrawableFactory.rounded( - t.candidateBackground, - toPx(ImeGeometryTokens.CONTROL_RADIUS_DP), - ) - } + "candidate-field" -> view.background = null else -> { if ( (view.tag as? String)?.startsWith("tool:") == true && @@ -195,7 +188,7 @@ internal class ImeThemeApplier( view.background = statefulRounded( t.toolCardBackground, ImeSurfacePolicy.pressedSurface(t.toolCardBackground, t), - toPx(ImeGeometryTokens.CONTROL_RADIUS_DP), + toPx(ImeGeometryTokens.CARD_RADIUS_DP), ) } } @@ -215,16 +208,42 @@ internal class ImeThemeApplier( } private fun applyScrollView(view: ScrollView, t: ImeTheme.Tokens) { - if (view.tag == "nine-punct-stack" || view.tag == "digits-symbol-scroll") { - view.background = ImeDrawableFactory.rounded( - t.sideKeyBackground, - toPx(ImeGeometryTokens.CONTROL_RADIUS_DP), - ) - } + if (view.tag == "nine-punct-stack" || view.tag == "digits-symbol-scroll") view.background = null } private fun applyImageView(view: ImageView, t: ImeTheme.Tokens) { + val iconSize = when { + view.tag == "candidate-emoji" || view.tag == "candidate-expand" -> 20 + view.tag == "key-panel-back" -> 24 + view.tag?.toString()?.startsWith("clip-pin:") == true || view.tag?.toString()?.startsWith("phrase-") == true -> 18 + hasAncestorTag(view, "tools-panel") -> 24 + (view.parent as? View)?.tag == "toolbar-row" -> 22 + else -> 0 + } + if (iconSize > 0) { + fun fitIcon() { + val drawable = view.drawable ?: return + if (view.width <= 0 || view.height <= 0) return + val size = toPx(iconSize).toFloat() + val scale = size / drawable.intrinsicWidth.coerceAtLeast(1) + view.imageMatrix = android.graphics.Matrix().apply { + setScale(scale, scale) + postTranslate((view.width - size) / 2f, (view.height - size) / 2f) + } + } + view.setPadding(0, 0, 0, 0) + view.scaleType = ImageView.ScaleType.MATRIX + if (view.getTag(REFERENCE_ICON_SIZE) == null) { + view.setTag(REFERENCE_ICON_SIZE, iconSize) + view.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> fitIcon() } + } + view.post { fitIcon() } + } + when { + (view.tag as? String)?.startsWith("clip-pin:") == true || (view.tag as? String)?.startsWith("phrase-") == true -> { + view.imageTintList = ColorStateList.valueOf(if (view.isSelected) t.primary else t.keySecondaryText) + } view.tag == "candidate-emoji" || view.tag == "candidate-expand" -> { view.imageTintList = ColorStateList.valueOf(t.keySecondaryText) view.background = statefulRounded( @@ -240,8 +259,9 @@ internal class ImeThemeApplier( toPx(ImeGeometryTokens.KEY_RADIUS_DP), ) } + view.tag == "undo-toolbar" -> view.imageTintList = ColorStateList.valueOf(t.keySecondaryText) view.tag == "key-panel-back" -> { - view.imageTintList = ColorStateList.valueOf(t.keySecondaryText) + view.imageTintList = ColorStateList.valueOf(t.keyText) view.background = statefulRounded( t.panelHeadBackground, ImeSurfacePolicy.pressedSurface(t.panelHeadBackground, t), @@ -252,7 +272,7 @@ internal class ImeThemeApplier( view.parent is LinearLayout && (view.parent as LinearLayout).tag == "toolbar-row" ) || hasAncestorTag(view, "tools-panel") -> { - view.imageTintList = ColorStateList.valueOf(t.keySecondaryText) + view.imageTintList = ColorStateList.valueOf(if (hasAncestorTag(view, "tools-panel") && !ImeSurfacePolicy.isDark(t)) Color.parseColor("#006AB1") else if (hasAncestorTag(view, "tools-panel")) t.primary else t.keyText) if (view.isClickable) { view.background = statefulRounded( Color.TRANSPARENT, @@ -265,13 +285,26 @@ internal class ImeThemeApplier( } private fun applySeekBar(view: SeekBar, t: ImeTheme.Tokens) { + view.progressDrawable = view.context.getDrawable(android.R.drawable.progress_horizontal)?.mutate() view.progressTintList = ColorStateList.valueOf(t.primary) - view.thumbTintList = ColorStateList.valueOf(t.primary) - view.progressBackgroundTintList = - ColorStateList.valueOf(t.panelHeadBackground) + view.progressBackgroundTintList = ColorStateList.valueOf(t.functionKeyBackground) + view.secondaryProgressTintList = ColorStateList.valueOf(t.functionKeyBackground) + if (android.os.Build.VERSION.SDK_INT >= 29) { + view.maxHeight = toPx(4) + view.minHeight = toPx(4) + } + view.thumbTintList = null + view.thumb = ImeDrawableFactory.rounded(Color.WHITE, toPx(99), t.border, toPx(1)).apply { + setSize(toPx(20), toPx(20)) + } + view.splitTrack = false } private fun applyTextView(view: TextView, t: ImeTheme.Tokens) { + if (view.parent !is ImeKeyView) { + val baseSize = (view.getTag(REFERENCE_TEXT_SIZE) as? Float) ?: (view.textSize / view.resources.displayMetrics.scaledDensity).also { view.setTag(REFERENCE_TEXT_SIZE, it) } + view.textSize = baseSize * referenceScale() + } val tag = view.tag as? String if (view.parent !is ImeKeyView) { view.setTextColor(t.keyText) @@ -325,14 +358,14 @@ internal class ImeThemeApplier( view.background = statefulRounded( selected, ImeSurfacePolicy.pressedSurface(selected, t), - toPx(ImeGeometryTokens.CONTROL_RADIUS_DP), + toPx(if (hasAncestorTag(view, "emoji-panel")) 99 else ImeGeometryTokens.CONTROL_RADIUS_DP), ) } tag == "panel-tab" -> { view.setTextColor(t.keySecondaryText) view.background = statefulRounded( - t.panelHeadBackground, + Color.TRANSPARENT, ImeSurfacePolicy.pressedSurface(t.panelHeadBackground, t), toPx(ImeGeometryTokens.CONTROL_RADIUS_DP), ) @@ -372,28 +405,43 @@ internal class ImeThemeApplier( tag == "clipboard-retention-destructive" || tag == "clipboard-clear-confirm" || tag?.startsWith("phrase-delete:") == true -> { - val destructiveSurface = ImeSurfacePolicy.destructiveSurface(t) - view.setTextColor(ImeSurfacePolicy.destructiveText(t)) - view.background = statefulRounded( - destructiveSurface, - ImeSurfacePolicy.pressedSurface(destructiveSurface, t), - toPx(ImeGeometryTokens.CONTROL_RADIUS_DP), + val destructiveText = if (ImeSurfacePolicy.isDark(t)) Color.parseColor("#FF6771") else Color.parseColor("#D60016") + view.setTextColor(destructiveText) + view.background = ImeDrawableFactory.rounded( + t.panelHeadBackground, toPx(8), destructiveText, toPx(1), ) } + tag == "segment-selected" -> { + view.setTextColor(t.keyText) + view.background = ImeDrawableFactory.rounded(t.toolCardBackground, toPx(10), t.border, toPx(1)) + view.typeface = android.graphics.Typeface.DEFAULT_BOLD + } + tag == "segment-option" -> { view.setTextColor(t.keySecondaryText); view.background = null } + tag == "keyboard-radio-selected" -> view.setTextColor(t.primary) + tag == "fuzzy-rules" -> view.background = ImeDrawableFactory.rounded(t.toolCardBackground, toPx(16)) + tag == "textedit-spacer" -> view.background = null + tag == "textedit-center" -> { + view.setTextColor(t.primary) + view.background = ImeDrawableFactory.rounded(ImeSurfacePolicy.selectedSurface(t), toPx(12)) + } + tag?.startsWith("clip-pin:") == true || tag?.startsWith("phrase-edit:") == true || tag?.startsWith("phrase-delete:") == true -> { + view.setTextColor(t.keySecondaryText); view.background = null + view.compoundDrawableTintList = ColorStateList.valueOf(if (view.isSelected) t.primary else t.keySecondaryText) + } tag?.startsWith("punct:") == true || tag?.startsWith("digit-symbol:") == true -> { view.setTextColor(t.keyText) view.background = statefulRounded( - Color.TRANSPARENT, + t.sideKeyBackground, ImeSurfacePolicy.pressedSurface(t.sideKeyBackground, t), toPx(ImeGeometryTokens.KEY_RADIUS_DP), ) } tag == "nine-pinyin-path-selected" -> { - val selected = ImeSurfacePolicy.selectedSurface(t) - view.setTextColor(ImeSurfacePolicy.selectedText(t)) + val selected = ImeDrawableFactory.blend(t.primary, t.sideKeyBackground, 0.22f) + view.setTextColor(if (ImeSurfacePolicy.isDark(t)) t.primary else Color.parseColor("#006AB1")) view.background = statefulRounded( selected, ImeSurfacePolicy.pressedSurface(selected, t), @@ -404,39 +452,13 @@ internal class ImeThemeApplier( tag == "nine-pinyin-path-filter" -> { view.setTextColor(t.sideKeyText) view.background = statefulRounded( - Color.TRANSPARENT, + t.sideKeyBackground, ImeSurfacePolicy.pressedSurface(t.sideKeyBackground, t), toPx(ImeGeometryTokens.KEY_RADIUS_DP), ) } - tag == "accent-custom" -> { - val customSelected = AccentPalette.presets.none { - AccentPalette.normalize(it.first) == - AccentPalette.normalize(skinPrimaryColor()) - } - view.setTextColor( - if (customSelected) { - ImeDrawableFactory.contrastText(t.primary) - } else { - t.keyText - }, - ) - view.background = if (customSelected) { - statefulRounded( - t.primary, - ImeSurfacePolicy.primaryPressed(t), - toPx(ImeGeometryTokens.CONTROL_RADIUS_DP), - ) - } else { - statefulRounded( - t.panelHeadBackground, - ImeSurfacePolicy.pressedSurface(t.panelHeadBackground, t), - toPx(ImeGeometryTokens.CONTROL_RADIUS_DP), - ) - } - } - + tag == "accent-custom" -> { view.setTextColor(t.keyText); view.background = null } tag?.startsWith("accent-selected-mark:") == true -> { val hex = tag.substringAfter(':') view.setTextColor( @@ -481,7 +503,7 @@ internal class ImeThemeApplier( tag == "association-candidate" -> { view.setTextColor(t.candidateText) view.background = statefulRounded( - t.toolCardBackground, + Color.TRANSPARENT, ImeSurfacePolicy.pressedSurface(t.toolCardBackground, t), toPx(ImeGeometryTokens.CONTROL_RADIUS_DP), ) @@ -497,7 +519,7 @@ internal class ImeThemeApplier( view.background = statefulRounded( t.primary, ImeSurfacePolicy.primaryPressed(t), - toPx(ImeGeometryTokens.CONTROL_RADIUS_DP), + toPx(ImeGeometryTokens.PILL_RADIUS_DP), ) } @@ -569,7 +591,7 @@ internal class ImeThemeApplier( ) } "setting-divider" -> - view.setBackgroundColor(ImeSurfacePolicy.divider(t)) + view.setBackgroundColor(ImeDrawableFactory.withAlpha(t.border, if (ImeSurfacePolicy.isDark(t)) 150 else 48)) } } @@ -583,6 +605,8 @@ internal class ImeThemeApplier( } private companion object { + const val REFERENCE_ICON_SIZE = 0x1F000011 + const val REFERENCE_TEXT_SIZE = 0x1F000010 val DIGITS_ONLY = Regex("[0-9]+") } } diff --git a/app/src/main/java/llc/slacker/openime/ImeTopZone.kt b/app/src/main/java/llc/slacker/openime/ImeTopZone.kt index a7f5bd70..c6eec513 100644 --- a/app/src/main/java/llc/slacker/openime/ImeTopZone.kt +++ b/app/src/main/java/llc/slacker/openime/ImeTopZone.kt @@ -39,6 +39,7 @@ internal class ImeTopZone( onClipboard: () -> Unit, onEmoji: () -> Unit, onSymbols: () -> Unit, + onTextEditor: () -> Unit, onHideKeyboard: () -> Unit, onTools: () -> Unit, onExpandCandidates: () -> Unit, @@ -49,6 +50,7 @@ internal class ImeTopZone( val composeZone = LinearLayout(context) val composition = EditText(context) val candidateField = LinearLayout(context) + val expandedCaption = TextView(context) val candidateRow = LinearLayout(context) val candidateScroll = HorizontalScrollView(context) val associationRow = LinearLayout(context) @@ -60,8 +62,8 @@ internal class ImeTopZone( val voiceInlineWaves = mutableListOf() val undoClearAction = TextView(context) private val hideUndoClearRunnable = Runnable { - if (undoClearAction.visibility == View.VISIBLE) { - undoClearAction.visibility = View.GONE + if (toolbarRow.findViewWithTag("undo-toolbar")?.isActivated == true) { + toolbarRow.findViewWithTag("undo-toolbar")?.isActivated = false onUndoClearExpired() } } @@ -76,25 +78,19 @@ internal class ImeTopZone( tag = "toolbar-row" orientation = LinearLayout.HORIZONTAL gravity = Gravity.CENTER_VERTICAL - setPadding(toPx(10), 0, toPx(10), 0) + setPadding(toPx(6), 0, toPx(6), 0) minimumHeight = toPx(ImeGeometryTokens.TOOLBAR_HEIGHT_DP) } - toolbarRow.addView( - toolbarIcon(R.drawable.ic_grid, "切换键盘", "keyboard-selector", onKeyboardSelect), - touchTargetParams(), - ) - toolbarRow.addView( + val toolbarActions = listOf( + toolbarIcon(R.drawable.ic_keyboard, "切换键盘", "keyboard-selector", onKeyboardSelect), toolbarIcon(R.drawable.ic_clipboard, "剪贴板", "clipboard-toolbar", onClipboard), - touchTargetParams(), - ) - toolbarRow.addView( toolbarIcon(R.drawable.ic_emoji, "表情", "toolbar", onEmoji), - touchTargetParams(), - ) - toolbarRow.addView( - toolbarIcon(R.drawable.ic_symbols, "符号", "toolbar", onSymbols), - touchTargetParams(), + toolbarIcon(R.drawable.ic_text_cursor, "文本编辑", "toolbar", onTextEditor), + toolbarIcon(R.drawable.ic_undo, "撤销", "undo-toolbar") { onUndoClear() }, + toolbarIcon(R.drawable.ic_grid, "更多", "toolbar", onTools), + toolbarIcon(R.drawable.ic_chevron_down, "收起键盘", "keyboard-hide", onHideKeyboard), ) + toolbarActions.forEach { toolbarRow.addView(it, LinearLayout.LayoutParams(0, toPx(48), 1f)) } associationRow.apply { orientation = LinearLayout.HORIZONTAL @@ -103,6 +99,7 @@ internal class ImeTopZone( } val associationScroll = HorizontalScrollView(context).apply { tag = "association-scroll" + visibility = View.GONE isHorizontalScrollBarEnabled = false overScrollMode = View.OVER_SCROLL_IF_CONTENT_SCROLLS addView( @@ -147,19 +144,11 @@ internal class ImeTopZone( toPx(ImeGeometryTokens.TOUCH_TARGET_DP), ), ) - toolbarRow.addView( - toolbarIcon(R.drawable.ic_keyboard_hide, "收起键盘", "keyboard-hide", onHideKeyboard), - touchTargetParams(), - ) - toolbarRow.addView( - toolbarIcon(R.drawable.ic_more, "更多", "toolbar", onTools), - touchTargetParams(), - ) addView( toolbarRow, LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, - toPx(ImeGeometryTokens.TOOLBAR_HEIGHT_DP), + toPx(ImeGeometryTokens.COMPOSED_TOP_ZONE_HEIGHT_DP), ), ) @@ -172,6 +161,8 @@ internal class ImeTopZone( tag = "pinyin-composition-editor" contentDescription = "可编辑拼音预编辑" textSize = ImeTypographyTokens.BODY_SP + letterSpacing = 0.04f + typeface = android.graphics.Typeface.create("sans-serif-medium", android.graphics.Typeface.NORMAL) gravity = Gravity.CENTER_VERTICAL or Gravity.START inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS setSingleLine(true) @@ -208,7 +199,7 @@ internal class ImeTopZone( orientation = LinearLayout.HORIZONTAL gravity = Gravity.CENTER_VERTICAL tag = "candidate-field" - setPadding(toPx(8), 0, toPx(8), 0) + setPadding(toPx(6), 0, toPx(0), 0) } candidateRow.apply { orientation = LinearLayout.HORIZONTAL @@ -224,6 +215,11 @@ internal class ImeTopZone( ), ) } + expandedCaption.apply { + text = "候选字词"; textSize = 14f; gravity = Gravity.CENTER_VERTICAL + setPadding(toPx(10), 0, 0, 0); tag = "panel-note"; visibility = View.GONE + } + candidateField.addView(expandedCaption, LinearLayout.LayoutParams(0, toPx(48), 1f)) candidateField.addView( candidateScroll, LinearLayout.LayoutParams(0, toPx(ImeGeometryTokens.TOUCH_TARGET_DP), 1f), @@ -242,8 +238,6 @@ internal class ImeTopZone( onEmoji() } } - candidateField.addView(candidateEmojiButton, touchTargetParams()) - candidateExpandButton.apply { tag = "candidate-expand" setImageResource(R.drawable.ic_chevron_down) @@ -258,15 +252,6 @@ internal class ImeTopZone( } } candidateField.addView(candidateExpandButton, touchTargetParams()) - candidateField.addView( - toolbarIcon( - R.drawable.ic_keyboard_hide, - "收起键盘", - "keyboard-hide-composing", - onHideKeyboard, - ), - touchTargetParams(), - ) composeZone.addView( candidateField, LinearLayout.LayoutParams( @@ -302,7 +287,7 @@ internal class ImeTopZone( ) voiceInlineStatus.apply { tag = "voice-inline-status" - text = "正在聆听…" + text = "正在聆听" textSize = ImeTypographyTokens.BODY_SP setTextColor(Color.WHITE) includeFontPadding = false @@ -320,7 +305,7 @@ internal class ImeTopZone( orientation = LinearLayout.HORIZONTAL gravity = Gravity.CENTER } - repeat(6) { index -> + repeat(10) { index -> val bar = View(context).apply { tag = "voice-inline-wave-$index" background = ImeDrawableFactory.rounded( @@ -339,37 +324,53 @@ internal class ImeTopZone( }, ) } - voiceInlineZone.addView( - inlineWave, - LinearLayout.LayoutParams(toPx(42), LinearLayout.LayoutParams.MATCH_PARENT), - ) + voiceInlineZone.addView(inlineWave, 0, + LinearLayout.LayoutParams(toPx(64), LinearLayout.LayoutParams.MATCH_PARENT).apply { marginEnd = toPx(12) }) + voiceInlineIcon.visibility = View.GONE + voiceInlineZone.addView(TextView(context).apply { + text = "↑ 上滑取消" + textSize = 12f + gravity = Gravity.CENTER + tag = "voice-cancel-hint" + includeFontPadding = false + }, LinearLayout.LayoutParams(toPx(88), toPx(30))) addView( voiceInlineZone, LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), + toPx(54), ).apply { setMargins(toPx(8), toPx(8), toPx(8), toPx(8)) }, ) } + fun showAssociations(show: Boolean) { + for (index in 0 until toolbarRow.childCount) { + val child = toolbarRow.getChildAt(index) + child.visibility = if (show) View.GONE else View.VISIBLE + } + undoClearAction.visibility = View.GONE + toolbarRow.findViewWithTag("association-scroll").visibility = if (show) View.VISIBLE else View.GONE + if (show) toolbarRow.findViewWithTag("keyboard-hide").visibility = View.VISIBLE + } + fun showUndoClear() { removeCallbacks(hideUndoClearRunnable) - undoClearAction.visibility = View.VISIBLE - undoClearAction.bringToFront() + toolbarRow.findViewWithTag("undo-toolbar")?.isActivated = true postDelayed(hideUndoClearRunnable, CLEAR_UNDO_VISIBLE_MS) } fun hideUndoClear(discardSnapshot: Boolean = false) { removeCallbacks(hideUndoClearRunnable) - val wasVisible = undoClearAction.visibility == View.VISIBLE + val wasVisible = toolbarRow.findViewWithTag("undo-toolbar")?.isActivated == true + toolbarRow.findViewWithTag("undo-toolbar")?.isActivated = false undoClearAction.visibility = View.GONE if (discardSnapshot && wasVisible) onUndoClearExpired() } fun setContentInset(contentInsetPx: Int) { - toolbarRow.setPadding(contentInsetPx + toPx(10), 0, contentInsetPx + toPx(10), 0) + toolbarRow.setPadding(contentInsetPx + toPx(6), 0, contentInsetPx + toPx(6), 0) composition.setPadding(contentInsetPx + toPx(14), toPx(3), contentInsetPx + toPx(14), 0) } @@ -384,6 +385,9 @@ internal class ImeTopZone( voiceInlineZone.visibility = if (state == ImeTopZoneState.VOICE_INLINE) View.VISIBLE else View.GONE composition.visibility = if (composing && showCompositionEditor) View.VISIBLE else View.GONE candidateField.visibility = if (composing) View.VISIBLE else View.GONE + val expanded = state == ImeTopZoneState.CANDIDATE_EXPANDED + candidateScroll.visibility = if (expanded) View.GONE else View.VISIBLE + expandedCaption.visibility = if (expanded) View.VISIBLE else View.GONE } private fun toolbarIcon( @@ -394,7 +398,7 @@ internal class ImeTopZone( ): ImageView = ImageView(context).apply { contentDescription = description tag = tagValue - minimumWidth = toPx(ImeGeometryTokens.TOUCH_TARGET_DP) + minimumWidth = 0 minimumHeight = toPx(ImeGeometryTokens.TOUCH_TARGET_DP) scaleType = ImageView.ScaleType.CENTER_INSIDE setImageResource(iconRes) diff --git a/app/src/main/java/llc/slacker/openime/InlineVoicePresenter.kt b/app/src/main/java/llc/slacker/openime/InlineVoicePresenter.kt index 8b2cd512..64ddbdc1 100644 --- a/app/src/main/java/llc/slacker/openime/InlineVoicePresenter.kt +++ b/app/src/main/java/llc/slacker/openime/InlineVoicePresenter.kt @@ -103,7 +103,7 @@ internal class InlineVoicePresenter( if (!active) return val palette = tokens() val backgroundColor = - if (cancelling || error) palette.destructive else palette.primary + if (cancelling || error) palette.destructive else ImeDrawableFactory.blend(palette.primary, palette.toolbarBackground, 0.16f) if (paletteColor == backgroundColor) return paletteColor = backgroundColor @@ -111,12 +111,16 @@ internal class InlineVoicePresenter( backgroundColor, toPx(ImeGeometryTokens.CONTROL_RADIUS_DP), ) - val foregroundColor = ImeDrawableFactory.contrastText(backgroundColor) + val foregroundColor = palette.keyText + zone().findViewWithTag("voice-cancel-hint")?.apply { + setTextColor(foregroundColor) + background = ImeDrawableFactory.rounded(palette.functionKeyBackground, toPx(99)) + } icon().imageTintList = ColorStateList.valueOf(foregroundColor) status().setTextColor(foregroundColor) waves().forEach { bar -> bar.background = ImeDrawableFactory.rounded( - foregroundColor, + palette.primary, toPx(ImeGeometryTokens.PILL_RADIUS_DP), ) } diff --git a/app/src/main/java/llc/slacker/openime/KeyboardGeometry.kt b/app/src/main/java/llc/slacker/openime/KeyboardGeometry.kt index 34ea84b0..e085c07c 100644 --- a/app/src/main/java/llc/slacker/openime/KeyboardGeometry.kt +++ b/app/src/main/java/llc/slacker/openime/KeyboardGeometry.kt @@ -54,25 +54,26 @@ internal data class KeyboardLayoutMetrics( val landscape: Boolean, val fontScale: Float, val heightPercent: Int = 100, + val availableWidthDp: Int = 390, ) { val keyRowHeightDp: Int = run { val base = if (landscape) { ImeGeometryTokens.LANDSCAPE_KEY_ROW_HEIGHT_DP } else { - ImeGeometryTokens.TOUCH_TARGET_DP + 54 } val fontGrow = ((fontScale - 1f).coerceAtLeast(0f) * 12f) .toInt() .coerceAtMost(12) - val scaled = ((base + fontGrow) * heightPercent.coerceIn(92, 120) / 100f).toInt() + val scaled = ((base + fontGrow) * heightPercent.coerceIn(80, 120) / 100f).toInt() scaled.coerceAtLeast(if (landscape) 38 else 44) } val nineGridHeightDp: Int = - keyRowHeightDp * 3 + ImeGeometryTokens.KEY_ROW_GAP_DP * 2 + keyRowHeightDp * 3 val nineBodyHeightDp: Int = - nineGridHeightDp + ImeGeometryTokens.KEY_ROW_GAP_DP + keyRowHeightDp + nineGridHeightDp + keyRowHeightDp val doubleKeyHeightDp: Int = keyRowHeightDp * 2 + ImeGeometryTokens.KEY_ROW_GAP_DP @@ -81,12 +82,10 @@ internal data class KeyboardLayoutMetrics( val imeHeightDp: Int = run { val derived = topZoneHeightDp + - keyRowHeightDp * 4 + - ImeGeometryTokens.KEY_ROW_GAP_DP * 3 + - 22 - val baseMinimum = if (landscape) 264 else 302 + keyRowHeightDp * 4 + 16 + val baseMinimum = if (landscape) 256 else 0 val scaledMinimum = - (baseMinimum * heightPercent.coerceIn(92, 120) / 100f).toInt() + (baseMinimum * heightPercent.coerceIn(80, 120) / 100f).toInt() maxOf(scaledMinimum, derived) } @@ -96,3 +95,16 @@ internal data class KeyboardLayoutMetrics( (imeHeightDp - ImeGeometryTokens.TOUCH_TARGET_DP).coerceAtLeast(0) } + +/** All reference dimensions scale together from the PDF's 390-unit canvas. */ +internal object ImeReferenceSizing { + fun scale(context: android.content.Context, widthPx: Int = 0): Float { + val config = context.resources.configuration + val metrics = context.resources.displayMetrics + val widthDp = if (widthPx > 0) widthPx / metrics.density else config.screenWidthDp.toFloat() + val widthScale = widthDp.coerceAtMost(600f) / 390f + return if (config.orientation == android.content.res.Configuration.ORIENTATION_LANDSCAPE) { + minOf(widthScale, config.screenHeightDp * 0.55f / 256f) + } else widthScale + } +} diff --git a/app/src/main/java/llc/slacker/openime/MainActivity.kt b/app/src/main/java/llc/slacker/openime/MainActivity.kt index 2ecc0b66..48650b26 100644 --- a/app/src/main/java/llc/slacker/openime/MainActivity.kt +++ b/app/src/main/java/llc/slacker/openime/MainActivity.kt @@ -28,7 +28,14 @@ internal fun matchesSelectedInputMethod(defaultInputMethodId: String, packageNam } class MainActivity : Activity() { + override fun attachBaseContext(newBase: android.content.Context) { + super.attachBaseContext(SetupUi.appearanceContext(newBase)) + } + + private var appliedAppearance = ImeAppearance.SYSTEM + override fun onCreate(savedInstanceState: Bundle?) { + appliedAppearance = ImeSettingsRepository.loadAppearance(this) super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) findViewById(R.id.main_scroll).setOnApplyWindowInsetsListener { view, insets -> @@ -78,6 +85,7 @@ class MainActivity : Activity() { requestPermissions(arrayOf(Manifest.permission.RECORD_AUDIO), 1) } } + setupClick(findViewById(R.id.voice_permission_authorize)) { findViewById(R.id.voice_permission).performClick() } setupClick(findViewById(R.id.voice_permission_skip)) { getPreferences(MODE_PRIVATE) .edit() @@ -118,6 +126,10 @@ class MainActivity : Activity() { override fun onResume() { super.onResume() + if (appliedAppearance != ImeSettingsRepository.loadAppearance(this)) { + recreate() + return + } refreshSetupState() } @@ -130,7 +142,7 @@ class MainActivity : Activity() { val status = imeStatus() val enabled = status.enabled val selected = status.selected - val accent = AccentPalette.parse(ImeSettingsRepository.loadSkinColor(this)) + val accent = SetupUi.accent(this) val prefs = getPreferences(MODE_PRIVATE) val microphoneGranted = checkSelfPermission(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED @@ -143,7 +155,8 @@ class MainActivity : Activity() { val testInput = findViewById(R.id.test_input) val testDone = testInput.text?.isNotBlank() == true - testInput.background = SetupUi.focusRingBackground(this) + testInput.background = SetupUi.inputBackground(this) + testInput.setPadding(SetupUi.dp(this, 16), 0, SetupUi.dp(this, 16), 0) SetupUi.styleCursor(this, testInput) findViewById(R.id.status).setText( @@ -175,14 +188,14 @@ class MainActivity : Activity() { chevron = findViewById(R.id.choose_ime_chevron), done = selected, active = enabled && !selected, - doneText = getString(R.string.choose_ime_done), + doneText = "已切换到 openIME", activeText = getString(R.string.choose_ime), markText = "2", accent = accent, ) findViewById(R.id.choose_ime).apply { isEnabled = enabled - alpha = if (enabled) 1f else ImeSurfacePolicy.DISABLED_ALPHA + alpha = 1f } val voiceDone = microphoneGranted || microphoneSkipped @@ -208,12 +221,12 @@ class MainActivity : Activity() { active = voiceActive, doneText = voiceDoneText, activeText = voiceActiveText, - markText = "3", + markText = "", accent = accent, ) findViewById(R.id.voice_permission).apply { isEnabled = selected && !microphoneGranted - alpha = if (selected) 1f else ImeSurfacePolicy.DISABLED_ALPHA + alpha = 1f } findViewById(R.id.voice_permission_description).setText( when { @@ -222,6 +235,8 @@ class MainActivity : Activity() { else -> R.string.voice_permission_description }, ) + findViewById(R.id.voice_permission_actions).visibility = if (microphoneGranted || microphoneSkipped) View.GONE else View.VISIBLE + findViewById(R.id.voice_permission_authorize).background = SetupUi.secondaryBackground(this) findViewById(R.id.voice_permission_skip).apply { visibility = if (selected && !microphoneGranted && !microphoneSkipped) { @@ -230,7 +245,7 @@ class MainActivity : Activity() { View.GONE } isEnabled = visibility == View.VISIBLE - background = SetupUi.secondaryBackground(this@MainActivity) + background = null } styleStep( @@ -242,15 +257,15 @@ class MainActivity : Activity() { active = selected && !testDone, doneText = getString(R.string.test_step_done), activeText = getString(R.string.test_step), - markText = "4", + markText = "3", accent = accent, ) findViewById(R.id.test_step).apply { isEnabled = selected - alpha = if (selected) 1f else ImeSurfacePolicy.DISABLED_ALPHA + alpha = 1f } testInput.isEnabled = selected - testInput.alpha = if (selected) 1f else ImeSurfacePolicy.DISABLED_ALPHA + testInput.alpha = 1f val ready = enabled && selected findViewById(R.id.open_app_settings).apply { @@ -304,48 +319,60 @@ class MainActivity : Activity() { // A completed setup step remains an action: users may need to revisit // the system picker or input-method settings after initial setup. row.isEnabled = true - row.background = when { - active -> SetupUi.buttonBackground(this, accent) - done -> completedBackground(accent) - else -> SetupUi.secondaryBackground(this) - } + row.background = null label.text = if (done) doneText else activeText - label.setTextColor( - if (active) contrastText(accent) else getColor( - if (done) R.color.setup_body else R.color.setup_title, - ), - ) + label.setTextColor(getColor(if (done || active) R.color.setup_title else R.color.setup_body)) // A completed step is easier to scan as a result than as an old // step number. Keep the number for the current step so the flow still // reads as 1 -> 2 while the completed state reads as a check. mark.text = if (done) "" else markText - mark.setCompoundDrawablesRelativeWithIntrinsicBounds( - if (done) R.drawable.ic_check else 0, - 0, - 0, - 0, - ) + val markIcon = if (row.id == R.id.voice_permission) R.drawable.ic_mic else if (done) R.drawable.ic_check else 0 + val drawable = if (markIcon != 0) getDrawable(markIcon)?.apply { + setBounds(0, 0, SetupUi.dp(this@MainActivity, 16), SetupUi.dp(this@MainActivity, 16)) + } else null + mark.setCompoundDrawablesRelative(drawable, null, null, null) mark.compoundDrawableTintList = ColorStateList.valueOf( - if (done) contrastText(getColor(R.color.setup_ready)) else accent, - ) - mark.setBackgroundResource( - when { - active -> R.drawable.bg_setup_mark_active - done -> R.drawable.bg_setup_mark_done - else -> R.drawable.bg_setup_mark - }, + if (done) contrastText(getColor(R.color.setup_ready)) else getColor(R.color.setup_body), ) + mark.background = android.graphics.drawable.GradientDrawable().apply { + shape = android.graphics.drawable.GradientDrawable.OVAL + setColor(if (done) getColor(R.color.setup_ready) else if (active) accent else getColor(R.color.setup_surface)) + if (!done && !active) setStroke(SetupUi.dp(this@MainActivity, 1), getColor(R.color.setup_input_line)) + } mark.setTextColor( when { - active -> accent + active -> contrastText(accent) done -> contrastText(getColor(R.color.setup_ready)) - else -> accent + else -> getColor(R.color.setup_body) }, ) chevron?.imageTintList = ColorStateList.valueOf( - if (active) contrastText(accent) else getColor(R.color.setup_body), + getColor(R.color.setup_body), ) - chevron?.visibility = if (done) View.GONE else View.VISIBLE + chevron?.visibility = View.GONE + if (row.id == R.id.open_ime_settings || row.id == R.id.choose_ime) { + val layout = row as android.widget.LinearLayout + (layout.getChildAt(1) as? android.widget.LinearLayout)?.getChildAt(1)?.visibility = if (done) View.GONE else View.VISIBLE + val status = (layout.findViewWithTag("setup-result") as? TextView) ?: TextView(this).apply { + tag = "setup-result"; textSize = 12f; setTextColor(getColor(R.color.setup_body)) + layout.addView(this, android.widget.LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams.WRAP_CONTENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT)) + } + val enableStep = row.id == R.id.open_ime_settings + status.text = if (done) { if (enableStep) "已启用" else "已切换" } else { if (enableStep) "启用" else "切换" } + status.visibility = View.VISIBLE + status.gravity = android.view.Gravity.CENTER + status.typeface = android.graphics.Typeface.create("sans-serif-medium", android.graphics.Typeface.NORMAL) + status.layoutParams = android.widget.LinearLayout.LayoutParams( + if (done) android.widget.LinearLayout.LayoutParams.WRAP_CONTENT else SetupUi.dp(this, 66), + if (done) android.widget.LinearLayout.LayoutParams.WRAP_CONTENT else SetupUi.dp(this, 40), + ) + status.background = if (done) null else SetupUi.rounded( + if (active) accent else getColor(R.color.setup_disabled), SetupUi.dp(this, 12).toFloat(), + ) + status.setTextColor(if (done) getColor(R.color.setup_body) else if (active) contrastText(accent) else getColor(R.color.setup_disabled_text)) + + } + if (row.id == R.id.test_step) (row as android.widget.LinearLayout).getChildAt(2)?.visibility = View.GONE row.alpha = 1f row.contentDescription = when { done -> doneText diff --git a/app/src/main/java/llc/slacker/openime/NineKeySymbolRailController.kt b/app/src/main/java/llc/slacker/openime/NineKeySymbolRailController.kt index afdf59d7..d150c151 100644 --- a/app/src/main/java/llc/slacker/openime/NineKeySymbolRailController.kt +++ b/app/src/main/java/llc/slacker/openime/NineKeySymbolRailController.kt @@ -15,8 +15,8 @@ import android.widget.TextView /** * Owns the Chinese 9-key side rail. * - * With no ambiguity it behaves as the normal vertically scrollable symbol - * rail. Once one digit sequence maps to multiple Pinyin paths, the same rail + * With no composition it behaves as the normal vertically scrollable symbol + * rail. During composition, the same rail * becomes a directly selectable Pinyin list. This mirrors mature 9-key IMEs: * the user sees all useful spellings at once instead of cycling one hidden * option through a single button. @@ -26,6 +26,8 @@ internal class NineKeySymbolRailController( private val composition: EditText, private val onCommit: (String) -> Unit, private val onFeedback: () -> Unit, + private val cellHeightDp: () -> Int, + private val toPx: (Int) -> Int = { (it * context.resources.displayMetrics.density).toInt() }, private val onRailChanged: (View) -> Unit, ) { private enum class RailMode { SYMBOLS, PINYIN } @@ -64,6 +66,8 @@ internal class NineKeySymbolRailController( contentTag = NINE_CONTENT_TAG, contentDescription = "九键拼音筛选或常用符号,上下滑动查看更多", symbols = commonSymbols(), + cellHeightDp = cellHeightDp(), + toPx = toPx, tagPrefix = "punct:", onCommit = onCommit, onFeedback = onFeedback, @@ -119,9 +123,9 @@ internal class NineKeySymbolRailController( .take(MAX_VISIBLE_PATHS) .toList() - // One spelling needs no disambiguation. Keep the valuable symbol rail - // available instead of occupying the whole column with redundant UI. - if (choices.size <= 1) { + // Keep the selected spelling visible throughout composition, even when + // this digit sequence currently has only one complete display path. + if (choices.isEmpty()) { renderSymbols() return } @@ -149,6 +153,8 @@ internal class NineKeySymbolRailController( SymbolRailRenderer.populate( scroll = scroll, symbols = commonSymbols(), + cellHeightDp = cellHeightDp(), + toPx = toPx, tagPrefix = "punct:", onCommit = onCommit, onFeedback = onFeedback, @@ -187,7 +193,7 @@ internal class NineKeySymbolRailController( content.addView( TextView(content.context).apply { text = displayPath(choice) - textSize = ImeTypographyTokens.BODY_SP + textSize = 18f gravity = Gravity.CENTER tag = if (active) SELECTED_FILTER_TAG else FILTER_TAG contentDescription = @@ -204,7 +210,7 @@ internal class NineKeySymbolRailController( isClickable = true isFocusable = true maxLines = 2 - minimumHeight = SymbolRailRenderer.cellHeightPx(content.context) + includeFontPadding = false inheritedTextColor?.let(::setTextColor) setOnClickListener { onFeedback() @@ -214,6 +220,8 @@ internal class NineKeySymbolRailController( SymbolRailRenderer.cellParams( content.context, withGap = index < choices.lastIndex, + heightDp = cellHeightDp(), + toPx = toPx, ), ) } @@ -233,21 +241,17 @@ internal class NineKeySymbolRailController( } private fun displayPath(path: String): String = - path.replace(" ", "·").replace("|", "·").replace("'", "·") + path.replace(" ", "'").replace("|", "'") private fun speakablePath(path: String): String = path.replace(" ", "、").replace("|", "、").replace("'", "、") private fun commonSymbols(): List = - CustomSymbolRepository.load(context) - .map { it.symbol } - .filter { it.isNotBlank() } + - ImeData.symbols["常用"].orEmpty() - .asSequence() - .filter { it.isNotBlank() } - .distinct() - .toList() - .ifEmpty { listOf(",", "。", "?", "!") } + (listOf(",", "。", "?", "!") + + CustomSymbolRepository.load(context).map { it.symbol } + + ImeData.symbols["常用"].orEmpty()) + .filter { it.isNotBlank() } + .distinct() private companion object { const val NINE_RAIL_TAG = "nine-punct-stack" diff --git a/app/src/main/java/llc/slacker/openime/NumericKeyboardRenderer.kt b/app/src/main/java/llc/slacker/openime/NumericKeyboardRenderer.kt index 6c06f63b..c44c9f36 100644 --- a/app/src/main/java/llc/slacker/openime/NumericKeyboardRenderer.kt +++ b/app/src/main/java/llc/slacker/openime/NumericKeyboardRenderer.kt @@ -56,6 +56,8 @@ internal class NumericKeyboardRenderer( contentTag = DIGITS_CONTENT_TAG, contentDescription = "数字键盘符号,上下滑动查看更多", symbols = digitSymbols(), + cellHeightDp = keyRowHeightDp(), + toPx = toPx, tagPrefix = "digit-symbol:", onCommit = onCommitCharacter, onFeedback = onFeedback, @@ -89,7 +91,7 @@ internal class NumericKeyboardRenderer( val row = LinearLayout(context).apply { orientation = LinearLayout.HORIZONTAL } rowDigits.forEach { digit -> row.addView( - createKey(digit, false, ImeTypographyTokens.KEY_LETTER_SP) { onCommitCharacter(digit) }.apply { + createKey(digit, false, 24f) { onCommitCharacter(digit) }.apply { tag = "key:$digit" markWhiteKey(this) }, @@ -138,10 +140,10 @@ internal class NumericKeyboardRenderer( flexKeyParams(), ) centerBottom.addView( - createKey(literal("key:.", "."), false, ImeTypographyTokens.KEY_LETTER_SP) { - onCommitCharacter(literal("key:.", ".")) + createKey(literal("key:0", "0"), false, 24f) { + onCommitCharacter(literal("key:0", "0")) }.apply { - tag = "key:." + tag = "key:0" markWhiteKey(this) }, flexKeyParams(), @@ -151,9 +153,9 @@ internal class NumericKeyboardRenderer( LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, toPx(keyRowHeightDp()), - ).apply { topMargin = toPx(ImeGeometryTokens.KEY_ROW_GAP_DP) }, + ), ) - container.addView(center, adaptiveColumnParams(3.7f)) + container.addView(center, adaptiveColumnParams(25f / 7f)) val side = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL @@ -164,8 +166,8 @@ internal class NumericKeyboardRenderer( sideKeyParams(), ) side.addView( - createKey("0", false, ImeTypographyTokens.KEY_LETTER_SP) { onCommitCharacter("0") }.apply { - tag = "key:0" + createKey(".", true, ImeTypographyTokens.KEY_LETTER_SP) { onCommitCharacter(".") }.apply { + tag = "key:." markSideKey(this) }, sideKeyParams(), @@ -202,6 +204,8 @@ internal class NumericKeyboardRenderer( SymbolRailRenderer.populate( scroll = rail, symbols = digitSymbols(), + cellHeightDp = keyRowHeightDp(), + toPx = toPx, tagPrefix = "digit-symbol:", onCommit = onCommitCharacter, onFeedback = onFeedback, diff --git a/app/src/main/java/llc/slacker/openime/PanelHeaderFactory.kt b/app/src/main/java/llc/slacker/openime/PanelHeaderFactory.kt index d06a755e..20d6317b 100644 --- a/app/src/main/java/llc/slacker/openime/PanelHeaderFactory.kt +++ b/app/src/main/java/llc/slacker/openime/PanelHeaderFactory.kt @@ -38,7 +38,7 @@ internal class PanelHeaderFactory( return LinearLayout(context).apply { orientation = LinearLayout.HORIZONTAL gravity = Gravity.CENTER_VERTICAL - setPadding(toPx(10), 0, toPx(10), 0) + setPadding(toPx(4), 0, toPx(8), 0) minimumHeight = toPx(ImeGeometryTokens.TOUCH_TARGET_DP) tag = "panel-head" @@ -70,7 +70,8 @@ internal class PanelHeaderFactory( TextView(context).apply { text = name textSize = ImeTypographyTokens.PANEL_TITLE_SP - setPadding(toPx(8), 0, 0, 0) + setPadding(0, 0, 0, 0) + typeface = android.graphics.Typeface.DEFAULT_BOLD tag = "panel-title" }, LinearLayout.LayoutParams( @@ -92,6 +93,7 @@ internal class PanelHeaderFactory( Panel.TEXT_EDITOR -> "文本编辑" Panel.SETTINGS -> "设置" Panel.FUZZY_SETTINGS -> "模糊音纠错" + Panel.SKIN_SETTINGS -> "强调色与按键皮肤" Panel.NONE, Panel.CANDIDATE_EXPANDED -> "键盘" } } diff --git a/app/src/main/java/llc/slacker/openime/Pinyin26KeyboardRenderer.kt b/app/src/main/java/llc/slacker/openime/Pinyin26KeyboardRenderer.kt index 04df68a0..635f246f 100644 --- a/app/src/main/java/llc/slacker/openime/Pinyin26KeyboardRenderer.kt +++ b/app/src/main/java/llc/slacker/openime/Pinyin26KeyboardRenderer.kt @@ -47,7 +47,7 @@ internal class Pinyin26KeyboardRenderer( } if (rowIndex == 2) { row.addView( - if (english) shiftKey(shiftState) else segmentKey(), + shiftKey(shiftState), flexKeyParams(1.25f), ) } @@ -72,7 +72,7 @@ internal class Pinyin26KeyboardRenderer( createKey("123", true, null, ImeTypographyTokens.BODY_SP, 0, onDigits), flexKeyParams(weights.leftOuter), ) - val punctuation = if (english) "." else "," + val punctuation = "中/英" bottom.addView( createKey( punctuation, @@ -80,19 +80,13 @@ internal class Pinyin26KeyboardRenderer( null, ImeTypographyTokens.BODY_SP, 0, - ) { onCommitCharacter(punctuation) }, + ) { onModeSwitch() }.apply { tag = "key:mode" }, flexKeyParams(weights.leftInner), ) bottom.addView( - createSpaceVoiceKey(if (english) "space" else "空格", onSpace), + createSpaceVoiceKey("空格", onSpace), flexKeyParams(weights.space), ) - bottom.addView( - createKey("中/英", true, null, ImeTypographyTokens.BODY_SP, 0, onModeSwitch).apply { - tag = "key:mode" - }, - flexKeyParams(weights.rightInner), - ) bottom.addView( createKey(enterLabel, true, null, ImeTypographyTokens.BODY_SP, 0, onEnter).apply { tag = "key-enter" @@ -135,6 +129,8 @@ internal class Pinyin26KeyboardRenderer( val base = character.toString() val main = if (english && shiftState != ShiftState.LOWERCASE) { character.uppercaseChar().toString() + } else if (!english) { + character.uppercaseChar().toString() } else { base } @@ -145,7 +141,7 @@ internal class Pinyin26KeyboardRenderer( tag = "key:$base" if (secondary != null) { setSecondaryVisible(true) - setSecondaryAlpha(0.4f) + setSecondaryAlpha(1f) setOnLongClickListener { onCommitCharacter(secondary) true diff --git a/app/src/main/java/llc/slacker/openime/Pinyin9KeyboardRenderer.kt b/app/src/main/java/llc/slacker/openime/Pinyin9KeyboardRenderer.kt index b31724b8..6db5d6e0 100644 --- a/app/src/main/java/llc/slacker/openime/Pinyin9KeyboardRenderer.kt +++ b/app/src/main/java/llc/slacker/openime/Pinyin9KeyboardRenderer.kt @@ -54,16 +54,7 @@ internal class Pinyin9KeyboardRenderer( createSymbolRail(), LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, - toPx(nineGridHeightDp()), - ), - ) - left.addView( - createKey("符号", true, null, ImeTypographyTokens.BODY_SP, onShowSymbols).apply { - markSideKey(this) - }, - LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - toPx(keyRowHeightDp()), + toPx(nineBodyHeightDp()), ), ) container.addView(left, adaptiveColumnParams(1f)) @@ -83,27 +74,27 @@ internal class Pinyin9KeyboardRenderer( createKey("123", true, null, ImeTypographyTokens.BODY_SP, onDigits).apply { markSideKey(this) }, - flexKeyParams(0.925f), + flexKeyParams(), ) centerBottom.addView( createSpaceVoiceKey("空格", onSpace), - flexKeyParams(3.4f), + flexKeyParams(), ) centerBottom.addView( createKey("中/英", true, null, ImeTypographyTokens.BODY_SP, onModeSwitch).apply { tag = "key:mode" markSideKey(this) }, - flexKeyParams(0.925f), + flexKeyParams(), ) center.addView( centerBottom, LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, toPx(keyRowHeightDp()), - ).apply { topMargin = toPx(ImeGeometryTokens.KEY_ROW_GAP_DP) }, + ), ) - container.addView(center, adaptiveColumnParams(3.7f)) + container.addView(center, adaptiveColumnParams(25f / 7f)) val side = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL @@ -111,20 +102,21 @@ internal class Pinyin9KeyboardRenderer( } side.addView( createBackspaceKey().apply { markSideKey(this) }, - sideKeyParams(keyRowHeightDp()), + sideKeyParams(nineBodyHeightDp() / 3), ) side.addView( createKey("重输", true, null, ImeTypographyTokens.BODY_SP, onRetranslate).apply { + tag = "key-retype" markSideKey(this) }, - sideKeyParams(keyRowHeightDp()), + sideKeyParams(nineBodyHeightDp() / 3), ) side.addView( createKey(enterLabel, true, null, ImeTypographyTokens.BODY_SP, onEnter).apply { tag = "key-enter" markSideKey(this) }, - sideKeyParams(doubleKeyHeightDp()), + sideKeyParams(nineBodyHeightDp() / 3), ) container.addView(side, adaptiveColumnParams(1f)) @@ -146,8 +138,8 @@ internal class Pinyin9KeyboardRenderer( val key = createKey( if (segmentation) "分词" else subLabel, false, - if (segmentation) "@#/" else null, - if (segmentation) ImeTypographyTokens.BODY_SP else ImeTypographyTokens.KEY_LETTER_SP, + digit, + if (segmentation) ImeTypographyTokens.BODY_SP else ImeTypographyTokens.CANDIDATE_SP, ) { if (segmentation) onPinyinSegment() else onNineKey(digit) }.apply { diff --git a/app/src/main/java/llc/slacker/openime/ProductionKeyPolicy.kt b/app/src/main/java/llc/slacker/openime/ProductionKeyPolicy.kt index 1618f625..4566ef6b 100644 --- a/app/src/main/java/llc/slacker/openime/ProductionKeyPolicy.kt +++ b/app/src/main/java/llc/slacker/openime/ProductionKeyPolicy.kt @@ -17,23 +17,7 @@ internal object ProductionKeyPolicy { /** Visual reference geometry for the shared Chinese/English 26-key bottom row. */ fun twentySixKeyBottomRowWeights(): BottomRowWeights { - val leftOuter = 1.30f - val leftInner = 0.95f - val rightInner = 1.05f - val rightOuter = 1.80f - val balanced = balancedOuterWeights( - leftTotal = leftOuter + leftInner, - rightTotal = rightInner + rightOuter, - leftOuter = leftOuter, - rightOuter = rightOuter, - ) - return BottomRowWeights( - leftOuter = balanced.leftOuter, - leftInner = leftInner, - space = 3.40f, - rightInner = rightInner, - rightOuter = balanced.rightOuter, - ) + return BottomRowWeights(68f, 56f, 178f, 0f, 88f) } /** diff --git a/app/src/main/java/llc/slacker/openime/QuickPhraseEditActivity.kt b/app/src/main/java/llc/slacker/openime/QuickPhraseEditActivity.kt index e44cb403..5984c48f 100644 --- a/app/src/main/java/llc/slacker/openime/QuickPhraseEditActivity.kt +++ b/app/src/main/java/llc/slacker/openime/QuickPhraseEditActivity.kt @@ -17,6 +17,10 @@ import android.window.OnBackInvokedCallback /** Full-screen editor so the active IME can be used to edit the phrase itself. */ class QuickPhraseEditActivity : Activity() { + override fun attachBaseContext(newBase: android.content.Context) { + super.attachBaseContext(SetupUi.appearanceContext(newBase)) + } + companion object { const val EXTRA_ID = "quick_phrase_id" const val EXTRA_CATEGORY = "quick_phrase_category" @@ -111,7 +115,7 @@ class QuickPhraseEditActivity : Activity() { setText(category) setSingleLine(true) imeOptions = EditorInfo.IME_ACTION_NEXT - textSize = ImeTypographyTokens.BODY_SP + textSize = 16f } SetupUi.styleInput(this, categoryEdit) codeEdit = EditText(this).apply { @@ -122,7 +126,7 @@ class QuickPhraseEditActivity : Activity() { inputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS imeOptions = EditorInfo.IME_ACTION_NEXT - textSize = ImeTypographyTokens.BODY_SP + textSize = 16f } SetupUi.styleInput(this, codeEdit) phraseEdit = EditText(this).apply { @@ -133,7 +137,7 @@ class QuickPhraseEditActivity : Activity() { maxLines = 8 gravity = Gravity.TOP or Gravity.START imeOptions = EditorInfo.IME_ACTION_DONE - textSize = ImeTypographyTokens.BODY_SP + textSize = 16f } SetupUi.styleInput(this, phraseEdit) val save = SetupUi.primaryButton(this, "保存") { @@ -200,104 +204,55 @@ class QuickPhraseEditActivity : Activity() { } val actions = LinearLayout(this).apply { orientation = LinearLayout.HORIZONTAL - addView(save, LinearLayout.LayoutParams(0, dp(ImeGeometryTokens.PRIMARY_ROW_HEIGHT_DP), 1f).apply { marginEnd = dp(8) }) - addView(cancel, LinearLayout.LayoutParams(0, dp(ImeGeometryTokens.PRIMARY_ROW_HEIGHT_DP), 1f)) + setPadding(dp(16), dp(12), dp(16), dp(12)) + addView(cancel, LinearLayout.LayoutParams(0, dp(48), 1f).apply { marginEnd = dp(10) }) + addView(save, LinearLayout.LayoutParams(0, dp(48), 1.7f)) } val form = LinearLayout(this).apply { orientation = LinearLayout.VERTICAL - setPadding(dp(16), dp(16), dp(16), dp(16)) - background = SetupUi.rounded( - getColor(R.color.setup_surface), - dp(ImeGeometryTokens.CARD_RADIUS_DP).toFloat(), - getColor(R.color.setup_input_line), - ) - addView(fieldLabel("分类(可选)", R.id.quick_phrase_category_editor), LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - LinearLayout.LayoutParams.WRAP_CONTENT, - )) - addView(categoryEdit, LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - dp(ImeGeometryTokens.FIELD_HEIGHT_DP), - ).apply { bottomMargin = dp(14) }) - addView(fieldLabel("输入码(可选)", R.id.quick_phrase_code_editor), LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - LinearLayout.LayoutParams.WRAP_CONTENT, - )) - addView(codeEdit, LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - dp(ImeGeometryTokens.FIELD_HEIGHT_DP), - ).apply { bottomMargin = dp(14) }) - addView(TextView(this@QuickPhraseEditActivity).apply { - text = "设置后,输入至少 2 个字符的短码即可在候选栏召回这条常用语。" - textSize = ImeTypographyTokens.BODY_SP - setTextColor(getColor(R.color.setup_body)) - setPadding(dp(4), 0, dp(4), dp(12)) - }, LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - LinearLayout.LayoutParams.WRAP_CONTENT, - )) - addView(fieldLabel("常用语内容", R.id.quick_phrase_text_editor), LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - LinearLayout.LayoutParams.WRAP_CONTENT, - )) - addView(phraseEdit, LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - dp(154), - ).apply { bottomMargin = dp(8) }) + setPadding(dp(16), dp(12), dp(16), dp(16)) + val fields = LinearLayout(this@QuickPhraseEditActivity).apply { orientation = LinearLayout.HORIZONTAL } + listOf(Triple("分类(可选)", R.id.quick_phrase_category_editor, categoryEdit), Triple("输入码(可选)", R.id.quick_phrase_code_editor, codeEdit)).forEachIndexed { index, (label, target, field) -> + fields.addView(LinearLayout(this@QuickPhraseEditActivity).apply { + orientation = LinearLayout.VERTICAL + addView(fieldLabel(label, target)) + addView(field, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, dp(48))) + }, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f).apply { if (index == 0) marginEnd = dp(12) }) + } + addView(fields) + addView(fieldLabel("常用语内容", R.id.quick_phrase_text_editor), LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT).apply { topMargin = dp(18) }) + addView(phraseEdit, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, dp(132))) addView(TextView(this@QuickPhraseEditActivity).apply { - text = "保存后会在剪贴板面板中按分类显示,可直接点选输入。" - textSize = ImeTypographyTokens.BODY_SP - setTextColor(getColor(R.color.setup_body)) - setPadding(dp(4), 0, dp(4), dp(12)) - }, LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - LinearLayout.LayoutParams.WRAP_CONTENT, - )) - addView(actions, LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - dp(ImeGeometryTokens.PRIMARY_ROW_HEIGHT_DP), - )) - } - val content = LinearLayout(this).apply { - orientation = LinearLayout.VERTICAL - setPadding(dp(20), dp(24), dp(20), dp(24)) - addView(header, LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - dp(ImeGeometryTokens.TOP_BAR_HEIGHT_DP), - ).apply { bottomMargin = dp(ImeSpacingTokens.MD_DP) }) - addView(form, LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - LinearLayout.LayoutParams.WRAP_CONTENT, - )) + text = "保存后会在剪贴板面板的“常用语”中按分类显示,点选即输入。\n\n设置输入码后,输入至少 2 个字符的短码即可在候选栏召回这条常用语。" + textSize = 12f; setTextColor(getColor(R.color.setup_body)); setLineSpacing(0f, 1.25f) + }, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT).apply { topMargin = dp(8) }) } - setContentView(ScrollView(this).apply { - id = R.id.quick_phrase_scroll - setBackgroundColor(getColor(R.color.setup_page_bg)) - isFillViewport = true + val scroll = ScrollView(this).apply { + id = R.id.quick_phrase_scroll; isFillViewport = true; isVerticalScrollBarEnabled = false setOnScrollChangeListener { _, _, scrollY, _, _ -> savedScrollY = scrollY } + addView(form); post { scrollTo(0, savedScrollY.coerceAtLeast(0)) } + } + setContentView(LinearLayout(this).apply { + orientation = LinearLayout.VERTICAL; setBackgroundColor(getColor(R.color.setup_page_bg)) + addView(header, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, dp(48))) + addView(scroll, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f)) + addView(actions) setOnApplyWindowInsetsListener { view, insets -> if (Build.VERSION.SDK_INT >= 30) { val bars = insets.getInsets(WindowInsets.Type.systemBars() or WindowInsets.Type.displayCutout()) view.setPadding(bars.left, bars.top, bars.right, bars.bottom) } else { @Suppress("DEPRECATION") - view.setPadding( - insets.systemWindowInsetLeft, - insets.systemWindowInsetTop, - insets.systemWindowInsetRight, - insets.systemWindowInsetBottom, - ) + view.setPadding(insets.systemWindowInsetLeft, insets.systemWindowInsetTop, insets.systemWindowInsetRight, insets.systemWindowInsetBottom) } insets } - addView(content) - post { scrollTo(0, savedScrollY.coerceAtLeast(0)) } }) } private fun fieldLabel(label: String, targetId: Int) = TextView(this).apply { text = label - textSize = ImeTypographyTokens.BODY_SP + textSize = 16f setTextColor(getColor(R.color.setup_body)) setPadding(dp(4), 0, dp(4), dp(4)) labelFor = targetId @@ -321,7 +276,7 @@ class QuickPhraseEditActivity : Activity() { .setPositiveButton("放弃", null) .create() dialog.setOnShowListener { - SetupUi.styleDialog(dialog, this@QuickPhraseEditActivity) + SetupUi.styleDialog(dialog, this@QuickPhraseEditActivity, destructivePositive = true) dialog.getButton(android.content.DialogInterface.BUTTON_POSITIVE).setOnClickListener { dialog.dismiss() finish() diff --git a/app/src/main/java/llc/slacker/openime/SettingsPanelController.kt b/app/src/main/java/llc/slacker/openime/SettingsPanelController.kt index ffffd5a3..55a0d934 100644 --- a/app/src/main/java/llc/slacker/openime/SettingsPanelController.kt +++ b/app/src/main/java/llc/slacker/openime/SettingsPanelController.kt @@ -63,6 +63,7 @@ internal class SettingsPanelController( private val onKeyboardHeightChanged: (Int) -> Unit, private val onFloatingStyleChanged: (Int, Int) -> Unit, private val onShowFuzzySettings: () -> Unit, + private val onShowSkinSettings: () -> Unit, private val onOpenAboutData: () -> Unit, private val onFeedback: () -> Unit, private val applyTheme: () -> Unit, @@ -70,6 +71,7 @@ internal class SettingsPanelController( ) { private var storedScrollY = 0 private var settingsScroll: ScrollView? = null + private var showingSkinOnly = false fun scrollPosition(): Int = (settingsScroll?.scrollY ?: storedScrollY).coerceAtLeast(0) @@ -81,7 +83,8 @@ internal class SettingsPanelController( } } - fun renderSettings(reusePanel: Boolean = false) { + fun renderSettings(reusePanel: Boolean = false, skinOnly: Boolean = false) { + showingSkinOnly = skinOnly val previousFocusKey = if (reusePanel) semanticFocusKey(expandedPanel.findFocus()) else null val previousScrollY = @@ -89,7 +92,7 @@ internal class SettingsPanelController( if (!reusePanel || expandedPanel.childCount == 0) { expandedPanel.addView( - createHeader("偏好设置"), + createHeader(if (skinOnly) "强调色与按键皮肤" else "偏好设置"), LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, toPx(ImeGeometryTokens.TOP_BAR_HEIGHT_DP), @@ -118,129 +121,46 @@ internal class SettingsPanelController( tag = "settings-panel" } - content.addView(createSectionTitle("键盘主题"), wrapParams()) - content.addView( - createChipScroll( - ImeTheme.entries.map { it.label }, - currentTheme().label, - ) { label -> - ImeTheme.entries.firstOrNull { it.label == label }?.let { selected -> - onThemeSelected(selected) - renderSettings(reusePanel = true) - } - }, - chipParams(), - ) - - content.addView(createSectionTitle("外观"), wrapParams()) - content.addView( - createChipScroll( - ImeAppearance.entries.map { it.label }, - currentAppearance().label, - ) { label -> - ImeAppearance.entries.firstOrNull { it.label == label }?.let { selected -> - onAppearanceSelected(selected) - renderSettings(reusePanel = true) - } - }, - chipParams(), - ) - - content.addView(createSectionTitle("键盘布局"), wrapParams()) - content.addView( - createChipScroll( - ImeHandedness.entries.map { it.label }, - currentHandedness().label, - ) { label -> - ImeHandedness.entries.firstOrNull { it.label == label }?.let { selected -> - onHandednessChanged(selected) + if (skinOnly) { + content.addView(createSectionTitle("强调色"), wrapParams()) + content.addView(accentColorRow(), groupParams()) + content.addView(createSectionTitle("按键皮肤"), wrapParams()) + content.addView(skinSliders(), groupParams()) + } else { + content.addView(createSectionTitle("外观与布局"), wrapParams()) + content.addView(settingGroup( + segmentedSetting("外观", ImeAppearance.entries.map { it.label }, currentAppearance().label) { label -> + ImeAppearance.entries.first { it.label == label }.let(onAppearanceSelected) renderSettings(reusePanel = true) - } - }, - chipParams(), - ) - content.addView( - settingGroup( - settingsSlider( - "键盘高度", - 92, - 120, - currentKeyboardHeightPercent(), - onKeyboardHeightChanged, - ), - ), - groupParams(), - ) - - content.addView(createSectionTitle("浮动键盘"), wrapParams()) - content.addView( - settingGroup( - settingsSlider( - "浮动宽度", - 72, - 96, - currentFloatingWidthPercent(), - ) { width -> - onFloatingStyleChanged(width, currentFloatingOpacityPercent()) - }, - settingsSlider( - "浮动透明度", - 82, - 100, - currentFloatingOpacityPercent(), - ) { opacity -> - onFloatingStyleChanged(currentFloatingWidthPercent(), opacity) }, - ), - groupParams(), - ) - - content.addView(createSectionTitle("强调色"), wrapParams()) - content.addView( - accentColorRow(), - LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - LinearLayout.LayoutParams.WRAP_CONTENT, - ).apply { bottomMargin = toPx(12) }, - ) - - content.addView(createSectionTitle("按键皮肤"), wrapParams()) - content.addView( - settingGroup( - settingsSlider("圆角", 0, 24, currentSkinRadius()) { value -> - onSkinChanged( - currentSkinOpacity(), - value, - currentSkinFontSize(), - currentSkinColor(), - ) - }, - settingsSlider("不透明度", 70, 100, currentSkinOpacity()) { value -> - onSkinChanged( - value, - currentSkinRadius(), - currentSkinFontSize(), - currentSkinColor(), - ) - }, - settingsSlider("按键字号", 14, 22, currentSkinFontSize()) { value -> - onSkinChanged( - currentSkinOpacity(), - currentSkinRadius(), - value, - currentSkinColor(), - ) + segmentedSetting("单手模式", ImeHandedness.entries.map { it.label }, currentHandedness().label) { label -> + ImeHandedness.entries.first { it.label == label }.let(onHandednessChanged) + renderSettings(reusePanel = true) }, - ), - groupParams(), - ) + settingsSlider("键盘高度", 80, 120, currentKeyboardHeightPercent(), onKeyboardHeightChanged), + ), groupParams()) + if (context !is ImeSettingsActivity) { + content.addView(createSectionTitle("更多外观"), wrapParams()) + content.addView(settingGroup(settingNavigationRow("强调色与按键皮肤", "颜色、圆角、不透明度与字号", onShowSkinSettings)), groupParams()) + } + if (context is ImeSettingsActivity) { + content.addView(createSectionTitle("强调色"), wrapParams()) + content.addView(accentColorRow(), groupParams()) + content.addView(createSectionTitle("按键皮肤"), wrapParams()) + content.addView(skinSliders(), groupParams()) + } + content.addView(createSectionTitle("浮动键盘"), wrapParams()) + content.addView(settingGroup( + settingsSlider("浮动宽度", 72, 100, currentFloatingWidthPercent()) { onFloatingStyleChanged(it, currentFloatingOpacityPercent()) }, + settingsSlider("浮动透明度", 82, 100, currentFloatingOpacityPercent()) { onFloatingStyleChanged(currentFloatingWidthPercent(), it) }, + ), groupParams()) content.addView(createSectionTitle("按键与输入"), wrapParams()) content.addView( settingGroup( settingToggleRow("按键音效", "机械轴敲击反馈"), settingToggleRow("触感震动", "轻微触感反馈"), - settingToggleRow("按键气泡", "可选字母预览,默认仅按键变色"), + settingToggleRow("按键气泡", "按下时显示字母预览"), ), groupParams(), ) @@ -269,6 +189,7 @@ internal class SettingsPanelController( groupParams(), ) + } scroll.addView( content, ViewGroup.LayoutParams( @@ -297,6 +218,35 @@ internal class SettingsPanelController( } } + private fun skinSliders() = settingGroup( + settingsSlider("圆角", 0, 24, currentSkinRadius()) { onSkinChanged(currentSkinOpacity(), it, currentSkinFontSize(), currentSkinColor()) }, + settingsSlider("不透明度", 70, 100, currentSkinOpacity()) { onSkinChanged(it, currentSkinRadius(), currentSkinFontSize(), currentSkinColor()) }, + settingsSlider("按键字号", 14, 22, currentSkinFontSize()) { onSkinChanged(currentSkinOpacity(), currentSkinRadius(), it, currentSkinColor()) }, + ) + + private fun segmentedSetting(label: String, labels: List, selected: String, onSelected: (String) -> Unit): View = + LinearLayout(context).apply { + orientation = LinearLayout.HORIZONTAL + gravity = Gravity.CENTER_VERTICAL + setPadding(toPx(16), 0, toPx(16), 0) + addView(labelText(label, 14f).apply { typeface = android.graphics.Typeface.DEFAULT_BOLD; gravity = Gravity.CENTER_VERTICAL }, + LinearLayout.LayoutParams(0, toPx(56), 1f)) + addView(LinearLayout(context).apply { + orientation = LinearLayout.HORIZONTAL + tag = "segmented-track" + setPadding(toPx(2), toPx(2), toPx(2), toPx(2)) + labels.forEach { value -> + addView(TextView(context).apply { + text = value; textSize = 14f; gravity = Gravity.CENTER; includeFontPadding = false + tag = if (value == selected) "segment-selected" else "segment-option" + contentDescription = "$value,${if (value == selected) "已选中" else "未选中"}" + isClickable = true; isFocusable = true + setOnClickListener { onFeedback(); onSelected(value) } + }, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1f)) + } + }, LinearLayout.LayoutParams(0, toPx(34), 2f)) + } + fun renderFuzzySettings() { expandedPanel.addView( createHeader("模糊音纠错"), @@ -317,7 +267,7 @@ internal class SettingsPanelController( } content.addView( TextView(context).apply { - text = "用于处理常见的近音输入。开启后,候选会同时尝试相近声母,不会改变用户已经输入的拼音。" + text = "近音输入时,候选会同时尝试相近声母;不会改变你已输入的拼音。" textSize = ImeTypographyTokens.PANEL_BODY_SP setLineSpacing(0f, 1.15f) tag = "panel-note" @@ -341,7 +291,8 @@ internal class SettingsPanelController( TextView(context).apply { text = "z / zh · c / ch · s / sh · l / n · en / eng · in / ing" textSize = ImeTypographyTokens.PANEL_BODY_SP - setPadding(0, toPx(6), 0, toPx(6)) + setPadding(toPx(16), toPx(16), toPx(16), toPx(16)) + tag = "fuzzy-rules" }, LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, @@ -385,8 +336,8 @@ internal class SettingsPanelController( LinearLayout.LayoutParams.MATCH_PARENT, toPx(1), ).apply { - marginStart = toPx(44) - marginEnd = toPx(12) + marginStart = 0 + marginEnd = 0 }, ) } @@ -659,7 +610,7 @@ internal class SettingsPanelController( } } }, - FrameLayout.LayoutParams(toPx(28), toPx(28)).apply { + FrameLayout.LayoutParams(toPx(32), toPx(32)).apply { gravity = Gravity.CENTER }, ) @@ -677,7 +628,7 @@ internal class SettingsPanelController( importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO }, - FrameLayout.LayoutParams(toPx(28), toPx(28)).apply { + FrameLayout.LayoutParams(toPx(32), toPx(32)).apply { gravity = Gravity.CENTER }, ) @@ -687,14 +638,14 @@ internal class SettingsPanelController( applyAccentColor(hex) } }, - LinearLayout.LayoutParams(toPx(ImeGeometryTokens.TOUCH_TARGET_DP), toPx(ImeGeometryTokens.TOUCH_TARGET_DP)), + LinearLayout.LayoutParams(0, toPx(44), 1f), ) } swatchGrid.addView( swatchRow, LinearLayout.LayoutParams( - LinearLayout.LayoutParams.WRAP_CONTENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), + LinearLayout.LayoutParams.MATCH_PARENT, + toPx(44), ), ) } @@ -702,7 +653,7 @@ internal class SettingsPanelController( swatchGrid, LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, - toPx(144), + toPx(132), ), ) @@ -712,11 +663,11 @@ internal class SettingsPanelController( row.addView( TextView(context).apply { text = - if (customSelected) "自定义 · $current" else "自定义颜色" + "自定义颜色\n输入 6 位十六进制,如 5B6B7A" textSize = ImeTypographyTokens.PANEL_NOTE_SP - gravity = Gravity.CENTER + gravity = Gravity.CENTER_VERTICAL or Gravity.START includeFontPadding = false - maxLines = 1 + maxLines = 2 ellipsize = TextUtils.TruncateAt.END setPadding(toPx(10), 0, toPx(10), 0) tag = "accent-custom" @@ -735,22 +686,10 @@ internal class SettingsPanelController( showCustomAccentDialog() } }, - LinearLayout.LayoutParams(toPx(132), toPx(ImeGeometryTokens.TOUCH_TARGET_DP)).apply { + LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, toPx(48)).apply { topMargin = toPx(6) }, ) - row.addView( - TextView(context).apply { - text = - AccentPalette.presets.firstOrNull { - AccentPalette.normalize(it.first) == current - }?.second ?: current - textSize = ImeTypographyTokens.PANEL_NOTE_SP - setPadding(0, toPx(8), 0, 0) - tag = "panel-note" - }, - wrapParams(), - ) return row } @@ -762,10 +701,16 @@ internal class SettingsPanelController( currentSkinFontSize(), normalized, ) - renderSettings(reusePanel = true) + renderSettings(reusePanel = true, skinOnly = showingSkinOnly) } - private fun showCustomAccentDialog() { + fun showCustomAccentDialog() { + if (context is android.inputmethodservice.InputMethodService) { + context.startActivity(android.content.Intent(context, ImeSettingsActivity::class.java) + .addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK) + .putExtra(ImeSettingsActivity.EXTRA_EDIT_ACCENT, true)) + return + } val field = EditText(context).apply { setText(AccentPalette.normalize(currentSkinColor()).removePrefix("#")) hint = "RRGGBB" @@ -778,20 +723,33 @@ internal class SettingsPanelController( setSelectAllOnFocus(true) filters = arrayOf(InputFilter.LengthFilter(6)) } + val palette = ImeTheme.IOS.tokens(currentAppearance(), resourcesDark(), AccentPalette.parse(currentSkinColor())) + val inputRow = LinearLayout(context).apply { + orientation = LinearLayout.HORIZONTAL; gravity = Gravity.CENTER_VERTICAL + setPadding(toPx(12), 0, toPx(12), 0) + background = ImeDrawableFactory.rounded(palette.toolbarBackground, toPx(8), palette.primary, toPx(1)) + addView(View(context).apply { + background = ImeDrawableFactory.rounded(palette.primary, toPx(99)) + }, LinearLayout.LayoutParams(toPx(16), toPx(16)).apply { marginEnd = toPx(8) }) + addView(TextView(context).apply { text = "#"; textSize = 14f; setTextColor(palette.keyText) }, wrapParams()) + field.textSize = 14f; field.background = null; field.setPadding(0, 0, 0, 0) + field.setTextColor(palette.keyText) + addView(field, LinearLayout.LayoutParams(0, toPx(44), 1f)) + } val dialog = AlertDialog.Builder(context) .setTitle("自定义强调色") .setMessage("输入 6 位十六进制颜色,例如 5B6B7A") - .setView(field) + .setView(FrameLayout(context).apply { + setPadding(toPx(24), toPx(8), toPx(24), toPx(8)) + addView(inputRow, FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, toPx(44))) + }) .setPositiveButton("应用", null) .setNegativeButton("取消", null) .create() dialog.setOnShowListener { SetupUi.styleDialog(dialog, context) - val accent = AccentPalette.parse(currentSkinColor()) - dialog.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(accent) - dialog.getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(accent) - field.backgroundTintList = ColorStateList.valueOf(accent) + dialog.window?.setSoftInputMode(android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) SetupUi.styleCursor(context, field) field.setOnEditorActionListener { _, actionId, _ -> if (actionId == EditorInfo.IME_ACTION_DONE) { @@ -814,9 +772,11 @@ internal class SettingsPanelController( dialog.dismiss() } } - dialog.show() + SetupUi.showDialog(dialog, context, expandedPanel) } + private fun resourcesDark(): Boolean = context.resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_NIGHT_MASK == android.content.res.Configuration.UI_MODE_NIGHT_YES + private fun settingsSlider( labelText: String, min: Int, @@ -827,7 +787,7 @@ internal class SettingsPanelController( val row = LinearLayout(context).apply { orientation = LinearLayout.HORIZONTAL gravity = Gravity.CENTER_VERTICAL - setPadding(toPx(10), toPx(4), toPx(10), toPx(4)) + setPadding(toPx(16), toPx(4), toPx(16), toPx(4)) tag = "setting-row" minimumHeight = toPx(ImeGeometryTokens.SETTING_ROW_HEIGHT_DP) } @@ -835,11 +795,11 @@ internal class SettingsPanelController( TextView(context).apply { text = labelText textSize = ImeTypographyTokens.PANEL_BODY_SP + typeface = android.graphics.Typeface.DEFAULT_BOLD }, LinearLayout.LayoutParams( - 0, + toPx(72), LinearLayout.LayoutParams.WRAP_CONTENT, - 1f, ), ) val valueView = TextView(context).apply { @@ -890,12 +850,12 @@ internal class SettingsPanelController( LinearLayout.LayoutParams( 0, LinearLayout.LayoutParams.WRAP_CONTENT, - 2f, + 1f, ), ) row.addView( valueView, - LinearLayout.LayoutParams(toPx(ImeGeometryTokens.TOUCH_TARGET_DP), toPx(ImeGeometryTokens.TOUCH_TARGET_DP)), + LinearLayout.LayoutParams(toPx(44), toPx(ImeGeometryTokens.TOUCH_TARGET_DP)), ) val initialDescription = "$labelText,${seekBar.progress}$suffix" diff --git a/app/src/main/java/llc/slacker/openime/SetupUi.kt b/app/src/main/java/llc/slacker/openime/SetupUi.kt index 1bda3365..d53b4dbd 100644 --- a/app/src/main/java/llc/slacker/openime/SetupUi.kt +++ b/app/src/main/java/llc/slacker/openime/SetupUi.kt @@ -19,11 +19,35 @@ import android.widget.TextView /** Shared visual primitives for the non-IME setup and editor screens. */ object SetupUi { + fun appearanceContext(context: Context): Context { + val appearance = ImeSettingsRepository.loadAppearance(context) + val configuration = android.content.res.Configuration(context.resources.configuration) + val night = when (appearance) { + ImeAppearance.DARK -> android.content.res.Configuration.UI_MODE_NIGHT_YES + ImeAppearance.LIGHT -> android.content.res.Configuration.UI_MODE_NIGHT_NO + ImeAppearance.SYSTEM -> configuration.uiMode and android.content.res.Configuration.UI_MODE_NIGHT_MASK + } + configuration.uiMode = (configuration.uiMode and android.content.res.Configuration.UI_MODE_NIGHT_MASK.inv()) or night + val metrics = context.resources.displayMetrics + val density = metrics.density * ImeReferenceSizing.scale(context) + configuration.densityDpi = kotlin.math.round(density * 160f).toInt() + configuration.screenWidthDp = kotlin.math.round(metrics.widthPixels / density).toInt() + configuration.screenHeightDp = kotlin.math.round(metrics.heightPixels / density).toInt() + return context.createConfigurationContext(configuration) + } + + fun dp(context: Context, value: Int): Int = (value * context.resources.displayMetrics.density).toInt() fun accent(context: Context): Int = - AccentPalette.parse(ImeSettingsRepository.loadSkinColor(context)) + tokensForAccent(context).primary + + private fun tokensForAccent(context: Context): ImeTheme.Tokens = ImeTheme.IOS.tokens( + ImeSettingsRepository.loadAppearance(context), + context.resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_NIGHT_MASK == android.content.res.Configuration.UI_MODE_NIGHT_YES, + AccentPalette.parse(ImeSettingsRepository.loadSkinColor(context)), + ) private fun tokens(context: Context): ImeTheme.Tokens { val nightMask = @@ -127,12 +151,15 @@ object SetupUi { text = label textSize = ImeTypographyTokens.BODY_SP isAllCaps = false + elevation = 0f + stateListAnimator = null + typeface = android.graphics.Typeface.create("sans-serif-medium", android.graphics.Typeface.NORMAL) minHeight = dp(context, 48) minWidth = 0 setPadding(dp(context, 8), 0, dp(context, 8), 0) val accent = accent(context) - background = outlineButtonBackground(context) - setTextColor(accent) + background = secondaryBackground(context) + setTextColor(context.getColor(R.color.setup_title)) setOnClickListener { performHapticFeedback(android.view.HapticFeedbackConstants.VIRTUAL_KEY) onClick() @@ -179,6 +206,9 @@ object SetupUi { text = label textSize = ImeTypographyTokens.BODY_SP isAllCaps = false + elevation = 0f + stateListAnimator = null + typeface = android.graphics.Typeface.create("sans-serif-medium", android.graphics.Typeface.NORMAL) minHeight = dp(context, ImeGeometryTokens.PRIMARY_ROW_HEIGHT_DP) background = buttonBackground( context, @@ -208,7 +238,7 @@ object SetupUi { val surface = context.getColor(R.color.setup_surface) val line = context.getColor(R.color.setup_input_line) val accent = accent(context) - val radius = dp(context, ImeGeometryTokens.CARD_RADIUS_DP).toFloat() + val radius = dp(context, ImeGeometryTokens.CONTROL_RADIUS_DP).toFloat() return ImeDrawableFactory.focusedRounded( fillColor = surface, radiusPx = radius, @@ -268,11 +298,12 @@ object SetupUi { orientation = LinearLayout.HORIZONTAL gravity = Gravity.CENTER_VERTICAL minimumHeight = dp(context, ImeGeometryTokens.TOP_BAR_HEIGHT_DP) + setPadding(dp(context, 4), 0, dp(context, 4), 0) addView( ImageButton(context).apply { setImageResource(R.drawable.ic_arrow_back) - imageTintList = ColorStateList.valueOf(accent(context)) + imageTintList = ColorStateList.valueOf(context.getColor(R.color.setup_title)) scaleType = android.widget.ImageView.ScaleType.CENTER setPadding( dp(context, ImeSpacingTokens.MD_DP), @@ -312,7 +343,7 @@ object SetupUi { text = title textSize = ImeTypographyTokens.TITLE_SP setTextColor(context.getColor(R.color.setup_title)) - setTypeface(typeface, android.graphics.Typeface.BOLD) + typeface = android.graphics.Typeface.DEFAULT_BOLD gravity = Gravity.CENTER_VERTICAL includeFontPadding = false if (Build.VERSION.SDK_INT >= 28) setAccessibilityHeading(true) @@ -325,25 +356,39 @@ object SetupUi { ) } + fun showDialog(dialog: AlertDialog, context: Context, anchor: android.view.View) { + if (context is android.inputmethodservice.InputMethodService) { + dialog.window?.apply { + setType(android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG) + attributes = attributes.apply { token = anchor.windowToken } + addFlags(android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) + } + } + dialog.show() + } + fun styleDialog(dialog: AlertDialog, context: Context, destructivePositive: Boolean = false) { - val accent = accent(context) + val palette = tokensForAccent(context) + val accent = if (!ImeSurfacePolicy.isDark(palette) && ImeSettingsRepository.loadSkinColor(context) == AccentPalette.DEFAULT) Color.parseColor("#006AB1") else palette.primary val alertTitleId = context.resources.getIdentifier("alertTitle", "id", "android") if (alertTitleId != 0) { dialog.findViewById(alertTitleId)?.setTextColor( - context.getColor(R.color.setup_title), + palette.keyText, ) } dialog.findViewById(android.R.id.message)?.setTextColor( - context.getColor(R.color.setup_body), + palette.keySecondaryText, ) dialog.getButton(AlertDialog.BUTTON_POSITIVE)?.setTextColor( if (destructivePositive) tokens(context).danger else accent, ) - dialog.getButton(AlertDialog.BUTTON_NEGATIVE)?.setTextColor(accent) + dialog.getButton(AlertDialog.BUTTON_NEGATIVE)?.setTextColor( + if (dialog.getButton(AlertDialog.BUTTON_NEGATIVE)?.text == "取消") palette.keySecondaryText else accent, + ) dialog.getButton(AlertDialog.BUTTON_NEUTRAL)?.setTextColor(accent) dialog.window?.setBackgroundDrawable( ImeDrawableFactory.rounded( - context.getColor(R.color.setup_surface), + palette.toolCardBackground, dp(context, ImeGeometryTokens.DIALOG_RADIUS_DP).toFloat(), ), ) diff --git a/app/src/main/java/llc/slacker/openime/SymbolManagerActivity.kt b/app/src/main/java/llc/slacker/openime/SymbolManagerActivity.kt index bd7295a0..da6ba121 100644 --- a/app/src/main/java/llc/slacker/openime/SymbolManagerActivity.kt +++ b/app/src/main/java/llc/slacker/openime/SymbolManagerActivity.kt @@ -16,10 +16,17 @@ import android.widget.EditText import android.widget.LinearLayout import android.widget.ScrollView import android.widget.TextView +import android.widget.ImageView +import android.widget.PopupMenu +import android.content.res.ColorStateList import android.window.OnBackInvokedCallback /** Touch-friendly manager for user symbols and their order. */ class SymbolManagerActivity : Activity() { + override fun attachBaseContext(newBase: android.content.Context) { + super.attachBaseContext(SetupUi.appearanceContext(newBase)) + } + private val density by lazy { resources.displayMetrics.density } private lateinit var content: LinearLayout private lateinit var groupEdit: EditText @@ -85,7 +92,7 @@ class SymbolManagerActivity : Activity() { val accent = SetupUi.accent(this) content = LinearLayout(this).apply { orientation = LinearLayout.VERTICAL - setPadding(dp(20), dp(24), dp(20), dp(24)) + setPadding(dp(16), 0, dp(16), dp(16)) } val header = SetupUi.activityTopBar( context = this, @@ -96,38 +103,36 @@ class SymbolManagerActivity : Activity() { content.addView( header, fullHeight(ImeGeometryTokens.TOP_BAR_HEIGHT_DP).apply { - bottomMargin = dp(ImeSpacingTokens.SM_DP) + marginStart = -dp(16); marginEnd = -dp(16) }, ) - content.addView(TextView(this).apply { - text = "可添加、分类、固定和删除。点击箭头调整顺序,也可长按符号行拖动排序。" - textSize = ImeTypographyTokens.BODY_SP - setTextColor(getColor(R.color.setup_body)) - setLineSpacing(dp(2).toFloat(), 1f) - setPadding(0, 0, 0, dp(12)) - }, fullWrap()) - content.addView(fieldLabel("分组(可选)", R.id.custom_symbol_group_editor), fullWrap()) + val form = LinearLayout(this).apply { + orientation = LinearLayout.VERTICAL; setPadding(dp(16), dp(16), dp(16), dp(16)) + background = SetupUi.rounded(getColor(R.color.setup_surface), dp(16).toFloat()) + } + content.addView(form, fullWrap().apply { topMargin = dp(12); bottomMargin = dp(18) }) + form.addView(fieldLabel("分组(可选)", R.id.custom_symbol_group_editor), fullWrap()) groupEdit = EditText(this).apply { id = R.id.custom_symbol_group_editor - hint = "分组,例如:常用箭头" + hint = "例如:常用箭头" setSingleLine(true) imeOptions = EditorInfo.IME_ACTION_NEXT - textSize = ImeTypographyTokens.BODY_SP + textSize = 16f setText(draftGroup) } SetupUi.styleInput(this, groupEdit) - content.addView(groupEdit, fullHeight(ImeGeometryTokens.FIELD_HEIGHT_DP).apply { bottomMargin = dp(10) }) - content.addView(fieldLabel("符号或自定义文本", R.id.custom_symbol_text_editor), fullWrap().apply { bottomMargin = dp(2) }) + form.addView(groupEdit, fullHeight(48).apply { bottomMargin = dp(10) }) + form.addView(fieldLabel("符号或自定义文本", R.id.custom_symbol_text_editor), fullWrap().apply { bottomMargin = dp(2) }) symbolEdit = EditText(this).apply { id = R.id.custom_symbol_text_editor - hint = "符号,例如:⇢ 或 自定义文本" + hint = "符号或自定义文本" setSingleLine(true) imeOptions = EditorInfo.IME_ACTION_DONE - textSize = ImeTypographyTokens.BODY_SP + textSize = 16f setText(draftSymbol) } SetupUi.styleInput(this, symbolEdit) - content.addView(symbolEdit, fullHeight(ImeGeometryTokens.FIELD_HEIGHT_DP).apply { bottomMargin = dp(12) }) + form.addView(symbolEdit, fullHeight(48).apply { bottomMargin = dp(12) }) val save = SetupUi.primaryButton(this, "保存符号") { if (symbolEdit.text.isNullOrBlank()) { symbolEdit.error = "请输入符号或自定义文本" @@ -184,12 +189,12 @@ class SymbolManagerActivity : Activity() { override fun afterTextChanged(s: Editable?) = Unit }) refreshSaveState() - content.addView(save, fullHeight(ImeGeometryTokens.PRIMARY_ROW_HEIGHT_DP).apply { bottomMargin = dp(20) }) + form.addView(save, fullHeight(48).apply { bottomMargin = dp(0) }) content.addView(TextView(this).apply { text = "已保存符号" - textSize = ImeTypographyTokens.TITLE_SP - setTextColor(getColor(R.color.setup_title)) - setTypeface(typeface, android.graphics.Typeface.BOLD) + textSize = 12f + setTextColor(getColor(R.color.setup_body)) + setPadding(dp(16), 0, 0, dp(8)) setPadding(0, 0, 0, dp(8)) if (Build.VERSION.SDK_INT >= 28) setAccessibilityHeading(true) }, fullWrap()) @@ -204,29 +209,33 @@ class SymbolManagerActivity : Activity() { tag = "symbol-empty-state" }, fullWrap()) } else { - symbols.groupBy { it.group } - .forEach { (group, groupedSymbols) -> - content.addView(TextView(this).apply { - text = group - textSize = ImeTypographyTokens.TITLE_SP - setTextColor(accent) - setTypeface(typeface, android.graphics.Typeface.BOLD) - setPadding(0, dp(8), 0, dp(4)) - }, fullWrap()) - groupedSymbols.forEach { item -> - content.addView(symbolRow(item, accent), fullWrap().apply { bottomMargin = dp(12) }) - } - } + val list = LinearLayout(this).apply { + orientation = LinearLayout.VERTICAL + background = SetupUi.rounded(getColor(R.color.setup_surface), dp(16).toFloat()) + } + symbols.forEachIndexed { index, item -> + if (index > 0) list.addView(View(this).apply { setBackgroundColor(getColor(R.color.setup_input_line)); alpha = 0.25f }, fullHeight(1)) + list.addView(symbolRow(item, accent), fullHeight(56)) + } + content.addView(list, fullWrap()) } - content.addView(SetupUi.primaryButton(this, "完成") { - requestClose() - }, fullHeight(ImeGeometryTokens.PRIMARY_ROW_HEIGHT_DP).apply { topMargin = dp(12) }) + content.addView(TextView(this).apply { + text = "点击图钉固定;长按左侧把手拖动排序,也可从菜单上移、下移。" + textSize = 12f; setTextColor(getColor(R.color.setup_body)) + }, fullWrap().apply { topMargin = dp(16) }) + val done = SetupUi.secondaryButton(this, "完成") { requestClose() } val scroll = ScrollView(this).apply { setBackgroundColor(getColor(R.color.setup_page_bg)) isFillViewport = true isVerticalScrollBarEnabled = false overScrollMode = View.OVER_SCROLL_IF_CONTENT_SCROLLS setOnScrollChangeListener { _, _, scrollY, _, _ -> savedScrollY = scrollY } + addView(content) + } + setContentView(LinearLayout(this).apply { + orientation = LinearLayout.VERTICAL; setBackgroundColor(getColor(R.color.setup_page_bg)) + addView(scroll, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f)) + addView(done, fullHeight(48).apply { setMargins(dp(16), dp(12), dp(16), dp(12)) }) setOnApplyWindowInsetsListener { view, insets -> if (android.os.Build.VERSION.SDK_INT >= 30) { val bars = insets.getInsets(WindowInsets.Type.systemBars() or WindowInsets.Type.displayCutout()) @@ -242,35 +251,32 @@ class SymbolManagerActivity : Activity() { } insets } - addView(content) - } - setContentView(scroll) + }) scroll.post { scroll.scrollTo(0, savedScrollY.coerceAtLeast(0)) } } private fun symbolRow(item: CustomSymbol, accent: Int): LinearLayout = LinearLayout(this).apply { - orientation = LinearLayout.VERTICAL - setPadding(dp(16), dp(14), dp(12), dp(10)) - background = SetupUi.rounded( - getColor(R.color.setup_surface), - dp(ImeGeometryTokens.CARD_RADIUS_DP).toFloat(), - getColor(R.color.setup_input_line), - ) + orientation = LinearLayout.HORIZONTAL; gravity = Gravity.CENTER_VERTICAL + setPadding(dp(8), 0, dp(8), 0) addView(TextView(this@SymbolManagerActivity).apply { - text = item.symbol - textSize = ImeTypographyTokens.KEY_LETTER_SP - setTextColor(getColor(R.color.setup_title)) - maxLines = 2 - ellipsize = TextUtils.TruncateAt.END - contentDescription = "自定义符号:${item.symbol},${if (item.pinned) "已固定" else "未固定"}" - importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES - }, fullWrap()) + text = "⠿"; textSize = 20f; gravity = Gravity.CENTER; setTextColor(getColor(R.color.setup_body)) + contentDescription = "拖动排序"; isLongClickable = true + setOnLongClickListener { this@apply.performLongClick() } + }, LinearLayout.LayoutParams(dp(32), dp(48))) addView(TextView(this@SymbolManagerActivity).apply { - text = if (item.pinned) "已固定" else "未固定" - textSize = ImeTypographyTokens.CAPTION_SP - setTextColor(if (item.pinned) accent else getColor(R.color.setup_body)) - importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO - }, fullWrap()) + text = item.symbol; textSize = 24f; gravity = Gravity.CENTER; maxLines = 2 + setTextColor(getColor(R.color.setup_title)); contentDescription = "自定义符号:${item.symbol}" + }, LinearLayout.LayoutParams(dp(52), dp(52))) + addView(TextView(this@SymbolManagerActivity).apply { + text = item.group; textSize = 14f; maxLines = 1; ellipsize = TextUtils.TruncateAt.END + setTextColor(getColor(R.color.setup_body)) + }, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)) + addView(ImageView(this@SymbolManagerActivity).apply { + setImageResource(R.drawable.ic_pin); scaleType = ImageView.ScaleType.CENTER_INSIDE + imageTintList = ColorStateList.valueOf(if (item.pinned) accent else getColor(R.color.setup_body)) + contentDescription = if (item.pinned) "取消固定" else "固定"; isClickable = true; isFocusable = true + setOnClickListener { CustomSymbolRepository.togglePinned(this@SymbolManagerActivity, item.id); render() } + }, LinearLayout.LayoutParams(dp(40), dp(48))) val actions = LinearLayout(this@SymbolManagerActivity).apply { orientation = LinearLayout.HORIZONTAL gravity = Gravity.CENTER_VERTICAL @@ -324,7 +330,17 @@ class SymbolManagerActivity : Activity() { } dialog.show() } - addView(actions, fullWrap()) + addView(TextView(this@SymbolManagerActivity).apply { + text = "⋯"; textSize = 24f; gravity = Gravity.CENTER; setTextColor(getColor(R.color.setup_body)) + contentDescription = "符号菜单"; isClickable = true; isFocusable = true + setOnClickListener { anchor -> + PopupMenu(this@SymbolManagerActivity, anchor).apply { + listOf(0, 2, 3, 4).forEach { index -> menu.add(0, index, index, (actions.getChildAt(index) as TextView).text) } + setOnMenuItemClickListener { entry -> actions.getChildAt(entry.itemId).performClick() } + show() + } + } + }, LinearLayout.LayoutParams(dp(36), dp(48))) tag = "symbol-row:${item.id}" contentDescription = null isFocusable = false @@ -386,7 +402,7 @@ class SymbolManagerActivity : Activity() { .setPositiveButton("放弃", null) .create() dialog.setOnShowListener { - SetupUi.styleDialog(dialog, this@SymbolManagerActivity) + SetupUi.styleDialog(dialog, this@SymbolManagerActivity, destructivePositive = true) dialog.getButton(android.content.DialogInterface.BUTTON_POSITIVE).setOnClickListener { dialog.dismiss() finish() diff --git a/app/src/main/java/llc/slacker/openime/SymbolRailRenderer.kt b/app/src/main/java/llc/slacker/openime/SymbolRailRenderer.kt index 3a0fcd72..d6a6a727 100644 --- a/app/src/main/java/llc/slacker/openime/SymbolRailRenderer.kt +++ b/app/src/main/java/llc/slacker/openime/SymbolRailRenderer.kt @@ -14,7 +14,7 @@ import android.widget.TextView * the nine-key/numeric callers. */ internal object SymbolRailRenderer { - private const val CELL_HEIGHT_DP = 48 + private const val CELL_HEIGHT_DP = 54 fun build( context: Context, @@ -22,6 +22,8 @@ internal object SymbolRailRenderer { contentTag: String, contentDescription: String, symbols: List, + cellHeightDp: Int = CELL_HEIGHT_DP, + toPx: (Int) -> Int = { dp(context, it) }, tagPrefix: String, onCommit: (String) -> Unit, onFeedback: () -> Unit, @@ -47,6 +49,8 @@ internal object SymbolRailRenderer { populate( scroll = scroll, symbols = symbols, + cellHeightDp = cellHeightDp, + toPx = toPx, tagPrefix = tagPrefix, onCommit = onCommit, onFeedback = onFeedback, @@ -57,8 +61,10 @@ internal object SymbolRailRenderer { fun populate( scroll: ScrollView, symbols: List, + cellHeightDp: Int = CELL_HEIGHT_DP, tagPrefix: String, preservedHeader: TextView? = null, + toPx: (Int) -> Int = { dp(scroll.context, it) }, onCommit: (String) -> Unit, onFeedback: () -> Unit, ) { @@ -74,7 +80,7 @@ internal object SymbolRailRenderer { inheritedTextColor?.let(preservedHeader::setTextColor) content.addView( preservedHeader, - cellParams(content.context, withGap = true), + cellParams(content.context, withGap = true, heightDp = cellHeightDp, toPx = toPx), ) } symbols.forEachIndexed { index, symbol -> @@ -87,16 +93,18 @@ internal object SymbolRailRenderer { onCommit = onCommit, onFeedback = onFeedback, ), - cellParams(content.context, withGap = index < symbols.lastIndex), + cellParams(content.context, withGap = index < symbols.lastIndex, heightDp = cellHeightDp, toPx = toPx), ) } } - fun cellParams(context: Context, withGap: Boolean) = LinearLayout.LayoutParams( + fun cellParams(context: Context, withGap: Boolean, heightDp: Int = CELL_HEIGHT_DP, toPx: (Int) -> Int = { dp(context, it) }) = LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, - dp(context, CELL_HEIGHT_DP), + toPx(heightDp), ).apply { - if (withGap) bottomMargin = dp(context, 1) + val gap = toPx(ImeGeometryTokens.KEY_GAP_DP) / 2 + setMargins(gap, gap, gap, gap) + height -= gap * 2 } fun cellHeightPx(context: Context): Int = dp(context, CELL_HEIGHT_DP) @@ -110,14 +118,14 @@ internal object SymbolRailRenderer { onFeedback: () -> Unit, ): TextView = TextView(context).apply { text = symbol - textSize = ImeTypographyTokens.BODY_SP + textSize = when (symbol) { "!", "!", "?", "?" -> 24f; ",", "、", "%", "+", "−", "-" -> 22f; else -> 20f } gravity = Gravity.CENTER tag = "$tagPrefix$symbol" contentDescription = symbol isClickable = true isFocusable = true maxLines = 2 - minimumHeight = cellHeightPx(context) + includeFontPadding = false inheritedTextColor?.let(::setTextColor) setOnClickListener { onFeedback() diff --git a/app/src/main/java/llc/slacker/openime/TextEditorPanelController.kt b/app/src/main/java/llc/slacker/openime/TextEditorPanelController.kt index 8b80808d..b43ef434 100644 --- a/app/src/main/java/llc/slacker/openime/TextEditorPanelController.kt +++ b/app/src/main/java/llc/slacker/openime/TextEditorPanelController.kt @@ -47,92 +47,43 @@ internal class TextEditorPanelController( ) val body = LinearLayout(context).apply { - orientation = LinearLayout.VERTICAL - setPadding(toPx(10), toPx(10), toPx(10), toPx(10)) - tag = "text_editor_panel" - } - - val quick = LinearLayout(context).apply { orientation = LinearLayout.HORIZONTAL + gravity = Gravity.CENTER_VERTICAL + setPadding(toPx(12), toPx(18), toPx(12), toPx(18)) + tag = "text_editor_panel" } - QUICK_ACTIONS.forEach { (label, action) -> - val control = createKey(label, ImeTypographyTokens.CAPTION_SP) { onTextEdit(action) }.apply { - tag = "textedit-action:$action" - } - actionControls[action] = ActionControl(label, control) - quick.addView( - control, - LinearLayout.LayoutParams(0, toPx(ImeGeometryTokens.TOUCH_TARGET_DP), 1f).apply { - marginEnd = toPx(5) - }, - ) - } - body.addView( - quick, - LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), - ).apply { bottomMargin = toPx(10) }, - ) - - val cross = LinearLayout(context).apply { - orientation = LinearLayout.VERTICAL - tag = "textedit-cross" - } - fun cell( - label: String? = null, - action: String? = null, - center: Boolean = false, - ): TextView = createPanelButton( - label ?: "", - if (center) ImeTypographyTokens.CAPTION_SP else ImeTypographyTokens.BODY_SP, - !center, - ).apply { - if (action != null) { - setOnClickListener { - onFeedback() - onTextEdit(action) + val cross = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL; tag = "textedit-cross" } + fun cell(label: String = "", action: String? = null, center: Boolean = false): TextView = + createPanelButton(label, if (center) 14f else 24f, false).apply { + if (action != null) { + contentDescription = when (action) { "up" -> "上"; "down" -> "下"; "left" -> "左"; else -> "右" } + setOnClickListener { onFeedback(); onTextEdit(action) } + } else { + tag = if (center) "textedit-center" else "textedit-spacer" + isClickable = false; isFocusable = false } - } else { - tag = "textedit-spacer" - isClickable = false - isFocusable = false - importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO - contentDescription = null } - if (center) text = "光标" - } - listOf( - listOf(cell(), cell("上", "up"), cell()), - listOf(cell("左", "left"), cell(center = true), cell("右", "right")), - listOf(cell(), cell("下", "down"), cell()), - ).forEach { rowItems -> - val row = LinearLayout(context).apply { - orientation = LinearLayout.HORIZONTAL - } - rowItems.forEach { item -> - row.addView( - item, - LinearLayout.LayoutParams(0, toPx(ImeGeometryTokens.TOUCH_TARGET_DP), 1f).apply { - marginEnd = toPx(5) - }, - ) + listOf(cell(), cell("↑", "up"), cell()), + listOf(cell("←", "left"), cell("光标", center = true), cell("→", "right")), + listOf(cell(), cell("↓", "down"), cell()), + ).forEach { items -> + val row = LinearLayout(context).apply { orientation = LinearLayout.HORIZONTAL } + items.forEach { row.addView(it, LinearLayout.LayoutParams(0, toPx(56), 1f).apply { setMargins(toPx(3), toPx(3), toPx(3), toPx(3)) }) } + cross.addView(row, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, toPx(62))) + } + body.addView(cross, LinearLayout.LayoutParams(0, toPx(186), 1.15f).apply { marginEnd = toPx(12) }) + val actions = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL } + listOf(listOf("全选" to "select-all", "撤销" to "undo"), listOf("复制" to "copy", "剪切" to "cut"), listOf("粘贴" to "paste")).forEach { entries -> + val row = LinearLayout(context).apply { orientation = LinearLayout.HORIZONTAL } + entries.forEach { (label, action) -> + val control = createKey(label, 14f) { onTextEdit(action) }.apply { tag = "textedit-action:$action" } + actionControls[action] = ActionControl(label, control) + row.addView(control, LinearLayout.LayoutParams(0, toPx(62), 1f)) } - cross.addView( - row, - LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - toPx(ImeGeometryTokens.TOUCH_TARGET_DP), - ).apply { bottomMargin = toPx(5) }, - ) + actions.addView(row, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, toPx(62))) } - body.addView( - cross, - LinearLayout.LayoutParams(toPx(158), toPx(150)).apply { - gravity = Gravity.CENTER_HORIZONTAL - }, - ) + body.addView(actions, LinearLayout.LayoutParams(0, toPx(186), 1f)) expandedPanel.addView( body, diff --git a/app/src/main/java/llc/slacker/openime/UserDataArchive.kt b/app/src/main/java/llc/slacker/openime/UserDataArchive.kt index 3b1bb6f3..b1d9b39f 100644 --- a/app/src/main/java/llc/slacker/openime/UserDataArchive.kt +++ b/app/src/main/java/llc/slacker/openime/UserDataArchive.kt @@ -201,7 +201,7 @@ internal object UserDataArchiveCodec { ), handedness = value.optString("handedness", ImeHandedness.STANDARD.name), keyboardHeightPercent = - value.optInt("keyboard_height_percent", 100).coerceIn(92, 120), + value.optInt("keyboard_height_percent", 100).coerceIn(80, 120), floatingWidthPercent = value.optInt("floating_width_percent", 88).coerceIn(72, 96), floatingOpacityPercent = diff --git a/app/src/main/java/llc/slacker/openime/VoicePanelController.kt b/app/src/main/java/llc/slacker/openime/VoicePanelController.kt index aef63828..590aa98e 100644 --- a/app/src/main/java/llc/slacker/openime/VoicePanelController.kt +++ b/app/src/main/java/llc/slacker/openime/VoicePanelController.kt @@ -162,7 +162,7 @@ internal class VoicePanelController( setTranscript(recognizedText.ifBlank { "正在聆听… 松开空格结束" }) setModelStatus("正在聆听 · 松开空格结束") onInlineState( - recognizedText.ifBlank { "正在聆听…" }, + recognizedText.ifBlank { "正在聆听" }, false, false, null, @@ -219,7 +219,7 @@ internal class VoicePanelController( "松开空格结束语音并自动上屏,上滑取消", ) onInlineState( - text.ifBlank { "正在聆听…" }, + text.ifBlank { "正在聆听" }, false, false, null, @@ -284,7 +284,7 @@ internal class VoicePanelController( ) onInlineState( if (modelPrepared) { - "正在聆听…" + "正在聆听" } else { "正在录音 · 模型准备中…" }, @@ -371,7 +371,7 @@ internal class VoicePanelController( "松开空格结束语音并自动上屏,上滑取消", ) setModelStatus("正在识别 · 松开空格结束") - onInlineState("正在聆听…", false, false, null) + onInlineState("正在聆听", false, false, null) } } } diff --git a/app/src/main/java/llc/slacker/openime/VoicePanelView.kt b/app/src/main/java/llc/slacker/openime/VoicePanelView.kt index 7563b3b9..3defb2af 100644 --- a/app/src/main/java/llc/slacker/openime/VoicePanelView.kt +++ b/app/src/main/java/llc/slacker/openime/VoicePanelView.kt @@ -7,6 +7,10 @@ import android.view.Gravity import android.view.View import android.widget.LinearLayout import android.widget.TextView +import android.widget.FrameLayout +import android.widget.ImageView +import android.graphics.Color +import android.content.res.ColorStateList /** * Concrete visual surface for the voice panel. @@ -28,6 +32,7 @@ internal class VoicePanelView( private val waveform = LinearLayout(context) private val waves = mutableListOf() private val languageButton: TextView + private val englishButton: TextView private val micButton: TextView private val gestureHint: TextView @@ -37,134 +42,83 @@ internal class VoicePanelView( init { tag = "voice-panel" orientation = VERTICAL - setPadding(toPx(12), toPx(10), toPx(12), toPx(10)) - - val modelReady = initialModelState in setOf( - VoiceModelLifecycleState.HOT, - VoiceModelLifecycleState.RECORDING, - VoiceModelLifecycleState.COOLDOWN, - ) + setPadding(toPx(12), toPx(14), toPx(12), toPx(10)) + gravity = Gravity.CENTER_HORIZONTAL + val dark = resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_NIGHT_MASK == android.content.res.Configuration.UI_MODE_NIGHT_YES + val palette = ImeTheme.IOS.tokens(ImeSettingsRepository.loadAppearance(context), dark, AccentPalette.parse(ImeSettingsRepository.loadSkinColor(context))) + val modelReady = initialModelState in setOf(VoiceModelLifecycleState.HOT, VoiceModelLifecycleState.RECORDING, VoiceModelLifecycleState.COOLDOWN) modelStatus.apply { - text = if (modelReady) { - "离线模型已就绪 · 音频不出设备" - } else { - "离线模型后台准备中 · 未启用联网识别" - } - textSize = ImeTypographyTokens.CAPTION_SP - includeFontPadding = false - gravity = Gravity.CENTER_VERTICAL - tag = "voice-model-status" - accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_POLITE + text = if (modelReady) "离线模型已就绪 · 音频不出设备" else "离线模型准备中 · 音频不出设备" + textSize = 12f; gravity = Gravity.CENTER; tag = "voice-model-status" + includeFontPadding = false; accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_POLITE } - addView( - modelStatus, - LayoutParams(LayoutParams.MATCH_PARENT, toPx(22)), - ) - transcript.apply { - text = "只需长按空格;松开自动上屏,上滑取消" - textSize = ImeTypographyTokens.BODY_SP - gravity = Gravity.CENTER_VERTICAL - maxLines = 2 - ellipsize = TextUtils.TruncateAt.END - setPadding(toPx(12), 0, toPx(12), 0) - tag = "voice-transcript" + tag = "voice-transcript"; visibility = View.GONE accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_POLITE } - addView( - transcript, - LayoutParams(LayoutParams.MATCH_PARENT, toPx(52)), - ) - - waveform.apply { - tag = "voice-waveform" - orientation = HORIZONTAL + addView(transcript, LayoutParams(0, 0)) + val hero = FrameLayout(context).apply { + background = ImeDrawableFactory.rounded(ImeDrawableFactory.blend(palette.primary, palette.keyboardBackground, 0.16f), toPx(99)) + } + micButton = createButton("", 14f, false).apply { + tag = "voice-mic" + setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.ic_mic, 0, 0, 0) gravity = Gravity.CENTER + setPadding(toPx(18), 0, 0, 0) + background = ImeDrawableFactory.rounded(palette.primary, toPx(99)) + compoundDrawableTintList = ColorStateList.valueOf(palette.onAccent) + isEnabled = false + contentDescription = "语音状态,长按空格开始" } - repeat(10) { - val bar = View(context).apply { - tag = "voice-wave-bar" - } - waves += bar - waveform.addView( - bar, - LayoutParams(toPx(4), toPx(12)).apply { - marginEnd = toPx(5) - }, - ) + hero.addView(micButton, FrameLayout.LayoutParams(toPx(60), toPx(60)).apply { gravity = Gravity.CENTER }) + addView(hero, LayoutParams(toPx(88), toPx(88)).apply { bottomMargin = toPx(14) }) + languageButton = createButton(LANGUAGES[0].first, 14f, true).apply { + tag = "voice-language" + setOnClickListener { onFeedback(); languageIndex = 0; onLanguageChanged(languageIndex); updateLanguagePresentation(false) } } - addView( - waveform, - LayoutParams(LayoutParams.MATCH_PARENT, toPx(52)), - ) - - val controls = LinearLayout(context).apply { - orientation = HORIZONTAL + val languageTrack = LinearLayout(context).apply { + orientation = HORIZONTAL; tag = "segmented-track"; setPadding(toPx(2), toPx(2), toPx(2), toPx(2)) } - languageButton = createButton( - LANGUAGES[languageIndex].first, - ImeTypographyTokens.BODY_SP, - true, - ).apply { - tag = "voice-language" + languageTrack.addView(languageButton, LayoutParams(0, LayoutParams.MATCH_PARENT, 1f)) + englishButton = TextView(context).apply { + text = LANGUAGES[1].first; textSize = 14f; gravity = Gravity.CENTER + isClickable = true; isFocusable = true setOnClickListener { - onFeedback() - languageIndex = (languageIndex + 1) % LANGUAGES.size - onLanguageChanged(languageIndex) - updateLanguagePresentation(locked = false) + if (!languageButton.isEnabled) return@setOnClickListener + onFeedback(); languageIndex = 1; onLanguageChanged(languageIndex) + updateLanguagePresentation(false) } } - updateLanguagePresentation(locked = false) - controls.addView( - languageButton, - LayoutParams( - 0, - toPx(ImeGeometryTokens.VOICE_CONTROL_HEIGHT_DP), - 1f, - ), - ) - - micButton = createButton("", ImeTypographyTokens.BODY_SP, false).apply { - tag = "voice-mic" - setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.ic_mic, 0, 0, 0) - compoundDrawablePadding = 0 - isEnabled = false - contentDescription = "语音状态,当前未开始,仅支持长按空格启动" + languageTrack.addView(englishButton, LayoutParams(0, LayoutParams.MATCH_PARENT, 1f)) + addView(languageTrack, LayoutParams(toPx(200), toPx(34)).apply { bottomMargin = toPx(14) }) + gestureHint = createButton("长按说话 · 松开上屏 · 上滑取消", 14f, false).apply { + tag = "voice-gesture-hint"; isClickable = false; isFocusable = false + background = null + typeface = android.graphics.Typeface.DEFAULT } - controls.addView( - micButton, - LayoutParams( - toPx(ImeGeometryTokens.VOICE_CONTROL_HEIGHT_DP), - toPx(ImeGeometryTokens.VOICE_CONTROL_HEIGHT_DP), - ), - ) - - gestureHint = createButton("长按空格开始", ImeTypographyTokens.BODY_SP, true).apply { - tag = "voice-gesture-hint" - isEnabled = false - contentDescription = "长按空格开始语音,松开自动上屏,上滑取消" + val hintRow = LinearLayout(context).apply { + orientation = HORIZONTAL; gravity = Gravity.CENTER_VERTICAL + setPadding(toPx(12), 0, toPx(12), 0) + background = ImeDrawableFactory.rounded(palette.toolCardBackground, toPx(12)) + addView(TextView(context).apply { + text = "空格"; textSize = 14f; gravity = Gravity.CENTER + typeface = android.graphics.Typeface.DEFAULT_BOLD + background = ImeDrawableFactory.rounded(palette.toolCardBackground, toPx(8), palette.border, toPx(1)) + }, LayoutParams(toPx(44), toPx(28)).apply { marginEnd = toPx(10) }) + addView(gestureHint, LayoutParams(0, LayoutParams.MATCH_PARENT, 1f)) } - controls.addView( - gestureHint, - LayoutParams( - 0, - toPx(ImeGeometryTokens.VOICE_CONTROL_HEIGHT_DP), - 1f, - ), - ) - addView( - controls, - LayoutParams( - LayoutParams.MATCH_PARENT, - toPx(ImeGeometryTokens.VOICE_CONTROL_HEIGHT_DP), - ), - ) + addView(hintRow, LayoutParams(LayoutParams.MATCH_PARENT, toPx(44)).apply { marginStart = toPx(34); marginEnd = toPx(34); bottomMargin = toPx(12) }) + addView(modelStatus, LayoutParams(LayoutParams.MATCH_PARENT, toPx(22))) + updateLanguagePresentation(false) } fun selectedLanguageCode(): String = LANGUAGES[languageIndex].second fun refreshLanguageControl(locked: Boolean) { + englishButton.isEnabled = !locked + englishButton.isClickable = !locked + englishButton.alpha = if (locked) ImeSurfacePolicy.DISABLED_ALPHA else 1f languageButton.isEnabled = !locked languageButton.isClickable = !locked languageButton.alpha = if (locked) ImeSurfacePolicy.DISABLED_ALPHA else 1f @@ -194,11 +148,21 @@ internal class VoicePanelView( private fun updateLanguagePresentation(locked: Boolean) { val selected = LANGUAGES[languageIndex].first - languageButton.text = selected + val dark = resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_NIGHT_MASK == android.content.res.Configuration.UI_MODE_NIGHT_YES + val palette = ImeTheme.IOS.tokens(ImeSettingsRepository.loadAppearance(context), dark, AccentPalette.parse(ImeSettingsRepository.loadSkinColor(context))) + listOf(languageButton, englishButton).forEachIndexed { index, button -> + val active = index == languageIndex + button.tag = if (active) "segment-selected" else "segment-option" + button.setTextColor(if (active) palette.keyText else palette.keySecondaryText) + button.typeface = if (active) android.graphics.Typeface.DEFAULT_BOLD else android.graphics.Typeface.DEFAULT + button.background = if (active) ImeDrawableFactory.rounded(palette.toolCardBackground, toPx(10), palette.border, toPx(1)) else null + button.isSelected = active + } + englishButton.contentDescription = if (locked) "语音语言:英文,识别进行中不可切换" else "语音语言:英文" languageButton.contentDescription = if (locked) { - "语音语言:$selected,识别进行中不可切换" + "语音语言:普通话,识别进行中不可切换" } else { - "语音语言:$selected,点击切换" + "语音语言:普通话" } if (Build.VERSION.SDK_INT >= 30) { languageButton.stateDescription = if (locked) { diff --git a/app/src/main/res/drawable/bg_setup_card.xml b/app/src/main/res/drawable/bg_setup_card.xml index 06b5cff6..117bba0d 100644 --- a/app/src/main/res/drawable/bg_setup_card.xml +++ b/app/src/main/res/drawable/bg_setup_card.xml @@ -2,8 +2,5 @@ - diff --git a/app/src/main/res/drawable/ic_arrow_back.xml b/app/src/main/res/drawable/ic_arrow_back.xml index a71b3be0..aa57351d 100644 --- a/app/src/main/res/drawable/ic_arrow_back.xml +++ b/app/src/main/res/drawable/ic_arrow_back.xml @@ -1,9 +1 @@ - - - + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_backspace.xml b/app/src/main/res/drawable/ic_backspace.xml index 8ce73a5e..d32e4280 100644 --- a/app/src/main/res/drawable/ic_backspace.xml +++ b/app/src/main/res/drawable/ic_backspace.xml @@ -1,9 +1 @@ - - - + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_brand_mark.xml b/app/src/main/res/drawable/ic_brand_mark.xml index 28d4895c..f66e0185 100644 --- a/app/src/main/res/drawable/ic_brand_mark.xml +++ b/app/src/main/res/drawable/ic_brand_mark.xml @@ -1,10 +1,4 @@ - - - + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_clipboard.xml b/app/src/main/res/drawable/ic_clipboard.xml index bd260caf..11bfe4e6 100644 --- a/app/src/main/res/drawable/ic_clipboard.xml +++ b/app/src/main/res/drawable/ic_clipboard.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_delete.xml b/app/src/main/res/drawable/ic_delete.xml new file mode 100644 index 00000000..181a8951 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_download.xml b/app/src/main/res/drawable/ic_download.xml new file mode 100644 index 00000000..259d47c8 --- /dev/null +++ b/app/src/main/res/drawable/ic_download.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_edit.xml b/app/src/main/res/drawable/ic_edit.xml index ad93744e..1c95398d 100644 --- a/app/src/main/res/drawable/ic_edit.xml +++ b/app/src/main/res/drawable/ic_edit.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_emoji.xml b/app/src/main/res/drawable/ic_emoji.xml index f8fbb147..b8e76083 100644 --- a/app/src/main/res/drawable/ic_emoji.xml +++ b/app/src/main/res/drawable/ic_emoji.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_floating.xml b/app/src/main/res/drawable/ic_floating.xml new file mode 100644 index 00000000..adbc99fc --- /dev/null +++ b/app/src/main/res/drawable/ic_floating.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_grid.xml b/app/src/main/res/drawable/ic_grid.xml index 5c8f1cb2..023e4a11 100644 --- a/app/src/main/res/drawable/ic_grid.xml +++ b/app/src/main/res/drawable/ic_grid.xml @@ -1,9 +1 @@ - - - + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_keyboard.xml b/app/src/main/res/drawable/ic_keyboard.xml index decb2778..dc4e6dd7 100644 --- a/app/src/main/res/drawable/ic_keyboard.xml +++ b/app/src/main/res/drawable/ic_keyboard.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_mic.xml b/app/src/main/res/drawable/ic_mic.xml index 94769cde..4687a8b1 100644 --- a/app/src/main/res/drawable/ic_mic.xml +++ b/app/src/main/res/drawable/ic_mic.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_pin.xml b/app/src/main/res/drawable/ic_pin.xml new file mode 100644 index 00000000..ac451bbd --- /dev/null +++ b/app/src/main/res/drawable/ic_pin.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_return.xml b/app/src/main/res/drawable/ic_return.xml new file mode 100644 index 00000000..79489b18 --- /dev/null +++ b/app/src/main/res/drawable/ic_return.xml @@ -0,0 +1,8 @@ + + + diff --git a/app/src/main/res/drawable/ic_settings.xml b/app/src/main/res/drawable/ic_settings.xml index 8f789b5c..9a0e9ff7 100644 --- a/app/src/main/res/drawable/ic_settings.xml +++ b/app/src/main/res/drawable/ic_settings.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_shield.xml b/app/src/main/res/drawable/ic_shield.xml new file mode 100644 index 00000000..93a02fb0 --- /dev/null +++ b/app/src/main/res/drawable/ic_shield.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_shift.xml b/app/src/main/res/drawable/ic_shift.xml index d05525b9..c638d060 100644 --- a/app/src/main/res/drawable/ic_shift.xml +++ b/app/src/main/res/drawable/ic_shift.xml @@ -1,9 +1 @@ - - - + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_symbols.xml b/app/src/main/res/drawable/ic_symbols.xml index 2a6870d3..11ed624e 100644 --- a/app/src/main/res/drawable/ic_symbols.xml +++ b/app/src/main/res/drawable/ic_symbols.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_text_cursor.xml b/app/src/main/res/drawable/ic_text_cursor.xml new file mode 100644 index 00000000..e4cb6840 --- /dev/null +++ b/app/src/main/res/drawable/ic_text_cursor.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_undo.xml b/app/src/main/res/drawable/ic_undo.xml new file mode 100644 index 00000000..80befa6f --- /dev/null +++ b/app/src/main/res/drawable/ic_undo.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index e80e5be9..07d5ac98 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,331 +1,55 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index b29c2e4f..63ab93e7 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -1,20 +1,22 @@ #1C1C1E - #242426 + #303032 #F2F2F7 #AEAEB2 #6EC3F7 #50B6F5 #07131D - #242426 - #303033 + #2C2C2E + #3A3A3C #AEAEB2 #5BD08A - #242426 + #1F8A4C #5BD08A #242426 #48484A #242426 #6EC3F7 + #2C2C2E + #6D6D72 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml new file mode 100644 index 00000000..a4e9a6c7 --- /dev/null +++ b/app/src/main/res/values-zh/strings.xml @@ -0,0 +1,36 @@ + + + openIME + 中文 + 英文 + 本地拼音输入法\n词库和语音都在设备内运行 + 在这里试打 + 启用输入法 + 已启用 + 切换到 openIME + 已切换到 openIME + 启用后即可开始输入 + 已启用,切换后就能打字 + 已就绪,在下方试打 + 输入 nihao 得到 你好。点候选上屏,点空格选首选。 + 语音输入需要麦克风权限。音频只在本机处理,不会上传。可选择授权,也可以跳过后继续试打。 + 未获得麦克风授权,语音输入无法使用。授权后即可长按空格说话。 + 语音输入(可选) + 前往系统设置 + 跳过 + 已跳过,可随时授权 + 麦克风已授权 + 长按空格开始说话,松手即可识别。 + 试打 + 试打完成 + 打开偏好设置 + 先启用并切换到 openIME,再进入设置 + 强调色 + 自定义 + 输入 6 位十六进制颜色,例如 5B6B7A + 偏好设置 + 偏好设置 + 常用语 + 自定义符号 + 关于与数据 + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 47c231ab..bfb9a47d 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,21 +1,23 @@ - #D5D8DE - #EEF0F3 + #EFF0F4 + #FFFFFF #1C1C1E #6D6D72 #1D9BF0 #0E85D5 #07131D - #EEF0F3 - #DDE1E7 + #C5C9D2 + #B7BCC5 #6D6D72 #1F8A4C - #EEF0F3 + #1F8A4C #1F8A4C - #EEF0F3 + #EFF0F4 #B7BCC5 - #EEF0F3 + #EFF0F4 #1D9BF0 #1D9BF0 + #E8E9ED + #9B9B9F diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index db440796..a4e9a6c7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -5,9 +5,9 @@ 英文 本地拼音输入法\n词库和语音都在设备内运行 在这里试打 - 启用 + 启用输入法 已启用 - 切换 + 切换到 openIME 已切换到 openIME 启用后即可开始输入 已启用,切换后就能打字 @@ -15,12 +15,12 @@ 输入 nihao 得到 你好。点候选上屏,点空格选首选。 语音输入需要麦克风权限。音频只在本机处理,不会上传。可选择授权,也可以跳过后继续试打。 未获得麦克风授权,语音输入无法使用。授权后即可长按空格说话。 - 授权 + 语音输入(可选) 前往系统设置 跳过 已跳过,可随时授权 - 已授权 - 麦克风已授权,语音输入可以使用。长按空格开始说话,松手即可识别。 + 麦克风已授权 + 长按空格开始说话,松手即可识别。 试打 试打完成 打开偏好设置 diff --git a/scripts/design_reference_e2e.py b/scripts/design_reference_e2e.py new file mode 100644 index 00000000..848bc829 --- /dev/null +++ b/scripts/design_reference_e2e.py @@ -0,0 +1,301 @@ +#!/usr/bin/env python3 +"""Real IME visual/interaction E2E. Explicit emulator serial; screenshots + replay log. +Usage: python3 scripts/design_reference_e2e.py emulator-5554 [output-directory] +Append --panels-only after the output directory to refresh only affected panels. +Requires a built/installed debug APK and Pillow for cropped reference comparisons. +Backs up and restores affected preferences; uses deterministic visual fixtures. +Restores emulator display, locale and font scale. No unit tests or fake InputConnection. +""" +import base64 +import json +import re +import subprocess +import sys +import time +from pathlib import Path +import xml.etree.ElementTree as ET +from PIL import Image + +serial = sys.argv[1] if len(sys.argv) > 1 else '' +if not serial.startswith('emulator-'): + raise SystemExit('Please pass an explicit emulator serial; this suite changes display configuration.') +out = Path(sys.argv[2] if len(sys.argv) > 2 else 'output/design-reference').resolve() +out.mkdir(parents=True, exist_ok=True) +pkg = 'llc.slacker.openime' +panels_only = '--panels-only' in sys.argv +records = json.loads((out / 'results.json').read_text()) if panels_only and (out / 'results.json').exists() else [] + +def adb(*args, binary=False): + result = subprocess.run(['adb', '-s', serial, *args], check=True, capture_output=True) + return result.stdout if binary else result.stdout.decode('utf-8', errors='replace').strip() + +def command(value): + adb('logcat', '-c') + adb('shell', 'am', 'broadcast', '-n', pkg + '/.E2ETestReceiver', '-a', pkg + '.TEST_COMMAND', '--es', 'cmd', value) + time.sleep(0.3) + log = adb('logcat', '-d', '-s', 'OpenImeE2E:I', 'OpenIme:I') + if 'ok=true' not in log: + raise AssertionError(f'Command failed: {value}\n{log}') + return log + +def tap(value): + return command('tap:' + value) + +def tree(): + adb('shell', 'uiautomator', 'dump', '/sdcard/openime-design.xml') + return adb('shell', 'cat', '/sdcard/openime-design.xml') + +def editor(): + for node in ET.fromstring(tree()).iter('node'): + if node.get('resource-id') == pkg + ':id/test_input': + return node.get('text', '') if node.get('text', '') != node.get('hint') else '' + raise AssertionError('Real editor missing') + +def launch(): + adb('shell', 'am', 'force-stop', pkg) + adb('shell', 'am', 'start', '-n', pkg + '/.MainActivity') + time.sleep(1) + for attempt in range(5): + for node in ET.fromstring(tree()).iter('node'): + if node.get('resource-id') == pkg + ':id/test_input': + x1, y1, x2, y2 = map(int, re.findall(r'\d+', node.get('bounds'))) + if y2 <= y1: continue + adb('shell', 'input', 'tap', str((x1+x2)//2), str((y1+y2)//2)) + time.sleep(1) + for _ in range(5): + if 'window=' in command('bounds'): + command('state') + return + adb('shell', 'input', 'tap', str((x1+x2)//2), str((y1+y2)//2)) + time.sleep(.5) + sizes = re.findall(r'(\d+)x(\d+)', adb('shell', 'wm', 'size')) + w, h = map(int, sizes[-1]) + adb('shell', 'input', 'swipe', str(w//2), str(int(h*.6)), str(w//2), str(int(h*.3)), '250') + raise AssertionError('Cannot focus real editor') + +def capture(name, required=()): + time.sleep(0.3) + log = command('bounds') + match = re.search(r'window=(\d+),(\d+),(\d+),(\d+)', log) + if not match: + raise AssertionError('No measured real IME window') + x, y, w, h = map(int, match.groups()) + for label in required: + if label not in log: + raise AssertionError(f'{name}: missing {label}') + # Every actual keyboard key must fit its measured window. Scrollable panel + # content may intentionally extend beyond its viewport and is excluded. + for tag, bounds in re.findall(r'tag=(key:[^|]+|key-9:[^|]+|key-enter|key-space)\|[^\n]*?\|([\d.eE,+-]+)', log): + left, top, width, height = map(float, bounds.split(',')) + scrolling_symbols = 'tag=symbols-panel' in log + if left < -0.002 or left+width > 1.002 or (not scrolling_symbols and (top < -0.002 or top+height > 1.002)): + raise AssertionError(f'{name}: key outside window {tag}: {bounds}') + raw = out / (name + '-screen.png') + raw.write_bytes(adb('exec-out', 'screencap', '-p', binary=True)) + Image.open(raw).crop((x, y, x+w, y+h)).save(out / (name + '.png')) + (out / (name + '-bounds.txt')).write_text(log) + records[:] = [record for record in records if record['case'] != name] + records.append({'case': name, 'window': [x,y,w,h], 'required': list(required), 'passed': True}) + (out / 'results.json').write_text(json.dumps(records, ensure_ascii=False, indent=2)) + print('PASS', name, flush=True) + +def panel(label, name, required=()): + command('mode:PINYIN_9') + tap('更多') + tap(label) + capture(name, required) + +def capture_voice_hold(name): + log = command('bounds') + x,y,w,h = map(int,re.search(r'window=(\d+),(\d+),(\d+),(\d+)',log).groups()) + match = re.search(r'tag=key-space\|[^\n]*?\|([\d.eE,+-]+)',log) + left,top,width,height = map(float,match.group(1).split(',')) + cx,cy = str(int(x+(left+width/2)*w)),str(int(y+(top+height/2)*h)) + hold = subprocess.Popen(['adb','-s',serial,'shell','input','swipe',cx,cy,cx,cy,'3000'],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL) + try: + time.sleep(.9) + capture(name, ('voice-inline-zone','voice-inline-status')) + finally: + hold.wait(timeout=15) + command('mode:PINYIN_26'); command('mode:PINYIN_9') + +def ui_tap(selector): + for attempt in range(5): + for node in ET.fromstring(tree()).iter('node'): + if selector in (node.get('resource-id'), node.get('text'), node.get('content-desc')): + x1,y1,x2,y2 = map(int, re.findall(r'\d+', node.get('bounds'))) + if x2 > x1 and y2 > y1: + adb('shell','input','tap',str((x1+x2)//2),str((y1+y2)//2)) + time.sleep(.7) + return + sizes = re.findall(r'(\d+)x(\d+)', adb('shell','wm','size')) + w,h = map(int,sizes[-1]) + adb('shell','input','swipe',str(w//2),str(int(h*.8)),str(w//2),str(int(h*.3)),'250') + raise AssertionError('Missing visible UI target: ' + selector) + +def capture_app(name, required=()): + time.sleep(.5) + xml = tree() + for label in required: + if label not in xml: raise AssertionError(name + ': missing ' + label) + (out / (name + '.png')).write_bytes(adb('exec-out','screencap','-p',binary=True)) + (out / (name + '-ui.xml')).write_text(xml) + records[:] = [record for record in records if record['case'] != name] + records.append({'case': name, 'required': list(required), 'passed': True}) + (out / 'results.json').write_text(json.dumps(records,ensure_ascii=False,indent=2)) + print('PASS', name, flush=True) + +def appearance(label): + command('mode:PINYIN_9') + tap('更多'); tap('设置'); tap(label) + command('mode:PINYIN_9') + +def write_pref(name, raw): + path = 'shared_prefs/' + name + '.xml' + if raw is None: + adb('shell','run-as',pkg,'rm','-f',path) + else: + subprocess.run(['adb','-s',serial,'shell',f"run-as {pkg} sh -c 'mkdir -p shared_prefs; cat > {path}'"],input=raw,check=True,capture_output=True) + +def pref_items(items): + root = ET.Element('map') + ET.SubElement(root,'string',{'name':'items'}).text = json.dumps(items,ensure_ascii=False) + return ET.tostring(root,encoding='utf-8',xml_declaration=True) + +pref_names = ['ime_settings','ime_quick_phrases','ime_custom_symbols','ime_clipboard_history'] +old_prefs = {} +for name in pref_names: + result = subprocess.run(['adb','-s',serial,'shell','run-as',pkg,'cat','shared_prefs/'+name+'.xml'],capture_output=True) + old_prefs[name] = result.stdout if result.returncode == 0 else None + +old_size = adb('shell', 'wm', 'size') +old_density = adb('shell', 'wm', 'density') +old_font = adb('shell', 'settings', 'get', 'system', 'font_scale') +old_locale = adb('shell', 'cmd', 'locale', 'get-app-locales', pkg) +try: + adb('shell','am','force-stop',pkg) + settings = ET.fromstring(old_prefs['ime_settings'] or b'') + fixtures = {'skin_font': ('int','21'), 'skin_opacity': ('int','100'), 'skin_radius': ('int','8'), 'keyboard_height_percent': ('int','100'), 'floating_width_percent': ('int','100'), 'floating_opacity_percent': ('int','100'), 'sound': ('boolean','false'), 'haptic': ('boolean','true'), 'popup': ('boolean','true'), 'handedness': ('string','STANDARD'), 'skin_color': ('string','#1D9BF0')} + for name,(kind,value) in fixtures.items(): + for node in list(settings): + if node.get('name') == name: settings.remove(node) + node = ET.SubElement(settings,kind,{'name':name}) + if kind == 'string': node.text = value + else: node.set('value',value) + write_pref('ime_settings',ET.tostring(settings,encoding='utf-8',xml_declaration=True)) + write_pref('ime_quick_phrases',pref_items([{'id':i+1,'category':'常用','text':text,'input_code':''} for i,text in enumerate(['会议室 B,下午三点','我到家了,不用担心','example@mail.com'])])) + write_pref('ime_custom_symbols',pref_items([{'id':i+1,'group':'常用箭头','symbol':text,'pinned':i==0} for i,text in enumerate(['→','★','¯\\_(ツ)_/¯'])])) + write_pref('ime_clipboard_history',pref_items([{'text':text,'timestamp':int(time.time()*1000),'pinned':i==0} for i,text in enumerate(['会议室 B,下午三点','example@mail.com','https://example.com/docs/getting-started'])])) + adb('shell', 'cmd', 'locale' , 'set-app-locales', pkg, '--locales', 'zh-CN') + adb('shell', 'ime', 'enable', pkg + '/.LocalVoiceImeService') + adb('shell', 'ime', 'set', pkg + '/.LocalVoiceImeService') + adb('shell', 'pm', 'grant', pkg, 'android.permission.RECORD_AUDIO') + launch() + for theme in ('浅色', '深色'): + appearance(theme) + stem = 'light' if theme == '浅色' else 'dark' + if panels_only: + command('clear-swipe'); command('mode:PINYIN_9') + capture(stem + '-nine-idle', ('key-9:9',)) + command('mode:ENGLISH_26'); capture(stem + '-english26', ('key:q',)) + for label,target,required in [('工具','tools',('tool:设置',)),('切换键盘','keyboard-select',('keyboard-choice-selected',)),('符号','symbols',('symbol-categories',)),('表情','emoji',('emoji-cell',)),('文本编辑','text-editor',('textedit-cross',)),('剪贴板','clipboard',('clip-card',)),('语音输入','voice',('voice-mic',)),('设置','preferences',('settings-slider:键盘高度',))]: + if label == '工具': + command('mode:PINYIN_9'); tap('更多'); capture(stem + '-' + target, required) + else: panel(label,stem + '-' + target,required) + continue + command('clear-swipe'); command('mode:PINYIN_9') + capture(stem + '-nine-idle', ('key-9:1', 'key-9:9', 'key-space')) + capture_voice_hold(stem + '-voice-hold') + command('nine-sequence:64426') + capture(stem + '-nine-composing', ('candidate-first', 'nine-pinyin-path-selected')) + tap('candidate-expand') + capture(stem + '-candidates-expanded', ('candidate-grid-first',)) + tap('candidate-expand'); tap('key-space') + assert '你好' in editor(), 'Nine-key selection did not commit to the real editor' + command('clear-swipe'); command('mode:PINYIN_26') + for letter in 'nihao': tap('key:' + letter) + capture(stem + '-pinyin26', ('key:q', 'candidate-first')) + tap('key-space') + assert '你好' in editor(), '26-key selection did not commit to the real editor' + command('clear-swipe'); command('mode:ENGLISH_26') + capture(stem + '-english26', ('key:q', 'key:mode')) + before = editor() + tap('key:a'); tap('key:b'); tap('key:c') + assert editor() == before + 'abc', 'English input did not commit' + command('clear-swipe'); command('mode:DIGITS') + capture(stem + '-numeric', ('key:0', 'key:.', 'key:@')) + before = editor() + tap('key:1'); tap('key:0'); tap('key:.'); tap('key:5') + assert editor() == before + '10.5', 'Numeric layout commits wrong literals' + command('clear-swipe'); command('mode:PINYIN_9'); tap('更多') + capture(stem + '-tools', ('tool:语音输入', 'tool:设置', 'tool:文本编辑', 'tool:浮动键盘')) + for label, target, required in [ + ('切换键盘','keyboard-select',('keyboard-choice-selected',)), + ('符号','symbols',('symbol-categories',)), + ('表情','emoji',('emoji-cell',)), + ('文本编辑','text-editor',('textedit-cross', 'textedit-action:paste')), + ('语音输入','voice',('voice-mic', 'segment-selected')), + ('剪贴板','clipboard',('segmented-track',)), + ('设置','preferences',('segmented-track', 'settings-slider:键盘高度')), + ]: + panel(label, stem + '-' + target, required) + tap('强调色与按键皮肤') + capture(stem + '-skin', ('accent-swatch', 'accent-custom')) + tap('accent-custom') + capture_app(stem + '-accent-dialog', ('自定义强调色', '应用')) + adb('shell','input','text','5B6B7A') + capture_app(stem + '-accent-editor', ('5B6B7A',)) + ui_tap('应用') + ui_tap('强调色蓝色,未选中') + launch() + command('mode:PINYIN_26'); tap('更多'); tap('浮动键盘') + capture(stem + '-floating', ('floating-drag-handle', 'key:q')) + tap('floating-drag-handle'); command('mode:PINYIN_9') + panel('设置', stem + '-preferences-return') + tap('模糊音与智能纠错') + capture(stem + '-fuzzy', ('fuzzy-rules',)) + command('mode:PINYIN_9') + launch(); adb('shell','input','keyevent','4'); time.sleep(.5) + capture_app(stem + '-setup', ('open_app_settings',)) + ui_tap(pkg + ':id/open_app_settings') + capture_app(stem + '-preferences-full', ('偏好设置', '强调色')) + ui_tap('关于与数据') + capture_app(stem + '-about', ('隐私','用户数据','导出','导入')) + launch() + panel('符号', stem + '-symbols-return') + tap('自定义'); tap('管理自定义符号') + capture_app(stem + '-symbol-manager', ('custom_symbol_text_editor', '完成')) + ui_tap('符号菜单') + capture_app(stem + '-symbol-menu', ('编辑','上移','下移','删除')) + adb('shell','input','keyevent','4'); ui_tap('完成'); launch() + panel('剪贴板', stem + '-clipboard-return') + tap('常用语') + capture(stem + '-quick-phrases', ('quick-phrase-add', 'phrase-card')) + tap('phrase-delete:2') + capture_app(stem + '-phrase-delete-dialog', ('删除常用语','删除')) + ui_tap('取消') + tap('quick-phrase-add') + command('mode:ENGLISH_26'); tap('key:a') + adb('shell','input','keyevent','4'); time.sleep(.5) + capture_app(stem + '-quick-phrase-editor', ('quick_phrase_text_editor','保存')) + ui_tap('取消') + capture_app(stem + '-discard-dialog', ('放弃未保存内容','继续编辑')) + ui_tap('放弃'); launch() + # Narrow phone, wide portrait, landscape, and large fonts use the same view. + for name, size, font in ([] if panels_only else [('narrow','840x1860','1.0'),('wide','1440x2560','1.0'),('landscape','2400x1080','1.0'),('large-font','1080x2400','1.3')]): + adb('shell', 'wm', 'size', size) + adb('shell', 'settings', 'put', 'system', 'font_scale', font) + time.sleep(0.7); launch(); command('clear-swipe'); appearance('浅色') + command('mode:PINYIN_9'); capture(name + '-nine', ('key-9:9',)) + command('mode:PINYIN_26'); capture(name + '-pinyin26', ('key:q',)) + print('All visual and real input scenarios passed.', flush=True) +finally: + adb('shell','am','force-stop',pkg) + for name,raw in old_prefs.items(): write_pref(name,raw) + override = re.search(r'Override size: (\d+x\d+)', old_size) + adb('shell', 'wm', 'size', override.group(1) if override else 'reset') + override = re.search(r'Override density: (\d+)', old_density) + adb('shell', 'wm', 'density', override.group(1) if override else 'reset') + adb('shell', 'settings', 'put', 'system', 'font_scale', old_font if old_font != 'null' else '1.0') + match = re.search(r'\[(.*?)\]', old_locale) + adb('shell', 'cmd', 'locale', 'set-app-locales', pkg, '--locales', match.group(1) if match else '') diff --git a/scripts/extract_reference_emoji.py b/scripts/extract_reference_emoji.py new file mode 100644 index 00000000..7d2a59a4 --- /dev/null +++ b/scripts/extract_reference_emoji.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +"""Extract the emoji artwork supplied on PDF page 28 at its original 3x scale. +Usage: python3 scripts/extract_reference_emoji.py /absolute/path/to/design.pdf +This reads the PDF image directly; no replacement artwork is generated. +""" +import subprocess +import sys +import tempfile +from pathlib import Path +from PIL import Image + +emojis = [ + '😀','😃','😄','😁','😆','😅','😂','🤣', + '🥹','😊','😇','🙂','🙃','😉','😌','😍', + '🥰','😘','😗','😙','😚','☺️','😛','😝', + '😜','🤪','😳','🥺','🤓','😎','🥸','🤩', + '🥳','😏','😒','😞','😔','😟','😕','🙁', +] +output=Path(__file__).resolve().parents[1]/'app/src/main/assets/emoji/reference' +output.mkdir(parents=True,exist_ok=True) +with tempfile.TemporaryDirectory() as folder: + prefix=Path(folder)/'page' + subprocess.run(['pdfimages','-f','28','-l','28','-j',sys.argv[1],str(prefix)],check=True) + page=Image.open(sorted(Path(folder).glob('page-*.jpg'))[0]).convert('RGB') + if page.size!=(1170,906): raise ValueError('Expected the original 390x302 reference at 3x resolution') + background=(213,216,223) + for index,emoji in enumerate(emojis): + cx=(28+48*(index%8))*3; cy=(113+42*(index//8))*3 + icon=page.crop((cx-42,cy-42,cx+42,cy+42)).convert('RGBA') + pixels=icon.load() + for y in range(icon.height): + for x in range(icon.width): + rgb=pixels[x,y][:3] + distance=max(abs(rgb[k]-background[k]) for k in range(3)) + alpha=max(0.,min(1.,(distance-12)/48)) + if alpha==0: pixels[x,y]=(0,0,0,0) + else: + foreground=tuple(max(0,min(255,round((rgb[k]-(1-alpha)*background[k])/alpha))) for k in range(3)) + pixels[x,y]=(*foreground,round(alpha*255)) + name='_'.join(format(ord(c),'x') for c in emoji)+'.png' + icon.save(output/name,optimize=True) +print('Extracted',len(emojis),'reference emoji assets') diff --git a/scripts/reference_phone_capture.py b/scripts/reference_phone_capture.py new file mode 100644 index 00000000..77215c4d --- /dev/null +++ b/scripts/reference_phone_capture.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +"""Capture the real phone UI after installing the debug APK. +Usage: python3 scripts/reference_phone_capture.py SERIAL OUTPUT [--apply-reference-skin] +Only the explicit skin flag updates visual settings. It preserves other preferences +and all dictionaries, clipboard entries, phrases and custom symbols. +""" +import json +import re +import subprocess +import sys +import time +from pathlib import Path +import xml.etree.ElementTree as ET +from PIL import Image + +serial, output = sys.argv[1:3] +out = Path(output).resolve(); out.mkdir(parents=True, exist_ok=True) +pkg = 'llc.slacker.openime' +def adb(*args, binary=False): + data = subprocess.run(['adb', '-s', serial, *args], check=True, capture_output=True).stdout + return data if binary else data.decode('utf-8', errors='replace') +def cmd(value): + adb('logcat','-c') + adb('shell','am','broadcast','-n',pkg+'/.E2ETestReceiver','-a',pkg+'.TEST_COMMAND','--es','cmd',value) + time.sleep(.4) + log = adb('logcat','-d','-s','OpenImeE2E:I','OpenIme:I') + if 'ok=true' not in log: raise AssertionError(value + ': ' + log) + return log + +def tree(): + adb('shell','uiautomator','dump','/sdcard/openime-reference.xml') + return adb('shell','cat','/sdcard/openime-reference.xml') + +def tap_ui(target): + for node in ET.fromstring(tree()).iter('node'): + if node.get('resource-id') == pkg+':id/'+target: + x1,y1,x2,y2 = map(int,re.findall(r'\d+',node.get('bounds'))) + if y2>y1: + adb('shell','input','tap',str((x1+x2)//2),str((y1+y2)//2)); return + raise AssertionError('Missing visible ' + target) + +raw=adb('shell','run-as',pkg,'cat','shared_prefs/ime_settings.xml',binary=True) +prefs=ET.fromstring(raw) +old_mode=next((n.text for n in prefs if n.get('name')=='preferred_chinese_mode'),'PINYIN_26') +if '--apply-reference-skin' in sys.argv: + for name,kind,value in [('skin_font','int','21'),('skin_opacity','int','100'),('skin_radius','int','8'),('skin_color','string','#1D9BF0'),('floating_width_percent','int','100')]: + for n in list(prefs): + if n.get('name')==name: prefs.remove(n) + n=ET.SubElement(prefs,kind,{'name':name}) + if kind=='string': n.text=value + else: n.set('value',value) + adb('shell','am','force-stop',pkg) + subprocess.run(['adb','-s',serial,'shell',f"run-as {pkg} sh -c 'cat > shared_prefs/ime_settings.xml'"],input=ET.tostring(prefs,encoding='utf-8',xml_declaration=True),check=True,capture_output=True) + +old_ime = adb('shell','settings','get','secure','default_input_method').strip() +adb('shell','am','force-stop',pkg) +adb('shell','ime','set',pkg+'/.LocalVoiceImeService') +time.sleep(.7) +records=[] +def capture(name, keyboard=True): + time.sleep(.6) + screen=Image.open(__import__('io').BytesIO(adb('exec-out','screencap','-p',binary=True))) + screen.save(out/(name+'-screen.png')) + if keyboard: + log=cmd('bounds'); box=re.search(r'window=(\d+),(\d+),(\d+),(\d+)',log) + if not box: raise AssertionError('Missing real IME window') + x,y,w,h=map(int,box.groups());screen.crop((x,y,x+w,y+h)).save(out/(name+'.png')) + (out/(name+'-bounds.txt')).write_text(log) + else: + screen.save(out/(name+'.png'));(out/(name+'-ui.xml')).write_text(tree()) + records.append({'case':name,'captured':True}) + print('CAPTURE',name,flush=True) +try: + adb('shell','am','start','-n',pkg+'/.MainActivity');time.sleep(1) + adb('shell','input','keyevent','111');capture('phone-setup',False) + focused = False + for _ in range(5): + tap_ui('test_step');time.sleep(.7) + try: + if 'window=' in cmd('bounds'): + focused = True + break + except AssertionError: + time.sleep(.5) + if not focused: raise AssertionError('Cannot focus the real phone editor') + cmd('mode:PINYIN_9');capture('phone-nine-idle') + cmd('nine-sequence:64426');capture('phone-nine-composing') + cmd('tap:key-space') + # Verify a genuine commit into the Activity's actual EditText. + ui=tree() + if not any(n.get('resource-id')==pkg+':id/test_input' and '你好' in n.get('text','') for n in ET.fromstring(ui).iter('node')): + raise AssertionError('Chinese input did not commit to the real phone editor') + for label,name in [('工具','tools'),('符号','symbols'),('表情','emoji'),('语音输入','voice'),('设置','preferences')]: + cmd('mode:PINYIN_9');cmd('tap:更多') + if label!='工具': cmd('tap:'+label) + capture('phone-'+name) + records.append({'case':'phone-chinese-commit','passed':True}) +finally: + try: cmd('mode:'+old_mode) + except AssertionError: pass + if old_ime and old_ime != pkg+'/.LocalVoiceImeService': adb('shell','ime','set',old_ime) + (out/'results.json').write_text(json.dumps(records,ensure_ascii=False,indent=2)) diff --git a/scripts/reference_visual_review.py b/scripts/reference_visual_review.py new file mode 100644 index 00000000..a866b402 --- /dev/null +++ b/scripts/reference_visual_review.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 +"""Generate review artifacts from the PDF and measured Android E2E screenshots. +Usage: python3 scripts/reference_visual_review.py DESIGN.pdf OUTPUT_DIRECTORY +Images retain their aspect ratio; system navigation is cropped from IME bounds. +""" +import html +import json +import re +import subprocess +import sys +from pathlib import Path +from PIL import Image, ImageDraw, ImageFont + +pdf, output = Path(sys.argv[1]), Path(sys.argv[2]).resolve() +reference = output / 'reference' +review = output / 'review' +reference.mkdir(parents=True, exist_ok=True) +review.mkdir(parents=True, exist_ok=True) +subprocess.run(['pdfimages', '-j', str(pdf), str(reference / 'page')], check=True) +font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 15) + +def resize(im, width): + return im.resize((width, round(im.height * width / im.width)), Image.Resampling.LANCZOS) + +def measured_image(path): + im = Image.open(path).convert('RGB') + bounds = path.with_name(path.stem + '-bounds.txt') + if bounds.exists(): + match = re.search(r'tag=main-dock\|desc=[^|]*\|([\d.eE,+-]+)', bounds.read_text()) + if match: + x, y, w, h = map(float, match.group(1).split(',')) + im = im.crop((round(x * im.width), round(y * im.height), + round((x+w) * im.width), round((y+h) * im.height))) + return im + +pairs = [ + ('phone/phone-nine-idle', 1, '实机 · 九键'), + ('phone/phone-nine-composing', 3, '实机 · 拼音候选'), + ('phone/phone-tools', 22, '实机 · 工具'), + ('phone/phone-symbols', 27, '实机 · 符号'), + ('phone/phone-emoji', 28, '实机 · 表情'), + ('phone/phone-voice', 29, '实机 · 语音'), + ('phone/phone-preferences', 30, '实机 · 偏好设置'), + ('light-pinyin26', 11, '拼音 26 键'), + ('light-english26', 12, '英文 26 键'), + ('light-numeric', 13, '数字键盘'), + ('light-keyboard-select', 23, '切换键盘'), + ('light-clipboard', 24, '剪贴板'), + ('light-quick-phrases', 25, '常用语'), + ('light-text-editor', 26, '文本编辑'), + ('light-skin', 31, '强调色与皮肤'), + ('light-fuzzy', 32, '模糊音'), + ('dark-nine-idle', 6, '深色九键'), + ('dark-tools', 34, '深色工具'), + ('dark-preferences', 33, '深色设置'), +] +cards = [] +phone_rows = [] +for stem, page, label in pairs: + source = output / (stem + '.png') + if not source.exists(): + raise FileNotFoundError(source) + a = resize(Image.open(reference / f'page-{page-1:03d}.jpg').convert('RGB'), 390) + b = resize(measured_image(source), 390) + # Preserve both actual heights. Never stretch a capture to disguise mismatch. + canvas = Image.new('RGB', (800, max(a.height, b.height) + 32), '#f8fafc') + draw = ImageDraw.Draw(canvas) + draw.text((8, 8), f'PDF {page:02d}', fill='#475569', font=font) + draw.text((408, 8), 'Android / phone' if stem.startswith('phone/') else 'Android / emulator', fill='#475569', font=font) + canvas.paste(a, (0, 32)); canvas.paste(b, (410, 32)) + name = stem.replace('/', '-') + '.png' + canvas.save(review / name) + cards.append(f'

{html.escape(label)} · 设计稿第 {page} 页

') + if stem.startswith('phone/') and 'composing' not in stem: + phone_rows.append(canvas) + +overview = Image.new('RGB', (800, sum(im.height for im in phone_rows) + 12*(len(phone_rows)-1)), '#cbd5e1') +y = 0 +for im in phone_rows: + overview.paste(im, (0, y)); y += im.height + 12 +overview.save(output / 'comparison.png') + +for name in ['narrow', 'wide', 'landscape', 'large-font']: + for keyboard in ['nine', 'pinyin26']: + path = output / f'{name}-{keyboard}.png' + im = measured_image(path) + im.save(review / path.name) + cards.append(f'

{name} · {keyboard} · 实测 {im.width} × {im.height}

') + +(output / 'review.html').write_text(''' +openIME 设计稿对照 + +

openIME · 设计稿与真实 Android 对照

+

每组左侧为 PDF 原图,右侧为实机或模拟器截图,统一到 390 宽,仅等比例缩放。输入内容、回车动作、权限与模型状态按实际运行显示。横屏按可用高度收敛键盘尺寸;设置和工具面板可滚动。

+''' + '\n'.join(cards) + '') +records = json.loads((output / 'results.json').read_text()) +phone = json.loads((output / 'phone/results.json').read_text()) +(output / 'README.md').write_text(f'''# openIME 本轮验收 + +设计来源:`{pdf}`。参考画布 390 单位宽,实际尺寸由设备可用宽度计算;横屏同时限制可用高度。文字、图标、键位、间距、圆角同步缩放。 + +- 完整 Android 端到端场景:{len(records)} 项通过,覆盖浅色、深色、窄屏 840×1860、宽屏 1440×2560、横屏 2400×1080、系统字体 1.3 倍。 +- 核心输入回归:7 项通过,验证九键、26 键、英文、数字、删除和真实提交。 +- 最终图标与原稿表情更新:重新执行 20 项面板场景。 +- 手机:1200×2670,截图 {sum(bool(r.get('captured')) for r in phone)} 个页面,真实编辑器提交“你好”通过。 +- 最终 APK 已覆盖安装到连接的手机及模拟器。构建和 Android Lint 通过。 +- 比对保留真实页面状态;没有将模型状态、用户数据或回车动作伪装为设计示例。 + +查看 `review.html` 可逐页并排检查;`comparison.png` 为实机六个页面的设计稿对照。原始截图、控件实测 bounds 和结果 JSON 均在本目录。 + +## 可重复验证 + +在项目根目录执行: + +```bash +./gradlew --offline :app:assembleDebug :app:lintDebug +adb -s emulator-5554 install -r app/build/outputs/apk/debug/app-debug.apk +python3 scripts/design_reference_e2e.py emulator-5554 output/reference-final +bash scripts/core_regression.sh emulator-5554 app/build/outputs/apk/debug/app-debug.apk +python3 scripts/reference_phone_capture.py PHONE_SERIAL output/reference-final/phone +python3 scripts/reference_visual_review.py '{pdf}' output/reference-final +``` + +多尺寸脚本仅允许明确指定模拟器,结束时恢复显示尺寸、字体、外观和测试数据;手机脚本恢复原默认输入法。 +''') +print('Saved comparison.png, review.html and README.md') From 950bbc785a17e6a665bd169995da25ab29588db4 Mon Sep 17 00:00:00 2001 From: limuzi013 <128580527+limuzi013@users.noreply.github.com> Date: Thu, 1 Oct 2026 21:40:16 +0800 Subject: [PATCH 02/12] fix(nine-key): syllable rail, pinyin/word agreement, enter vs space, swipe-clear MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nine-key left rail - While composing, the rail lists the real syllables that can start the open digits (zhong/xiong/xin/yin), longest first, led by the previewed syllable. Tapping one fixes it and the rail moves on to the next position (rime-t9-shiyin / Trime style). Backspace unlocks the last fixed syllable and the segment key's boundary instead of deleting letters. - Fixed syllables reach Rime as letters (luna_pinyin accepts letters and 2-9 in one input) so zhong/xiong stay distinct and candidates match the choice. - The pre-edit pinyin follows the word Rime ranks first (9694264244326 -> wo'xiang'chi'fan / 我想吃饭) instead of the local decoder's independent guess. - The fixed prefix is the one the view recorded, not whatever follows a space: decoder-inserted spaces between guessed syllables were being treated as user-fixed boundaries. Edit/delete logic is now divider-aware. - Side-rail symbols are centred by their ink bounds; full-width punctuation sat in the corner of its em box. Enter / space - Space commits the first candidate; Enter ("确定") commits the typed pinyin as text, matching Rime, fcitx and Gboard Pinyin. They were identical before. Backspace swipe-up clear - Arm distance lowered from 56dp to 32dp (CLEAR_ARM_DP); ordinary flicks fell through to a single delete. The debug clear-swipe hook moved only 48dp and never armed it; it now uses the shared constant. Tests: core_regression.sh gains enter-keeps-pinyin cases (9/9 on emulator); unit tests added for locked-code, syllable options and word readings. The 12 design-contract unit failures from the previous commit are unchanged. Known open: choosing a partial candidate still drops the remaining input. Co-Authored-By: Claude Sonnet 5.5 --- CHANGELOG.md | 2 +- .../slacker/openime/DebugKeyboardActivity.kt | 8 + .../openime/BackspaceGestureController.kt | 16 +- .../llc/slacker/openime/CandidatePipeline.kt | 27 ++- .../llc/slacker/openime/ImeKeyboardView.kt | 181 +++++++++++++++--- .../slacker/openime/LocalVoiceImeService.kt | 36 +++- .../openime/NativeCandidatePipeline.kt | 2 +- .../slacker/openime/NineKeyLocalDecoder.kt | 135 ++++++++++++- .../openime/NineKeySymbolRailController.kt | 62 +++--- .../llc/slacker/openime/NineKeyUiState.kt | 2 +- .../llc/slacker/openime/SymbolRailRenderer.kt | 35 +++- .../slacker/openime/CandidatePipelineTest.kt | 50 ++++- scripts/core_regression.ps1 | 2 +- scripts/core_regression.sh | 14 +- scripts/nine_key_regression.ps1 | 2 +- 15 files changed, 503 insertions(+), 71 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bbac87d3..55a6d6de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ - 持续完善输入法 UI、自适应布局和本地语音模型接入。 - 引入固定版本的 Rime Ice 基础、扩展和 8105 字表,并增加首次部署期间即时可用的高频候选层。 - 增强全拼、简拼、显式分词、首选命中和用户词排序,候选读取上限扩展到 96 项。 -- 统一选词、空格及回车提交后的 composition 清理,删除键不再误删残留候选状态。 +- 统一选词、空格及回车提交后的 composition 清理,删除键不再误删残留候选状态。回车(确定)改为提交已输入的拼音原文,空格仍提交首选候选。 - 增加连续长句、扩展候选、分词和选词后回删的真实 IME 回归脚本。 - 建立 L0~L3 正式测试 SOP、统一证据目录、输入框实验室和隐私回归门禁。 - 将 `DebugKeyboardActivity` 从主变体迁入 debug,release APK 不再导出测试宿主。 diff --git a/app/src/debug/java/llc/slacker/openime/DebugKeyboardActivity.kt b/app/src/debug/java/llc/slacker/openime/DebugKeyboardActivity.kt index 2aba91cc..1fa38cb0 100644 --- a/app/src/debug/java/llc/slacker/openime/DebugKeyboardActivity.kt +++ b/app/src/debug/java/llc/slacker/openime/DebugKeyboardActivity.kt @@ -82,13 +82,21 @@ class DebugKeyboardActivity : Activity(), ImeKeyboardView.Listener, CandidateRes segmentPrefix: String, preferredSuffix: String?, fuzzy: Boolean, + lockPreferred: Boolean, ): CandidatePipeline.NineKeyResolution = candidatePipeline.resolveNineKey( digits = digits, segmentPrefix = segmentPrefix, preferredSuffix = preferredSuffix, fuzzy = fuzzy, + lockPreferred = lockPreferred, ) + override fun nineKeySyllablesFor(digits: String, preferred: String?): List = + candidatePipeline.nineKeySyllablesFor(digits, preferred) + + override fun nineKeyReadingFor(digits: String, candidate: String): List? = + candidatePipeline.nineKeyReadingFor(digits, candidate) + override fun nineKeyPathsFor(code: String?): List = candidatePipeline.nineKeyPathsFor(code) diff --git a/app/src/main/java/llc/slacker/openime/BackspaceGestureController.kt b/app/src/main/java/llc/slacker/openime/BackspaceGestureController.kt index eabce336..b1a08746 100644 --- a/app/src/main/java/llc/slacker/openime/BackspaceGestureController.kt +++ b/app/src/main/java/llc/slacker/openime/BackspaceGestureController.kt @@ -116,7 +116,7 @@ internal class BackspaceGestureController( val shouldUndo = undoAvailable && if (undoArmed) { downward > toPx(16) && horizontal <= toPx(120) } else { - downward >= toPx(36) && horizontal <= toPx(96) + downward >= toPx(CLEAR_ARM_DP) && horizontal <= toPx(96) } if (shouldUndo != undoArmed) { undoArmed = shouldUndo @@ -138,7 +138,7 @@ internal class BackspaceGestureController( val shouldClear = if (clearArmed) { upward > toPx(16) && horizontal <= toPx(120) } else { - upward >= toPx(56) && horizontal <= toPx(96) + upward >= toPx(CLEAR_ARM_DP) && horizontal <= toPx(96) } if (shouldClear == clearArmed) return @@ -210,7 +210,17 @@ internal class BackspaceGestureController( undoAvailable = false } - private companion object { + internal companion object { const val REPEAT_INTERVAL_MS = 60L + + /** + * Travel from the press point that arms clear (up) or restore (down). + * Half a key height past its edge: a normal thumb flick reaches it, a + * wobble while holding repeat-delete does not (the 8dp vertical + * command check and 96dp drift limit still apply). It used to be + * 56dp, more than a full key above the key centre, so ordinary + * flicks fell through to a single delete. + */ + const val CLEAR_ARM_DP = 32 } } diff --git a/app/src/main/java/llc/slacker/openime/CandidatePipeline.kt b/app/src/main/java/llc/slacker/openime/CandidatePipeline.kt index 54d3fc04..ef728b2c 100644 --- a/app/src/main/java/llc/slacker/openime/CandidatePipeline.kt +++ b/app/src/main/java/llc/slacker/openime/CandidatePipeline.kt @@ -13,8 +13,15 @@ interface CandidateResolver { segmentPrefix: String, preferredSuffix: String?, fuzzy: Boolean, + lockPreferred: Boolean = false, ): CandidatePipeline.NineKeyResolution + /** Syllables of [candidate] if it spells exactly all of [digits]; null otherwise. */ + fun nineKeyReadingFor(digits: String, candidate: String): List? = null + + /** Pinyin syllables that can start [digits], best first, for the left rail. */ + fun nineKeySyllablesFor(digits: String, preferred: String?): List = emptyList() + fun nineKeyPathsFor(code: String?): List fun selectedNineKeyPathFor(code: String?): String? fun selectNineKeyPath(code: String, path: String) @@ -122,6 +129,7 @@ class CandidatePipeline internal constructor( segmentPrefix: String, preferredSuffix: String?, fuzzy: Boolean, + lockPreferred: Boolean, ): NineKeyResolution { val boundedDigits = digits .filter { it in '2'..'9' } @@ -136,7 +144,18 @@ class CandidatePipeline internal constructor( ) } - val nativeInput = NineKeyLocalDecoder.nativeCode(segmentPrefix, boundedDigits) + // A syllable the user tapped on the rail is a decision, not a guess: + // hand Rime its letters so zhong/xiong (same digits) stay distinct and + // the candidates agree with the pinyin shown. + val locked = preferredSuffix + ?.lowercase() + ?.trim() + ?.takeIf { lockPreferred && NineKeyLocalDecoder.digitsForPinyin(it) == boundedDigits } + val nativeInput = if (locked != null) { + NineKeyLocalDecoder.nativeCode(segmentPrefix + locked, "", lockLetters = true) + } else { + NineKeyLocalDecoder.nativeCode(segmentPrefix, boundedDigits, lockLetters = true) + } val effectivePreferred = preferredSuffix ?: nineKeyUiState.preferredSuffixFor(nativeInput, segmentPrefix) val local = nineKeyDecoder.resolve( @@ -194,6 +213,12 @@ class CandidatePipeline internal constructor( internal fun nineKeyFallbackCandidatesFor(code: String): List = nineKeyFallbackRegistry.candidatesFor(code) + override fun nineKeySyllablesFor(digits: String, preferred: String?): List = + nineKeyDecoder.syllableOptions(digits, preferred) + + override fun nineKeyReadingFor(digits: String, candidate: String): List? = + nineKeyDecoder.readingFor(digits, candidate) + override fun nineKeyPathsFor(code: String?): List = nineKeyUiState.pathsFor(code) diff --git a/app/src/main/java/llc/slacker/openime/ImeKeyboardView.kt b/app/src/main/java/llc/slacker/openime/ImeKeyboardView.kt index 980d5be7..d605a46b 100644 --- a/app/src/main/java/llc/slacker/openime/ImeKeyboardView.kt +++ b/app/src/main/java/llc/slacker/openime/ImeKeyboardView.kt @@ -1725,7 +1725,7 @@ open class ImeKeyboardView( val rawX = location[0] + anchor.width / 2f val rawY = location[1] + anchor.height / 2f backspaceGestureController.begin(anchor, pointerId = 0, rawX, rawY) { } - backspaceGestureController.update(rawX, rawY - dp(48)) + backspaceGestureController.update(rawX, rawY - dp(BackspaceGestureController.CLEAR_ARM_DP + 8)) backspaceGestureController.finish(commit = true) return true } @@ -1915,6 +1915,8 @@ open class ImeKeyboardView( cellHeightDp = ::keyRowHeightDp, toPx = ::dp, onRailChanged = ::applyThemeToSubtree, + onChooseSyllable = ::chooseNineKeySyllable, + fixedPrefix = ::nineKeyFixedPrefix, ).also { nineKeySymbolRailController = it } } @@ -2243,22 +2245,33 @@ open class ImeKeyboardView( val selStart = minOf(rawStart, rawEnd) val selEnd = maxOf(rawStart, rawEnd) - val lastSpace = current.lastIndexOf(' ') - if (selStart > lastSpace) { - val prefix = if (lastSpace >= 0) current.substring(0, lastSpace + 1) else "" - val suffix = if (lastSpace >= 0) current.substring(lastSpace + 1) else current + val (prefix, suffix) = splitNineKeyText(current) + if (selStart >= prefix.length) { val suffixStart = (selStart - prefix.length).coerceIn(0, suffix.length) val suffixEnd = (selEnd - prefix.length).coerceIn(0, suffix.length) val isAtEnd = (selStart == selEnd && selStart == current.length && prefix == lastNineSegmentPrefix && lastNineDigits.isNotEmpty()) val suffixDigits = if (isAtEnd) { lastNineDigits - } else if (lastNineDigits.isNotEmpty() && lastNineDigits.length == suffix.length && prefix == lastNineSegmentPrefix) { + } else if (lastNineDigits.isNotEmpty() && + lastNineDigits.length == nineKeyLetterCount(suffix, suffix.length) && + prefix == lastNineSegmentPrefix + ) { lastNineDigits } else { - CandidatePipeline.nineKeyDigitsFor(suffix) ?: lastNineDigits + nineKeyDigitsOfTail(suffix) ?: lastNineDigits + } + // The tail may carry decoder dividers; cursor columns are text + // positions, digits are letter positions. + val insertPos = if (isAtEnd) { + suffixDigits.length + } else { + nineKeyLetterCount(suffix, suffixStart).coerceAtMost(suffixDigits.length) + } + val deleteEnd = if (isAtEnd) { + suffixDigits.length + } else { + nineKeyLetterCount(suffix, suffixEnd).coerceIn(insertPos, suffixDigits.length) } - val insertPos = if (isAtEnd) suffixDigits.length else suffixStart - val deleteEnd = if (isAtEnd) suffixDigits.length else suffixEnd val newDigits = (suffixDigits.substring(0, insertPos) + num + suffixDigits.substring(deleteEnd)).take(64) lastNineSegmentPrefix = prefix val newCursor = if (isAtEnd) null else (prefix.length + suffixStart + 1) @@ -2289,6 +2302,7 @@ open class ImeKeyboardView( digits: String, preferredSuffix: String? = null, cursorPosition: Int? = null, + lockPreferred: Boolean = false, ) { val resolveStartedAt = SystemClock.elapsedRealtimeNanos() val resolution = requireCandidateProvider().resolveNineKey( @@ -2296,6 +2310,7 @@ open class ImeKeyboardView( segmentPrefix = lastNineSegmentPrefix, preferredSuffix = preferredSuffix, fuzzy = fuzzyEnabled, + lockPreferred = lockPreferred, ) NineKeyPerformanceTrace.recordResolve( digitLength = digits.length, @@ -2327,6 +2342,114 @@ open class ImeKeyboardView( ) } + /** + * Split the pre-edit text into the part the user fixed (a tapped syllable + * or the segment key) and the still-open tail. Spaces the local decoder + * puts between guessed syllables belong to the tail: treating them as fixed + * boundaries froze guesses such as "woyi a m" and fed them to Rime. + */ + private fun splitNineKeyText(text: String): Pair { + val fixed = lastNineSegmentPrefix + if (fixed.isEmpty()) return "" to text + if (text.startsWith(fixed)) return fixed to text.substring(fixed.length) + val boundary = text.lastIndexOf(' ') + return if (boundary >= 0) { + text.substring(0, boundary + 1) to text.substring(boundary + 1) + } else { + "" to text + } + } + + /** Release the last fixed syllable of [prefix] back into open digits (keeping its spelling shown). */ + private fun unlockLastNineKeySyllable(prefix: String): Boolean { + val trimmed = prefix.trimEnd() + val cut = trimmed.lastIndexOf(' ') + val last = trimmed.substring(cut + 1) + val digits = NineKeyLocalDecoder.digitsForPinyin(last) ?: return false + lastNineSegmentPrefix = if (cut >= 0) trimmed.substring(0, cut + 1) else "" + publishNineKeyDigits(digits, preferredSuffix = last) + return true + } + + private fun nineKeyIsDivider(ch: Char): Boolean = ch == ' ' || ch == '\'' + + /** Letters (not dividers) in the first [end] characters of [text]. */ + private fun nineKeyLetterCount(text: String, end: Int): Int = + (0 until end.coerceIn(0, text.length)).count { !nineKeyIsDivider(text[it]) } + + /** T9 digits of an open tail, ignoring decoder-inserted dividers. */ + private fun nineKeyDigitsOfTail(tail: String): String? = + CandidatePipeline.nineKeyDigitsFor(tail.filterNot(::nineKeyIsDivider)) + + /** + * Rime ranked [topCandidate] first for the current digits. Show that + * word's own pinyin so the pre-edit text and the candidates agree, instead + * of the local decoder's independent guess. Display-only: digits, the + * fixed prefix and the native query are unchanged. + */ + internal fun alignNineKeyPreview(expected: String, topCandidate: String) { + if (mode != KeyboardMode.PINYIN_9 || composition.text.toString() != expected) return + val selection = composition.selectionStart + if (selection >= 0 && selection != expected.length) return // user is editing mid-text + val (prefix, tail) = splitNineKeyText(expected) + val digits = lastNineDigits + if (digits.isEmpty() || digits.length != nineKeyLetterCount(tail, tail.length)) return + // The word also covers the fixed syllables in front; only its tail + // characters spell the still-open digits. + val fixedSyllables = prefix.split(' ').count { it.isNotEmpty() } + val skipped = if (fixedSyllables == 0) 0 else { + if (topCandidate.codePointCount(0, topCandidate.length) <= fixedSyllables) return + topCandidate.offsetByCodePoints(0, fixedSyllables) + } + val syllables = candidateProvider + ?.nineKeyReadingFor(digits, topCandidate.substring(skipped)) + ?.takeIf { it.isNotEmpty() } + ?: return + val aligned = prefix + syllables.joinToString("'") + if (aligned == expected) return + setCompositionText(aligned, aligned.length) + pinyinBuffer.clear() + pinyinBuffer.append(aligned) + candidateBarController.render( + candidates = currentCandidates, + compositionPreview = aligned, + showCompositionWhenEmpty = composeZone.visibility == View.VISIBLE, + ) + listener.onNineKeyCompositionChanged( + composition = aligned, + digitBuffer = digits, + pinyinPaths = lastNinePinyinPaths, + candidates = currentCandidates, + ) + } + + /** The prefix the user has explicitly fixed, for the Pinyin rail. */ + internal fun nineKeyFixedPrefix(): String = + lastNineSegmentPrefix.takeIf { composition.text.toString().startsWith(it) }.orEmpty() + + /** + * The user tapped a syllable in the left Pinyin rail. It becomes a fixed + * boundary: the remaining digits keep decoding after it, and the candidates + * are re-queried with the syllable's letters so every word agrees with it. + * Choosing the syllable that spans all open digits fixes just that tail. + */ + internal fun chooseNineKeySyllable(syllable: String) { + if (mode != KeyboardMode.PINYIN_9) return + val chosen = syllable.lowercase().trim() + val chosenDigits = NineKeyLocalDecoder.digitsForPinyin(chosen) ?: return + val (prefix, tail) = splitNineKeyText(composition.text.toString()) + val digits = lastNineDigits.ifEmpty { CandidatePipeline.nineKeyDigitsFor(tail).orEmpty() } + if (digits.isEmpty() || !digits.startsWith(chosenDigits)) return + lastNineSegmentPrefix = prefix + val rest = digits.substring(chosenDigits.length) + if (rest.isEmpty()) { + publishNineKeyDigits(digits, preferredSuffix = chosen, lockPreferred = true) + } else { + lastNineSegmentPrefix = prefix + chosen + " " + publishNineKeyDigits(rest) + } + } + /** Insert an editable syllable boundary without committing the text. */ private fun onPinyinSegment() { if (mode != KeyboardMode.PINYIN_26 && mode != KeyboardMode.PINYIN_9) return @@ -2436,31 +2559,45 @@ open class ImeKeyboardView( val start = minOf(rawStart, rawEnd) val end = maxOf(rawStart, rawEnd) - val lastSpace = current.lastIndexOf(' ') - if (start > lastSpace) { - val prefix = if (lastSpace >= 0) current.substring(0, lastSpace + 1) else "" - val suffix = if (lastSpace >= 0) current.substring(lastSpace + 1) else current + val (prefix, suffix) = splitNineKeyText(current) + if (start >= prefix.length) { + // Nothing left to delete after the fixed syllables: undo + // the last fix (tapped syllable or the segment key) and + // hand its digits back, rather than eating its letters. + if (suffix.isEmpty() && prefix.isNotEmpty() && start == end && start == current.length && + unlockLastNineKeySyllable(prefix) + ) { + return true + } val suffixStart = (start - prefix.length).coerceIn(0, suffix.length) val suffixEnd = (end - prefix.length).coerceIn(0, suffix.length) - val suffixDigits = if (lastNineDigits.isNotEmpty() && lastNineDigits.length == suffix.length && prefix == lastNineSegmentPrefix) { + val suffixDigits = if (lastNineDigits.isNotEmpty() && + lastNineDigits.length == nineKeyLetterCount(suffix, suffix.length) && + prefix == lastNineSegmentPrefix + ) { lastNineDigits } else { - CandidatePipeline.nineKeyDigitsFor(suffix) + nineKeyDigitsOfTail(suffix) } if (suffixDigits != null && suffixDigits.isNotEmpty()) { + // Decoder dividers make text columns differ from digit + // columns; delete by letter position. + val digitStart = nineKeyLetterCount(suffix, suffixStart).coerceAtMost(suffixDigits.length) + val digitEnd = nineKeyLetterCount(suffix, suffixEnd).coerceIn(digitStart, suffixDigits.length) + val letters = suffix.filterNot(::nineKeyIsDivider) val (nextDigits, newCursor, expectedSuffix) = if (suffixStart == suffixEnd) { - if (suffixStart == 0) { + if (digitStart == 0) { Triple(null, null, null) } else { - val deleteIdx = suffixStart - 1 - val remDigits = suffixDigits.removeRange(deleteIdx, suffixStart) - val remSuffix = if (suffix.length >= suffixStart) suffix.removeRange(deleteIdx, suffixStart) else null - Triple(remDigits, prefix.length + deleteIdx, remSuffix) + val deleteIdx = digitStart - 1 + val remDigits = suffixDigits.removeRange(deleteIdx, digitStart) + val remSuffix = if (letters.length >= digitStart) letters.removeRange(deleteIdx, digitStart) else null + Triple(remDigits, prefix.length + (suffixStart - 1).coerceAtLeast(0), remSuffix) } } else { - val remDigits = suffixDigits.removeRange(suffixStart, suffixEnd) - val remSuffix = if (suffix.length >= suffixEnd) suffix.removeRange(suffixStart, suffixEnd) else null + val remDigits = suffixDigits.removeRange(digitStart, digitEnd) + val remSuffix = if (letters.length >= digitEnd) letters.removeRange(digitStart, digitEnd) else null Triple(remDigits, prefix.length + suffixStart, remSuffix) } diff --git a/app/src/main/java/llc/slacker/openime/LocalVoiceImeService.kt b/app/src/main/java/llc/slacker/openime/LocalVoiceImeService.kt index cf7b58fe..cbe5c2fe 100644 --- a/app/src/main/java/llc/slacker/openime/LocalVoiceImeService.kt +++ b/app/src/main/java/llc/slacker/openime/LocalVoiceImeService.kt @@ -127,13 +127,21 @@ class LocalVoiceImeService : InputMethodService(), ImeKeyboardView.Listener, Can segmentPrefix: String, preferredSuffix: String?, fuzzy: Boolean, + lockPreferred: Boolean, ): CandidatePipeline.NineKeyResolution = candidatePipeline.resolveNineKey( digits = digits, segmentPrefix = segmentPrefix, preferredSuffix = preferredSuffix, fuzzy = fuzzy, + lockPreferred = lockPreferred, ) + override fun nineKeySyllablesFor(digits: String, preferred: String?): List = + candidatePipeline.nineKeySyllablesFor(digits, preferred) + + override fun nineKeyReadingFor(digits: String, candidate: String): List? = + candidatePipeline.nineKeyReadingFor(digits, candidate) + override fun nineKeyPathsFor(code: String?): List = candidatePipeline.nineKeyPathsFor(code) @@ -885,7 +893,10 @@ class LocalVoiceImeService : InputMethodService(), ImeKeyboardView.Listener, Can override fun onEnter() { prepareForManualInput() if (lastComposition.isNotEmpty()) { - commitFirstCandidate() + // Space picks the first word; Enter ("确定") keeps what was typed, + // as Rime, fcitx, Sogou and Gboard Pinyin do. Collapsing both into + // "commit the first candidate" left no way to enter pinyin as text. + commitRawComposition() return } voiceCorrectionTracker.finalizeIfNeeded() @@ -1364,6 +1375,11 @@ class LocalVoiceImeService : InputMethodService(), ImeKeyboardView.Listener, Can nativeReferences = nativeReferences, ) keyboardView?.renderState(state) + if (mode == KeyboardMode.PINYIN_9 && native.isNotEmpty()) { + finalCandidates.firstOrNull()?.let { top -> + keyboardView?.alignNineKeyPreview(composition, top) + } + } } applyWhenCandidateSurfaceIdle() }, @@ -1402,6 +1418,24 @@ class LocalVoiceImeService : InputMethodService(), ImeKeyboardView.Listener, Can finishCandidateCommit(composition, nativeCommit.ifBlank { entry.text }) } + /** Commit the pre-edit pinyin as typed (separators dropped); no word is chosen or learned. */ + private fun commitRawComposition() { + val composition = lastComposition + if (composition.isEmpty()) return + val raw = composition + .filterNot { it == ' ' || it == '\'' || it == '|' } + .ifEmpty { composition } + invalidateCandidateQueries() + gateway.commitText(raw) + gateway.finishComposing() + voiceCorrectionTracker.finalizeIfNeeded() + rime.clear() + lastComposition = "" + state = state.copy(composition = "", candidates = emptyList()) + keyboardView?.clearAssociationCandidates() + keyboardView?.renderState(state) + } + private fun selectCandidate(candidate: String) { val composition = lastComposition if (composition.isEmpty()) return diff --git a/app/src/main/java/llc/slacker/openime/NativeCandidatePipeline.kt b/app/src/main/java/llc/slacker/openime/NativeCandidatePipeline.kt index a85e8be9..6b0cec3e 100644 --- a/app/src/main/java/llc/slacker/openime/NativeCandidatePipeline.kt +++ b/app/src/main/java/llc/slacker/openime/NativeCandidatePipeline.kt @@ -69,7 +69,7 @@ internal class NineKeyFallbackRegistry { } private fun isNineKeyCode(value: String): Boolean = - value.isNotEmpty() && value.all { it in '2'..'9' || it == '\'' } + value.isNotEmpty() && value.all { it in '2'..'9' || it in 'a'..'z' || it == '\'' } } /** Pure merge policy for one or more native Rime query batches. */ diff --git a/app/src/main/java/llc/slacker/openime/NineKeyLocalDecoder.kt b/app/src/main/java/llc/slacker/openime/NineKeyLocalDecoder.kt index 97d3b74d..fa03bbef 100644 --- a/app/src/main/java/llc/slacker/openime/NineKeyLocalDecoder.kt +++ b/app/src/main/java/llc/slacker/openime/NineKeyLocalDecoder.kt @@ -41,12 +41,17 @@ internal class NineKeyLocalDecoder( } private val root = TrieNode() + + /** Han character -> syllables that can read it, most likely first. */ + private val readingsByChar = HashMap>() private var previousDigits = "" private var previousPreview = "" init { - buildEntries().forEach(::insert) + val entries = buildEntries() + entries.forEach(::insert) sortTrie(root) + buildReadings(entries) } @Synchronized @@ -169,6 +174,107 @@ internal class NineKeyLocalDecoder( ) } + private fun buildReadings(entries: List) { + val byChar = HashMap>() + entries.forEach { entry -> + if (entry.phrase || entry.pinyin.length > MAX_SYLLABLE_LENGTH || + !entry.pinyin.all { it in 'a'..'z' } + ) { + return@forEach + } + entry.candidates.forEach { value -> + if (value.codePointCount(0, value.length) == 1) { + byChar.getOrPut(value) { ArrayList(2) } += entry + } + } + } + byChar.forEach { (char, list) -> + readingsByChar[char] = list + .sortedWith(compareByDescending(::entryScore).thenBy { it.pinyin }) + .map { it.pinyin } + .distinct() + } + } + + /** + * Pinyin of [text] when it exactly spells the whole digit string, one + * syllable per character, or null. Used to make the visible pinyin agree + * with the word Rime ranks first. + */ + @Synchronized + fun readingFor(digits: String, text: String): List? { + val bounded = digits.filter { it in '2'..'9' } + if (bounded.isEmpty() || text.isEmpty()) return null + val chars = ArrayList() + var index = 0 + while (index < text.length) { + val cp = text.codePointAt(index) + chars += String(Character.toChars(cp)) + index += Character.charCount(cp) + } + if (chars.size > bounded.length) return null + + val picked = arrayOfNulls(chars.size) + fun walk(charIndex: Int, digitIndex: Int): Boolean { + if (charIndex == chars.size) return digitIndex == bounded.length + for (reading in readingsByChar[chars[charIndex]].orEmpty()) { + val code = digitsForPinyin(reading) ?: continue + if (!bounded.startsWith(code, digitIndex)) continue + picked[charIndex] = reading + if (walk(charIndex + 1, digitIndex + code.length)) return true + } + return false + } + return if (walk(0, 0)) picked.filterNotNull() else null + } + + /** + * Real Pinyin syllables that can start the open digit tail, for the left + * selection rail. Longer spellings come first (they consume more of the + * typed digits), the syllable the preview currently starts with leads, and + * ties follow corpus frequency. A lone digit also offers its key letters so + * a key such as 9 is never a dead end. + */ + @Synchronized + fun syllableOptions(digits: String, preferred: String?, limit: Int = MAX_SYLLABLE_OPTIONS): List { + val bounded = digits.filter { it in '2'..'9' }.take(MAX_DIGITS) + if (bounded.isEmpty()) return emptyList() + val lead = preferred?.lowercase()?.trim()?.takeIf { it.isNotEmpty() } + data class Option(val pinyin: String, val depth: Int, val score: Int) + val found = ArrayList