SubwayTooter-Android-App/app/src/main/java/jp/juggler/subwaytooter/StatusButtonsPopup.kt

139 lines
4.2 KiB
Kotlin

package jp.juggler.subwaytooter
import android.annotation.SuppressLint
import android.graphics.drawable.ColorDrawable
import android.os.SystemClock
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import android.widget.LinearLayout
import android.widget.PopupWindow
import androidx.recyclerview.widget.RecyclerView
import jp.juggler.subwaytooter.api.entity.TootNotification
import jp.juggler.subwaytooter.api.entity.TootStatus
import jp.juggler.util.LogCategory
import org.jetbrains.anko.matchParent
internal class StatusButtonsPopup(
private val activity : ActMain,
column : Column,
bSimpleList : Boolean,
itemViewHolder : ItemViewHolder
) {
companion object {
@Suppress("unused")
private var log = LogCategory("StatusButtonsPopup")
private fun getViewWidth(v : View) : Int {
val spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
v.measure(spec, spec)
return v.measuredWidth
}
var last_popup_close = 0L
}
private val viewRoot : View
private val buttons_for_status : StatusButtons
private var window : PopupWindow? = null
init {
@SuppressLint("InflateParams")
this.viewRoot = activity.layoutInflater.inflate(R.layout.list_item_popup, null, false)
val statusButtonsViewHolder = StatusButtonsViewHolder(activity, matchParent, 0f)
viewRoot.findViewById<LinearLayout>(R.id.llBarPlaceHolder)
.addView(statusButtonsViewHolder.viewRoot)
this.buttons_for_status = StatusButtons(
activity,
column,
bSimpleList,
statusButtonsViewHolder,
itemViewHolder
)
}
fun dismiss() {
val window = this.window
if(window != null && window.isShowing) {
window.dismiss()
}
}
@SuppressLint("RtlHardcoded", "ClickableViewAccessibility")
fun show(
listView : RecyclerView,
anchor : View,
status : TootStatus,
notification : TootNotification?
) {
val window = PopupWindow(activity)
this.window = window
window.width = WindowManager.LayoutParams.WRAP_CONTENT
window.height = WindowManager.LayoutParams.WRAP_CONTENT
window.contentView = viewRoot
window.setBackgroundDrawable(ColorDrawable(0x00000000))
window.isTouchable = true
window.isOutsideTouchable = true
window.setTouchInterceptor { _, event ->
if(event.action == MotionEvent.ACTION_OUTSIDE) {
// ポップアップの外側をタッチしたらポップアップを閉じる
// また、そのタッチイベントがlistViewに影響しないようにする
window.dismiss()
last_popup_close = SystemClock.elapsedRealtime()
true
} else {
false
}
}
buttons_for_status.bind(status, notification)
buttons_for_status.close_window = window
val location = IntArray(2)
anchor.getLocationOnScreen(location)
val anchor_left = location[0]
val anchor_top = location[1]
listView.getLocationOnScreen(location)
val listView_top = location[1]
val density = activity.density
val clip_top = listView_top + (0.5f + 8f * density).toInt()
val clip_bottom = listView_top + listView.height - (0.5f + 8f * density).toInt()
val popup_height = (0.5f + (56f + 24f) * density).toInt()
var popup_y = anchor_top + anchor.height / 2
if(popup_y < clip_top) {
// 画面外のは画面内にする
popup_y = clip_top
} else if(clip_bottom - popup_y < popup_height) {
// 画面外のは画面内にする
if(popup_y > clip_bottom) popup_y = clip_bottom
// 画面の下側にあるならポップアップの吹き出しが下から出ているように見せる
viewRoot.findViewById<View>(R.id.ivTriangleTop).visibility = View.GONE
viewRoot.findViewById<View>(R.id.ivTriangleBottom).visibility = View.VISIBLE
popup_y -= popup_height
}
val anchor_width = anchor.width
val popup_width = getViewWidth(viewRoot)
var popup_x = anchor_left + anchor_width / 2 - popup_width / 2
if(popup_x < 0) popup_x = 0
val popup_x_max = activity.resources.displayMetrics.widthPixels - popup_width
if(popup_x > popup_x_max) popup_x = popup_x_max
window.showAtLocation(
listView, Gravity.LEFT or Gravity.TOP, popup_x, popup_y
)
}
}