|
@@ -0,0 +1,494 @@
|
|
|
+(function(window) {
|
|
|
+ function startHLayout() {
|
|
|
+ var md
|
|
|
+ var grabEl
|
|
|
+ var sectionResizeEl
|
|
|
+
|
|
|
+ // Global mouse update
|
|
|
+ document.addEventListener("mousemove", function(e) {
|
|
|
+ if (md === undefined) md = {x: e.clientX, y: e.clientY}
|
|
|
+ md.deltaX = e.clientX - md.x
|
|
|
+ md.deltaY = e.clientY - md.y
|
|
|
+ md.x = e.clientX
|
|
|
+ md.y = e.clientY
|
|
|
+ })
|
|
|
+ // Handle dragstart
|
|
|
+ document.addEventListener("mousedown", function(e) {
|
|
|
+ // Check for section resize
|
|
|
+ if (e.target.matches("section")) {
|
|
|
+ e.preventDefault()
|
|
|
+ e.stopPropagation()
|
|
|
+
|
|
|
+ sectionResizeEl = e.target
|
|
|
+ sectionResizeEl.classList.add("resizing")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // Check if element is our
|
|
|
+ if (!e.target.matches(".hpane > header")) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ e.preventDefault()
|
|
|
+ e.stopPropagation()
|
|
|
+ grabEl = e.target.parentElement
|
|
|
+
|
|
|
+ var parent = grabEl.parentElement
|
|
|
+
|
|
|
+ var elDim = grabEl.getBoundingClientRect()
|
|
|
+ document.body.appendChild(grabEl)
|
|
|
+ grabEl.classList.add("detached", "moving")
|
|
|
+ grabEl.style.width = elDim.width + "px"
|
|
|
+ grabEl.style.height = elDim.height + "px"
|
|
|
+
|
|
|
+ // Add discover to other panes
|
|
|
+ // $('.hpane:not(.detached)').addClass("discover");
|
|
|
+ // All childs to pointer event none
|
|
|
+ if (parent.matches("section")) {
|
|
|
+ var child = parent.querySelector(".hpane, section") // hpane or section
|
|
|
+ child.removeAttribute("style")
|
|
|
+ child.style["flex-basis"] = parent.style["flex-basis"]
|
|
|
+ parent.parentElement.insertBefore(child, parent)
|
|
|
+ parent.parentElement.removeChild(parent)
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // Handle drag
|
|
|
+ document.addEventListener("mousemove", function(e) {
|
|
|
+ if (sectionResizeEl != null) {
|
|
|
+ var firstEl = sectionResizeEl.children[0]
|
|
|
+ var secondEl = sectionResizeEl.children[1]
|
|
|
+ // Default vertical
|
|
|
+ var tDim = "offsetWidth"
|
|
|
+ var tDelta = "deltaX"
|
|
|
+ if (sectionResizeEl.matches(".horizontal")) {
|
|
|
+ tDim = "offsetHeight"
|
|
|
+ tDelta = "deltaY"
|
|
|
+ }
|
|
|
+ var parentValue = sectionResizeEl[tDim]
|
|
|
+
|
|
|
+ var firstNewDim = (firstEl[tDim] + md[tDelta]) / parentValue * 100
|
|
|
+ var secondNewDim = (secondEl[tDim] - md[tDelta]) / parentValue * 100
|
|
|
+
|
|
|
+ firstEl.style["flex-basis"] = firstNewDim + "%"
|
|
|
+ secondEl.style["flex-basis"] = secondNewDim + "%"
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // console.log("Drag:",e)
|
|
|
+ // if (!e.target.matches(".hpane > header")) { // we only deal with header
|
|
|
+ // return
|
|
|
+ // }
|
|
|
+ if (grabEl === undefined) return
|
|
|
+ // Get Absolute position somehow
|
|
|
+ // var pos = $grab.position();
|
|
|
+ var elDim = grabEl.getBoundingClientRect()
|
|
|
+ // var nx = elDim.left + md.deltaX
|
|
|
+ // var ny = elDim.top + md.deltaY
|
|
|
+ var offX = elDim.width / 2
|
|
|
+ var offY = 0
|
|
|
+ grabEl.style.left = e.clientX - offX + "px"
|
|
|
+ grabEl.style.top = e.clientY - offY + "px"
|
|
|
+ var targetEl = e.target
|
|
|
+ // if(!targetEl.matches(".hpane")) {
|
|
|
+ for (;targetEl !== null && !targetEl.matches(".hpane"); targetEl = targetEl.parentElement); // find Parent ".hpane"
|
|
|
+
|
|
|
+ if (targetEl != null && targetEl.matches(".hpane:not(.preview)")) {
|
|
|
+ // check attachment
|
|
|
+ var placement = checkAttach(targetEl, e)
|
|
|
+ if (placement !== 0) {
|
|
|
+ previewPanel(grabEl, targetEl, placement)
|
|
|
+ } else {
|
|
|
+ removePreviews()
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ removePreviews()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ document.addEventListener("mouseup", function(e) {
|
|
|
+ if (sectionResizeEl) {
|
|
|
+ sectionResizeEl.classList.remove("resizing")
|
|
|
+ sectionResizeEl = null
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // Drag
|
|
|
+ if (grabEl === undefined) return
|
|
|
+ removePreviews()
|
|
|
+ grabEl.classList.remove("moving")
|
|
|
+
|
|
|
+ var targetEl = e.target
|
|
|
+ for (;targetEl !== null && !targetEl.matches(".hpane"); targetEl = targetEl.parentElement); // find Parent ".hpane"
|
|
|
+
|
|
|
+ if (targetEl !== null) {
|
|
|
+ var placement = checkAttach(targetEl, e)
|
|
|
+ if (placement !== 0) {
|
|
|
+ grabEl.classList.remove("detached")
|
|
|
+ grabEl.removeAttribute("style")
|
|
|
+ attachPanel(grabEl, targetEl, placement)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ grabEl = undefined
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ function attachPanel(grabEl, targetEl, placement) {
|
|
|
+ if (!placement) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var type
|
|
|
+ if ((placement % 2) === 1)type = "horizontal" // else
|
|
|
+ if ((placement % 2) === 0)type = "vertical"
|
|
|
+
|
|
|
+ var parentEl = targetEl.parentElement
|
|
|
+ var sectionEl
|
|
|
+ var sibEl = targetEl // it will be new sibling
|
|
|
+
|
|
|
+ var newSectionEl = document.createElement("section")
|
|
|
+ newSectionEl.classList.add(type)
|
|
|
+ newSectionEl.style["flex-basis"] = targetEl.style["flex-basis"]
|
|
|
+ if (sibEl.nextElementSibling !== null && sibEl.nextElementSibling.matches("section, .hpane")) {
|
|
|
+ parentEl.insertBefore(newSectionEl, parentEl.children[0])
|
|
|
+ } else {
|
|
|
+ parentEl.appendChild(newSectionEl)
|
|
|
+ }
|
|
|
+ // parentEl.removeChild(sibEl)
|
|
|
+
|
|
|
+ grabEl.style["flex-basis"] = "33%"
|
|
|
+ sibEl.style["flex-basis"] = "66%"
|
|
|
+ if (placement < 3) {
|
|
|
+ newSectionEl.appendChild(grabEl)
|
|
|
+ newSectionEl.appendChild(sibEl) // will this work?
|
|
|
+ // $section.append(what);
|
|
|
+ // $section.append("<div class='splitter'></div>");
|
|
|
+ // $section.append($sib);
|
|
|
+ } else {
|
|
|
+ newSectionEl.appendChild(sibEl)
|
|
|
+ newSectionEl.appendChild(grabEl) // will this work?
|
|
|
+ // $section.append($sib);
|
|
|
+ // $section.append("<div class='splitter'></div>");
|
|
|
+ // $section.append(what);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function removePreviews() {
|
|
|
+ var previewEls = document.querySelectorAll(".attach-preview")
|
|
|
+ if (previewEls === null) { // not sure if it is needed
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for (var i = previewEls.length; i--; i >= 0) {
|
|
|
+ previewEls[i].style.display = "none"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ function checkAttach(targetEl, e) {
|
|
|
+ var targetDim = targetEl.getBoundingClientRect()
|
|
|
+
|
|
|
+ var tW = targetDim.width / 3
|
|
|
+ var tH = targetDim.height / 3
|
|
|
+ var rPos = {x: e.pageX - targetDim.left, y: e.pageY - targetDim.top}
|
|
|
+ // Calc dists and check the closest one
|
|
|
+ // Counter clock wise 1 TOP 2 RIGHT 3 BOTTOM 4 LEFT
|
|
|
+ if (rPos.x > tW && rPos.x < targetDim.width - tW && rPos.y < tH) { // 1 Top
|
|
|
+ return 1
|
|
|
+ } else if (rPos.x > tW && rPos.x < targetDim.width - tW && rPos.y > targetDim.height - tH) { // 3 Bottom
|
|
|
+ return 3
|
|
|
+ } else if (rPos.x < tW) { // 2 Left
|
|
|
+ return 2
|
|
|
+ } else if (rPos.x > targetDim.width - tW) { // 4 Right
|
|
|
+ return 4
|
|
|
+ }
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+
|
|
|
+ function previewPanel(grabEl, targetEl, placement) {
|
|
|
+ var previewEl = document.querySelector(".attach-preview")
|
|
|
+ if (previewEl === undefined || previewEl === null) {
|
|
|
+ previewEl = document.createElement("div")
|
|
|
+ previewEl.setAttribute("class", "attach-preview")
|
|
|
+ previewEl.setAttribute("style", "display:none;position:fixed")
|
|
|
+ document.body.appendChild(previewEl)
|
|
|
+ }
|
|
|
+ previewEl.style.display = "block" // Show element
|
|
|
+ var targetDim = targetEl.getBoundingClientRect()
|
|
|
+ if ((placement % 2) === 1) { // Odd is top or bottom
|
|
|
+ previewEl.style.height = (targetDim.height / 3) + "px"
|
|
|
+ previewEl.style.width = targetDim.width + "px"
|
|
|
+ previewEl.style.left = targetDim.left + "px"
|
|
|
+ if (placement === 1) {
|
|
|
+ previewEl.style.top = targetDim.top + "px"
|
|
|
+ } else {
|
|
|
+ previewEl.style.top = (targetDim.top + targetDim.height - (targetDim.height / 3)) + "px"
|
|
|
+ }
|
|
|
+ } else if ((placement % 2) === 0) {
|
|
|
+ previewEl.style.height = targetDim.height + "px"
|
|
|
+ previewEl.style.width = (targetDim.width / 3) + "px"
|
|
|
+ previewEl.style.top = targetDim.top + "px"
|
|
|
+ if (placement === 2) {
|
|
|
+ previewEl.style.left = targetDim.left + "px"
|
|
|
+ } else {
|
|
|
+ previewEl.style.left = (targetDim.left + targetDim.width - (targetDim.width / 3)) + "px"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ window.onload = startHLayout
|
|
|
+})(window)
|
|
|
+
|
|
|
+/*
|
|
|
+var md
|
|
|
+function startHLayoutEvents() {
|
|
|
+ document.addEventListener("mousemove", function(e) {
|
|
|
+ if (md === undefined) md = {x: e.clientX, y: e.clientY}
|
|
|
+ md.deltaX = e.clientX - md.x
|
|
|
+ md.deltaY = e.clientY - md.y
|
|
|
+ md.x = e.clientX
|
|
|
+ md.y = e.clientY
|
|
|
+ })
|
|
|
+ // Global mouse event;
|
|
|
+
|
|
|
+ var $grab = undefined;
|
|
|
+ // Start drag
|
|
|
+ $(document).on('mousedown','.hpane > header',function(e){
|
|
|
+ if(e.which != 1) return;
|
|
|
+ if(!$(e.target).is(".hpane > header")) return;
|
|
|
+
|
|
|
+ e.preventDefault();
|
|
|
+ e.stopPropagation();
|
|
|
+
|
|
|
+ $grab = $(this).parent();
|
|
|
+ $parent = $grab.parent();
|
|
|
+ var next = $grab.next();
|
|
|
+ var origW = $grab.width();
|
|
|
+ var origH = $grab.height();
|
|
|
+
|
|
|
+ // Check if we are root?
|
|
|
+
|
|
|
+ var dim = {w: $grab.width(), h: $grab.height()};
|
|
|
+ var pos = $grab.position();
|
|
|
+
|
|
|
+ $($grab).detach().appendTo('body').addClass("detached").addClass("moving").css({width:dim.w,height:dim.h});
|
|
|
+
|
|
|
+ $('.hpane:not(.detached)').addClass("discover");
|
|
|
+
|
|
|
+ // All childs to pointer event none
|
|
|
+ if($parent.is('section')) {
|
|
|
+ // We aren't
|
|
|
+
|
|
|
+ $child = $parent.children('.hpane, section');
|
|
|
+ $child.attr('style','');
|
|
|
+ $child.css('flex-basis',$parent.css('flex-basis'));
|
|
|
+ $child.detach();
|
|
|
+ $parent.replaceWith($child);
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ var $sectionResize = null;
|
|
|
+ $(document).on('mousedown','section',function(e) {
|
|
|
+
|
|
|
+ var $target = $(e.target);
|
|
|
+ if(!$target.is("section"))return;
|
|
|
+ e.preventDefault();
|
|
|
+ $sectionResize = $target;
|
|
|
+ $sectionResize.addClass("resizing");
|
|
|
+ });
|
|
|
+ $(document).on('mousemove',function(e) {
|
|
|
+ if($sectionResize == null) return;
|
|
|
+ var $first = $sectionResize.children(':nth-child(1)');
|
|
|
+ var $second = $sectionResize.children(':nth-child(2)');
|
|
|
+
|
|
|
+
|
|
|
+ var common;
|
|
|
+ var common2;
|
|
|
+ if( $sectionResize.is(".horizontal")) {common = "height",common2 = "deltaY"};
|
|
|
+ if( $sectionResize.is(".vertical")) {common = "width", common2 = "deltaX"};
|
|
|
+
|
|
|
+ var parentValue = $sectionResize[common]();
|
|
|
+ var hFirst = $first[common]();
|
|
|
+ var hSec = $second[common]();
|
|
|
+
|
|
|
+ var newVal1 = (hFirst + md[common2]) / parentValue * 100;
|
|
|
+ var newVal2 = (hSec -md[common2]) / parentValue * 100;
|
|
|
+
|
|
|
+ $first.css('flex-basis',newVal1 + "%");
|
|
|
+ $second.css('flex-basis',newVal2 + "%");
|
|
|
+
|
|
|
+ });
|
|
|
+ $(document).on('mouseup',function(e) {
|
|
|
+ if($sectionResize) {
|
|
|
+ $sectionResize.removeClass("resizing");
|
|
|
+ }
|
|
|
+
|
|
|
+ $sectionResize = null;
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ $(document).on('mousemove',function(e) {
|
|
|
+ if($grab == undefined) return;
|
|
|
+ var pos = $grab.position();
|
|
|
+
|
|
|
+ var nx = pos.left + md.deltaX;
|
|
|
+ var ny = pos.top + md.deltaY;
|
|
|
+ var offX = $grab.width() / 2;
|
|
|
+ var offY = 0;
|
|
|
+
|
|
|
+ $grab.css({left: e.clientX - offX, top: e.clientY -offY});
|
|
|
+
|
|
|
+ // Check target
|
|
|
+ var $target = $(e.target);
|
|
|
+
|
|
|
+ if(!$target.is(".hpane")) {
|
|
|
+ $target = $target.parents(".hpane");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if($target.is(".hpane:not(.preview)")){
|
|
|
+ var placement = checkAttach($target,e);
|
|
|
+ if(placement != 0 ) {
|
|
|
+ previewPanel($grab,$target,placement);
|
|
|
+ } else {
|
|
|
+ removePreviews();
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ removePreviews();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ $(document).on('mouseup',function(e) {
|
|
|
+ if($grab == undefined) return;
|
|
|
+
|
|
|
+ removePreviews();
|
|
|
+
|
|
|
+ $grab.removeClass("moving");
|
|
|
+ $('.hpane').removeClass("discover");
|
|
|
+
|
|
|
+ $target = $(e.target);
|
|
|
+ if(!$target.is(".hpane")) $target = $target.parents('.hpane');
|
|
|
+
|
|
|
+ if($target.is(".hpane")){
|
|
|
+ var placement = checkAttach($target,e);
|
|
|
+ if(placement != 0 ) {
|
|
|
+ $grab.removeClass("detached");
|
|
|
+ $grab.attr('style','');
|
|
|
+ attachPanel($grab,$target,placement);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $grab = undefined;
|
|
|
+ return;
|
|
|
+ });
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ function recalcFlex() {
|
|
|
+ $('section.horizontal > section, section.horizontal > .hpane').each(function() {
|
|
|
+ var parentH = $(this).parent().height();
|
|
|
+ var curH = $(this).height();
|
|
|
+ var flex = 100 * curH / parentH;
|
|
|
+ $(this).css({'flex-basis':flex + "%"});
|
|
|
+ });
|
|
|
+ $('section.vertical > section, section.vertical > .hpane').each(function() {
|
|
|
+ var parentW = $(this).parent().width();
|
|
|
+ var curW = $(this).width();
|
|
|
+ var flex = 100 * curW / parentW;
|
|
|
+ $(this).css({'flex-basis':flex + "%"});
|
|
|
+ });
|
|
|
+ }
|
|
|
+ recalcFlex();
|
|
|
+
|
|
|
+ function checkAttach($target,e) {
|
|
|
+
|
|
|
+ var tW = $target.width()/3;
|
|
|
+ var tH = $target.height()/3;
|
|
|
+
|
|
|
+ var targetPos = $target.offset();
|
|
|
+ var dim = { w: $target.width(), h: $target.height()};
|
|
|
+ var rPos = { x: e.pageX - targetPos.left, y: e.pageY - targetPos.top};
|
|
|
+ //Calc dists and check the closest one
|
|
|
+
|
|
|
+
|
|
|
+ if(rPos.x > tW && rPos.x < dim.w - tW && rPos.y < tH) { // 1 Top
|
|
|
+ return 1;
|
|
|
+ } else if(rPos.x > tW && rPos.x < dim.w - tW && rPos.y > dim.h - tH){ // 3 Bottom
|
|
|
+ return 3;
|
|
|
+ } else if(rPos.x < tW) { // 2 Left
|
|
|
+ return 2;
|
|
|
+ } else if( rPos.x > dim.w - tW){ // 4 Right
|
|
|
+ return 4;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ function removePreviews() {
|
|
|
+ $('.attach-preview').hide();
|
|
|
+ }
|
|
|
+ function previewPanel($grab,$target,attach) {
|
|
|
+
|
|
|
+ $previewDiv = $(".attach-preview");
|
|
|
+ if($previewDiv.length == 0 ) {
|
|
|
+ $previewDiv = $('<div class="attach-preview" style="display:none;position:fixed"></div>').appendTo('body');
|
|
|
+ }
|
|
|
+
|
|
|
+ $previewDiv.show();
|
|
|
+ var dim = {w:$target.width(),h:$target.height()};
|
|
|
+ var pos = $target.offset();
|
|
|
+
|
|
|
+ if((attach % 2) == 1) {
|
|
|
+ $previewDiv.css('height',dim.h/3);
|
|
|
+ $previewDiv.css("width",dim.w);
|
|
|
+ $previewDiv.css("left",pos.left);
|
|
|
+ if(attach == 1) {
|
|
|
+ $previewDiv.css('top',pos.top);
|
|
|
+ } else {
|
|
|
+ $previewDiv.css('top',pos.top + dim.h - dim.h/3);
|
|
|
+ }
|
|
|
+ } else if((attach % 2) == 0) {
|
|
|
+ $previewDiv.css("height",dim.h);
|
|
|
+ $previewDiv.css('width',dim.w/3);
|
|
|
+ $previewDiv.css("top",pos.top);
|
|
|
+ if(attach == 2) {
|
|
|
+ $previewDiv.css('left',pos.left);
|
|
|
+ } else {
|
|
|
+ $previewDiv.css('left',pos.left + dim.w - dim.w/3);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ function attachPanel(what,target, attach) {
|
|
|
+ if(attach){
|
|
|
+ var type
|
|
|
+ if((attach % 2) == 1)type = "horizontal";
|
|
|
+ if((attach % 2) == 0)type = "vertical";
|
|
|
+ $target = $(target);
|
|
|
+ $parent = $(target).parent();
|
|
|
+
|
|
|
+ $sib = $(target);
|
|
|
+ if($sib.next().is("section, .hpane,.splitter")) {
|
|
|
+ $section = $("<section class='" + type +"' style='flex-basis:" + $target.css('flex-basis') + "'></section>").prependTo($parent);
|
|
|
+ } else {
|
|
|
+ $section = $("<section class='" + type + "' style='flex-basis:" + $target.css('flex-basis') +" '></section>").appendTo($parent);
|
|
|
+ }
|
|
|
+ $sib.detach();
|
|
|
+ what.css('flex-basis','33%');
|
|
|
+ $sib.css('flex-basis','66%');
|
|
|
+ if(attach < 3) {
|
|
|
+ $section.append(what);
|
|
|
+ //$section.append("<div class='splitter'></div>");
|
|
|
+ $section.append($sib);
|
|
|
+ } else {
|
|
|
+ $section.append($sib);
|
|
|
+ //$section.append("<div class='splitter'></div>");
|
|
|
+ $section.append(what);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+$(function() {
|
|
|
+
|
|
|
+ startHLayoutEvents();
|
|
|
+
|
|
|
+});*/
|