Files
netease--tango/packages/core/src/models/designer.ts
T
wehub-resource-sync 2d398e1894
Deploy Github Pages / deploy (push) Failing after 1s
chore: import upstream snapshot with attribution
2026-07-13 12:30:43 +08:00

309 lines
6.3 KiB
TypeScript

import { action, computed, makeObservable, observable, toJS } from 'mobx';
import { MenuDataType } from '@music163/tango-helpers';
import { AbstractWorkspace } from './abstract-workspace';
export type SimulatorNameType = 'desktop' | 'phone';
export type DesignerViewType = 'design' | 'code' | 'dual';
interface ISimulatorType {
name: SimulatorNameType;
width: number;
height: number;
}
interface IViewportBounding {
width: number;
height: number;
}
interface IDesignerOptions {
workspace: AbstractWorkspace;
simulator?: SimulatorNameType | ISimulatorType;
/**
* 菜单配置
*/
menuData: MenuDataType;
activeSidebarPanel?: string;
/**
* 默认激活的视图模式
*/
activeView?: DesignerViewType;
}
const ISimulatorTypes: Record<string, ISimulatorType> = {
desktop: {
name: 'desktop',
width: 1366,
height: 800,
},
phone: {
name: 'phone',
width: 375,
height: 812,
},
};
export class Designer {
/**
* 当前的沙箱模拟器类型
*/
_simulator: ISimulatorType = ISimulatorTypes.desktop;
/**
* 当前的视图尺寸
*/
_viewport: IViewportBounding = {
width: 1366,
height: 800,
};
/**
* 当前激活的视图
*/
_activeView: DesignerViewType = 'design';
/**
* 当前选中的侧边栏面板
*/
_activeSidebarPanel = '';
/**
* 是否显示智能引导
*/
_showSmartWizard = false;
/**
* 是否显示添加组件面板
*/
_showAddComponentPopover = false;
/**
* 添加组件面板的位置
*/
_addComponentPopoverPosition = { clientX: 0, clientY: 0 };
/**
* 是否显示右键菜单
*/
_showContextMenu = false;
/**
* 右键菜单在 iframe 上的位置
*/
_contextMenuPosition = { clientX: 0, clientY: 0 };
/**
* 是否显示右侧面板
*/
_showRightPanel = true;
/**
* 是否预览模式
*/
_isPreview = false;
/**
* 菜单列表
*/
_menuData?: MenuDataType = null;
private readonly workspace: AbstractWorkspace;
get simulator(): ISimulatorType {
return toJS(this._simulator);
}
get viewport() {
return toJS(this._viewport);
}
get activeView() {
return this._activeView;
}
get isPreview() {
return this._isPreview;
}
get showSmartWizard() {
return this._showSmartWizard;
}
get activeSidebarPanel() {
return this._activeSidebarPanel;
}
get showRightPanel() {
return this._showRightPanel;
}
get showAddComponentPopover() {
return this._showAddComponentPopover;
}
get addComponentPopoverPosition() {
return this._addComponentPopoverPosition;
}
get showContextMenu() {
return this._showContextMenu;
}
get contextMenuPosition() {
return this._contextMenuPosition;
}
get menuData() {
return this._menuData ?? ([] as MenuDataType);
}
constructor(options: IDesignerOptions) {
this.workspace = options.workspace;
const {
simulator,
menuData,
activeSidebarPanel: defaultActiveSidebarPanel,
activeView: defaultActiveView,
} = options;
if (menuData) {
this.setMenuData(menuData);
}
// 默认设计器模式
if (simulator) {
this.setSimulator(simulator);
}
// 默认展开的侧边栏
if (defaultActiveSidebarPanel) {
this.setActiveSidebarPanel(defaultActiveSidebarPanel);
}
// 默认激活的视图
if (defaultActiveView) {
this.setActiveView(defaultActiveView);
}
makeObservable(this, {
_simulator: observable,
_viewport: observable,
_activeView: observable,
_activeSidebarPanel: observable,
_showSmartWizard: observable,
_showRightPanel: observable,
_showAddComponentPopover: observable,
_addComponentPopoverPosition: observable,
_showContextMenu: observable,
_contextMenuPosition: observable,
_menuData: observable,
_isPreview: observable,
simulator: computed,
viewport: computed,
activeView: computed,
activeSidebarPanel: computed,
isPreview: computed,
showRightPanel: computed,
showSmartWizard: computed,
showAddComponentPopover: computed,
addComponentPopoverPosition: computed,
showContextMenu: computed,
contextMenuPosition: computed,
menuData: computed,
setSimulator: action,
setViewport: action,
setActiveView: action,
setActiveSidebarPanel: action,
closeSidebarPanel: action,
toggleRightPanel: action,
toggleSmartWizard: action,
toggleIsPreview: action,
toggleAddComponentPopover: action,
toggleContextMenu: action,
});
}
setSimulator(value: ISimulatorType | SimulatorNameType) {
if (typeof value === 'string') {
this._simulator = ISimulatorTypes[value];
} else {
this._simulator = value;
}
}
setViewport(value: IViewportBounding) {
this._viewport = value;
}
setActiveView(view: DesignerViewType) {
this._activeView = view;
if (view === 'dual') {
this.setActiveSidebarPanel('');
this.toggleRightPanel(false);
this.toggleIsPreview(true);
} else if (view === 'design') {
this.toggleIsPreview(false);
}
}
setActiveSidebarPanel(panel: string) {
if (panel && panel !== this.activeSidebarPanel) {
this._activeSidebarPanel = panel;
} else {
this._activeSidebarPanel = '';
}
}
setMenuData(menuData: MenuDataType) {
this._menuData = menuData;
}
closeSidebarPanel() {
this._activeSidebarPanel = '';
}
toggleSmartWizard(value: boolean) {
this._showSmartWizard = value;
}
toggleRightPanel(value?: boolean) {
this._showRightPanel = value ?? !this._showRightPanel;
}
/**
* 显示添加组件面板
* @param value 是否显示
* @param position 坐标
*/
toggleAddComponentPopover(
value: boolean,
position: {
clientX: number;
clientY: number;
} = this.addComponentPopoverPosition,
) {
this._showAddComponentPopover = value;
this._addComponentPopoverPosition = position;
}
toggleIsPreview(value: boolean) {
this._isPreview = value ?? !this._isPreview;
if (value) {
this.workspace.selectSource.clear();
}
}
toggleContextMenu(
value: boolean,
position: {
clientX: number;
clientY: number;
} = this.contextMenuPosition,
) {
this._showContextMenu = value;
this._contextMenuPosition = position;
}
}