Rebuild commond bar component

This commit is contained in:
MrKBear 2022-04-26 16:42:02 +08:00
parent ec3aaa5e3a
commit 23ebbeb120
6 changed files with 133 additions and 90 deletions

View File

@ -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);
} }

View File

@ -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>
} }

View File

@ -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",

View File

@ -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,6 +44,7 @@ function ArchiveSaveFsView(props) {
const runner = async () => { const runner = async () => {
const file = await props.fileData(); const file = await props.fileData();
setTimeout(() => {
if (props.electron) { if (props.electron) {
props.electron.fileSave( props.electron.fileSave(
file, file,
@ -53,6 +54,7 @@ function ArchiveSaveFsView(props) {
props.fileUrl 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}) => {

View File

@ -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);
}; };

View File

@ -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}>
<DndProvider backend={HTML5Backend}>
{this.renderContent()} {this.renderContent()}
</DndProvider>
</ElectronProvider> </ElectronProvider>
</StatusProvider> </StatusProvider>
</SettingProvider> </SettingProvider>
@ -102,6 +106,7 @@ class SimulatorDesktop extends Component {
fontLevel={FontLevel.Level3} fontLevel={FontLevel.Level3}
> >
<Popup/> <Popup/>
<LoadFile>
<HeaderBar height={35}/> <HeaderBar height={35}/>
<div className="app-root-space" style={{ <div className="app-root-space" style={{
height: `calc( 100% - ${35}px)` height: `calc( 100% - ${35}px)`
@ -109,6 +114,7 @@ class SimulatorDesktop extends Component {
<CommandBar/> <CommandBar/>
<RootContainer/> <RootContainer/>
</div> </div>
</LoadFile>
</Theme> </Theme>
} }
} }