clean up getting rid of old UI code

This commit is contained in:
Val Erastov 2018-01-23 01:31:21 -08:00
parent 3f9b1d804a
commit 0da15743f9
16 changed files with 10 additions and 1199 deletions

View file

@ -0,0 +1,4 @@
export default function capitalize(str) {
if (!str) return;
return str.charAt(0).toUpperCase() + str.slice(1);
}

View file

@ -3,12 +3,12 @@ import connect from 'ui/connect';
import Fa from 'ui/components/Fa';
import {TOKENS as UI_TOKENS} from '../uiEntryPointsPlugin';
import {TOKENS as ACTION_TOKENS} from '../../actions/actionSystemPlugin';
import Toolbar, {ToolbarButton} from "../../../../../modules/ui/components/Toolbar";
import ImgIcon from "../../../../../modules/ui/components/ImgIcon";
import {toIdAndOverrides} from "../../actions/actionRef";
import {capitalize} from "../../ui/utils";
import {mapActionBehavior} from "../../actions/actionButtonBehavior";
import {DEFAULT_MAPPER} from "../../../../../modules/ui/connect";
import Toolbar, {ToolbarButton} from '../../../../../modules/ui/components/Toolbar';
import ImgIcon from '../../../../../modules/ui/components/ImgIcon';
import {toIdAndOverrides} from '../../actions/actionRef';
import {mapActionBehavior} from '../../actions/actionButtonBehavior';
import {DEFAULT_MAPPER} from '../../../../../modules/ui/connect';
import capitalize from '../../../../../modules/gems/capitalize';
function ConfigurableToolbar({actions, small, ...props}) {

View file

@ -1,99 +0,0 @@
import {cssIconsToClasses} from '../ui/utils'
import {EventData} from '../ui/utils'
export default function Menu(menuActions, inputManager) {
this.inputManager = inputManager;
this.node = $('<div>', {
'class' : 'menu'
});
let container = $('<div>', {'class': 'menu-container'});
this.node.append(container);
let separatorAllowed = false;
for (var i = 0; i < menuActions.length; i++) {
var action = menuActions[i];
if (action.type == 'separator') {
container.append($('<div>', {'class': 'menu-separator'}));
separatorAllowed = false;
continue;
}
separatorAllowed = i != menuActions.length - 1;
let menuItem = $('<div>', {'class' : 'menu-item action-item'});
menuItem.data('action', action.id);
menuItem.addClass('icon16-left');
if (action.icon32 != undefined) {
menuItem.css({
'background-image' : 'url('+action.icon32+')'
});
} else if (action.cssIcons != undefined) {
menuItem.append($('<i>', {'class': 'fa ' + cssIconsToClasses(action.cssIcons)})).append(' ');
} else {
}
menuItem.append($('<span>',{text: action.label, class: 'menu-text'}));
var hotkey = this.inputManager.keymap[action.id];
if (hotkey) {
hotkey = hotkey.replace(/\s/g, '');
if (hotkey.length < 15) {
menuItem.append($('<span>',{text: hotkey,'class' : 'action-hotkey-info'}));
}
}
container.append(menuItem);
this.inputManager.app.actionManager.subscribe(action.id, (state) => {
if (state.enabled) {
menuItem.removeClass('action-disabled');
} else {
menuItem.addClass('action-disabled');
}
});
}
this.node.hide();
$('body').append(this.node);
};
Menu.prototype.show = function(app, event) {
this.node.removeClass('menu-flat-top');
this.node.removeClass('menu-flat-bottom');
this.node.show(); //node should be visible to get right dimensions
const r = Math.round;
let button = EventData.get(event, 'initiator');
if (button != undefined) {
var off = button.offset();
var orientation = button.data('menuOrientation');
if (orientation == 'up') {
this.node.addClass('menu-flat-bottom');
this.node.offset({
left: r(off.left),
top: r(off.top - this.node.outerHeight())
});
} else if (orientation == 'down') {
this.node.addClass('menu-flat-top');
this.node.offset({
left: r(off.left),
top: r(off.top + button.outerHeight())
});
} else {
let mouseInfo = this.inputManager.mouseInfo;
let screenOff = $(document).outerHeight() - (mouseInfo.pageX + this.node.outerHeight());
if (screenOff > 0) {
screenOff = 0;
}
let x = mouseInfo.pageX;
if (x + this.node.outerWidth()) {
}
this.node.offset({
left: mouseInfo.pageX,
top: mouseInfo.pageY + screenOff
});
}
} else {
let mouseInfo = this.inputManager.mouseInfo;
this.node.offset({
left: r(mouseInfo.pageX - this.node.outerWidth() / 2),
top: r(mouseInfo.pageY - this.node.outerHeight() / 2)
});
}
this.inputManager.registerOpenMenu(this);
};

View file

@ -1,318 +0,0 @@
import {sprintf} from 'sprintf'
export const BINDING_CALLBACK = 'OnBind';
export function Bind(node, data, policy) {
const scope = getScope(node);
const props = Object.getOwnPropertyNames(data);
for (let prop of props) {
if (prop == BINDING_CALLBACK) continue;
let value = data[prop];
if (Array.isArray(value)) {
const nodesToBind = scope.nestedScopes[prop];
if (!nodesToBind) continue;
for (let nodeToBind of nodesToBind) {
BindArray(nodeToBind, value, policy);
}
} else if (typeof value === 'object') {
const nodesToBind = scope.nestedScopes[prop];
if (!nodesToBind) continue;
for (let nodeToBind of nodesToBind) {
Bind(nodeToBind, value, policy);
}
} else {
const bindCallbacks = scope.bindings[prop];
if (!bindCallbacks) continue;
for (let bindCallback of bindCallbacks) {
bindCallback(value, policy);
}
}
}
var callback = data[BINDING_CALLBACK];
if (callback) {
callback(node, data, policy)
}
}
export function BindArray(node, array, policy) {
let scope = getScope(node);
let template = detachTemplate(node);
function createFromTemplate(id) {
const child = template.clone();
child.attr('data-bind-scope', id);
scope.nestedScopes[id] = [child];
return child;
}
const children = node.children();
let domPointer = 0;
for (let dataPointer = 0; dataPointer < array.length; dataPointer++) {
const value = array[dataPointer];
let domItem;
if (domPointer == children.length) {
domItem = createFromTemplate(value.id);
node.append(domItem);
} else {
domItem = children.eq(domPointer);
var domItemId = domItem.attr('data-bind-scope');
if (domItemId != value.id) {
domItem = scope.nestedScopes[value.id];
if (!domItem) {
domItem = createFromTemplate(value.id);
} else {
domItem = domItem[0];
}
if (domPointer == 0) {
node.prepend(domItem);
} else {
children.eq(domPointer - 1).after(domItem);
}
}
domPointer ++;
}
Bind(domItem, value, policy);
}
//clean up
for (; domPointer < children.length; domPointer++) {
let item = children.eq(domPointer);
item.remove();
delete scope[item.attr('data-bind-scope')];
}
}
function detachTemplate(node) {
let template = node.data("BindingTemplate");
if (!template) {
template = node.children();
template.detach();
node.data("BindingTemplate", template);
}
return template;
}
function clearScope(dom) {
dom.removeData('BindingScope');
}
function getScope(dom) {
let scope = dom.data('BindingScope');
if (!scope) {
scope = index(dom);
dom.data('BindingScope', scope);
}
return scope;
}
function detectBinder(def) {
for (let binder of BINDERS) {
if (def.startsWith(binder.prefix)) {
return binder;
}
}
return DEFAULT_BINDER;
}
function setupBindings(bindings, bindingsDefinition, node) {
bindingsDefinition.split(',').forEach(defStr => {
defStr = defStr.trim();
const binder = detectBinder(defStr);
const def = parseBindDefinition(defStr.substring(binder.prefix.length));
addToList(bindings, def.dataKey, (value, policy) => {
policy = adjustPolicyForNode(policy, def.policy);
const formattedValue = format(def.formatters, value);
binder.apply(node, formattedValue, policy, def.key);
});
binder.init(node);
});
}
function index(dom) {
const scope = new Scope();
//do bfs
const queue = [];
function advance(node) {
let bindingsDefinition = node.attr('data-bind');
if (bindingsDefinition) {
setupBindings(scope.bindings, bindingsDefinition, node)
}
node.children().each((i, e) => queue.push($(e)))
}
advance(dom);
while (queue.length != 0) {
let list = false;
let node = queue.shift();
var nestedScope = node.attr('data-bind-scope');
if (!nestedScope) {
nestedScope = node.attr('data-bind-list');
list = true;
}
if (nestedScope) {
addToList(scope.nestedScopes, nestedScope, node);
if (list) {
detachTemplate(node);
}
} else {
advance(node);
}
}
return scope;
}
function adjustPolicyForNode(propagatedPolicy, nodePolicy) {
let policy = propagatedPolicy || DEFAULT_POLICY;
if (nodePolicy) {
policy = Object.assign({}, policy, nodePolicy);
}
return policy;
}
function addToList(map, key, value) {
let list = map[key];
if (!list) {
list = [];
map[key] = list;
}
list.push(value);
}
const DEFAULT_POLICY = {
hideEmpty: true
};
export const FORMATTERS = {
capitalize: (s) => s.replace(/\b\w/g, l => l.toUpperCase()),
uppercase: (s) => s.toUpperCase(),
'css-url': (s) => 'url(' + s + ')'
};
function parseDataLink(str, def) {
const idx = str.indexOf('|');
if (idx == -1) {
def.dataKey = str.trim();
def.formatters = [];
} else {
def.dataKey = str.substring(0, idx).trim();
def.formatters = str.substring(idx + 1).split('|').map(s => s.trim());
}
}
function parsePolicy(policyStr) {
const policy = {};
policyStr.split('&').forEach(p => {
p = p.trim();
let eqIdx = p.indexOf('=');
if (eqIdx == -1) {
policy[p] = true;
} else {
policy[p.substring(0, eqIdx)] = p.substring(eqIdx + 1);
}
});
return policy;
}
function parseBindDefinition(str) {
const def = {};
let qmIdx = str.indexOf('?');
if (qmIdx != -1) {
def.policy = parsePolicy(str.substring(qmIdx + 1));
str = str.substring(0, qmIdx);
}
const colonIdx = str.indexOf(':');
if (colonIdx == -1) {
parseDataLink(str, def);
} else {
def.key = str.substring(0, colonIdx).trim();
parseDataLink(str.substring(colonIdx + 1), def);
}
return def;
}
function format(formatters, value) {
for (let formatterKey of formatters) {
const formatter = FORMATTERS[formatterKey];
if (formatter) {
value = formatter(value);
}
}
return value;
}
const DEFAULT_BINDER = {
prefix: '',
apply: (node, value, policy) => {
let templateData = node.attr('data-bind-template');
var isEmpty = value === '' || value === undefined || value === null;
if (isEmpty) {
node.text('');
} else {
if (templateData) {
value = sprintf(templateData, value);
}
node.text(value);
}
if (isEmpty && policy.hideEmpty) {
node.hide();
} else {
node.show();
}
},
init: (node) => {
let template = node.text();
if (template) {
node.attr('data-bind-template', template);
}
}
};
export const BINDERS = [
{
prefix: '@',
apply: (node, value, policy, key) => node.attr(key, value),
init: (node) => {}
},
{
prefix: '$',
apply: (node, value, policy, key) => node.css(key, value),
init: (node) => {}
},
{
prefix: '!',
apply: (node, value, policy, key) => value ? node.addClass(key) : node.removeClass(key),
init: (node) => {}
},
DEFAULT_BINDER
];
export function Scope() {
this.bindings = {};
this.nestedScopes = {};
}
function example(dom) {
let initState = {
title : 'this is title',
users : [
{id: 1, name: 'Peach', email: 'Peach@ooo.com'},
{id: 2, name: 'Melon', email: 'Melon@ooo.com'},
{id: 3, name: 'Berry', email: 'Berry@ooo.com'},
{id: 4, name: 'Apple', email: 'Apple@ooo.com'},
{id: 5, name: 'Banana', email: 'Banana@ooo.com'}
]
};
Bind(dom, initState);
//reordering, removing, updating provided attributes
Bind(dom, {users: [ {id:3}, {id:1, name: 'Peach-Beach'}, {id:2} ]});
//only content update
Bind(dom, {users: {
'3' : {name: 'updated', email: 'light@update.com'}
}});
}

View file

@ -1,39 +0,0 @@
import {cssIconsToClasses} from '../ui/utils'
export default function ControlBar(app, bar) {
this.app = app;
this.bar = bar;
}
ControlBar.prototype.add = function(actionName, left, overrides) {
let action = this.app.actionManager.actions[actionName];
if (action == undefined) return;
if (overrides != undefined) {
action = Object.assign({}, action, overrides);
}
const btn = $('<div>', {'class': 'button'});
if (action.cssIcons != undefined) {
btn.append($('<i>', {'class': 'fa ' + cssIconsToClasses(action.cssIcons)}));
}
if (action.label != undefined && action.label != null) {
if (action.cssIcons != undefined) {
btn.append(' ');
}
btn.append(action.label);
}
var to = this.bar.find(left ? '.left-group' : '.right-group');
to.append(btn);
if (action.type == 'binary') {
this.app.bus.subscribe(action.property, (show) => {
btn.removeClass('button-selected');
if (show) {
btn.addClass('button-selected');
}
})(this.app.state[action.property]);
} else if (action.type == 'menu') {
btn.data('menuOrientation', 'up');
}
btn.addClass('action-item');
btn.data('action', actionName);
return btn;
};

View file

@ -1,197 +0,0 @@
import * as tk from '../../ui/toolkit'
import * as cad_utils from '../cad-utils'
import * as math from '../../math/math'
import * as workbench from '../craft/mesh/workbench'
import ToolBar from './toolbar'
import * as MenuConfig from '../menu/menu-config'
import * as Operations from '../craft/operations'
import Menu from '../menu/menu'
import {ExtrudeWizard, CutWizard} from '../craft/brep/wizards/cut-extrude-wizard'
import {RevolveWizard} from '../craft/brep/wizards/revolve-wizard'
import {PlaneWizard} from '../craft/brep/wizards/plane-wizard'
import {BoxWizard} from '../craft/brep/wizards/box'
import {SphereWizard} from '../craft/mesh/wizards/sphere'
import {TransformWizard} from '../craft/mesh/wizards/transform'
import {ImportWizard} from '../craft/mesh/wizards/import'
import {LoadTemplate} from './utils'
import {BindArray} from './bind'
import {SolidList} from './solid-list'
import {ModificationsPanel} from './modifications-panel'
function UI(app) {
this.app = app;
this.viewer = app.viewer;
var mainBox = this.mainBox = new tk.Panel();
mainBox.root.css({height : '100%'});
$('#right-panel').append(mainBox.root);
var modelFolder = new tk.Folder("Model");
this.solidList = new SolidList(this.app);
modelFolder.content.append(this.solidList.dom);
tk.add(mainBox, modelFolder);
let modificationsPanel = new ModificationsPanel(this.app);
mainBox.content.append(modificationsPanel.dom);
var toolbarVertOffset = 10; //this.mainBox.root.position().top;
this.registerMenuActions(MenuConfig);
this.craftToolBar = this.createCraftToolBar(toolbarVertOffset);
this.createBoolToolBar(this.craftToolBar.node.position().top + this.craftToolBar.node.height() + 20);
this.createMiscToolBar(toolbarVertOffset);
this.fillControlBar();
var ui = this;
this.app.bus.subscribe("showSketches", (enabled) => {
var solids = app.findAllSolidsOnScene();
for (var i = 0; i < solids.length; i++) {
for (var j = 0; j < solids[i].sceneFaces.length; j++) {
var face = solids[i].sceneFaces[j];
if (face.sketch3DGroup != null) face.sketch3DGroup.visible = enabled;
}
}
app.viewer.render();
});
app.bus.subscribe('selection_solid', function([solid]) {
if (solid) {
ui.registerWizard(new TransformWizard(app.viewer, solid));
}
});
registerOperations(app);
}
function registerOperations(app) {
const opNames = Object.keys(Operations);
for (let opName of opNames) {
console.log('Registering Operation ' + opName);
app.craft.registerOperation(opName, Operations[opName].action);
}
}
UI.prototype.createCraftToolBar = function (vertPos) {
var toolBar = new ToolBar(this.app);
toolBar.add(this.app.actionManager.actions['PLANE']);
toolBar.add(this.app.actionManager.actions['EditFace']);
toolBar.add(this.app.actionManager.actions['EXTRUDE']);
toolBar.add(this.app.actionManager.actions['CUT']);
toolBar.add(this.app.actionManager.actions['REVOLVE']);
$('#viewer-container').append(toolBar.node);
toolBar.node.css({left: '10px',top : vertPos + 'px'});
return toolBar;
};
UI.prototype.createMiscToolBar = function (vertPos) {
var toolBar = new ToolBar(this.app);
toolBar.addFa(this.app.actionManager.actions['Save']);
toolBar.addFa(this.app.actionManager.actions['StlExport']);
$('#viewer-container').append(toolBar.node);
toolBar.node.css({top : vertPos + 'px'});
toolBar.node.css({right: '10px', 'font-size': '16px'});
return toolBar;
};
UI.prototype.createBoolToolBar = function(vertPos) {
var toolBar = new ToolBar(this.app);
toolBar.add(this.app.actionManager.actions['INTERSECTION']);
toolBar.add(this.app.actionManager.actions['DIFFERENCE']);
toolBar.add(this.app.actionManager.actions['UNION']);
$('#viewer-container').append(toolBar.node);
toolBar.node.css({left: '10px', top : vertPos + 'px'});
return toolBar;
};
UI.prototype.registerMenuActions = function(menuConfig) {
for (let menuName in menuConfig) {
const m = menuConfig[menuName];
var action = Object.assign({'type' : 'menu'}, m);
delete action['actions'];
action.menu = new Menu(
m.actions.map((a) => this.app.actionManager.actions[a])
.filter((a) => a != undefined), this.app.inputManager);
this.app.actionManager.registerAction('menu.' + menuName, action);
}
};
UI.prototype.fillControlBar = function() {
const LEFT = true;
const RIGHT = !LEFT;
this.app.controlBar.add('Info', RIGHT, {'label': null});
this.app.controlBar.add('RefreshSketches', RIGHT, {'label': null});
this.app.controlBar.add('ShowSketches', RIGHT, {'label': 'sketches'});
this.app.controlBar.add('DeselectAll', RIGHT, {'label': null});
this.app.controlBar.add('ToggleCameraMode', RIGHT, {'label': null});
this.app.controlBar.add('menu.file', LEFT);
this.app.controlBar.add('menu.craft', LEFT);
this.app.controlBar.add('menu.boolean', LEFT);
this.app.controlBar.add('menu.primitives', LEFT);
this.app.controlBar.add('Donate', LEFT);
this.app.controlBar.add('GitHub', LEFT);
};
UI.prototype.registerWizard = function(wizard, overridingHistory) {
wizard.box.root.css({left : (this.mainBox.root.width() + this.craftToolBar.node.width() + 30) + 'px', top : 0});
var craft = this.app.craft;
wizard.overridingHistory = overridingHistory;
wizard.focus();
if (this.registeredWizard != undefined) {
if (!this.registeredWizard.disposed) {
this.registeredWizard.dispose();
}
}
this.registeredWizard = wizard;
return wizard;
};
UI.prototype.getInfoForOp = function(op) {
var p = op.params;
var opDef = Operations[op.type];
if (opDef && opDef.info) {
return op.type + ' ' + opDef.info(p);
}
return op.type;
};
UI.prototype.initOperation = function(op) {
var selection = this.app.getFaceSelection();
return this.createWizard(op, false, undefined, selection[0]);
};
UI.prototype.createWizardForOperation = function(op) {
var initParams = op.params;
var face = op.face !== undefined ? this.app.findFace(op.face) : null;
if (face != null) {
this.app.context.bus.dispatch('selection_face', [face]);
}
return this.createWizard(op.type, true, initParams, face);
};
UI.prototype.createWizard = function(type, overridingHistory, initParams, face) {
let wizard = null;
if ('CUT' === type) {
wizard = new CutWizard(this.app, initParams);
} else if ('EXTRUDE' === type) {
wizard = new ExtrudeWizard(this.app, initParams);
} else if ('REVOLVE' === type) {
wizard = new RevolveWizard(this.app, face, initParams);
} else if ('PLANE' === type) {
wizard = new PlaneWizard(this.app, initParams);
} else if ('BOX' === type) {
wizard = new BoxWizard(this.app, initParams);
} else if ('SPHERE' === type) {
wizard = new SphereWizard(this.app.viewer, initParams);
} else if ('IMPORT_STL' === type) {
wizard = new ImportWizard(this.app.viewer, initParams);
} else {
console.log('unknown operation');
}
if (wizard != null) {
this.registerWizard(wizard, overridingHistory);
}
return wizard;
};
export {UI}

View file

@ -1,121 +0,0 @@
import {jwerty} from 'jwerty'
import {keymap} from '../keyboard/keymaps/default'
import {Bind} from './bind'
import {MessageSink} from './message-sink'
import {LoadTemplate, DefaultMouseEvent, EventData, fit} from './utils'
export function InputManager(app) {
this.app = app;
this.openMenus = [];
this.keymap = keymap;
this.mouseInfo = new DefaultMouseEvent();
this.requestedActionInfo = null;
this.actionInfoDom = $(LoadTemplate('action-info')({}));
this.messageSink = new MessageSink(this);
this.context = null;
$(() => {
$(document)
.on('keydown', (e) => this.handleKeyPress(e))
.on('mousedown', (e) => this.clear(e))
.on('click', '.context-click', (e) => this.context = $(e.currentTarget))
.on('mouseenter', '.context-hover', (e) => this.context = $(e.currentTarget))
.on('mouseleave', '.context-hover', (e) => this.context = null)
.on('mouseenter', '.action-item', (e) => this.showActionInfo($(e.currentTarget)))
.on('mouseleave', '.action-item', (e) => this.hideActionInfo())
.on('mousemove', (e) => this.mouseInfo = e)
.on('click', '.action-item', (e) => this.handleActionClick(e))
.on('contextmenu', '.action-item', (e) => {return this.handleRightClick(e)});
});
}
InputManager.prototype.handleKeyPress = function(e) {
switch (e.keyCode) {
case 27 : this.clear(); break;
}
for (let action in this.keymap) {
if (jwerty.is(this.keymap[action], e)) {
setTimeout(() => this.app.actionManager.run(action, e), 0);
break;
}
}
};
InputManager.prototype.clear = function(e) {
if (e != undefined && $(e.target).closest('.menu-item').length != 0) {
return;
}
this.clearMenus();
this.requestedActionInfo = null;
this.messageSink.hide();
};
InputManager.prototype.clearMenus = function() {
if (this.openMenus.length != 0) {
for (let openMenu of this.openMenus) {
openMenu.node.hide();
}
this.openMenus = [];
}
};
InputManager.prototype.handleRightClick = function(e) {
if ($(event.currentTarget).hasClass('.right-click-action')) {
e.preventDefault();
this.handleActionClick(e);
return false;
}
return true;
};
InputManager.prototype.handleActionClick = function(event) {
this.mouseInfo = event;
var target = $(event.currentTarget);
var action = target.data('action');
if (action != undefined) {
this.clear();
EventData.set(event, 'initiator', target);
this.app.actionManager.run(action, event);
event.stopPropagation();
}
};
InputManager.prototype.registerOpenMenu = function(menu) {
fit(menu.node, $('body'));
this.openMenus.push(menu);
};
InputManager.prototype.hideActionInfo = function() {
this.requestedActionInfo = null;
this.messageSink.hide();
};
InputManager.prototype.showActionInfo = function(el) {
var action = el.data('action');
if (action) {
this.requestInfo(action);
}
};
InputManager.prototype.requestInfo = function(actionRequest) {
if (this.requestedActionInfo == actionRequest) {
return;
}
this.requestedActionInfo = actionRequest;
setTimeout(() => {
const actionId = this.requestedActionInfo;
this.requestedActionInfo = null;
if (actionId != null ) {
const action = this.app.actionManager.actions[actionId];
const hotKey = this.keymap[actionId];
if (action && (action.state.hint || action.info || hotKey)) {
Bind(this.actionInfoDom, {
hint: action.state.hint,
info: action.info,
hotKey: hotKey
});
this.messageSink.showContent(this.actionInfoDom);
}
}
}, 500);
};

View file

@ -1,30 +0,0 @@
import {fit} from './utils'
export function MessageSink(inputManager) {
this.inputManager = inputManager;
this.node = $('<div>', {'class': 'message-sink'});
$('body').append(this.node);
}
MessageSink.prototype.show = function() {
this.node.show();
this.node.offset({left: this.inputManager.mouseInfo.pageX + 10, top: this.inputManager.mouseInfo.pageY + 10});
fit(this.node, $('body'));
};
MessageSink.prototype.hide = function() {
this.node.hide();
};
MessageSink.prototype.showContent = function(dom) {
this.node.children().detach();
this.node.empty();
this.node.append(dom);
this.show();
};
MessageSink.prototype.info = function(text) {
this.node.children().detach();
this.node.html(text);
this.show();
};

View file

@ -1,84 +0,0 @@
import {LoadTemplate} from './utils'
import {Bind} from './bind'
import * as Operations from '../craft/operations'
export function ModificationsPanel(app) {
this.app = app;
this.dom = $(LoadTemplate('modifications')({}));
this.buttonsBlock = this.dom.find(".tc-buttons-block");
var buttons = this.buttonsBlock.find(".tc-block-btn");
buttons.eq(0).click(() => app.craft.finishHistoryEditing());
this.buttonsBlock.hide();
this.historyWizard = null;
this.app.bus.subscribe("craft", () => {
this.updateList();
this.updateHistoryPointer();
});
this.app.bus.subscribe("historyShrink", () => {
this.updateList();
});
this.app.bus.subscribe("refreshSketch", () => {
if (this.historyWizard != null) {
var craft = this.app.craft;
var op = JSON.parse(JSON.stringify(craft.history[craft.historyPointer]));
op.protoParams = this.historyWizard.getParams();
this.historyWizard.dispose();
this.historyWizard = this.app.ui.createWizardForOperation(op, app);
}
});
Bind(this.dom, {});
}
ModificationsPanel.prototype.updateList = function() {
let modifications = [];
for (let i = 0; i < this.app.craft.history.length; i++) {
let op = this.app.craft.history[i];
let m = {
id : i,
info: this.app.ui.getInfoForOp(op),
OnBind : (dom, data) => {
const icon = getIconForOp(op);
if (icon) {
dom.css('background-image', 'url('+ icon+')');
}
if (!op.face) {
dom.find('.require-face').addClass('action-disabled');
}
}
};
modifications.push(m);
}
Bind(this.dom, {modifications});
};
ModificationsPanel.prototype.updateHistoryPointer = function() {
if (this.historyWizard != null) {
this.historyWizard.dispose();
this.historyWizard = null;
}
var modificationRows = this.dom.find('.modification-item');
modificationRows.removeClass('history-selected');
var craft = this.app.craft;
var historyEditMode = craft.historyPointer != craft.history.length;
if (historyEditMode) {
modificationRows.eq(craft.historyPointer).addClass('history-selected');
var op = craft.history[craft.historyPointer];
this.historyWizard = this.app.ui.createWizardForOperation(op);
this.buttonsBlock.show();
} else {
this.buttonsBlock.hide();
}
};
function getIconForOp(op) {
var opDef = Operations[op.type];
if (!opDef || !opDef.icon) {
return null;
}
return opDef.icon + '32.png';
}

View file

@ -1,29 +0,0 @@
import {LoadTemplate} from './utils'
import {BindArray} from './bind'
export function SolidList(app) {
this.app = app;
app.bus.subscribe('solid-list', (data) => this.onChange(data));
this.dom = $(LoadTemplate('solid-list')({}));
BindArray(this.dom, []);
}
SolidList.prototype.onChange = function(data) {
let domData = data.solids.map(s => ({id: s.id}));
domData.forEach(s => {
let toRefresh = data.needRefresh.find(nr => nr.id == s.id);
if (toRefresh) {
Object.assign(s, this.getFullInfo(toRefresh));
}
});
BindArray(this.dom, domData);
};
SolidList.prototype.getFullInfo = function(solid) {
return {
id: solid.id,
type: solid.tCadType,
sketches: this.app.findSketches(solid).map(id => ({id}))
};
};

View file

@ -1,86 +0,0 @@
export default function TabSwitcher(tabBar, defaultView) {
this.tabBar = tabBar;
var defaultTab = $('<div>', {
'class': 'tab',
text: '3D View'
});
this.defaultViewHandle = new ViewHandle(defaultView, defaultTab);
defaultTab.click(() => {
this.defaultViewHandle.show(this);
});
this.tabBar.append(defaultTab);
this.markSelected(defaultTab);
this.detachedViews = {};
}
function idToName(id) {
var match = /\$+$/.exec(id);
if (match == null) return id;
var beenCraftedTimes = match[0].length;
function to27Base(n) {
if (n == 0) return "";
var rad = n % 27;
return to27Base(Math.floor(n / 27)) + String.fromCharCode(65 + rad);
}
return id.replace(/\$+$/, '') + to27Base(beenCraftedTimes);
}
TabSwitcher.prototype.showSketch = function(sketchURL, sketchId) {
var tab = this.tabBar.find('[data-sketch-id="'+sketchId+'"]');
var detachedView = this.detachedViews[sketchId];
if (detachedView !== undefined) {
if (!detachedView.closed) {
detachedView.focus();
return;
} else {
delete this.detachedViews[sketchId];
}
}
if (tab.length == 0) {
tab = $('<div>', {'class': 'tab', text : 'Sketch ' + idToName(sketchId)})
.append(' ')
.append($('<i>', {'class': 'fa fa-expand expand'}))
.append(' ')
.append($('<i>', {'class': 'fa fa-close close'}));
tab.attr('data-sketch-id', sketchId);
var url = "sketcher.html#" + sketchURL;
var view = $('<div>', {'class': 'app-tab-view'})
.append($('<iframe>', {css:{
width: '100%', height: '100%'
}}));
view.insertAfter($('.app-tab-view').last());
view.find('iframe').attr('src', url);
var viewHandle = new ViewHandle(view, tab);
tab.on('click', () => viewHandle.show(this));
this.tabBar.append(tab);
var close = () => {
view.remove();
tab.remove();
this.defaultViewHandle.show(this);
};
tab.find('.expand').click(() => {
close();
this.detachedViews[sketchId] = window.open(url, sketchId, "height=900,width=1200")
});
tab.find('.close').click(close);
}
tab.click();
};
TabSwitcher.prototype.markSelected = function(tab) {
this.tabBar.find('.tab').removeClass('tab-selected');
tab.addClass('tab-selected');
};
function ViewHandle(view, tab) {
this.view = view;
this.tab = tab;
}
ViewHandle.prototype.show = function(tabSwitcher) {
tabSwitcher.markSelected(this.tab);
$('.app-tab-view').not(this.view).hide();
this.view.show();
};

View file

@ -1,5 +0,0 @@
<div class="action-info">
<div class="action-info-hint" data-bind="hint"></div>
<div class="action-info-info" data-bind="info"></div>
<div class="action-info-hotkey" data-bind="hotKey">hotkey: %s</div>
</div>

View file

@ -1,16 +0,0 @@
<div class="tc-folder">
<div class="tc-row tc-title">Modifications</div>
<div class="tc-list" data-bind-list="modifications">
<div class="tc-row tc-pseudo-btn modification-item context-hover action-item" data-action="SetHistoryPointer" data-bind="@data-modification: id">
<span data-bind="info" style="float: left"></span>
<span style="float: right" class="modification-right-buttons">
<i class="fa fa-edit modification-button action-item" data-action="OpenHistoryWizard"></i>
<i class="fa fa-image modification-button action-item require-face" data-action="EditOperationSketch"></i>
<i class="fa fa-remove modification-button action-item danger" data-action="RemoveModification"></i>
</span>
</div>
</div>
<div class="tc-row tc-ctrl tc-buttons-block">
<span class="tc-block-btn active-btn">Finish History Editing</span>
</div>
</div>

View file

@ -1,11 +0,0 @@
<div class="tc-list solid-list">
<div>
<div class="tc-row tc-pseudo-btn solid-item action-item context-click"
data-action="menu.SolidContext"
data-bind="id, @data-id: id">Solid %s</div>
<div class="sketch-list" data-bind-list="sketches">
<div class="tc-row tc-pseudo-btn sketch-item" data-bind="id, @data-id: id" >Sketch %s</div>
</div>
</div>
</div>

View file

@ -1,72 +0,0 @@
import {capitalize, cssIconsToClasses} from './utils'
export default function ToolBar(app) {
this.app = app;
this.node = $('<div>', {
css :{
'position': 'absolute',
'background-color': 'rgba(255, 255, 255, 0.5)',
'padding': '5px',
'border-radius' : '5px'
}
});
}
ToolBar.prototype.add = function(action) {
if (!action) return;
var btn = $('<div>', {
'class': 'tc-toolbar-btn tc-squeezed-text',
text : capitalize(action.label),
css: ToolBar.buttonCss({
'background-image': 'url('+action.icon96+')',
'background-repeat': 'no-repeat',
'background-position-x': 'center',
'background-position-y': 'top',
'background-size': '48px 48px'
})
});
this.setUp(btn, action);
this.node.append(btn);
return btn;
};
ToolBar.prototype.setUp = function(btn, action) {
btn.addClass('action-item');
btn.attr('data-action', action.id);
this.app.actionManager.subscribe(action.id, (state) => {
if (state.enabled) {
btn.removeClass('action-disabled');
} else {
btn.addClass('action-disabled');
}
});
};
ToolBar.prototype.addFa = function(action) {
if (!action || !action.cssIcons) return;
var btn = $('<div>', {
'class': 'tc-toolbar-btn',
css : {
'border-radius' : '5px',
'padding' : '5px'
}
});
btn.append($('<i>', {
'class' : 'fa ' + cssIconsToClasses(action.cssIcons),
css: {
'vertical-align': 'middle'
}
}));
this.setUp(btn, action);
this.node.append(btn);
return btn;
};
ToolBar.buttonCss = function(css) {
return Object.assign(css, {
'border-radius' : '5px',
'width': '53px',
'padding-top' : '48px',
'margin-top' : '5px'
})
};

View file

@ -1,86 +0,0 @@
export function DefaultMouseEvent() {
var viewer = $('#viewer-container');
var off = viewer.offset();
const r = Math.round;
this.type = 'click';
this.canBubble = true;
this.cancelable = true;
this.detail = 1;
this.screenX = r(off.left + viewer.width() / 2);
this.screenY = r(off.top + viewer.height() / 2);
this.clientX = this.screenX;
this.clientY = this.screenY;
this.pageX = this.screenX;
this.pageY = this.screenY;
this.ctrlKey = false;
this.altKey = false;
this.shiftKey = false;
this.metaKey = false;
this.button = 0;
this.relatedTarget = null;
}
export const EventData = {
get: function(event, key) {
if (event.data) {
return event.data[key];
} else {
return undefined;
}
},
set: function(event, key, value) {
if (!event.data) {
event.data = {};
}
event.data[key] = value;
}
};
export function fit(el, relativeEl) {
const span = 5;
var relOff = relativeEl.offset();
var off = el.offset();
var needToSet = false;
if (off.left < relOff.left ) {
off.left = relOff.left + span;
needToSet = true;
}
const right = relOff.left + relativeEl.width() - span;
var outerWidth = el.outerWidth();
if (off.left + outerWidth >= right) {
off.left = right - outerWidth;
needToSet = true;
}
if (off.top < relOff.top + span) {
off.top = relOff.top + span;
needToSet = true;
}
var bottom = relOff.top + relativeEl.height() - span;
var outerHeight = el.outerHeight();
if (off.top + outerHeight >= bottom) {
off.top = bottom - outerHeight;
needToSet = true;
}
if (needToSet) {
el.css({
left: off.left + 'px',
top: off.top + 'px'
});
}
}
export function capitalize(str) {
if (!str) return;
return str.charAt(0).toUpperCase() + str.slice(1);
}
export function cssIconsToClasses(cssIcons) {
return cssIcons.map((i)=> 'fa-'+i).join(' ')
}
export function LoadTemplate(name) {
return require('./tmpl/' + name + '.html');
}