Files
behavior3editor/render-process/Properties.tsx
T

242 lines
7.0 KiB
TypeScript

import React, { Component } from "react";
import { Menu, Input, Tree ,Dropdown} from "antd";
import * as fs from "fs";
import * as path from "path";
import { ipcRenderer } from "electron";
import MainEventType from "../common/MainEventType";
import { DataNode } from "antd/lib/tree";
import { IconType } from "rc-tree/lib/interface";
const { Search } = Input;
const { DirectoryTree } = Tree;
export interface PropertiesProps {
workdir: string;
onOpenTree: (path: string) => void;
onDeleteTree: (path: string) => void;
}
class FileDataNode implements DataNode {
checkable?: boolean;
children?: FileDataNode[];
disabled?: boolean;
disableCheckbox?: boolean;
icon?: IconType;
isLeaf?: boolean;
key: React.ReactText;
title?: React.ReactNode;
selectable?: boolean;
switcherIcon?: IconType;
className?: string;
style?: React.CSSProperties;
parent: FileDataNode;
public constructor(init?: Partial<FileDataNode>) {
Object.assign(this, init);
}
get isFolder() {
return this.isLeaf !== void 0 && !this.isLeaf;
}
get name() {
return this.title as string;
}
get path() {
return this.key as string;
}
loadChilds(recursive?: boolean) {
const folder = this.key as string;
if (folder == "" || !fs.existsSync(folder)) {
return [];
}
const files = fs.readdirSync(folder);
const list: FileDataNode[] = [];
files.forEach((filename) => {
const fullPath = path.join(folder, filename);
const stat = fs.statSync(fullPath);
const isFolder = stat.isDirectory();
const name = isFolder ? filename : filename.slice(0, -5);
const node = new FileDataNode({
title: name,
key: fullPath,
isLeaf: !isFolder,
parent: this,
});
node.children = isFolder&&recursive ? (node.loadChilds(recursive) as FileDataNode[]) : [],
list.push(node);
});
return list;
}
addChild(filePath: string) {
const isDir = fs.statSync(filePath).isDirectory();
const newNode = new FileDataNode({
title: path.basename(filePath),
key: filePath,
isLeaf: !isDir,
parent: this,
children: [],
});
this.children = [newNode, ...this.children];
}
removeFromParent() {
const parent = this.parent;
if (parent) {
const index = parent.children.indexOf(this);
parent.children.splice(index, 1);
}
}
expandSelf(recursive?: boolean) {
if (this.isFolder) this.children = this.loadChilds(recursive);
}
findChild(key: string): FileDataNode {
for (const child of this.children) {
if (child.key == key) {
return child;
} else {
const ret = child.findChild(key);
if (ret) {
return ret;
}
}
}
return null;
}
// name:string;
// path: string;
// isFolder : boolean;
// isEditing?: boolean;
// children?: NodeData[];
}
interface PropertiesState {
root: FileDataNode;
}
const NodeActions: { [x: string]: string } = {
["create"]: "New Tree",
["createFolder"]: "New Folder",
["rename"]: "Rename",
["delete"]: "Delete",
["reveal_in_explorer"]: "Reveal In File Explorer",
};
export default class Properties extends Component<PropertiesProps> {
state: PropertiesState = {
root: null,
};
curWorkdir: string = "";
shouldComponentUpdate(nextProps: PropertiesProps) {
const shouldUpdate = this.curWorkdir != nextProps.workdir;
this.curWorkdir = nextProps.workdir;
return shouldUpdate;
}
componentDidMount() {
ipcRenderer.on(MainEventType.CREATE_TREE, (event: any, path: string) => {
console.log("on Create tree", path);
this.props.onOpenTree(path);
this.state.root.expandSelf();
this.forceUpdate();
});
var workdir = this.props.workdir;
if (workdir == "") {
return;
}
const root = this.getRootNode(workdir);
root.expandSelf();
this.setState({ root: root });
}
getRootNode(workdir: string) {
return new FileDataNode({
title: path.basename(workdir),
key: workdir,
isLeaf: false,
parent: null,
children: [],
});
}
// renderContextMeun(selectedNode: FileDataNode) {
// const actions = Object.keys(NodeActions);
// return (
// <Menu>
// {actions.map((action) => {
// const displayName: string = NodeActions[action];
// return (
// <Menu.Item
// key={action}
// onClick={(info) => {
// //this.handleContextMenu({ node: selectedNode, action:{action} });
// }}
// >{displayName}
// </Menu.Item>
// );
// })}
// </Menu>
// );
// }
// renderNode(node:FileDataNode){
// return (<Dropdown
// overlay={this.renderContextMeun(node)}
// trigger={["contextMenu"]}
// >
// <div>{node.title}</div>
// </Dropdown>)
// }
render() {
console.log("render Properties");
const { onOpenTree, onDeleteTree, workdir } = this.props;
const root = this.state.root;
const nodes = root ? [root] : [];
return nodes.length ? (
<DirectoryTree
selectable
showLine
expandAction="click"
treeData={nodes}
defaultExpandedKeys={[root.key]}
onCheck={(node) => console.log("onCheck")}
onSelect={(keys, info) => {
console.log("onSelect", keys, info);
if (info.node.isLeaf) {
onOpenTree(keys[0] as string);
}
}}
onExpand={(keys, info) => {
console.log("onExpand", info);
if (info.expanded && !info.node.expanded) {
//let newRoot = _.cloneDeep(root);
const node = root.findChild(info.node.key as string);
if (node) {
node.expandSelf();
this.setState({ root: root });
this.forceUpdate();
}
}
}}
onLoad={(keys, info) => console.log("onLoad", keys, info)}
onRightClick={(event) => console.log("onRightClick", event)}
></DirectoryTree>
) : (
`Work Dir (${workdir}) Empty`
);
}
}