Compare commits
	
		
			No commits in common. "99fa5c698aecece761773a5f76ad24207944c2e5" and "aae7e54557bad37f534b80a55193c5e1866107d4" have entirely different histories.
		
	
	
		
			99fa5c698a
			...
			aae7e54557
		
	
		
| @ -6,7 +6,6 @@ div.app-container { | ||||
| 	width: 100%; | ||||
| 	height: 100%; | ||||
| 	display: flex; | ||||
| 	align-items: stretch; | ||||
| 	overflow: hidden; | ||||
| 	box-sizing: border-box; | ||||
| 
 | ||||
| @ -99,24 +98,13 @@ div.app-container { | ||||
| 		padding: 10px; | ||||
| 	} | ||||
| 
 | ||||
| 	div.app-panel-root { | ||||
| 		width: 100%; | ||||
| 		height: calc( 100% - 32px ); | ||||
| 		box-sizing: border-box; | ||||
| 		display: flex; | ||||
| 		justify-content: space-between; | ||||
| 		align-items: stretch; | ||||
| 		flex-direction: column; | ||||
| 		border: .8px solid rgba($color: #000000, $alpha: 0); | ||||
| 	} | ||||
| 
 | ||||
| 	div.app-panel { | ||||
| 		width: 100%; | ||||
| 		height: 100%; | ||||
| 		box-sizing: border-box; | ||||
| 		overflow: scroll; | ||||
| 		-ms-overflow-style: none; | ||||
| 		flex-shrink: 1; | ||||
| 		border: .8px solid rgba($color: #000000, $alpha: 0); | ||||
| 	} | ||||
| 
 | ||||
| 	div.app-panel.hide-scrollbar::-webkit-scrollbar { | ||||
| @ -140,7 +128,7 @@ div.app-container { | ||||
| 		background-color: rgba($color: #000000, $alpha: 0); | ||||
| 	} | ||||
| 
 | ||||
| 	div.app-panel-root.active { | ||||
| 	div.app-panel.active { | ||||
| 		border: .8px solid blue !important; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -68,7 +68,7 @@ class Container extends Component<IContainerProps> { | ||||
| 							delay={2} | ||||
| 							key={panelId} | ||||
| 						> | ||||
| 							<div | ||||
| 							<div	 | ||||
| 								className={classList.join(" ")} | ||||
| 								onClick={(e) => { | ||||
| 									e.stopPropagation(); | ||||
| @ -90,32 +90,16 @@ class Container extends Component<IContainerProps> { | ||||
| 				}</div> : null | ||||
| 			} | ||||
| 			<div | ||||
| 				className={[ | ||||
| 					"app-panel-root", | ||||
| 					hasActivePanel ? "active" : "" | ||||
| 				].filter(x => !!x).join(" ")} | ||||
| 				onClick={() => this.props.onFocusTab ? this.props.onFocusTab(showPanelId) : undefined} | ||||
| 				className={[ | ||||
| 					"app-panel", | ||||
| 					hasActivePanel ? "active" : "", | ||||
| 					showPanelInfo?.hidePadding ? "" : "has-padding", | ||||
| 					showPanelInfo?.hideScrollBar ? "hide-scrollbar" : "" | ||||
| 				].filter(x => !!x).join(" ")} | ||||
| 				draggable={false} | ||||
| 			> | ||||
| 				{/* 渲染 Command Bar */} | ||||
| 				{(() => { | ||||
| 					let info = getPanelInfoById(showPanelId as any); | ||||
| 					if (info &&  info.header) { | ||||
| 						const Header = info.header; | ||||
| 						return <Header></Header> | ||||
| 					} | ||||
| 				})()} | ||||
| 
 | ||||
| 				{/* 渲染 Panel 内容 */} | ||||
| 				<div | ||||
| 					className={[ | ||||
| 						"app-panel", | ||||
| 						showPanelInfo?.hidePadding ? "" : "has-padding", | ||||
| 						showPanelInfo?.hideScrollBar ? "hide-scrollbar" : "" | ||||
| 					].filter(x => !!x).join(" ")} | ||||
| 					draggable={false} | ||||
| 				> | ||||
| 					{getPanelById(showPanelId as any)} | ||||
| 				</div> | ||||
| 				{getPanelById(showPanelId as any)} | ||||
| 			</div> | ||||
| 		</> | ||||
| 	} | ||||
|  | ||||
| @ -19,58 +19,31 @@ div.details-list { | ||||
| 
 | ||||
|         div.details-list-checkbox { | ||||
|             display: flex; | ||||
|             width: 30px; | ||||
|             align-items: center; | ||||
|             justify-content: center; | ||||
|             opacity: 0; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     div.details-list-item.active, | ||||
|     div.details-list-item:hover { | ||||
| 
 | ||||
|         div.details-list-checkbox { | ||||
|             opacity: 1; | ||||
|             padding: 0 10px; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| div.light.details-list { | ||||
|      | ||||
|     div.details-list-item:nth-child(2n-1) { | ||||
|     div.details-list-item:nth-child(2n) { | ||||
|         background-color: rgba($lt-bg-color-lvl5-light, .4); | ||||
|     } | ||||
| 
 | ||||
|     div.details-list-item:hover { | ||||
|         background-color: $lt-bg-color-lvl3-light; | ||||
|     } | ||||
| 
 | ||||
|     div.details-list-item.active { | ||||
|         background-color: $lt-bg-color-lvl2-light; | ||||
|         color: rgba(0, 0, 0, 0.95); | ||||
|     } | ||||
| 
 | ||||
|     // div.details-list-checkbox:hover { | ||||
|     //     background-color: rgba($lt-bg-color-lvl1-light, .4); | ||||
|     // } | ||||
| } | ||||
| 
 | ||||
| div.dark.details-list { | ||||
| 
 | ||||
|     div.details-list-item:nth-child(2n-1) { | ||||
|         background-color: rgba($lt-bg-color-lvl5-dark, .8); | ||||
|     div.details-list-item:nth-child(2n) { | ||||
|         background-color: rgba($lt-bg-color-lvl5-dark, .4); | ||||
|     } | ||||
| 
 | ||||
|     div.details-list-item:hover { | ||||
|         background-color: $lt-bg-color-lvl3-dark; | ||||
|     } | ||||
| 
 | ||||
|     div.details-list-item.active { | ||||
|         background-color: $lt-bg-color-lvl2-dark; | ||||
|         color: rgba(255, 255, 255, 0.85); | ||||
|     } | ||||
| 
 | ||||
|     // div.details-list-checkbox:hover { | ||||
|     //     background-color: rgba($lt-bg-color-lvl1-dark, .8); | ||||
|     // } | ||||
| } | ||||
| @ -16,13 +16,9 @@ interface IColumns<D extends IItems, K extends keyof D> { | ||||
| 
 | ||||
| interface IDetailsListProps { | ||||
|     items: IItems[]; | ||||
|     className?: string; | ||||
|     columns: IColumns<this["items"][number], keyof this["items"][number]>[]; | ||||
|     hideCheckBox?: boolean; | ||||
|     checkboxClassName?: string; | ||||
|     click?: () => void; | ||||
|     clickLine?: (item: IItems) => any; | ||||
|     checkBox?: (data: IItems) => any; | ||||
| } | ||||
| 
 | ||||
| class DetailsList extends Component<IDetailsListProps> { | ||||
| @ -45,27 +41,13 @@ class DetailsList extends Component<IDetailsListProps> { | ||||
| 
 | ||||
|     public render(): ReactNode { | ||||
|         return <Theme | ||||
|             className={"details-list" + (this.props.className ? ` ${this.props.className}` : "")} | ||||
|             onClick={this.props.click} | ||||
|             className="details-list" | ||||
|             backgroundLevel={BackgroundLevel.Level4} | ||||
|             fontLevel={FontLevel.normal} | ||||
|         >{ | ||||
|             this.props.items.map((item) => { | ||||
|                 const { checkboxClassName } = this.props; | ||||
|                 const classList: string[] = ["details-list-item"]; | ||||
|                 if (item.select) { | ||||
|                     classList.push("active"); | ||||
|                 } | ||||
|                 return <div | ||||
|                     className={classList.join(" ")} | ||||
|                     key={item.key} | ||||
|                     onClick={(e) => { | ||||
|                         if (this.props.clickLine) { | ||||
|                             e.stopPropagation(); | ||||
|                             this.props.clickLine(item); | ||||
|                         } | ||||
|                     }} | ||||
|                 > | ||||
|                 return <div className="details-list-item" key={item.key}> | ||||
|                     { | ||||
|                         this.props.columns.map((column) => { | ||||
|                             if (column.beforeCheckbox) { | ||||
| @ -77,12 +59,6 @@ class DetailsList extends Component<IDetailsListProps> { | ||||
|                         this.props.hideCheckBox ? null : | ||||
|                         <div  | ||||
|                             className={"details-list-checkbox" + (checkboxClassName ? ` ${checkboxClassName}` : "")} | ||||
|                             onClick={(e) => { | ||||
|                                 if (this.props.checkBox) { | ||||
|                                     e.stopPropagation(); | ||||
|                                     this.props.checkBox(item); | ||||
|                                 } | ||||
|                             }} | ||||
|                         > | ||||
|                             <Icon iconName="CheckMark"></Icon> | ||||
|                         </div> | ||||
| @ -100,4 +76,4 @@ class DetailsList extends Component<IDetailsListProps> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export { DetailsList, IItems }; | ||||
| export { DetailsList }; | ||||
| @ -1,8 +1,7 @@ | ||||
| import { createContext, Component, FunctionComponent } from "react"; | ||||
| import { Emitter } from "@Model/Emitter"; | ||||
| import { Model, ObjectID } from "@Model/Model"; | ||||
| import { Model } from "@Model/Model"; | ||||
| import { Archive } from "@Model/Archive"; | ||||
| import { CtrlObject } from "@Model/CtrlObject"; | ||||
| import { AbstractRenderer } from "@Model/Renderer"; | ||||
| import { ClassicRenderer, MouseMod } from "@GLRender/ClassicRenderer"; | ||||
| import { Setting } from "./Setting"; | ||||
| @ -17,8 +16,7 @@ function randomColor() { | ||||
| } | ||||
| 
 | ||||
| class Status extends Emitter<{ | ||||
|     mouseModChange: MouseMod, | ||||
|     focusObjectChange: Set<ObjectID> | ||||
|     mouseModChange: MouseMod | ||||
| }> { | ||||
| 
 | ||||
|     public setting: Setting = undefined as any; | ||||
| @ -43,19 +41,6 @@ class Status extends Emitter<{ | ||||
|      */ | ||||
|     public model: Model = new Model(); | ||||
| 
 | ||||
|     /** | ||||
|      * 焦点对象 | ||||
|      */ | ||||
|     public focusObject: Set<ObjectID> = new Set(); | ||||
| 
 | ||||
|     /** | ||||
|      * 更新焦点对象 | ||||
|      */ | ||||
|     public setFocusObject(focusObject: Set<ObjectID>) { | ||||
|         this.focusObject = focusObject; | ||||
|         this.emit("focusObjectChange", this.focusObject); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 鼠标工具状态 | ||||
|      */ | ||||
|  | ||||
| @ -37,14 +37,6 @@ class Model extends Emitter<ModelEvent> { | ||||
|      */ | ||||
|     public objectPool: CtrlObject[] = []; | ||||
| 
 | ||||
|     public getObjectById(id: ObjectID): CtrlObject | undefined { | ||||
|         for (let i = 0; i < this.objectPool.length; i++) { | ||||
|             if (this.objectPool[i].id === id) { | ||||
|                 return this.objectPool[i]; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 标签列表 | ||||
|      */ | ||||
| @ -171,6 +163,9 @@ class Model extends Emitter<ModelEvent> { | ||||
|      */ | ||||
|     public update(t: number) { | ||||
| 
 | ||||
|         // 清除全部渲染状态
 | ||||
|         this.renderer.clean(); | ||||
| 
 | ||||
|         // 第一轮更新
 | ||||
|         for (let i = 0; i < this.objectPool.length; i++) { | ||||
|             let object = this.objectPool[i]; | ||||
| @ -195,16 +190,6 @@ class Model extends Emitter<ModelEvent> { | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         this.draw(); | ||||
| 
 | ||||
|         this.emit("loop", t); | ||||
|     } | ||||
| 
 | ||||
|     public draw() { | ||||
| 
 | ||||
|         // 清除全部渲染状态
 | ||||
|         this.renderer.clean(); | ||||
| 
 | ||||
|         // 渲染
 | ||||
|         for (let i = 0; i < this.objectPool.length; i++) { | ||||
|             let object = this.objectPool[i]; | ||||
| @ -221,6 +206,8 @@ class Model extends Emitter<ModelEvent> { | ||||
|                 } as any); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         this.emit("loop", t); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -73,7 +73,7 @@ class SimulatorWeb extends Component { | ||||
|                 }, | ||||
|                 { | ||||
|                     items: [{ | ||||
|                         panles: ["ObjectList", "Test tab"] | ||||
|                         panles: ["ObjectList"] | ||||
|                     }, { | ||||
|                         items: [{panles: ["Label e", "ee"]}, {panles: ["F"]}], | ||||
|                         layout: LayoutDirection.Y | ||||
|  | ||||
| @ -1,78 +0,0 @@ | ||||
| import { BackgroundLevel, FontLevel, Theme } from "@Component/Theme/Theme"; | ||||
| import { useStatus, IMixinStatusProps } from "../../Context/Status"; | ||||
| import { Icon } from "@fluentui/react"; | ||||
| import { Component, ReactNode } from "react"; | ||||
| import { ObjectID } from "@Model/Renderer"; | ||||
| import "./ObjectList.scss"; | ||||
| 
 | ||||
| @useStatus | ||||
| class ObjectCommand extends Component<IMixinStatusProps> { | ||||
| 	public render(): ReactNode { | ||||
| 		return <Theme | ||||
| 			className="object-list-command-bar" | ||||
| 			backgroundLevel={BackgroundLevel.Level4} | ||||
| 			fontLevel={FontLevel.normal} | ||||
| 		> | ||||
| 			<div | ||||
| 				className="command-item" | ||||
| 				onClick={() => { | ||||
| 					if (this.props.status) { | ||||
| 						let allObjSet = new Set<ObjectID>(); | ||||
| 						this.props.status.model.objectPool.forEach((obj) => { | ||||
| 							allObjSet.add(obj.id.toString()); | ||||
| 						}) | ||||
| 						this.props.status.setFocusObject(allObjSet); | ||||
| 					} | ||||
| 				}} | ||||
| 			> | ||||
| 				<Icon iconName="CheckMark"></Icon> | ||||
| 			</div> | ||||
| 			<div | ||||
| 				className="command-item" | ||||
| 				onClick={() => { | ||||
| 					if (this.props.status) { | ||||
| 						this.props.status.setFocusObject(new Set<ObjectID>()); | ||||
| 					} | ||||
| 				}} | ||||
| 			> | ||||
| 				<Icon iconName="CalculatorMultiply"></Icon> | ||||
| 			</div> | ||||
| 			<div | ||||
| 				className="command-item" | ||||
| 				onClick={() => { | ||||
| 					this.props.status ? this.props.status.newGroup() : undefined; | ||||
| 					this.props.status ? this.props.status.model.draw() : undefined; | ||||
| 				}} | ||||
| 			> | ||||
| 				<Icon iconName="WebAppBuilderFragmentCreate"></Icon> | ||||
| 			</div> | ||||
| 			<div | ||||
| 				className="command-item" | ||||
| 				onClick={() => { | ||||
| 					this.props.status ? this.props.status.newRange() : undefined; | ||||
| 					this.props.status ? this.props.status.model.draw() : undefined; | ||||
| 				}} | ||||
| 			> | ||||
| 				<Icon iconName="CubeShape"></Icon> | ||||
| 			</div> | ||||
| 			<div | ||||
| 				className="command-item" | ||||
| 				onClick={() => { | ||||
| 					if (this.props.status) { | ||||
| 						let deleteId: ObjectID[] = []; | ||||
| 						this.props.status.focusObject.forEach((obj) => { | ||||
| 							deleteId.push(obj); | ||||
| 						}) | ||||
| 						this.props.status.model.deleteObject(deleteId); | ||||
| 						this.props.status.setFocusObject(new Set<ObjectID>()); | ||||
| 						this.props.status.model.draw(); | ||||
| 					} | ||||
| 				}} | ||||
| 			> | ||||
| 				<Icon iconName="Delete"></Icon> | ||||
| 			</div> | ||||
| 		</Theme> | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| export { ObjectCommand }; | ||||
| @ -1,44 +1,7 @@ | ||||
| @import "../../Component/Theme/Theme.scss"; | ||||
| 
 | ||||
| div.object-list-color-value { | ||||
|     height: calc( 100% - 6px); | ||||
|     margin: 3px 0; | ||||
|     margin-left: 3px; | ||||
|     border-radius: 1000px; | ||||
|     width: 3px; | ||||
| } | ||||
| 
 | ||||
| div.object-list { | ||||
|     min-height: 100%; | ||||
| } | ||||
| 
 | ||||
| div.object-list-command-bar { | ||||
|     width: 100%; | ||||
|     height: 30px; | ||||
|     flex-shrink: 0; | ||||
|     display: flex; | ||||
| 
 | ||||
|     div.command-item{ | ||||
|         width: 30px; | ||||
|         height: 100%; | ||||
|         display: flex; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         user-select: none; | ||||
|         cursor: pointer; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| div.dark.object-list-command-bar { | ||||
| 
 | ||||
|     div.command-item:hover { | ||||
|         background-color: $lt-bg-color-lvl3-dark; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| div.light.object-list-command-bar { | ||||
| 
 | ||||
|     div.command-item:hover { | ||||
|         background-color: $lt-bg-color-lvl3-light; | ||||
|     } | ||||
| } | ||||
| @ -1,14 +1,11 @@ | ||||
| import { Component, ReactNode } from "react"; | ||||
| import { DetailsList } from "@Component/DetailsList/DetailsList"; | ||||
| import { useStatus, IMixinStatusProps } from "@Context/Status"; | ||||
| import { useSetting, IMixinSettingProps } from "@Context/Setting"; | ||||
| import { Localization } from "@Component/Localization/Localization"; | ||||
| import { ObjectID } from "@Model/Renderer"; | ||||
| import "./ObjectList.scss"; | ||||
| 
 | ||||
| @useSetting | ||||
| @useStatus | ||||
| class ObjectList extends Component<IMixinStatusProps & IMixinSettingProps> { | ||||
| class ObjectList extends Component<IMixinStatusProps> { | ||||
| 
 | ||||
|     private handelChange = () => { | ||||
|         this.forceUpdate(); | ||||
| @ -17,14 +14,12 @@ class ObjectList extends Component<IMixinStatusProps & IMixinSettingProps> { | ||||
|     public componentDidMount(){ | ||||
|         if (this.props.status) { | ||||
|             this.props.status.model.on("objectChange", this.handelChange); | ||||
|             this.props.status.on("focusObjectChange", this.handelChange); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public componentWillUnmount(){ | ||||
|         if (this.props.status) { | ||||
|             this.props.status.model.off("objectChange", this.handelChange); | ||||
|             this.props.status.off("focusObjectChange", this.handelChange); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -39,50 +34,15 @@ class ObjectList extends Component<IMixinStatusProps & IMixinSettingProps> { | ||||
|         } | ||||
| 
 | ||||
|         return <DetailsList | ||||
|             className="object-list" | ||||
|             items={objList.concat([]).map((object => { | ||||
|                 return { | ||||
|                     key: object.id.toString(), | ||||
|                     name: object.displayName, | ||||
|                     color: object.color, | ||||
|                     display: object.display, | ||||
|                     update: object.update, | ||||
|                     select: this.props.status ?  | ||||
|                         this.props.status.focusObject.has(object.id.toString()) ||  | ||||
|                         this.props.status.focusObject.has(object.id) : | ||||
|                         false | ||||
|                     update: object.update | ||||
|                 } | ||||
|             }))} | ||||
|             clickLine={(item) => { | ||||
|                 if (this.props.setting) { | ||||
|                     this.props.setting.layout.focus("ObjectList"); | ||||
|                 } | ||||
|                 if (this.props.status) { | ||||
|                     this.props.status.setFocusObject(new Set<ObjectID>().add(item.key)); | ||||
|                 } | ||||
|             }} | ||||
|             checkBox={(item) => { | ||||
|                 if (this.props.setting) { | ||||
|                     this.props.setting.layout.focus("ObjectList"); | ||||
|                 } | ||||
|                 if (this.props.status) { | ||||
|                     if ( | ||||
|                         this.props.status.focusObject.has(item.key.toString()) || | ||||
|                         this.props.status.focusObject.has(item.key) | ||||
|                     ) { | ||||
|                         this.props.status.focusObject.delete(item.key); | ||||
|                         this.props.status.focusObject.delete(item.key.toString()); | ||||
|                         this.props.status.setFocusObject(this.props.status.focusObject); | ||||
|                     } else { | ||||
|                         this.props.status.setFocusObject(this.props.status.focusObject.add(item.key)); | ||||
|                     } | ||||
|                 } | ||||
|             }} | ||||
|             click={() => { | ||||
|                 if (this.props.status) { | ||||
|                     this.props.status.setFocusObject(new Set<ObjectID>()); | ||||
|                 } | ||||
|             }} | ||||
|             columns={[ | ||||
|                 { | ||||
|                     key: "color", | ||||
|  | ||||
| @ -3,13 +3,11 @@ import { Theme } from "@Component/Theme/Theme"; | ||||
| import { Localization } from "@Component/Localization/Localization"; | ||||
| import { RenderView } from "./RenderView/RenderView"; | ||||
| import { ObjectList } from "./ObjectList/ObjectList"; | ||||
| import { ObjectCommand } from "./ObjectList/ObjectCommand"; | ||||
| 
 | ||||
| interface IPanelInfo { | ||||
| 	nameKey: string; | ||||
| 	introKay: string; | ||||
| 	class: (new (...p: any) => Component) | FunctionComponent; | ||||
| 	header?: (new (...p: any) => Component) | FunctionComponent; | ||||
| 	hidePadding?: boolean; | ||||
| 	hideScrollBar?: boolean; | ||||
|     isDeepDark?: boolean; | ||||
| @ -28,7 +26,7 @@ PanelInfoMap.set("RenderView", { | ||||
| }); | ||||
| PanelInfoMap.set("ObjectList", { | ||||
|     nameKey: "Panel.Title.Object.List.View", introKay: "Panel.Info.Object.List.View", | ||||
|     class: ObjectList, header: ObjectCommand, hidePadding: true | ||||
|     class: ObjectList, hidePadding: true | ||||
| }) | ||||
| 
 | ||||
| function getPanelById(panelId: PanelId): ReactNode { | ||||
|  | ||||
| @ -28,7 +28,7 @@ class RenderView extends Component<IMixinStatusProps & IMixinSettingProps> { | ||||
| 
 | ||||
| 	public componentDidMount() { | ||||
| 		let div = this.rootEle.current; | ||||
| 		// console.log(div, div?.childNodes, this.props.status, this.props.status?.renderer.dom)
 | ||||
| 		console.log(div, div?.childNodes, this.props.status, this.props.status?.renderer.dom) | ||||
| 		if (div && (!div.childNodes || div.childNodes.length <= 0) && this.props.status) {	 | ||||
| 			div.appendChild(this.props.status.renderer.dom); | ||||
| 		} | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user