Commit 5474c9b4 authored by timothy@apple.com's avatar timothy@apple.com

Improve WebInspector.TimelineOverview by not putting WebInspector.TimelineRuler in a scroll area.

https://bugs.webkit.org/show_bug.cgi?id=127145

Reviewed by Joseph Pecoraro.

* UserInterface/TimelineOverview.css:
(.timeline-overview > .scroll-container):
(.timeline-overview > .timeline-ruler):
(.timeline-overview > .scroll-container > .scroll-width-sizer):
* UserInterface/TimelineOverview.js:
(WebInspector.TimelineOverview):
(WebInspector.TimelineOverview.prototype.get startTime):
(WebInspector.TimelineOverview.prototype.set startTime):
(WebInspector.TimelineOverview.prototype.get secondsPerPixel):
(WebInspector.TimelineOverview.prototype.set secondsPerPixel):
(WebInspector.TimelineOverview.prototype.get scrollStartTime):
(WebInspector.TimelineOverview.prototype.set scrollStartTime):
(WebInspector.TimelineOverview.prototype.get visibleDuration):
(WebInspector.TimelineOverview.prototype.revealMarker):
(WebInspector.TimelineOverview.prototype.updateLayout):
(WebInspector.TimelineOverview.prototype._handleScrollEvent):
(WebInspector.TimelineOverview.prototype._handleWheelEvent):
* UserInterface/TimelineRuler.js:
(WebInspector.TimelineRuler.MinimumSelectionTimeRange): Reduce to 10ms now that super zoom has no performance impact.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@162417 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e6e3f133
2014-01-16 Timothy Hatcher <timothy@apple.com>
Improve WebInspector.TimelineOverview by not putting WebInspector.TimelineRuler in a scroll area.
https://bugs.webkit.org/show_bug.cgi?id=127145
Reviewed by Joseph Pecoraro.
* UserInterface/TimelineOverview.css:
(.timeline-overview > .scroll-container):
(.timeline-overview > .timeline-ruler):
(.timeline-overview > .scroll-container > .scroll-width-sizer):
* UserInterface/TimelineOverview.js:
(WebInspector.TimelineOverview):
(WebInspector.TimelineOverview.prototype.get startTime):
(WebInspector.TimelineOverview.prototype.set startTime):
(WebInspector.TimelineOverview.prototype.get secondsPerPixel):
(WebInspector.TimelineOverview.prototype.set secondsPerPixel):
(WebInspector.TimelineOverview.prototype.get scrollStartTime):
(WebInspector.TimelineOverview.prototype.set scrollStartTime):
(WebInspector.TimelineOverview.prototype.get visibleDuration):
(WebInspector.TimelineOverview.prototype.revealMarker):
(WebInspector.TimelineOverview.prototype.updateLayout):
(WebInspector.TimelineOverview.prototype._handleScrollEvent):
(WebInspector.TimelineOverview.prototype._handleWheelEvent):
* UserInterface/TimelineRuler.js:
(WebInspector.TimelineRuler.MinimumSelectionTimeRange): Reduce to 10ms now that super zoom has no performance impact.
2014-01-15 Timothy Hatcher <timothy@apple.com>
Implement the discrete Script and Layout timeline views.
......
......@@ -261,12 +261,12 @@ WebInspector.TimelineContentView.prototype = {
this._currentTimeMarker.time = currentTime;
this._currentTimelineView.currentTime = currentTime;
this._timelineOverview.revealMarker(this._currentTimeMarker);
// Force a layout now since we are already in an animation frame and don't need to delay it until the next.
this._timelineOverview.updateLayoutIfNeeded();
this._currentTimelineView.updateLayoutIfNeeded();
this._timelineOverview.revealMarker(this._currentTimeMarker);
// Only stop updating if the current time is greater than the end time.
if (!this._updating && currentTime >= endTime) {
this._lastUpdateTimestamp = NaN;
......
......@@ -25,19 +25,36 @@
.timeline-overview > .scroll-container {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
height: 16px;
overflow-x: auto;
overflow-y: hidden;
opacity: 0;
}
.timeline-overview:hover > .scroll-container {
opacity: 0.75;
}
.timeline-overview > .scroll-container > .timeline-ruler {
.timeline-overview > .scroll-container:hover {
opacity: 1;
}
.timeline-overview > .timeline-ruler {
position: absolute;
top: 0;
left: 0;
bottom: 0;
min-width: 100%;
overflow: hidden;
right: 0;
}
.timeline-overview > .scroll-container > .scroll-width-sizer {
position: absolute;
top: 0;
left: 0;
height: 1px;
visibility: hidden;
pointer-events: none;
}
......@@ -29,28 +29,35 @@ WebInspector.TimelineOverview = function()
this._element = document.createElement("div");
this._element.className = WebInspector.TimelineOverview.StyleClassName;
this._element.addEventListener("wheel", this._handleWheelEvent.bind(this));
this._scrollContainer = document.createElement("div");
this._scrollContainer.className = WebInspector.TimelineOverview.ScrollContainerStyleClassName;
this._element.appendChild(this._scrollContainer);
this._timelineRuler = new WebInspector.TimelineRuler;
this._timelineRuler.allowsClippedLabels = true;
this._timelineRuler.allowsTimeRangeSelection = true;
this._timelineRuler.addEventListener(WebInspector.TimelineRuler.Event.TimeRangeSelectionChanged, this._timeRangeSelectionChanged, this);
this._scrollContainer.appendChild(this._timelineRuler.element);
this._element.appendChild(this._timelineRuler.element);
this._scrollContainer = document.createElement("div");
this._scrollContainer.className = WebInspector.TimelineOverview.ScrollContainerStyleClassName;
this._scrollContainer.addEventListener("scroll", this._handleScrollEvent.bind(this));
this._element.appendChild(this._scrollContainer);
this._scrollWidthSizer = document.createElement("div");
this._scrollWidthSizer.className = WebInspector.TimelineOverview.ScrollWidthSizerStyleClassName;
this._scrollContainer.appendChild(this._scrollWidthSizer);
this._startTime = 0;
this._endTime = 0;
this._secondsPerPixel = 0.0025;
this._scrollStartTime = 0;
this.startTime = 0;
this.secondsPerPixel = 0.0025;
this.selectionStartTime = 0;
this.selectionDuration = 3;
};
WebInspector.TimelineOverview.StyleClassName = "timeline-overview";
WebInspector.TimelineOverview.ScrollContainerStyleClassName = "scroll-container";
WebInspector.TimelineOverview.ScrollWidthSizerStyleClassName = "scroll-width-sizer";
WebInspector.TimelineOverview.MinimumSecondsPerPixel = 0.001;
WebInspector.TimelineOverview.ScrollDeltaDenominator = 500;
......@@ -71,31 +78,32 @@ WebInspector.TimelineOverview.prototype = {
get startTime()
{
return this._timelineRuler.startTime;
return this._startTime;
},
set startTime(x)
{
if (this._timelineRuler.startTime === x)
if (this._startTime === x)
return;
this._timelineRuler.zeroTime = x;
this._timelineRuler.startTime = x;
this._startTime = x;
this._needsLayout();
},
get secondsPerPixel()
{
return this._timelineRuler.secondsPerPixel;
return this._secondsPerPixel;
},
set secondsPerPixel(x)
{
if (this._timelineRuler.secondsPerPixel === x)
x = Math.max(WebInspector.TimelineOverview.MinimumSecondsPerPixel, x);
if (this._secondsPerPixel === x)
return;
this._timelineRuler.secondsPerPixel = Math.max(WebInspector.TimelineOverview.MinimumSecondsPerPixel, x);
this._secondsPerPixel = x;
this._needsLayout();
},
......@@ -115,6 +123,26 @@ WebInspector.TimelineOverview.prototype = {
this._needsLayout();
},
get scrollStartTime()
{
return this._scrollStartTime;
},
set scrollStartTime(x)
{
if (this._scrollStartTime === x)
return;
this._scrollStartTime = x || 0;
this._needsLayout();
},
get visibleDuration()
{
return this._scrollContainer.offsetWidth * this._secondsPerPixel;
},
get selectionStartTime()
{
return this._timelineRuler.selectionStartTime;
......@@ -147,10 +175,7 @@ WebInspector.TimelineOverview.prototype = {
revealMarker: function(marker)
{
var markerElement = this._timelineRuler.elementForMarker(marker);
if (!markerElement)
return;
markerElement.scrollIntoViewIfNeeded(true);
this.scrollStartTime = marker.time - (this.visibleDuration / 2);
},
updateLayout: function()
......@@ -161,13 +186,25 @@ WebInspector.TimelineOverview.prototype = {
}
// Calculate the required width based on the duration and seconds per pixel.
var duration = this.endTime - this.startTime;
var newWidth = Math.ceil(duration / this.secondsPerPixel);
var duration = this._endTime - this._startTime;
var newWidth = Math.ceil(duration / this._secondsPerPixel);
// Update all relevant elements to the new required width.
this._updateElementWidth(this._timelineRuler.element, newWidth);
this._updateElementWidth(this._scrollWidthSizer, newWidth);
// Clamp the scroll start time to match what the scroll bar would allow.
var scrollStartTime = Math.min(this._scrollStartTime, this._endTime - this.visibleDuration);
scrollStartTime = Math.max(this._startTime, scrollStartTime);
this._timelineRuler.zeroTime = this._startTime;
this._timelineRuler.startTime = scrollStartTime;
this._timelineRuler.secondsPerPixel = this._secondsPerPixel;
if (!this._dontUpdateScrollLeft) {
this._ignoreNextScrollEvent = true;
this._scrollContainer.scrollLeft = Math.ceil((scrollStartTime - this._startTime) / this._secondsPerPixel);
}
// Update the time ruler layout now that its width has changed.
this._timelineRuler.updateLayout();
},
......@@ -196,26 +233,50 @@ WebInspector.TimelineOverview.prototype = {
this._scheduledLayoutUpdateIdentifier = requestAnimationFrame(this.updateLayout.bind(this));
},
_handleScrollEvent: function(event)
{
if (this._ignoreNextScrollEvent) {
delete this._ignoreNextScrollEvent;
return;
}
this._dontUpdateScrollLeft = true;
var scrollOffset = this._scrollContainer.scrollLeft;
this.scrollStartTime = this._startTime + (scrollOffset * this._secondsPerPixel);
// Force layout so we can update with the scroll position synchronously.
this.updateLayoutIfNeeded();
delete this._dontUpdateScrollLeft;
},
_handleWheelEvent: function(event)
{
// Ignore cloned events that come our way, we already handled the original.
if (event.__cloned)
return;
// Require twice the vertical delta to overcome horizontal scrolling. This prevents most
// cases of inadvertent zooming for slightly diagonal scrolls.
if (Math.abs(event.deltaX) >= Math.abs(event.deltaY) * 0.5)
if (Math.abs(event.deltaX) >= Math.abs(event.deltaY) * 0.5) {
// Clone the event to dispatch it on the scroll container. Mark it as cloned so we don't get into a loop.
var newWheelEvent = new event.constructor(event.type, event);
newWheelEvent.__cloned = true;
this._scrollContainer.dispatchEvent(newWheelEvent);
return;
}
// Remember the mouse position in time.
var mouseOffset = event.pageX - this._scrollContainer.totalOffsetLeft;
var scrollOffset = this._scrollContainer.scrollLeft;
var mousePositionTime = (scrollOffset + mouseOffset) * this.secondsPerPixel;
var mouseOffset = event.pageX - this._element.totalOffsetLeft;
var mousePositionTime = this._scrollStartTime + (mouseOffset * this._secondsPerPixel);
var deviceDirection = event.webkitDirectionInvertedFromDevice ? 1 : -1;
this.secondsPerPixel += event.deltaY * (this._secondsPerPixel / WebInspector.TimelineOverview.ScrollDeltaDenominator) * deviceDirection;
// Force layout so we can update the scroll position synchronously.
this.updateLayoutIfNeeded();
// Center the zoom around the mouse based on the remembered mouse position time.
this._scrollContainer.scrollLeft = Math.max(0, Math.round((mousePositionTime / this.secondsPerPixel) - mouseOffset));
this.scrollStartTime = mousePositionTime - (mouseOffset * this._secondsPerPixel);
event.preventDefault();
event.stopPropagation();
......
......@@ -68,7 +68,7 @@ WebInspector.TimelineRuler.SelectionDragElementStyleClassName = "selection-drag"
WebInspector.TimelineRuler.SelectionHandleElementStyleClassName = "selection-handle";
WebInspector.TimelineRuler.LeftSelectionElementStyleClassName = "left";
WebInspector.TimelineRuler.RightSelectionElementStyleClassName = "right";
WebInspector.TimelineRuler.MinimumSelectionTimeRange = 0.1;
WebInspector.TimelineRuler.MinimumSelectionTimeRange = 0.01;
WebInspector.TimelineRuler.Event = {
TimeRangeSelectionChanged: "time-ruler-time-range-selection-changed"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment