|
|
@@ -30,6 +30,22 @@ export const useActionStore = defineStore('action', () => {
|
|
|
const appStore = useAppStore()
|
|
|
const clipboard = ref<BaseWidget[]>()
|
|
|
|
|
|
+ const isLockedWidget = (widget?: BaseWidget | Page) => {
|
|
|
+ return !!(widget && 'locked' in widget && widget.locked)
|
|
|
+ }
|
|
|
+
|
|
|
+ const hasLockedDescendant = (widget?: BaseWidget | Page): boolean => {
|
|
|
+ return !!widget?.children?.some((child) => isLockedWidget(child) || hasLockedDescendant(child))
|
|
|
+ }
|
|
|
+
|
|
|
+ const isWidgetTreeLocked = (widget?: BaseWidget | Page) => {
|
|
|
+ return isLockedWidget(widget) || hasLockedDescendant(widget)
|
|
|
+ }
|
|
|
+
|
|
|
+ const getEditableWidgets = (widgets = projectStore.activeWidgets) => {
|
|
|
+ return widgets.filter((widget) => !isWidgetTreeLocked(widget))
|
|
|
+ }
|
|
|
+
|
|
|
const findWidgetLocation = (
|
|
|
parent: Page | BaseWidget,
|
|
|
widgetId: string,
|
|
|
@@ -98,7 +114,8 @@ export const useActionStore = defineStore('action', () => {
|
|
|
* @param type 对齐类型
|
|
|
*/
|
|
|
const onAlign = (type: AlignType) => {
|
|
|
- const widgets = projectStore.activeWidgets
|
|
|
+ const widgets = getEditableWidgets()
|
|
|
+ if (!widgets.length) return
|
|
|
const screen = projectStore.activeScreen
|
|
|
switch (type) {
|
|
|
case 'left': {
|
|
|
@@ -203,7 +220,8 @@ export const useActionStore = defineStore('action', () => {
|
|
|
* @param type 宽高匹配类型
|
|
|
*/
|
|
|
const onMatchSize = (type: 'width' | 'height' | 'both') => {
|
|
|
- const widgets = projectStore.activeWidgets
|
|
|
+ const widgets = getEditableWidgets()
|
|
|
+ if (!widgets.length) return
|
|
|
switch (type) {
|
|
|
case 'width': {
|
|
|
const width = Math.max(...widgets.map((widget) => widget.props.width))
|
|
|
@@ -238,7 +256,8 @@ export const useActionStore = defineStore('action', () => {
|
|
|
* @param type 层级调整类型
|
|
|
*/
|
|
|
const onLevel = (type: 'up' | 'down' | 'top' | 'bottom') => {
|
|
|
- let widgetIds = projectStore.activeWidgets.map((widget) => widget.id)
|
|
|
+ let widgetIds = getEditableWidgets().map((widget) => widget.id)
|
|
|
+ if (!widgetIds.length) return
|
|
|
|
|
|
bfsWalk(projectStore.activePage, (child) => {
|
|
|
// 对子节点遍历排序
|
|
|
@@ -296,7 +315,7 @@ export const useActionStore = defineStore('action', () => {
|
|
|
screen.pages.forEach((page) => {
|
|
|
bfsWalk(page, (child) => {
|
|
|
const index = child?.children?.findIndex((item) => item.id === widgetId) ?? -1
|
|
|
- if (index !== -1) {
|
|
|
+ if (index !== -1 && !isWidgetTreeLocked(child.children[index])) {
|
|
|
child.children.splice(index, 1)
|
|
|
}
|
|
|
})
|
|
|
@@ -308,7 +327,7 @@ export const useActionStore = defineStore('action', () => {
|
|
|
* 删除控件
|
|
|
*/
|
|
|
const onDelete = () => {
|
|
|
- const widgetIds = projectStore.activeWidgets.map((widget) => widget.id)
|
|
|
+ const widgetIds = getEditableWidgets().map((widget) => widget.id)
|
|
|
if (!widgetIds.length) return
|
|
|
|
|
|
projectStore.project?.screens.forEach((screen) => {
|
|
|
@@ -324,7 +343,7 @@ export const useActionStore = defineStore('action', () => {
|
|
|
})
|
|
|
})
|
|
|
})
|
|
|
- projectStore.activeWidgets = []
|
|
|
+ projectStore.activeWidgets = projectStore.activeWidgets.filter((widget) => widget.locked)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -339,7 +358,7 @@ export const useActionStore = defineStore('action', () => {
|
|
|
* 复用
|
|
|
*/
|
|
|
const onCopyFrom = () => {
|
|
|
- const widgetIds = projectStore.activeWidgets.map((widget) => widget.id)
|
|
|
+ const widgetIds = getEditableWidgets().map((widget) => widget.id)
|
|
|
if (!widgetIds.length) return
|
|
|
|
|
|
bfsWalk(projectStore.activePage, (child) => {
|
|
|
@@ -383,8 +402,10 @@ export const useActionStore = defineStore('action', () => {
|
|
|
const onPaste = () => {
|
|
|
if (!clipboard.value?.length) return
|
|
|
|
|
|
- const list =
|
|
|
- projectStore.activeWidgets?.[0]?.children || projectStore.activePage?.children || []
|
|
|
+ const target = projectStore.activeWidgets?.[0]
|
|
|
+ const list = !isWidgetTreeLocked(target)
|
|
|
+ ? target?.children || projectStore.activePage?.children || []
|
|
|
+ : projectStore.activePage?.children || []
|
|
|
const newArr: BaseWidget[] = []
|
|
|
clipboard.value.forEach((obj) => {
|
|
|
obj.props.x += 10
|
|
|
@@ -404,7 +425,7 @@ export const useActionStore = defineStore('action', () => {
|
|
|
* 剪切
|
|
|
*/
|
|
|
const onCut = () => {
|
|
|
- const widgetIds = projectStore.activeWidgets.map((widget) => widget.id)
|
|
|
+ const widgetIds = getEditableWidgets().map((widget) => widget.id)
|
|
|
if (!widgetIds.length) return
|
|
|
clipboard.value = []
|
|
|
bfsWalk(projectStore.activePage, (child) => {
|
|
|
@@ -414,14 +435,14 @@ export const useActionStore = defineStore('action', () => {
|
|
|
child.children.splice(index, 1)
|
|
|
}
|
|
|
})
|
|
|
- projectStore.activeWidgets = []
|
|
|
+ projectStore.activeWidgets = projectStore.activeWidgets.filter((widget) => widget.locked)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 隐藏/显示
|
|
|
*/
|
|
|
const onHidden = (hidden: boolean) => {
|
|
|
- const widgetIds = projectStore.activeWidgets.map((widget) => widget.id)
|
|
|
+ const widgetIds = getEditableWidgets().map((widget) => widget.id)
|
|
|
if (!widgetIds.length) return
|
|
|
|
|
|
bfsWalk(projectStore.activePage, (child) => {
|
|
|
@@ -452,6 +473,7 @@ export const useActionStore = defineStore('action', () => {
|
|
|
widgetIds.forEach((widgetId) => {
|
|
|
const location = findWidgetLocationInProject(widgetId)
|
|
|
if (!location || location.parent.type === 'page') return
|
|
|
+ if (isWidgetTreeLocked(location.widget)) return
|
|
|
|
|
|
const { widget, list, index, ancestors, page, screen } = location
|
|
|
const offset = getUnbindOffset(ancestors.slice(1))
|