From 37d31ab83acc726b3a4c1461407f049050a23401 Mon Sep 17 00:00:00 2001 From: John Bintz Date: Sun, 30 Aug 2009 11:00:58 -0400 Subject: [PATCH] nearly have layout editor working --- .../FloatedDivConstructor.js | 76 +++++--- .../LayoutConstructorsTest.html | 148 ++++++++++++++- addons/Core/layout_manager/LayoutEditor.js | 173 +++++++++++------- addons/Core/layout_manager/index.html | 76 ++++++-- 4 files changed, 356 insertions(+), 117 deletions(-) diff --git a/addons/Core/layout_constructors/FloatedDivConstructor.js b/addons/Core/layout_constructors/FloatedDivConstructor.js index 01de19e..a3f011e 100644 --- a/addons/Core/layout_constructors/FloatedDivConstructor.js +++ b/addons/Core/layout_constructors/FloatedDivConstructor.js @@ -1,30 +1,36 @@ var FloatedDivConstructor = Class.create({ + 'areas': ["header", "comic", "body", "footer"], 'generate_html': function(layout) { var output = []; output.push('
'); - - var areas = $w("header comic body footer"); var i, il; var indent = 1; var gi = function() { return " ".times(indent); } var has_whole_sidebar = null; + var has_layout = {}; + $w('left right').each(function(which) { + if (layout[which].active) { + has_layout[which] = [layout[which].start, layout[which].end]; + } + }); + var range = null; - if (layout.left) { - if (layout.right) { + if (has_layout.left) { + if (has_layout.right) { range = []; var all_same = true; - for (i = 0; i < 2; ++i) { - if (layout.left[i] != layout.right[i]) { all_same = false; break; } + for (i = 0; i <= 1; ++i) { + if (has_layout.left[i] != has_layout.right[i]) { all_same = false; break; } } if (!all_same) { $w('left right').each(function(field) { if (!has_whole_sidebar) { - if ((layout[field][0] == 0) && (layout[field][1] == 3)) { + if ((has_layout[field][0] == 0) && (has_layout[field][1] == 3)) { has_whole_sidebar = field; } } @@ -32,24 +38,24 @@ var FloatedDivConstructor = Class.create({ } if (!has_whole_sidebar) { - range[0] = Math.min(layout.left[0], layout.right[0]); - range[1] = Math.max(layout.left[1], layout.right[1]); + range[0] = Math.min(has_layout.left[0], has_layout.right[0]); + range[1] = Math.max(has_layout.left[1], has_layout.right[1]); } else { switch (has_whole_sidebar) { - case 'left': range = layout.right; break; - case 'right': range = layout.left; break; + case 'left': range = has_layout.right; break; + case 'right': range = has_layout.left; break; } } } else { - range = layout.left; + range = has_layout.left; } } else { - if (layout.right) { - range = layout.right; + if (has_layout.right) { + range = has_layout.right; } } - for (i = 0, il = areas.length; i < il; ++i) { + for (i = 0, il = this.areas.length; i < il; ++i) { if ((i == 0) && has_whole_sidebar) { output.push(gi() + '
'); indent++; @@ -62,8 +68,8 @@ var FloatedDivConstructor = Class.create({ } $w("left right").each(function(field) { if (field != has_whole_sidebar) { - if (layout[field]) { - if (layout[field][0] == i) { + if (has_layout[field]) { + if (has_layout[field][0] == i) { output.push(gi() + '
'); } } @@ -71,7 +77,7 @@ var FloatedDivConstructor = Class.create({ }); } - output.push(gi() + '
'); + output.push(gi() + '
'); if (range) { if (range[1] == i) { @@ -91,22 +97,48 @@ var FloatedDivConstructor = Class.create({ return output.join("\n"); }, - 'generate_css': function(info) { + 'generate_css': function(layout) { var output = []; var include_container = false; - + + var area_margins = {}; + var i; + var myThis = this; + $w('left right').each(function(field) { - if (info[field]) { + if (layout[field].active) { include_container = true; - output.push('#' + field + '-sidebar { float: ' + field + '; display: inline; width: ' + info[field].width + 'px }'); + output.push('#' + field + '-sidebar { float: ' + field + '; display: inline; width: ' + layout[field].width + 'px }'); + + for (i = layout[field].start; i <= layout[field].end; ++i) { + var area = myThis.areas[i]; + if (!area_margins[area]) { area_margins[area] = {}; } + area_margins[area][field] = layout[field].width; + } } }); + for (i = 0; i < this.areas.length; ++i) { + var area = this.areas[i]; + if (area_margins[area]) { + var types = []; + var type; + for (type in area_margins[area]) { + types.push("margin-" + type + ": " + area_margins[area][type] + "px"); + } + output.push("#" + area + " { " + types.join("; ") + " }"); + } + } + if (include_container) { output.unshift('#sidebar-container, #whole-sidebar-container { overflow: hidden }'); output.push('.clear { clear: both }'); } + if (layout.body) { + output.unshift('#container { width: ' + layout.body + 'px }'); + } + return output.join("\n"); } }); \ No newline at end of file diff --git a/addons/Core/layout_constructors/LayoutConstructorsTest.html b/addons/Core/layout_constructors/LayoutConstructorsTest.html index 153fc6a..9304be3 100644 --- a/addons/Core/layout_constructors/LayoutConstructorsTest.html +++ b/addons/Core/layout_constructors/LayoutConstructorsTest.html @@ -14,7 +14,18 @@ var myThis = this; [ { - 'input': {}, + 'input': { + 'left': { + 'active': false, + 'start': 0, + 'end': 3 + }, + 'right': { + 'active': false, + 'start': 1, + 'end': 3 + } + }, 'expected_result': '
\n' + ' \n' + '
\n' + @@ -23,7 +34,18 @@ '
' }, { - 'input': {'left': [0, 0]}, + 'input': { + 'left': { + 'active': true, + 'start': 0, + 'end': 0 + }, + 'right': { + 'active': false, + 'start': 0, + 'end': 3 + } + }, 'expected_result': '
\n' + ' ' }, { - 'input': {'left': [0, 1]}, + 'input': { + 'left': { + 'active': true, + 'start': 0, + 'end': 1 + }, 'right': { + 'active': false, + 'start': 1, + 'end': 3 + } + }, 'expected_result': '
\n' + ' ' }, { - 'input': {'right': [0, 1]}, + 'input': { + 'right': { + 'active': true, + 'start': 0, + 'end': 1 + }, + 'left': { + 'active': false, + 'start': 1, + 'end': 3 + } + }, 'expected_result': '
\n' + ' ' }, { - 'input': {'left': [0, 3], 'right': [0, 1]}, + 'input': { + 'left': { + 'active': true, + 'start': 0, + 'end': 3 + }, + 'right': { + 'active': true, + 'start': 0, + 'end': 1 + } + }, 'expected_result': '
\n' + '
\n' + ' \n' + @@ -88,20 +142,94 @@ var myThis = this; [ { - 'input': {}, + 'input': { + 'left': { + 'active': false, + 'start': 0, + 'end': 0, + 'width': 0 + }, + 'right': { + 'active': false, + 'start': 0, + 'end': 0, + 'width': 0 + } + }, 'expected_result': '' }, { - 'input': {'left': {'width': '200'}}, - 'expected_result': '#sidebar-container, #whole-sidebar-container { overflow: hidden }\n' + 'input': { + 'body': '800', + 'left': { + 'active': true, + 'start': 0, + 'end': 3, + 'width': 200 + }, + 'right': { + 'active': false, + 'start': 1, + 'end': 3, + 'width': 175 + } + }, + 'expected_result': '#container { width: 800px }\n' + + '#sidebar-container, #whole-sidebar-container { overflow: hidden }\n' + '#left-sidebar { float: left; display: inline; width: 200px }\n' + + '#header { margin-left: 200px }\n' + + '#comic { margin-left: 200px }\n' + + '#body { margin-left: 200px }\n' + + '#footer { margin-left: 200px }\n' + '.clear { clear: both }' }, { - 'input': {'left': {'width': '200'}, 'right': {'width': '100'}}, - 'expected_result': '#sidebar-container, #whole-sidebar-container { overflow: hidden }\n' + 'input': { + 'body': '800', + 'left': { + 'active': true, + 'start': 1, + 'end': 2, + 'width': 200 + }, + 'right': { + 'active': false, + 'start': 1, + 'end': 3, + 'width': 175 + } + }, + 'expected_result': '#container { width: 800px }\n' + + '#sidebar-container, #whole-sidebar-container { overflow: hidden }\n' + + '#left-sidebar { float: left; display: inline; width: 200px }\n' + + '#comic { margin-left: 200px }\n' + + '#body { margin-left: 200px }\n' + + '.clear { clear: both }' + }, + { + 'input': { + 'body': '800', + 'left': { + 'active': true, + 'start': 0, + 'end': 1, + 'width': 200 + }, + 'right': { + 'active': true, + 'start': 0, + 'end': 3, + 'width': 100 + } + }, + 'expected_result': '#container { width: 800px }\n' + + '#sidebar-container, #whole-sidebar-container { overflow: hidden }\n' + '#left-sidebar { float: left; display: inline; width: 200px }\n' + '#right-sidebar { float: right; display: inline; width: 100px }\n' + + '#header { margin-left: 200px; margin-right: 100px }\n' + + '#comic { margin-left: 200px; margin-right: 100px }\n' + + '#body { margin-right: 100px }\n' + + '#footer { margin-right: 100px }\n' + '.clear { clear: both }' } ].each(function(info) { diff --git a/addons/Core/layout_manager/LayoutEditor.js b/addons/Core/layout_manager/LayoutEditor.js index ee6a82e..0e40d19 100644 --- a/addons/Core/layout_manager/LayoutEditor.js +++ b/addons/Core/layout_manager/LayoutEditor.js @@ -41,55 +41,62 @@ var LayoutEditor = Class.create({ handle.insert(b); handle.insert(inside); myThis.container.insert(handle); + myThis.sidebar_handles[which] = handle; var generate_handle_move = function(g) { return function(e) { Event.stop(e); - var cy = handle.viewportOffset()['top']; + var cy = handle.viewportOffset()['top'] + document.viewport.getScrollOffsets()['top']; var ch = handle.getDimensions()['height']; var ny, nh; switch(g.className) { case 'top': - ny = e.clientY; + ny = e.clientY + document.viewport.getScrollOffsets()['top']; nh = ch + (cy - ny); break; - case 'bottom': - nh = ch + (cy + ch - e.clientY); + case 'bottom': + ny = cy; + nh = e.clientY - cy + document.viewport.getScrollOffsets()['top']; break; } if (nh < 5) { nh = 5; } handle.style.top = ny; handle.style.height = nh; + var i, il; + var h = 0; + var closest = { 'top': null, 'bottom': null }; + + var ty = ny; + var by = ty + nh; + + for (i = 0, il = myThis.section_handles.length; i < il; ++i) { + var distance = { 'top': null, 'bottom': null }; + distance.top = Math.abs(ty - h); + h += myThis.section_handles[i].getDimensions()['height']; + distance.bottom = Math.abs(by - h); + for (field in closest) { + var ty = handle.viewportOffset()['top']; + var by = ny + handle.getDimensions()['height']; + + if (closest[field] == null) { closest[field] = [distance[field], i]; } + if (distance[field] < closest[field][0]) { + closest[field] = [distance[field], i]; + } + } + } + if (closest['bottom'][1] < closest['top'][1]) { + closest['bottom'][1] = closest['top'][1]; + } + myThis.info.info[which].start = closest['top'][1]; + myThis.info.info[which].end = closest['bottom'][1]; + handle.align_bottom(); }; }; - - var snap_handle = function() { - var ty = handle.viewportOffset()['top']; - var by = ty + handle.getDimensions()['height']; - - var i, il; - var h = 0; - var closest = { 'top': null, 'bottom': null }; - for (i = 0, il = myThis.section_handles.length; i < il; ++i) { - var distance = { 'top': null, 'bottom': null }; - distance.top = Math.abs(ty - h); - h += myThis.section_handles[i].getDimensions()['height']; - distance.bottom = Math.abs(by - h); - for (field in closest) { - if (closest[field] == null) { closest[field] = [distance[field], i]; } - if (distance[field] < closest[field][0]) { - closest[field] = [distance[field], i]; - } - } - } - top.console.log(closest); - myThis.info.change('sidebars', which, [closest.top[1], closest.bottom[1]]); - }; - + inside.observe('mousedown', function(e) { Event.stop(e); }); handle.observe('mousedown', function(e) { Event.stop(e); }); @@ -105,18 +112,19 @@ var LayoutEditor = Class.create({ Event.observe(document.body, 'mouseup', function() { Event.stopObserving(document.body, 'mousemove', t_handle); Event.stopObserving(document.body, 'mousemove', b_handle); - snap_handle(); }); - - myThis.sidebar_handles[which] = handle; + }); + + Event.observe(document.body, 'mouseup', function() { + myThis.draw_sidebars(); }); }, 'register_info': function(info) { this.info = info; var myThis = this; - this.info.onchange = function() { - myThis.draw_sidebars(); - } + this.info.onChange = function() { + myThis.draw(); + }; }, 'draw': function() { this.draw_sidebars(); @@ -124,62 +132,85 @@ var LayoutEditor = Class.create({ 'draw_sidebars': function() { var myThis = this; $w('left right').each(function(field) { - if (myThis.info.sidebars[field]) { - var fi = myThis.info.sidebars[field]; - var t = myThis.section_handles[fi[0]].viewportOffset()['top']; + if (myThis.info.info[field].active) { + myThis.sidebar_handles[field].show(); + var fi = myThis.info.info[field]; + var t = myThis.section_handles[fi.start].viewportOffset()['top'] + document.viewport.getScrollOffsets()['top']; var h = 0; var i; - for (i = fi[0]; i <= fi[1]; ++i) { + for (i = fi.start; i <= fi.end; ++i) { h += myThis.section_handles[i].getDimensions()['height']; } - var w = Math.floor((myThis.info.widths[field] / myThis.info.widths.body) * myThis.width); + var w = Math.floor((fi.width / myThis.info.info.body) * myThis.width); var l; switch (field) { case 'left': - l = myThis.container.viewportOffset()['left']; - break; + l = myThis.container.viewportOffset()['left']; break; case 'right': - l = myThis.container.viewportOffset()['left'] + myThis.width - w; - break; + l = myThis.container.viewportOffset()['left'] + myThis.width - w; break; } - var field_map = { - 'top': t, - 'left': l, - 'width': w, - 'height': h - }; + var field_map = { 'top': t, 'left': l, 'width': w, 'height': h }; for (param in field_map) { myThis.sidebar_handles[field].style[param] = field_map[param]; } myThis.sidebar_handles[field].align_bottom(); + } else { + myThis.sidebar_handles[field].hide(); } }); + myThis.info.do_sidebar_drag(); } }); + var LayoutInfo = Class.create({ - 'sidebars': { - 'left': [1, 3], 'right': [2, 3] - }, - 'widths': { - 'body': 800, 'left': 200, 'right': 175 - }, - 'change': function(group, detail, value) { - if (this[group]) { - if (this[group][detail]) { - this[group][detail] = value; - this.onchange(); - } + 'info': { + 'body': 800, + 'left': { + 'active': true, + 'start': 0, + 'end': 3, + 'width': 200 + }, + 'right': { + 'active': true, + 'start': 0, + 'end': 3, + 'width': 175 } - } + }, + 'register_form': function(target) { + var myThis = this; + $w('left right').each(function(which) { + var i; + var get_v = function(v) { return v; } + for (i in myThis.info[which]) { + var my_which = get_v(which); + var f = target.select('#' + which + "-" + i).pop(); + if (f) { + switch (i) { + case 'active': + f.checked = myThis.info[my_which]['active']; + f.observe('click', function(e) { + myThis.info[my_which]['active'] = e.currentTarget.checked; + myThis.onChange(); + }); + break; + case 'width': + f.value = myThis.info[my_which]['width']; + f.observe('keyup', function(e) { + myThis.info[my_which]['width'] = e.currentTarget.value.replace(/[^0-9]/, ''); + myThis.onChange(); + }); + break; + } + } + } + }); + }, + 'do_sidebar_drag': function() { + this.onSidebarDrag(); + }, + 'onChange': function() {} }); -Event.observe(window, 'load', function() { - if ($('layout-editor-container')) { - var l = new LayoutEditor($('layout-editor-container')); - - var info = new LayoutInfo(); - l.register_info(info); - l.draw(); - } -}); diff --git a/addons/Core/layout_manager/index.html b/addons/Core/layout_manager/index.html index ffd0175..d576ca2 100644 --- a/addons/Core/layout_manager/index.html +++ b/addons/Core/layout_manager/index.html @@ -3,10 +3,29 @@ Layout Editor - -
-
-

Sidebars

- -
+
+
+
+
+
+
+
+ + +
+
+ + +
+
+ +
+
+
+ +
+