aboutsummaryrefslogtreecommitdiff
path: root/src_js
diff options
context:
space:
mode:
Diffstat (limited to 'src_js')
-rw-r--r--src_js/opcut/common.js15
-rw-r--r--src_js/opcut/grid.js175
-rw-r--r--src_js/opcut/main.js4
-rw-r--r--src_js/opcut/states.js26
-rw-r--r--src_js/opcut/vt.js90
5 files changed, 301 insertions, 9 deletions
diff --git a/src_js/opcut/common.js b/src_js/opcut/common.js
index 7e63d19..3f39115 100644
--- a/src_js/opcut/common.js
+++ b/src_js/opcut/common.js
@@ -1,3 +1,16 @@
-export const defaultState = {};
+
+export function submit() {
+
+}
+
+
+export function addPanel() {
+
+}
+
+
+export function addItem() {
+
+}
diff --git a/src_js/opcut/grid.js b/src_js/opcut/grid.js
new file mode 100644
index 0000000..b72e0b0
--- /dev/null
+++ b/src_js/opcut/grid.js
@@ -0,0 +1,175 @@
+import r from 'opcut/renderer';
+import * as u from 'opcut/util';
+import * as ev from 'opcut/ev';
+
+
+export const state = {
+ items: [],
+ selectedItem: null
+};
+
+
+export function clearState(state) {
+ return u.set('selectedItem', null, state);
+}
+
+
+export function tbody(gridPath, columns, validators) {
+ const gridState = r.get(gridPath);
+ return ['tbody', gridState.items.map((row, rowIndex) =>
+ ['tr', u.zip(columns || [], validators || []).map(([column, validator]) => {
+ let content = '';
+ if (typeof column == 'function') {
+ content = column(row, rowIndex);
+ } else {
+ const selected = u.equals(gridState.selectedItem, [rowIndex, column]);
+ content = u.get(column, row);
+ if (typeof content == 'boolean') {
+ content = checkboxColumn(gridPath, column)(row, rowIndex);
+ } else if (selected) {
+ content = ['input.grid-input', {
+ type: 'text',
+ 'ev-change': (evt) => r.set([gridPath, 'items', rowIndex, column],
+ evt.target.value),
+ 'ev-blur': _ => {
+ if (u.equals(gridState.selectedItem, [rowIndex, column]))
+ r.set([gridPath, 'selectedItem'], null);
+ },
+ 'ev-keyup': (evt) => {
+ switch (evt.key) {
+ case 'Enter':
+ evt.target.blur();
+ break;
+ case 'Escape':
+ evt.target.value = u.get(column, row);
+ evt.target.blur();
+ break;
+ }
+ },
+ value: content
+ }];
+ }
+ }
+ const title = (validator ? validator(u.get(column, row), row) : null);
+ return ['td' + (title ? '.invalid' : ''), {
+ title: (title ? title : ''),
+ 'ev-click': evt => {
+ if (u.equals(gridState.selectedItem, [rowIndex, column]))
+ return;
+ ev.one(r, 'render', () => {
+ if (evt.target.firstChild && evt.target.firstChild.focus)
+ evt.target.firstChild.focus();
+ });
+ r.set([gridPath, 'selectedItem'], [rowIndex, column]);
+ }},
+ content];
+ })]
+ )];
+}
+
+
+export function tfoot(gridPath, colspan, newItem) {
+ const itemsPath = [gridPath, 'items'];
+ return ['tfoot',
+ ['tr',
+ ['td', {
+ colSpan: colspan},
+ ['div',
+ ['button', {
+ 'ev-click': () => r.change(itemsPath, u.append(newItem))},
+ ['span.fa.fa-plus'],
+ ' Add'
+ ],
+ ['span.spacer'],
+ ['button', {
+ 'ev-click': () => r.set(itemsPath, [])},
+ ['span.fa.fa-trash-o'],
+ ' Remove all'
+ ]
+ ]
+ ]
+ ]
+ ];
+}
+
+
+export function deleteColumn(gridPath, showUpDown, onDeleteCb) {
+ const itemsPath = [gridPath, 'items'];
+ return (i, index) => [
+ (!showUpDown ? [] : [
+ ['button', {
+ 'ev-click': () => {
+ const gridState = r.get(gridPath);
+ if (index < 1)
+ return;
+ r.change(itemsPath, u.pipe(
+ u.set(index, gridState.items[index-1]),
+ u.set(index-1, i)
+ ));
+ }},
+ ['span.fa.fa-arrow-up']
+ ],
+ ['button', {
+ 'ev-click': () => {
+ const gridState = r.get(gridPath);
+ if (index > gridState.items.length - 2)
+ return;
+ r.change(itemsPath, u.pipe(
+ u.set(index, gridState.items[index+1]),
+ u.set(index+1, i)
+ ));
+ }},
+ ['span.fa.fa-arrow-down']
+ ]
+ ]),
+ ['button', {
+ 'ev-click': () => {
+ const item = r.get(itemsPath, index);
+ r.change(itemsPath, u.omit(index));
+ if (onDeleteCb)
+ onDeleteCb(item);
+ }},
+ ['span.fa.fa-minus']
+ ]
+ ];
+}
+
+
+export function checkboxColumn(gridPath, column) {
+ return (i, index) => {
+ const columnPath = [gridPath, 'items', index, column];
+ return ['div', {
+ style: 'text-align: center'},
+ ['input', {
+ type: 'checkbox',
+ 'ev-change': (evt) => r.set(columnPath, evt.target.checked),
+ checked: r.get(columnPath)}
+ ]
+ ];
+ };
+}
+
+
+export function selectColumn(gridPath, column, values) {
+ return (i, index) => {
+ const columnPath = [gridPath, 'items', index, column];
+ const selectedValue = r.get(columnPath);
+ const invalid = values.find(
+ i => u.equals(selectedValue, (u.isArray(i) ? i[0] : i))) === undefined;
+ const allValues = (invalid ? u.append(selectedValue, values) : values);
+ return ['select' + (invalid ? '.invalid' : ''), {
+ title: (invalid ? 'invalid value' : ''),
+ style: 'width: 100%',
+ 'ev-change': (evt) => r.set(columnPath, evt.target.value)},
+ allValues.map(i => {
+ const value = (u.isArray(i) ? i[0] : i);
+ const label = (u.isArray(i) ? i[1] : i);
+ return ['option', {
+ selected: selectedValue == value,
+ value: value},
+ label
+ ];
+ })
+ ];
+ };
+}
diff --git a/src_js/opcut/main.js b/src_js/opcut/main.js
index 06ca4a0..8d00c56 100644
--- a/src_js/opcut/main.js
+++ b/src_js/opcut/main.js
@@ -1,7 +1,7 @@
import r from 'opcut/renderer';
import * as u from 'opcut/util';
import * as ev from 'opcut/ev';
-import * as common from 'opcut/common';
+import * as states from 'opcut/states';
import * as vt from 'opcut/vt';
import 'style/main.scss';
@@ -9,7 +9,7 @@ import 'style/main.scss';
function main() {
let root = document.body.appendChild(document.createElement('div'));
- r.init(root, common.defaultState, vt.main);
+ r.init(root, states.main, vt.main);
}
diff --git a/src_js/opcut/states.js b/src_js/opcut/states.js
new file mode 100644
index 0000000..12c3f8a
--- /dev/null
+++ b/src_js/opcut/states.js
@@ -0,0 +1,26 @@
+import * as grid from 'opcut/grid';
+
+
+export const main = {
+ form: {
+ method: 'FORWARD_GREEDY',
+ cut_width: '1',
+ panels: grid.state,
+ items: grid.state
+ }
+};
+
+
+export const panelsItem = {
+ name: 'Panel',
+ width: '100',
+ height: '100'
+};
+
+
+export const itemsItem = {
+ name: 'Item',
+ width: '10',
+ height: '10',
+ can_rotate: true
+};
diff --git a/src_js/opcut/vt.js b/src_js/opcut/vt.js
index f67b23f..39f6188 100644
--- a/src_js/opcut/vt.js
+++ b/src_js/opcut/vt.js
@@ -1,13 +1,91 @@
+import r from 'opcut/renderer';
+
+import * as common from 'opcut/common';
export function main() {
- return ['div',
- 'application in development - ',
- ['a', {
- props: {
- href: 'https://github.com/bozokopic/opcut'
+ return ['div.window',
+ leftPanel(),
+ ['div.center-panel'],
+ ['div.right-panel']
+ ];
+}
+
+
+function leftPanel() {
+ return ['div.left-panel',
+ ['div.header',
+ ['div.title', 'OPCUT'],
+ ['a', {
+ props: {
+ href: 'https://github.com/bozokopic/opcut'
+ }},
+ ['span.fa.fa-github']
+ ]
+ ],
+ ['div',
+ ['label', 'Method'],
+ ['select',
+ ['FORWARD_GREEDY', 'GREEDY'].map(method =>
+ ['option', {
+ props: {
+ value: method,
+ selected: r.get('form', 'method') == method
+ }},
+ method
+ ])
+ ]
+ ],
+ ['div',
+ ['label', 'Cut width'],
+ ['input', {
+ props: {
+ value: r.get('form', 'cut_width')
+ },
+ on: {
+ change: evt => r.set(['form', 'cut_width'], evt.target.value)
+ }}
+ ]
+ ],
+ ['div.list',
+ ['label', 'Panels'],
+ ['div.content',
+ 'sdfsdfssfd', ['br'],
+ 'sdfsdfssfd', ['br'],
+ 'sdfsdfssfd', ['br'],
+ 'sdfsdfssfd', ['br'],
+ 'sdfsdfssfd', ['br']
+ ],
+ ['button.add', {
+ on: {
+ click: common.addPanel
+ }},
+ ['span.fa.fa-plus'],
+ ' Add panel'
+ ]
+ ],
+ ['div.list',
+ ['label', 'Items'],
+ ['div.content',
+ 'sdfsdfssfd', ['br'],
+ 'sdfsdfssfd', ['br'],
+ 'sdfsdfssfd', ['br'],
+ 'sdfsdfssfd', ['br'],
+ 'sdfsdfssfd', ['br']
+ ],
+ ['button.add', {
+ on: {
+ click: common.addItem
+ }},
+ ['span.fa.fa-plus'],
+ ' Add item'
+ ]
+ ],
+ ['button.submit', {
+ on: {
+ click: common.submit
}},
- 'Github page'
+ 'Calculate'
]
];
}