Fixed vertical layout

This commit is contained in:
benweet 2014-04-14 19:00:22 +01:00
parent 2c1e1fe131
commit b5475d1669
4 changed files with 170 additions and 93 deletions

View File

@ -258,7 +258,7 @@ define([
} }
var selectionRange = this.createRange(startOffset, endOffset); var selectionRange = this.createRange(startOffset, endOffset);
var selectionRect = selectionRange.getBoundingClientRect(); var selectionRect = selectionRange.getBoundingClientRect();
y = selectionRect.top + selectionRect.height / 2 - inputElt.offsetTop + inputElt.scrollTop; y = selectionRect.top + selectionRect.height / 2 - inputElt.getBoundingClientRect().top + inputElt.scrollTop;
selectionRange.detach(); selectionRange.detach();
} }
return { return {

View File

@ -1,5 +1,5 @@
<div class="layout-outer-wrapper"> <div class="layout-wrapper-l1">
<div class="layout-inner-wrapper"> <div class="layout-wrapper-l2">
<div class="navbar navbar-default ui-layout-north"> <div class="navbar navbar-default ui-layout-north">
<div class="navbar-inner"> <div class="navbar-inner">
<div class="nav left-space"></div> <div class="nav left-space"></div>
@ -49,16 +49,18 @@
</ul> </ul>
</div> </div>
</div> </div>
<pre id="wmd-input" class="ui-layout-center form-control"><div class="editor-content" contenteditable=true></div><div class="editor-margin"></div></pre> <div class="layout-wrapper-l3">
<div class="preview-panel"> <pre id="wmd-input" class="ui-layout-center form-control"><div class="editor-content" contenteditable=true></div><div class="editor-margin"></div></pre>
<div class="extension-preview-buttons"></div> <div class="preview-panel">
<div class="layout-resizer layout-resizer-preview"></div> <div class="extension-preview-buttons"></div>
<div class="layout-toggler layout-toggler-navbar btn btn-info"><i class="icon-th"></i></div> <div class="layout-resizer layout-resizer-preview"></div>
<div class="layout-toggler layout-toggler-preview btn btn-info"><i class="icon-none"></i></div> <div class="layout-toggler layout-toggler-navbar btn btn-info"><i class="icon-th"></i></div>
<div class="extension-editor-buttons"></div> <div class="layout-toggler layout-toggler-preview btn btn-info"><i class="icon-none"></i></div>
<div class="preview-container"> <div class="extension-editor-buttons"></div>
<div id="preview-contents"> <div class="preview-container">
<div id="wmd-preview" class="preview-content"></div> <div id="preview-contents">
<div id="wmd-preview" class="preview-content"></div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -3,17 +3,24 @@ define([
'underscore', 'underscore',
'utils', 'utils',
'constants', 'constants',
'settings',
'eventMgr', 'eventMgr',
'crel', 'crel',
'mousetrap', 'mousetrap',
], function($, _, utils, constants, eventMgr, crel, mousetrap) { ], function($, _, utils, constants, settings, eventMgr, crel, mousetrap) {
var layout = {}; var layout = {};
var resizerSize = 32; var resizerSize = 32;
var togglerSize = 60; var togglerSize = 60;
var navbarHeight = 50; var navbarHeight = 50;
var editorMaxWidth = 250; var editorMinSize = {
var previewMaxWidth = 330; width: 250,
height: 180
};
var previewMinSize = {
width: 330,
height: 200
};
var menuPanelWidth = 280; var menuPanelWidth = 280;
var documentPanelWidth = 320; var documentPanelWidth = 320;
var windowSize; var windowSize;
@ -27,13 +34,14 @@ define([
var laterCssTimeoutId; var laterCssTimeoutId;
var laterCssQueue = []; var laterCssQueue = [];
var outerWrapper, innerWrapper, navbar, menuPanel, documentPanel, editor, previewPanel, previewContainer, navbarToggler, previewToggler, previewResizer; var wrapperL1, wrapperL2, wrapperL3;
var navbar, menuPanel, documentPanel, editor, previewPanel, previewContainer, navbarToggler, previewToggler, previewResizer;
var animate = false; var animate = false;
function applyCssLater() { function applyCssLater() {
if(laterCssQueue.length === 0) { if(laterCssQueue.length === 0) {
outerWrapper.$elt.removeClass('layout-animate'); wrapperL1.$elt.removeClass('layout-animate');
animate = false; animate = false;
return onResize(); return onResize();
} }
@ -92,7 +100,7 @@ define([
if(this.isOpen) { if(this.isOpen) {
this.$elt.addClass('panel-open'); this.$elt.addClass('panel-open');
if(backdrop) { if(backdrop) {
$(backdropElt = utils.createBackdrop(outerWrapper.elt)).click(_.bind(function() { $(backdropElt = utils.createBackdrop(wrapperL1.elt)).click(_.bind(function() {
this.toggle(false); this.toggle(false);
}, this)); }, this));
this.$elt.addClass('bring-to-front'); this.$elt.addClass('bring-to-front');
@ -107,7 +115,7 @@ define([
}, this)); }, this));
} }
animate = true; animate = true;
outerWrapper.$elt.addClass('layout-animate'); wrapperL1.$elt.addClass('layout-animate');
resizeAll(); resizeAll();
}; };
}; };
@ -125,6 +133,8 @@ define([
}).maxWidth; }).maxWidth;
} }
var editorContentElt;
var editorMarginElt;
function onResize() { function onResize() {
var padding = (editor.elt.offsetWidth - getMaxWidth()) / 2; var padding = (editor.elt.offsetWidth - getMaxWidth()) / 2;
if(padding < constants.EDITOR_DEFAULT_PADDING) { if(padding < constants.EDITOR_DEFAULT_PADDING) {
@ -137,89 +147,135 @@ define([
eventMgr.onLayoutResize(); eventMgr.onLayoutResize();
} }
var editorContentElt; var isVertical = settings.layoutOrientation == "vertical";
var editorMarginElt;
function resizeAll() { function resizeAll() {
windowSize = { windowSize = {
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight height: window.innerHeight
}; };
// Layout outer wrapper // Layout wrapper level 1
outerWrapper.y = navbar.isOpen ? 0 : -navbarHeight; wrapperL1.y = navbar.isOpen ? 0 : -navbarHeight;
outerWrapper.x = menuPanel.isOpen ? 0 : documentPanel.isOpen ? -(menuPanelWidth + documentPanelWidth) : -menuPanelWidth; wrapperL1.x = menuPanel.isOpen ? 0 : documentPanel.isOpen ? -(menuPanelWidth + documentPanelWidth) : -menuPanelWidth;
outerWrapper.width = windowSize.width + menuPanelWidth + documentPanelWidth; wrapperL1.width = windowSize.width + menuPanelWidth + documentPanelWidth;
outerWrapper.height = windowSize.height - outerWrapper.y; wrapperL1.height = windowSize.height - wrapperL1.y;
outerWrapper.applyCss();
// Layout inner wrapper // Layout wrapper level 2
innerWrapper.left = menuPanelWidth; wrapperL2.left = menuPanelWidth;
innerWrapper.width = windowSize.width; wrapperL2.width = windowSize.width;
innerWrapper.height = outerWrapper.height; wrapperL2.height = wrapperL1.height;
innerWrapper.applyCss();
// Preview panel // Layout wrapper level 3
if(!previewPanel.isOpen) { wrapperL3.top = navbarHeight;
previewPanel.x = innerWrapper.width - resizerSize; wrapperL3.width = windowSize.width;
} wrapperL3.height = wrapperL1.height - navbarHeight;
else {
if(previewPanel.halfSize) { if(isVertical) {
previewPanel.width = (windowSize.width + resizerSize) / 2; if(navbar.isOpen && wrapperL3.height < editorMinSize.height + (previewPanel.isOpen ? previewMinSize.height : 0)) {
navbar.isOpen = false;
return resizeAll();
} }
if(previewPanel.width < previewMaxWidth) { if(!previewPanel.isOpen) {
previewPanel.halfSize = false; previewPanel.y = wrapperL3.height - resizerSize;
previewPanel.width = previewMaxWidth;
} }
previewPanel.x = innerWrapper.width - previewPanel.width; else {
if(previewPanel.x < editorMaxWidth) { if(previewPanel.halfSize) {
previewPanel.halfSize = false; previewPanel.height = (wrapperL3.height + resizerSize) / 2;
previewPanel.x = editorMaxWidth; }
previewPanel.width = innerWrapper.width - previewPanel.x; if(previewPanel.height < previewMinSize.height) {
if(previewPanel.width < previewMaxWidth) { previewPanel.halfSize = false;
previewPanel.isOpen = false; previewPanel.height = previewMinSize.height;
previewPanel.width = previewMaxWidth; }
previewPanel.x = innerWrapper.width - resizerSize; previewPanel.y = wrapperL3.height - previewPanel.height;
if(previewPanel.y < editorMinSize.height) {
var previewPanelHeight = wrapperL3.height - editorMinSize.height;
if(previewPanelHeight < previewMinSize.height) {
previewPanel.isOpen = false;
}
else {
previewPanel.halfSize = false;
previewPanel.height = previewPanelHeight;
}
return resizeAll();
} }
} }
previewPanel.width = wrapperL3.width;
editor.height = previewPanel.y;
editor.width = wrapperL3.width;
previewContainer.top = resizerSize;
previewContainer.height = previewPanel.height - resizerSize;
previewContainer.width = previewPanel.width;
navbarToggler.width = togglerSize;
previewToggler.width = togglerSize;
previewToggler.x = (previewPanel.width - togglerSize) / 2;
previewResizer.width = previewContainer.width;
}
else {
if(navbar.isOpen && wrapperL3.height < editorMinSize.height) {
navbar.isOpen = false;
return resizeAll();
}
if(!previewPanel.isOpen) {
previewPanel.x = wrapperL3.width - resizerSize;
}
else {
if(previewPanel.halfSize) {
previewPanel.width = (wrapperL3.width + resizerSize) / 2;
}
if(previewPanel.width < previewMinSize.width) {
previewPanel.halfSize = false;
previewPanel.width = previewMinSize.width;
}
previewPanel.x = wrapperL3.width - previewPanel.width;
if(previewPanel.x < editorMinSize.width) {
var previewPanelWidth = wrapperL3.width - editorMinSize.width;
if(previewPanelWidth < previewMinSize.width) {
previewPanel.isOpen = false;
}
else {
previewPanel.halfSize = false;
previewPanel.width = previewPanelWidth;
}
return resizeAll();
}
}
previewPanel.height = wrapperL3.height;
editor.width = previewPanel.x;
editor.height = wrapperL3.height;
previewContainer.left = resizerSize;
previewContainer.width = previewPanel.width - resizerSize;
previewContainer.height = previewPanel.height;
navbarToggler.height = togglerSize;
previewToggler.height = togglerSize;
previewToggler.y = (previewPanel.height - togglerSize) / 2;
previewResizer.height = previewContainer.height;
} }
previewPanel.top = navbarHeight;
previewPanel.height = innerWrapper.height - previewPanel.top;
previewPanel.applyCss();
// Editor
editor.top = navbarHeight;
editor.width = previewPanel.x;
editor.height = innerWrapper.height - editor.top;
editor.applyCss();
// Preview container
previewContainer.left = resizerSize;
previewContainer.width = previewPanel.width - resizerSize;
previewContainer.height = previewPanel.height;
previewContainer.applyCss();
// Navbar toggler
navbarToggler.applyCss();
navbarToggler.$elt.toggleClass('open', navbar.isOpen); navbarToggler.$elt.toggleClass('open', navbar.isOpen);
// Preview toggler
previewToggler.y = (previewPanel.height - togglerSize) / 2;
previewToggler.applyCss();
previewToggler.$elt.toggleClass('open', previewPanel.isOpen); previewToggler.$elt.toggleClass('open', previewPanel.isOpen);
// Preview resizer
previewResizer.height = previewContainer.height;
previewResizer.applyCss();
previewResizer.$elt.toggleClass('open', previewPanel.isOpen); previewResizer.$elt.toggleClass('open', previewPanel.isOpen);
wrapperL1.applyCss();
wrapperL2.applyCss();
wrapperL3.applyCss();
editor.applyCss();
previewPanel.applyCss();
previewContainer.applyCss();
previewToggler.applyCss();
previewResizer.applyCss();
navbarToggler.applyCss();
onResize(); onResize();
} }
layout.resizeAll = resizeAll; layout.resizeAll = resizeAll;
layout.init = function() { layout.init = function() {
outerWrapper = new DomObject('.layout-outer-wrapper'); wrapperL1 = new DomObject('.layout-wrapper-l1');
innerWrapper = new DomObject('.layout-inner-wrapper'); wrapperL2 = new DomObject('.layout-wrapper-l2');
wrapperL3 = new DomObject('.layout-wrapper-l3');
navbar = new DomObject('.navbar'); navbar = new DomObject('.navbar');
menuPanel = new DomObject('.menu-panel'); menuPanel = new DomObject('.menu-panel');
documentPanel = new DomObject('.document-panel'); documentPanel = new DomObject('.document-panel');
@ -233,6 +289,8 @@ define([
editorContentElt = editor.elt.querySelector('.editor-content'); editorContentElt = editor.elt.querySelector('.editor-content');
editorMarginElt = editor.elt.querySelector('.editor-margin'); editorMarginElt = editor.elt.querySelector('.editor-margin');
wrapperL1.$elt.toggleClass('layout-vertical', isVertical);
navbar.isOpen = true; navbar.isOpen = true;
navbar.createToggler(); navbar.createToggler();
navbarToggler.$elt.click(_.bind(navbar.toggle, navbar)); navbarToggler.$elt.click(_.bind(navbar.toggle, navbar));
@ -263,9 +321,9 @@ define([
}); });
var isDragging = false; var isDragging = false;
var desiredWidth; var desiredWidth, desiredHeight;
var lastCoord; var lastCoord;
outerWrapper.$elt.on('mousemove', function(evt) { wrapperL1.$elt.on('mousemove', function(evt) {
if(!isDragging) { if(!isDragging) {
return; return;
} }
@ -277,7 +335,13 @@ define([
x: evt.pageX, x: evt.pageX,
y: evt.pageY, y: evt.pageY,
}; };
if(lastCoord.x !== newCoord.x) { if(isVertical && lastCoord.y !== newCoord.y) {
desiredHeight += lastCoord.y - newCoord.y;
previewPanel.height = desiredHeight;
previewPanel.halfSize = false;
resizeAll();
}
if(!isVertical && lastCoord.x !== newCoord.x) {
desiredWidth += lastCoord.x - newCoord.x; desiredWidth += lastCoord.x - newCoord.x;
previewPanel.width = desiredWidth; previewPanel.width = desiredWidth;
previewPanel.halfSize = false; previewPanel.halfSize = false;
@ -292,6 +356,7 @@ define([
if(evt.which === 1) { if(evt.which === 1) {
isDragging = true; isDragging = true;
desiredWidth = previewPanel.width; desiredWidth = previewPanel.width;
desiredHeight = previewPanel.height;
lastCoord = { lastCoord = {
x: evt.pageX, x: evt.pageX,
y: evt.pageY, y: evt.pageY,

View File

@ -958,17 +958,15 @@ a {
* Layout * Layout
*********************************/ *********************************/
.layout-outer-wrapper { .layout-wrapper-l1,
.layout-wrapper-l2,
.layout-wrapper-l3 {
.layout-panel(); .layout-panel();
overflow: hidden; overflow: hidden;
&.layout-animate {
.transition(350ms ease-in-out all);
}
} }
.layout-inner-wrapper { .layout-animate {
.layout-panel(); .transition(350ms ease-in-out all);
overflow: hidden;
} }
.layout-resizer { .layout-resizer {
@ -977,6 +975,9 @@ a {
height: @resizer-size; height: @resizer-size;
&.open { &.open {
cursor: e-resize; cursor: e-resize;
.layout-vertical & {
cursor: s-resize;
}
} }
} }
@ -985,21 +986,30 @@ a {
padding: 0; padding: 0;
margin: 0; margin: 0;
width: @resizer-size; width: @resizer-size;
height: 60px; height: @resizer-size;
i { i {
font-size: 22px; font-size: 22px;
} }
&.layout-toggler-preview { &.layout-toggler-preview {
line-height: 55px;
.layout-animate & { .layout-animate & {
.transition(350ms ease-in-out all); .transition(350ms ease-in-out all);
} }
line-height: 55px;
i:before { i:before {
content: '\e87d'; content: '\e87d';
} }
&.open > i:before { &.open > i:before {
content: '\e87e'; content: '\e87e';
} }
.layout-vertical & {
line-height: 1.45;
i:before {
content: '\e87f';
}
&.open > i:before {
content: '\e880';
}
}
} }
&.layout-toggler-navbar { &.layout-toggler-navbar {
line-height: 0; line-height: 0;
@ -1338,7 +1348,7 @@ a {
.preview-panel { .preview-panel {
.layout-panel(); .layout-panel();
overflow: hidden; overflow: hidden;
border-left: 1px solid fade(@secondary, 6%); .box-shadow(inset 1px 0 fade(@secondary, 6%));
background-color: @secondary-bg-light; background-color: @secondary-bg-light;
z-index: 10; z-index: 10;
.layout-animate & { .layout-animate & {