From 7774d87d971de74eb485a1f0ece60ed9a74b2365 Mon Sep 17 00:00:00 2001 From: serso Date: Fri, 8 Jan 2016 12:37:28 +0100 Subject: [PATCH] Vibrator has been removed from the app --- app/build.gradle | 2 +- app/misc/libs/drag-button-1.0.aar | Bin 22980 -> 0 bytes app/misc/libs/drag-button-1.1.aar | Bin 0 -> 23037 bytes app/src/main/AndroidManifest.xml | 1 - .../calculator/AndroidCalculatorKeyboard.java | 105 ------------- .../org/solovyev/android/calculator/App.java | 8 - .../solovyev/android/calculator/BaseUi.java | 1 - .../calculator/ButtonOnClickListener.java | 33 ++-- .../calculator/CalculatorApplication.java | 2 +- .../android/calculator/CalculatorButton.java | 9 +- .../android/calculator/CalculatorButtons.java | 58 +++---- .../calculator/CalculatorKeyboard.java | 115 ++++++++++++-- .../calculator/CalculatorKeyboardImpl.java | 142 ------------------ .../calculator/CursorDragProcessor.java | 21 +-- .../calculator/DigitButtonDragProcessor.java | 14 +- .../calculator/EqualsDragProcessor.java | 35 ++--- .../android/calculator/Preferences.java | 33 ++-- .../solovyev/android/calculator/Vibrator.java | 42 ------ .../history/BaseHistoryFragment.java | 13 +- .../history/HistoryDragProcessor.java | 41 ++--- .../onscreen/CalculatorOnscreenView.java | 25 ++- .../calculator/view/LongClickEraser.java | 13 +- .../wizard/DragButtonWizardStep.java | 10 +- .../main/res/xml/preferences_appearance.xml | 7 - 24 files changed, 224 insertions(+), 506 deletions(-) delete mode 100644 app/misc/libs/drag-button-1.0.aar create mode 100644 app/misc/libs/drag-button-1.1.aar delete mode 100644 app/src/main/java/org/solovyev/android/calculator/AndroidCalculatorKeyboard.java delete mode 100644 app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboardImpl.java delete mode 100644 app/src/main/java/org/solovyev/android/calculator/Vibrator.java diff --git a/app/build.gradle b/app/build.gradle index e5a9b952..f7f3a535 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,7 +64,7 @@ dependencies { compile('ch.acra:acra:4.7.0') { exclude group: 'org.json' } - compile 'org.solovyev.android.views.dragbutton:drag-button:1.0@aar' + compile 'org.solovyev.android.views.dragbutton:drag-button:1.1@aar' compile 'org.solovyev.android:android-common-lists:1.1.18@aar' compile 'org.solovyev.android:android-common-core:1.1.18@aar' compile 'org.solovyev.android:android-common-other:1.1.18@aar' diff --git a/app/misc/libs/drag-button-1.0.aar b/app/misc/libs/drag-button-1.0.aar deleted file mode 100644 index f9c4de7dc83bad9f6283cee3581e6e78f0671742..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22980 zcmV(%K;pkpO9KQ7000OG0Q0^iNFW;Z-O>O60OA4w00jU508%b=cyyJL%MOAt5JmTV zML)nrdAe3vy7I9yhEyof1X==P#2EkGhKDT)nzFmeIg`%hmT^D?phgL+X$(y86K!Er zR5?MoU8mT_7zY-c)pnu~wbJkp?HH4SD$Q3KNE(UA6zK z?oh%?%2862EGij~64n6W@vxaQ9&ov$2A%~aH@S2;-Vw^F?HxdH^wKU~X>VxR(Xy*$ zPs_fR1N81T{QGb;Q&F&VY^ZGMSYM%UF!rs~F_gQCJwv&#+%>f27qG1lP)h>@3IG5I z2mtiHBuMGV+Zy#z001Rk000XB003ibVRLh3b1rIOa=g1^kZ#eoC78Bt+qO>Hww?K< zZQHhO+dgUAwvCgSC;Q&_ZdG?jMc;leqM~-}9kF8lTw{zm=9+VEMHx^qG$1G_D4^#) zGD)ES$HN5#24wGK!RTynWAEl^=Ei7bXX<1RFlBTDn7KPMnmQR-7`wW-*xNCR{$nW% zaCR}XGjn1vu`zOX{yPZ-l&Z+DFwBI+-%cJVTu65hi8UESj>QTL4oz)^ytAHj9HG1I ze8M5w$6gpiCEhn*wU{kT>8%R1eq-t_w~ zQUYG^!S!S6uQGt0=+wTgy48|Xbt*zWR!708<;FeH!|)@86U|)?Mc%o)p4N52xoq^Y z$HU>o1iXM!g1S0Pekd}oi=|y;3#zo{o_;ewPE;YgAHSR_oizoHBzlsxb6VklrBpoV{ZivOP{F7uD?zj)#RCo>Zl zfW6&6k6!pc_Q?L{9vSO@g3znFWrxa)gkPR5v&GgcRKR%)?6s$gjz|TCzKEeNT^x}n zaDRHOjayuc-y;u$cn|CY&ll*i5Bgpa)wonbZ-rz@o=28fz8{G;Qs{{z^;i6 z0(pzAB02oc#z&UmH3Yt<0Btj;w!6sTN=hT_ERtc4I9JqCQ zP2>hDHtZ#1O}z~tf~(7H;7l!@$JsA2Ks^m^n2!0 zX?_8o02S-H5oz2@m`N?p5|4G;>!H5Y1zT2W&bDSg8huq7Ogt$01jWOpuAYoZp1lp4 zQ%i2NXIP96WVp8j(-2g+%zeY#H|NQ*ZgB+)-Ik++u$z4{l;I_oP@!zQz$(1gn)#r) z&oO5JTNS0Ut>M;mDFG$pnljwEVku*V2M{-UDd$GW41%59Yu!8!Tn7=DsX<@(A@C%c zJ%%UoB@0zq2>_aHnpcU_nJH7n$==;@t5#OkQ3~k^6_m14UGOc-=LfeGvxNlo0YkM>jwcI3vTY3(zD{>;tP}qeFf7iR63)Nw;V< zt$Sj6@x>SmT`_Ky++XtN8nXZE7Dkx==?#^_FdzLw0=K_c?upWolmG$(5UpP*n~$fX zn`Jo5^-1ypeOxIso6lkk5Wy1dHiQ;8gu>KJ305j$w}cywccVlif6&m_r@6(3j$M7< zK3sf6qd8WYb(i$vuKk6geq=`3T%H)rr`ybayw6h9pvU2i##B-3jWxz?;StZN2$=4Gd=wr_HT7H<0sSlDYR!1;9t&*F}N= z0cAt{I|Xq6*A?)O<^N>-fAT$7MNeVL5Y2D5R;OKgy@II?ItZ!@zVwm0D{{av%rr6j zFiFh5t2QR7j(rF6f%DzM6pR@Me(f*Sk>`}K=CM^T*POS&?pe-R%lFgUm^~2fI;_Y* zRESzlWClhfgApEM$HsnU`gRWtF~zZ%(0DxvidYk04lFUlwPFZwy@;g4HXQN9Lu>>+ zguy53u=axEmDN&X&a6do@ul00>vYy8bL>)?w)2Zu>5dh5TbIn3-V%Ei{ZeByobU{H zD>U6v#cw2snLo@%n(bF@8h@+?vxZ_F+v16aL}|oH z;^W+`K_u#|wuic%3ar~g{YEMhuVY9FxX;SN$lV3CXmgF$H0#Y58?OO3>4nNmbt!kb z-O@GbhL^BG=bu*MSneeboou)V-m-N@v_sPctQ6Cw?zr~=HYT|Jxq#f2Hz%4kFMx>L?=NuR+n@OOuo>s5qABt4ryQo z{x}OLBV;T4Q^t|u{7VHWGxBQsbo8QUEx9@9jFS-ktk*8 zLLxFMRS+@iA}Yxq?nr0`T;4}7%m;-YqCiE@f7k=n$a=Q;;bT&d2j5Yq^K8sbet+K& zkOL-XHPwL?IICv12=+~o~qcHSv!`gBgAvw?LhD4&6?n_KsFIDoP z2+9lGox8GiYgFER8+VlzQ%#?2YAWc1tQkvUt|p(dw2ob=Im(zwVcb{>IiuU zH)OqnuUk^j-iu)t)5UPz$*3&T5xU>Gk)7C85g!G0>xF@7lg4CP5SseakfGl}#G z@XYZ*u*dib@Z;+3{eiZ3K4SNoJwVYd42ldDWs)E0RhlIAX%;4#4F~Sr!&;l^8xcXB zo%5Gaulq%D`>;W%XjlTV(9(ZRH$cNZSD`XG3**QHD6!=w&yn2hatk!yA&XC$SD$(s zJCJBQ&gVpQhiKHeGM@%D&HMCU4K@5g|4BLOHR?Ese^4$B?B7vN;J-{c6@aaSjoJU2 z71nCrxT9&{``z|U@9a#MQ745I%8`@L?}WM$3kARzC75j)qLBQuslcG@9yT{*MYXUH ziP}_;_EoaREnQg+(r$eZf=NkR&s$O;5PW}oA3S|n_H5zpkq(Gr6LJJR7flgtrJiX?UKZ+qikE{g4>xh!2L>l8nxmQfR zN42b#si@4v7MrDDil$s%b&m33ou%KCc9?1}uJ|d%$$j6`Zh%&xxJS#2OZJgSyrX%H zAvq)OqkO0taYmVgC40)#B6!&@QmgIC3lKQxO5;>yu2!q2L1MPB8n{%`A?-!ze0RXi5Ocz``ZY>~Hd9U8e<57o!+fAXj z*-d#@C2g&S9^*1Yqzq>gbl7Oel-a>@f`K#uDmsRNbeSx~HnU8+1*DD-YQ3?iaW6)|Bh^17u zT2_NX8XDFj+X)jQ;u?4rZkL*fudl75jcrQ68A=~M-Kb1@-m$-NBE|4rJD+oqRS$Ad zaHUSi$`yZ+qGlM;lce(m((mArp{3HqU#&@ar~TXU3DyQJAMa`AFw@AHC!)WAtB2^p zHld2f(gRY{h|t(CxbtyRIlvT}&|%3Ddr#fbS(ME%E()fr?hqrG8^@6&K6Q!f z7fS!)1BD;`11^65Zyg?nBX=IZ`f)-Bp)rm7ia5bTnD62vh4<#TenZi*;V4}(^)Yr+ z@K-h+F|bWE%?+4hMsL$Yww*B_-OjP}V>E$W9NGrk*55)z-IFLp4R)P)nClCoJ*;6P0rHhflU!I~CaI0UvW?$y7Odn6SY z(Ak-(=3OOnL2iD{6hzR>v0BY(r!s%$bnPn#1DYf{zAO_uLjM@%&}eC>5?H9mVMV(X zSPVAlRhs3~OfgWw4$*yr49__19oV83+d^KReEOgkr5jjYGANzd=uKW4E#)8MA9j0I zUuz9oGo~t>T|J>K4~iZl8IuGsZpfz-=Q9(T|HtK{B^CwG%dN>j_pgzv_lEkT}*8&G&`eWM>F_ zcPs)Em0U||drB?_y_%2A&Dl`I4A47=6(EfXb6VMo2#6(dpJ<$#v5EG9z^Z#phhel);(kH*uDj(yr-tfYz&O{yT)LncW$f zkhm=znb?20OZDomSEzKbf89GTbyqm37jYnv)g35*PBDPnxf?vZKJEPi>{nfSPqy=b z!mPNS1N(l8(U>_b;KMLrj_~>5ISK1{hv^XDW$f{bA2-6DHc!bOa%eFYfM={wT*d<9 zQc%)2=BXt(^c}u|kThD!8_sA9MZcXo$RwUHf^4+`_JE9jj#7+bki>7iiof6nXZg7ScXUcBMc zW<1y#jM$Odlo)qIE$MCH33sf^C5wSM&jqUvXR0oiF}ox=HV4Xv@(R8V4cZ+BK87ih z7Znr@AL&5)8SEV?e%U*J$NWuCHWvw$Ja(_996GArCap{5WX84m{!SD<7pJqyW z8!dS7k4p{<(!VoP&i}HR3cCVqOhxSN%mEhv>7uDgS_)f2NMk=DvtjFCs;?oqY&t&lLXf&*<^vq`J>x|?`H&_Bhe zLoT8RSi>DFK<+xC5JR-BZ8mbN7t(*VN5zLcX70HBNmsi@x|Dx&%7EGYmQVLLFLjzc z@t%R*ZJp|tS1mYH5k6Q76rpNsrG<`egE3|7%pG?iqv(_Eo>w{GB~hgoq=g?{x0{zd ztv#pqa$NhxbgG%H|t8pT~b)}sEVT1k9O zQ{BkFVyFH6y;+&Zw-OnpN}D2~jZ2xs!egu{lc}_QhkMl_Io4z3LW&@Qf_;U(_mL|p z=N3&(t@If7^O3Po9|~HU%4@o=^W#>1_kk-Hw%vFk8Rn!1*og3^2QY%&%qZ4ow?SnO z(HQizJKst#{BpY-b@Mb8PTrmj`LRcOh(q5|zsAeGz#M#2TkF%G$!sX1%x%fPt#Gk3 z-b$mK+>$E+*;*q(1_q%6rz*fI2w{f!JIszn(Tji>di&U4YrRpX?&ez@spfUT$L|k; zUXK`tTm_RNL9NlVlTJ{~IKahBQPEYBQ>t6XAF#r4msn}LL+Z_$K&MiZ1RP5(kJ2k# zLPKn5CRr?xj#W_DE3wNKOg(gzx$KHn4mreH|4+oN-4ov9|ABbxzeQZ>e@|6U)y%_1 z)X2r?KiSZ#X{&;(hURC7vX0dDxEQ4wWh`e6wGQMvC>_11Xk`Nf_|>9h%{jqA2j6Yv zo(y8OvViFK5X?IJPWfeM0fv|R0Qp{wH@CA>V&txZw}HTV)|dN~bC&mcy$kRE^E74v zG<#Id@O;F;>1ii$dWvc%aB`|2Gi||)H|7hh45!yYC;}|DOY2DL{6rMSvTCf@FdL2t zt_o(uyI+c50NTX}YxoTt(D)u}5dYb~*srdHE9 zmJqKhkvS2bVPj`s5zQ#?v|iQi;pQA>aw#v%nheWPx{4}9qj}7!vML+VpqAm=0^+b* zsVd7(sc6j6US9sKT`Ek3uO_7=7dBYdO>Li9iO#~^C(M8>Fg%~Hmwu^SMN)aP+*ClHKH4ljq+kK%x3aWU~=p|2{Rm}4~!kY7R7M;hFSs~_nClRIxW6j;`^2A z58O+sv}-H}MVeW&SU)F9F|d?6(LTD293|9}gu>2og0-|&M9yY3&7|+mcdm`&^LhFw z{nj5|KO$?9z}%=t8vs)d)(q@CmY<*gA6}5_67t>oRWQ!vZCPereiR}RSsDzp;Rppe zq;+$mZabJw6+r(cCsfWESRZtT5bq72j2gT!CPl^ki6Jz^e$g zEIx34^g9SIN#BS`ST?X-a^YKLSvt&B%VYuq5%BOd@@~Z{y0HDl)DLcOosa}xagPGN5XPK@uF$2dO-oz}c1kLkwqG{z#F~LOg zH7?s99HT#=vlMU0a(^T1x<4asNRqzrce>AI#oY#zOuC`S$J~+qj1S1h^Tg2%VMwkC zyfmSEWk-Q%O(JSdLik6p)d#6QV%N_ljqw`1UgbUG@5nxfzJU01pjhC3&!EML z^!Xe7xfrtov*guU{yvG6f|#455Ah(9mT#{Jwy+Ww7$DIEa!Nn(xa&$sw2k{4zUM4p z4#{I2V(!k16A+BZb#OuP&gZWTO%?p+8_0LIMqoJt(iK^wP|H`IE~rQg8x~}5v_QE| zD*m%ie(V#(A0Og>Z@c}$C~-~L6N8?=&r#|O=^vn`a1vheXzTQ;CLn)B>|^=iACg|d zFQv#>6cFh77cmKBl_6jk&Mj^hF*p#A8uI^%t_#b*BD1QD{gM#U-!|7I z0hC1y5PJGMAm8o)F4bQZ^N^y_)e&jCoU=4q$F~sPxkJDsnFgSgNRS;*;ao(-=D8H~ zYQc&+bhU3!)9;_7tj&M_UQKBLz3n3q1@=7M;2SQ?pxKo&O(ggbrLrMnuTsh|dL(xX zXt294fhn)R{7yo!va9gj@uAOR&{z?gs@h61=5(nBu2&;5X>rnksv8&b5VumJ!YFUU z&N0(NhucU}H74Dxj4+JW@M(%kX&L*rC6N5=v2c;q3xoT{#|U##qDH3snvnRR7r8A($TFMXIgK>tX2)kV$wNG-H7*O z)v~f)2HCBUVRV_&rBOMz+Pj-}%7x56G$Tu)?AojZl~4o}X&3jP!plrDZOX;{Q9LN5 zY9GQA+1NT~FoyHx@S=?~?ryn+JDMXgJC38ODuW|$eNR;0bkG61H0vwI6ORo;fJ5)S zapP>+jPS|#cnX)AsN?7=Y{Pqe26cq@; z9m>k4{K619k6mCAf9+QgxbjIhj zv`42AnTjHFz`aQQs|hCKo6+>CxM%-QC9qV+JS6@jODXub-506!6zq9tLR5ITM<#?PJUKA&^TEqcn5RBa@w*-<_k4#_5ttf2BjdXnL*YC6-Rze$ zeCGRn4-P%|p%h~gbuY#@SIziv&&TSM8D8)408;%yYtM}NSp&&GVxE!(*-5h~V6Wwae_UM9!`f29K;(YWm1QSGl^K(T>|m+_g1wrDnq!yqU|rdQ+*{RVnlZQztKnfkr!d?LGui{=Lw=N zY!lvU0&*s+4!afv@~PmmtGMO-vPwW&I+i$A_bS>lxXajd39O*;lHpiQH{YsPI%}F` z`8g;@hrI%4C*{gF=RABx$%LVtpnCG;$WU7f9?&S;p|Rjn3|RQ)j&FgdzKHlEslH-z zS@fx=H&*>LE}c{(|JeGOg25R^)yWIUHHHsyXWlvP@*^*P)wW>>mNmK+V}td`{A`#Y zmtV+#!7G0+Tao4Xm2Jied^%SV8TehLhf5NM;{9Hb#L^s2LzgS+WTmipjwO#>4z68o zH_X`CGn?!jba)(74T@q8#GUD;ffHF=>-!r-#AuH!&tcgo$55?z@oE2gK1zqTL56-e(IvnutTH=qJe z2XF_j>x;ZfH)+WWhahNsY={lN0iky%_nM9FUXPAj!1r;~=6xwM>78i|(L16>hMH*f z)W4W-9-aYr^r01rBx}CN*sOf0ZKgr|@vYGsRl-XyB&9CKv`=4%K6ah-fY%`N zF({}7Dlo+xP*Z;d#jahaHzC{vlg6BoH1|oWT7rNUOnD&v(i~MlBL91pY-yk_GqTbW zl0W&5?Z7h5u_z)IjZ~&j=AU=x3hTSi&I%IG9h0&k6>Q ze-O{|cY1d#bQA>IK4D>`?hkCVEltLHElZZxwSkt6^WcbG^1_huAErj4PI6D(b~ zfDeeAyW`>cWgK}D5Bd9K)kphQ;osyD*>J-(eAsdUpTU($La_D@l?~BFt)%+J2Q9`4 zgYimnxN7OJE|zK&s8egHN*Uy0G7^8=@*!g~3;eEmbmy7UBeps2{yB=<$RV2nWDyxf1!4epx0qJ5Wwf#!|H3M72MF1hUcuj2{p;#+ zta8+<6`#-3T8%U4KfyM?k^dah8pN#I`3=%b-*WU{uQG_=Hg|PRZiVdjB?>6H&uetL zD`0D&2b@xP+qIoxg{PFsFp_ z0fP1Gpz_YY-E>sjwqqlxADH6ib&p$iOmJq_^1)?n3N(CLIQfFf7XV;5r3GhrY3Wjh zhovf-9FZqyjpS^>#w2y?k1*;mvc%&p`)JY;Cgtt2FkQ20UXT%-Y@y13>M!>$YAfj( zx?@&G9AmJyZ^0Vr79s(1nHSdOfUDjb-IQU@mk7HcPC#l2j&*yP@t0D}8=R+VW1X@z-f4v?bOaD{;Z!!{J=U z&*@ak)`eL~kP)}RNBvakOq#7ko$IOAWS>T>h0bwiYm2Sc5`4mF;>xnvDt-vcGoJ6l zWsqmroX!%olVO)Pse>X0xJwH2Z%J~qulbk=05%B0-HXC~plsa!cY`?}9?#dVT5vCeb;)s%J zi?Y6u)pC)!nFw9~E-vE7v;xV4z1L(IFzEz}KLOzr52v+)@R){c-O_ce;2sFW--Wdcx5{+qZ=M@HO=5zAYr%k*mR&k8C+x-`E9t1myqRh? z1zy>8V6OT>%3mlX?}SOr(LU?q43T)JY%Ffrup$}yF5wKn{5*}oQGK6iGPbIi7=GPO zp{%|5Q9se0rkm-WL7H0udp95AYzT~AdmJ8rlPj2XLjNu&6L zqOH$8qb=}Smpbf04zQQSqOUGG13lX1O}4<=Wa9nkCdwwt zQgi^?=&B=Z^k6haimB?t?DOhq6}n*CWZ4b2UAUatAiK!u^{jr23yxnE26&9D`c<>< z$QEDde~~17XE$u6WTuD!Z`a*-+-IJVSRF4syvDRlXtTm2EGWXTYixpCup{+qYlCdJwn)szvUmZ z)%2|bvI*R73|)iWj&I$>uG7?GVqR${#n*1LS}r@6wpXb9G`A%eIOw=meUfdrliO`N zb0SxM*y%#U?vSE`Q3*Ig^esCCD^*1P>g7Jka zrwClG`_!Rte5{x=Z^dTC*Uv%aPlbJ&1;wGL9L<*87WvPgtP_O{%y_C;cAl#?ye7+yqL2vBuNo+q`r~?SCd#E> zNi?y}7o)2d9ea7LQL}i^9k&q|nayeTp2cxTf65e;M}4o}g)6da#fM*f!u*VQ1TT1! zYrS%rr58Ga=%4f{CW1G9>#@(-Jat<=&Oc-tW+XeBwQs4I#;bSg$YMT0&O>Ny=8x-Z6zAiKhx5mlceP}YN{rJyMey%VdmQ< zG00QmG_azI?WSmTOxmX1!ms&xkDWku9NObF;CsT>;J4#z0>c|M#>_zN_oD)RJ(dO- z@Yobbhy&%SkGBVOJhleZxNQb`A;g&`4RJic?r=O1?_dW8xcL|px?f(Y=3RHn%cYmn zuGO`fnm^sFjG+yYO314U5Sd%i$z{QFBhrCCmCs(xP|N)DF2lS7!y|hYTSsjQ^MO$? zKN^yLlXJ6kP}Cz2%2#HZwPV-N7*g6-2<+8hckbh~4x;A|VlW9@IiA5j`I2 zC#|>$1d(dn-I&`2^%K?r>Unru!V!4BcOF}&+~SF80g@fgP5Zs%oEYdS+OOxrTUXFV zU3F_XL6TYrrMVHaaf@{Ba{kq2yAiv|*YZedAhgyOgz@dQ&_%%;oCbn6+?>pi_5yPZ}2+K1PK^9LR4oMkO=H55@DQ1yES1Ye?0jj+(2#}Y5? zdQglm`*v_HBtx-FaVx|wn1p1_-mE3;ojW9lw zP4VZt1O%}1kH+xE%T31bPakUr4>0F-9-WUg+kjJg&?r2*RK75)TSXu^%+8tm^Gau@3O-jclpTK!O+2HY3a?48* z3=d}%nIie8tR8o&6)}`x4GbCv&DscfJu69tq*+WCyO#1`;PiLd(qi^wn00J6-|36We zWBY$kL$_zkEdAfp&;y__!l5Zc(g5^@MabP8J!_Me*5I}5Ay6M615gDbf_ESR7-qMu z7FBp*+uzc!Ik}lRth^>?XZ3f2K>GwW#{+>n=Co$}ZV*+?V@yB!t-Dphq#p-to!bbz1B;AE7qnsA@eg=3rq^_%qRwXSP#mgQ z48g>$bsK6;>j#$+Y(>vAE2Q$pyHy>Z{Pta3lE=Wpyy(Cl^N?iKNO8vCMCN{4(-?xO zFDqYCz4{ivVFDBPEjz&oaxQ71V^m^ohlr}DGTb{NBn&&w-au@G#-9*<)8dksD~r5kSzjP^>~tt5EpY!i42}Aq!_a)FejzGI2NX+k*vG`+PoA0qVjy#~ zCk|$YkwPzc6)X+1`%B!r}4cCoF;SKL=3#f48vxJTC8u6}d$i zS0|Yw{PRz-2U3IBkj9C;LcMWr#)l5CoffFe#x;lxY_u`llOf39MItci2BD4}0>!|w z#I%D)4ZnzZ0;xj#yMQp6&B@qqM=>zc)5;YKGYGyQK=b1P$2FtT^5zP~Kw=%HhY<{< zI1QF4Wi@udWystZGn#tA=E$W7lfX}EEo%;Pt_E?pxfV!uTgG++axHP>(??lt{N13# zS0d^Nt4&N6*P5@K{}e#-{DVZq|L-s~&wp6}a;`2$#x`cc_VzYrM*m|PI-ya1SO_lc z$9gF&WIhc;(<5*(P^8Ehm^omXdI0Eh{w67BNR61XR0=8ncR&J`2M_^_QF$s7?bL?F z&yU5F!5(2gkbL9a@L*jyM;L=R!z&n1>m&_55eCQ(Y;yLaasj_U7A)5qN1?nRTW4Qw z9*G`b1y%7RQ%mFIX%*Ag9$N0>LJioguuh4S8LLkJxpoyFb&Zs%?emi~MW}Rf6`d`E zeN~dL#;UpY$=NX>qeq3meKpA{>+tk~!ODa33Qa(CEfBs7c-c=TIg?@Bv})dDw`JuK z3Z)B5xV)&lA&VLPq$N_XzBA7)Q0@fpi1pIz#S3+iDFSpmHS8)$6fgX=m_2AlVp6LB zC`Guv<+rjITaFe2Gv6c2g<S3sTXRguR9H{-tr5pQB=gKL)XX6^apkj*I-q_myG=o);w+ z`6*_`7U2qvlEQo~@ifQf0lJGFOY6f~@x3_|{Q2=qTIu>>&lK>W3Z|n*EPQ zdIhf!97t2gKsxG_GRZ9PMKl=|61hq?vqid;)aXS|=CjEw6s>O6EY=ckmC;GD9vIKs zlr^(O9R{9!^4{js%Et$oI{71DCI5_7%68LUU}C@%Z%@d>PNOC;mt!=p`exEj+q=7|G3V*W3lg zq9AGuTLm)YTb7{2+5?Y{(xr+h(W1x%Mer@|mqJM$IvhLNxHlJf36sdfgzwG{W*orv z#Wh%Brinv+l|gS)6kw96Z%}f`lGAuhOSQMkZ$+B|fyGQ!BubPjiA!*K!-Na+-s0L- zTCHr_XgUj}(V+ytXAw1R1xI*C7IlW2KhnX18RDM5mU^22n%v76Vu^IZfcC1m@%7N7 zg|*8yys_0|oTN~l?bVJ@gc1R~t)UlPXos#Bp z&caDeVhgU(h|8Gm)uk1y@l-L|Sf4Ny?JV5b$g>?nFEWnF;hFk5yiU7%B7Z`#%u-fn zEN$y=L5_AR5Z%DMC5vq8HgSy5WX{pF3C~f+yuDK0B`g-7Wh_Z}TAufp|RY20J zHUvEV9S+7O^&1$g9bPPC({Yf#0T^nAfZTpM0+aLZoMW@fxN#mq)|o7zILtAW`x&Hq z9f8k!#=`A!HK#a?+1`rfnJ68+zfKi)6d(~FQ`$t!nuSuhDl;hcAR)inA#&6(nr`V+ zIhq?$L3(s^sYthMMi!%~yr1j6JrG?%`y6V-wiv>%y93N^N@?vmSOAT-8)g7WgmPn} zV=tgy^+5vzH=CczDT^30niVtU6(d=#WR&QbiEIByb7>z>^c<_qLpz3E3A*5R9-{)Z z!VSBSOW3NpXnz{jX*VRdZ+mOV78>gOf@$amKO=D!C2AP&AmWg-!rz;2c?a1p7PFcW z9mjoe59E_JquY?LO z9_E{8LWfMeAzh_&I8Ndg@<}d1xRI z@!-3YtMb(Z&+KB}#H78Du1v%VNm6b){DUk;LfMr2KkSSoH*u z{J-)BEg|*d==~R;6_?ZKG*y|e%a_zz^vb88Mg$pWR#N6Ka5gKK@LigzO0%{~I`xi1 zW_7TMi$%_EdPL5qr~{|#pU{0uXEltd{qyQqKX7&{pIRSpcyjB{a9#S8D7Hro=0Bpp z$aC#abzJ&V?U&xCc=l!ujCkzvn$xka5ccKIct03&@5=OZcgx&e{?hCfKlJk49eyfS zoqw_S8JyKWfeuJU(MX>`egNkZ9)`Q_(kD~I2_??P-xu@XgZcgqv;2?)yh=W0u*J(f zg|I0+wu?U5TYur_=9QB2_@}>J_QbzkeW4M~U$_cXI5WOoY|n+e_-Tvw1tVTPX&{HujFbtkeoz`W<}X$Yf5Trp=K7BcTJXG}k`Sou zk0hfN_42v+CF`%eWAgA1_RDT+(TY4Ecu1WYMA{M_8eDzhIxgCuyioW>S00aa!r#V3 zB|{ogFSRho@iyFKoZ&B*jS0Fit=Qs}v&x?)yaZ9{i9k~yi;uBZkLP4{bqR;zWO8Ow zkXhiP?MvxM(KH;Sw(7nWywAVemMx+#+1})I;6ctj$!|9NO-Ui1ZKQ^RFQSKzsF_W) zZCgk*nVaOD1$I$k`bnM(d{TDU$+?6WiXIxg>~gf6K+GH0u0Bsdaho67sAyL~r^Du= z3QzbGtaIE^5_eZD)2>8HE#=#!yQ(&Itn{Wk&uXJ*P)Ul^@+|aTFd(K<{;H<4A8(2u zc00~z1%ubj!sy>KaNE4-A8GoNdZfxC%xEt`Wk*e8Q4m|nG077EvuSzYVXNT|qQhk| z{Zx+BVc}DPyO!0fijR=9!yk#9p}pb+O`#D(FhR%>{y(W(> z1sYUd2$jm_%j5*@*iqzozYNdYMRH00(P9xz62LbXz?yS2WT+2Qs$7?hZ^P|_q+&*H zCYv4`y>>nPT5-u{)(fMxn*9ciIe$h>jiFQF{c3}04@H53Dvtr+KWRHE{wY1&Svk7ii5;$0DY63>#GNneD8FJO zxj_jni)Dr^550MxaF(djT3O}K$27KOWz3aUQDqo3)Z5X-!1(0x>N?Su+}YFfY-)Eq z!WB$|QCy3ur{##M=Vvaa?Lsfe_BSRcm`)A^+dzuNz9fURE|&^YWt4SRQItw`%8^7- z_A47t0}%p?fvCW@3O7tnin{zmHMu&8n&i4J=`2ClCAafOrtu`|=!?7R9bbCJk(b@# z7gBc&A&h~Rr)yZ2R?MN4efvrji?)ezjPhj^39t6~+5(E89dqbcHK@~} zX1Htli{c4N#tq{|A}x&fxq)#&f(-!~Z2|dyx2hBd6Zb|^>OWqsB&oY8hbol`k8biK zyN-d_Gm=E+trdw(N=7sA04`XDY&lkDC!Uh&;1n@cDOf;el2hWuRGL#F{RxTAq*z+Y z;wOw3NGtEYY54e*e<=Cl{Y~#s`uT3q&^KFYdJ_()*eCVYf{coo&~y3A;`4Ni-(&Q> zM?NsP7j=2M`Rfw(d`Z4}YWG(ism%5)d7h0zn>T0fk-M4q*BRui(!Lc z@AlQ(>k{BiNq!#);CI7xVs~%t$0+3chdAq~H@rfT0-c*FL+AFj+n|WruRVq_!SnaGYLnmGz!NYgT%W>? z6tgQSkhBZOZWUFqI#AWhIx{$3QnA!WU&57baXs|zQ4z^9d0*y=oPOPZgQ z+%u)Ngn!w~vwICvdrjzPk;7JQ1iXF>eQ9@tJm|L$(4qH!3?~xsEjT{sIoP>Cm%-o- z|5oDNMx4)_)A8EE8nf}NKhP85h$J!q)P(_n!(Xy6jB~SkjvPy1R`Zo$B|!A1ZGUSe zU_9h=ycH2{>Rx9(%v?!_eDn7^ed1cF?bLkU0+l6?s0B>gWG2`e#_?=I-VokCI@M#h zcO?jr^P5U3+f-DE9s-WV$@Fz;^JgWDhd1&at*BVJvLkS5F*{HgJqA@j2NHjA{ER>( z-x-K#9-9Y@6cM-Rgmt0CV>}83v<~;43=3P}4dK_dxxGTlpIjg{o*)wF-E@;V5k*~{ z7r_l%=mch0_;G?z<)@1YtxEJi(rzKOrjBp4Ikp`AGKGC3uPAst^s~x{>JkYLw?GkG<(!36oLRGnaVG=~ z?ry=|-DQA~K+ph#4(=qwK!D)xF2M=zE(5_Gf&>Tzhu|)`u>0-Z&EEa?AGkeLXKJeY z={~2Y`>lH4nfmR4pk0jtcqn)n-V5ES)w2_;wG^2|YZz})Qm64YYs;RLv zkT+O0eClv`%$A5OQgh20#TSN<|lVJAK#bb)o-4EVrPzszP zc@H)({>o{Kt;^wm8t+?5BjL3$wJJ(YoL^LKwI7*l(Z#n~ zud>31lEtjqWpN@cq~|0+M$;%b$1GTY)Z=5Rx|E;;)B7RoNB-B7XpLC7_8Bzc$px;}9Q6C`4)O!$4D(y)1ExqNx*VZ*s}7$i=K&wM z0s8wOhoE?Onb#lS1ZnD|jJi|~BG5ujv)D@@tC~lEWkJtFdK$Y>Gr0X_+~`!g@@mDz zs`b~wev_vh;iS8G>3Vjn2Z4O1v)QU`x9whnqgnX`u9)x>%{)|;A5c(Ww_DvmzF(5f zBau{skrZO4DB%;8keV)?@*Ccahw;UP#dgyPB_Ym0o!lZyo3}87?;omEh-K z0Sfnez1tkeAune?)Q6|3hjU%*lcDVnYo0BYvJo&+H zGVVTc11WSYr~B!z98(NAk_UxpN! znrK6HnjP@IY;20nm|4#!^>n61BMa~iqukz?-mW6bee);(`rXQ_G`bB-D13!&4Q@P_ zGAfK2$3dl+cNB-j)6O-)Q;q+eIoBPSBeAX0+FA^*+819MpaT{3r+8295^1QsTQ zxVkVR0rO@k?YT0umd@US>kTGv!vl|MW8uj@godX# zHxIUx{16(ZB!yM_GJV{)y~X(4DU%CM?1@q9Gj&HJm-FOQCxIoUl)^MTRLb~NyZo1f zA6B8WDM1H^-Mtic>>g^Wua-J9ET{|G`ougOqZ0eRP1>p4Yu2qIMPM`N^GT5*}YOJyE{Nn7(Bol776p_QD~Vr!|-0506LD9~^Eddr?#Angni7?)V86fPO% zO%Ho1a#fv<-;RaraRfCcE|(;T7ohvOL<{Tpbu%Y_4^$p~OAX;h)U|Ttd4JpAFT9Buhy57X2H^S+`RNVKK0m|@8{7&`5+9+hq4OREA!8EVF>Cf#Q zw8Q%3H-}&9MZN;|UMjs2@}*Pt_LJPOF{)ez0t@2|?A>POJX2k&nA9|LeZIyCbK@l! z@mps&i z`BONZOrWuhEbyJKKjCciDPVa+2@=#~ZMAneJ?P9T1UD}UQKe{WvfBZ?JK z(WXROpp%V+TrMbuo@A!&74W<$Gj1qO8Lcg;BY~Rm9#6(46aDBov`yVu3gGIpf!^9_ z(p(D9$1xTX79bv{>Q~RJzhXY5pI6}K?P?gP_FlcG8T}1^wt2Z^hmid$UIE@lBol_$ zt*epQood!>oh>}~-FmGk5f-8jq98#8x)*mRU6W9f%yUQY^Oo_X0rK+vz+;g$;~p~v z8cugRdkdmO4b{HkeKlKRcy%q<oB;@+&raIfwMbV#dKv$liNWQl>m8SSCk$ z+QV=dDLh_I$S0(4ir{08`upM{V(C1yplE`K(%oi+m@f0>5?3~Jh7(06jd>}UrI!*a zHMJKAr3)t>pDe;p8J`Kh3f)^c1zzllz&?4ZtJh-bc~~665}gevUaFy0p@}#@4kSt9 zm~vcr$>RBO2!ZoD1U}lw2X;7#S;Wd{17goyX*N;zZvUGIj$CmsX4)i9z4);#KSye8 zZ`*p!rzFE+=dEu#{wO`Y9KMVR2wPDQM&b78;+nh~3H8+<^T@*BqHA}*ZOdnvyUu0U z*r<&&esgNl*T~y1!aRu?o9%0c?RI*?{kt{eU$9#>_^1^bX(T#@gxY31elt@$&1vwJ z9ga>+FV3-;iOna!sD^fG@@_;3CVf)Jz}2%G)FeOmA1&N3BzIO_4OVVfmI573#gbgo znQMm9VJiji`1qOl$s1WVi21rG&Nvj}4Z+3p2GEd*G64lIKV-@k zps@sk*0@;mF<&ak23kRL(XsA?Fz5&?u5; za<9e`YDf{VxuZf0bA`07g<3Y*s8Y6Xv`nx-m^jc*!j-{WUAgx9> zW(Dm&3nk&Qlmmg`*;YO;+L!{^+V2@*`8NZn3{d+<&!SQB1)(Rp?=@bPs9Z?qy)Uv; z;U!tb4M5mCdFs&-Xtjq)rabFN&QPG|y1u_>$5NN3eRjoDp~dC?b&ETvxxvTvShtif zp%MsL;JKW$msB<&4?$`1kz?wgvM!u*@p98%_h$u+>>y1lzp+cM`y55%6vS@}aCcon z{W8_ewd8R-_;$ESHIjtPpUu5i`;8qCcWmfDyV=sU_rQ%gL|*7T(vlJbN0eM zuS)GREhN$>W+wN*ha#=vEJ@BkVwAH8KMWGAKq?M`;}uO3#!%+^v4Cc0A=+cw`0S3o z1qklRZO?QAE~H$YMf8f@A>HObfj_!g|n`o|p)L|`VW;~BidO<{oo%R~PMX8$Bxcm8bk@&qrCfy)+XKO{xZ&%1m{(($_OwFFG#!RfxF*>a@H9wY(f7>aBaY3^{`?6csCicVYvjIWGnY>rD05iRBhP zwG#y-b#~3Yky}Gg&;Q|lf2%D>JTv7g=EqdBHnsoOhvJjD2LCwJ>(znUi~1(+JNONT z+WzE+-{C;vmM|G)i&LLb#@2?xMCCZ1B@F(ev2G~nwz@>S*?JQ4Atjsz#@om-e7S2> zk>DG%fd!-aFwcgzK8!*I@1nh87t8wr6)!Dc-J%+Zgk_8>XoyOO3=tBNSfX1*-=@kQ zoxS@k!~VQ&K2ky&ps{l)+))3zO4v&U1KZzdJ4}v}2LC9G9&2GvAoT-r{zX#o2`i%Xp4y4Svj&Dg!+NQR~59JkQc zAz}{l9;f?mp*T#^ig4ES?UR6Yn^3{DAoJ*=9f(%|I%SGGVna!3Z%7int{80shF*yb z7gHnJodJ*Bmx2fdr%K`akfD0+k+;4JL30p4lfh`g^P904p)&Cc$;D{WeMDJRAZ?9e zludId0X1oT_ zaoe(}+uE+Deah)@l~;j4bsmEk3M+LDxDc;$XpfZ%hkQ3AUyn%-Ix4qSYBfVLV zRqa;bFPjItEVwTcoRd3kAmfqDKPAt1`rP9Cj#lsOGL^b8jpK4&V;;$cbT&TX^J+lh zk2=~a#?xjX9oUSeerN3fZNu{k7Tyj^*LXP%RN+(m4;Ngu-3`)vua6(KE?<=Ac{dma z*R%vg7*UT5YTpJW9L(zwFeU38Zyodpx<4;fJcQ96cyDH+k(#3`92EHiRYeb#9Qss6 zLnDqzb1a8aN$cCCplI@kfbGFMxD)-oS**)r%yBx9@|P=v7#BwD5D_C&G3(p28VK++e@LP)R!9JbhH*PU4-KIL2_&1I|1 z>`aLGSYGVMfnJ;A!#QDvQbhS_KGdOWFy!4Nz9>y`81rdB{B^!3F0@F*C3L+GP-U>A zjU2&*AxyEAhmlN|6*q-G*u#zcDI?HvRJIlEt7~V*t}assh)Hu`-QsDhq&5*%wV?`Z zt-YFLW?Nyt$YM^Xrw~N2icXuh`#WyM52Dex z7uD0(lCB89CyqFt8wtsK;13s@g#sN-QDb^Rl;$yZ^Bn}T3f5sQHJ4% z?a_M|`)U^lp5Pukq*xXqg;E~?d9moMaV2IxLJ(_#=|vL!+~>w`qa=Qv&C8LF25n@x z33>a?xV=v>WVPqs?x0L9Ev9Jd!aSV^@G%zD+$=jkIb^z#$rXQo`dUAZ--#9Xh7qNC zLiC=UDh~;G2q>n{MFakO$UHyA zJjp{9N;eO!shyBlK*1ktJ%R^L=)2r9%=(Kfvm;De*FdVB5r?WMP1mjxm;yM#K@KOY zm8RsQual#)+lK*YOyO82g}(Dh_ZS7ZcC}`*w;l>A_sPaxz1f}DnG~H?bKAi(=X<;E zaaEg&1s`LGfs9Z0#ESu$bt9e0@i>z+eaoT-aM7-1{*ci>Hv0w`}4&^WHA z-R7O}sL;L=ws3b$F(QnldPDM6P3C{PHQNzdVH;G5P)yi>rM>{Bs!EVFe89rVg@I|GO7H7Z=#^N15(uIO*6+$3|^f@bR zRW(5_N`#DbT>AOJn+7H9taZ2VWRZPMH^&!F`HT_L@cL)4bO9OR=yeb#1AgSK`J8jY z#duo$bpXvdyq>jhu1=SGM!VGuLKQRM)ZP}=fJ{xMmJ+G)G%KHE@sQO@!o*7}w!3hV zf$}ofL2M*eagiOcsvUv8wj4{v zj3AxUcJ0Y}7eYBS6%Ni5f z^``VeH6x_q9rL6rF@M1zu&7!boL#1=qmoIR!)L6e0B6*adc`2La|bNAh63ZOhFC4X zW%MCxBrbWtp05P?v#+>K{S3NmSRXgd;_j@TkN_KjNqXTk!gg2}1zjkDfwkY8BQq{W zfUBE>#r~yakJ_pxCJrwDr>=kPHo`xg{(rR`^5d}|1Xx}Ez3YA} zp_Q5KFC~1GbA7;nX{XH8j93K3Cm&1Jw{b+fR$MrXHTn*(vk$)1C zeRO=ZJjmI@`WI>0zk>gCo%xOW4aC*@$E(iY13UtM9oydnJcZepMAZI$K>v++9O6F- zrvDKC8R@@+e;?^T&^(Ctui&2p{`U}%$RE3X{04rv$KAfx`Oj?p9r^og`~l@bAb%kL zFe!hJ@<{!W__5V~x5vaDFaEdj{tfzdx0#R7V;lYz`KLDgGf&S0^4OIBM*Ny&>w);K XMKzQWksbqKJiM|WPJyZW`00ND^9+Ge diff --git a/app/misc/libs/drag-button-1.1.aar b/app/misc/libs/drag-button-1.1.aar new file mode 100644 index 0000000000000000000000000000000000000000..04ed325e3b0179ec4e43084e921fc0ce632a9b91 GIT binary patch literal 23037 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 literal 0 HcmV?d00001 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c99831e9..b16a64d7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,7 +3,6 @@ package="org.solovyev.android.calculator" android:installLocation="auto"> - diff --git a/app/src/main/java/org/solovyev/android/calculator/AndroidCalculatorKeyboard.java b/app/src/main/java/org/solovyev/android/calculator/AndroidCalculatorKeyboard.java deleted file mode 100644 index 943a6712..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/AndroidCalculatorKeyboard.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2013 serso aka se.solovyev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * Contact details - * - * Email: se.solovyev@gmail.com - * Site: http://se.solovyev.org - */ - -package org.solovyev.android.calculator; - -import android.app.Application; -import android.content.Context; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -/** - * User: serso - * Date: 11/18/12 - * Time: 6:05 PM - */ -public class AndroidCalculatorKeyboard implements CalculatorKeyboard { - - @Nonnull - private final CalculatorKeyboard calculatorKeyboard; - - @Nonnull - private final Context context; - - @android.support.annotation.Nullable - private org.solovyev.android.calculator.Vibrator vibrator; - - public AndroidCalculatorKeyboard(@Nonnull Application application, - @Nonnull CalculatorKeyboard calculatorKeyboard) { - this.context = application; - this.calculatorKeyboard = calculatorKeyboard; - } - - @Override - public boolean buttonPressed(@Nullable String text) { - App.getGa().onButtonPressed(text); - final boolean processed = calculatorKeyboard.buttonPressed(text); - if (processed) { - vibrate(); - } - return processed; - } - - private void vibrate() { - if (vibrator == null) { - vibrator = App.getVibrator(); - } - vibrator.vibrate(); - } - - @Override - public void roundBracketsButtonPressed() { - vibrate(); - calculatorKeyboard.roundBracketsButtonPressed(); - } - - @Override - public void pasteButtonPressed() { - vibrate(); - calculatorKeyboard.pasteButtonPressed(); - } - - @Override - public void clearButtonPressed() { - vibrate(); - calculatorKeyboard.clearButtonPressed(); - } - - @Override - public void copyButtonPressed() { - vibrate(); - calculatorKeyboard.copyButtonPressed(); - } - - @Override - public void moveCursorLeft() { - vibrate(); - calculatorKeyboard.moveCursorLeft(); - } - - @Override - public void moveCursorRight() { - vibrate(); - calculatorKeyboard.moveCursorRight(); - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/App.java b/app/src/main/java/org/solovyev/android/calculator/App.java index a641dda0..3a919368 100644 --- a/app/src/main/java/org/solovyev/android/calculator/App.java +++ b/app/src/main/java/org/solovyev/android/calculator/App.java @@ -103,8 +103,6 @@ public final class App { @Nullable private static Boolean lg = null; @Nonnull - private static volatile Vibrator vibrator; - @Nonnull private static volatile ScreenMetrics screenMetrics; private App() { @@ -150,7 +148,6 @@ public final class App { } }); App.broadcaster = new CalculatorBroadcaster(application, preferences); - App.vibrator = new Vibrator(application, preferences); App.screenMetrics = new ScreenMetrics(application); App.languages.init(App.preferences); @@ -273,11 +270,6 @@ public final class App { return isLg() && Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN; } - @Nonnull - public static Vibrator getVibrator() { - return vibrator; - } - @Nonnull public static ScreenMetrics getScreenMetrics() { return screenMetrics; diff --git a/app/src/main/java/org/solovyev/android/calculator/BaseUi.java b/app/src/main/java/org/solovyev/android/calculator/BaseUi.java index a3e929a2..bff45d9c 100644 --- a/app/src/main/java/org/solovyev/android/calculator/BaseUi.java +++ b/app/src/main/java/org/solovyev/android/calculator/BaseUi.java @@ -312,7 +312,6 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan @Override public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { if (dragDirection == DragDirection.down) { - App.getVibrator().vibrate(); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_operators, null); return true; } diff --git a/app/src/main/java/org/solovyev/android/calculator/ButtonOnClickListener.java b/app/src/main/java/org/solovyev/android/calculator/ButtonOnClickListener.java index 727f567b..8eb10505 100644 --- a/app/src/main/java/org/solovyev/android/calculator/ButtonOnClickListener.java +++ b/app/src/main/java/org/solovyev/android/calculator/ButtonOnClickListener.java @@ -1,6 +1,7 @@ package org.solovyev.android.calculator; import android.support.annotation.IdRes; +import android.view.HapticFeedbackConstants; import android.view.View; import android.widget.Button; @@ -31,47 +32,49 @@ final class ButtonOnClickListener implements View.OnClickListener { case R.id.cpp_button_plus: case R.id.cpp_button_right: case R.id.cpp_button_round_brackets: - onClick(((Button) v).getText().toString()); + onClick(v, ((Button) v).getText().toString()); break; case R.id.cpp_button_clear: - onClick(CalculatorSpecialButton.clear); + onClick(v, CalculatorSpecialButton.clear); break; case R.id.cpp_button_functions: - onClick(CalculatorSpecialButton.functions); + onClick(v, CalculatorSpecialButton.functions); break; case R.id.cpp_button_history: - onClick(CalculatorSpecialButton.history); + onClick(v, CalculatorSpecialButton.history); break; case R.id.cpp_button_erase: - onClick(CalculatorSpecialButton.erase); + onClick(v, CalculatorSpecialButton.erase); break; case R.id.cpp_button_paste: - onClick(CalculatorSpecialButton.paste); + onClick(v, CalculatorSpecialButton.paste); break; case R.id.cpp_button_copy: - onClick(CalculatorSpecialButton.copy); + onClick(v, CalculatorSpecialButton.copy); break; case R.id.cpp_button_like: - onClick(CalculatorSpecialButton.like); + onClick(v, CalculatorSpecialButton.like); break; case R.id.cpp_button_operators: - onClick(CalculatorSpecialButton.operators); + onClick(v, CalculatorSpecialButton.operators); break; case R.id.cpp_button_vars: - onClick(CalculatorSpecialButton.vars); + onClick(v, CalculatorSpecialButton.vars); break; case R.id.cpp_button_equals: - onClick(CalculatorSpecialButton.equals); + onClick(v, CalculatorSpecialButton.equals); break; } } - private void onClick(@Nonnull CalculatorSpecialButton b) { - onClick(b.getActionCode()); + private void onClick(@Nonnull View v, @Nonnull CalculatorSpecialButton b) { + onClick(v, b.getActionCode()); } - private void onClick(@Nonnull String s) { - Locator.getInstance().getKeyboard().buttonPressed(s); + private void onClick(@Nonnull View v, @Nonnull String s) { + if (Locator.getInstance().getKeyboard().buttonPressed(s)) { + v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); + } } public void attachToViews(@Nonnull ViewsCache views) { diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java index 0f632e84..551908f1 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java @@ -171,7 +171,7 @@ public class CalculatorApplication extends android.app.Application implements Sh new AndroidCalculatorHistory(this, calculator), new AndroidCalculatorLogger(), new AndroidCalculatorPreferenceService(this), - new AndroidCalculatorKeyboard(this, new CalculatorKeyboardImpl()), + new CalculatorKeyboard(), new AndroidCalculatorPlotter(this, new CalculatorPlotterImpl(calculator)), editorTextProcessor); diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorButton.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorButton.java index 87f54188..bc9e1af8 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorButton.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorButton.java @@ -138,14 +138,15 @@ public enum CalculatorButton { } } - public void onLongClick() { + public boolean onLongClick() { if (onLongClickText != null) { - Locator.getInstance().getKeyboard().buttonPressed(onLongClickText); + return Locator.getInstance().getKeyboard().buttonPressed(onLongClickText); } + return false; } - public void onClick() { - Locator.getInstance().getKeyboard().buttonPressed(onClickText); + public boolean onClick() { + return Locator.getInstance().getKeyboard().buttonPressed(onClickText); } public int getButtonId() { diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java index 73783e1e..c67e39f4 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java @@ -33,8 +33,7 @@ import android.util.TypedValue; import android.view.MotionEvent; import android.view.View; import android.widget.Button; -import jscl.AngleUnit; -import jscl.NumeralBase; + import org.solovyev.android.Views; import org.solovyev.android.calculator.model.AndroidCalculatorEngine; import org.solovyev.android.calculator.view.AngleUnitsButton; @@ -47,6 +46,9 @@ import org.solovyev.android.views.dragbutton.SimpleDragListener; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import jscl.AngleUnit; +import jscl.NumeralBase; + public final class CalculatorButtons { private CalculatorButtons() { @@ -115,18 +117,13 @@ public final class CalculatorButtons { private final DigitButtonDragProcessor upDownProcessor = new DigitButtonDragProcessor(getKeyboard()); @Override - public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { - final boolean result; - - if (dragDirection == DragDirection.left) { - App.getVibrator().vibrate(); + public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { + if (direction == DragDirection.left) { getKeyboard().roundBracketsButtonPressed(); - result = true; - } else { - result = upDownProcessor.processDragEvent(dragDirection, dragButton, startPoint, motionEvent); + return true; } - return result; + return upDownProcessor.processDragEvent(direction, button, startPoint, motionEvent); } } @@ -144,18 +141,12 @@ public final class CalculatorButtons { @Nonnull DragButton dragButton, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { - boolean result = false; - if (dragDirection == DragDirection.up) { - App.getVibrator().vibrate(); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_create_var_dialog, null, context); - result = true; - }/* else if (dragDirection == DragDirection.down) { - Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_create_matrix_dialog, null, context); - result = true; - }*/ + return true; + } - return result; + return false; } } @@ -177,8 +168,6 @@ public final class CalculatorButtons { @Nonnull DragButton dragButton, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { - boolean result = false; - if (dragButton instanceof AngleUnitsButton) { if (dragDirection != DragDirection.left) { final String directionText = ((AngleUnitsButton) dragButton).getText(dragDirection); @@ -191,21 +180,19 @@ public final class CalculatorButtons { final AngleUnit oldAngleUnits = AndroidCalculatorEngine.Preferences.angleUnit.getPreference(preferences); if (oldAngleUnits != angleUnits) { - App.getVibrator().vibrate(); Locator.getInstance().getPreferenceService().setAngleUnits(angleUnits); } - - result = true; } catch (IllegalArgumentException e) { Log.d(this.getClass().getName(), "Unsupported angle units: " + directionText); } + return true; } } else if (dragDirection == DragDirection.left) { - result = processor.processDragEvent(dragDirection, dragButton, startPoint, motionEvent); + return processor.processDragEvent(dragDirection, dragButton, startPoint, motionEvent); } } - return result; + return false; } } @@ -223,31 +210,26 @@ public final class CalculatorButtons { @Nonnull DragButton dragButton, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { - boolean result = false; - if (dragButton instanceof NumeralBasesButton) { final String directionText = ((NumeralBasesButton) dragButton).getText(dragDirection); if (directionText != null) { try { - final NumeralBase numeralBase = NumeralBase.valueOf(directionText); final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); final NumeralBase oldNumeralBase = AndroidCalculatorEngine.Preferences.numeralBase.getPreference(preferences); if (oldNumeralBase != numeralBase) { - App.getVibrator().vibrate(); Locator.getInstance().getPreferenceService().setNumeralBase(numeralBase); } - - result = true; } catch (IllegalArgumentException e) { Log.d(this.getClass().getName(), "Unsupported numeral base: " + directionText); } + return true; } } - return result; + return false; } } @@ -265,15 +247,11 @@ public final class CalculatorButtons { @Nonnull DragButton dragButton, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { - boolean result = false; - if (dragDirection == DragDirection.up) { - App.getVibrator().vibrate(); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_create_function_dialog, null, context); - result = true; + return true; } - - return result; + return false; } } } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboard.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboard.java index 45fc7a1f..11538532 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboard.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboard.java @@ -22,26 +22,115 @@ package org.solovyev.android.calculator; +import org.solovyev.android.calculator.math.MathType; +import org.solovyev.common.text.Strings; + +import javax.annotation.Nonnull; import javax.annotation.Nullable; -/** - * User: serso - * Date: 9/22/12 - * Time: 1:08 PM - */ -public interface CalculatorKeyboard { +public class CalculatorKeyboard { - boolean buttonPressed(@Nullable String text); + public boolean buttonPressed(@Nullable final String text) { + App.getGa().onButtonPressed(text); + if (!Strings.isEmpty(text)) { + // process special buttons + boolean processed = processSpecialButtons(text); - void roundBracketsButtonPressed(); + if (!processed) { + processText(prepareText(text)); + } + return true; + } + return false; + } - void pasteButtonPressed(); + private void processText(@Nonnull String text) { + int cursorPositionOffset = 0; + final StringBuilder textToBeInserted = new StringBuilder(text); - void clearButtonPressed(); + final MathType.Result mathType = MathType.getType(text, 0, false); + switch (mathType.type) { + case function: + textToBeInserted.append("()"); + cursorPositionOffset = -1; + break; + case operator: + textToBeInserted.append("()"); + cursorPositionOffset = -1; + break; + case comma: + textToBeInserted.append(" "); + break; + } - void copyButtonPressed(); + if (cursorPositionOffset == 0) { + if (MathType.groupSymbols.contains(text)) { + cursorPositionOffset = -1; + } + } - void moveCursorLeft(); + final Editor editor = Locator.getInstance().getEditor(); + editor.insert(textToBeInserted.toString(), cursorPositionOffset); + } - void moveCursorRight(); + @Nonnull + private String prepareText(@Nonnull String text) { + if ("( )".equals(text) || "( )".equals(text)) { + return "()"; + } else { + return text; + } + } + + private boolean processSpecialButtons(@Nonnull String text) { + boolean result = false; + + final CalculatorSpecialButton button = CalculatorSpecialButton.getByActionCode(text); + if (button != null) { + button.onClick(this); + result = true; + } + + return result; + } + + public void roundBracketsButtonPressed() { + final Editor editor = Locator.getInstance().getEditor(); + EditorState viewState = editor.getState(); + + final int cursorPosition = viewState.selection; + final CharSequence oldText = viewState.text; + + editor.setText("(" + oldText.subSequence(0, cursorPosition) + ")" + oldText.subSequence(cursorPosition, oldText.length()), cursorPosition + 2); + } + + public void pasteButtonPressed() { + final String text = Locator.getInstance().getClipboard().getText(); + if (text != null) { + Locator.getInstance().getEditor().insert(text); + } + } + + public void clearButtonPressed() { + Locator.getInstance().getEditor().clear(); + } + + public void copyButtonPressed() { + final DisplayState displayViewState = Locator.getInstance().getDisplay().getViewState(); + if (displayViewState.isValid()) { + final CharSequence text = displayViewState.getText(); + if (!Strings.isEmpty(text)) { + Locator.getInstance().getClipboard().setText(text); + Locator.getInstance().getNotifier().showMessage(CalculatorMessage.newInfoMessage(CalculatorMessages.result_copied)); + } + } + } + + public void moveCursorLeft() { + Locator.getInstance().getEditor().moveCursorLeft(); + } + + public void moveCursorRight() { + Locator.getInstance().getEditor().moveCursorRight(); + } } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboardImpl.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboardImpl.java deleted file mode 100644 index 4271660b..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboardImpl.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2013 serso aka se.solovyev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * Contact details - * - * Email: se.solovyev@gmail.com - * Site: http://se.solovyev.org - */ - -package org.solovyev.android.calculator; - -import org.solovyev.android.calculator.math.MathType; -import org.solovyev.common.text.Strings; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public class CalculatorKeyboardImpl implements CalculatorKeyboard { - - @Override - public boolean buttonPressed(@Nullable final String text) { - if (!Strings.isEmpty(text)) { - // process special buttons - boolean processed = processSpecialButtons(text); - - if (!processed) { - processText(prepareText(text)); - } - return true; - } - return false; - } - - private void processText(@Nonnull String text) { - int cursorPositionOffset = 0; - final StringBuilder textToBeInserted = new StringBuilder(text); - - final MathType.Result mathType = MathType.getType(text, 0, false); - switch (mathType.type) { - case function: - textToBeInserted.append("()"); - cursorPositionOffset = -1; - break; - case operator: - textToBeInserted.append("()"); - cursorPositionOffset = -1; - break; - case comma: - textToBeInserted.append(" "); - break; - } - - if (cursorPositionOffset == 0) { - if (MathType.groupSymbols.contains(text)) { - cursorPositionOffset = -1; - } - } - - final Editor editor = Locator.getInstance().getEditor(); - editor.insert(textToBeInserted.toString(), cursorPositionOffset); - } - - @Nonnull - private String prepareText(@Nonnull String text) { - if ("( )".equals(text) || "( )".equals(text)) { - return "()"; - } else { - return text; - } - } - - private boolean processSpecialButtons(@Nonnull String text) { - boolean result = false; - - final CalculatorSpecialButton button = CalculatorSpecialButton.getByActionCode(text); - if (button != null) { - button.onClick(this); - result = true; - } - - return result; - } - - @Override - public void roundBracketsButtonPressed() { - final Editor editor = Locator.getInstance().getEditor(); - EditorState viewState = editor.getState(); - - final int cursorPosition = viewState.selection; - final CharSequence oldText = viewState.text; - - editor.setText("(" + oldText.subSequence(0, cursorPosition) + ")" + oldText.subSequence(cursorPosition, oldText.length()), cursorPosition + 2); - } - - @Override - public void pasteButtonPressed() { - final String text = Locator.getInstance().getClipboard().getText(); - if (text != null) { - Locator.getInstance().getEditor().insert(text); - } - } - - @Override - public void clearButtonPressed() { - Locator.getInstance().getEditor().clear(); - } - - @Override - public void copyButtonPressed() { - final DisplayState displayViewState = Locator.getInstance().getDisplay().getViewState(); - if (displayViewState.isValid()) { - final CharSequence text = displayViewState.getText(); - if (!Strings.isEmpty(text)) { - Locator.getInstance().getClipboard().setText(text); - Locator.getInstance().getNotifier().showMessage(CalculatorMessage.newInfoMessage(CalculatorMessages.result_copied)); - } - } - } - - @Override - public void moveCursorLeft() { - Locator.getInstance().getEditor().moveCursorLeft(); - } - - @Override - public void moveCursorRight() { - Locator.getInstance().getEditor().moveCursorRight(); - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java b/app/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java index 36675f24..0b495efc 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java +++ b/app/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java @@ -24,6 +24,7 @@ package org.solovyev.android.calculator; import android.graphics.PointF; import android.view.MotionEvent; + import org.solovyev.android.views.dragbutton.DirectionDragButton; import org.solovyev.android.views.dragbutton.DragButton; import org.solovyev.android.views.dragbutton.DragDirection; @@ -31,33 +32,21 @@ import org.solovyev.android.views.dragbutton.SimpleDragListener; import javax.annotation.Nonnull; -/** - * User: serso - * Date: 9/16/11 - * Time: 11:45 PM - */ public class CursorDragProcessor implements SimpleDragListener.DragProcessor { - public CursorDragProcessor() { - } - @Override public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { - boolean result = false; - if (dragButton instanceof DirectionDragButton) { - String text = ((DirectionDragButton) dragButton).getText(dragDirection); + final String text = ((DirectionDragButton) dragButton).getText(dragDirection); if ("◁◁".equals(text)) { - App.getVibrator().vibrate(); Locator.getInstance().getEditor().setCursorOnStart(); - result = true; + return true; } else if ("▷▷".equals(text)) { - App.getVibrator().vibrate(); Locator.getInstance().getEditor().setCursorOnEnd(); - result = true; + return true; } } - return result; + return false; } } diff --git a/app/src/main/java/org/solovyev/android/calculator/DigitButtonDragProcessor.java b/app/src/main/java/org/solovyev/android/calculator/DigitButtonDragProcessor.java index d57caf6e..8bfafce1 100644 --- a/app/src/main/java/org/solovyev/android/calculator/DigitButtonDragProcessor.java +++ b/app/src/main/java/org/solovyev/android/calculator/DigitButtonDragProcessor.java @@ -31,11 +31,6 @@ import org.solovyev.android.views.dragbutton.SimpleDragListener; import javax.annotation.Nonnull; -/** - * User: serso - * Date: 9/16/11 - * Time: 11:48 PM - */ public class DigitButtonDragProcessor implements SimpleDragListener.DragProcessor { @Nonnull @@ -46,11 +41,8 @@ public class DigitButtonDragProcessor implements SimpleDragListener.DragProcesso } @Override - public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { - if (!(dragButton instanceof DirectionDragButton)) throw new AssertionError(); - final String text = ((DirectionDragButton) dragButton).getText(dragDirection); - calculatorKeyboard.buttonPressed(text); - return true; + public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { + final String text = ((DirectionDragButton) button).getText(direction); + return calculatorKeyboard.buttonPressed(text); } - } diff --git a/app/src/main/java/org/solovyev/android/calculator/EqualsDragProcessor.java b/app/src/main/java/org/solovyev/android/calculator/EqualsDragProcessor.java index 61c84ffb..435857d7 100644 --- a/app/src/main/java/org/solovyev/android/calculator/EqualsDragProcessor.java +++ b/app/src/main/java/org/solovyev/android/calculator/EqualsDragProcessor.java @@ -24,6 +24,7 @@ package org.solovyev.android.calculator; import android.graphics.PointF; import android.view.MotionEvent; + import org.solovyev.android.views.dragbutton.DirectionDragButton; import org.solovyev.android.views.dragbutton.DragButton; import org.solovyev.android.views.dragbutton.DragDirection; @@ -31,35 +32,21 @@ import org.solovyev.android.views.dragbutton.SimpleDragListener; import javax.annotation.Nonnull; -/** - * User: serso - * Date: 10/24/11 - * Time: 9:52 PM - */ public class EqualsDragProcessor implements SimpleDragListener.DragProcessor { - public EqualsDragProcessor() { - } - @Override - public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { - boolean result = false; - - if (dragButton instanceof DirectionDragButton) { - if (dragDirection == DragDirection.down) { - App.getVibrator().vibrate(); - CalculatorActivityLauncher.tryPlot(); - result = true; - } else { - final String text = ((DirectionDragButton) dragButton).getText(dragDirection); - if ("≡".equals(text)) { - App.getVibrator().vibrate(); - Locator.getInstance().getCalculator().simplify(); - result = true; - } + public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { + if (direction == DragDirection.down) { + CalculatorActivityLauncher.tryPlot(); + return true; + } else if (button instanceof DirectionDragButton) { + final String text = ((DirectionDragButton) button).getText(direction); + if ("≡".equals(text)) { + Locator.getInstance().getCalculator().simplify(); + return true; } } - return result; + return false; } } diff --git a/app/src/main/java/org/solovyev/android/calculator/Preferences.java b/app/src/main/java/org/solovyev/android/calculator/Preferences.java index 2024b568..5536ad4c 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Preferences.java +++ b/app/src/main/java/org/solovyev/android/calculator/Preferences.java @@ -31,23 +31,31 @@ import android.support.annotation.LayoutRes; import android.support.annotation.StyleRes; import android.util.SparseArray; import android.view.ContextThemeWrapper; -import jscl.AngleUnit; -import jscl.NumeralBase; + import org.solovyev.android.Check; import org.solovyev.android.calculator.language.Languages; import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.model.AndroidCalculatorEngine; import org.solovyev.android.calculator.preferences.PurchaseDialogActivity; import org.solovyev.android.calculator.wizard.WizardActivity; -import org.solovyev.android.prefs.*; +import org.solovyev.android.prefs.BooleanPreference; +import org.solovyev.android.prefs.IntegerPreference; +import org.solovyev.android.prefs.LongPreference; +import org.solovyev.android.prefs.NumberToStringPreference; +import org.solovyev.android.prefs.Preference; +import org.solovyev.android.prefs.StringPreference; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.text.DecimalFormatSymbols; import java.util.EnumMap; import java.util.Locale; import java.util.Map; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import jscl.AngleUnit; +import jscl.NumeralBase; + import static org.solovyev.android.Android.isPhoneModel; import static org.solovyev.android.DeviceModel.samsung_galaxy_s; import static org.solovyev.android.DeviceModel.samsung_galaxy_s_2; @@ -126,18 +134,6 @@ public final class Preferences { // renew value after each application start Calculations.showCalculationMessagesDialog.putDefault(preferences); Calculations.lastPreferredPreferencesCheck.putDefault(preferences); - - if (!Gui.hapticFeedback.isSet(preferences)) { - final Preference hfEnabled = Gui.hapticFeedbackEnabled; - final boolean enabled = !hfEnabled.isSet(preferences) ? true : hfEnabled.getPreference(preferences); - if (enabled) { - final Preference hfDuration = Gui.hapticFeedbackDuration; - final long duration = !hfDuration.isSet(preferences) ? 60L : hfDuration.getPreference(preferences); - Gui.hapticFeedback.putPreference(preferences, duration); - } else { - Gui.hapticFeedback.putPreference(preferences, 0L); - } - } } private static void applyDefaultPreference(@Nonnull SharedPreferences preferences, @Nonnull Preference preference) { @@ -281,9 +277,6 @@ public final class Preferences { public static final Preference colorDisplay = BooleanPreference.of("org.solovyev.android.calculator.CalculatorModel_color_display", true); public static final Preference hapticFeedback = NumberToStringPreference.of("hapticFeedback", 60L, Long.class); - private static final Preference hapticFeedbackEnabled = BooleanPreference.of("org.solovyev.android.calculator.CalculatorModel_haptic_feedback", false); - private static final Preference hapticFeedbackDuration = NumberToStringPreference.of("org.solovyev.android.calculator.CalculatorActivity_calc_haptic_feedback_duration_key", 60L, Long.class); - @Nonnull public static Theme getTheme(@Nonnull SharedPreferences preferences) { return theme.getPreferenceNoError(preferences); diff --git a/app/src/main/java/org/solovyev/android/calculator/Vibrator.java b/app/src/main/java/org/solovyev/android/calculator/Vibrator.java deleted file mode 100644 index 8ae957d3..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/Vibrator.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.solovyev.android.calculator; - -import android.content.Context; -import android.content.SharedPreferences; -import android.util.Log; - -import javax.annotation.Nonnull; - -public final class Vibrator implements SharedPreferences.OnSharedPreferenceChangeListener { - - @Nonnull - private final android.os.Vibrator service; - - private long time = 0; - - public Vibrator(@Nonnull Context context, @Nonnull SharedPreferences preferences) { - service = (android.os.Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); - preferences.registerOnSharedPreferenceChangeListener(this); - updateTime(preferences); - } - - private void updateTime(@Nonnull SharedPreferences preferences) { - time = Preferences.Gui.hapticFeedback.getPreference(preferences) / 2; - } - - public void vibrate() { - try { - if (time > 0) { - service.vibrate(time); - } - } catch (SecurityException e) { - Log.e("Vibrator", e.getMessage(), e); - } - } - - @Override - public void onSharedPreferenceChanged(@Nonnull SharedPreferences preferences, String key) { - if (Preferences.Gui.hapticFeedback.isSameKey(key)) { - updateTime(preferences); - } - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java b/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java index d1513d99..99018e25 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java @@ -44,7 +44,6 @@ import android.widget.ListView; import com.melnykov.fab.FloatingActionButton; -import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.CalculatorApplication; import org.solovyev.android.calculator.CalculatorEventData; import org.solovyev.android.calculator.CalculatorEventListener; @@ -105,13 +104,6 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul @Nonnull private static final String TAG = "CalculatorHistoryFragment"; - /* - ********************************************************************** - * - * FIELDS - * - ********************************************************************** - */ private final ActivityMenu menu = ListActivityMenu.fromResource(R.menu.history_menu, HistoryMenu.class, AndroidMenuHelper.getInstance(), new HistoryMenuFilter()); @Nonnull private final SharedPreferences.OnSharedPreferenceChangeListener preferencesListener = new HistoryOnPreferenceChangeListener(); @@ -160,9 +152,8 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul return result; } - public static void useHistoryItem(@Nonnull final HistoryState historyState) { - App.getVibrator().vibrate(); - Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.use_history_state, historyState); + public static void useHistoryItem(@Nonnull final HistoryState state) { + Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.use_history_state, state); } @Nonnull diff --git a/app/src/main/java/org/solovyev/android/calculator/history/HistoryDragProcessor.java b/app/src/main/java/org/solovyev/android/calculator/history/HistoryDragProcessor.java index 9b3f5400..d4f20db1 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/HistoryDragProcessor.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/HistoryDragProcessor.java @@ -23,9 +23,8 @@ package org.solovyev.android.calculator.history; import android.graphics.PointF; -import android.util.Log; import android.view.MotionEvent; -import org.solovyev.android.calculator.App; + import org.solovyev.android.views.dragbutton.DragButton; import org.solovyev.android.views.dragbutton.DragDirection; import org.solovyev.android.views.dragbutton.SimpleDragListener; @@ -33,12 +32,8 @@ import org.solovyev.common.history.HistoryAction; import org.solovyev.common.history.HistoryControl; import javax.annotation.Nonnull; +import javax.annotation.Nullable; -/** - * User: serso - * Date: 9/16/11 - * Time: 11:36 PM - */ public class HistoryDragProcessor implements SimpleDragListener.DragProcessor { @Nonnull @@ -49,26 +44,22 @@ public class HistoryDragProcessor implements SimpleDragListener.DragProcessor } @Override - public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { - boolean result = false; - - Log.d(String.valueOf(dragButton.getId()), "History on drag event start: " + dragDirection); - - final HistoryAction historyAction; - if (dragDirection == DragDirection.up) { - historyAction = HistoryAction.undo; - } else if (dragDirection == DragDirection.down) { - historyAction = HistoryAction.redo; - } else { - historyAction = null; + public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { + final HistoryAction action = getActionFromDirection(direction); + if (action != null) { + historyControl.doHistoryAction(action); + return true; } + return false; + } - if (historyAction != null) { - App.getVibrator().vibrate(); - result = true; - historyControl.doHistoryAction(historyAction); + @Nullable + private HistoryAction getActionFromDirection(@Nonnull DragDirection direction) { + if (direction == DragDirection.up) { + return HistoryAction.undo; + } else if (direction == DragDirection.down) { + return HistoryAction.redo; } - - return result; + return null; } } diff --git a/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenView.java b/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenView.java index 1ee4d1f2..cd7652db 100644 --- a/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenView.java +++ b/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenView.java @@ -31,16 +31,26 @@ import android.preference.PreferenceManager; import android.util.DisplayMetrics; import android.util.Log; import android.view.Gravity; +import android.view.HapticFeedbackConstants; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; -import org.solovyev.android.calculator.*; + +import org.solovyev.android.calculator.AndroidCalculatorDisplayView; +import org.solovyev.android.calculator.App; +import org.solovyev.android.calculator.CalculatorButton; +import org.solovyev.android.calculator.DisplayState; +import org.solovyev.android.calculator.EditorState; +import org.solovyev.android.calculator.EditorView; +import org.solovyev.android.calculator.Preferences; +import org.solovyev.android.calculator.R; import org.solovyev.android.prefs.Preference; +import java.util.Locale; + import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.Locale; /** * User: serso @@ -217,7 +227,9 @@ public class CalculatorOnscreenView { button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - widgetButton.onClick(); + if (widgetButton.onClick()) { + v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); + } if (widgetButton == CalculatorButton.app) { minimize(); } @@ -226,7 +238,9 @@ public class CalculatorOnscreenView { button.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { - widgetButton.onLongClick(); + if (widgetButton.onLongClick()) { + v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); + } return true; } }); @@ -250,7 +264,6 @@ public class CalculatorOnscreenView { onscreenFoldButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - App.getVibrator().vibrate(); if (folded) { unfold(); } else { @@ -263,7 +276,6 @@ public class CalculatorOnscreenView { onscreenHideButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - App.getVibrator().vibrate(); minimize(); } }); @@ -271,7 +283,6 @@ public class CalculatorOnscreenView { root.findViewById(R.id.onscreen_close_button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - App.getVibrator().vibrate(); hide(); } }); diff --git a/app/src/main/java/org/solovyev/android/calculator/view/LongClickEraser.java b/app/src/main/java/org/solovyev/android/calculator/view/LongClickEraser.java index 6a45b836..75f781f8 100644 --- a/app/src/main/java/org/solovyev/android/calculator/view/LongClickEraser.java +++ b/app/src/main/java/org/solovyev/android/calculator/view/LongClickEraser.java @@ -1,6 +1,7 @@ package org.solovyev.android.calculator.view; import android.view.GestureDetector; +import android.view.HapticFeedbackConstants; import android.view.MotionEvent; import android.view.View; @@ -42,7 +43,8 @@ public final class LongClickEraser implements View.OnTouchListener { } public static void createAndAttach(@Nonnull View view) { - view.setOnTouchListener(new LongClickEraser(view)); + final LongClickEraser l = new LongClickEraser(view); + view.setOnTouchListener(l); } @Override @@ -61,11 +63,11 @@ public final class LongClickEraser implements View.OnTouchListener { } private class Eraser implements Runnable { - private static final int DELAY = 500; + private static final int DELAY = 300; private long delay; - private boolean wasCalculatingOnFly; private boolean erasing; private boolean tracking = true; + private boolean wasCalculatingOnFly; @Override public void run() { @@ -84,12 +86,13 @@ public final class LongClickEraser implements View.OnTouchListener { } erasing = true; delay = DELAY; + view.removeCallbacks(this); + view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); wasCalculatingOnFly = calculator.isCalculateOnFly(); if (wasCalculatingOnFly) { calculator.setCalculateOnFly(false); } - view.removeCallbacks(this); - view.post(this); + run(); } void stop() { diff --git a/app/src/main/java/org/solovyev/android/calculator/wizard/DragButtonWizardStep.java b/app/src/main/java/org/solovyev/android/calculator/wizard/DragButtonWizardStep.java index 5a911b0b..3c33defb 100644 --- a/app/src/main/java/org/solovyev/android/calculator/wizard/DragButtonWizardStep.java +++ b/app/src/main/java/org/solovyev/android/calculator/wizard/DragButtonWizardStep.java @@ -27,16 +27,17 @@ import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.widget.TextView; -import org.solovyev.android.calculator.App; + import org.solovyev.android.calculator.R; import org.solovyev.android.views.dragbutton.DirectionDragButton; import org.solovyev.android.views.dragbutton.DragButton; import org.solovyev.android.views.dragbutton.DragDirection; import org.solovyev.android.views.dragbutton.SimpleDragListener; +import java.util.Arrays; + import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.Arrays; public class DragButtonWizardStep extends WizardFragment { @@ -161,7 +162,6 @@ public class DragButtonWizardStep extends WizardFragment { private class DragButtonOnClickListener implements View.OnClickListener { @Override public void onClick(View v) { - App.getVibrator().vibrate(); if (action == DragButtonAction.center || action == DragButtonAction.end) { setNextAction(); } @@ -174,10 +174,6 @@ public class DragButtonWizardStep extends WizardFragment { @Nonnull DragButton dragButton, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { - if (dragDirection == DragDirection.up || dragDirection == DragDirection.down) { - App.getVibrator().vibrate(); - } - if (action.dragDirection == dragDirection) { setNextAction(); return true; diff --git a/app/src/main/res/xml/preferences_appearance.xml b/app/src/main/res/xml/preferences_appearance.xml index 1c088635..fe5f55e9 100644 --- a/app/src/main/res/xml/preferences_appearance.xml +++ b/app/src/main/res/xml/preferences_appearance.xml @@ -36,13 +36,6 @@ a:summary="@string/c_calc_color_display_summary" a:title="@string/c_calc_color_display_title" /> - -