Skip to content

Commit

Permalink
1. Speed up auto stitch
Browse files Browse the repository at this point in the history
2. draggable float button
  • Loading branch information
ekibun committed Nov 6, 2021
1 parent 9453a5c commit 80f8b7a
Show file tree
Hide file tree
Showing 15 changed files with 532 additions and 408 deletions.
2 changes: 1 addition & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 0 additions & 10 deletions .idea/runConfigurations.xml

This file was deleted.

7 changes: 5 additions & 2 deletions app/src/main/java/soko/ekibun/stitch/App.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package soko.ekibun.stitch

import android.app.Application
import android.preference.PreferenceManager

class App : Application() {
private val bitmapCache by lazy { BitmapCache(this) }
val sp by lazy { PreferenceManager.getDefaultSharedPreferences(this) }
private val bitmapCache by lazy { BitmapCache(this) }
val stitchInfo by lazy { mutableListOf<Stitch.StitchInfo>() }
val stitchInfo2 by lazy { mutableListOf<Stitch.StitchInfo>() }

Expand All @@ -17,7 +19,8 @@ class App : Application() {
private lateinit var app: App
val bitmapCache get() = app.bitmapCache
val stitchInfo get() = app.stitchInfo
var foreground = false
var foreground = false
val sp get() = app.sp

fun updateUndo() {
app.stitchInfo2.clear()
Expand Down
104 changes: 63 additions & 41 deletions app/src/main/java/soko/ekibun/stitch/EditActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.preference.PreferenceManager
import android.text.Html
import android.text.method.LinkMovementMethod
import android.util.Log
Expand All @@ -37,6 +36,7 @@ class EditActivity : Activity() {

private val editView by lazy { findViewById<EditView>(R.id.edit) }
private val guidanceView by lazy { findViewById<View>(R.id.guidance) }
private val rootView by lazy { findViewById<View>(R.id.root) }
private val selectInfo by lazy { findViewById<TextView>(R.id.select_info) }
private val seekDx by lazy { findViewById<RangeSeekbar>(R.id.seek_x) }
private val seekDy by lazy { findViewById<RangeSeekbar>(R.id.seek_y) }
Expand All @@ -51,6 +51,7 @@ class EditActivity : Activity() {
private fun updateSelectInfo() {
editView.dirty = true
guidanceView.visibility = if (App.stitchInfo.isEmpty()) View.VISIBLE else View.INVISIBLE
rootView.visibility = if (App.stitchInfo.isEmpty()) View.INVISIBLE else View.VISIBLE
selectInfo.text = getString(R.string.label_select, selected.size, App.stitchInfo.size)
editView.invalidate()
val selected = App.stitchInfo.filterIndexed { i, it -> i > 0 && selected.contains(it.key) }
Expand Down Expand Up @@ -117,30 +118,40 @@ class EditActivity : Activity() {

private fun updateSystemUI() {
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
(if (Build.VERSION.SDK_INT >= 26) View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION else 0)
(if (Build.VERSION.SDK_INT >= 26) View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION else 0)
if (Build.VERSION.SDK_INT < 26) return
val night = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
Configuration.UI_MODE_NIGHT_YES
Configuration.UI_MODE_NIGHT_YES
if (!night) window.decorView.systemUiVisibility = window.decorView.systemUiVisibility or
View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR or
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR or
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
}

private fun importFromGallery() {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "image/*"
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
startActivityForResult(Intent.createChooser(intent, "Stitch"), REQUEST_IMPORT)
}

private fun importFromCapture() {
this.startActivity(Intent(this, StartCaptureActivity::class.java))
}

@SuppressLint("ClickableViewAccessibility")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val sp = PreferenceManager.getDefaultSharedPreferences(this)
val policyVersion = getString(R.string.policy_version)
if (sp.getString("policy_version", "") != policyVersion) {
if (App.sp.getString("policy_version", "") != policyVersion) {
val policyView = TextView(this)
policyView.text = Html.fromHtml(getString(R.string.policy))
val padding = (resources.displayMetrics.density * 24).roundToInt()
policyView.setPaddingRelative(padding, padding, padding, 0)
policyView.movementMethod = LinkMovementMethod.getInstance()
AlertDialog.Builder(this).setCancelable(false).setView(policyView)
.setPositiveButton(R.string.policy_accept) { _, _ ->
sp.edit().putString("policy_version", policyVersion).apply()
App.sp.edit().putString("policy_version", policyVersion).apply()
}.setNegativeButton(R.string.policy_dismiss) { _, _ ->
finish()
}.show()
Expand Down Expand Up @@ -188,13 +199,16 @@ class EditActivity : Activity() {
updateRange()
}
findViewById<View>(R.id.menu_import).setOnClickListener {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "image/*"
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
startActivityForResult(Intent.createChooser(intent, "Stitch"), REQUEST_IMPORT)
importFromGallery()
}
findViewById<View>(R.id.guidance_from_gallery).setOnClickListener {
importFromGallery()
}
findViewById<View>(R.id.menu_capture).setOnClickListener {
this.startActivity(Intent(this, StartCaptureActivity::class.java))
importFromCapture()
}
findViewById<View>(R.id.guidance_from_capture).setOnClickListener {
importFromCapture()
}
findViewById<View>(R.id.menu_select_all).setOnClickListener {
selectAll()
Expand Down Expand Up @@ -325,38 +339,46 @@ class EditActivity : Activity() {
Toast.makeText(this, R.string.open_error, Toast.LENGTH_SHORT).show()
}
}
findViewById<TextView>(R.id.menu_opensource).setOnClickListener {
val opensourceView = TextView(this)
opensourceView.text = Html.fromHtml(getString(R.string.opensource))
findViewById<TextView>(R.id.menu_about).setOnClickListener {
val aboutView = TextView(this)
aboutView.text = Html.fromHtml(getString(R.string.about_info, getVersion(this)))
val padding = (resources.displayMetrics.density * 24).roundToInt()
opensourceView.setPaddingRelative(padding, padding, padding, 0)
opensourceView.movementMethod = LinkMovementMethod.getInstance()
aboutView.setPaddingRelative(padding, padding, padding, 0)
aboutView.movementMethod = LinkMovementMethod.getInstance()
AlertDialog.Builder(this)
.setTitle(R.string.menu_opensource)
.setView(opensourceView)
.setPositiveButton(getString(R.string.alert_ok)) { _, _ -> }
.setView(aboutView)
.setNegativeButton(getString(R.string.menu_opensource)) { _, _ ->
val opensourceView = TextView(this)
opensourceView.text = Html.fromHtml(getString(R.string.opensource))
aboutView.setPaddingRelative(padding, padding, padding, 0)
aboutView.movementMethod = LinkMovementMethod.getInstance()
AlertDialog.Builder(this)
.setView(aboutView)
.setPositiveButton(getString(R.string.alert_ok)) { _, _ -> }
.show()
}
.setNeutralButton(getString(R.string.menu_support)) { _, _ ->
val intentFullUrl = "intent://platformapi/startapp?saId=10000007&" +
"qrcode=https%3A%2F%2Fqr.alipay.com%2Ffkx14754b1r4mkbh6gfgg24#Intent;" +
"scheme=alipayqr;package=com.eg.android.AlipayGphone;end"
try {
val intent = Intent.parseUri(intentFullUrl, Intent.URI_INTENT_SCHEME)
startActivity(intent)
} catch (e: Exception) {
Toast.makeText(this, R.string.support_error, Toast.LENGTH_SHORT).show()
}
}
.setPositiveButton(getString(R.string.menu_github)) { _, _ ->
try {
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("https://github.com/ekibun/Stitch")
startActivity(intent)
} catch (e: Exception) {
Toast.makeText(this, R.string.open_error, Toast.LENGTH_SHORT).show()
}
}
.show()
}
findViewById<TextView>(R.id.menu_support).setOnClickListener {
val intentFullUrl = "intent://platformapi/startapp?saId=10000007&" +
"qrcode=https%3A%2F%2Fqr.alipay.com%2Ffkx14754b1r4mkbh6gfgg24#Intent;" +
"scheme=alipayqr;package=com.eg.android.AlipayGphone;end"
try {
val intent = Intent.parseUri(intentFullUrl, Intent.URI_INTENT_SCHEME)
startActivity(intent)
} catch (e: Exception) {
Toast.makeText(this, R.string.support_error, Toast.LENGTH_SHORT).show()
}
}
findViewById<TextView>(R.id.menu_github).setOnClickListener {
try {
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("https://github.com/ekibun/Stitch")
startActivity(intent)
} catch (e: Exception) {
Toast.makeText(this, R.string.open_error, Toast.LENGTH_SHORT).show()
}
}

seekDx.type = RangeSeekbar.TYPE_CENTER
seekDx.a = 0.5f
Expand Down
136 changes: 94 additions & 42 deletions app/src/main/java/soko/ekibun/stitch/FloatButton.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,59 +3,111 @@ package soko.ekibun.stitch
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.PixelFormat
import android.graphics.Rect
import android.os.Build
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import android.view.*
import android.widget.RelativeLayout
import androidx.core.content.edit
import kotlin.math.abs
import kotlin.math.roundToInt

@SuppressLint("ClickableViewAccessibility", "RtlHardcoded")
class FloatButton(var service: CaptureService) {
private var windowManager: WindowManager
private var floatLayout: RelativeLayout?
private var floatView: View
fun destroy() {
if (floatLayout != null) {
//移除悬浮窗口
windowManager.removeView(floatLayout)
floatLayout = null
}
private var windowManager: WindowManager
private var floatLayout: RelativeLayout?
private var floatView: View
fun destroy() {
if (floatLayout != null) {
//移除悬浮窗口
windowManager.removeView(floatLayout)
floatLayout = null
}
}

init {
service.applicationContext.setTheme(R.style.Theme_Stitch_Transparent)
val wmParams = WindowManager.LayoutParams()
windowManager =
service.application.getSystemService(Context.WINDOW_SERVICE) as WindowManager
wmParams.type = if (Build.VERSION.SDK_INT >= 26)
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
else @Suppress("DEPRECATION") WindowManager.LayoutParams.TYPE_PHONE
wmParams.format = PixelFormat.RGBA_8888
wmParams.flags =
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT
wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT
val inflater = LayoutInflater.from(service.application)
@SuppressLint("InflateParams")
floatLayout = inflater.inflate(R.layout.float_button, null) as RelativeLayout

floatView = floatLayout!!.findViewById(R.id.floatingActionButton)
wmParams.gravity = Gravity.LEFT or Gravity.TOP
wmParams.x = App.sp.getInt("float_x", Int.MAX_VALUE / 2)
wmParams.y = App.sp.getInt("float_y", Int.MAX_VALUE / 2)
windowManager.addView(floatLayout, wmParams)

init {
service.applicationContext.setTheme(R.style.Theme_Stitch_Transparent)
val wmParams = WindowManager.LayoutParams()
windowManager =
service.application.getSystemService(Context.WINDOW_SERVICE) as WindowManager
wmParams.type = if (Build.VERSION.SDK_INT >= 26)
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
else @Suppress("DEPRECATION") WindowManager.LayoutParams.TYPE_PHONE
wmParams.format = PixelFormat.RGBA_8888
wmParams.flags =
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
wmParams.gravity = Gravity.END or Gravity.BOTTOM
wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT
wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT
val inflater = LayoutInflater.from(service.application)
@SuppressLint("InflateParams")
floatLayout = inflater.inflate(R.layout.float_button, null) as RelativeLayout?
windowManager.addView(floatLayout, wmParams)
floatView = floatLayout!!.findViewById(R.id.floatingActionButton)

//点击
floatView.setOnClickListener { // 截屏
var downX = 0
var downY = 0
var isMove = false
var clickTime: Long
var isLongClick = false
floatView.setOnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
floatView.parent.requestDisallowInterceptTouchEvent(true)
downX = event.rawX.roundToInt()
downY = event.rawY.roundToInt()
isMove = false
isLongClick = false
val time = System.currentTimeMillis()
clickTime = time
floatView.postDelayed({
if (time == clickTime) {
floatLayout?.visibility = View.GONE
service.longClick()
isLongClick = true
}
}, ViewConfiguration.getLongPressTimeout().toLong())
}
MotionEvent.ACTION_MOVE -> {
if (!isMove && abs(downX - event.rawX) + abs(downY - event.rawY) > 10) {
clickTime = 0L
isMove = true
val rect = Rect()
val pos = IntArray(2)
floatLayout?.getWindowVisibleDisplayFrame(rect)
floatLayout?.getLocationOnScreen(pos)
downX = pos[0] - rect.left - downX
downY = pos[1] - rect.top - downY
}
if (isMove) {
wmParams.gravity = Gravity.LEFT or Gravity.TOP
wmParams.x = event.rawX.roundToInt() + downX
wmParams.y = event.rawY.roundToInt() + downY
windowManager.updateViewLayout(floatLayout, wmParams)
}
}
MotionEvent.ACTION_CANCEL,
MotionEvent.ACTION_UP -> {
clickTime = 0L
if (!isMove && !isLongClick) {
floatView.visibility = View.INVISIBLE
service.updateOrientation()
floatView.postDelayed({
service.capture()
floatView.visibility = View.VISIBLE
service.capture()
floatView.visibility = View.VISIBLE
}, 100)
} else if (isMove) {
App.sp.edit {
putInt("float_x", wmParams.x)
putInt("float_y", wmParams.y)
}
}
}
//长按
floatView.setOnLongClickListener {
floatLayout?.visibility = View.GONE
service.longClick()
true
}
}
true
}
}
}
Loading

0 comments on commit 80f8b7a

Please sign in to comment.