From 3162283ce088f54a0c15b208edf58af0fbddacf9 Mon Sep 17 00:00:00 2001 From: Alex Sytnyk Date: Fri, 6 Jul 2018 12:35:02 +0300 Subject: [PATCH] Add UiUtils#updateLocationView and related stuff --- .../res/drawable-hdpi/ic_direction_arrow.png | Bin 0 -> 1137 bytes .../res/drawable-mdpi/ic_direction_arrow.png | Bin 0 -> 1094 bytes .../res/drawable-xhdpi/ic_direction_arrow.png | Bin 0 -> 1169 bytes .../drawable-xxhdpi/ic_direction_arrow.png | Bin 0 -> 1268 bytes .../telegram/ui/views/DirectionDrawable.kt | 63 ++++++++++++ .../src/net/osmand/telegram/utils/UiUtils.kt | 90 ++++++++++++++++++ 6 files changed, 153 insertions(+) create mode 100644 OsmAnd-telegram/res/drawable-hdpi/ic_direction_arrow.png create mode 100644 OsmAnd-telegram/res/drawable-mdpi/ic_direction_arrow.png create mode 100644 OsmAnd-telegram/res/drawable-xhdpi/ic_direction_arrow.png create mode 100644 OsmAnd-telegram/res/drawable-xxhdpi/ic_direction_arrow.png create mode 100644 OsmAnd-telegram/src/net/osmand/telegram/ui/views/DirectionDrawable.kt diff --git a/OsmAnd-telegram/res/drawable-hdpi/ic_direction_arrow.png b/OsmAnd-telegram/res/drawable-hdpi/ic_direction_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..790efba776fc8cb4b7911c8badde0d91897e435d GIT binary patch literal 1137 zcmbVMO=#0l9FJCIibL`H10h62#pScj+85TyFV2^U$yc&%K0g6cssd z7kY3{_NZbahciMMuIhLMO;K&Bs%Mye5Yt82Yr9G2`_pF(ZCgp^gq#(!o(jwM;UOP( z4|NsHp*|B>Osbu3t13i+1F=C@oqjh^s!67%S0U%{nP=#l2<}TV3#59oIa)*ejZb_z$v8V8SrBdN4 zQ4aaNya)i`1&Nm=mPoL{po@(v>jt|U8Z;P~zU^Tfxpb(}D53$JWC+s*7aT8}T~zD_ z^+1u3@m0g)MNZ%yC-kc(9pF6tLt{zlpfKn`J`V#l;F}~LrQHoMiQT^qg@S~Qa?H0$ zQjC5LnF9`Vv92W<@`bZ(OMykh0>F&3(U@qkf)R_dMLAkxV-Q*pNOClhh&S{sg_k>o zj&xkk$WlBlika4gCU=62D#xQ85|9P8fz{mr8?Ff(wryg&j@AB&Ra74u82JT+`Wsb{ zDxpPg-T-;Q^hr z*|@Hy3)T0=;aJKrCCd?a^k!^o~*>TpE-Iws@Po7u=4Y15aP`RS>f z+thV;whs;G)w$F9^*()I&+$ilUffu5`s(Z1ODonU4?ehi`PA6k$>}FQcCP;(`LH_o z_QKvzC%3fRezp9{e0t*ZMY?_UbZYz)xO4W~$h&1T?IZov$MRf!w0UKdKylZmez{!= P3V#B6rb~O&ac1;4XYO(x literal 0 HcmV?d00001 diff --git a/OsmAnd-telegram/res/drawable-mdpi/ic_direction_arrow.png b/OsmAnd-telegram/res/drawable-mdpi/ic_direction_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..0dd7c1772eb92abfce1e80d1315e49b51aff896a GIT binary patch literal 1094 zcmbVLNodqi7>P{hX6gQD3dGxI`YX(uywpwrgrK<8+dmrmLyFD9>@v>v+L z3YLN(c<|tgdT=?3C@7+cdeU3*=*feiJqkj7na)%Xr3VAaTk?P3|NYzY$k4gYjw2lu zMRk@2^a@$`C-1(!5T)!nuM4(;kfH-%#RnZ7}~WpW=tsyKLtN9a5XA+2y3))GaL z&H_$Uan;oHVA6aiH>iqtW0RGKa!( zUIYN}g2YP_ODx!E*2hN7`cZeAL5GnQx&d~PPbZ9qiKel}5T%HwjdO?x0 zeWF;%^ydmWkk1N|Sd?;-SZHHQeuNF*f^FX}@!i7eJ7U#*2n~$FDne83E*PmJjG{UU z=zP9eb^7F(>)WUiol45I8MO{WcLv(U5P5Vn&#JqfhMWT(8JH|^9D`MC5&^^?S%fc^WMX? z^s%?M)~VwwYg2C~PS4%vc7L7!bU>q4xJ&i-OZ~aUYu|3nf4sR;T%b~v{PGvAJ?prW OOm?X-q(ADvu=EGOOI@h| literal 0 HcmV?d00001 diff --git a/OsmAnd-telegram/res/drawable-xhdpi/ic_direction_arrow.png b/OsmAnd-telegram/res/drawable-xhdpi/ic_direction_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..fbab873b59e28d0d9df585ba8a29c9c22a1c3d7a GIT binary patch literal 1169 zcmbVMO=uKX9G_^3CGA$Bz1SKU#*2Z@yqVdV-F;)$u-Vzwg>D+w6+@}eH#2W{r^(El z%)DeLQK%Iy6;Y^Yy%edCLN5x*Nl+}MX-jE(XiFuw#nO`&1U+~t3eq>5-PA+y;K2L- z{r=zoIXOPIH#PA30LO8u%09Ek)*Z=sv7gOh>aTNb*-lFnbU$g(HVQFUaEOKZiieuG zhLJNj{R1B6xXrU}eS%I@-!g3CNhrZcu@^8l#|@9f0kS7CrzIv6-D8*P*U_y>C?hQ`T6(%6Y8X2hs(Lz? z%l71K#MjJh8EWN%u4W60Qp$|Nf?m#=xtysfYRS}l+=?Gj7NI0+k$^82J6Y#<9dvz%w4178ICN*RQx1v8cj9cg8`zM^HE<&h zEfF>vNYowXKh&VcCe_YZ8gv{R3SGYQyzv9fD3BD(Q^nJ}VilQe*IR)d)|(0Ytb;<< zD(2%aPp~#yteAy*{QJF6zfK+HUoL%HSvCJ${_Qg}*tYc*VYFre>!tIrj{H;DbmRK+ zg9Eo8U&7yAnl>JY{T~e;`1j}4IJ2_6XZwdM%9E3SUj%*cyg)zLym;sne435RgMTdD zJmU?a@0S)f4ffq#IQrV|r7zA6-m3j_#u;)iSke8JL$?=GnTJP?-$Fl){19KX<_E+ZhW16yV}ZWdkbz2+{-olQ%cOS)9k)g-2^qu9&cbIq;27w@jk zwPSM|L+3tBMpa}}2!lbZBAYm2Zc@<-E2H3tRb3TfA4GJ%d{7i$KKNXkR6mq`@VI+k zf4~3x|6Ujx><(ftnHn%L4IzqAkR(8yn^-ipxvGT1?a$)P*0yS9KnlYHMs&@`^O}P)*$X= z9NREzBs+vAO&g#b5y54erqL)*&|ECca9t=v(Hu$fBu(KIEzp#}P-y+Zpf+1kg`AkK z>w>#DR(4%WAjwLlLR7+pX-|+e&+{b3kPL%E1n$fluH@l{v%4Wd1deQLmaCZt>PwVL z=Cm8fprsow=vFqnDcEr8fr23;J;@?zf+BU@_p63>+#LAVj4jblVb%g<4mjqtEyH}M zyBlN}yE`lLfzTRZpRK{9NK>LIPwT*NGh!TrH-w@o0w_re&&yFf%+eB0No*J|abXo_ z0Z;(XaN$@i+K{sqpN&S+Tr8d7m}r8gQxQH%vm#5=Y+r(B5-G01%@~d=88T?-)}Zb> zm%k%dNZLShO}k*4Q;jMZDx0q9luZjwCTm$oA0E~W#jH4c{4{NNEdpDc0ZQ67b+i^| zLEFNHNK6H4m@nbHs!BMgK>vA`XW_uekrK-*ip*nmzVd(LM?#}WzgYfLJdGn*k^XYC z72syGnScR1$cC+Qb{zj3K>{rqF;Vc=e|YuB&@t-X=WgBi?WdXY&E+TDmWNI=Cwg}+ z56n-p>C?Y`jV&LX|0|Iv_OC(yO_|?`&iO`M1o;O}xtY#OU>@4p%@N)3W!p_f+gpD%IWv_EhqN?sj4dFj?=yh-n$d+Nb*dFF87_H5UYv8C6R4z9o6 z)^kd`e0TG&>NC27s>e?wZP(0`Vhcc-_ K@$J6xWB&jkK&yfP literal 0 HcmV?d00001 diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/views/DirectionDrawable.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/views/DirectionDrawable.kt new file mode 100644 index 0000000000..60e44aec52 --- /dev/null +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/views/DirectionDrawable.kt @@ -0,0 +1,63 @@ +package net.osmand.telegram.ui.views + +import android.graphics.Canvas +import android.graphics.ColorFilter +import android.graphics.PixelFormat +import android.graphics.Rect +import android.graphics.drawable.Drawable +import net.osmand.telegram.TelegramApplication + +class DirectionDrawable(private val app: TelegramApplication) : Drawable() { + + private var angle: Float = 0.toFloat() + private var arrowImage: Drawable? = null + + fun setImage(resourceId: Int, clrId: Int) { + arrowImage = app.uiUtils.getIcon(resourceId, clrId) + onBoundsChange(bounds) + } + + fun setAngle(angle: Float) { + this.angle = angle + } + + override fun getIntrinsicWidth() = arrowImage?.intrinsicWidth ?: super.getIntrinsicWidth() + + override fun getIntrinsicHeight() = arrowImage?.intrinsicHeight ?: super.getIntrinsicHeight() + + override fun onBoundsChange(bounds: Rect) { + super.onBoundsChange(bounds) + if (arrowImage != null) { + val w = arrowImage!!.intrinsicWidth + val h = arrowImage!!.intrinsicHeight + val dx = Math.max(0, bounds.width() - w) + val dy = Math.max(0, bounds.height() - h) + if (bounds.width() == 0 && bounds.height() == 0) { + arrowImage!!.setBounds(0, 0, w, h) + } else { + arrowImage!!.setBounds( + bounds.left + dx / 2, + bounds.top + dy / 2, + bounds.right - dx / 2, + bounds.bottom - dy / 2 + ) + } + } + } + + override fun draw(canvas: Canvas) { + canvas.save() + if (arrowImage != null) { + val r = bounds + canvas.rotate(angle, r.centerX().toFloat(), r.centerY().toFloat()) + arrowImage!!.draw(canvas) + } + canvas.restore() + } + + override fun getOpacity() = PixelFormat.UNKNOWN + + override fun setAlpha(alpha: Int) {} + + override fun setColorFilter(cf: ColorFilter?) {} +} diff --git a/OsmAnd-telegram/src/net/osmand/telegram/utils/UiUtils.kt b/OsmAnd-telegram/src/net/osmand/telegram/utils/UiUtils.kt index a45e53d8ba..b744ff09c7 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/utils/UiUtils.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/utils/UiUtils.kt @@ -1,15 +1,25 @@ package net.osmand.telegram.utils +import android.content.Context import android.graphics.* import android.graphics.drawable.Drawable import android.graphics.drawable.LayerDrawable +import android.hardware.Sensor +import android.hardware.SensorManager import android.support.annotation.ColorInt import android.support.annotation.ColorRes import android.support.annotation.DrawableRes import android.support.v4.content.ContextCompat import android.support.v4.graphics.drawable.DrawableCompat +import android.view.Surface +import android.view.WindowManager +import android.widget.ImageView +import android.widget.TextView +import net.osmand.Location +import net.osmand.data.LatLon import net.osmand.telegram.R import net.osmand.telegram.TelegramApplication +import net.osmand.telegram.ui.views.DirectionDrawable import java.util.* class UiUtils(private val app: TelegramApplication) { @@ -122,4 +132,84 @@ class UiUtils(private val app: TelegramApplication) { return bitmap } + + fun updateLocationView( + arrow: ImageView?, + text: TextView?, + lat: Double, + lon: Double, + cache: UpdateLocationViewCache + ) { + updateLocationView(arrow, text, LatLon(lat, lon), cache) + } + + fun updateLocationView( + arrow: ImageView?, + text: TextView?, + toLoc: LatLon, + cache: UpdateLocationViewCache + ) { + val fromLoc = app.locationProvider.lastKnownLocationLatLon + val heading = app.locationProvider.heading + val mes = FloatArray(2) + val locPassive = fromLoc == null || cache.outdatedLocation + val colorId = if (locPassive) R.color.icon_light else R.color.ctrl_active_light + + fromLoc?.also { l -> + Location.distanceBetween(toLoc.latitude, toLoc.longitude, l.latitude, l.longitude, mes) + } + + if (arrow != null) { + var newImage = false + val drawable = arrow.drawable + val dd = if (drawable is DirectionDrawable) { + drawable + } else { + newImage = true + DirectionDrawable(app) + } + dd.setImage(R.drawable.ic_direction_arrow, colorId) + if (fromLoc == null || heading == null) { + dd.setAngle(0f) + } else { + dd.setAngle(mes[1] - heading + 180 + cache.screenOrientation) + } + if (newImage) { + arrow.setImageDrawable(dd) + } + arrow.invalidate() + } + + if (text != null) { + text.setTextColor(ContextCompat.getColor(app, colorId)) + val meters = if (fromLoc == null) 0f else mes[1] + text.text = OsmandFormatter.getFormattedDistance(meters, app) + } + } + + fun getUpdateLocationViewCache() = + UpdateLocationViewCache().apply { screenOrientation = getScreenOrientation() } + + private fun getScreenOrientation(): Int { + // screenOrientation correction must not be applied for devices without compass + val sensorManager = app.getSystemService(Context.SENSOR_SERVICE) as SensorManager? + if (sensorManager?.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) == null) { + return 0 + } + + val windowManager = app.getSystemService(Context.WINDOW_SERVICE) as WindowManager? + val rotation = windowManager?.defaultDisplay?.rotation ?: return 0 + + return when (rotation) { + Surface.ROTATION_90 -> 90 + Surface.ROTATION_180 -> 180 + Surface.ROTATION_270 -> 270 + else -> 0 + } + } + + class UpdateLocationViewCache { + var screenOrientation: Int = 0 + var outdatedLocation: Boolean = false + } }