diff --git a/source/Component/Container/Container.scss b/source/Component/Container/Container.scss index a21aeab..6f6609d 100644 --- a/source/Component/Container/Container.scss +++ b/source/Component/Container/Container.scss @@ -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; diff --git a/source/Component/Container/Container.tsx b/source/Component/Container/Container.tsx index cc9ee54..1c88ed0 100644 --- a/source/Component/Container/Container.tsx +++ b/source/Component/Container/Container.tsx @@ -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 {id} + return {id} } class Container extends Component { + 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 ? - { +
{ panles.map((panelId: string) => { return
{panelId}
}) - } : null + }
: null } {getPanelById(panles[0])} @@ -46,16 +68,56 @@ class Container extends Component { 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 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
{ + 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 { width: layout === LayoutDirection.Y ? "100%" : 0, height: layout === LayoutDirection.X ? "100%" : 0 }}> -
+
{ + 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 }} + >
: null} {items && items[1] ? this.renderContainer(items[1], 100 - scale, layout) : null} - +
} public render(): ReactNode { diff --git a/source/Component/Container/RootContainer.tsx b/source/Component/Container/RootContainer.tsx new file mode 100644 index 0000000..c80d1fa --- /dev/null +++ b/source/Component/Container/RootContainer.tsx @@ -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 { + + 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 + } +} + +export { RootContainer } \ No newline at end of file diff --git a/source/Context/Setting.tsx b/source/Context/Setting.tsx index f2d9797..eacc522 100644 --- a/source/Context/Setting.tsx +++ b/source/Context/Setting.tsx @@ -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(); + /** * 设置参数 */ diff --git a/source/Model/Layout.ts b/source/Model/Layout.ts index 5d6b224..5ce21ac 100644 --- a/source/Model/Layout.ts +++ b/source/Model/Layout.ts @@ -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 { + + 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 }; \ No newline at end of file diff --git a/source/Page/SimulatorWeb/SimulatorWeb.tsx b/source/Page/SimulatorWeb/SimulatorWeb.tsx index 8fef91d..e26e1a7 100644 --- a/source/Page/SimulatorWeb/SimulatorWeb.tsx +++ b/source/Page/SimulatorWeb/SimulatorWeb.tsx @@ -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,6 +55,36 @@ class SimulatorWeb extends Component { (window as any).s = this; } + public componentDidMount() { + this.setting.layout.setData({ + items: [ + { + items: [ + {panles: ["Label A", "Label Aa Bb", "Label aaa"]}, + { + items: [{panles: ["Label b", "Label bbb"]}, {panles: ["C"]}], + scale: 80, + layout: LayoutDirection.X + } + ], + scale: 60, + layout: LayoutDirection.Y + }, + { + items: [{ + panles: ["Label d"] + }, { + items: [{panles: ["Label e", "ee"]}, {panles: ["F"]}], + layout: LayoutDirection.Y + }], + layout: LayoutDirection.Y + } + ], + scale: 60, + layout: LayoutDirection.X + }) + } + public render(): ReactNode { return @@ -74,33 +104,7 @@ class SimulatorWeb extends Component { height: `calc( 100% - ${45}px)` }}> - +
}