Add label list component
This commit is contained in:
parent
c86a856a32
commit
54a03181f1
@ -37,6 +37,7 @@ div.color-input-root {
|
||||
div.color-box {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,13 @@ class CommandBar extends Component<ICommandBarProps & IMixinSettingProps & IMixi
|
||||
}
|
||||
})}
|
||||
{this.getRenderButton({ iconName: "StepSharedAdd", i18NKey: "Command.Bar.Add.Behavior.Info" })}
|
||||
{this.getRenderButton({ iconName: "Tag", i18NKey: "Command.Bar.Add.Tag.Info" })}
|
||||
{this.getRenderButton({
|
||||
iconName: "Tag",
|
||||
i18NKey: "Command.Bar.Add.Tag.Info",
|
||||
click: () => {
|
||||
this.props.status ? this.props.status.newLabel() : undefined;
|
||||
}
|
||||
})}
|
||||
{this.getRenderButton({ iconName: "Camera", i18NKey: "Command.Bar.Camera.Info" })}
|
||||
</div>
|
||||
<div>
|
||||
|
64
source/Component/LabelList/LabelList.scss
Normal file
64
source/Component/LabelList/LabelList.scss
Normal file
@ -0,0 +1,64 @@
|
||||
@import "../Theme/Theme.scss";
|
||||
|
||||
div.label {
|
||||
width: auto;
|
||||
height: auto;
|
||||
display: inline-flex;
|
||||
margin: 5px 5px;
|
||||
justify-content: center;
|
||||
vertical-align: middle;
|
||||
align-items: stretch;
|
||||
border-radius: 3px;
|
||||
border: .5px solid transparent;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
|
||||
div.label-color {
|
||||
width: 3px;
|
||||
margin-right: 2px;
|
||||
border-radius: 3px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
div.label-name {
|
||||
padding: 2px 3px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
div.delete-button {
|
||||
padding: 2px 3px;
|
||||
border-radius: 3px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
div.dark.label {
|
||||
background-color: $lt-bg-color-lvl3-dark;
|
||||
|
||||
div.label-color {
|
||||
color: $lt-bg-color-lvl3-dark;
|
||||
}
|
||||
|
||||
div.delete-button:hover {
|
||||
color: $lt-font-color-lvl2-dark;
|
||||
background-color: $lt-bg-color-lvl2-dark;
|
||||
}
|
||||
}
|
||||
|
||||
div.light.label {
|
||||
background-color: $lt-bg-color-lvl3-light;
|
||||
|
||||
div.label-color {
|
||||
color: $lt-bg-color-lvl3-light;
|
||||
}
|
||||
|
||||
div.delete-button:hover {
|
||||
color: $lt-font-color-lvl2-light;
|
||||
background-color: $lt-bg-color-lvl2-light;
|
||||
}
|
||||
}
|
56
source/Component/LabelList/LabelList.tsx
Normal file
56
source/Component/LabelList/LabelList.tsx
Normal file
@ -0,0 +1,56 @@
|
||||
import { Component } from "react";
|
||||
import { Label } from "@Model/Label";
|
||||
import { Icon } from "@fluentui/react";
|
||||
import { useSetting, IMixinSettingProps, Themes } from "@Context/Setting";
|
||||
import "./LabelList.scss";
|
||||
|
||||
interface ILabelListProps {
|
||||
labels: Label[];
|
||||
canDelete?: boolean;
|
||||
}
|
||||
|
||||
interface ILabelListState {
|
||||
focusLabel?: Label;
|
||||
}
|
||||
|
||||
@useSetting
|
||||
class LabelList extends Component<ILabelListProps & IMixinSettingProps, ILabelListState> {
|
||||
|
||||
public state: Readonly<ILabelListState> = {
|
||||
focusLabel: undefined
|
||||
};
|
||||
|
||||
private renderLabel(label: Label) {
|
||||
|
||||
const theme = this.props.setting?.themes ?? Themes.dark;
|
||||
const themeClassName = theme === Themes.dark ? "dark" : "light";
|
||||
const colorCss = `rgb(${label.color.join(",")})`;
|
||||
|
||||
return <div className={`label ${themeClassName}`} key={label.id}>
|
||||
<div className="label-color" style={{
|
||||
backgroundColor: colorCss
|
||||
}}/>
|
||||
<div className="label-name">
|
||||
{label.name}
|
||||
</div>
|
||||
{
|
||||
this.props.canDelete ?
|
||||
<div className="delete-button">
|
||||
<Icon iconName="delete"></Icon>
|
||||
</div> : null
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
public render() {
|
||||
return <>
|
||||
{
|
||||
this.props.labels.map((label) => {
|
||||
return this.renderLabel(label);
|
||||
})
|
||||
}
|
||||
</>
|
||||
}
|
||||
}
|
||||
|
||||
export { LabelList };
|
@ -8,12 +8,18 @@ import { ClassicRenderer, MouseMod } from "@GLRender/ClassicRenderer";
|
||||
import { Setting } from "./Setting";
|
||||
import { I18N } from "@Component/Localization/Localization";
|
||||
|
||||
function randomColor() {
|
||||
return [
|
||||
function randomColor(unNormal: boolean = false) {
|
||||
const color = [
|
||||
Math.random() * .8 + .2,
|
||||
Math.random() * .8 + .2,
|
||||
Math.random() * .8 + .2, 1
|
||||
]
|
||||
if (unNormal) {
|
||||
color[0] = Math.round(color[0] * 255),
|
||||
color[1] = Math.round(color[1] * 255),
|
||||
color[2] = Math.round(color[2] * 255)
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
interface IStatusEvent {
|
||||
@ -34,6 +40,7 @@ class Status extends Emitter<IStatusEvent> {
|
||||
* 对象命名
|
||||
*/
|
||||
public objectNameIndex = 1;
|
||||
public labelNameIndex = 1;
|
||||
|
||||
/**
|
||||
* 渲染器
|
||||
@ -123,6 +130,17 @@ class Status extends Emitter<IStatusEvent> {
|
||||
return range;
|
||||
}
|
||||
|
||||
public newLabel() {
|
||||
const label = this.model.addLabel(
|
||||
I18N(this.setting.language, "Object.List.New.Label", {
|
||||
id: this.labelNameIndex.toString()
|
||||
})
|
||||
);
|
||||
label.color = randomColor(true);
|
||||
this.labelNameIndex ++;
|
||||
return label;
|
||||
}
|
||||
|
||||
public setMouseMod(mod: MouseMod) {
|
||||
this.mouseMod = mod;
|
||||
if (this.renderer instanceof ClassicRenderer) {
|
||||
|
@ -25,6 +25,7 @@ const EN_US = {
|
||||
"Input.Error.Length": "The length of the input content must be less than {num}",
|
||||
"Object.List.New.Group": "Group object {id}",
|
||||
"Object.List.New.Range": "Range object {id}",
|
||||
"Object.List.New.Label": "Label {id}",
|
||||
"Object.List.No.Data": "There are no objects in the model, click the button to create it",
|
||||
"Panel.Title.Notfound": "{id}",
|
||||
"Panel.Info.Notfound": "This panel with id {id} can not found!",
|
||||
|
@ -25,6 +25,7 @@ const ZH_CN = {
|
||||
"Input.Error.Length": "输入内容长度须小于 {number}",
|
||||
"Object.List.New.Group": "组对象 {id}",
|
||||
"Object.List.New.Range": "范围对象 {id}",
|
||||
"Object.List.New.Label": "标签 {id}",
|
||||
"Object.List.No.Data": "模型中没有任何对象,点击按钮以创建",
|
||||
"Panel.Title.Notfound": "{id}",
|
||||
"Panel.Info.Notfound": "这个编号为 {id} 的面板无法找到!",
|
||||
|
@ -14,12 +14,12 @@ class Label {
|
||||
/**
|
||||
* 用户定义的名称
|
||||
*/
|
||||
public name?: string;
|
||||
public name: string = "";
|
||||
|
||||
/**
|
||||
* CSS 颜色
|
||||
*/
|
||||
public color?: string;
|
||||
public color: number[] = [0, 0, 0];
|
||||
|
||||
/**
|
||||
* 所属模型
|
||||
@ -31,10 +31,10 @@ class Label {
|
||||
* @param id 标签 ID
|
||||
* @param name 用户定义的名称
|
||||
*/
|
||||
public constructor(model:Model, id: ObjectID, name?: string) {
|
||||
public constructor(model: Model, id: ObjectID, name?: string) {
|
||||
this.model = model;
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.name = name ?? this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -51,6 +51,8 @@ class SimulatorWeb extends Component {
|
||||
individual.position[2] = (Math.random() - .5) * 2;
|
||||
})
|
||||
this.status.model.update(0);
|
||||
this.status.newLabel().name = "New Label";
|
||||
this.status.newLabel().name = "Test Label 01";
|
||||
}
|
||||
|
||||
(window as any).s = this;
|
||||
|
@ -1,3 +1,4 @@
|
||||
@import "../../Component/Theme/Theme.scss";
|
||||
|
||||
div.label-list-command-bar {
|
||||
width: 100%;
|
||||
@ -15,4 +16,18 @@ div.label-list-command-bar {
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
div.dark.label-list-command-bar {
|
||||
|
||||
div.command-item:hover {
|
||||
background-color: $lt-bg-color-lvl3-dark;
|
||||
}
|
||||
}
|
||||
|
||||
div.light.label-list-command-bar {
|
||||
|
||||
div.command-item:hover {
|
||||
background-color: $lt-bg-color-lvl3-light;
|
||||
}
|
||||
}
|
@ -1,15 +1,23 @@
|
||||
import { Theme } from "@Component/Theme/Theme";
|
||||
import { LabelList as LabelListComponent } from "@Component/LabelList/LabelList";
|
||||
import { Component } from "react";
|
||||
import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status";
|
||||
import { Label } from "@Model/Label";
|
||||
import "./LabelList.scss";
|
||||
|
||||
interface ILabelListProps {
|
||||
|
||||
}
|
||||
|
||||
class LabelList extends Component<ILabelListProps> {
|
||||
@useStatusWithEvent("labelChange")
|
||||
class LabelList extends Component<ILabelListProps & IMixinStatusProps> {
|
||||
|
||||
public render() {
|
||||
return <Theme>LabelList</Theme>
|
||||
let labels: Label[] = [];
|
||||
if (this.props.status) {
|
||||
labels = this.props.status.model.labelPool.concat([]);
|
||||
}
|
||||
return <LabelListComponent labels={labels} canDelete/>
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
import { BackgroundLevel, FontLevel, Theme } from "@Component/Theme/Theme";
|
||||
import { Icon } from "@fluentui/react";
|
||||
import { Component } from "react";
|
||||
import "./LabelList.scss";
|
||||
|
||||
interface ILabelListCommandProps {}
|
||||
|
||||
class LabelListCommand extends Component<ILabelListCommandProps> {
|
||||
|
||||
public render() {
|
||||
return <Theme
|
||||
className="label-list-command-bar"
|
||||
backgroundLevel={BackgroundLevel.Level4}
|
||||
fontLevel={FontLevel.normal}
|
||||
>
|
||||
<div className="command-item">
|
||||
<Icon iconName="Tag"></Icon>
|
||||
</div>
|
||||
</Theme>
|
||||
}
|
||||
}
|
||||
|
||||
export { LabelListCommand };
|
@ -6,7 +6,6 @@ import { ObjectList } from "./ObjectList/ObjectList";
|
||||
import { ObjectCommand } from "./ObjectList/ObjectCommand";
|
||||
import { RangeDetails } from "./RangeDetails/RangeDetails";
|
||||
import { LabelList } from "./LabelList/LabelList";
|
||||
import { LabelListCommand } from "./LabelList/LabelListCommand";
|
||||
|
||||
interface IPanelInfo {
|
||||
nameKey: string;
|
||||
@ -41,7 +40,7 @@ PanelInfoMap.set("RangeDetails", {
|
||||
})
|
||||
PanelInfoMap.set("LabelList", {
|
||||
nameKey: "Panel.Title.Label.List.View", introKay: "Panel.Info.Label.List.View",
|
||||
class: LabelList, header: LabelListCommand, hidePadding: true
|
||||
class: LabelList
|
||||
})
|
||||
|
||||
function getPanelById(panelId: PanelId): ReactNode {
|
||||
|
Loading…
Reference in New Issue
Block a user