migrate sketch export dialog

This commit is contained in:
Val Erastov (xibyte) 2020-03-20 01:37:34 -07:00
parent 167167be89
commit 557b3474ee
16 changed files with 116 additions and 87 deletions

View file

@ -1,17 +1,9 @@
import React, {useEffect, useMemo, useRef} from 'react';
import React, {useMemo} from 'react';
export function SvgIcon({content, size, ...props}) {
const divEl = useRef(null);
const className = size&&'icon-'+size;
useEffect(() => {
if (divEl.current) {
divEl.current.innerHTML = content;
}
}, [divEl]);
const style = useMemo(() => {
return {
display: 'flex',
@ -19,7 +11,7 @@ export function SvgIcon({content, size, ...props}) {
};
}, [props.style]);
return <div className={className} ref={divEl} {...props} style={style}/>
return <div className={className} {...props} style={style} dangerouslySetInnerHTML={{__html: content}}/>
}

View file

@ -2,8 +2,8 @@ import React from 'react';
import ls from './Stack.less'
export default function Stack({children}) {
return <div className={ls.root}>{children}</div>
export default function Stack(props) {
return <div className={ls.root} {...props} />
}

View file

@ -2,9 +2,9 @@ import React from 'react';
import cx from 'classnames';
export default function Button({type, onClick, className, children}) {
export default function Button({type, onClick, className, ...props}) {
return <button onClick={onClick} className={cx(type, className)}>{children}</button>
return <button onClick={onClick} className={cx(type, className)} {...props} />
}

View file

@ -1,11 +1,12 @@
import '../css/app.less'
import 'ui/styles/init/index.less';
import App2D from './sketcher/sketcher-app';
import {Layer} from './sketcher/viewer2d';
import * as ui from './ui/ui.js';
import * as toolkit from './ui/toolkit';
import {Constraints} from './sketcher/parametric'
import './utils/jqueryfy'
import '../css/app.less'
import 'ui/styles/init/index.less';
import ReactDOM from "react-dom";
import {SketcherApp} from "./sketcher/components/SketcherApp";
@ -25,16 +26,6 @@ function initializeSketcherApplication() {
app.loadFromLocalStorage();
app.fit();
var actionsWin = new ui.Window($('#actions'), app.winManager);
ui.bindOpening( $('#showActions'), actionsWin );
var addAction = ui.createActionsWinBuilder(actionsWin);
for (var p = 0; p < app._actionsOrder.length; ++p) {
var act = app.actions[app._actionsOrder[p]];
addAction(act.desc, act.action);
$('.act-' + act.id).click(act.action).attr('title', act.desc);
}
const constraintsView = app.dock.views['Constraints'];

View file

@ -65,9 +65,11 @@ export default [
icon: AiOutlineExport,
invoke: (ctx, e) => {
ui.openWin(ctx.app._exportWin, e);
ctx.ui.$exportDialogRequest.next({
x: e.pageX,
y: e.pageY
});
}
},
{

View file

@ -0,0 +1,31 @@
import {IO} from "../io";
import React from "react";
import {AiOutlineExport} from "react-icons/ai";
export default [
{
id: 'ExportSVG',
shortName: 'Export to SVG',
kind: 'Export',
description: 'Export sketch to SVG',
icon: AiOutlineExport,
invoke: (ctx) => {
IO.exportTextData(ctx.viewer.io.svgExport(), ctx.app.getSketchId() + ".svg");
}
},
{
id: 'ExportDXF',
shortName: 'Export to DXF',
kind: 'Export',
description: 'Export sketch to DXF',
icon: AiOutlineExport,
invoke: (ctx) => {
IO.exportTextData(ctx.viewer.io.dxfExport(), ctx.app.getSketchId() + ".dxf");
}
},
];

View file

@ -6,6 +6,7 @@ import constraintGlobalActions from "./constraintGlobalActions";
import measureActions from "./measureActions";
import toolActions from "./toolActions";
import commonActions from "./commonActions";
import exportActions from "./exportActions";
const ALL_CONTEXTUAL_ACTIONS = [
...constraintActions,
@ -16,7 +17,8 @@ const ACTIONS = [
...constraintGlobalActions,
...measureActions,
...toolActions,
...commonActions
...commonActions,
...exportActions
//keep going here
];

View file

@ -0,0 +1,29 @@
import React from 'react';
import {useStreamWithUpdater} from "ui/effects";
import Window from "../../../../modules/ui/components/Window";
import Stack from "../../../../modules/ui/components/Stack";
import {SketcherActionButton} from "./SketcherActionButton";
export function ExportDialog() {
const [request, setRequest] = useStreamWithUpdater(ctx => ctx.ui.$exportDialogRequest);
if (!request) {
return null;
}
const x = request.x || 200;
const y = request.y || 200;
return <Window title='Format' initLeft={x} initTop={y}
className='sketcher-window'
onClose={() => setRequest(null)}>
<Stack style={style}>
<div><SketcherActionButton actionId='ExportSVG' text={true}/></div>
<div><SketcherActionButton actionId='ExportDXF' text={true}/></div>
</Stack>
</Window>
}
const style = {
fontSize: 12,
};

View file

@ -52,12 +52,12 @@ function SketchList() {
{items.map(item => <div key={item} style={listStyle} className='hover'
onClick={() => app.openSketch(item)}>
{item}
{' '}
<Button type='danger'><RiDeleteBinLine onClick={e => {
<Button style={{marginLeft: 5}} type='danger'><RiDeleteBinLine onClick={e => {
e.stopPropagation();
if (confirm("Selected sketch will be REMOVED! Are you sure?")) {
localStorage.removeItem(App2D.STORAGE_PREFIX + item);
setModification(m => m + 1);
e.stopPropagation();
}
}}/> </Button>
</div>)}

View file

@ -0,0 +1,21 @@
import {getSketcherAction} from "../actions";
import React, {useContext} from "react";
import {SketcherAppContext} from "./SketcherApp";
export function SketcherActionButton({actionId, text=false}) {
const action = getSketcherAction(actionId);
if (!action) {
return <span>?{actionId}?</span>;
}
const ctx = useContext(SketcherAppContext);
const Icon = action.icon;
return <button onClick={e => action.invoke(ctx, e)} title={action.description} className={`action-kind-${action.kind} ${text ? 'icon-button' : ''}`}>
{Icon && <Icon />} {(text || !Icon) && action.shortName}
</button>;
}

View file

@ -12,6 +12,7 @@ import {Scope} from "./Scope";
import {SketcherToolbar} from "./SketcherToolbar";
import {sketcherRightToolbarConfig, sketcherTopToolbarConfig} from "../uiConfig";
import {SketchManager} from "./SketchManager";
import {ExportDialog} from "./ExportDialog";
export const SketcherAppContext = React.createContext({});
@ -33,7 +34,10 @@ export function SketcherApp({applicationContext}) {
document.getElementById('top-toolbar')
)}
{ReactDOM.createPortal(
<Scope><SketchManager /></Scope>,
<React.Fragment>
<Scope><SketchManager /></Scope>
<Scope><ExportDialog /></Scope>
</React.Fragment>,
document.getElementById('global-windows')
)}

View file

@ -1,8 +1,7 @@
import React, {useContext} from 'react';
import {getSketcherAction} from "../actions";
import {SketcherAppContext} from "./SketcherApp";
import React from 'react';
import ls from './SketcherToolbar.less';
import cx from 'classnames';
import {SketcherActionButton} from "./SketcherActionButton";
export function SketcherToolbar({actions, horizontal=false, compact}) {
@ -15,21 +14,3 @@ export function SketcherToolbar({actions, horizontal=false, compact}) {
})}
</div>;
}
export function SketcherActionButton({actionId}) {
const action = getSketcherAction(actionId);
if (!action) {
return <span>?{actionId}?</span>;
}
const ctx = useContext(SketcherAppContext);
const Icon = action.icon;
return <button onClick={e => action.invoke(ctx, e)} title={action.description} className={`action-kind-${action.kind}`}>
{Icon ? <Icon /> : action.shortName}
</button>;
}

View file

@ -4,7 +4,8 @@ import diff_match_patch from 'diff-match-patch';
function HistoryManager(viewer) {
this.viewer = viewer;
this.dmp = new diff_match_patch();
this.init(this.viewer.io.serializeSketch());
this.init({});
// this.init(this.viewer.io.serializeSketch());
}
HistoryManager.prototype.init = function(sketchData) {

View file

@ -15,10 +15,6 @@ function App2D() {
this.winManager = new ui.WinManager();
this.inputManager = new InputManager(this);
this._exportWin = new ui.Window($('#exportManager'), app.winManager);
$('#exportManager li').click(function() {ui.closeWin(app._exportWin);});
this.constraintFilter = {};
this.actions = {};
this.commands = {};
@ -72,14 +68,6 @@ function App2D() {
app.viewer.refresh();
});
this.registerAction('exportSVG', "Export To SVG", function () {
IO.exportTextData(app.viewer.io.svgExport(), app.getSketchId() + ".ui.styles.init.svg");
});
this.registerAction('exportDXF', "Export To DXF", function () {
IO.exportTextData(app.viewer.io.dxfExport(), app.getSketchId() + ".dxf");
});
this.registerAction('undo', "Undo", function () {
app.viewer.historyManager.undo();
});
@ -261,7 +249,8 @@ function createAppContext(viewer, app) {
ui: {
$constraintEditRequest: stream(),
$wizardRequest: stream(),
$sketchManagerRequest: stream()
$sketchManagerRequest: stream(),
$exportDialogRequest: stream()
}
};
}

View file

@ -80,6 +80,10 @@ html, body {
padding-left: 5px;
}
.dock-node {
border-bottom: 1px solid black;
}
.selected {
background-color: #333;
color: #ccc;
@ -190,7 +194,6 @@ html, body {
}
.sketcher-window {
background: #666;
border: 5px solid #444444;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
}

View file

@ -17,7 +17,7 @@
<span class="logo" style="float:left">sketcher <sup> 2D</sup></span>
<div style="display: flex" id="top-toolbar"></div>
</div>
<div style="width: 100%; height: calc(100% - 59px); display: flex;">
<div style="width: 100%; height: calc(100% - 65px); display: flex;">
<div id="dock" class="panel b-right scroll" style="width: 245px; height: 100%; flex-shrink: 0;"></div>
@ -32,7 +32,6 @@
<div id="status" class="panel b-top" style="width: 100%; height:22px;">
<div class="button-group" style="float: left">
<span id='showActions' class="dock-btn" ><i class="fa fa-slack"></i></span>
</div>
<div class="status-item coordinates-info">0.000:0.000</div>
<div class="status-item tool-info"></div>
@ -41,22 +40,6 @@
<div style="width: 0; height: 0" id="global-windows">
</div>
<div id="actions" class="scroll win" style="display: none;">
<div class="tool-caption" >ACTIONS</div>
<div class="content">
<div><input class="btn txt-btn" style="width: 100%;" type="submit" value="$value$"></div>
</div>
</div>
<div id="exportManager" class="scroll win" style="display: none;">
<div class="tool-caption" >FORMAT</div>
<div class="content panel" style="padding: 0;">
<ul class="tlist">
<li class="act-exportSVG">SVG</li>
<li class="act-exportDXF">DXF</li>
</ul>
</div>
</div>
<div id="commands" class="win" style="display: none; height: 200px; width: 700px;">
<div class="tool-caption" >COMMANDS</div>