Skip to content
Snippets Groups Projects
Commit 1e1bd405 authored by Maximilian Giller's avatar Maximilian Giller :squid:
Browse files

Connected first components to editor backend, but still WIP

parent f896d95b
No related branches found
No related tags found
1 merge request!2Implemented editor in the react framework
Pipeline #56366 failed
...@@ -3,3 +3,5 @@ import "./editor/css/editor.css"; ...@@ -3,3 +3,5 @@ import "./editor/css/editor.css";
import "./display/display"; import "./display/display";
import "./editor/js/editor"; import "./editor/js/editor";
// TODO: Is this file deprecated?
import React from "react";
import ReactDOM from "react-dom";
import "./editor/css/editor.css";
import "./editor/js/editor";
import { Editor } from "./editor/js/components/editor";
ReactDOM.render(<Editor />, document.getElementById("ks-editor"));
<div id="ks-editor"> <div id="ks-editor"></div>
<!--The id "ks-editor" indicates, that the javascript associated with this should automatically be executed--> \ No newline at end of file
<h1>Interface</h1>
<div id="box-select-layer"><div id="2d-graph"></div></div>
<section id="toolbar"></section>
<section id="tool-menu">
<div id="delete-menu" class="hidden">
<p>Drag and drop while pressing SHIFT to delete all the nodes that are being selected.</p>
</div>
<div id="collect-menu" class="hidden">
<h3>Collected items</h3>
<button id="clear-collection">Clear</button>
<ul id="selected-items"></ul>
</div>
<div id="select-menu" class="">
<p id="nothing-selected">Nothing selected</p>
<div id="node-selected" class="hidden">
<label for="node-name" hidden>Name</label>
</br>
<input type="text" id="node-name" name="node-name" placeholder="Enter name" class="bottom-space"></input>
</br>
<label for="node-description">Description</label>
</br>
<textarea id="node-description" name="node-description" class="bottom-space"></textarea>
</br>
<label for="node-image">Node Image</label>
</br>
<img id="node-image-preview" style="color:red" class="preview-image" src="" />
</br>
<input type="text" id="node-image" name="node-image" placeholder="Enter file name or URL" class="bottom-space" />
</br>
<label for="node-detail-image">Info Image</label>
</br>
<img id="node-detail-image-preview" style="color:red" class="preview-image" src="" />
</br>
<input type="text" id="node-detail-image" name="node-detail-image" placeholder="Enter file name or URL" class="bottom-space" />
</br>
<label for="node-type">Type</label>
</br>
<select id="node-type" name="node-type" class="bottom-space">
<option value="Vorlesung">Vorlesung</option>
<option value="Algorithmus">Algorithmus</option>
<option value="Definition">Definition</option>
<option value="Beispiel">Beispiel</option>
<option value="Übung">Übung</option>
<option value="Kapitel">Kapitel</option>
</select>
</br>
<label for="node-video">Video</label>
</br>
<input type="text" placeholder="Video URL" id="node-video" name="node-video"></input>
</br>
<label for="node-references">References</label> <small>One URL per line</small>
</br>
<textarea id="node-references" name="node-references" class="bottom-space"></textarea>
</div>
<div id="link-selected" class="hidden">
<h3 id="link-name"></h3>
</div>
</div>
<div id="settings-menu" class="hidden" checked>
<label for="label-toggle" class="bottom-space">
<input type="checkbox" checked id="label-toggle" name="label-toggle"></input>
Show labels in graph
</label>
</br>
</br>
<h3>Space</h3>
<label for="space-id-select">Currently open</label>
</br>
<select id="space-id-select" name="space-id-select" class="bottom-space">
</select>
</br>
</br>
<h3>Physics Simulation</h3>
<button id="reanimate-button" name="reanimate-button" class="bottom-space">Re-simulate</button>
</br>
<label for="stop-physics-delay">Amount of time [in seconds] after which the physics simulation is stopped</label>
</br>
<input type="number" onkeypress="return (event.charCode !=8 && event.charCode ==0 || (event.charCode >= 48 && event.charCode <= 57))" value="5" id="stop-physics-delay" name="stop-physics-delay" class="small-width">
</input>
</br>
</br>
<h3>Import Space</h3>
<label for="import-space-area">Space JSON</label>
</br>
<textarea id="import-space-area" name="import-space-area" class="bottom-space">
</textarea>
</br>
<label for="import-space-name-text">Space Name</label>
</br>
<input type="text" id="import-space-name-text" name="import-space-name-text" class="bottom-space">
</input>
</br>
<button id="import-space-btn" name="import-space-btn" class="bottom-space">Import</button>
</br>
</br>
</div>
</section>
</div>
\ No newline at end of file
import React from "react";
import { Tool } from "../structures/editor/tools/tool";
import { ToolBar } from "./toolbar";
export class Editor extends React.Component {
state: {
currentTool: Tool;
previousTool: Tool;
};
constructor(props: any) {
super(props);
}
/**
* Sets current tool. Select events not triggered if already selected.
* @param tool New tool to select.
*/
public setTool(tool: Tool) {
if (this.state.currentTool == tool) {
return;
}
this.setState({ currentTool: tool });
}
/**
* If exists, sets previously selected tool as current tool.
*/
public setPreviousTool() {
if (this.state.previousTool === undefined) {
return;
}
this.setTool(this.state.previousTool);
}
/**
* @returns Tool that is currently selected.
*/
public getCurrentTool(): Tool {
return this.state.currentTool;
}
render(): React.ReactNode {
return (
<div id="ks-editor">
<ToolBar editor={this}></ToolBar>
</div>
);
}
}
import React from "react";
import { Editor } from "./editor";
type ToolBarProps = { editor: Editor };
export class ToolBar extends React.Component {
props: ToolBarProps;
constructor(props: ToolBarProps) {
super(props);
}
}
import React from "react";
import { Tool } from "../structures/editor/tools/tool";
import { Editor } from "./editor";
type ToolItemProps = { tool: Tool; editor: Editor };
class ToolItem extends React.Component {
state = {};
props: ToolItemProps;
constructor(props: ToolItemProps) {
super(props);
}
/**
* Handles the click-on-tool-icon event.
*/
private handleClick() {
if (this.props.editor.getCurrentTool() !== this.props.tool) {
// Not selected, so select
this.props.editor.setTool(this.props.tool);
return;
}
// Is already set, so only unset, if tool is toggleable
if (!this.props.tool.isToggleable) {
return;
}
this.props.editor.setPreviousTool();
}
public render() {
return (
<button
id={this.props.tool.id}
title={this.props.tool.name}
onClick={this.handleClick}
>
<img src={this.props.tool.icon} />
</button>
);
}
}
...@@ -86,40 +86,6 @@ export class PREVIOUSGraph extends ManagedData { ...@@ -86,40 +86,6 @@ export class PREVIOUSGraph extends ManagedData {
return cleanLink; return cleanLink;
} }
existsNodeId(nodeId) {
var nodes = this.data[GRAPH_NODES];
for (var i = 0; i < nodes.length; i++) {
if (nodes[i][NODE_ID] === nodeId) {
return true;
}
}
return false;
}
getUnusedNodeId() {
var id;
do {
id = this.getRandomString();
} while (this.existsNodeId(id));
return id;
}
getRandomString(length = 8) {
// Move to global helpers
// Based on: https://stackoverflow.com/a/1349426/7376120
var characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var charactersLength = characters.length;
var result = "";
for (var i = 0; i < length; i++) {
result += characters.charAt(
Math.floor(Math.random() * charactersLength)
);
}
return result;
}
static toStr(item) { static toStr(item) {
if (item === undefined) { if (item === undefined) {
return "UNDEFINED"; return "UNDEFINED";
......
export class Tool {
public id: string;
public name: string;
public icon: string;
public isToggleable: boolean = false;
}
\ No newline at end of file
...@@ -26,6 +26,30 @@ export class Graph extends ManagedData { ...@@ -26,6 +26,30 @@ export class Graph extends ManagedData {
this.prepareIds(data); this.prepareIds(data);
} }
/**
* Intuitive getter for links.
* @returns All links associated with the graph.
*/
public get links(): Link[] {
return this.data.links;
}
/**
* Intuitive getter for nodes.
* @returns All nodes associated with the graph.
*/
public get nodes(): Node[] {
return this.data.nodes;
}
/**
* Intuitive getter for node types.
* @returns All node types associated with the graph.
*/
public get types(): NodeType[] {
return this.data.types;
}
/** /**
* Determines the highest, used ids for GraphElements in data for later use. * Determines the highest, used ids for GraphElements in data for later use.
......
...@@ -9,7 +9,7 @@ const babelOptions = { ...@@ -9,7 +9,7 @@ const babelOptions = {
module.exports = { module.exports = {
entry: { entry: {
frontend: "./src/frontend.tsx", frontend: "./src/frontend.tsx",
backend: "./src/backend.js", backend: "./src/backend.tsx",
}, },
output: { output: {
filename: "[name].js", filename: "[name].js",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment