Add command bar tooltips

This commit is contained in:
MrKBear 2022-02-27 21:03:32 +08:00
parent 57b13b551f
commit 7cd501c780
7 changed files with 126 additions and 54 deletions

View File

@ -1,5 +1,7 @@
import { BackgroundLevel, Theme } from "@Component/Theme/Theme"; import { BackgroundLevel, Theme } from "@Component/Theme/Theme";
import { IconButton } from "@fluentui/react"; import { DirectionalHint, IconButton } from "@fluentui/react";
import { LocalizationTooltipHost } from "../Localization/LocalizationTooltipHost";
import { AllI18nKeys } from "../Localization/Localization";
import { Component, ReactNode } from "react"; import { Component, ReactNode } from "react";
import "./CommandBar.scss"; import "./CommandBar.scss";
@ -16,51 +18,39 @@ class CommandBar extends Component<ICommandBarProps> {
style={{ width: this.props.width }} style={{ width: this.props.width }}
> >
<div> <div>
<IconButton {this.getRenderButton({ iconName: "Save", i18NKey: "Command.Bar.Save.Info" })}
style={{ height: this.props.width }} {this.getRenderButton({ iconName: "Play", i18NKey: "Command.Bar.Play.Info" })}
iconProps={{iconName: "Save"}} {this.getRenderButton({ iconName: "HandsFree", i18NKey: "Command.Bar.Drag.Info" })}
className="command-button" {this.getRenderButton({ iconName: "TouchPointer", i18NKey: "Command.Bar.Select.Info" })}
/> {this.getRenderButton({ iconName: "WebAppBuilderFragmentCreate", i18NKey: "Command.Bar.Add.Group.Info" })}
<IconButton {this.getRenderButton({ iconName: "CubeShape", i18NKey: "Command.Bar.Add.Range.Info" })}
style={{ height: this.props.width }} {this.getRenderButton({ iconName: "StepSharedAdd", i18NKey: "Command.Bar.Add.Behavior.Info" })}
iconProps={{iconName: "HandsFree"}} {this.getRenderButton({ iconName: "Tag", i18NKey: "Command.Bar.Add.Tag.Info" })}
className="command-button" {this.getRenderButton({ iconName: "Camera", i18NKey: "Command.Bar.Camera.Info" })}
/>
<IconButton
style={{ height: this.props.width }}
iconProps={{iconName: "TouchPointer"}}
className="command-button"
/>
<IconButton
style={{ height: this.props.width }}
iconProps={{iconName: "Camera"}}
className="command-button"
/>
<IconButton
style={{ height: this.props.width }}
iconProps={{iconName: "Play"}}
className="command-button"
/>
<IconButton
style={{ height: this.props.width }}
iconProps={{iconName: "PlayResume"}}
className="command-button"
/>
<IconButton
style={{ height: this.props.width }}
iconProps={{iconName: "PlayReverseResume"}}
className="command-button"
/>
</div> </div>
<div> <div>
<IconButton {this.getRenderButton({ iconName: "Settings", i18NKey: "Command.Bar.Setting.Info" })}
style={{ height: this.props.width }}
iconProps={{iconName: "Settings"}}
className="command-button on-end"
/>
</div> </div>
</Theme> </Theme>
} }
private getRenderButton(param: {
i18NKey: AllI18nKeys;
iconName?: string;
click?: () => void;
}): ReactNode {
return <LocalizationTooltipHost
i18nKey={param.i18NKey}
directionalHint={DirectionalHint.rightCenter}
>
<IconButton
style={{ height: this.props.width }}
iconProps={{ iconName: param.iconName }}
onClick={ param.click }
className="command-button on-end"
/>
</LocalizationTooltipHost>
}
} }
export { CommandBar }; export { CommandBar };

View File

@ -3,6 +3,7 @@ import { useStatus, IMixinStatusProps } from "@Context/Status";
import { useSetting, IMixinSettingProps } from "@Context/Setting"; import { useSetting, IMixinSettingProps } from "@Context/Setting";
import { Theme, BackgroundLevel, FontLevel } from "@Component/Theme/Theme"; import { Theme, BackgroundLevel, FontLevel } from "@Component/Theme/Theme";
import { Icon } from '@fluentui/react/lib/Icon'; import { Icon } from '@fluentui/react/lib/Icon';
import { LocalizationTooltipHost } from "../Localization/LocalizationTooltipHost";
import { I18N } from "../Localization/Localization"; import { I18N } from "../Localization/Localization";
import "./HeaderBar.scss"; import "./HeaderBar.scss";
import { Tooltip, TooltipHost } from "@fluentui/react"; import { Tooltip, TooltipHost } from "@fluentui/react";
@ -100,29 +101,31 @@ class HeaderBar extends Component<
fontLevel={FontLevel.Level3} fontLevel={FontLevel.Level3}
style={{ height: this.props.height }} style={{ height: this.props.height }}
> >
<TooltipHost content={I18N(this.props, "Header.Bar.Title.Info")}> <LocalizationTooltipHost i18nKey="Header.Bar.Title.Info">
<div className="title"> <div className="title">
<Icon iconName="HomeGroup"></Icon> <Icon iconName="HomeGroup"></Icon>
<span>{I18N(this.props, "Header.Bar.Title")}</span> <span>{I18N(this.props, "Header.Bar.Title")}</span>
</div> </div>
</TooltipHost> </LocalizationTooltipHost>
<TooltipHost content={I18N(this.props, "Header.Bar.File.Name.Info", { <LocalizationTooltipHost i18nKey="Header.Bar.File.Name.Info"
file: isNewFile ? I18N(this.props, "Header.Bar.New.File.Name") : fileName, options={{
status: isSaved ? I18N(this.props, "Header.Bar.File.Save.Status.Saved") : file: isNewFile ? I18N(this.props, "Header.Bar.New.File.Name") : fileName,
I18N(this.props, "Header.Bar.File.Save.Status.Unsaved") status: isSaved ? I18N(this.props, "Header.Bar.File.Save.Status.Saved") :
})}> I18N(this.props, "Header.Bar.File.Save.Status.Unsaved")
}}
>
<div className="file-name">{ <div className="file-name">{
isNewFile ? I18N(this.props, "Header.Bar.New.File.Name") : fileName isNewFile ? I18N(this.props, "Header.Bar.New.File.Name") : fileName
}{ }{
isSaved ? "" : "*" isSaved ? "" : "*"
}</div> }</div>
</TooltipHost> </LocalizationTooltipHost>
<TooltipHost content={I18N(this.props, "Header.Bar.Fps.Info", fpsInfo)}> <LocalizationTooltipHost i18nKey="Header.Bar.Fps.Info" options={fpsInfo}>
<div className="fps-view"> <div className="fps-view">
<Icon iconName="SpeedHigh"></Icon> <Icon iconName="SpeedHigh"></Icon>
<span>{I18N(this.props, "Header.Bar.Fps", fpsInfo)}</span> <span>{I18N(this.props, "Header.Bar.Fps", fpsInfo)}</span>
</div> </div>
</TooltipHost> </LocalizationTooltipHost>
</Theme> </Theme>
} }
} }

View File

@ -9,9 +9,11 @@ const LanguageDataBase = {
EN_US, ZH_CN EN_US, ZH_CN
} }
type AllI18nKeys = keyof typeof EN_US;
interface ILocalizationProps { interface ILocalizationProps {
className?: string; className?: string;
i18nKey: keyof typeof EN_US; i18nKey: AllI18nKeys;
options?: Record<string, string>; options?: Record<string, string>;
} }
@ -73,4 +75,4 @@ class Localization extends Component<ILocalizationProps & IMixinSettingProps &
} }
} }
export { Localization, I18N }; export { Localization, I18N, LanguageDataBase, AllI18nKeys };

View File

@ -0,0 +1,57 @@
import { Component, ReactNode } from "react";
import { TooltipHost, ITooltipHostProps } from "@fluentui/react";
import { useSetting, IMixinSettingProps, Language } from "@Context/Setting";
import { I18N, AllI18nKeys } from "./Localization";
import "./Localization.scss";
interface ILocalizationTooltipHostProps {
className?: string;
i18nKey: AllI18nKeys;
options?: Record<string, string>;
}
/**
*
*/
@useSetting
class LocalizationTooltipHost extends Component<ILocalizationTooltipHostProps & IMixinSettingProps &
ITooltipHostProps
> {
private handelLanguageChange = () => {
this.forceUpdate();
}
public componentDidMount() {
if (this.props.setting) {
this.props.setting.on("language", this.handelLanguageChange);
}
}
public componentWillUnmount() {
if (this.props.setting) {
this.props.setting.off("language", this.handelLanguageChange);
}
}
public render(): ReactNode {
let language: Language = this.props.setting ? this.props.setting.language : "EN_US";
let classNameList: string[] = [];
if (this.props.className) classNameList.push(this.props.className);
classNameList.push(language);
let safeProps = {...this.props};
delete safeProps.className;
delete safeProps.setting;
delete (safeProps as any).i18nKey;
delete safeProps.options;
return <TooltipHost
{...safeProps}
className={classNameList.join(" ")}
content={I18N(language, this.props.i18nKey, this.props.options)}
>
{this.props.children}
</TooltipHost>
}
}
export { LocalizationTooltipHost };

View File

@ -9,5 +9,15 @@ const EN_US = {
"Header.Bar.File.Save.Status.Unsaved": "UnSaved", "Header.Bar.File.Save.Status.Unsaved": "UnSaved",
"Header.Bar.Fps": "FPS: {renderFps} | {physicsFps}", "Header.Bar.Fps": "FPS: {renderFps} | {physicsFps}",
"Header.Bar.Fps.Info": "The rendering frame rate ({renderFps} fps) is on the left, and the simulation frame rate ({physicsFps} fps) is on the right.", "Header.Bar.Fps.Info": "The rendering frame rate ({renderFps} fps) is on the left, and the simulation frame rate ({physicsFps} fps) is on the right.",
"Command.Bar.Save.Info": "Save",
"Command.Bar.Play.Info": "Start simulation",
"Command.Bar.Drag.Info": "Drag and drop to move the camera",
"Command.Bar.Select.Info": "Select object",
"Command.Bar.Add.Group.Info": "Add group object",
"Command.Bar.Add.Range.Info": "Add scope object",
"Command.Bar.Add.Behavior.Info": "Add behavior object",
"Command.Bar.Add.Tag.Info": "Add label object",
"Command.Bar.Camera.Info": "Renderer settings",
"Command.Bar.Setting.Info": "Global Settings",
} }
export default EN_US; export default EN_US;

View File

@ -9,5 +9,15 @@ const ZH_CN = {
"Header.Bar.File.Save.Status.Unsaved": "未保存", "Header.Bar.File.Save.Status.Unsaved": "未保存",
"Header.Bar.Fps": "帧率: {renderFps} | {physicsFps}", "Header.Bar.Fps": "帧率: {renderFps} | {physicsFps}",
"Header.Bar.Fps.Info": "左侧为渲染帧率 ({renderFps} fps), 右侧为模拟帧率 ({physicsFps} fps)。", "Header.Bar.Fps.Info": "左侧为渲染帧率 ({renderFps} fps), 右侧为模拟帧率 ({physicsFps} fps)。",
"Command.Bar.Save.Info": "保存",
"Command.Bar.Play.Info": "开始仿真",
"Command.Bar.Drag.Info": "拖拽进行视角移动",
"Command.Bar.Select.Info": "选择对象",
"Command.Bar.Add.Group.Info": "添加群对象",
"Command.Bar.Add.Range.Info": "添加范围对象",
"Command.Bar.Add.Behavior.Info": "添加行为对象",
"Command.Bar.Add.Tag.Info": "添加标签对象",
"Command.Bar.Camera.Info": "渲染器设置",
"Command.Bar.Setting.Info": "全局设置",
} }
export default ZH_CN; export default ZH_CN;

View File

@ -9,7 +9,7 @@ import { initializeIcons } from '@fluentui/font-icons-mdl2';
import "./SimulatorWeb.scss"; import "./SimulatorWeb.scss";
import { CommandBar } from "@Component/CommandBar/CommandBar"; import { CommandBar } from "@Component/CommandBar/CommandBar";
initializeIcons("http://cdn.mrkbear.com/fabric-cdn-prod_20210407.001/"); initializeIcons("https://img.mrkbear.com/fabric-cdn-prod_20210407.001/");
class SimulatorWeb extends Component { class SimulatorWeb extends Component {