Compare commits
	
		
			No commits in common. "90398b593e6f9f54794023e198aab60ddd9ad87f" and "04060902e0d7f2d47c484616ed301d175b8e870e" have entirely different histories.
		
	
	
		
			90398b593e
			...
			04060902e0
		
	
		
| @ -68,13 +68,7 @@ class CommandBar extends Component<ICommandBarProps & IMixinSettingProps & IMixi | |||||||
|                 {this.getRenderButton({ iconName: "Camera", i18NKey: "Command.Bar.Camera.Info" })} |                 {this.getRenderButton({ iconName: "Camera", i18NKey: "Command.Bar.Camera.Info" })} | ||||||
|             </div> |             </div> | ||||||
|             <div> |             <div> | ||||||
|                 {this.getRenderButton({ |                 {this.getRenderButton({ iconName: "Settings", i18NKey: "Command.Bar.Setting.Info" })} | ||||||
|                     iconName: "Settings", |  | ||||||
|                     i18NKey: "Command.Bar.Setting.Info", |  | ||||||
|                     click: () => { |  | ||||||
|                         this.props.status ? this.props.status.popup.showPopup() : undefined; |  | ||||||
|                     } |  | ||||||
|                 })} |  | ||||||
|             </div> |             </div> | ||||||
|         </Theme> |         </Theme> | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -2,8 +2,8 @@ import { Component, ReactNode, DetailedHTMLProps, HTMLAttributes } from "react"; | |||||||
| import { useSetting, IMixinSettingProps, Language } from "@Context/Setting"; | import { useSetting, IMixinSettingProps, Language } from "@Context/Setting"; | ||||||
| import "./Localization.scss"; | import "./Localization.scss"; | ||||||
| 
 | 
 | ||||||
| import EN_US from "@Localization/EN-US"; | import EN_US from "../../Localization/EN-US"; | ||||||
| import ZH_CN from "@Localization/ZH-CN"; | import ZH_CN from "../../Localization/ZH-CN"; | ||||||
| 
 | 
 | ||||||
| const LanguageDataBase = { | const LanguageDataBase = { | ||||||
|     EN_US, ZH_CN |     EN_US, ZH_CN | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import { AllI18nKeys, I18N } from "@Component/Localization/Localization"; | import { AllI18nKeys, I18N } from "@Component/Localization/Localization"; | ||||||
| import { useSettingWithEvent, IMixinSettingProps, Themes, Language } from "@Context/Setting"; | import { useStatusWithEvent, IMixinSettingProps, Themes, Language } from "@Context/Setting"; | ||||||
| import { FunctionComponent } from "react"; | import { FunctionComponent } from "react"; | ||||||
| import "./Message.scss"; | import "./Message.scss"; | ||||||
| 
 | 
 | ||||||
| @ -38,5 +38,5 @@ const MessageView: FunctionComponent<IMessageProps & IMixinSettingProps> = (prop | |||||||
|     </div> |     </div> | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const Message = useSettingWithEvent("language", "themes")(MessageView); | const Message = useStatusWithEvent("language", "themes")(MessageView); | ||||||
| export { Message }; | export { Message }; | ||||||
| @ -1,71 +0,0 @@ | |||||||
| @import "../Theme/Theme.scss"; |  | ||||||
| 
 |  | ||||||
| @keyframes show-scale{ |  | ||||||
|     from { |  | ||||||
|         transform: scale3d(1.15, 1.15, 1); |  | ||||||
|     } |  | ||||||
|     to { |  | ||||||
|         transform: scale3d(1, 1, 1); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| @keyframes show-fade{ |  | ||||||
|     from { |  | ||||||
|         opacity: 0; |  | ||||||
|     } |  | ||||||
|     to { |  | ||||||
|         opacity: 1; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| div.popup-mask.show-fade { |  | ||||||
|     animation: show-fade .1s cubic-bezier(0, 0, 1, 1) both; |  | ||||||
|     opacity: 1; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| div.popup-layer.show-scale { |  | ||||||
|     animation: show-scale .3s cubic-bezier(.1, .9, .2, 1) both, |  | ||||||
|     show-fade .1s cubic-bezier(0, 0, 1, 1) both; |  | ||||||
|     transform: scale3d(1, 1, 1); |  | ||||||
|     opacity: 1; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| div.popup-mask { |  | ||||||
|     position: absolute; |  | ||||||
|     cursor: pointer; |  | ||||||
|     width: 100%; |  | ||||||
|     height: 100%; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| div.popup-layer { |  | ||||||
|     position: absolute; |  | ||||||
|     border-radius: 3px; |  | ||||||
|     overflow: hidden; |  | ||||||
| 
 |  | ||||||
|     div.popup-layer-header { |  | ||||||
|         min-height: 32px; |  | ||||||
|         max-height: 32px; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| div.popup-layer.dark { |  | ||||||
| 
 |  | ||||||
|     div.popup-layer-header { |  | ||||||
|         background-color: $lt-bg-color-lvl3-dark; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| div.popup-layer.light { |  | ||||||
| 
 |  | ||||||
|     div.popup-layer-header { |  | ||||||
|         background-color: $lt-bg-color-lvl3-light; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| div.dark.popup-mask { |  | ||||||
|     background-color: rgba(0, 0, 0, 0.55); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| div.light.popup-mask { |  | ||||||
|     background-color: rgba(0, 0, 0, 0.15); |  | ||||||
| } |  | ||||||
| @ -1,97 +0,0 @@ | |||||||
| import { Component, ReactNode } from "react"; |  | ||||||
| import { IMixinStatusProps, useStatusWithEvent } from "@Context/Status"; |  | ||||||
| import { BackgroundLevel, Theme } from "@Component/Theme/Theme"; |  | ||||||
| import { Popup as PopupModel } from "@Context/Popups"; |  | ||||||
| import "./Popup.scss"; |  | ||||||
| 
 |  | ||||||
| interface IPopupProps {} |  | ||||||
| 
 |  | ||||||
| @useStatusWithEvent("popupChange") |  | ||||||
| class Popup extends Component<IPopupProps & IMixinStatusProps> { |  | ||||||
| 
 |  | ||||||
|     public renderMask(index?: number, click?: () => void, key?: string): ReactNode { |  | ||||||
|         const classList: string[] = ["popup-mask", "show-fade"]; |  | ||||||
|         return <Theme |  | ||||||
|             key={key} |  | ||||||
|             onClick={click} |  | ||||||
|             className={classList.join(" ")} |  | ||||||
|             style={{ |  | ||||||
|                 zIndex: index, |  | ||||||
|             }} |  | ||||||
|         /> |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public renderRootMask(): ReactNode { |  | ||||||
|         if (this.props.status) { |  | ||||||
|             const needMask = this.props.status.popup.popups.some(popup => popup.needMask); |  | ||||||
|             if (!needMask) return null; |  | ||||||
|             return this.renderMask(this.props.status.popup.zIndex, |  | ||||||
|                 () => { |  | ||||||
|                     this.props.status?.popup.popups.forEach( |  | ||||||
|                         popup => popup.onClose() |  | ||||||
|                     ) |  | ||||||
|                 } |  | ||||||
|             ); |  | ||||||
|         } else { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public renderMaskList(): ReactNode { |  | ||||||
|         if (this.props.status) { |  | ||||||
|             return this.props.status.popup.popups |  | ||||||
|             .filter((popup) => { |  | ||||||
|                 return popup.needMask && popup.maskForSelf; |  | ||||||
|             }) |  | ||||||
|             .filter((_, index) => { |  | ||||||
|                 if (index === 0) return false; |  | ||||||
|                 return true; |  | ||||||
|             }) |  | ||||||
|             .map((popup) => { |  | ||||||
|                 return this.renderMask(popup.zIndex() - 1, |  | ||||||
|                     () => { |  | ||||||
|                         popup.onClose(); |  | ||||||
|                     }, popup.id |  | ||||||
|                 ); |  | ||||||
|             }) |  | ||||||
|         } else { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public renderLayer(popup: PopupModel) { |  | ||||||
|         const pageWidth = document.documentElement.clientWidth; |  | ||||||
|         const pageHeight = document.documentElement.clientHeight; |  | ||||||
|         const top = (pageHeight - popup.height) / 2; |  | ||||||
|         const left = (pageWidth - popup.width) / 2; |  | ||||||
| 
 |  | ||||||
|         return <Theme |  | ||||||
|             style={{ |  | ||||||
|                 width: popup.width, |  | ||||||
|                 height: popup.height, |  | ||||||
|                 zIndex: popup.zIndex(), |  | ||||||
|                 top: top, |  | ||||||
|                 left: left |  | ||||||
|             }} |  | ||||||
|             key={popup.id} |  | ||||||
|             backgroundLevel={BackgroundLevel.Level4} |  | ||||||
|             className="popup-layer show-scale" |  | ||||||
|         > |  | ||||||
|             <div className="popup-layer-header"> |  | ||||||
|                  |  | ||||||
|             </div> |  | ||||||
|         </Theme> |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public render(): ReactNode { |  | ||||||
|         return <> |  | ||||||
|             {this.renderRootMask()} |  | ||||||
|             {this.renderMaskList()} |  | ||||||
|             {this.props.status?.popup.popups.map((popup) => { |  | ||||||
|                 return this.renderLayer(popup); |  | ||||||
|             })} |  | ||||||
|         </>; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export { Popup }; |  | ||||||
| @ -8,33 +8,11 @@ type IPopupConstructor = new (controller: PopupController, id: string) => Popup; | |||||||
|  */ |  */ | ||||||
| class Popup { | class Popup { | ||||||
| 
 | 
 | ||||||
|     public zIndex() { |  | ||||||
|         return this.index * 2 + this.controller.zIndex; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public width: number = 300; |  | ||||||
| 
 |  | ||||||
|     public height: number = 200; |  | ||||||
| 
 |  | ||||||
|     public top: number = 0; |  | ||||||
| 
 |  | ||||||
|     public left: number = 0; |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * 是否关闭 |      * 是否关闭 | ||||||
|      */ |      */ | ||||||
|     public isClose: boolean = false; |     public isClose: boolean = false; | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * 需要蒙版 |  | ||||||
|      */ |  | ||||||
|     public needMask: boolean = true; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 单独遮挡下层的蒙版 |  | ||||||
|      */ |  | ||||||
|     public maskForSelf: boolean = false; |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * 唯一标识符 |      * 唯一标识符 | ||||||
|      */ |      */ | ||||||
| @ -58,29 +36,18 @@ class Popup { | |||||||
|     /** |     /** | ||||||
|      * 渲染函数 |      * 渲染函数 | ||||||
|      */ |      */ | ||||||
|     public onRender(p: Popup): ReactNode { |     public rendererFunction: undefined | ((p: Popup) => ReactNode); | ||||||
|         return null; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 关闭回调 |  | ||||||
|      */ |  | ||||||
|     public onClose(): void { |  | ||||||
|         this.close(); |  | ||||||
|     }; |  | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * 渲染节点 |      * 渲染节点 | ||||||
|      */ |      */ | ||||||
|     public render(): ReactNode { |     public render(): ReactNode { | ||||||
|         this.reactNode = this.onRender(this); |         if (this.rendererFunction) { | ||||||
|  |             this.reactNode = this.rendererFunction(this); | ||||||
|  |         } | ||||||
|         return this.reactNode; |         return this.reactNode; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     public close() { |  | ||||||
|         return this.controller.closePopup(this); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public constructor(controller: PopupController, id: string) { |     public constructor(controller: PopupController, id: string) { | ||||||
|         this.controller = controller; |         this.controller = controller; | ||||||
|         this.id = id; |         this.id = id; | ||||||
| @ -101,11 +68,6 @@ class PopupController extends Emitter<IPopupControllerEvent> { | |||||||
|      */ |      */ | ||||||
|     private idIndex = 0; |     private idIndex = 0; | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * 最小弹窗 Index |  | ||||||
|      */ |  | ||||||
|     public zIndex = 100; |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * 弹窗列表 |      * 弹窗列表 | ||||||
|      */ |      */ | ||||||
| @ -120,7 +82,6 @@ class PopupController extends Emitter<IPopupControllerEvent> { | |||||||
|             popup.index = (index + 1); |             popup.index = (index + 1); | ||||||
|             return popup; |             return popup; | ||||||
|         }); |         }); | ||||||
|         this.emit("popupChange"); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -129,7 +90,7 @@ class PopupController extends Emitter<IPopupControllerEvent> { | |||||||
|     public showPopup<P extends IPopupConstructor>(popup?: P): Popup { |     public showPopup<P extends IPopupConstructor>(popup?: P): Popup { | ||||||
|         let newPopup = new (popup ?? Popup)(this, `P-${this.idIndex ++}`); |         let newPopup = new (popup ?? Popup)(this, `P-${this.idIndex ++}`); | ||||||
|         this.popups.push(newPopup); |         this.popups.push(newPopup); | ||||||
|         this.sortPopup(); |         this.emit("popupChange"); | ||||||
|         return newPopup; |         return newPopup; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -149,7 +110,6 @@ class PopupController extends Emitter<IPopupControllerEvent> { | |||||||
|                 let isDelete = currentPopup.id === id; |                 let isDelete = currentPopup.id === id; | ||||||
|                 if (isDelete) { |                 if (isDelete) { | ||||||
|                     closePopup = currentPopup; |                     closePopup = currentPopup; | ||||||
|                     currentPopup.isClose = true; |  | ||||||
|                     return false; |                     return false; | ||||||
|                 } else { |                 } else { | ||||||
|                     return true; |                     return true; | ||||||
| @ -157,7 +117,6 @@ class PopupController extends Emitter<IPopupControllerEvent> { | |||||||
|             } |             } | ||||||
|         ); |         ); | ||||||
|         if (closePopup) { |         if (closePopup) { | ||||||
|             this.sortPopup(); |  | ||||||
|             this.emit("popupChange"); |             this.emit("popupChange"); | ||||||
|         } |         } | ||||||
|         return closePopup; |         return closePopup; | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ enum Themes { | |||||||
| type Language = "ZH_CN" | "EN_US"; | type Language = "ZH_CN" | "EN_US"; | ||||||
| 
 | 
 | ||||||
| interface ISettingEvents extends Setting { | interface ISettingEvents extends Setting { | ||||||
|     attrChange: keyof Setting; |     change: keyof Setting; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class Setting extends Emitter<ISettingEvents> { | class Setting extends Emitter<ISettingEvents> { | ||||||
| @ -39,7 +39,7 @@ class Setting extends Emitter<ISettingEvents> { | |||||||
|      */ |      */ | ||||||
|     public setProps<P extends keyof Setting>(key: P, value: Setting[P]) { |     public setProps<P extends keyof Setting>(key: P, value: Setting[P]) { | ||||||
|         this[key] = value as any; |         this[key] = value as any; | ||||||
|         this.emit("attrChange", key); |         this.emit("change", key); | ||||||
|         this.emit(key as any, value as any); |         this.emit(key as any, value as any); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -59,9 +59,9 @@ const SettingConsumer = SettingContext.Consumer; | |||||||
|  */ |  */ | ||||||
| const useSetting = superConnect<Setting>(SettingConsumer, "setting"); | const useSetting = superConnect<Setting>(SettingConsumer, "setting"); | ||||||
| 
 | 
 | ||||||
| const useSettingWithEvent = superConnectWithEvent<Setting, ISettingEvents>(SettingConsumer, "setting"); | const useStatusWithEvent = superConnectWithEvent<Setting, ISettingEvents>(SettingConsumer, "setting"); | ||||||
| 
 | 
 | ||||||
| export { | export { | ||||||
|     Themes, Setting, SettingContext, useSetting, Language, useSettingWithEvent, |     Themes, Setting, SettingContext, useSetting, Language, useStatusWithEvent, | ||||||
|     IMixinSettingProps, SettingProvider, SettingConsumer |     IMixinSettingProps, SettingProvider, SettingConsumer | ||||||
| }; | }; | ||||||
| @ -1,4 +1,4 @@ | |||||||
| import { createContext } from "react"; | import { createContext, Component, FunctionComponent, ReactNode } from "react"; | ||||||
| import { Emitter } from "@Model/Emitter"; | import { Emitter } from "@Model/Emitter"; | ||||||
| import { Model, ObjectID } from "@Model/Model"; | import { Model, ObjectID } from "@Model/Model"; | ||||||
| import { Label } from "@Model/Label"; | import { Label } from "@Model/Label"; | ||||||
| @ -10,7 +10,6 @@ import { ClassicRenderer, MouseMod } from "@GLRender/ClassicRenderer"; | |||||||
| import { Setting } from "./Setting"; | import { Setting } from "./Setting"; | ||||||
| import { I18N } from "@Component/Localization/Localization"; | import { I18N } from "@Component/Localization/Localization"; | ||||||
| import { superConnectWithEvent, superConnect } from "./Context"; | import { superConnectWithEvent, superConnect } from "./Context"; | ||||||
| import { PopupController } from "./Popups"; |  | ||||||
| 
 | 
 | ||||||
| function randomColor(unNormal: boolean = false) { | function randomColor(unNormal: boolean = false) { | ||||||
|     const color = [ |     const color = [ | ||||||
| @ -40,7 +39,6 @@ interface IStatusEvent { | |||||||
|     labelAttrChange: void; |     labelAttrChange: void; | ||||||
|     groupAttrChange: void; |     groupAttrChange: void; | ||||||
|     individualChange: void; |     individualChange: void; | ||||||
|     popupChange: void; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class Status extends Emitter<IStatusEvent> { | class Status extends Emitter<IStatusEvent> { | ||||||
| @ -68,11 +66,6 @@ class Status extends Emitter<IStatusEvent> { | |||||||
|      */ |      */ | ||||||
|     public model: Model = new Model(); |     public model: Model = new Model(); | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * 弹窗 |  | ||||||
|      */ |  | ||||||
|     public popup: PopupController = new PopupController(); |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * 焦点对象 |      * 焦点对象 | ||||||
|      */ |      */ | ||||||
| @ -103,9 +96,6 @@ class Status extends Emitter<IStatusEvent> { | |||||||
|         this.model.on("objectChange", () => this.emit("objectChange")); |         this.model.on("objectChange", () => this.emit("objectChange")); | ||||||
|         this.model.on("labelChange", () => this.emit("labelChange")); |         this.model.on("labelChange", () => this.emit("labelChange")); | ||||||
| 
 | 
 | ||||||
|         // 弹窗事件
 |  | ||||||
|         this.popup.on("popupChange", () => this.emit("popupChange")); |  | ||||||
| 
 |  | ||||||
|         // 对象变换时执行渲染,更新渲染器数据
 |         // 对象变换时执行渲染,更新渲染器数据
 | ||||||
|         this.on("objectChange", this.delayDraw); |         this.on("objectChange", this.delayDraw); | ||||||
|         this.model.on("individualChange", this.delayDraw); |         this.model.on("individualChange", this.delayDraw); | ||||||
|  | |||||||
| @ -9,7 +9,6 @@ import { initializeIcons } from '@fluentui/font-icons-mdl2'; | |||||||
| import { RootContainer } from "@Component/Container/RootContainer"; | import { RootContainer } from "@Component/Container/RootContainer"; | ||||||
| import { LayoutDirection } from "@Context/Layout"; | import { LayoutDirection } from "@Context/Layout"; | ||||||
| import { CommandBar } from "@Component/CommandBar/CommandBar"; | import { CommandBar } from "@Component/CommandBar/CommandBar"; | ||||||
| import { Popup } from "@Component/Popup/Popup"; |  | ||||||
| import "./SimulatorWeb.scss"; | import "./SimulatorWeb.scss"; | ||||||
| 
 | 
 | ||||||
| initializeIcons("https://img.mrkbear.com/fabric-cdn-prod_20210407.001/"); | initializeIcons("https://img.mrkbear.com/fabric-cdn-prod_20210407.001/"); | ||||||
| @ -102,7 +101,6 @@ class SimulatorWeb extends Component { | |||||||
|             backgroundLevel={BackgroundLevel.Level5} |             backgroundLevel={BackgroundLevel.Level5} | ||||||
|             fontLevel={FontLevel.Level3} |             fontLevel={FontLevel.Level3} | ||||||
|         > |         > | ||||||
|             <Popup/> |  | ||||||
|             <HeaderBar height={45}/> |             <HeaderBar height={45}/> | ||||||
|             <div className="app-root-space" style={{ |             <div className="app-root-space" style={{ | ||||||
|                 height: `calc( 100% - ${45}px)` |                 height: `calc( 100% - ${45}px)` | ||||||
|  | |||||||
| @ -31,12 +31,6 @@ | |||||||
|             ], |             ], | ||||||
|             "@Component/*": [ |             "@Component/*": [ | ||||||
|                 "./source/Component/*" |                 "./source/Component/*" | ||||||
|             ], |  | ||||||
|             "@Localization/*": [ |  | ||||||
|                 "./source/Localization/*" |  | ||||||
|             ], |  | ||||||
|             "@Panel/*": [ |  | ||||||
|                 "./source/Panel/*" |  | ||||||
|             ] |             ] | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user