|
@@ -2,25 +2,72 @@ package com.iscs.bozzys.ui.pages.edit.step
|
|
|
|
|
|
|
|
import android.content.Context
|
|
import android.content.Context
|
|
|
import android.content.Intent
|
|
import android.content.Intent
|
|
|
|
|
+import android.view.WindowManager
|
|
|
|
|
+import androidx.compose.animation.AnimatedVisibility
|
|
|
|
|
+import androidx.compose.animation.core.Animatable
|
|
|
|
|
+import androidx.compose.animation.core.spring
|
|
|
|
|
+import androidx.compose.animation.core.tween
|
|
|
|
|
+import androidx.compose.animation.slideInVertically
|
|
|
|
|
+import androidx.compose.animation.slideOutVertically
|
|
|
|
|
+import androidx.compose.foundation.background
|
|
|
|
|
+import androidx.compose.foundation.clickable
|
|
|
|
|
+import androidx.compose.foundation.interaction.MutableInteractionSource
|
|
|
import androidx.compose.foundation.layout.Box
|
|
import androidx.compose.foundation.layout.Box
|
|
|
import androidx.compose.foundation.layout.Column
|
|
import androidx.compose.foundation.layout.Column
|
|
|
import androidx.compose.foundation.layout.PaddingValues
|
|
import androidx.compose.foundation.layout.PaddingValues
|
|
|
|
|
+import androidx.compose.foundation.layout.Row
|
|
|
|
|
+import androidx.compose.foundation.layout.Spacer
|
|
|
|
|
+import androidx.compose.foundation.layout.fillMaxHeight
|
|
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
|
|
|
+import androidx.compose.foundation.layout.fillMaxWidth
|
|
|
|
|
+import androidx.compose.foundation.layout.height
|
|
|
|
|
+import androidx.compose.foundation.layout.offset
|
|
|
|
|
+import androidx.compose.foundation.layout.padding
|
|
|
|
|
+import androidx.compose.foundation.layout.size
|
|
|
|
|
+import androidx.compose.foundation.shape.RoundedCornerShape
|
|
|
|
|
+import androidx.compose.material3.Button
|
|
|
|
|
+import androidx.compose.material3.Icon
|
|
|
|
|
+import androidx.compose.material3.MaterialTheme
|
|
|
|
|
+import androidx.compose.material3.Text
|
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.Composable
|
|
|
import androidx.compose.runtime.LaunchedEffect
|
|
import androidx.compose.runtime.LaunchedEffect
|
|
|
|
|
+import androidx.compose.runtime.SideEffect
|
|
|
|
|
+import androidx.compose.runtime.getValue
|
|
|
import androidx.compose.runtime.mutableStateMapOf
|
|
import androidx.compose.runtime.mutableStateMapOf
|
|
|
|
|
+import androidx.compose.runtime.mutableStateOf
|
|
|
import androidx.compose.runtime.remember
|
|
import androidx.compose.runtime.remember
|
|
|
|
|
+import androidx.compose.runtime.rememberCoroutineScope
|
|
|
|
|
+import androidx.compose.runtime.setValue
|
|
|
import androidx.compose.ui.Alignment
|
|
import androidx.compose.ui.Alignment
|
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.Modifier
|
|
|
|
|
+import androidx.compose.ui.draw.clip
|
|
|
import androidx.compose.ui.geometry.Offset
|
|
import androidx.compose.ui.geometry.Offset
|
|
|
|
|
+import androidx.compose.ui.graphics.Color
|
|
|
|
|
+import androidx.compose.ui.graphics.graphicsLayer
|
|
|
|
|
+import androidx.compose.ui.platform.LocalContext
|
|
|
|
|
+import androidx.compose.ui.res.painterResource
|
|
|
|
|
+import androidx.compose.ui.text.font.FontWeight
|
|
|
|
|
+import androidx.compose.ui.text.style.TextAlign
|
|
|
|
|
+import androidx.compose.ui.unit.dp
|
|
|
|
|
+import androidx.compose.ui.unit.sp
|
|
|
|
|
+import androidx.compose.ui.window.Dialog
|
|
|
|
|
+import androidx.compose.ui.window.DialogProperties
|
|
|
import androidx.compose.ui.zIndex
|
|
import androidx.compose.ui.zIndex
|
|
|
|
|
+import androidx.lifecycle.lifecycleScope
|
|
|
|
|
+import com.iscs.bozzys.R
|
|
|
import com.iscs.bozzys.ui.base.PageBase
|
|
import com.iscs.bozzys.ui.base.PageBase
|
|
|
import com.iscs.bozzys.ui.base.Title
|
|
import com.iscs.bozzys.ui.base.Title
|
|
|
|
|
+import com.iscs.bozzys.ui.pages.compose.CardContainer
|
|
|
|
|
+import com.iscs.bozzys.ui.pages.compose.FormInput
|
|
|
|
|
+import com.iscs.bozzys.ui.pages.compose.FormSelect
|
|
|
import com.iscs.bozzys.ui.pages.edit.step.compose.Anchor
|
|
import com.iscs.bozzys.ui.pages.edit.step.compose.Anchor
|
|
|
import com.iscs.bozzys.ui.pages.edit.step.compose.Connection
|
|
import com.iscs.bozzys.ui.pages.edit.step.compose.Connection
|
|
|
import com.iscs.bozzys.ui.pages.edit.step.compose.Node
|
|
import com.iscs.bozzys.ui.pages.edit.step.compose.Node
|
|
|
import com.iscs.bozzys.ui.pages.edit.step.compose.NodeItem
|
|
import com.iscs.bozzys.ui.pages.edit.step.compose.NodeItem
|
|
|
import com.iscs.bozzys.ui.pages.edit.step.compose.ZoomPanContainer
|
|
import com.iscs.bozzys.ui.pages.edit.step.compose.ZoomPanContainer
|
|
|
|
|
+import com.iscs.bozzys.ui.theme.Text
|
|
|
|
|
+import kotlinx.coroutines.delay
|
|
|
|
|
+import kotlinx.coroutines.launch
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 跳转到编辑流程页面
|
|
* 跳转到编辑流程页面
|
|
@@ -33,20 +80,24 @@ class PageEditStep : PageBase() {
|
|
|
@Composable
|
|
@Composable
|
|
|
override fun GetViews(pv: PaddingValues) {
|
|
override fun GetViews(pv: PaddingValues) {
|
|
|
val nodes = remember { mutableStateMapOf<String, Node>() }
|
|
val nodes = remember { mutableStateMapOf<String, Node>() }
|
|
|
|
|
+ val selectNode = remember { mutableStateOf(Node("-1", Offset(0f, 0f))) }
|
|
|
val lines = listOf(
|
|
val lines = listOf(
|
|
|
Connection("A", "B"),
|
|
Connection("A", "B"),
|
|
|
Connection("A", "D", fromAnchor = Anchor.RIGHT, toAnchor = Anchor.LEFT),
|
|
Connection("A", "D", fromAnchor = Anchor.RIGHT, toAnchor = Anchor.LEFT),
|
|
|
Connection("B", "C")
|
|
Connection("B", "C")
|
|
|
)
|
|
)
|
|
|
|
|
+ var showFormDialog by remember { mutableStateOf(false) }
|
|
|
LaunchedEffect(Unit) {
|
|
LaunchedEffect(Unit) {
|
|
|
nodes["A"] = Node("A", Offset(50f, 0f))
|
|
nodes["A"] = Node("A", Offset(50f, 0f))
|
|
|
nodes["B"] = Node("B", Offset(250f, 0f))
|
|
nodes["B"] = Node("B", Offset(250f, 0f))
|
|
|
nodes["D"] = Node("D", Offset(250f, 100f))
|
|
nodes["D"] = Node("D", Offset(250f, 100f))
|
|
|
nodes["C"] = Node("C", Offset(450f, 0f))
|
|
nodes["C"] = Node("C", Offset(450f, 0f))
|
|
|
|
|
+ // 默认选中第一个节点
|
|
|
|
|
+ nodes["A"]?.let { selectNode.value = it }
|
|
|
}
|
|
}
|
|
|
Column(Modifier.fillMaxSize()) {
|
|
Column(Modifier.fillMaxSize()) {
|
|
|
Title(pv, "作业流程管理")
|
|
Title(pv, "作业流程管理")
|
|
|
- ZoomPanContainer(nodes, lines, modifier = Modifier.fillMaxSize()) {
|
|
|
|
|
|
|
+ ZoomPanContainer(nodes, lines, modifier = Modifier.fillMaxSize()) { scale, toTopCenter, toCenter ->
|
|
|
// 控件显示
|
|
// 控件显示
|
|
|
Box(
|
|
Box(
|
|
|
modifier = Modifier
|
|
modifier = Modifier
|
|
@@ -54,11 +105,203 @@ class PageEditStep : PageBase() {
|
|
|
.zIndex(3f),
|
|
.zIndex(3f),
|
|
|
contentAlignment = Alignment.CenterStart
|
|
contentAlignment = Alignment.CenterStart
|
|
|
) {
|
|
) {
|
|
|
- nodes.forEach { NodeItem(it.key, nodes) }
|
|
|
|
|
|
|
+ nodes.forEach {
|
|
|
|
|
+ NodeItem(it.key, nodes, selectNode, { node ->
|
|
|
|
|
+ selectNode.value = node
|
|
|
|
|
+ // 将当前Node平移到屏幕中间
|
|
|
|
|
+ toTopCenter(node)
|
|
|
|
|
+ lifecycleScope.launch {
|
|
|
|
|
+ // 给移动位置增加点动画效果
|
|
|
|
|
+ delay(280)
|
|
|
|
|
+ // 弹出Dialog
|
|
|
|
|
+ showFormDialog = true
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // 底部弹出式的Dialog
|
|
|
|
|
+ FormDialog(showFormDialog, {
|
|
|
|
|
+ // 回到中心位置,默认不添加 等反馈
|
|
|
|
|
+ // toCenter(selectNode.value)
|
|
|
|
|
+ showFormDialog = false
|
|
|
|
|
+ }, pv) {
|
|
|
|
|
+ Column(
|
|
|
|
|
+ Modifier
|
|
|
|
|
+ .fillMaxWidth()
|
|
|
|
|
+ .fillMaxHeight(5 / 7f)
|
|
|
|
|
+ .padding(horizontal = 16.dp)
|
|
|
|
|
+ ) {
|
|
|
|
|
+ Column(
|
|
|
|
|
+ Modifier
|
|
|
|
|
+ .fillMaxWidth()
|
|
|
|
|
+ .weight(1f)
|
|
|
|
|
+ ) {
|
|
|
|
|
+ FormInput("节点名称", "", {})
|
|
|
|
|
+ FormSelect("负责人", "张三" to "zhangsan", listOf("张三" to "zhangsan"), {})
|
|
|
|
|
+ FormSelect(
|
|
|
|
|
+ "关联表单",
|
|
|
|
|
+ "通用作业申请单" to "normal2",
|
|
|
|
|
+ listOf(
|
|
|
|
|
+ "通用作业申请单" to "normal2",
|
|
|
|
|
+ "通用作业申请单" to "normal3",
|
|
|
|
|
+ "通用作业申请单" to "normal4",
|
|
|
|
|
+ "通用作业申请单" to "normal5",
|
|
|
|
|
+ "通用作业申请单" to "normal6",
|
|
|
|
|
+ "通用作业申请单" to "normal7",
|
|
|
|
|
+ "通用作业申请单" to "normal8",
|
|
|
|
|
+ "通用作业申请单" to "normal",
|
|
|
|
|
+ "通用作业申请单" to "normal9"
|
|
|
|
|
+ ),
|
|
|
|
|
+ {})
|
|
|
|
|
+ }
|
|
|
|
|
+ Button(
|
|
|
|
|
+ {},
|
|
|
|
|
+ modifier = Modifier
|
|
|
|
|
+ .fillMaxWidth()
|
|
|
|
|
+ .height(50.dp)
|
|
|
|
|
+ .clip(RoundedCornerShape(12.dp))
|
|
|
|
|
+ .background(MaterialTheme.colorScheme.primary),
|
|
|
|
|
+ shape = RoundedCornerShape(12.dp)
|
|
|
|
|
+ ) {
|
|
|
|
|
+ Text("保存", fontSize = 16.sp, fontWeight = FontWeight.Bold)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 底部弹出式的表单录入弹窗,嵌入页面式
|
|
|
|
|
+ */
|
|
|
|
|
+@Composable
|
|
|
|
|
+fun FormInPage(show: Boolean, onDismiss: () -> Unit, content: @Composable () -> Unit) {
|
|
|
|
|
+ AnimatedVisibility(
|
|
|
|
|
+ visible = show,
|
|
|
|
|
+ enter = slideInVertically { it },
|
|
|
|
|
+ exit = slideOutVertically { it }
|
|
|
|
|
+ ) {
|
|
|
|
|
+ Box(Modifier.fillMaxSize()) {
|
|
|
|
|
+ Box(
|
|
|
|
|
+ modifier = Modifier
|
|
|
|
|
+ .align(Alignment.BottomCenter)
|
|
|
|
|
+ .fillMaxWidth()
|
|
|
|
|
+ .background(Color.White)
|
|
|
|
|
+ ) {
|
|
|
|
|
+ Column(modifier = Modifier.fillMaxWidth()) {
|
|
|
|
|
+ Row() {
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ content()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+@Composable
|
|
|
|
|
+fun FormDialog(
|
|
|
|
|
+ show: Boolean,
|
|
|
|
|
+ onDismiss: () -> Unit,
|
|
|
|
|
+ paddingValues: PaddingValues = PaddingValues(0.dp),
|
|
|
|
|
+ content: @Composable () -> Unit
|
|
|
|
|
+) {
|
|
|
|
|
+ val ctx = LocalContext.current
|
|
|
|
|
+ if (!show || ctx !is PageBase) return
|
|
|
|
|
+ val scope = rememberCoroutineScope()
|
|
|
|
|
+ // 默认放到屏幕外部
|
|
|
|
|
+ val offsetY = remember { Animatable(1f) }
|
|
|
|
|
+
|
|
|
|
|
+ LaunchedEffect(Unit) {
|
|
|
|
|
+ ctx.setNavigationLight(false)
|
|
|
|
|
+ // 底部弹出动画处理
|
|
|
|
|
+ offsetY.animateTo(targetValue = 0f, animationSpec = spring(dampingRatio = 0.85f, stiffness = 300f))
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ Dialog(onDismissRequest = onDismiss, properties = DialogProperties(decorFitsSystemWindows = false)) {
|
|
|
|
|
+ val activityWindow = ctx.window
|
|
|
|
|
+ val dialogWindow = ctx.getDialogWindow()
|
|
|
|
|
+ SideEffect {
|
|
|
|
|
+ if (activityWindow != null && dialogWindow != null) {
|
|
|
|
|
+ val attributes = WindowManager.LayoutParams()
|
|
|
|
|
+ // 复制Activity窗口属性
|
|
|
|
|
+ attributes.copyFrom(activityWindow.attributes)
|
|
|
|
|
+ // 这个一定要设置
|
|
|
|
|
+ attributes.type = dialogWindow.attributes.type
|
|
|
|
|
+ // 更新窗口属性
|
|
|
|
|
+ dialogWindow.attributes = attributes
|
|
|
|
|
+ // 设置窗口的宽度和高度,这段代码Dialog源码中就有哦,可以自己去查看
|
|
|
|
|
+ dialogWindow.setLayout(activityWindow.decorView.width, activityWindow.decorView.height)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ Box(
|
|
|
|
|
+ modifier = Modifier
|
|
|
|
|
+ .fillMaxSize()
|
|
|
|
|
+ .background(Color.Black.copy(alpha = 0.6f))
|
|
|
|
|
+ .clickable(
|
|
|
|
|
+ indication = null,
|
|
|
|
|
+ interactionSource = remember { MutableInteractionSource() }) {
|
|
|
|
|
+ scope.launch {
|
|
|
|
|
+ offsetY.animateTo(1f, tween(200))
|
|
|
|
|
+ onDismiss()
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ contentAlignment = Alignment.BottomCenter
|
|
|
|
|
+ ) {
|
|
|
|
|
+ CardContainer(
|
|
|
|
|
+ topRadius = 16.dp,
|
|
|
|
|
+ bottomRadius = 0.dp,
|
|
|
|
|
+ modifier = Modifier
|
|
|
|
|
+ .graphicsLayer { translationY = offsetY.value * size.height }
|
|
|
|
|
+ .fillMaxWidth()
|
|
|
|
|
+ // 防止点击穿透
|
|
|
|
|
+ .clickable(indication = null, interactionSource = remember { MutableInteractionSource() }, onClick = {})
|
|
|
|
|
+ .background(Color.White, RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp))
|
|
|
|
|
+ ) {
|
|
|
|
|
+ Column(
|
|
|
|
|
+ Modifier
|
|
|
|
|
+ .fillMaxWidth()
|
|
|
|
|
+ .padding(bottom = paddingValues.calculateBottomPadding())
|
|
|
|
|
+ ) {
|
|
|
|
|
+ Row(
|
|
|
|
|
+ Modifier
|
|
|
|
|
+ .fillMaxWidth()
|
|
|
|
|
+ .height(40.dp)
|
|
|
|
|
+ .padding(horizontal = 16.dp),
|
|
|
|
|
+ verticalAlignment = Alignment.CenterVertically
|
|
|
|
|
+ ) {
|
|
|
|
|
+ Spacer(Modifier.size(40.dp))
|
|
|
|
|
+ Text(
|
|
|
|
|
+ "我是标题",
|
|
|
|
|
+ fontSize = 16.sp,
|
|
|
|
|
+ fontWeight = FontWeight.Bold,
|
|
|
|
|
+ color = Text,
|
|
|
|
|
+ modifier = Modifier.weight(1f),
|
|
|
|
|
+ textAlign = TextAlign.Center
|
|
|
|
|
+ )
|
|
|
|
|
+ Icon(
|
|
|
|
|
+ painter = painterResource(R.drawable.close),
|
|
|
|
|
+ contentDescription = null,
|
|
|
|
|
+ modifier = Modifier
|
|
|
|
|
+ .offset(8.dp, 0.dp)
|
|
|
|
|
+ .size(36.dp)
|
|
|
|
|
+ .clip(RoundedCornerShape(50))
|
|
|
|
|
+ .clickable(onClick = {
|
|
|
|
|
+ scope.launch {
|
|
|
|
|
+ offsetY.animateTo(1f, tween(200))
|
|
|
|
|
+ onDismiss()
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .padding(10.dp)
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+ content()
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
-}
|
|
|