mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
[WIP] Add copy/paste/delete in VariablesList in newIDE
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -89,5 +89,6 @@
|
||||
"newIDE/electron-app/app/www": true
|
||||
},
|
||||
// Support for Flowtype:
|
||||
"javascript.validate.enable": false
|
||||
"javascript.validate.enable": false,
|
||||
"flow.useNPMPackagedFlow": true
|
||||
}
|
||||
|
@@ -5,24 +5,23 @@
|
||||
*/
|
||||
|
||||
#include "GDCore/Project/Variable.h"
|
||||
#include "GDCore/String.h"
|
||||
#include <sstream>
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/TinyXml/tinyxml.h"
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gd
|
||||
{
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* Get value as a double
|
||||
*/
|
||||
double Variable::GetValue() const
|
||||
{
|
||||
if (!isNumber)
|
||||
{
|
||||
stringstream ss; ss << str;
|
||||
if (!isNumber) {
|
||||
stringstream ss;
|
||||
ss << str;
|
||||
ss >> value;
|
||||
isNumber = true;
|
||||
}
|
||||
@@ -30,11 +29,11 @@ double Variable::GetValue() const
|
||||
return value;
|
||||
}
|
||||
|
||||
const gd::String & Variable::GetString() const
|
||||
const gd::String& Variable::GetString() const
|
||||
{
|
||||
if (isNumber)
|
||||
{
|
||||
stringstream s; s << (value);
|
||||
if (isNumber) {
|
||||
stringstream s;
|
||||
s << (value);
|
||||
str = s.str();
|
||||
isNumber = false;
|
||||
}
|
||||
@@ -42,7 +41,7 @@ const gd::String & Variable::GetString() const
|
||||
return str;
|
||||
}
|
||||
|
||||
bool Variable::HasChild(const gd::String & name) const
|
||||
bool Variable::HasChild(const gd::String& name) const
|
||||
{
|
||||
return isStructure && children.find(name) != children.end();
|
||||
}
|
||||
@@ -53,10 +52,11 @@ bool Variable::HasChild(const gd::String & name) const
|
||||
* If the variable is not a structure or has not
|
||||
* the specified child, an empty variable is returned.
|
||||
*/
|
||||
Variable & Variable::GetChild(const gd::String & name)
|
||||
Variable& Variable::GetChild(const gd::String& name)
|
||||
{
|
||||
std::map<gd::String, Variable>::iterator it = children.find(name);
|
||||
if ( it != children.end() ) return it->second;
|
||||
if (it != children.end())
|
||||
return it->second;
|
||||
|
||||
isStructure = true;
|
||||
Variable newEmptyVariable;
|
||||
@@ -70,10 +70,11 @@ Variable & Variable::GetChild(const gd::String & name)
|
||||
* If the variable is not a structure or has not
|
||||
* the specified child, an empty variable is returned.
|
||||
*/
|
||||
const Variable & Variable::GetChild(const gd::String & name) const
|
||||
const Variable& Variable::GetChild(const gd::String& name) const
|
||||
{
|
||||
std::map<gd::String, Variable>::iterator it = children.find(name);
|
||||
if ( it != children.end() ) return it->second;
|
||||
if (it != children.end())
|
||||
return it->second;
|
||||
|
||||
isStructure = true;
|
||||
Variable newEmptyVariable;
|
||||
@@ -81,15 +82,17 @@ const Variable & Variable::GetChild(const gd::String & name) const
|
||||
return children[name];
|
||||
}
|
||||
|
||||
void Variable::RemoveChild(const gd::String & name)
|
||||
void Variable::RemoveChild(const gd::String& name)
|
||||
{
|
||||
if ( !isStructure ) return;
|
||||
if (!isStructure)
|
||||
return;
|
||||
children.erase(name);
|
||||
}
|
||||
|
||||
bool Variable::RenameChild(const gd::String & oldName, const gd::String & newName)
|
||||
bool Variable::RenameChild(const gd::String& oldName, const gd::String& newName)
|
||||
{
|
||||
if ( !isStructure || !HasChild(oldName)|| HasChild(newName) ) return false;
|
||||
if (!isStructure || !HasChild(oldName) || HasChild(newName))
|
||||
return false;
|
||||
|
||||
children[newName] = children[oldName];
|
||||
children.erase(oldName);
|
||||
@@ -99,63 +102,58 @@ bool Variable::RenameChild(const gd::String & oldName, const gd::String & newNam
|
||||
|
||||
void Variable::ClearChildren()
|
||||
{
|
||||
if ( !isStructure ) return;
|
||||
if (!isStructure)
|
||||
return;
|
||||
children.clear();
|
||||
}
|
||||
|
||||
void Variable::SerializeTo(SerializerElement & element) const
|
||||
void Variable::SerializeTo(SerializerElement& element) const
|
||||
{
|
||||
if (!isStructure)
|
||||
element.SetAttribute("value", GetString());
|
||||
else
|
||||
{
|
||||
SerializerElement & childrenElement = element.AddChild("children");
|
||||
else {
|
||||
SerializerElement& childrenElement = element.AddChild("children");
|
||||
childrenElement.ConsiderAsArrayOf("variable");
|
||||
for (std::map<gd::String, gd::Variable>::iterator i = children.begin(); i != children.end(); ++i)
|
||||
{
|
||||
SerializerElement & variableElement = childrenElement.AddChild("variable");
|
||||
for (std::map<gd::String, gd::Variable>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
SerializerElement& variableElement = childrenElement.AddChild("variable");
|
||||
variableElement.SetAttribute("name", i->first);
|
||||
i->second.SerializeTo(variableElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Variable::UnserializeFrom(const SerializerElement & element)
|
||||
void Variable::UnserializeFrom(const SerializerElement& element)
|
||||
{
|
||||
isStructure = element.HasChild("children", "Children");
|
||||
|
||||
if (isStructure)
|
||||
{
|
||||
const SerializerElement & childrenElement = element.GetChild("children", 0, "Children");
|
||||
if (isStructure) {
|
||||
const SerializerElement& childrenElement = element.GetChild("children", 0, "Children");
|
||||
childrenElement.ConsiderAsArrayOf("variable", "Variable");
|
||||
for (int i = 0; i < childrenElement.GetChildrenCount(); ++i)
|
||||
{
|
||||
const SerializerElement & childElement = childrenElement.GetChild(i);
|
||||
for (int i = 0; i < childrenElement.GetChildrenCount(); ++i) {
|
||||
const SerializerElement& childElement = childrenElement.GetChild(i);
|
||||
gd::String name = childElement.GetStringAttribute("name", "", "Name");
|
||||
|
||||
gd::Variable childVariable;
|
||||
childVariable.UnserializeFrom(childElement);
|
||||
children[name] = childVariable;
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
SetString(element.GetStringAttribute("value", "", "Value"));
|
||||
}
|
||||
|
||||
void Variable::SaveToXml(TiXmlElement * element) const
|
||||
void Variable::SaveToXml(TiXmlElement* element) const
|
||||
{
|
||||
if (!element) return;
|
||||
if (!element)
|
||||
return;
|
||||
|
||||
if ( !isStructure )
|
||||
if (!isStructure)
|
||||
element->SetAttribute("Value", GetString().c_str());
|
||||
else
|
||||
{
|
||||
TiXmlElement * childrenElem = new TiXmlElement( "Children" );
|
||||
element->LinkEndChild( childrenElem );
|
||||
for (std::map<gd::String, gd::Variable>::iterator i = children.begin(); i != children.end(); ++i)
|
||||
{
|
||||
TiXmlElement * variable = new TiXmlElement( "Variable" );
|
||||
childrenElem->LinkEndChild( variable );
|
||||
else {
|
||||
TiXmlElement* childrenElem = new TiXmlElement("Children");
|
||||
element->LinkEndChild(childrenElem);
|
||||
for (std::map<gd::String, gd::Variable>::iterator i = children.begin(); i != children.end(); ++i) {
|
||||
TiXmlElement* variable = new TiXmlElement("Variable");
|
||||
childrenElem->LinkEndChild(variable);
|
||||
|
||||
variable->SetAttribute("Name", i->first.c_str());
|
||||
i->second.SaveToXml(variable);
|
||||
@@ -163,17 +161,16 @@ void Variable::SaveToXml(TiXmlElement * element) const
|
||||
}
|
||||
}
|
||||
|
||||
void Variable::LoadFromXml(const TiXmlElement * element)
|
||||
void Variable::LoadFromXml(const TiXmlElement* element)
|
||||
{
|
||||
if (!element) return;
|
||||
if (!element)
|
||||
return;
|
||||
|
||||
isStructure = element->FirstChildElement("Children") != NULL;
|
||||
|
||||
if ( isStructure )
|
||||
{
|
||||
const TiXmlElement * child = element->FirstChildElement("Children")->FirstChildElement();
|
||||
while ( child )
|
||||
{
|
||||
if (isStructure) {
|
||||
const TiXmlElement* child = element->FirstChildElement("Children")->FirstChildElement();
|
||||
while (child) {
|
||||
gd::String name = child->Attribute("Name") ? child->Attribute("Name") : "";
|
||||
gd::Variable childVariable;
|
||||
childVariable.LoadFromXml(child);
|
||||
@@ -181,9 +178,31 @@ void Variable::LoadFromXml(const TiXmlElement * element)
|
||||
|
||||
child = child->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
else if (element->Attribute("Value"))
|
||||
} else if (element->Attribute("Value"))
|
||||
SetString(element->Attribute("Value"));
|
||||
}
|
||||
|
||||
bool Variable::Contains(const gd::Variable& variableToSearch, bool recursive) const
|
||||
{
|
||||
for (auto& it : children) {
|
||||
if (&it.second == &variableToSearch)
|
||||
return true;
|
||||
if (recursive && it.second.Contains(variableToSearch, true))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Variable::RemoveRecursively(const gd::Variable& variableToRemove)
|
||||
{
|
||||
for (auto it = children.begin(); it != children.end();) {
|
||||
if (&(it->second) == &variableToRemove) {
|
||||
it = children.erase(it);
|
||||
} else {
|
||||
it->second.RemoveRecursively(variableToRemove);
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -153,6 +153,15 @@ public:
|
||||
*/
|
||||
const std::map<gd::String, Variable> & GetAllChildren() const { return children; }
|
||||
|
||||
/**
|
||||
* \brief Search if a variable is part of the children, optionally recursively
|
||||
*/
|
||||
bool Contains(const gd::Variable & variableToSearch, bool recursive) const;
|
||||
|
||||
/**
|
||||
* \brief Remove the specified variable if it can be found in the children
|
||||
*/
|
||||
void RemoveRecursively(const gd::Variable & variableToRemove);
|
||||
///@}
|
||||
|
||||
/** \name Serialization
|
||||
|
@@ -102,6 +102,18 @@ void VariablesContainer::Remove(const gd::String & varName)
|
||||
VariableHasName(varName)), variables.end() );
|
||||
}
|
||||
|
||||
void VariablesContainer::RemoveRecursively(const gd::Variable & variableToRemove)
|
||||
{
|
||||
variables.erase(std::remove_if(variables.begin(), variables.end(),
|
||||
[&variableToRemove](const std::pair<gd::String, gd::Variable> & nameAndVariable) {
|
||||
return &variableToRemove == &nameAndVariable.second;
|
||||
}), variables.end() );
|
||||
|
||||
for(auto & it: variables) {
|
||||
it.second.RemoveRecursively(variableToRemove);
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t VariablesContainer::GetPosition(const gd::String & name) const
|
||||
{
|
||||
for(std::size_t i = 0;i<variables.size();++i)
|
||||
|
@@ -94,10 +94,16 @@ public:
|
||||
Variable & InsertNew(const gd::String & name, std::size_t position = -1);
|
||||
|
||||
/**
|
||||
* \brief Remove the specified variable from the container.
|
||||
* \brief Remove the variable with the specified name from the container.
|
||||
* \note This operation is not recursive on variable children.
|
||||
*/
|
||||
void Remove(const gd::String & name);
|
||||
|
||||
/**
|
||||
* \brief Remove the specified variable from the container.
|
||||
*/
|
||||
void RemoveRecursively(const gd::Variable & variable);
|
||||
|
||||
/**
|
||||
* \brief Rename a variable.
|
||||
* \return true if the variable was renamed, false otherwise.
|
||||
|
43
newIDE/app/src/Utils/SelectionHandler.js
Normal file
43
newIDE/app/src/Utils/SelectionHandler.js
Normal file
@@ -0,0 +1,43 @@
|
||||
// @flow
|
||||
/**
|
||||
* Export functions to manipulate a selection of objects.
|
||||
*/
|
||||
|
||||
import values from 'lodash/values';
|
||||
|
||||
type ObjectType = { ptr: number };
|
||||
|
||||
type SelectionState<T> = {
|
||||
[number]: ?T,
|
||||
};
|
||||
|
||||
export const getInitialSelection = () => ({});
|
||||
|
||||
export const clearSelection = () => getInitialSelection();
|
||||
|
||||
export const getSelection = <T: ObjectType>(
|
||||
selection: SelectionState<T>
|
||||
): Array<T> => values(selection).filter(value => !!value);
|
||||
|
||||
export const addToSelection = <T: ObjectType>(
|
||||
selection: SelectionState<T>,
|
||||
object: T,
|
||||
select: boolean = true
|
||||
): SelectionState<T> => {
|
||||
console.log(object, select);
|
||||
return {
|
||||
...selection,
|
||||
[object.ptr]: select ? object : null,
|
||||
};
|
||||
};
|
||||
|
||||
export const isSelected = <T: ObjectType>(
|
||||
selection: SelectionState<T>,
|
||||
object: T
|
||||
): boolean => !!selection[object.ptr];
|
||||
|
||||
export const hasSelection = <T: ObjectType>(
|
||||
selection: SelectionState<T>
|
||||
): boolean => {
|
||||
return !!values(selection).filter(value => !!value).length;
|
||||
};
|
1
newIDE/app/src/VariablesList/ClipboardKind.js
Normal file
1
newIDE/app/src/VariablesList/ClipboardKind.js
Normal file
@@ -0,0 +1 @@
|
||||
export const CLIPBOARD_KIND = 'Variables';
|
@@ -1,8 +1,9 @@
|
||||
import React from 'react';
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import { TreeTableRow, TreeTableCell } from '../UI/TreeTable';
|
||||
import DragHandle from '../UI/DragHandle';
|
||||
import SemiControlledTextField from '../UI/SemiControlledTextField';
|
||||
import Delete from 'material-ui/svg-icons/action/delete';
|
||||
import Checkbox from 'material-ui/Checkbox';
|
||||
import AddCircle from 'material-ui/svg-icons/content/add-circle';
|
||||
import SubdirectoryArrowRight from 'material-ui/svg-icons/navigation/subdirectory-arrow-right';
|
||||
import TextField from 'material-ui/TextField';
|
||||
@@ -16,6 +17,25 @@ const Indent = ({ width }) => (
|
||||
</div>
|
||||
);
|
||||
|
||||
const InlineCheckbox = props => <Checkbox {...props} style={{ width: 32 }} />;
|
||||
|
||||
type Props = {|
|
||||
name: string,
|
||||
variable: gdVariable,
|
||||
depth: number,
|
||||
errorText?: ?string,
|
||||
onBlur: () => void,
|
||||
onRemove: () => void,
|
||||
onAddChild: () => void,
|
||||
onChangeValue: string => void,
|
||||
children?: React.Node,
|
||||
muiTheme: Object,
|
||||
showHandle: boolean,
|
||||
showSelectionCheckbox: boolean,
|
||||
isSelected: boolean,
|
||||
onSelect: boolean => void,
|
||||
|};
|
||||
|
||||
const ThemableVariableRow = ({
|
||||
name,
|
||||
variable,
|
||||
@@ -27,7 +47,11 @@ const ThemableVariableRow = ({
|
||||
onChangeValue,
|
||||
children,
|
||||
muiTheme,
|
||||
}) => {
|
||||
showHandle,
|
||||
showSelectionCheckbox,
|
||||
isSelected,
|
||||
onSelect,
|
||||
}: Props) => {
|
||||
const isStructure = variable.isStructure();
|
||||
const key = '' + depth + name;
|
||||
|
||||
@@ -36,7 +60,13 @@ const ThemableVariableRow = ({
|
||||
{depth > 0 && (
|
||||
<Indent width={(depth + 1) * styles.tableChildIndentation} />
|
||||
)}
|
||||
{depth === 0 && <DragHandle />}
|
||||
{depth === 0 && showHandle && <DragHandle />}
|
||||
{showSelectionCheckbox && (
|
||||
<InlineCheckbox
|
||||
checked={isSelected}
|
||||
onCheck={(e, checked) => onSelect(checked)}
|
||||
/>
|
||||
)}
|
||||
<TextField
|
||||
fullWidth
|
||||
name={key + 'name'}
|
||||
@@ -64,9 +94,6 @@ const ThemableVariableRow = ({
|
||||
}
|
||||
columns.push(
|
||||
<TreeTableCell key="tools" style={styles.toolColumn}>
|
||||
<IconButton onClick={onRemove}>
|
||||
<Delete />
|
||||
</IconButton>
|
||||
<IconButton onClick={onAddChild}>
|
||||
<AddCircle />
|
||||
</IconButton>
|
||||
|
@@ -1,11 +1,15 @@
|
||||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
Table,
|
||||
TableHeader,
|
||||
TableHeaderColumn,
|
||||
TableRow,
|
||||
TableRowColumn,
|
||||
} from 'material-ui/Table';
|
||||
import IconButton from 'material-ui/IconButton';
|
||||
import ContentCopy from 'material-ui/svg-icons/content/content-copy';
|
||||
import ContentPaste from 'material-ui/svg-icons/content/content-paste';
|
||||
import Delete from 'material-ui/svg-icons/action/delete';
|
||||
import flatten from 'lodash/flatten';
|
||||
import { SortableContainer, SortableElement } from 'react-sortable-hoc';
|
||||
import { mapFor } from '../Utils/MapFor';
|
||||
@@ -14,12 +18,20 @@ import newNameGenerator from '../Utils/NewNameGenerator';
|
||||
import VariableRow from './VariableRow';
|
||||
import AddVariableRow from './AddVariableRow';
|
||||
import styles from './styles';
|
||||
import {
|
||||
getInitialSelection,
|
||||
hasSelection,
|
||||
addToSelection,
|
||||
getSelection,
|
||||
} from '../Utils/SelectionHandler';
|
||||
import { CLIPBOARD_KIND } from './ClipboardKind';
|
||||
import Clipboard from '../Utils/Clipboard';
|
||||
const gd = global.gd;
|
||||
|
||||
const SortableVariableRow = SortableElement(VariableRow);
|
||||
const SortableAddVariableRow = SortableElement(AddVariableRow);
|
||||
|
||||
class VariablesListBody extends Component {
|
||||
class VariablesListBody extends Component<*, *> {
|
||||
render() {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
@@ -28,16 +40,70 @@ class VariablesListBody extends Component {
|
||||
const SortableVariablesListBody = SortableContainer(VariablesListBody);
|
||||
SortableVariablesListBody.muiName = 'TableBody';
|
||||
|
||||
export default class VariablesList extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
type VariableAndName = {| name: string, ptr: number, variable: gdVariable |};
|
||||
|
||||
this.state = {
|
||||
nameErrors: {},
|
||||
};
|
||||
}
|
||||
type Props = {|
|
||||
variablesContainer: gdVariablesContainer,
|
||||
emptyExplanationMessage?: string,
|
||||
emptyExplanationSecondMessage?: string,
|
||||
|};
|
||||
type State = {|
|
||||
nameErrors: { [string]: string },
|
||||
selectedVariables: { [number]: ?VariableAndName },
|
||||
mode: 'select' | 'move',
|
||||
|};
|
||||
|
||||
_renderVariableChildren(name, parentVariable, depth) {
|
||||
export default class VariablesList extends Component<Props, State> {
|
||||
state = {
|
||||
nameErrors: {},
|
||||
selectedVariables: getInitialSelection(),
|
||||
mode: 'select',
|
||||
};
|
||||
|
||||
_selectVariable = (variableAndName: VariableAndName, select: boolean) => {
|
||||
this.setState({
|
||||
selectedVariables: addToSelection(
|
||||
this.state.selectedVariables,
|
||||
variableAndName,
|
||||
select
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
copySelection = () => {
|
||||
Clipboard.set(CLIPBOARD_KIND, getSelection(this.state.selectedVariables));
|
||||
};
|
||||
|
||||
paste = () => {
|
||||
const { variablesContainer } = this.props;
|
||||
if (!Clipboard.has(CLIPBOARD_KIND)) return;
|
||||
|
||||
const variables = Clipboard.get(CLIPBOARD_KIND);
|
||||
variables.forEach(({ name, variable }) =>
|
||||
variablesContainer.insert(name, variable, variablesContainer.count())
|
||||
);
|
||||
this.forceUpdate();
|
||||
};
|
||||
|
||||
deleteSelection = () => {
|
||||
const { variablesContainer } = this.props;
|
||||
const selection: Array<VariableAndName> = getSelection(
|
||||
this.state.selectedVariables
|
||||
);
|
||||
|
||||
selection.forEach(({ variable }: VariableAndName) =>
|
||||
variablesContainer.removeRecursively(variable)
|
||||
);
|
||||
this.setState({
|
||||
selectedVariables: getInitialSelection(),
|
||||
})
|
||||
};
|
||||
|
||||
_renderVariableChildren(
|
||||
name: string,
|
||||
parentVariable: gdVariable,
|
||||
depth: number
|
||||
) {
|
||||
const children = parentVariable.getAllChildren();
|
||||
const names = children.keys().toJSArray();
|
||||
|
||||
@@ -55,7 +121,13 @@ export default class VariablesList extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
_renderVariableAndChildrenRows(name, variable, depth, index, parentVariable) {
|
||||
_renderVariableAndChildrenRows(
|
||||
name: string,
|
||||
variable: gdVariable,
|
||||
depth: number,
|
||||
index: number,
|
||||
parentVariable: ?gdVariable
|
||||
) {
|
||||
const { variablesContainer } = this.props;
|
||||
const isStructure = variable.isStructure();
|
||||
|
||||
@@ -119,6 +191,11 @@ export default class VariablesList extends Component {
|
||||
? this._renderVariableChildren(name, variable, depth)
|
||||
: null
|
||||
}
|
||||
showHandle={this.state.mode === 'move'}
|
||||
showSelectionCheckbox={this.state.mode === 'select'}
|
||||
isSelected={!!this.state.selectedVariables[variable.ptr]}
|
||||
onSelect={select =>
|
||||
this._selectVariable({ name, ptr: variable.ptr, variable }, select)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -190,7 +267,26 @@ export default class VariablesList extends Component {
|
||||
<TableRow>
|
||||
<TableHeaderColumn>Name</TableHeaderColumn>
|
||||
<TableHeaderColumn>Value</TableHeaderColumn>
|
||||
<TableRowColumn />
|
||||
<TableHeaderColumn style={styles.toolColumnHeader}>
|
||||
<IconButton
|
||||
onClick={this.copySelection}
|
||||
disabled={!hasSelection(this.state.selectedVariables)}
|
||||
>
|
||||
<ContentCopy />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
onClick={this.paste}
|
||||
disabled={!Clipboard.has(CLIPBOARD_KIND)}
|
||||
>
|
||||
<ContentPaste />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
onClick={this.deleteSelection}
|
||||
disabled={!hasSelection(this.state.selectedVariables)}
|
||||
>
|
||||
<Delete />
|
||||
</IconButton>
|
||||
</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
</Table>
|
||||
|
@@ -1,6 +1,10 @@
|
||||
export default {
|
||||
toolColumnHeader: {
|
||||
textAlign: 'right',
|
||||
paddingRight: 8,
|
||||
},
|
||||
toolColumn: {
|
||||
minWidth: 72,
|
||||
minWidth: 48,
|
||||
flex: 0,
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
|
@@ -23,8 +23,8 @@
|
||||
"7zip-bin-win" "^2.1.1"
|
||||
|
||||
"@types/node@^7.0.18":
|
||||
version "7.0.48"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.48.tgz#24bfdc0aa82e8f6dbd017159c58094a2e06d0abb"
|
||||
version "7.0.58"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.58.tgz#ae852120137f40a29731a559e48003bd2d5d19f7"
|
||||
|
||||
ajv-keywords@^2.1.1:
|
||||
version "2.1.1"
|
||||
|
Reference in New Issue
Block a user