+
+
-
+
-
diff --git a/src/project/SidebarView.js b/src/project/SidebarView.js
index 9ae9b74c4c0..35f8d5fa503 100644
--- a/src/project/SidebarView.js
+++ b/src/project/SidebarView.js
@@ -41,10 +41,8 @@ define(function (require, exports, module) {
Commands = require("command/Commands"),
Strings = require("strings"),
PreferencesManager = require("preferences/PreferencesManager"),
- EditorManager = require("editor/EditorManager"),
- Global = require("utils/Global");
-
- var isSidebarClosed = false;
+ Global = require("utils/Global"),
+ Resizer = require("utils/Resizer");
var PREFERENCES_CLIENT_ID = "com.adobe.brackets.SidebarView",
defaultPrefs = { sidebarWidth: 200, sidebarClosed: false };
@@ -67,68 +65,11 @@ define(function (require, exports, module) {
$projectTitle.attr("title", ProjectManager.getProjectRoot().fullPath);
}
- /**
- * @private
- * Sets sidebar width and resizes editor. Does not change internal sidebar open/closed state.
- * @param {number} width Optional width in pixels. If null or undefined, the default width is used.
- * @param {!boolean} updateMenu Updates "View" menu label to indicate current sidebar state.
- * @param {!boolean} displayTriangle Display selection marker triangle in the active view.
- */
- function _setWidth(width, updateMenu, displayTriangle) {
- // if we specify a width with the handler call, use that. Otherwise use
- // the greater of the current width or 200 (200 is the minimum width we'd snap back to)
-
- var prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_CLIENT_ID, defaultPrefs),
- sidebarWidth = Math.max(prefs.getValue("sidebarWidth"), 10);
-
- width = width || Math.max($sidebar.width(), sidebarWidth);
-
- if (typeof displayTriangle === "boolean") {
- var display = (displayTriangle) ? "block" : "none";
- $sidebar.find(".sidebar-selection-triangle").css("display", display);
- }
-
- if (isSidebarClosed) {
- $sidebarResizer.css("left", 0);
- } else {
- $sidebar.width(width);
- $sidebarResizer.css("left", width - 1);
-
- // the following three lines help resize things when the sidebar shows
- // but ultimately these should go into ProjectManager.js with a "notify"
- // event that we can just call from anywhere instead of hard-coding it.
- // waiting on a ProjectManager refactor to add that.
- $sidebar.find(".sidebar-selection").width(width);
-
- if (width > 10) {
- prefs.setValue("sidebarWidth", width);
- }
- }
-
- if (updateMenu) {
- var text = (isSidebarClosed) ? Strings.CMD_SHOW_SIDEBAR : Strings.CMD_HIDE_SIDEBAR;
- CommandManager.get(Commands.VIEW_HIDE_SIDEBAR).setName(text);
- }
- EditorManager.resizeEditor();
- }
-
/**
* Toggle sidebar visibility.
*/
function toggleSidebar(width) {
- if (isSidebarClosed) {
- $sidebar.show();
- $(exports).triggerHandler("show");
- } else {
- $sidebar.hide();
- $(exports).triggerHandler("hide");
- }
-
- isSidebarClosed = !isSidebarClosed;
-
- var prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_CLIENT_ID, defaultPrefs);
- prefs.setValue("sidebarClosed", isSidebarClosed);
- _setWidth(width, true, !isSidebarClosed);
+ Resizer.toggleVisibility($sidebar);
}
/**
@@ -136,113 +77,52 @@ define(function (require, exports, module) {
* Install sidebar resize handling.
*/
function _initSidebarResizer() {
- var $mainView = $(".main-view"),
- $body = $(document.body),
- prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_CLIENT_ID, defaultPrefs),
- sidebarWidth = prefs.getValue("sidebarWidth"),
- startingSidebarPosition = sidebarWidth,
- animationRequest = null,
- isMouseDown = false;
-
- $sidebarResizer.css("left", sidebarWidth - 1);
+ var prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_CLIENT_ID, defaultPrefs),
+ sidebarWidth = prefs.getValue("sidebarWidth");
- if (prefs.getValue("sidebarClosed")) {
- toggleSidebar(sidebarWidth);
- } else {
- _setWidth(sidebarWidth, true, true);
- }
+ $sidebar.on("panelResizeStart", function (evt, width) {
+ $sidebar.find(".sidebar-selection-triangle").css("display", "none");
+ $sidebar.find(".scroller-shadow").css("display", "none");
+ });
- $sidebarResizer.on("dblclick", function () {
- if ($sidebar.width() < 10) {
- //mousedown is fired first. Sidebar is already toggeled open to at least 10px.
- _setWidth(null, true, true);
- $projectFilesContainer.triggerHandler("scroll");
- $openFilesContainer.triggerHandler("scroll");
- } else {
- toggleSidebar(sidebarWidth);
- }
+ $sidebar.on("panelResizeUpdate", function (evt, width) {
+ $sidebar.find(".sidebar-selection").width(width);
});
- $sidebarResizer.on("mousedown.sidebar", function (e) {
- var startX = e.clientX,
- newWidth = Math.max(e.clientX, 0),
- doResize = true;
-
- isMouseDown = true;
-
- // take away the shadows (for performance reasons during sidebarmovement)
- $sidebar.find(".scroller-shadow").css("display", "none");
-
- $body.toggleClass("resizing");
-
- // check to see if we're currently in hidden mode
- if (isSidebarClosed) {
- toggleSidebar(1);
- }
-
-
- animationRequest = window.webkitRequestAnimationFrame(function doRedraw() {
- // only run this if the mouse is down so we don't constantly loop even
- // after we're done resizing.
- if (!isMouseDown) {
- return;
- }
-
- // if we've gone below 10 pixels on a mouse move, and the
- // sidebar is shrinking, hide the sidebar automatically an
- // unbind the mouse event.
- if ((startX > 10) && (newWidth < 10)) {
- toggleSidebar(startingSidebarPosition);
- $mainView.off("mousemove.sidebar");
-
- // turn off the mouseup event so that it doesn't fire twice and retoggle the
- // resizing class
- $mainView.off("mouseup.sidebar");
- $body.toggleClass("resizing");
- doResize = false;
- startX = 0;
-
- // force isMouseDown so that we don't keep calling requestAnimationFrame
- // this keeps the sidebar from stuttering
- isMouseDown = false;
-
- }
-
- if (doResize) {
- // for right now, displayTriangle is always going to be false for _setWidth
- // because we want to hide it when we move, and _setWidth only gets called
- // on mousemove now.
- _setWidth(newWidth, false, false);
- }
-
- animationRequest = window.webkitRequestAnimationFrame(doRedraw);
- });
-
- $mainView.on("mousemove.sidebar", function (e) {
- newWidth = Math.max(e.clientX, 0);
-
- e.preventDefault();
- });
-
- $mainView.one("mouseup.sidebar", function (e) {
- isMouseDown = false;
-
- // replace shadows and triangle
- $sidebar.find(".sidebar-selection-triangle").css("display", "block");
- $sidebar.find(".scroller-shadow").css("display", "block");
-
- $projectFilesContainer.triggerHandler("scroll");
- $openFilesContainer.triggerHandler("scroll");
- $mainView.off("mousemove.sidebar");
- $body.toggleClass("resizing");
- startingSidebarPosition = $sidebar.width();
- });
+
+ $sidebar.on("panelResizeEnd", function (evt, width) {
+ $sidebar.find(".sidebar-selection").width(width);
+ $sidebar.find(".sidebar-selection-triangle").css("display", "block").css("left", width);
+ $sidebar.find(".scroller-shadow").css("display", "block");
+ $projectFilesContainer.triggerHandler("scroll");
+ $openFilesContainer.triggerHandler("scroll");
- e.preventDefault();
+ prefs.setValue("sidebarWidth", width);
+ });
+
+ $sidebar.on("panelCollapsed", function () {
+ prefs.setValue("sidebarClosed", true);
+ CommandManager.get(Commands.VIEW_HIDE_SIDEBAR).setName(Strings.CMD_SHOW_SIDEBAR);
+ });
+
+ $sidebar.on("panelExpanded", function () {
+ prefs.setValue("sidebarClosed", false);
+ CommandManager.get(Commands.VIEW_HIDE_SIDEBAR).setName(Strings.CMD_HIDE_SIDEBAR);
});
+
+ // Set initial state
+ $sidebar.width(sidebarWidth);
+ if (prefs.getValue("sidebarClosed")) {
+ Resizer.toggleVisibility($sidebar);
+ } else {
+ $sidebar.trigger("resize");
+ }
}
// Initialize items dependent on HTML DOM
AppInit.htmlReady(function () {
+ var prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_CLIENT_ID, defaultPrefs),
+ sidebarWidth = prefs.getValue("sidebarWidth");
+
$sidebar = $("#sidebar");
$sidebarMenuText = $("#menu-view-hide-sidebar span");
$sidebarResizer = $("#sidebar-resizer");
@@ -253,10 +133,11 @@ define(function (require, exports, module) {
// init
WorkingSetView.create($openFilesContainer);
_initSidebarResizer();
+
});
$(ProjectManager).on("projectOpen", _updateProjectTitle);
- CommandManager.register(Strings.CMD_HIDE_SIDEBAR, Commands.VIEW_HIDE_SIDEBAR, toggleSidebar);
+ CommandManager.register(Strings.CMD_HIDE_SIDEBAR, Commands.VIEW_HIDE_SIDEBAR, toggleSidebar);
// Define public API
exports.toggleSidebar = toggleSidebar;
diff --git a/src/styles/brackets.less b/src/styles/brackets.less
index 65f1ef1e09c..1deb4cf774a 100644
--- a/src/styles/brackets.less
+++ b/src/styles/brackets.less
@@ -62,11 +62,11 @@ html, body {
body {
.vbox;
- &.resizing a, &.resizing #projects a, &.resizing .main-view, &.resizing .CodeMirror-lines {
+ &.horz-resizing a, &.horz-resizing #projects a, &.horz-resizing .main-view, &.horz-resizing .CodeMirror-lines, &.horz-resizing .CodeMirror-gutter-text {
cursor: col-resize;
}
- &.vert-resizing a, &.vert-resizing #projects a, &.vert-resizing .main-view, &.vert-resizing .CodeMirror-lines {
+ &.vert-resizing a, &.vert-resizing #projects a, &.vert-resizing .main-view, &.vert-resizing .CodeMirror-lines, &.vert-resizing .CodeMirror-gutter-text {
cursor: row-resize;
}
}
diff --git a/src/utils/Resizer.js b/src/utils/Resizer.js
index c380034d48a..ddd8f42f856 100644
--- a/src/utils/Resizer.js
+++ b/src/utils/Resizer.js
@@ -40,8 +40,10 @@
* while resizing), custom or internal resizes and save the final resized value into local
* storage for example.
*
- * TODO Trigger panelResizeStart and panelResizeUpdate as required. They aren't needed
- * currently.
+ * A resizable element can be collapsed/expanded using the `toggleVisibility` API
+ *
+ * The resizable elements trigger a panelCollapsed and panelExpanded event when the panel toggles
+ * between visible and invisible
*/
define(function (require, exports, module) {
"use strict";
@@ -63,6 +65,18 @@ define(function (require, exports, module) {
var $mainView;
+ /**
+ * Changes the visibility state of a resizable element. The toggle
+ * functionality is added when an element is made resizable.
+ * @param {DOMNode} element Html element to toggle if possible
+ */
+ function toggleVisibility(element) {
+ var toggleFunction = $(element).data("toggleVisibility");
+ if (toggleFunction) {
+ toggleFunction();
+ }
+ }
+
/**
* Adds resizing capabilities to a given html element.
*
@@ -75,13 +89,18 @@ define(function (require, exports, module) {
* - Left ("left") or right ("right") for horizontal resizing
*
* A resizable element triggers the following events while resizing:
+ * - panelResizeStarts: When the resize starts
+ * - panelResizeUpdate: When the resize gets updated
* - panelResizeEnds: When the resize ends
+ * - panelCollapsed: When the panel gets collapsed (or hidden)
+ * - panelExpanded: When the panel gets expanded (or shown)
*
* @param {DOMNode} element Html element which should be made resizable.
* @param {string} direction The direction of the resize action. Must be "horz" or "vert".
* @param {string} position The position of the resizer on the element. Can be "top" or "bottom"
* for vertical resizing and "left" or "right" for horizontal resizing.
- * @param {int} minSize Minimum size (width or height) of the element.
+ * @param {int} minSize Minimum size (width or height) of the element. A value of 0 makes the
+ * panel collapsable on double click on the resizer.
*/
function makeResizable(element, direction, position, minSize) {
@@ -92,20 +111,60 @@ define(function (require, exports, module) {
animationRequest = null,
directionProperty = direction === DIRECTION_HORIZONTAL ? "clientX" : "clientY",
elementSizeFunction = direction === DIRECTION_HORIZONTAL ? $element.width : $element.height,
- contentSizeFunction = null;
-
+ directionIncrement = (position === POSITION_TOP || position === POSITION_LEFT) ? 1 : -1,
+ contentSizeFunction = null,
+ resizerCSSPosition = "";
+
minSize = minSize || 0;
-
+
+ switch (position) {
+ case POSITION_RIGHT:
+ resizerCSSPosition = "left";
+ break;
+ }
+
$element.prepend($resizer);
+ $element.data("toggleVisibility", function () {
+
+ if ($element.is(":visible")) {
+ $element.hide();
+ $resizer.insertBefore($element).css(resizerCSSPosition, 0);
+ $element.trigger("panelCollapsed");
+ } else {
+ $element.show();
+ $element.prepend($resizer);
+ $resizer.css(resizerCSSPosition, elementSizeFunction.apply($element) - elementSizeFunction.apply($resizer) + 1);
+ $element.trigger("panelExpanded");
+ $element.trigger("panelResizeEnd", [elementSizeFunction.apply($element)]);
+ }
+
+ EditorManager.resizeEditor();
+ });
+
+ if (position === POSITION_RIGHT || position === POSITION_BOTTOM) {
+ $element.resize(function () {
+ $resizer.css(resizerCSSPosition, elementSizeFunction.apply($element) - elementSizeFunction.apply($resizer) + 1);
+ });
+ }
+
+ // A value of 0 for minSize implies that the panel is collapsable on doubleclick
+ if (!minSize) {
+ $resizer.on("dblclick", function () {
+ toggleVisibility($element);
+ });
+ }
+
$resizer.on("mousedown", function (e) {
var startPosition = e[directionProperty],
- startSize = elementSizeFunction.apply($element),
+ startSize = $element.is(":visible") ? elementSizeFunction.apply($element) : 0,
newSize = startSize,
baseSize = 0,
doResize = true,
isMouseDown = true;
-
+
+ $element.trigger("panelResizeStart", [elementSizeFunction.apply($element)]);
+
if ($resizableElement !== undefined) {
$element.children().not(".horz-resizer, .vert-resizer, .resizable-content").each(function (index, child) {
if (direction === DIRECTION_HORIZONTAL) {
@@ -129,14 +188,25 @@ define(function (require, exports, module) {
if (doResize) {
// resize the main element to the new size
- elementSizeFunction.apply($element, [newSize]);
- // if there is a content element, its size is the new size
- // minus the size of the non-resizable elements
- if ($resizableElement !== undefined) {
- contentSizeFunction.apply($resizableElement, [newSize - baseSize]);
- }
+ if ($element.is(":visible")) {
+ elementSizeFunction.apply($element, [newSize]);
+
+ // if there is a content element, its size is the new size
+ // minus the size of the non-resizable elements
+ if ($resizableElement !== undefined) {
+ contentSizeFunction.apply($resizableElement, [newSize - baseSize]);
+ }
+ if (newSize < 10) {
+ toggleVisibility($element);
+ }
+ } else if (newSize > 10) {
+ elementSizeFunction.apply($element, [newSize]);
+ toggleVisibility($element);
+ $element.trigger("panelResizeStart", [elementSizeFunction.apply($element)]);
+ }
+
EditorManager.resizeEditor();
}
@@ -146,7 +216,8 @@ define(function (require, exports, module) {
$mainView.on("mousemove", function (e) {
// calculate newSize adding to startSize the difference
// between starting and current position, capped at minSize
- newSize = Math.max(startSize + (startPosition - e[directionProperty]), minSize);
+ newSize = Math.max(startSize + directionIncrement * (startPosition - e[directionProperty]), minSize);
+ $element.trigger("panelResizeUpdate", [newSize]);
e.preventDefault();
});
@@ -155,7 +226,14 @@ define(function (require, exports, module) {
isMouseDown = false;
$mainView.off("mousemove");
$body.toggleClass(direction + "-resizing");
- $element.trigger("panelResizeEnd", [elementSizeFunction.apply($element)]);
+
+ if ($element.is(":visible")) {
+ if (position === POSITION_RIGHT || position === POSITION_BOTTOM) {
+ $resizer.css(resizerCSSPosition, elementSizeFunction.apply($element) - elementSizeFunction.apply($resizer) + 1);
+ }
+
+ $element.trigger("panelResizeEnd", [elementSizeFunction.apply($element)]);
+ }
}
}
@@ -168,12 +246,17 @@ define(function (require, exports, module) {
// Scan DOM for horz-resizable and vert-resizable classes and make them resizable
AppInit.htmlReady(function () {
+ var minSize = DEFAULT_MIN_SIZE;
$mainView = $(".main-view");
$(".vert-resizable").each(function (index, element) {
+ if ($(element).hasClass("collapsable")) {
+ minSize = 0;
+ }
+
if ($(element).hasClass("top-resizer")) {
- makeResizable(element, DIRECTION_VERTICAL, POSITION_TOP, DEFAULT_MIN_SIZE);
+ makeResizable(element, DIRECTION_VERTICAL, POSITION_TOP, minSize);
}
//if ($(element).hasClass("bottom-resizer")) {
@@ -183,15 +266,20 @@ define(function (require, exports, module) {
$(".horz-resizable").each(function (index, element) {
+ if ($(element).hasClass("collapsable")) {
+ minSize = 0;
+ }
+
//if ($(element).hasClass("left-resizer")) {
// makeResizable(element, DIRECTION_HORIZONTAL, POSITION_LEFT, DEFAULT_MIN_SIZE);
//}
- //if ($(element).hasClass("right-resizer")) {
- // makeResizable(element, DIRECTION_HORIZONTAL, POSITION_RIGHT, DEFAULT_MIN_SIZE);
- //}
+ if ($(element).hasClass("right-resizer")) {
+ makeResizable(element, DIRECTION_HORIZONTAL, POSITION_RIGHT, minSize);
+ }
});
});
exports.makeResizable = makeResizable;
+ exports.toggleVisibility = toggleVisibility;
});
\ No newline at end of file