Add save and load function #46
| @ -1,3 +1,5 @@ | |||||||
|  | @import "../Theme/Theme.scss"; | ||||||
|  | 
 | ||||||
| div.command-bar { | div.command-bar { | ||||||
|     height: 100%; |     height: 100%; | ||||||
|     user-select: none; |     user-select: none; | ||||||
| @ -5,32 +7,53 @@ div.command-bar { | |||||||
|     flex-direction: column; |     flex-direction: column; | ||||||
|     justify-content: space-between; |     justify-content: space-between; | ||||||
|      |      | ||||||
|     button.ms-Button.command-button { |     div.command-button { | ||||||
|         width: 100%; |         width: 100%; | ||||||
|         text-align: center; |  | ||||||
|         display: flex; |         display: flex; | ||||||
|         justify-content: center; |         justify-content: center; | ||||||
|  |         align-items: center; | ||||||
|         transition: all 100ms ease-in-out; |         transition: all 100ms ease-in-out; | ||||||
|         color:  inherit; |         cursor: pointer; | ||||||
|          |          | ||||||
|         span.ms-Button-flexContainer i.ms-Icon { |         i { | ||||||
|             font-size: 25px; |             font-size: 22px; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         div.command-button-loading { | ||||||
|  |              | ||||||
|  |             div.ms-Spinner-circle { | ||||||
|  |                 border-width: 2px; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     button.ms-Button.command-button.on-end { |     div.command-button.on-end { | ||||||
|         align-self: flex-end; |         align-self: flex-end; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| div.command-bar.dark button.ms-Button.command-button.active, | div.command-bar.dark div.command-button div.command-button-loading div.ms-Spinner-circle { | ||||||
| div.command-bar.dark button.ms-Button.command-button:hover { |     border-top-color: rgba($color: #FFFFFF, $alpha: .9); | ||||||
|  |     border-left-color: rgba($color: #FFFFFF, $alpha: .4); | ||||||
|  |     border-bottom-color: rgba($color: #FFFFFF, $alpha: .4); | ||||||
|  |     border-right-color: rgba($color: #FFFFFF, $alpha: .4); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | div.command-bar.light div.command-button div.command-button-loading div.ms-Spinner-circle { | ||||||
|  |     border-top-color: rgba($color: #000000, $alpha: .9); | ||||||
|  |     border-left-color: rgba($color: #000000, $alpha: .4); | ||||||
|  |     border-bottom-color: rgba($color: #000000, $alpha: .4); | ||||||
|  |     border-right-color: rgba($color: #000000, $alpha: .4); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | div.command-bar.dark div.command-button.active, | ||||||
|  | div.command-bar.dark div.command-button:hover { | ||||||
|     background-color: rgba($color: #FFFFFF, $alpha: .2); |     background-color: rgba($color: #FFFFFF, $alpha: .2); | ||||||
|     color: rgba($color: #FFFFFF, $alpha: 1); |     color: rgba($color: #FFFFFF, $alpha: 1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| div.command-bar.light button.ms-Button.command-button.active, | div.command-bar.light div.command-button.active, | ||||||
| div.command-bar.light button.ms-Button.command-button:hover { | div.command-bar.light div.command-button:hover { | ||||||
|     background-color: rgba($color: #000000, $alpha: .08); |     background-color: rgba($color: #000000, $alpha: .08); | ||||||
|     color: rgba($color: #000000, $alpha: 1); |     color: rgba($color: #000000, $alpha: 1); | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode, FunctionComponent } from "react"; | ||||||
| import { DirectionalHint, IconButton } from "@fluentui/react"; | import { DirectionalHint, Icon, Spinner } from "@fluentui/react"; | ||||||
| import { useSetting, IMixinSettingProps } from "@Context/Setting"; | import { useSetting, IMixinSettingProps } from "@Context/Setting"; | ||||||
| import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | ||||||
| import { BackgroundLevel, Theme } from "@Component/Theme/Theme"; | import { BackgroundLevel, Theme } from "@Component/Theme/Theme"; | ||||||
| @ -18,23 +18,28 @@ interface IRenderButtonParameter { | |||||||
|     iconName?: string; |     iconName?: string; | ||||||
|     click?: () => void; |     click?: () => void; | ||||||
|     active?: boolean; |     active?: boolean; | ||||||
|  |     isLoading?: boolean; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| interface ICommandBarState { | interface ICommandBarState { | ||||||
|     isSaveRunning: boolean; |     isSaveRunning: boolean; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function getRenderButton(param: IRenderButtonParameter): ReactNode { | const CommandButton: FunctionComponent<IRenderButtonParameter> = (param) => { | ||||||
|     return <LocalizationTooltipHost  |     return <LocalizationTooltipHost  | ||||||
|         i18nKey={param.i18NKey} |         i18nKey={param.i18NKey} | ||||||
|         directionalHint={DirectionalHint.rightCenter} |         directionalHint={DirectionalHint.rightCenter} | ||||||
|     > |     > | ||||||
|         <IconButton |         <div | ||||||
|             style={{ height: COMMAND_BAR_WIDTH }} |             style={{ height: COMMAND_BAR_WIDTH }} | ||||||
|             iconProps={{ iconName: param.iconName }} |             onClick={ param.isLoading ? undefined : param.click } | ||||||
|             onClick={ param.click } |  | ||||||
|             className={"command-button on-end" + (param.active ? " active" : "")} |             className={"command-button on-end" + (param.active ? " active" : "")} | ||||||
|         /> |         > | ||||||
|  |             {param.isLoading ?  | ||||||
|  |                 <Spinner className="command-button-loading"/> : | ||||||
|  |                 <Icon iconName={param.iconName}/> | ||||||
|  |             } | ||||||
|  |         </div> | ||||||
|     </LocalizationTooltipHost> |     </LocalizationTooltipHost> | ||||||
| } | } | ||||||
| @useSetting | @useSetting | ||||||
| @ -68,78 +73,84 @@ class CommandBar extends Component<IMixinSettingProps & IMixinStatusProps, IComm | |||||||
|                     }} |                     }} | ||||||
|                 /> |                 /> | ||||||
| 
 | 
 | ||||||
|                 {getRenderButton({ |                 <CommandButton | ||||||
|                     iconName: "Save", |                     iconName="Save" | ||||||
|                     i18NKey: "Command.Bar.Save.Info", |                     i18NKey="Command.Bar.Save.Info" | ||||||
|                     click: () => { |                     isLoading={this.state.isSaveRunning} | ||||||
|  |                     click={() => { | ||||||
|                         this.setState({ |                         this.setState({ | ||||||
|                             isSaveRunning: true |                             isSaveRunning: true | ||||||
|                         }); |                         }); | ||||||
|                     } |                     }} | ||||||
|                 })} |                 /> | ||||||
| 
 | 
 | ||||||
|                 {getRenderButton({ |                 <CommandButton | ||||||
|                     iconName: this.props.status?.actuator.start() ? "Pause" : "Play", |                     iconName={this.props.status?.actuator.start() ? "Pause" : "Play"} | ||||||
|                     i18NKey: "Command.Bar.Play.Info", |                     i18NKey="Command.Bar.Play.Info" | ||||||
|                     click: () => this.props.status ? this.props.status.actuator.start( |                     click={() => this.props.status ? this.props.status.actuator.start( | ||||||
|                         !this.props.status.actuator.start() |                         !this.props.status.actuator.start() | ||||||
|                     ) : undefined |                     ) : undefined} | ||||||
|                 })} |                 /> | ||||||
| 
 | 
 | ||||||
|                 {getRenderButton({ |                 <CommandButton | ||||||
|                     iconName: "HandsFree", i18NKey: "Command.Bar.Drag.Info",  |                     iconName="HandsFree" | ||||||
|                     active: mouseMod === MouseMod.Drag, |                     i18NKey="Command.Bar.Drag.Info" | ||||||
|                     click: () => this.props.status ? this.props.status.setMouseMod(MouseMod.Drag) : undefined |                     active={mouseMod === MouseMod.Drag} | ||||||
|                 })} |                     click={() => this.props.status ? this.props.status.setMouseMod(MouseMod.Drag) : undefined} | ||||||
|  |                 /> | ||||||
| 
 | 
 | ||||||
|                 {getRenderButton({ |                 <CommandButton | ||||||
|                     iconName: "TouchPointer", i18NKey: "Command.Bar.Select.Info", |                     iconName="TouchPointer" | ||||||
|                     active: mouseMod === MouseMod.click, |                     i18NKey="Command.Bar.Select.Info" | ||||||
|                     click: () => this.props.status ? this.props.status.setMouseMod(MouseMod.click) : undefined |                     active={mouseMod === MouseMod.click} | ||||||
|                 })} |                     click={() => this.props.status ? this.props.status.setMouseMod(MouseMod.click) : undefined} | ||||||
|  |                 /> | ||||||
| 
 | 
 | ||||||
|                 {getRenderButton({ |                 <CommandButton | ||||||
|                     iconName: "WebAppBuilderFragmentCreate", |                     iconName="WebAppBuilderFragmentCreate" | ||||||
|                     i18NKey: "Command.Bar.Add.Group.Info", |                     i18NKey="Command.Bar.Add.Group.Info" | ||||||
|                     click: () => { |                     click={() => { | ||||||
|                         this.props.status ? this.props.status.newGroup() : undefined; |                         this.props.status ? this.props.status.newGroup() : undefined; | ||||||
|                     } |                     }} | ||||||
|                 })} |                 /> | ||||||
| 
 | 
 | ||||||
|                 {getRenderButton({ |                 <CommandButton | ||||||
|                     iconName: "ProductVariant", |                     iconName="ProductVariant" | ||||||
|                     i18NKey: "Command.Bar.Add.Range.Info", |                     i18NKey="Command.Bar.Add.Range.Info" | ||||||
|                     click: () => { |                     click={() => { | ||||||
|                         this.props.status ? this.props.status.newRange() : undefined; |                         this.props.status ? this.props.status.newRange() : undefined; | ||||||
|                     } |                     }} | ||||||
|                 })} |                 /> | ||||||
| 
 | 
 | ||||||
|                 {getRenderButton({ |                 <CommandButton | ||||||
|                     iconName: "Running", |                     iconName="Running" | ||||||
|                     i18NKey: "Command.Bar.Add.Behavior.Info", |                     i18NKey="Command.Bar.Add.Behavior.Info" | ||||||
|                     click: () => { |                     click={() => { | ||||||
|                         this.props.status?.popup.showPopup(BehaviorPopup, {}); |                         this.props.status?.popup.showPopup(BehaviorPopup, {}); | ||||||
|                     } |                     }} | ||||||
|                 })} |                 /> | ||||||
| 
 | 
 | ||||||
|                 {getRenderButton({ |                 <CommandButton | ||||||
|                     iconName: "Tag", |                     iconName="Tag" | ||||||
|                     i18NKey: "Command.Bar.Add.Tag.Info", |                     i18NKey="Command.Bar.Add.Tag.Info" | ||||||
|                     click: () => { |                     click={() => { | ||||||
|                         this.props.status ? this.props.status.newLabel() : undefined; |                         this.props.status ? this.props.status.newLabel() : undefined; | ||||||
|                     } |                     }} | ||||||
|                 })} |                 /> | ||||||
| 
 | 
 | ||||||
|                 {getRenderButton({ iconName: "Camera", i18NKey: "Command.Bar.Camera.Info" })} |                 <CommandButton | ||||||
|  |                     iconName="Camera" | ||||||
|  |                     i18NKey="Command.Bar.Camera.Info" | ||||||
|  |                 /> | ||||||
|             </div> |             </div> | ||||||
|             <div> |             <div> | ||||||
|                 {getRenderButton({ |                 <CommandButton | ||||||
|                     iconName: "Settings", |                     iconName="Settings" | ||||||
|                     i18NKey: "Command.Bar.Setting.Info", |                     i18NKey="Command.Bar.Setting.Info" | ||||||
|                     click: () => { |                     click={() => { | ||||||
|                         this.props.status?.popup.showPopup(SettingPopup, {}); |                         this.props.status?.popup.showPopup(SettingPopup, {}); | ||||||
|                     } |                     }} | ||||||
|                 })} |                 /> | ||||||
|             </div> |             </div> | ||||||
|         </Theme> |         </Theme> | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -64,7 +64,7 @@ async function fileChecker(status: Status, file?: File) { | |||||||
| 			const loadFunc = () => { | 			const loadFunc = () => { | ||||||
| 
 | 
 | ||||||
| 				// 进行转换
 | 				// 进行转换
 | ||||||
| 				let errorMessage = status.archive.load(status.model, fileReader.result as string, file.name); | 				let errorMessage = status.archive.load(status.model, fileReader.result as string, file.name, file.path); | ||||||
| 				if (errorMessage) { | 				if (errorMessage) { | ||||||
| 					status.popup.showPopup(ConfirmPopup, { | 					status.popup.showPopup(ConfirmPopup, { | ||||||
| 						infoI18n: "Popup.Load.Save.Error.Parse", | 						infoI18n: "Popup.Load.Save.Error.Parse", | ||||||
|  | |||||||
| @ -29,7 +29,7 @@ const ArchiveSaveDownloadView: FunctionComponent<IFileInfo & ICallBackProps> = f | |||||||
| 		setTimeout(() => { | 		setTimeout(() => { | ||||||
| 			download(file, props.fileName, "text/json"); | 			download(file, props.fileName, "text/json"); | ||||||
| 			props.then(); | 			props.then(); | ||||||
| 		}, 10); | 		}, 100); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	useEffect(() => { runner() }, []); | 	useEffect(() => { runner() }, []); | ||||||
| @ -44,15 +44,17 @@ function ArchiveSaveFsView(props) { | |||||||
| 
 | 
 | ||||||
| 	const runner = async () => { | 	const runner = async () => { | ||||||
| 		const file = await props.fileData(); | 		const file = await props.fileData(); | ||||||
| 		if (props.electron) { | 		setTimeout(() => { | ||||||
| 			props.electron.fileSave( | 			if (props.electron) { | ||||||
| 				file, | 				props.electron.fileSave( | ||||||
| 				I18N(props, "Popup.Load.Save.Select.File.Name"), | 					file, | ||||||
| 				I18N(props, "Popup.Load.Save.Select.Path.Title"), | 					I18N(props, "Popup.Load.Save.Select.File.Name"), | ||||||
| 				I18N(props, "Popup.Load.Save.Select.Path.Button"), | 					I18N(props, "Popup.Load.Save.Select.Path.Title"), | ||||||
| 				props.fileUrl | 					I18N(props, "Popup.Load.Save.Select.Path.Button"), | ||||||
| 			); | 					props.fileUrl | ||||||
| 		} | 				); | ||||||
|  | 			} | ||||||
|  | 		}, 100); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	const saveEvent = ({name, url, success} : {name: string, url: string, success: boolean}) => { | 	const saveEvent = ({name, url, success} : {name: string, url: string, success: boolean}) => { | ||||||
|  | |||||||
| @ -266,6 +266,7 @@ class Archive extends Emitter<IArchiveEvent> { | |||||||
|         this.fileName = name; |         this.fileName = name; | ||||||
|         this.isSaved = true; |         this.isSaved = true; | ||||||
|         this.isNewFile = false; |         this.isNewFile = false; | ||||||
|  |         this.fileUrl = url; | ||||||
|         this.emit("fileSave", this); |         this.emit("fileSave", this); | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,4 +1,6 @@ | |||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
|  | import { DndProvider } from 'react-dnd' | ||||||
|  | import { HTML5Backend } from 'react-dnd-html5-backend' | ||||||
| import { SettingProvider, Setting, Platform } from "@Context/Setting"; | import { SettingProvider, Setting, Platform } from "@Context/Setting"; | ||||||
| import { Theme, BackgroundLevel, FontLevel } from "@Component/Theme/Theme"; | import { Theme, BackgroundLevel, FontLevel } from "@Component/Theme/Theme"; | ||||||
| import { ISimulatorAPI } from "@Electron/SimulatorAPI"; | import { ISimulatorAPI } from "@Electron/SimulatorAPI"; | ||||||
| @ -9,10 +11,10 @@ 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 { LoadFile } from "@Component/LoadFile/LoadFile"; | ||||||
| import { HeaderBar } from "@Component/HeaderBar/HeaderBar"; | import { HeaderBar } from "@Component/HeaderBar/HeaderBar"; | ||||||
| import { Popup } from "@Component/Popup/Popup"; | import { Popup } from "@Component/Popup/Popup"; | ||||||
| import { Entry } from "../Entry/Entry"; | import { Entry } from "../Entry/Entry"; | ||||||
| import { Group } from "@Model/Group"; |  | ||||||
| import "./SimulatorDesktop.scss"; | import "./SimulatorDesktop.scss"; | ||||||
| 
 | 
 | ||||||
| initializeIcons("./font-icon/"); | initializeIcons("./font-icon/"); | ||||||
| @ -89,7 +91,9 @@ class SimulatorDesktop extends Component { | |||||||
|         return <SettingProvider value={this.setting}> |         return <SettingProvider value={this.setting}> | ||||||
|             <StatusProvider value={this.status}> |             <StatusProvider value={this.status}> | ||||||
|                 <ElectronProvider value={this.electron}> |                 <ElectronProvider value={this.electron}> | ||||||
|                     {this.renderContent()} |                     <DndProvider backend={HTML5Backend}> | ||||||
|  |                         {this.renderContent()} | ||||||
|  |                     </DndProvider> | ||||||
|                 </ElectronProvider> |                 </ElectronProvider> | ||||||
|             </StatusProvider> |             </StatusProvider> | ||||||
|         </SettingProvider> |         </SettingProvider> | ||||||
| @ -102,13 +106,15 @@ class SimulatorDesktop extends Component { | |||||||
|             fontLevel={FontLevel.Level3} |             fontLevel={FontLevel.Level3} | ||||||
|         > |         > | ||||||
|             <Popup/> |             <Popup/> | ||||||
|             <HeaderBar height={35}/> |             <LoadFile> | ||||||
|             <div className="app-root-space" style={{ |                 <HeaderBar height={35}/> | ||||||
|                 height: `calc( 100% - ${35}px)` |                 <div className="app-root-space" style={{ | ||||||
|             }}> |                     height: `calc( 100% - ${35}px)` | ||||||
|                 <CommandBar/> |                 }}> | ||||||
|                 <RootContainer/> |                     <CommandBar/> | ||||||
|             </div> |                     <RootContainer/> | ||||||
|  |                 </div> | ||||||
|  |             </LoadFile> | ||||||
|         </Theme> |         </Theme> | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user