Compare commits
	
		
			3 Commits
		
	
	
		
			24dc1dea3c
			...
			bbeaa037ee
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| bbeaa037ee | |||
| 0bc8bd0192 | |||
| 38b7f1850e | 
| @ -7,7 +7,6 @@ div.app-container { | ||||
| 	height: 100%; | ||||
| 	display: flex; | ||||
| 	overflow: hidden; | ||||
| 	justify-content: center; | ||||
| 	box-sizing: border-box; | ||||
| 
 | ||||
| 	div.drag-bar { | ||||
| @ -22,13 +21,20 @@ div.app-container { | ||||
| 			z-index: 10; | ||||
| 			width: 100%; | ||||
| 			height: 100%; | ||||
| 			border: 4.5px solid rgba($color: #000000, $alpha: 0); | ||||
| 			border: 2px solid rgba($color: #000000, $alpha: 0); | ||||
| 			transition: all 300ms ease-in-out; | ||||
| 		} | ||||
| 
 | ||||
| 		div:hover { | ||||
| 			background-color: blue; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	div.app-tab-header { | ||||
| 		height: $container-header-tab-bar-height; | ||||
| 		flex-shrink: 0; | ||||
| 		min-height: $container-header-tab-bar-height; | ||||
| 		flex-shrink: 1; | ||||
| 		width: 100%; | ||||
| 		display: flex; | ||||
| 		user-select: none; | ||||
| 		 | ||||
| @ -66,6 +72,10 @@ div.app-container { | ||||
| 				vertical-align: middle; | ||||
| 				position: relative; | ||||
| 				transition: all 300ms ease-in-out; | ||||
| 				word-break: keep-all; | ||||
| 				white-space: nowrap; | ||||
| 				overflow: hidden; | ||||
| 				text-overflow: ellipsis; | ||||
| 				z-index: 1; | ||||
| 			} | ||||
| 		} | ||||
| @ -94,6 +104,15 @@ div.app-container { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| div.app-panel { | ||||
| 	overflow: scroll; | ||||
| 	-ms-overflow-style: none; | ||||
| } | ||||
| div.app-panel::-webkit-scrollbar { | ||||
| 	width: 0 !important; | ||||
| 	height: 0 !important; | ||||
| } | ||||
| 
 | ||||
| div.dark.app-container.end-containe { | ||||
| 	border: .8px solid $lt-bg-color-lvl3-dark; | ||||
| 
 | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| import { Theme, BackgroundLevel, FontLevel } from "@Component/Theme/Theme"; | ||||
| import { Themes } from "@Context/Setting"; | ||||
| import { ILayout, LayoutDirection } from "@Model/Layout"; | ||||
| import { Component, ReactNode } from "react"; | ||||
| import "./Container.scss"; | ||||
| @ -6,29 +7,50 @@ import "./Container.scss"; | ||||
| interface IContainerProps extends ILayout { | ||||
| 	showBar?: boolean; | ||||
| 	isRoot?: boolean; | ||||
| 	theme?: Themes; | ||||
| 	focusId?: string; | ||||
| 	onScaleChange?: (id: number, scale: number) => any; | ||||
| } | ||||
| 
 | ||||
| function getPanelById(id: string) { | ||||
| 	return <Theme className="app-panel">{id}</Theme> | ||||
| 	return <Theme | ||||
| 		className="app-panel" draggable={false} | ||||
| 	>{id}</Theme> | ||||
| } | ||||
| 
 | ||||
| class Container extends Component<IContainerProps> { | ||||
| 
 | ||||
| 	private focusEdgeId: number | undefined; | ||||
| 	private readonly edgeInfo = { | ||||
| 		direction: LayoutDirection.Y, | ||||
| 		rootWidth: 0, | ||||
| 		rootHeight: 0, | ||||
| 		edgeWidth: 0, | ||||
| 		edgeHeight: 0, | ||||
| 		mouseX: 0, | ||||
| 		mouseY: 0 | ||||
| 	}; | ||||
| 
 | ||||
| 	private renderPanel(panles: string[], showBar: boolean) { | ||||
| 
 | ||||
| 		const classList: string[] = []; | ||||
| 		const theme: Themes = this.props.theme ?? Themes.dark; | ||||
| 
 | ||||
| 		classList.push(theme === Themes.light ? "light" : "dark"); | ||||
| 		classList.push(`background-${BackgroundLevel.Level3}`); | ||||
| 		classList.push(`font-${FontLevel.Level3}`); | ||||
| 		classList.push("app-tab-header"); | ||||
| 
 | ||||
| 		return <> | ||||
| 			{showBar ?  | ||||
| 				<Theme | ||||
| 					className="app-tab-header" | ||||
| 					backgroundLevel={BackgroundLevel.Level3} | ||||
| 					fontLevel={FontLevel.Level3} | ||||
| 				>{ | ||||
| 				<div className={classList.join(" ")} >{ | ||||
| 					panles.map((panelId: string) => { | ||||
| 						return <div key={panelId} className="app-tab-header-item"> | ||||
| 							<div className="border-view"></div> | ||||
| 							<div className="title-view" >{panelId}</div> | ||||
| 						</div> | ||||
| 					}) | ||||
| 				}</Theme> : null | ||||
| 				}</div> : null | ||||
| 			} | ||||
| 			{getPanelById(panles[0])} | ||||
| 		</> | ||||
| @ -46,16 +68,56 @@ class Container extends Component<IContainerProps> { | ||||
| 		const layout: LayoutDirection = props.layout ?? LayoutDirection.Y; | ||||
| 		const scale: number = props.scale ?? 50; | ||||
| 		const isRoot: boolean = !!props.isRoot; | ||||
| 		const classList: string[] = []; | ||||
| 		const theme: Themes = this.props.theme ?? Themes.dark; | ||||
| 
 | ||||
| 		return <Theme | ||||
| 			className={"app-container" + (panles.length > 0 && !items ? " end-containe" : "")} | ||||
| 			backgroundLevel={BackgroundLevel.Level4} | ||||
| 			fontLevel={FontLevel.normal} | ||||
| 		classList.push(theme === Themes.light ? "light" : "dark"); | ||||
| 		classList.push(`background-${BackgroundLevel.Level4}`); | ||||
| 		classList.push(`font-${FontLevel.normal}`); | ||||
| 		classList.push("app-container"); | ||||
| 		if (panles.length > 0 && !items) classList.push("end-containe"); | ||||
| 
 | ||||
| 		return <div | ||||
| 			className={classList.join(" ")} | ||||
| 			draggable={false} | ||||
| 			style={{ | ||||
| 				transition: "none", | ||||
| 				flexDirection: layout === LayoutDirection.Y ? "column" : undefined, | ||||
| 				width: isRoot ? "100%" : selfLayout === LayoutDirection.X ? `${selfScale}%` : undefined, | ||||
| 				height: isRoot ? "100%" : selfLayout === LayoutDirection.Y ? `${selfScale}%` : undefined | ||||
| 			}} | ||||
| 			onMouseMove={isRoot ? (e) => { | ||||
| 				if (this.props.onScaleChange && this.focusEdgeId !== undefined) { | ||||
| 					e.preventDefault(); | ||||
| 					let mouveDist: number = 0; | ||||
| 					let rootSize: number = 0; | ||||
| 					let edgeSize: number = 0; | ||||
| 					let newSize: number = 0; | ||||
| 
 | ||||
| 					if (this.edgeInfo.direction === LayoutDirection.X) { | ||||
| 						mouveDist = e.clientX - this.edgeInfo.mouseX; | ||||
| 						rootSize = this.edgeInfo.rootWidth; | ||||
| 						edgeSize = this.edgeInfo.edgeWidth; | ||||
| 						newSize = edgeSize + mouveDist; | ||||
| 					} | ||||
| 
 | ||||
| 					if (this.edgeInfo.direction === LayoutDirection.Y) { | ||||
| 						mouveDist = e.clientY - this.edgeInfo.mouseY; | ||||
| 						rootSize = this.edgeInfo.rootHeight; | ||||
| 						edgeSize = this.edgeInfo.edgeHeight | ||||
| 						newSize = edgeSize + mouveDist;	 | ||||
| 					} | ||||
| 
 | ||||
| 					if (newSize < 38) { newSize = 38; } | ||||
| 					if ((rootSize - newSize) < 38) { newSize = rootSize - 38; } | ||||
| 
 | ||||
| 					let newScale = newSize / rootSize; | ||||
| 					this.props.onScaleChange(this.focusEdgeId, newScale * 100); | ||||
| 				} | ||||
| 			} : undefined} | ||||
| 			onMouseUp={isRoot ? () => { | ||||
| 				this.focusEdgeId = undefined; | ||||
| 			} : undefined} | ||||
| 		> | ||||
| 			{panles.length > 0 && !items ? this.renderPanel(panles, showBar) : null} | ||||
| 			{items && items[0] ? this.renderContainer(items[0], scale, layout) : null} | ||||
| @ -63,13 +125,32 @@ class Container extends Component<IContainerProps> { | ||||
| 				width: layout === LayoutDirection.Y ? "100%" : 0, | ||||
| 				height: layout === LayoutDirection.X ? "100%" : 0 | ||||
| 			}}> | ||||
| 				<div style={{ | ||||
| 					cursor: layout === LayoutDirection.Y ? "n-resize" : "e-resize" | ||||
| 				}}> | ||||
| 				<div | ||||
| 					style={{ cursor: layout === LayoutDirection.Y ? "n-resize" : "e-resize" }} | ||||
| 					onMouseDown={(e) => { | ||||
| 						const targetNode = e.target; | ||||
| 						if (targetNode instanceof HTMLDivElement) { | ||||
| 							let root = targetNode.parentNode?.parentNode; | ||||
| 							let firstDiv = targetNode.parentNode?.parentNode?.childNodes[0]; | ||||
| 
 | ||||
| 							if (root instanceof HTMLDivElement && firstDiv instanceof HTMLDivElement) { | ||||
| 								this.edgeInfo.rootWidth = root.offsetWidth; | ||||
| 								this.edgeInfo.rootHeight = root.offsetHeight; | ||||
| 								this.edgeInfo.edgeWidth = firstDiv.offsetWidth; | ||||
| 								this.edgeInfo.edgeHeight = firstDiv.offsetHeight; | ||||
| 							} | ||||
| 						} | ||||
| 						this.edgeInfo.mouseX = e.clientX; | ||||
| 						this.edgeInfo.mouseY = e.clientY; | ||||
| 						this.edgeInfo.direction = props.layout ?? LayoutDirection.Y; | ||||
| 						this.focusEdgeId = props.id ?? 0; | ||||
| 					}} | ||||
| 					onMouseUp={() => { this.focusEdgeId = undefined }} | ||||
| 				> | ||||
| 				</div> | ||||
| 			</div> : null} | ||||
| 			{items && items[1] ? this.renderContainer(items[1], 100 - scale, layout) : null} | ||||
| 		</Theme> | ||||
| 		</div> | ||||
| 	} | ||||
| 
 | ||||
| 	public render(): ReactNode { | ||||
|  | ||||
							
								
								
									
										43
									
								
								source/Component/Container/RootContainer.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								source/Component/Container/RootContainer.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| import { Component, ReactNode } from "react"; | ||||
| import { useSetting, IMixinSettingProps, Themes } from "@Context/Setting"; | ||||
| import { Container } from "./Container"; | ||||
| 
 | ||||
| @useSetting | ||||
| class RootContainer extends Component<IMixinSettingProps> { | ||||
| 
 | ||||
| 	private handelChange = () => { | ||||
| 		this.forceUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| 	public componentDidMount() { | ||||
| 		if (this.props.setting) { | ||||
| 			this.props.setting.layout.on("layoutChange", this.handelChange); | ||||
| 			this.props.setting.layout.on("scaleChange", this.handelChange); | ||||
| 			this.props.setting.on("themes", this.handelChange); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public componentWillUnmount() { | ||||
| 		if (this.props.setting) { | ||||
| 			this.props.setting.layout.off("layoutChange", this.handelChange); | ||||
| 			this.props.setting.layout.off("scaleChange", this.handelChange); | ||||
| 			this.props.setting.off("themes", this.handelChange); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public render(): ReactNode { | ||||
| 		const layoutData = this.props.setting ? this.props.setting.layout.getData() : {}; | ||||
| 		const theme = this.props.setting?.themes ?? Themes.dark; | ||||
| 		return <Container | ||||
| 			scale={layoutData.scale} | ||||
| 			items={layoutData.items} | ||||
| 			layout={layoutData.layout} | ||||
| 			theme={theme} | ||||
| 			isRoot={true} | ||||
| 			onScaleChange={this.props.setting?.layout.setScale} | ||||
| 			id={layoutData.id} | ||||
| 		/> | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| export { RootContainer } | ||||
| @ -1,5 +1,6 @@ | ||||
| import { createContext, Component, FunctionComponent } from "react"; | ||||
| import { Emitter } from "@Model/Emitter"; | ||||
| import { Layout } from "@Model/Layout"; | ||||
| 
 | ||||
| /** | ||||
|  * 主题模式 | ||||
| @ -25,6 +26,11 @@ class Setting extends Emitter< | ||||
|      */ | ||||
|     public language: Language = "EN_US"; | ||||
| 
 | ||||
|     /** | ||||
|      * 布局 | ||||
|      */ | ||||
|     public layout: Layout = new Layout(); | ||||
| 
 | ||||
|     /** | ||||
|      * 设置参数 | ||||
|      */ | ||||
|  | ||||
| @ -10,12 +10,58 @@ class ILayout { | ||||
| 	panles?: string[]; | ||||
| 	layout?: LayoutDirection; | ||||
| 	scale?: number; | ||||
| 	id?: number; | ||||
| } | ||||
| 
 | ||||
| class Layout extends Emitter<{}> { | ||||
| interface ILayoutEvent { | ||||
| 	layoutChange: Layout; | ||||
| 	scaleChange: Layout; | ||||
| } | ||||
| 
 | ||||
| class Layout extends Emitter<ILayoutEvent> { | ||||
| 
 | ||||
| 	private id: number = 0; | ||||
| 
 | ||||
| 	private data: ILayout = {}; | ||||
| 
 | ||||
| 	private map(fn: (layout: ILayout) => boolean | void, layout?: ILayout) { | ||||
| 		const currentLayout = layout ? layout : this.data; | ||||
| 		if( fn(currentLayout) ) return; | ||||
| 		if (currentLayout.items && currentLayout.items[0]) { | ||||
| 			this.map(fn, currentLayout.items[0]); | ||||
| 		} | ||||
| 		if (currentLayout.items && currentLayout.items[1]) { | ||||
| 			this.map(fn, currentLayout.items[1]); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public getData = (): ILayout => { | ||||
| 		return this.data; | ||||
| 	} | ||||
| 
 | ||||
| 	public setData = (data: ILayout) => { | ||||
| 		this.data = data; | ||||
| 		this.id = 0; | ||||
| 		this.map((layout) => { | ||||
| 			layout.id = this.id; | ||||
| 			this.id ++; | ||||
| 		}); | ||||
| 		this.emit("layoutChange", this); | ||||
| 	} | ||||
| 
 | ||||
| 	public setScale = (id: number, scale: number) => { | ||||
| 		let change = false; | ||||
| 		this.map((layout) => { | ||||
| 			if (layout.id === id) { | ||||
| 				layout.scale = scale; | ||||
| 				change = true;	 | ||||
| 			} | ||||
| 			return change; | ||||
| 		}) | ||||
| 		if (change) { | ||||
| 			this.emit("scaleChange", this); | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| export { Layout, ILayout, LayoutDirection }; | ||||
| @ -6,7 +6,7 @@ import { Entry } from "../Entry/Entry"; | ||||
| import { StatusProvider, Status } from "@Context/Status"; | ||||
| import { ClassicRenderer } from "@GLRender/ClassicRenderer"; | ||||
| import { initializeIcons } from '@fluentui/font-icons-mdl2'; | ||||
| import { Container } from "@Component/Container/Container"; | ||||
| import { RootContainer } from "@Component/Container/RootContainer"; | ||||
| import { LayoutDirection } from "@Model/Layout"; | ||||
| import "./SimulatorWeb.scss"; | ||||
| import { CommandBar } from "@Component/CommandBar/CommandBar"; | ||||
| @ -55,26 +55,9 @@ class SimulatorWeb extends Component { | ||||
|         (window as any).s = this; | ||||
|     } | ||||
| 
 | ||||
|     public render(): ReactNode { | ||||
|         return <SettingProvider value={this.setting}> | ||||
|             <StatusProvider value={this.status}> | ||||
|                 {this.renderContent()} | ||||
|             </StatusProvider> | ||||
|         </SettingProvider> | ||||
|     } | ||||
| 
 | ||||
|     private renderContent(): ReactNode { | ||||
|         return <Theme  | ||||
|             className="app-root" | ||||
|             backgroundLevel={BackgroundLevel.Level5} | ||||
|             fontLevel={FontLevel.Level3} | ||||
|         > | ||||
|             <HeaderBar height={45}/> | ||||
|             <div className="app-root-space" style={{ | ||||
|                 height: `calc( 100% - ${45}px)` | ||||
|             }}> | ||||
|                 <CommandBar width={45}/> | ||||
|                 <Container items={[ | ||||
|     public componentDidMount() { | ||||
|         this.setting.layout.setData({ | ||||
|             items: [ | ||||
|                 { | ||||
|                     items: [ | ||||
|                         {panles: ["Label A", "Label Aa Bb", "Label aaa"]}, | ||||
| @ -96,11 +79,32 @@ class SimulatorWeb extends Component { | ||||
|                     }], | ||||
|                     layout: LayoutDirection.Y | ||||
|                 } | ||||
|                     ]} | ||||
|                     scale={60} | ||||
|                     layout={LayoutDirection.X} | ||||
|                     isRoot={true} | ||||
|                 /> | ||||
|             ], | ||||
|             scale: 60, | ||||
|             layout: LayoutDirection.X | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     public render(): ReactNode { | ||||
|         return <SettingProvider value={this.setting}> | ||||
|             <StatusProvider value={this.status}> | ||||
|                 {this.renderContent()} | ||||
|             </StatusProvider> | ||||
|         </SettingProvider> | ||||
|     } | ||||
| 
 | ||||
|     private renderContent(): ReactNode { | ||||
|         return <Theme  | ||||
|             className="app-root" | ||||
|             backgroundLevel={BackgroundLevel.Level5} | ||||
|             fontLevel={FontLevel.Level3} | ||||
|         > | ||||
|             <HeaderBar height={45}/> | ||||
|             <div className="app-root-space" style={{ | ||||
|                 height: `calc( 100% - ${45}px)` | ||||
|             }}> | ||||
|                 <CommandBar width={45}/> | ||||
|                 <RootContainer /> | ||||
|             </div> | ||||
|         </Theme> | ||||
|     } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user