Stackedit/src/components/Layout.vue

169 lines
5.0 KiB
Vue
Raw Normal View History

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">
2017-07-31 09:04:01 +00:00
<div class="layout__panel layout__panel--explorer" v-show="styles.showExplorer" :style="{ width: constants.explorerWidth + 'px' }">
2017-07-28 20:04:12 +00:00
<explorer></explorer>
</div>
2017-07-31 09:04:01 +00:00
<div class="layout__panel flex flex--column" :style="{ width: styles.innerWidth + 'px' }">
<div class="layout__panel layout__panel--navigation-bar" v-show="styles.showNavigationBar" :style="{ height: constants.navigationBarHeight + 'px' }">
2017-07-28 20:04:12 +00:00
<navigation-bar></navigation-bar>
</div>
2017-07-31 09:04:01 +00:00
<div class="layout__panel flex flex--row" :style="{ height: styles.innerHeight + 'px' }">
<div class="layout__panel layout__panel--editor" v-show="styles.showEditor" :style="{ width: styles.editorWidth + 'px', 'font-size': styles.fontSize + 'px' }">
2017-07-28 20:04:12 +00:00
<editor></editor>
</div>
2017-07-31 09:04:01 +00:00
<div class="layout__panel layout__panel--button-bar" v-show="styles.showEditor" :style="{ width: constants.buttonBarWidth + 'px' }">
2017-07-23 18:42:08 +00:00
<button-bar></button-bar>
</div>
2017-07-31 09:04:01 +00:00
<div class="layout__panel layout__panel--preview" v-show="styles.showPreview" :style="{ width: styles.previewWidth + 'px', 'font-size': styles.fontSize + 'px' }">
2017-07-23 18:42:08 +00:00
<preview></preview>
</div>
</div>
2017-07-31 09:04:01 +00:00
<div class="layout__panel layout__panel--status-bar" v-show="styles.showStatusBar" :style="{ height: constants.statusBarHeight + 'px' }">
2017-07-28 20:04:12 +00:00
<status-bar></status-bar>
2017-07-23 18:42:08 +00:00
</div>
</div>
2017-07-31 09:04:01 +00:00
<div class="layout__panel layout__panel--side-bar" v-show="styles.showSideBar" :style="{ width: constants.sideBarWidth + 'px' }">
2017-07-28 20:04:12 +00:00
<side-bar></side-bar>
2017-07-23 18:42:08 +00:00
</div>
</div>
</div>
</template>
<script>
2017-07-31 09:04:01 +00:00
import { mapState, mapGetters, mapMutations } from 'vuex';
2017-07-23 18:42:08 +00:00
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';
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,
},
2017-07-31 09:04:01 +00:00
computed: {
...mapState('layout', [
'constants',
]),
...mapGetters('layout', [
'styles',
]),
},
2017-07-23 18:42:08 +00:00
methods: {
2017-07-31 09:04:01 +00:00
...mapMutations('layout', [
'updateBodySize',
2017-07-23 18:42:08 +00:00
]),
saveSelection: () => editorSvc.saveSelection(true),
},
created() {
2017-07-31 09:04:01 +00:00
this.updateBodySize();
window.addEventListener('resize', this.updateBodySize);
2017-07-23 18:42:08 +00:00
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);
2017-07-31 09:04:01 +00:00
editorElt.parentNode.scrollTop = editorScrollTop;
2017-07-23 18:42:08 +00:00
const previewScrollTop = sectionDesc.previewDimension.startOffset
+ (sectionDesc.previewDimension.height * posInSection);
2017-07-31 09:04:01 +00:00
previewElt.parentNode.scrollTop = previewScrollTop;
2017-07-23 18:42:08 +00:00
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 {
2017-07-31 09:04:01 +00:00
background-color: #dadada;
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>