123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703 |
- package com.sybotan.android.graphy
- import android.graphics.Canvas
- import android.graphics.Matrix
- import android.graphics.PointF
- import android.graphics.RectF
- import android.util.Log
- import android.view.MotionEvent
- import com.sybotan.android.graphy.enums.SGraphyItemFlag
- import com.sybotan.android.graphy.listeners.SGraphyItemPosListener
- import com.sybotan.android.graphy.utils.MatrixUtil
- import com.sybotan.base.extensions.toJson
- import org.jetbrains.anko.doAsync
- import java.util.*
- open class SGraphyItem(parent: SGraphyItem? = null) {
-
- companion object {
- private val TAG = SGraphyItem::class.java.name
-
- private var currentMoveItem: SGraphyItem? = null
-
- private var currentFocusItem: SGraphyItem? = null
-
- fun toChildMotionEvent(child: SGraphyItem, e: SMotionEvent): SMotionEvent {
- val ce = SMotionEvent(e)
- ce.matrix.preTranslate(child.pos.x, child.pos.y);
- ce.matrix.preScale(child.scale.x, child.scale.y);
- ce.matrix.preRotate(child.rotate, 0f, 0f);
-
- if (!child.isTransform) {
- val src = kotlin.floatArrayOf(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f)
- ce.matrix.getValues(src)
- val matrix = Matrix()
- matrix.preTranslate(src[2], src[5])
- matrix.preScale(child.scale.x, child.scale.y)
- matrix.preRotate(child.rotate)
- ce.matrix = matrix
- }
- val matrixMat = Matrix()
- ce.matrix.invert(matrixMat)
- val matrixTransform = MatrixUtil.matrixTransform(matrixMat, e.viewX, e.viewY)
- ce.x = matrixTransform.x
- ce.y = matrixTransform.y
- return ce
- }
- }
-
- var parent: SGraphyItem? = parent
- set(value) {
- if (field == value) {
- return
- }
- if (null != field) {
-
- field!!.children.remove(this)
- }
- field = value
- if (null != field) {
-
- field!!.children.add(this)
- field!!.children.sortByDescending { it.zOrder }
- }
- invalidate()
- }
-
- val children = ArrayList<SGraphyItem>()
-
- var scene: SGraphyScene? = null
- get() {
- return if (null != parent) {
- parent!!.scene
- } else {
- field
- }
- }
-
- var pos: PointF = PointF(0f, 0f)
- set(value) {
- if (field == value) {
- return
- }
- field = value
- invalidate()
- posListener?.onMoveTo(field.x, field.y)
- }
-
- var posListener: SGraphyItemPosListener? = null
-
- var zOrder = 0f
- set(value) {
- if (field == value) {
- return
- }
- field = value
- if (null != parent) {
- parent!!.children.sortByDescending { it.zOrder }
- }
- invalidate()
- }
-
- var scale = PointF(1f, 1f)
-
- var rotate = 0.0f
-
- var isTransform = true;
-
- var _inverseScaleX = 1f;
- var _inverseScaleY = 1f;
-
- var flags: EnumSet<SGraphyItemFlag> = EnumSet.noneOf(SGraphyItemFlag::class.java)
-
- var isVisible = true
- set(value) {
- if (field == value) {
- return
- }
- field = value
- invalidate()
- }
-
- var focus = false
- set(value) {
- if (!flags.contains(SGraphyItemFlag.ItemIsFocusable)) {
- return
- }
- if (field == value) {
- return
- }
- field = value
- if (value) {
- currentFocusItem?.focus = false
- onGetFocus()
- currentFocusItem = this
- } else {
- onLostFocus()
- if (currentFocusItem === this) {
- currentFocusItem = null
- }
- }
- }
-
- val focusItem: SGraphyItem?
- get() = currentFocusItem
-
- var isSelected = false
- set(value) {
- if (field == value) {
- return
- }
- field = value
- invalidate()
- }
-
- open fun boundingRect(): RectF {
- return RectF()
- }
-
- fun invalidate(rect: RectF = RectF()) {
- scene?.update()
- return
- }
-
- fun postInvalidateDelayed(delayed: Long) {
- doAsync {
- Thread.sleep(delayed)
- invalidate()
- }
- return
- }
-
- fun hide() {
- isVisible = false
- return
- }
-
- fun show() {
- isVisible = true
- return
- }
-
- fun moveTo(pos: PointF) {
- this.pos = pos
- return
- }
-
- fun moveTo(x: Float, y: Float) {
- pos = PointF(x, y)
- return
- }
-
-
-
- fun mapFromScene(x: Float, y: Float): PointF {
- val m = this.scene2itemMattrix()
- val matrix = Matrix()
- m.invert(matrix)
- return MatrixUtil.matrixTransform(matrix, x, y)
- }
-
- fun mapFromScene(point: PointF): PointF {
- return mapFromScene(point.x, point.y)
- }
-
- fun mapToScene(x: Float, y: Float): PointF {
- if (null == parent) {
- return PointF(x, y)
- }
- val m = this.scene2itemMattrix()
- return return MatrixUtil.matrixTransform(m, x, y)
- }
-
- fun mapToScene(point: PointF): PointF {
- return mapToScene(point.x, point.y)
- }
-
- fun itemPath(): MutableList<SGraphyItem> {
- if (null != parent) {
- val list = parent!!.itemPath()
- list.add(this)
- return list
- }
- return mutableListOf(this)
- }
-
- open fun contains(x: Float, y: Float): Boolean {
- Log.e("boundingRect", boundingRect().contains(x, y).toString())
- return boundingRect().contains(x, y)
- }
-
- fun contains(point: PointF): Boolean {
- return contains(point.x, point.y)
- }
-
-
-
- open fun onPaint(canvas: Canvas, rect: RectF) {
- canvas.save()
- this.onDraw(canvas)
- canvas.restore()
- val src = kotlin.floatArrayOf(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f)
- for (i in 1..children.size) {
- val item = children[children.size - i]
- if (!item.isVisible) {
- continue
- }
- try {
-
- canvas.save()
-
- canvas.translate(item.pos.x, item.pos.y)
- canvas.scale(item.scale.x, item.scale.y)
- canvas.rotate(item.rotate)
- if (!item.isTransform) {
- canvas.matrix.getValues(src)
- val matrix = Matrix()
- matrix.preTranslate(src[2], src[5])
- matrix.preScale(item.scale.x, item.scale.y)
- matrix.preRotate(item.rotate)
- canvas.matrix = matrix
- }
-
-
-
- item.onPaint(canvas, rect)
-
- canvas.restore()
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }
- return
- }
-
- open fun onDraw(canvas: Canvas) {
- }
-
- open fun onGetFocus() {
-
- return
- }
-
- open fun onLostFocus() {
-
- return
- }
-
- open fun onDown(e: SMotionEvent): Boolean {
- for (item in children) {
- if (!item.isVisible) {
- continue
- }
- val ce = toChildMotionEvent(item, e)
- if (item.contains(ce.x, ce.y)
- && item.onDown(ce)) {
- return true
- }
- }
- if (flags.contains(SGraphyItemFlag.ItemIsFocusable)) {
- focus = true
- return true
- }
- return false
- }
-
- open fun onSingleTapUp(e: SMotionEvent): Boolean {
- Log.d(TAG, "onSingleTapUp: releaseItem")
- releaseItem()
- for (item in children) {
- if (!item.isVisible) {
- Log.e("手势3scene", e.toJson())
- continue
- }
- val ce = toChildMotionEvent(item, e)
- Log.e("手势view", "${scene?.view?.scale}")
- Log.e("手势e", "${e.x}, ${e.y}")
- Log.e("手势ce", "${ce.x}, ${ce.y}")
- Log.e("手势1scene", (item.contains(ce.x, ce.y)).toString())
- if (item.contains(ce.x, ce.y)
- && item.onSingleTapUp(ce)) {
- Log.e("手势4scene", e.toJson())
- return true
- }
- }
- Log.e("手势2scene", e.toJson())
- return false
- }
- open fun onActionUp() {
- releaseItem()
- }
- open fun onActionMove(event: MotionEvent) {
- }
-
- open fun onShowPress(e: SMotionEvent): Boolean {
- Log.d(TAG, "onShowPress: releaseItem")
- for (item in children) {
- if (!item.isVisible) {
- continue
- }
- val ce = toChildMotionEvent(item, e)
- if (item.contains(ce.x, ce.y)
- && item.onShowPress(ce)) {
- return true
- }
- }
- return false
- }
-
- open fun onLongPress(e: SMotionEvent): Boolean {
- Log.d(TAG, "onLongPress: releaseItem")
- releaseItem()
- for (item in children) {
- if (!item.isVisible) {
- continue
- }
- val ce = toChildMotionEvent(item, e)
- if (item.contains(ce.x, ce.y)
- && item.onLongPress(ce)) {
- return true
- }
- }
- return false
- }
-
- open fun onScroll(e1: SMotionEvent, e2: SMotionEvent, distanceX: Float, distanceY: Float): Boolean {
- if (flags.contains(SGraphyItemFlag.ItemIsMovable) && currentMoveItem === this) {
- moveTo(pos.x - distanceX * scale.x, pos.y - distanceY * scale.y)
- return true
- }
- for (item in children) {
- if (!item.isVisible) {
- continue
- }
- val ce1 = toChildMotionEvent(item, e1)
- val ce2 = toChildMotionEvent(item, e2)
-
- if (item.contains(ce2.x, ce2.y)
- && item.onScroll(ce1, ce2, distanceX / item.scale.x, distanceY / item.scale.y)) {
- return true
- }
- }
- if (flags.contains(SGraphyItemFlag.ItemIsMovable) && null == currentMoveItem) {
- grabItem(this)
- currentMoveItem = this
- return true
- }
- return false
- }
-
- open fun onFling(e1: SMotionEvent, e2: SMotionEvent, velocityX: Float, velocityY: Float): Boolean {
- Log.d(TAG, "onFling: releaseItem")
- releaseItem()
- for (item in children) {
- if (!item.isVisible) {
- continue
- }
- val ce1 = toChildMotionEvent(item, e1)
- val ce2 = toChildMotionEvent(item, e2)
-
- if (item.contains(ce2.x, ce2.y)
- && item.onFling(ce1, ce2, velocityX / item.scale.x, velocityY / item.scale.y)) {
- return true
- }
- }
- return false
- }
-
-
-
- private fun grabItem(item: SGraphyItem) {
- Log.d(TAG, "grabItem")
- isSelected = true
- scene!!.grabItem = item
- return
- }
-
- private fun releaseItem() {
- isSelected = false
- currentMoveItem = null
- scene!!.grabItem = null
- return
- }
-
- fun scene2itemMattrix(): Matrix {
- var m = Matrix()
- val list = this.itemPath()
- for (item in list) {
- m.preTranslate(item.pos.x, item.pos.y);
- m.preScale(item.scale.x, item.scale.y);
- m.preRotate(item.rotate)
-
- if (!item.isTransform) {
-
- val src = kotlin.floatArrayOf(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f)
- m.getValues(src)
- val matrix = Matrix()
- matrix.preTranslate(src[2], src[5])
- matrix.preScale(item.scale.x, item.scale.y)
- matrix.preRotate(item.rotate)
- m = matrix
- }
- }
- return m
- }
- }
|