2017-07-23 18:42:08 +00:00
|
|
|
<template>
|
|
|
|
<div class="layout">
|
2017-07-28 20:04:12 +00:00
|
|
|
<div class="layout__panel flex flex--row">
|
|
|
|
<div class="layout__panel layout__panel--explorer" v-show="showExplorer" :style="{ width: explorerWidth + 'px' }">
|
|
|
|
<explorer></explorer>
|
|
|
|
</div>
|
|
|
|
<div class="layout__panel flex flex--column" :style="{ width: innerWidth + 'px' }">
|
|
|
|
<div class="layout__panel layout__panel--navigation-bar" v-show="showNavigationBar || !showEditor" :style="{ height: navigationBarHeight + 'px' }">
|
|
|
|
<navigation-bar></navigation-bar>
|
|
|
|
</div>
|
|
|
|
<div class="layout__panel flex flex--row" :style="{ height: innerHeight + 'px' }">
|
|
|
|
<div class="layout__panel layout__panel--editor" v-show="showEditor" :style="{ width: editorWidth + 'px', 'font-size': fontSize + 'px' }">
|
|
|
|
<editor></editor>
|
|
|
|
</div>
|
|
|
|
<div class="layout__panel layout__panel--button-bar" v-show="showEditor" :style="{ width: buttonBarWidth + 'px' }">
|
2017-07-23 18:42:08 +00:00
|
|
|
<button-bar></button-bar>
|
|
|
|
</div>
|
|
|
|
<div class="layout__panel layout__panel--preview" v-show="showSidePreview || !showEditor" :style="{ width: previewWidth + 'px', 'font-size': fontSize + 'px' }">
|
|
|
|
<preview></preview>
|
|
|
|
</div>
|
|
|
|
</div>
|
2017-07-28 20:04:12 +00:00
|
|
|
<div class="layout__panel layout__panel--status-bar" v-show="showStatusBar" :style="{ height: statusBarHeight + 'px' }">
|
|
|
|
<status-bar></status-bar>
|
2017-07-23 18:42:08 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
2017-07-28 20:04:12 +00:00
|
|
|
<div class="layout__panel layout__panel--side-bar" v-show="showSideBar" :style="{ width: sideBarWidth + 'px' }">
|
|
|
|
<side-bar></side-bar>
|
2017-07-23 18:42:08 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
import { mapState, mapActions } from 'vuex';
|
|
|
|
import NavigationBar from './NavigationBar';
|
|
|
|
import ButtonBar from './ButtonBar';
|
|
|
|
import StatusBar from './StatusBar';
|
2017-07-28 20:04:12 +00:00
|
|
|
import Explorer from './Explorer';
|
|
|
|
import SideBar from './SideBar';
|
2017-07-23 18:42:08 +00:00
|
|
|
import Editor from './Editor';
|
|
|
|
import Preview from './Preview';
|
|
|
|
import editorSvc from '../services/editorSvc';
|
|
|
|
import constants from '../services/constants';
|
|
|
|
|
|
|
|
export default {
|
|
|
|
components: {
|
|
|
|
NavigationBar,
|
|
|
|
ButtonBar,
|
|
|
|
StatusBar,
|
2017-07-28 20:04:12 +00:00
|
|
|
Explorer,
|
|
|
|
SideBar,
|
2017-07-23 18:42:08 +00:00
|
|
|
Editor,
|
|
|
|
Preview,
|
|
|
|
},
|
|
|
|
computed: mapState('layout', {
|
2017-07-28 20:04:12 +00:00
|
|
|
explorerWidth: 'explorerWidth',
|
|
|
|
sideBarWidth: 'sideBarWidth',
|
|
|
|
navigationBarHeight: 'navigationBarHeight',
|
|
|
|
buttonBarWidth: 'buttonBarWidth',
|
|
|
|
statusBarHeight: 'statusBarHeight',
|
2017-07-23 18:42:08 +00:00
|
|
|
showEditor: 'showEditor',
|
|
|
|
showSidePreview: 'showSidePreview',
|
2017-07-28 20:04:12 +00:00
|
|
|
showNavigationBar: 'showNavigationBar',
|
|
|
|
showStatusBar: 'showStatusBar',
|
|
|
|
showSideBar: 'showSideBar',
|
|
|
|
showExplorer: 'showExplorer',
|
2017-07-23 18:42:08 +00:00
|
|
|
fontSize: 'fontSize',
|
2017-07-28 20:04:12 +00:00
|
|
|
innerWidth: 'innerWidth',
|
|
|
|
innerHeight: 'innerHeight',
|
2017-07-23 18:42:08 +00:00
|
|
|
previewWidth: 'previewWidth',
|
|
|
|
editorWidth: 'editorWidth',
|
|
|
|
}),
|
|
|
|
methods: {
|
|
|
|
...mapActions('layout', [
|
|
|
|
'updateStyle',
|
|
|
|
]),
|
|
|
|
saveSelection: () => editorSvc.saveSelection(true),
|
|
|
|
},
|
|
|
|
created() {
|
|
|
|
this.updateStyle();
|
|
|
|
window.addEventListener('resize', this.updateStyle);
|
|
|
|
window.addEventListener('keyup', this.saveSelection);
|
|
|
|
window.addEventListener('mouseup', this.saveSelection);
|
|
|
|
window.addEventListener('contextmenu', this.saveSelection);
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
const editorElt = this.$el.querySelector('.editor__inner');
|
|
|
|
const previewElt = this.$el.querySelector('.preview__inner');
|
|
|
|
const tocElt = this.$el.querySelector('.toc__inner');
|
|
|
|
editorSvc.init(editorElt, previewElt, tocElt);
|
|
|
|
|
|
|
|
// TOC click behaviour
|
|
|
|
let isMousedown;
|
|
|
|
function onClick(e) {
|
|
|
|
if (!isMousedown) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
e.preventDefault();
|
|
|
|
const y = e.clientY - tocElt.getBoundingClientRect().top;
|
|
|
|
|
|
|
|
this.$store.state.sectionDescList.some((sectionDesc) => {
|
|
|
|
if (y >= sectionDesc.tocDimension.endOffset) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
const posInSection = (y - sectionDesc.tocDimension.startOffset)
|
|
|
|
/ (sectionDesc.tocDimension.height || 1);
|
|
|
|
const editorScrollTop = sectionDesc.editorDimension.startOffset
|
|
|
|
+ (sectionDesc.editorDimension.height * posInSection);
|
|
|
|
editorElt.parentNode.scrollTop = editorScrollTop - constants.scrollOffset;
|
|
|
|
const previewScrollTop = sectionDesc.previewDimension.startOffset
|
|
|
|
+ (sectionDesc.previewDimension.height * posInSection);
|
|
|
|
previewElt.parentNode.scrollTop = previewScrollTop - constants.scrollOffset;
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
tocElt.addEventListener('mouseup', () => {
|
|
|
|
isMousedown = false;
|
|
|
|
});
|
|
|
|
tocElt.addEventListener('mouseleave', () => {
|
|
|
|
isMousedown = false;
|
|
|
|
});
|
|
|
|
tocElt.addEventListener('mousedown', (e) => {
|
|
|
|
isMousedown = e.which === 1;
|
|
|
|
onClick(e);
|
|
|
|
});
|
|
|
|
tocElt.addEventListener('mousemove', (e) => {
|
|
|
|
onClick(e);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
destroyed() {
|
|
|
|
window.removeEventListener('resize', this.updateStyle);
|
|
|
|
},
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss">
|
2017-07-28 20:04:12 +00:00
|
|
|
.layout {
|
2017-07-23 18:42:08 +00:00
|
|
|
position: absolute;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
}
|
|
|
|
|
2017-07-28 20:04:12 +00:00
|
|
|
.layout__panel {
|
|
|
|
position: relative;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
-webkit-flex: none;
|
|
|
|
flex: none;
|
2017-07-23 18:42:08 +00:00
|
|
|
}
|
|
|
|
|
2017-07-28 20:04:12 +00:00
|
|
|
.layout__panel--navigation-bar {
|
|
|
|
background-color: #2c2c2c;
|
2017-07-23 18:42:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
.layout__panel--status-bar {
|
|
|
|
background-color: #007acc;
|
|
|
|
}
|
|
|
|
|
2017-07-28 20:04:12 +00:00
|
|
|
.layout__panel--editor {
|
|
|
|
background-color: #fff;
|
2017-07-23 18:42:08 +00:00
|
|
|
}
|
|
|
|
|
2017-07-28 20:04:12 +00:00
|
|
|
.layout__panel--explorer {
|
|
|
|
background-color: #ddd;
|
2017-07-28 07:40:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
.layout__panel--button-bar,
|
|
|
|
.layout__panel--status-bar,
|
|
|
|
.layout__panel--side-bar,
|
|
|
|
.layout__panel--navigation-bar {
|
|
|
|
.app--loading & > * {
|
2017-07-28 20:04:12 +00:00
|
|
|
opacity: 0.5;
|
|
|
|
|
|
|
|
/* Hack to disable mouse focus */
|
|
|
|
pointer-events: none;
|
2017-07-28 07:40:24 +00:00
|
|
|
}
|
2017-07-23 18:42:08 +00:00
|
|
|
}
|
|
|
|
</style>
|