Compare commits
	
		
			2 Commits
		
	
	
		
			cc127696c5
			...
			50f1cb0562
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 50f1cb0562 | |||
| 1f4c6feafa | 
| @ -73,7 +73,7 @@ class CommandBar extends Component<ICommandBarProps & IMixinSettingProps & IMixi | |||||||
|                     iconName: "Settings", |                     iconName: "Settings", | ||||||
|                     i18NKey: "Command.Bar.Setting.Info", |                     i18NKey: "Command.Bar.Setting.Info", | ||||||
|                     click: () => { |                     click: () => { | ||||||
|                         this.props.status?.popup.showPopup(ConfirmPopup, {}); |                         // this.props.status?.popup.showPopup(ConfirmPopup, {});
 | ||||||
|                     } |                     } | ||||||
|                 })} |                 })} | ||||||
|             </div> |             </div> | ||||||
|  | |||||||
| @ -32,7 +32,7 @@ div.confirm-root { | |||||||
| 			user-select: none; | 			user-select: none; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		div.action-button.yes-button:hover { | 		div.action-button.red { | ||||||
| 			color: $lt-red; | 			color: $lt-red; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -2,11 +2,17 @@ import { Popup } from "@Context/Popups"; | |||||||
| import { ReactNode } from "react"; | import { ReactNode } from "react"; | ||||||
| import { Message } from "@Component/Message/Message"; | import { Message } from "@Component/Message/Message"; | ||||||
| import { Theme } from "@Component/Theme/Theme"; | import { Theme } from "@Component/Theme/Theme"; | ||||||
| import { Localization } from "@Component/Localization/Localization"; | import { AllI18nKeys, Localization } from "@Component/Localization/Localization"; | ||||||
| import "./ConfirmPopup.scss"; | import "./ConfirmPopup.scss"; | ||||||
| 
 | 
 | ||||||
| interface IConfirmPopupProps { | interface IConfirmPopupProps { | ||||||
| 	 | 	titleI18N?: AllI18nKeys; | ||||||
|  | 	infoI18n: AllI18nKeys; | ||||||
|  | 	yesI18n?: AllI18nKeys; | ||||||
|  | 	noI18n?: AllI18nKeys; | ||||||
|  | 	yes?: () => any; | ||||||
|  | 	no?: () => any; | ||||||
|  | 	red?: "yes" | "no"; | ||||||
| } | } | ||||||
| class ConfirmPopup extends Popup<IConfirmPopupProps> { | class ConfirmPopup extends Popup<IConfirmPopupProps> { | ||||||
| 
 | 
 | ||||||
| @ -14,17 +20,37 @@ class ConfirmPopup extends Popup<IConfirmPopupProps> { | |||||||
| 
 | 
 | ||||||
| 	public height: number = 180; | 	public height: number = 180; | ||||||
| 
 | 
 | ||||||
|  | 	public onRenderHeader(): ReactNode { | ||||||
|  | 		return <Localization i18nKey={this.props.titleI18N ?? "Popup.Title.Confirm"}/> | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	public render(): ReactNode { | 	public render(): ReactNode { | ||||||
|  | 
 | ||||||
|  | 		const yesClassList: string[] = ["action-button", "yes-button"]; | ||||||
|  | 		const noClassList: string[] = ["action-button", "no-button"]; | ||||||
|  | 		if (this.props.red === "no") { | ||||||
|  | 			noClassList.push("red"); | ||||||
|  | 		} | ||||||
|  | 		if (this.props.red === "yes") { | ||||||
|  | 			yesClassList.push("red"); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		return <Theme className="confirm-root"> | 		return <Theme className="confirm-root"> | ||||||
| 			<div className="content-views"> | 			<div className="content-views"> | ||||||
| 				<Message i18nKey="ZH_CN"/> | 				<Message i18nKey={this.props.infoI18n}/> | ||||||
| 			</div> | 			</div> | ||||||
| 			<div className="action-view"> | 			<div className="action-view"> | ||||||
| 				<div className="yes-button action-button"> | 				<div className={yesClassList.join(" ")} onClick={() => { | ||||||
| 					<Localization i18nKey="Panel.Title.Group.Details.View"/> | 					this.props.yes ? this.props.yes() : null; | ||||||
|  | 					this.close(); | ||||||
|  | 				}}> | ||||||
|  | 					<Localization i18nKey={this.props.yesI18n ?? "Popup.Action.Yes"}/> | ||||||
| 				</div> | 				</div> | ||||||
| 				<div className="no-button action-button"> | 				<div className={noClassList.join(" ")} onClick={() => { | ||||||
| 					<Localization i18nKey="Panel.Title.Group.Details.View"/> | 					this.props.no ? this.props.no() : null; | ||||||
|  | 					this.close(); | ||||||
|  | 				}}> | ||||||
|  | 					<Localization i18nKey={this.props.noI18n ?? "Popup.Action.No"}/> | ||||||
| 				</div> | 				</div> | ||||||
| 			</div> | 			</div> | ||||||
| 		</Theme>; | 		</Theme>; | ||||||
|  | |||||||
| @ -34,7 +34,6 @@ div.popup-layer.show-scale { | |||||||
| 
 | 
 | ||||||
| div.popup-mask { | div.popup-mask { | ||||||
|     position: absolute; |     position: absolute; | ||||||
|     cursor: pointer; |  | ||||||
|     width: 100%; |     width: 100%; | ||||||
|     height: 100%; |     height: 100%; | ||||||
| } | } | ||||||
| @ -46,11 +45,21 @@ div.focus.popup-layer { | |||||||
| div.popup-layer { | div.popup-layer { | ||||||
|     position: absolute; |     position: absolute; | ||||||
|     border-radius: 3px; |     border-radius: 3px; | ||||||
|     overflow: hidden; |  | ||||||
|     transition: none; |     transition: none; | ||||||
|     box-sizing: border-box; |     box-sizing: border-box; | ||||||
|     border: 0.8px solid transparent; |     border: 0.8px solid transparent; | ||||||
| 
 | 
 | ||||||
|  |     div.popup-layer-container { | ||||||
|  |         width: 100%; | ||||||
|  |         height: 100%; | ||||||
|  |         display: flex; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     div.popup-layer-root-content { | ||||||
|  |         width: 100%; | ||||||
|  |         height: 100%; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     div.popup-layer-header { |     div.popup-layer-header { | ||||||
|         min-height: $header-height; |         min-height: $header-height; | ||||||
|         max-height: $header-height; |         max-height: $header-height; | ||||||
| @ -68,7 +77,7 @@ div.popup-layer { | |||||||
|             span { |             span { | ||||||
|                 padding-left: 10px; |                 padding-left: 10px; | ||||||
|                 display: inline-block; |                 display: inline-block; | ||||||
|                 vertical-align: middle; |                 vertical-align: bottom; | ||||||
|                 white-space: nowrap; |                 white-space: nowrap; | ||||||
|                 text-overflow: ellipsis; |                 text-overflow: ellipsis; | ||||||
|                 overflow: hidden; |                 overflow: hidden; | ||||||
| @ -92,6 +101,44 @@ div.popup-layer { | |||||||
|         width: 100%; |         width: 100%; | ||||||
|         overflow: hidden; |         overflow: hidden; | ||||||
|     } |     } | ||||||
|  |      | ||||||
|  |     div.drag-line-root.drag-line-y { | ||||||
|  |         flex-direction: column; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     div.drag-line-root { | ||||||
|  |         display: flex; | ||||||
|  |         justify-content: center; | ||||||
|  |         align-items: center; | ||||||
|  |         position: relative; | ||||||
|  | 
 | ||||||
|  |         div.drag-line { | ||||||
|  |             transition: all 300ms ease-in-out; | ||||||
|  |             display: flex; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         div.render-drag-block-root { | ||||||
|  |             height: 0; | ||||||
|  |             width: 0; | ||||||
|  |             display: flex; | ||||||
|  |             justify-content: center; | ||||||
|  |             align-items: center; | ||||||
|  | 
 | ||||||
|  |             div.render-drag-block { | ||||||
|  |                 min-width: 5px; | ||||||
|  |                 min-height: 5px; | ||||||
|  |                 position: relative; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         div.drag-line:hover { | ||||||
|  |             background-color: $lt-blue; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         div.drag-line.hover { | ||||||
|  |             background-color: $lt-blue; | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| div.popup-layer.dark { | div.popup-layer.dark { | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ import { Component, ReactNode } from "react"; | |||||||
| import { IMixinStatusProps, useStatusWithEvent } from "@Context/Status"; | import { IMixinStatusProps, useStatusWithEvent } from "@Context/Status"; | ||||||
| import { IMixinSettingProps, useSettingWithEvent } from "@Context/Setting"; | import { IMixinSettingProps, useSettingWithEvent } from "@Context/Setting"; | ||||||
| import { BackgroundLevel, FontLevel, getClassList, Theme } from "@Component/Theme/Theme"; | import { BackgroundLevel, FontLevel, getClassList, Theme } from "@Component/Theme/Theme"; | ||||||
| import { Popup as PopupModel } from "@Context/Popups"; | import { Popup as PopupModel, ResizeDragDirection } from "@Context/Popups"; | ||||||
| import { Icon } from "@fluentui/react"; | import { Icon } from "@fluentui/react"; | ||||||
| import "./Popup.scss"; | import "./Popup.scss"; | ||||||
| 
 | 
 | ||||||
| @ -79,9 +79,6 @@ class Popup extends Component<IPopupProps & IMixinStatusProps & IMixinSettingPro | |||||||
|                     popup.lastMouseLeft = e.clientX; |                     popup.lastMouseLeft = e.clientX; | ||||||
|                     popup.lastMouseTop = e.clientY; |                     popup.lastMouseTop = e.clientY; | ||||||
|                 }} |                 }} | ||||||
|                 onMouseUp={() => { |  | ||||||
|                     popup.isOnMouseDown = false; |  | ||||||
|                 }} |  | ||||||
|             > |             > | ||||||
|                 {popup.onRenderHeader()} |                 {popup.onRenderHeader()} | ||||||
|             </div> |             </div> | ||||||
| @ -108,6 +105,129 @@ class Popup extends Component<IPopupProps & IMixinStatusProps & IMixinSettingPro | |||||||
|         </div> |         </div> | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     private renderDragBlock(dir: ResizeDragDirection, popup: PopupModel) { | ||||||
|  |         return <div className="render-drag-block-root"> | ||||||
|  |             <div | ||||||
|  |                 draggable={false} | ||||||
|  |                 style={{ | ||||||
|  |                     cursor: this.mapDirToCursor.get(dir), | ||||||
|  |                     zIndex: popup.zIndex() + 2 | ||||||
|  |                 }} | ||||||
|  |                 className="render-drag-block" | ||||||
|  |                 onMouseDown={(e) => { | ||||||
|  |                     popup.lastMouseLeft = e.clientX; | ||||||
|  |                     popup.lastMouseTop = e.clientY; | ||||||
|  |                     popup.resizeDragDirection = dir; | ||||||
|  |                     popup.isResizeMouseDown = true; | ||||||
|  |                 }} | ||||||
|  |                 onMouseEnter={() => { | ||||||
|  |                     popup.resizeHoverDirection = dir; | ||||||
|  |                     this.forceUpdate(); | ||||||
|  |                 }} | ||||||
|  |                 onMouseLeave={() => { | ||||||
|  |                     popup.resizeHoverDirection = undefined; | ||||||
|  |                     this.forceUpdate(); | ||||||
|  |                 }} | ||||||
|  |             /> | ||||||
|  |         </div> | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private mapDirToCursor = new Map<ResizeDragDirection, string>([ | ||||||
|  |         [ResizeDragDirection.rightTop, "sw-resize"], | ||||||
|  |         [ResizeDragDirection.rightBottom, "nw-resize"], | ||||||
|  |         [ResizeDragDirection.leftBottom, "sw-resize"], | ||||||
|  |         [ResizeDragDirection.LeftTop, "nw-resize"] | ||||||
|  |     ]); | ||||||
|  | 
 | ||||||
|  |     private renderDragLine(dir: ResizeDragDirection, popup: PopupModel) { | ||||||
|  |         let xy: boolean = false; | ||||||
|  |         const dragLineCList: string[] = ["drag-line"]; | ||||||
|  | 
 | ||||||
|  |         if (dir === ResizeDragDirection.top || dir === ResizeDragDirection.bottom) { | ||||||
|  |             xy = false; | ||||||
|  |         } | ||||||
|  |         if (dir === ResizeDragDirection.left || dir === ResizeDragDirection.right) { | ||||||
|  |             xy = true; | ||||||
|  |         } | ||||||
|  |         if ( | ||||||
|  |             ( | ||||||
|  |                 dir === ResizeDragDirection.top &&  | ||||||
|  |                 ( | ||||||
|  |                     popup.resizeHoverDirection === ResizeDragDirection.LeftTop || | ||||||
|  |                     popup.resizeHoverDirection === ResizeDragDirection.rightTop | ||||||
|  |                 )     | ||||||
|  |             ) || | ||||||
|  |             ( | ||||||
|  |                 dir === ResizeDragDirection.bottom &&  | ||||||
|  |                 ( | ||||||
|  |                     popup.resizeHoverDirection === ResizeDragDirection.leftBottom || | ||||||
|  |                     popup.resizeHoverDirection === ResizeDragDirection.rightBottom | ||||||
|  |                 )     | ||||||
|  |             ) || | ||||||
|  |             ( | ||||||
|  |                 dir === ResizeDragDirection.right &&  | ||||||
|  |                 ( | ||||||
|  |                     popup.resizeHoverDirection === ResizeDragDirection.rightTop || | ||||||
|  |                     popup.resizeHoverDirection === ResizeDragDirection.rightBottom | ||||||
|  |                 )     | ||||||
|  |             ) || | ||||||
|  |             ( | ||||||
|  |                 dir === ResizeDragDirection.left &&  | ||||||
|  |                 ( | ||||||
|  |                     popup.resizeHoverDirection === ResizeDragDirection.leftBottom || | ||||||
|  |                     popup.resizeHoverDirection === ResizeDragDirection.LeftTop | ||||||
|  |                 )     | ||||||
|  |             ) | ||||||
|  |         ) { | ||||||
|  |             dragLineCList.push("hover") | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         return <div | ||||||
|  |             className={"drag-line-root" + (xy ? " drag-line-y" : "")} | ||||||
|  |             style={{ | ||||||
|  |                 width: xy ? "0" : "100%", | ||||||
|  |                 height: xy ? "100%" : "0", | ||||||
|  |                 zIndex: popup.zIndex() + 1 | ||||||
|  |             }} | ||||||
|  |         > | ||||||
|  |             { | ||||||
|  |                 xy && dir === ResizeDragDirection.left ? this.renderDragBlock( | ||||||
|  |                     ResizeDragDirection.LeftTop, popup | ||||||
|  |                 ) : null | ||||||
|  |             } | ||||||
|  |             { | ||||||
|  |                 xy && dir === ResizeDragDirection.right ? this.renderDragBlock( | ||||||
|  |                     ResizeDragDirection.rightTop, popup | ||||||
|  |                 ) : null | ||||||
|  |             } | ||||||
|  |             { | ||||||
|  |                 !xy && dir === ResizeDragDirection.bottom ? this.renderDragBlock( | ||||||
|  |                     ResizeDragDirection.leftBottom, popup | ||||||
|  |                 ) : null | ||||||
|  |             } | ||||||
|  |             <div | ||||||
|  |                 draggable={false} | ||||||
|  |                 className={dragLineCList.join(" ")} | ||||||
|  |                 style={{ | ||||||
|  |                     cursor: xy ? "e-resize" : "n-resize", | ||||||
|  |                     minWidth: xy ? "4px" : "calc( 100% + 2px )", | ||||||
|  |                     minHeight: xy ? "calc( 100% + 2px )" : "4px" | ||||||
|  |                 }} | ||||||
|  |                 onMouseDown={(e) => { | ||||||
|  |                     popup.lastMouseLeft = e.clientX; | ||||||
|  |                     popup.lastMouseTop = e.clientY; | ||||||
|  |                     popup.resizeDragDirection = dir; | ||||||
|  |                     popup.isResizeMouseDown = true; | ||||||
|  |                 }} | ||||||
|  |             /> | ||||||
|  |             { | ||||||
|  |                 !xy && dir === ResizeDragDirection.bottom ? this.renderDragBlock( | ||||||
|  |                     ResizeDragDirection.rightBottom, popup | ||||||
|  |                 ) : null | ||||||
|  |             } | ||||||
|  |         </div> | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     private renderLayer(popup: PopupModel) { |     private renderLayer(popup: PopupModel) { | ||||||
|         const pageWidth = document.documentElement.clientWidth; |         const pageWidth = document.documentElement.clientWidth; | ||||||
|         const pageHeight = document.documentElement.clientHeight; |         const pageHeight = document.documentElement.clientHeight; | ||||||
| @ -132,8 +252,16 @@ class Popup extends Component<IPopupProps & IMixinStatusProps & IMixinSettingPro | |||||||
|                 backgroundLevel: BackgroundLevel.Level4, |                 backgroundLevel: BackgroundLevel.Level4, | ||||||
|             }, this.props.setting).join(" ")} |             }, this.props.setting).join(" ")} | ||||||
|         > |         > | ||||||
|             {this.renderHeader(popup)} |             {this.renderDragLine(ResizeDragDirection.top, popup)} | ||||||
|             {this.renderContent(popup)} |             <div className="popup-layer-container"> | ||||||
|  |                 {this.renderDragLine(ResizeDragDirection.left, popup)} | ||||||
|  |                 <div className="popup-layer-root-content"> | ||||||
|  |                     {this.renderHeader(popup)} | ||||||
|  |                     {this.renderContent(popup)} | ||||||
|  |                 </div> | ||||||
|  |                 {this.renderDragLine(ResizeDragDirection.right, popup)} | ||||||
|  |             </div> | ||||||
|  |             {this.renderDragLine(ResizeDragDirection.bottom, popup)} | ||||||
|         </Theme> |         </Theme> | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -145,9 +273,54 @@ class Popup extends Component<IPopupProps & IMixinStatusProps & IMixinSettingPro | |||||||
| 
 | 
 | ||||||
|     private handelMouseUp = () => { |     private handelMouseUp = () => { | ||||||
|         this.isMouseDown = false; |         this.isMouseDown = false; | ||||||
|  |         if (this.props.status) { | ||||||
|  |             this.props.status.popup.popups.forEach((popup) => { | ||||||
|  |                 popup.isOnMouseDown = false; | ||||||
|  |                 popup.resizeDragDirection = undefined; | ||||||
|  |                 popup.isResizeMouseDown = false; | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private resize(popup: PopupModel, dis: number, dir: boolean, lsk: boolean) { | ||||||
|  |          | ||||||
|  |         if (dir) { | ||||||
|  |             // Y
 | ||||||
|  |             popup.isResizeOverFlowY = false; | ||||||
|  |             const heightBackup = popup.height | ||||||
|  |             const topBackup = popup.top; | ||||||
|  |             if (lsk) { | ||||||
|  |                 popup.height += dis; | ||||||
|  |             } else { | ||||||
|  |                 popup.top += dis; | ||||||
|  |                 popup.height -= dis; | ||||||
|  |             } | ||||||
|  |             if (popup.height < popup.minHeight) { | ||||||
|  |                 popup.height = heightBackup; | ||||||
|  |                 popup.top = topBackup; | ||||||
|  |                 popup.isResizeOverFlowY = true; | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             // X
 | ||||||
|  |             popup.isResizeOverFlowX = false; | ||||||
|  |             const leftBackup = popup.left | ||||||
|  |             const widthBackup = popup.width; | ||||||
|  |             if (lsk) { | ||||||
|  |                 popup.width += dis; | ||||||
|  |             } else { | ||||||
|  |                 popup.left += dis; | ||||||
|  |                 popup.width -= dis; | ||||||
|  |             } | ||||||
|  |             if (popup.width < popup.minWidth) { | ||||||
|  |                 popup.width = widthBackup; | ||||||
|  |                 popup.left = leftBackup; | ||||||
|  |                 popup.isResizeOverFlowX = true; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private handelMouseMove = (e: MouseEvent) => { |     private handelMouseMove = (e: MouseEvent) => { | ||||||
|  |         let isActionSuccess: boolean = false; | ||||||
|         if ( |         if ( | ||||||
|             this.isMouseDown && |             this.isMouseDown && | ||||||
|             this.props.status && |             this.props.status && | ||||||
| @ -159,10 +332,69 @@ class Popup extends Component<IPopupProps & IMixinStatusProps & IMixinSettingPro | |||||||
|                     popup.left += e.clientX - popup.lastMouseLeft; |                     popup.left += e.clientX - popup.lastMouseLeft; | ||||||
|                     popup.lastMouseLeft = e.clientX; |                     popup.lastMouseLeft = e.clientX; | ||||||
|                     popup.lastMouseTop = e.clientY; |                     popup.lastMouseTop = e.clientY; | ||||||
|  |                     isActionSuccess = true; | ||||||
|                     this.forceUpdate(); |                     this.forceUpdate(); | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|  |         if (this.props.status) { | ||||||
|  |             this.props.status.popup.popups.forEach((popup) => { | ||||||
|  |                 if (popup.resizeDragDirection) { | ||||||
|  |                          | ||||||
|  |                     let moveX = e.clientX - popup.lastMouseLeft; | ||||||
|  |                     let moveY = e.clientY - popup.lastMouseTop; | ||||||
|  |                     switch (popup.resizeDragDirection) { | ||||||
|  | 
 | ||||||
|  |                         case ResizeDragDirection.LeftTop: | ||||||
|  |                             this.resize(popup, moveX, false, false); | ||||||
|  |                             this.resize(popup, moveY, true, false); | ||||||
|  |                             break; | ||||||
|  | 
 | ||||||
|  |                         case ResizeDragDirection.leftBottom: | ||||||
|  |                             this.resize(popup, moveX, false, false); | ||||||
|  |                             this.resize(popup, moveY, true, true); | ||||||
|  |                             break; | ||||||
|  | 
 | ||||||
|  |                         case ResizeDragDirection.rightTop: | ||||||
|  |                             this.resize(popup, moveX, false, true); | ||||||
|  |                             this.resize(popup, moveY, true, false); | ||||||
|  |                             break; | ||||||
|  | 
 | ||||||
|  |                         case ResizeDragDirection.rightBottom: | ||||||
|  |                             this.resize(popup, moveX, false, true); | ||||||
|  |                             this.resize(popup, moveY, true, true); | ||||||
|  |                             break; | ||||||
|  | 
 | ||||||
|  |                         case ResizeDragDirection.top: | ||||||
|  |                             this.resize(popup, moveY, true, false); | ||||||
|  |                             break; | ||||||
|  | 
 | ||||||
|  |                         case ResizeDragDirection.left: | ||||||
|  |                             this.resize(popup, moveX, false, false); | ||||||
|  |                             break; | ||||||
|  | 
 | ||||||
|  |                         case ResizeDragDirection.bottom: | ||||||
|  |                             this.resize(popup, moveY, true, true); | ||||||
|  |                             break; | ||||||
|  | 
 | ||||||
|  |                         case ResizeDragDirection.right: | ||||||
|  |                             this.resize(popup, moveX, false, true); | ||||||
|  |                             break; | ||||||
|  |                     } | ||||||
|  |                     if (!popup.isResizeOverFlowX) { | ||||||
|  |                         popup.lastMouseLeft = e.clientX; | ||||||
|  |                     } | ||||||
|  |                     if (!popup.isResizeOverFlowY) { | ||||||
|  |                         popup.lastMouseTop = e.clientY; | ||||||
|  |                     } | ||||||
|  |                     isActionSuccess = true; | ||||||
|  |                     this.forceUpdate(); | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |         if (isActionSuccess) { | ||||||
|  |             e.preventDefault(); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public componentDidMount() { |     public componentDidMount() { | ||||||
|  | |||||||
| @ -15,6 +15,10 @@ div.toggles-input { | |||||||
|         cursor: pointer; |         cursor: pointer; | ||||||
|         user-select: none; |         user-select: none; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     div.checkbox.red:hover { | ||||||
|  |         color: $lt-red !important; | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| div.dark.text-field-root { | div.dark.text-field-root { | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ interface ITogglesInputProps extends ITextFieldProps { | |||||||
|     onIconName?: string; |     onIconName?: string; | ||||||
|     offIconName?: string; |     offIconName?: string; | ||||||
|     valueChange?: (value: boolean) => any; |     valueChange?: (value: boolean) => any; | ||||||
|  |     red?: boolean; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class TogglesInput extends Component<ITogglesInputProps> { | class TogglesInput extends Component<ITogglesInputProps> { | ||||||
| @ -20,7 +21,7 @@ class TogglesInput extends Component<ITogglesInputProps> { | |||||||
|             customStyle |             customStyle | ||||||
|         > |         > | ||||||
|             <div |             <div | ||||||
|                 className="checkbox" |                 className={"checkbox" + (this.props.red ? " red" : "")} | ||||||
|                 style={{ |                 style={{ | ||||||
|                     cursor: this.props.disableI18n ? "not-allowed" : "pointer" |                     cursor: this.props.disableI18n ? "not-allowed" : "pointer" | ||||||
|                 }} |                 }} | ||||||
|  | |||||||
| @ -3,6 +3,17 @@ import { Emitter } from "@Model/Emitter"; | |||||||
| import { Localization } from "@Component/Localization/Localization"; | import { Localization } from "@Component/Localization/Localization"; | ||||||
| import { IAnyObject } from "@Model/Renderer"; | import { IAnyObject } from "@Model/Renderer"; | ||||||
| 
 | 
 | ||||||
|  | enum ResizeDragDirection { | ||||||
|  |     top = 1, | ||||||
|  |     rightTop = 2, | ||||||
|  |     right = 3, | ||||||
|  |     rightBottom = 4, | ||||||
|  |     bottom = 5, | ||||||
|  |     leftBottom = 6, | ||||||
|  |     left = 7, | ||||||
|  |     LeftTop = 8 | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * 弹窗类型 |  * 弹窗类型 | ||||||
|  */ |  */ | ||||||
| @ -15,22 +26,23 @@ class Popup<P extends IAnyObject = IAnyObject> { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public zIndex() { |     public zIndex() { | ||||||
|         return this.index * 2 + this.controller.zIndex; |         return this.index * 5 + this.controller.zIndex; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public width: number = 300; |     public width: number = 300; | ||||||
| 
 |  | ||||||
|     public height: number = 200; |     public height: number = 200; | ||||||
| 
 |     public minWidth: number = 300; | ||||||
|  |     public minHeight: number = 200; | ||||||
|     public top: number = NaN; |     public top: number = NaN; | ||||||
| 
 |  | ||||||
|     public left: number = NaN; |     public left: number = NaN; | ||||||
| 
 |  | ||||||
|     public lastMouseTop: number = 0; |     public lastMouseTop: number = 0; | ||||||
| 
 |  | ||||||
|     public lastMouseLeft: number = 0; |     public lastMouseLeft: number = 0; | ||||||
| 
 |  | ||||||
|     public isOnMouseDown: boolean = false; |     public isOnMouseDown: boolean = false; | ||||||
|  |     public resizeHoverDirection?: ResizeDragDirection; | ||||||
|  |     public resizeDragDirection?: ResizeDragDirection; | ||||||
|  |     public isResizeMouseDown: boolean = false; | ||||||
|  |     public isResizeOverFlowX: boolean = false; | ||||||
|  |     public isResizeOverFlowY: boolean = false; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * 是否关闭 |      * 是否关闭 | ||||||
| @ -178,4 +190,4 @@ class PopupController extends Emitter<IPopupControllerEvent> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export { Popup, PopupController } | export { Popup, PopupController, ResizeDragDirection } | ||||||
| @ -45,6 +45,12 @@ const EN_US = { | |||||||
|     "Panel.Title.Group.Details.View": "Group", |     "Panel.Title.Group.Details.View": "Group", | ||||||
|     "Panel.Info.Group.Details.View": "Edit view group attributes", |     "Panel.Info.Group.Details.View": "Edit view group attributes", | ||||||
|     "Popup.Title.Unnamed": "Popup message", |     "Popup.Title.Unnamed": "Popup message", | ||||||
|  |     "Popup.Title.Confirm": "Confirm message", | ||||||
|  |     "Popup.Action.Yes": "Confirm", | ||||||
|  |     "Popup.Action.No": "Cancel", | ||||||
|  |     "Popup.Action.Objects.Confirm.Title": "Confirm Delete", | ||||||
|  |     "Popup.Action.Objects.Confirm.Delete": "Delete", | ||||||
|  |     "Popup.Delete.Objects.Confirm": "Are you sure you want to delete this object(s)? The object is deleted and cannot be recalled.", | ||||||
|     "Build.In.Label.Name.All.Group": "All group", |     "Build.In.Label.Name.All.Group": "All group", | ||||||
|     "Build.In.Label.Name.All.Range": "All range", |     "Build.In.Label.Name.All.Range": "All range", | ||||||
|     "Common.No.Data": "No Data", |     "Common.No.Data": "No Data", | ||||||
|  | |||||||
| @ -45,6 +45,12 @@ const ZH_CN = { | |||||||
|     "Panel.Title.Group.Details.View": "群", |     "Panel.Title.Group.Details.View": "群", | ||||||
|     "Panel.Info.Group.Details.View": "编辑查看群属性", |     "Panel.Info.Group.Details.View": "编辑查看群属性", | ||||||
|     "Popup.Title.Unnamed": "弹窗消息", |     "Popup.Title.Unnamed": "弹窗消息", | ||||||
|  |     "Popup.Title.Confirm": "确认消息", | ||||||
|  |     "Popup.Action.Yes": "确定", | ||||||
|  |     "Popup.Action.No": "取消", | ||||||
|  |     "Popup.Action.Objects.Confirm.Title": "删除确认", | ||||||
|  |     "Popup.Action.Objects.Confirm.Delete": "删除", | ||||||
|  |     "Popup.Delete.Objects.Confirm": "你确定要删除这个(些)对象吗?对象被删除将无法撤回。", | ||||||
|     "Build.In.Label.Name.All.Group": "全部群", |     "Build.In.Label.Name.All.Group": "全部群", | ||||||
|     "Build.In.Label.Name.All.Range": "全部范围", |     "Build.In.Label.Name.All.Range": "全部范围", | ||||||
|     "Common.No.Data": "暂无数据", |     "Common.No.Data": "暂无数据", | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ import { Group, GenMod } from "@Model/Group"; | |||||||
| import { AllI18nKeys } from "@Component/Localization/Localization"; | import { AllI18nKeys } from "@Component/Localization/Localization"; | ||||||
| import { ComboInput, IDisplayItem } from "@Component/ComboInput/ComboInput"; | import { ComboInput, IDisplayItem } from "@Component/ComboInput/ComboInput"; | ||||||
| import { ObjectPicker } from "@Component/ObjectPicker/ObjectPicker"; | import { ObjectPicker } from "@Component/ObjectPicker/ObjectPicker"; | ||||||
|  | import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | ||||||
| import "./GroupDetails.scss"; | import "./GroupDetails.scss"; | ||||||
| 
 | 
 | ||||||
| interface IGroupDetailsProps {} | interface IGroupDetailsProps {} | ||||||
| @ -88,12 +89,21 @@ class GroupDetails extends Component<IGroupDetailsProps & IMixinStatusProps> { | |||||||
|             /> |             /> | ||||||
| 
 | 
 | ||||||
| 			<TogglesInput | 			<TogglesInput | ||||||
| 				keyI18n="Common.Attr.Key.Delete" | 				keyI18n="Common.Attr.Key.Delete" red | ||||||
| 				onIconName="delete" offIconName="delete" | 				onIconName="delete" offIconName="delete" | ||||||
| 				valueChange={() => { | 				valueChange={() => { | ||||||
| 					if (this.props.status) { | 					if (this.props.status) { | ||||||
| 						this.props.status.model.deleteObject([group]); |                         const status = this.props.status; | ||||||
| 						this.props.status.setFocusObject(new Set()); | 						status.popup.showPopup(ConfirmPopup, { | ||||||
|  | 							infoI18n: "Popup.Delete.Objects.Confirm", | ||||||
|  | 							titleI18N: "Popup.Action.Objects.Confirm.Title", | ||||||
|  | 							yesI18n: "Popup.Action.Objects.Confirm.Delete", | ||||||
|  | 							red: "yes", | ||||||
|  | 							yes: () => { | ||||||
|  | 								status.model.deleteObject([group]); | ||||||
|  | 						        status.setFocusObject(new Set()); | ||||||
|  | 							} | ||||||
|  | 						}) | ||||||
| 					} | 					} | ||||||
| 				}} | 				}} | ||||||
| 			/> | 			/> | ||||||
| @ -147,7 +157,7 @@ class GroupDetails extends Component<IGroupDetailsProps & IMixinStatusProps> { | |||||||
|             /> |             /> | ||||||
| 
 | 
 | ||||||
|             <TogglesInput |             <TogglesInput | ||||||
| 				keyI18n="Common.Attr.Key.Generation" | 				keyI18n="Common.Attr.Key.Kill.Random" | ||||||
| 				onIconName="RemoveFilter" offIconName="RemoveFilter" | 				onIconName="RemoveFilter" offIconName="RemoveFilter" | ||||||
| 				valueChange={() => { | 				valueChange={() => { | ||||||
| 					group.killIndividuals() | 					group.killIndividuals() | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ import { Message } from "@Component/Message/Message"; | |||||||
| import { ColorInput } from "@Component/ColorInput/ColorInput"; | import { ColorInput } from "@Component/ColorInput/ColorInput"; | ||||||
| import { Label } from "@Model/Label"; | import { Label } from "@Model/Label"; | ||||||
| import { TogglesInput } from "@Component/TogglesInput/TogglesInput"; | import { TogglesInput } from "@Component/TogglesInput/TogglesInput"; | ||||||
|  | import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | ||||||
| import "./LabelDetails.scss"; | import "./LabelDetails.scss"; | ||||||
| 
 | 
 | ||||||
| @useStatusWithEvent("focusLabelChange", "labelAttrChange", "labelChange") | @useStatusWithEvent("focusLabelChange", "labelAttrChange", "labelChange") | ||||||
| @ -27,10 +28,21 @@ class LabelDetails extends Component<IMixinStatusProps> { | |||||||
|                 } |                 } | ||||||
|             }}/> |             }}/> | ||||||
| 
 | 
 | ||||||
|             <TogglesInput keyI18n="Common.Attr.Key.Delete" onIconName="delete" offIconName="delete" valueChange={() => { |             <TogglesInput | ||||||
|  |                 keyI18n="Common.Attr.Key.Delete" onIconName="delete" red | ||||||
|  |                 offIconName="delete" valueChange={() => { | ||||||
|                 if (this.props.status) { |                 if (this.props.status) { | ||||||
|                     this.props.status.model.deleteLabel(label); |                     const status = this.props.status; | ||||||
|                     this.props.status.setLabelObject(); |                     status.popup.showPopup(ConfirmPopup, { | ||||||
|  |                         infoI18n: "Popup.Delete.Objects.Confirm", | ||||||
|  |                         titleI18N: "Popup.Action.Objects.Confirm.Title", | ||||||
|  |                         yesI18n: "Popup.Action.Objects.Confirm.Delete", | ||||||
|  |                         red: "yes", | ||||||
|  |                         yes: () => { | ||||||
|  |                             status.model.deleteLabel(label); | ||||||
|  |                             status.setLabelObject(); | ||||||
|  |                         } | ||||||
|  |                     }) | ||||||
|                 } |                 } | ||||||
|             }}/> |             }}/> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | |||||||
| import { useSetting, IMixinSettingProps } from "@Context/Setting"; | import { useSetting, IMixinSettingProps } from "@Context/Setting"; | ||||||
| import { Label } from "@Model/Label"; | import { Label } from "@Model/Label"; | ||||||
| import { Message } from "@Component/Message/Message"; | import { Message } from "@Component/Message/Message"; | ||||||
|  | import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | ||||||
| import "./LabelList.scss"; | import "./LabelList.scss"; | ||||||
| 
 | 
 | ||||||
| interface ILabelListProps { | interface ILabelListProps { | ||||||
| @ -47,8 +48,17 @@ class LabelList extends Component<ILabelListProps & IMixinStatusProps & IMixinSe | |||||||
|                 }} |                 }} | ||||||
|                 deleteLabel={(label) => { |                 deleteLabel={(label) => { | ||||||
|                     if (this.props.status) { |                     if (this.props.status) { | ||||||
|                         this.props.status.model.deleteLabel(label); |                         const status = this.props.status; | ||||||
|                         this.props.status.setLabelObject(); |                         status.popup.showPopup(ConfirmPopup, { | ||||||
|  |                             infoI18n: "Popup.Delete.Objects.Confirm", | ||||||
|  |                             titleI18N: "Popup.Action.Objects.Confirm.Title", | ||||||
|  |                             yesI18n: "Popup.Action.Objects.Confirm.Delete", | ||||||
|  |                             red: "yes", | ||||||
|  |                             yes: () => { | ||||||
|  |                                 status.model.deleteLabel(label); | ||||||
|  |                                 status.setLabelObject(); | ||||||
|  |                             } | ||||||
|  |                         }) | ||||||
|                     } |                     } | ||||||
|                     this.labelInnerClick = true; |                     this.labelInnerClick = true; | ||||||
|                 }} |                 }} | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| import { BackgroundLevel, FontLevel, Theme } from "@Component/Theme/Theme"; | import { BackgroundLevel, FontLevel, Theme } from "@Component/Theme/Theme"; | ||||||
| import { useStatus, IMixinStatusProps } from "../../Context/Status"; | import { useStatus, IMixinStatusProps } from "../../Context/Status"; | ||||||
|  | import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | ||||||
| import { Icon } from "@fluentui/react"; | import { Icon } from "@fluentui/react"; | ||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
| import { ObjectID } from "@Model/Renderer"; | import { ObjectID } from "@Model/Renderer"; | ||||||
| @ -54,15 +55,24 @@ class ObjectCommand extends Component<IMixinStatusProps> { | |||||||
| 				<Icon iconName="CubeShape"></Icon> | 				<Icon iconName="CubeShape"></Icon> | ||||||
| 			</div> | 			</div> | ||||||
| 			<div | 			<div | ||||||
| 				className="command-item" | 				className="command-item red" | ||||||
| 				onClick={() => { | 				onClick={() => { | ||||||
| 					if (this.props.status) { | 					if (this.props.status && this.props.status.focusObject.size > 0) { | ||||||
| 						let deleteId: ObjectID[] = []; | 						const status = this.props.status; | ||||||
| 						this.props.status.focusObject.forEach((obj) => { | 						status.popup.showPopup(ConfirmPopup, { | ||||||
| 							deleteId.push(obj); | 							infoI18n: "Popup.Delete.Objects.Confirm", | ||||||
|  | 							titleI18N: "Popup.Action.Objects.Confirm.Title", | ||||||
|  | 							yesI18n: "Popup.Action.Objects.Confirm.Delete", | ||||||
|  | 							red: "yes", | ||||||
|  | 							yes: () => { | ||||||
|  | 								let deleteId: ObjectID[] = []; | ||||||
|  | 								status.focusObject.forEach((obj) => { | ||||||
|  | 									deleteId.push(obj); | ||||||
|  | 								}) | ||||||
|  | 								status.model.deleteObject(deleteId); | ||||||
|  | 								status.setFocusObject(new Set<ObjectID>()); | ||||||
|  | 							} | ||||||
| 						}) | 						}) | ||||||
| 						this.props.status.model.deleteObject(deleteId); |  | ||||||
| 						this.props.status.setFocusObject(new Set<ObjectID>()); |  | ||||||
| 					} | 					} | ||||||
| 				}} | 				}} | ||||||
| 			> | 			> | ||||||
|  | |||||||
| @ -59,6 +59,10 @@ div.object-list-command-bar { | |||||||
|         user-select: none; |         user-select: none; | ||||||
|         cursor: pointer; |         cursor: pointer; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     div.command-item.red:hover { | ||||||
|  |         color: $lt-red; | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| div.dark.object-list-command-bar { | div.dark.object-list-command-bar { | ||||||
|  | |||||||
| @ -1,13 +1,13 @@ | |||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
| import { AttrInput } from "@Component/AttrInput/AttrInput"; | import { AttrInput } from "@Component/AttrInput/AttrInput"; | ||||||
| import { useStatusWithEvent, IMixinStatusProps, Status } from "@Context/Status"; | import { useStatusWithEvent, IMixinStatusProps, Status } from "@Context/Status"; | ||||||
| import { AllI18nKeys } from "@Component/Localization/Localization"; |  | ||||||
| import { Message } from "@Component/Message/Message"; | import { Message } from "@Component/Message/Message"; | ||||||
| import { Range } from "@Model/Range"; | import { Range } from "@Model/Range"; | ||||||
| import { ObjectID } from "@Model/Renderer"; | import { ObjectID } from "@Model/Renderer"; | ||||||
| import { ColorInput } from "@Component/ColorInput/ColorInput"; | import { ColorInput } from "@Component/ColorInput/ColorInput"; | ||||||
| import { TogglesInput } from "@Component/TogglesInput/TogglesInput"; | import { TogglesInput } from "@Component/TogglesInput/TogglesInput"; | ||||||
| import { LabelPicker } from "@Component/LabelPicker/LabelPicker"; | import { LabelPicker } from "@Component/LabelPicker/LabelPicker"; | ||||||
|  | import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | ||||||
| import "./RangeDetails.scss"; | import "./RangeDetails.scss"; | ||||||
| 
 | 
 | ||||||
| @useStatusWithEvent("rangeAttrChange", "focusObjectChange", "rangeLabelChange") | @useStatusWithEvent("rangeAttrChange", "focusObjectChange", "rangeLabelChange") | ||||||
| @ -53,12 +53,21 @@ class RangeDetails extends Component<IMixinStatusProps> { | |||||||
|             /> |             /> | ||||||
| 
 | 
 | ||||||
|             <TogglesInput |             <TogglesInput | ||||||
| 				keyI18n="Common.Attr.Key.Delete" | 				keyI18n="Common.Attr.Key.Delete" red | ||||||
| 				onIconName="delete" offIconName="delete" | 				onIconName="delete" offIconName="delete" | ||||||
| 				valueChange={() => { | 				valueChange={() => { | ||||||
| 					if (this.props.status) { |                     if (this.props.status) { | ||||||
| 						this.props.status.model.deleteObject([range]); |                         const status = this.props.status; | ||||||
| 						this.props.status.setFocusObject(new Set()); | 						status.popup.showPopup(ConfirmPopup, { | ||||||
|  | 							infoI18n: "Popup.Delete.Objects.Confirm", | ||||||
|  | 							titleI18N: "Popup.Action.Objects.Confirm.Title", | ||||||
|  | 							yesI18n: "Popup.Action.Objects.Confirm.Delete", | ||||||
|  | 							red: "yes", | ||||||
|  | 							yes: () => { | ||||||
|  | 								status.model.deleteObject([range]); | ||||||
|  | 						        status.setFocusObject(new Set()); | ||||||
|  | 							} | ||||||
|  | 						}) | ||||||
| 					} | 					} | ||||||
| 				}} | 				}} | ||||||
| 			/> | 			/> | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user