|
|
@@ -1,169 +1,241 @@
|
|
|
|
|
|
-/* Event-rendering methods for the TimeGrid class
|
|
|
+/* Methods for rendering SEGMENTS, pieces of content that live on the view
|
|
|
+ ( this file is no longer just for events )
|
|
|
----------------------------------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
TimeGrid.mixin({
|
|
|
|
|
|
- eventSkeletonEl: null, // has cells with event-containers, which contain absolutely positioned event elements
|
|
|
+ colContainerEls: null, // containers for each column
|
|
|
|
|
|
+ // inner-containers for each column where different types of segs live
|
|
|
+ fgContainerEls: null,
|
|
|
+ bgContainerEls: null,
|
|
|
+ helperContainerEls: null,
|
|
|
+ highlightContainerEls: null,
|
|
|
+ businessContainerEls: null,
|
|
|
|
|
|
- // Renders the given foreground event segments onto the grid
|
|
|
- renderFgSegs: function(segs) {
|
|
|
- segs = this.renderFgSegEls(segs); // returns a subset of the segs. segs that were actually rendered
|
|
|
+ // arrays of different types of displayed segments
|
|
|
+ fgSegs: null,
|
|
|
+ bgSegs: null,
|
|
|
+ helperSegs: null,
|
|
|
+ highlightSegs: null,
|
|
|
+ businessSegs: null,
|
|
|
+
|
|
|
+
|
|
|
+ // Renders the DOM that the view's content will live in
|
|
|
+ renderContentSkeleton: function() {
|
|
|
+ var cellHtml = '';
|
|
|
+ var i;
|
|
|
+ var skeletonEl;
|
|
|
|
|
|
- this.el.append(
|
|
|
- this.eventSkeletonEl = $('<div class="fc-content-skeleton"/>')
|
|
|
- .append(this.renderSegTable(segs))
|
|
|
+ for (i = 0; i < this.colCnt; i++) {
|
|
|
+ cellHtml +=
|
|
|
+ '<td>' +
|
|
|
+ '<div class="fc-content-col">' +
|
|
|
+ '<div class="fc-event-container fc-helper-container"></div>' +
|
|
|
+ '<div class="fc-event-container"></div>' +
|
|
|
+ '<div class="fc-highlight-container"></div>' +
|
|
|
+ '<div class="fc-bgevent-container"></div>' +
|
|
|
+ '<div class="fc-business-container"></div>' +
|
|
|
+ '</div>' +
|
|
|
+ '</td>';
|
|
|
+ }
|
|
|
+
|
|
|
+ skeletonEl = $(
|
|
|
+ '<div class="fc-content-skeleton">' +
|
|
|
+ '<table>' +
|
|
|
+ '<tr>' + cellHtml + '</tr>' +
|
|
|
+ '</table>' +
|
|
|
+ '</div>'
|
|
|
);
|
|
|
|
|
|
- return segs; // return only the segs that were actually rendered
|
|
|
+ this.colContainerEls = skeletonEl.find('.fc-content-col');
|
|
|
+ this.helperContainerEls = skeletonEl.find('.fc-helper-container');
|
|
|
+ this.fgContainerEls = skeletonEl.find('.fc-event-container:not(.fc-helper-container)');
|
|
|
+ this.bgContainerEls = skeletonEl.find('.fc-bgevent-container');
|
|
|
+ this.highlightContainerEls = skeletonEl.find('.fc-highlight-container');
|
|
|
+ this.businessContainerEls = skeletonEl.find('.fc-business-container');
|
|
|
+
|
|
|
+ this.bookendCells(skeletonEl.find('tr')); // TODO: do this on string level
|
|
|
+ this.el.append(skeletonEl);
|
|
|
},
|
|
|
|
|
|
|
|
|
- // Unrenders all currently rendered foreground event segments
|
|
|
- unrenderFgSegs: function(segs) {
|
|
|
- if (this.eventSkeletonEl) {
|
|
|
- this.eventSkeletonEl.remove();
|
|
|
- this.eventSkeletonEl = null;
|
|
|
- }
|
|
|
+ /* Foreground Events
|
|
|
+ ------------------------------------------------------------------------------------------------------------------*/
|
|
|
+
|
|
|
+
|
|
|
+ renderFgSegs: function(segs) {
|
|
|
+ segs = this.renderFgSegsIntoContainers(segs, this.fgContainerEls);
|
|
|
+ this.fgSegs = segs;
|
|
|
+ return segs; // needed for Grid::renderEvents
|
|
|
},
|
|
|
|
|
|
|
|
|
- // Renders and returns the <table> portion of the event-skeleton.
|
|
|
- // Returns an object with properties 'tbodyEl' and 'segs'.
|
|
|
- renderSegTable: function(segs) {
|
|
|
- var tableEl = $('<table><tr/></table>');
|
|
|
- var trEl = tableEl.find('tr');
|
|
|
- var segCols;
|
|
|
+ unrenderFgSegs: function() {
|
|
|
+ this.unrenderNamedSegs('fgSegs');
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ /* Foreground Helper Events
|
|
|
+ ------------------------------------------------------------------------------------------------------------------*/
|
|
|
+
|
|
|
+
|
|
|
+ renderHelperSegs: function(segs, sourceSeg) {
|
|
|
var i, seg;
|
|
|
- var col, colSegs;
|
|
|
- var containerEl;
|
|
|
+ var sourceEl;
|
|
|
|
|
|
- segCols = this.groupSegCols(segs); // group into sub-arrays, and assigns 'col' to each seg
|
|
|
+ segs = this.renderFgSegsIntoContainers(segs, this.helperContainerEls);
|
|
|
|
|
|
- this.computeSegVerticals(segs); // compute and assign top/bottom
|
|
|
+ // Try to make the segment that is in the same row as sourceSeg look the same
|
|
|
+ for (i = 0; i < segs.length; i++) {
|
|
|
+ seg = segs[i];
|
|
|
+ if (sourceSeg && sourceSeg.col === seg.col) {
|
|
|
+ sourceEl = sourceSeg.el;
|
|
|
+ seg.el.css({
|
|
|
+ left: sourceEl.css('left'),
|
|
|
+ right: sourceEl.css('right'),
|
|
|
+ 'margin-left': sourceEl.css('margin-left'),
|
|
|
+ 'margin-right': sourceEl.css('margin-right')
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- for (col = 0; col < segCols.length; col++) { // iterate each column grouping
|
|
|
- colSegs = segCols[col];
|
|
|
- this.placeSlotSegs(colSegs); // compute horizontal coordinates, z-index's, and reorder the array
|
|
|
+ this.helperSegs = segs;
|
|
|
+ },
|
|
|
|
|
|
- containerEl = $('<div class="fc-event-container"/>');
|
|
|
|
|
|
- // assign positioning CSS and insert into container
|
|
|
- for (i = 0; i < colSegs.length; i++) {
|
|
|
- seg = colSegs[i];
|
|
|
- seg.el.css(this.generateSegPositionCss(seg));
|
|
|
+ unrenderHelperSegs: function() {
|
|
|
+ this.unrenderNamedSegs('helperSegs');
|
|
|
+ },
|
|
|
|
|
|
- // if the height is short, add a className for alternate styling
|
|
|
- if (seg.bottom - seg.top < 30) {
|
|
|
- seg.el.addClass('fc-short');
|
|
|
- }
|
|
|
|
|
|
- containerEl.append(seg.el);
|
|
|
- }
|
|
|
+ /* Background Events
|
|
|
+ ------------------------------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
- trEl.append($('<td/>').append(containerEl));
|
|
|
- }
|
|
|
|
|
|
- this.bookendCells(trEl);
|
|
|
+ renderBgSegs: function(segs) {
|
|
|
+ segs = this.renderFillSegEls('bgEvent', segs); // TODO: old fill system
|
|
|
+ this.updateSegVerticals(segs);
|
|
|
+ this.attachSegsByCol(this.groupSegsByCol(segs), this.bgContainerEls);
|
|
|
+ this.bgSegs = segs;
|
|
|
+ return segs; // needed for Grid::renderEvents
|
|
|
+ },
|
|
|
+
|
|
|
|
|
|
- return tableEl;
|
|
|
+ unrenderBgSegs: function() {
|
|
|
+ this.unrenderNamedSegs('bgSegs');
|
|
|
},
|
|
|
|
|
|
|
|
|
- // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
|
|
|
- // NOTE: Also reorders the given array by date!
|
|
|
- placeSlotSegs: function(segs) {
|
|
|
- var levels;
|
|
|
- var level0;
|
|
|
- var i;
|
|
|
+ /* Highlight
|
|
|
+ ------------------------------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
- this.sortEventSegs(segs); // order by certain criteria
|
|
|
- levels = buildSlotSegLevels(segs);
|
|
|
- computeForwardSlotSegs(levels);
|
|
|
|
|
|
- if ((level0 = levels[0])) {
|
|
|
+ renderHighlightSegs: function(segs) {
|
|
|
+ segs = this.renderFillSegEls('highlight', segs); // TODO: old fill system
|
|
|
+ this.updateSegVerticals(segs);
|
|
|
+ this.attachSegsByCol(this.groupSegsByCol(segs), this.highlightContainerEls);
|
|
|
+ this.highlightSegs = segs;
|
|
|
+ },
|
|
|
|
|
|
- for (i = 0; i < level0.length; i++) {
|
|
|
- computeSlotSegPressures(level0[i]);
|
|
|
- }
|
|
|
|
|
|
- for (i = 0; i < level0.length; i++) {
|
|
|
- this.computeSlotSegCoords(level0[i], 0, 0);
|
|
|
- }
|
|
|
- }
|
|
|
+ unrenderHighlightSegs: function() {
|
|
|
+ this.unrenderNamedSegs('highlightSegs');
|
|
|
},
|
|
|
|
|
|
|
|
|
- // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
|
|
|
- // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
|
|
|
- // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
|
|
|
- //
|
|
|
- // The segment might be part of a "series", which means consecutive segments with the same pressure
|
|
|
- // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
|
|
|
- // segments behind this one in the current series, and `seriesBackwardCoord` is the starting
|
|
|
- // coordinate of the first segment in the series.
|
|
|
- computeSlotSegCoords: function(seg, seriesBackwardPressure, seriesBackwardCoord) {
|
|
|
- var forwardSegs = seg.forwardSegs;
|
|
|
+ /* Business Hours
|
|
|
+ ------------------------------------------------------------------------------------------------------------------*/
|
|
|
+
|
|
|
+
|
|
|
+ renderBusinessSegs: function(segs) {
|
|
|
+ segs = this.renderFillSegEls('businessHours', segs); // TODO: old fill system
|
|
|
+ this.updateSegVerticals(segs);
|
|
|
+ this.attachSegsByCol(this.groupSegsByCol(segs), this.businessContainerEls);
|
|
|
+ this.businessSegs = segs;
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ unrenderBusinessSegs: function() {
|
|
|
+ this.unrenderNamedSegs('businessSegs');
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ /* Seg Rendering Utils
|
|
|
+ ------------------------------------------------------------------------------------------------------------------*/
|
|
|
+
|
|
|
+
|
|
|
+ // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col
|
|
|
+ groupSegsByCol: function(segs) {
|
|
|
+ var segsByCol = [];
|
|
|
var i;
|
|
|
|
|
|
- if (seg.forwardCoord === undefined) { // not already computed
|
|
|
+ for (i = 0; i < this.colCnt; i++) {
|
|
|
+ segsByCol.push([]);
|
|
|
+ }
|
|
|
|
|
|
- if (!forwardSegs.length) {
|
|
|
+ for (i = 0; i < segs.length; i++) {
|
|
|
+ segsByCol[segs[i].col].push(segs[i]);
|
|
|
+ }
|
|
|
|
|
|
- // if there are no forward segments, this segment should butt up against the edge
|
|
|
- seg.forwardCoord = 1;
|
|
|
- }
|
|
|
- else {
|
|
|
+ return segsByCol;
|
|
|
+ },
|
|
|
|
|
|
- // sort highest pressure first
|
|
|
- this.sortForwardSlotSegs(forwardSegs);
|
|
|
|
|
|
- // this segment's forwardCoord will be calculated from the backwardCoord of the
|
|
|
- // highest-pressure forward segment.
|
|
|
- this.computeSlotSegCoords(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);
|
|
|
- seg.forwardCoord = forwardSegs[0].backwardCoord;
|
|
|
- }
|
|
|
+ // Given segments grouped by column, insert the segments' elements into a parallel array of container
|
|
|
+ // elements, each living within a column.
|
|
|
+ attachSegsByCol: function(segsByCol, containerEls) {
|
|
|
+ var col;
|
|
|
+ var segs;
|
|
|
+ var i;
|
|
|
|
|
|
- // calculate the backwardCoord from the forwardCoord. consider the series
|
|
|
- seg.backwardCoord = seg.forwardCoord -
|
|
|
- (seg.forwardCoord - seriesBackwardCoord) / // available width for series
|
|
|
- (seriesBackwardPressure + 1); // # of segments in the series
|
|
|
+ for (col = 0; col < this.colCnt; col++) { // iterate each column grouping
|
|
|
+ segs = segsByCol[col];
|
|
|
|
|
|
- // use this segment's coordinates to computed the coordinates of the less-pressurized
|
|
|
- // forward segments
|
|
|
- for (i=0; i<forwardSegs.length; i++) {
|
|
|
- this.computeSlotSegCoords(forwardSegs[i], 0, seg.forwardCoord);
|
|
|
+ for (i = 0; i < segs.length; i++) {
|
|
|
+ containerEls.eq(col).append(segs[i].el);
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
|
|
|
|
|
|
- // Refreshes the CSS top/bottom coordinates for each segment element. Probably after a window resize/zoom.
|
|
|
- // Repositions business hours segs too, so not just for events. Maybe shouldn't be here.
|
|
|
- updateSegVerticals: function() {
|
|
|
- var allSegs = (this.segs || []).concat(this.businessHourSegs || []);
|
|
|
+ // Given the name of a property of `this` object, assumed to be an array of segments,
|
|
|
+ // loops through each segment and removes from DOM. Will null-out the property afterwards.
|
|
|
+ unrenderNamedSegs: function(propName) {
|
|
|
+ var segs = this[propName];
|
|
|
var i;
|
|
|
|
|
|
- this.computeSegVerticals(allSegs);
|
|
|
-
|
|
|
- for (i = 0; i < allSegs.length; i++) {
|
|
|
- allSegs[i].el.css(
|
|
|
- this.generateSegVerticalCss(allSegs[i])
|
|
|
- );
|
|
|
+ if (segs) {
|
|
|
+ for (i = 0; i < segs.length; i++) {
|
|
|
+ segs[i].el.remove();
|
|
|
+ }
|
|
|
+ this[propName] = null;
|
|
|
}
|
|
|
},
|
|
|
|
|
|
|
|
|
- // For each segment in an array, computes and assigns its top and bottom properties
|
|
|
- computeSegVerticals: function(segs) {
|
|
|
- var i, seg;
|
|
|
|
|
|
- for (i = 0; i < segs.length; i++) {
|
|
|
- seg = segs[i];
|
|
|
- seg.top = this.computeDateTop(seg.start, seg.start);
|
|
|
- seg.bottom = this.computeDateTop(seg.end, seg.start);
|
|
|
+ /* Foreground Event Rendering Utils
|
|
|
+ ------------------------------------------------------------------------------------------------------------------*/
|
|
|
+
|
|
|
+
|
|
|
+ // Given an array of foreground segments, render a DOM element for each, computes position,
|
|
|
+ // and attaches to the column inner-container elements.
|
|
|
+ renderFgSegsIntoContainers: function(segs, containerEls) {
|
|
|
+ var segsByCol;
|
|
|
+ var col;
|
|
|
+
|
|
|
+ segs = this.renderFgSegEls(segs); // will call fgSegHtml
|
|
|
+ segsByCol = this.groupSegsByCol(segs);
|
|
|
+
|
|
|
+ for (col = 0; col < this.colCnt; col++) {
|
|
|
+ this.updateFgSegCoords(segsByCol[col]);
|
|
|
}
|
|
|
+
|
|
|
+ this.attachSegsByCol(segsByCol, containerEls);
|
|
|
+
|
|
|
+ return segs;
|
|
|
},
|
|
|
|
|
|
|
|
|
@@ -240,40 +312,39 @@ TimeGrid.mixin({
|
|
|
},
|
|
|
|
|
|
|
|
|
- // Generates an object with CSS properties/values that should be applied to an event segment element.
|
|
|
- // Contains important positioning-related properties that should be applied to any event element, customized or not.
|
|
|
- generateSegPositionCss: function(seg) {
|
|
|
- var shouldOverlap = this.view.opt('slotEventOverlap');
|
|
|
- var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point
|
|
|
- var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point
|
|
|
- var props = this.generateSegVerticalCss(seg); // get top/bottom first
|
|
|
- var left; // amount of space from left edge, a fraction of the total width
|
|
|
- var right; // amount of space from right edge, a fraction of the total width
|
|
|
+ /* Seg Position Utils
|
|
|
+ ------------------------------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
- if (shouldOverlap) {
|
|
|
- // double the width, but don't go beyond the maximum forward coordinate (1.0)
|
|
|
- forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2);
|
|
|
- }
|
|
|
|
|
|
- if (this.isRTL) {
|
|
|
- left = 1 - forwardCoord;
|
|
|
- right = backwardCoord;
|
|
|
- }
|
|
|
- else {
|
|
|
- left = backwardCoord;
|
|
|
- right = 1 - forwardCoord;
|
|
|
- }
|
|
|
+ // Refreshes the CSS top/bottom coordinates for each segment element.
|
|
|
+ // Works when called after initial render, after a window resize/zoom for example.
|
|
|
+ updateSegVerticals: function(segs) {
|
|
|
+ this.computeSegVerticals(segs);
|
|
|
+ this.assignSegVerticals(segs);
|
|
|
+ },
|
|
|
|
|
|
- props.zIndex = seg.level + 1; // convert from 0-base to 1-based
|
|
|
- props.left = left * 100 + '%';
|
|
|
- props.right = right * 100 + '%';
|
|
|
|
|
|
- if (shouldOverlap && seg.forwardPressure) {
|
|
|
- // add padding to the edge so that forward stacked events don't cover the resizer's icon
|
|
|
- props[this.isRTL ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
|
|
|
+ // For each segment in an array, computes and assigns its top and bottom properties
|
|
|
+ computeSegVerticals: function(segs) {
|
|
|
+ var i, seg;
|
|
|
+
|
|
|
+ for (i = 0; i < segs.length; i++) {
|
|
|
+ seg = segs[i];
|
|
|
+ seg.top = this.computeDateTop(seg.start, seg.start);
|
|
|
+ seg.bottom = this.computeDateTop(seg.end, seg.start);
|
|
|
}
|
|
|
+ },
|
|
|
|
|
|
- return props;
|
|
|
+
|
|
|
+ // Given segments that already have their top/bottom properties computed, applies those values to
|
|
|
+ // the segments' elements.
|
|
|
+ assignSegVerticals: function(segs) {
|
|
|
+ var i, seg;
|
|
|
+
|
|
|
+ for (i = 0; i < segs.length; i++) {
|
|
|
+ seg = segs[i];
|
|
|
+ seg.el.css(this.generateSegVerticalCss(seg));
|
|
|
+ }
|
|
|
},
|
|
|
|
|
|
|
|
|
@@ -286,36 +357,155 @@ TimeGrid.mixin({
|
|
|
},
|
|
|
|
|
|
|
|
|
- // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col
|
|
|
- groupSegCols: function(segs) {
|
|
|
- var segCols = [];
|
|
|
+ /* Foreground Event Positioning Utils
|
|
|
+ ------------------------------------------------------------------------------------------------------------------*/
|
|
|
+
|
|
|
+
|
|
|
+ // Given segments that are assumed to all live in the *same column*,
|
|
|
+ // compute their verical/horizontal coordinates and assign to their elements.
|
|
|
+ updateFgSegCoords: function(segs) {
|
|
|
+ this.computeSegVerticals(segs); // horizontals relies on this
|
|
|
+ this.computeFgSegHorizontals(segs); // compute horizontal coordinates, z-index's, and reorder the array
|
|
|
+ this.assignSegVerticals(segs);
|
|
|
+ this.assignFgSegHorizontals(segs);
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
|
|
|
+ // NOTE: Also reorders the given array by date!
|
|
|
+ computeFgSegHorizontals: function(segs) {
|
|
|
+ var levels;
|
|
|
+ var level0;
|
|
|
var i;
|
|
|
|
|
|
- for (i = 0; i < this.colCnt; i++) {
|
|
|
- segCols.push([]);
|
|
|
- }
|
|
|
+ this.sortEventSegs(segs); // order by certain criteria
|
|
|
+ levels = buildSlotSegLevels(segs);
|
|
|
+ computeForwardSlotSegs(levels);
|
|
|
|
|
|
- for (i = 0; i < segs.length; i++) {
|
|
|
- segCols[segs[i].col].push(segs[i]);
|
|
|
+ if ((level0 = levels[0])) {
|
|
|
+
|
|
|
+ for (i = 0; i < level0.length; i++) {
|
|
|
+ computeSlotSegPressures(level0[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < level0.length; i++) {
|
|
|
+ this.computeFgSegForwardBack(level0[i], 0, 0);
|
|
|
+ }
|
|
|
}
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
|
|
|
+ // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
|
|
|
+ // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
|
|
|
+ //
|
|
|
+ // The segment might be part of a "series", which means consecutive segments with the same pressure
|
|
|
+ // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
|
|
|
+ // segments behind this one in the current series, and `seriesBackwardCoord` is the starting
|
|
|
+ // coordinate of the first segment in the series.
|
|
|
+ computeFgSegForwardBack: function(seg, seriesBackwardPressure, seriesBackwardCoord) {
|
|
|
+ var forwardSegs = seg.forwardSegs;
|
|
|
+ var i;
|
|
|
+
|
|
|
+ if (seg.forwardCoord === undefined) { // not already computed
|
|
|
+
|
|
|
+ if (!forwardSegs.length) {
|
|
|
+
|
|
|
+ // if there are no forward segments, this segment should butt up against the edge
|
|
|
+ seg.forwardCoord = 1;
|
|
|
+ }
|
|
|
+ else {
|
|
|
|
|
|
- return segCols;
|
|
|
+ // sort highest pressure first
|
|
|
+ this.sortForwardSegs(forwardSegs);
|
|
|
+
|
|
|
+ // this segment's forwardCoord will be calculated from the backwardCoord of the
|
|
|
+ // highest-pressure forward segment.
|
|
|
+ this.computeFgSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);
|
|
|
+ seg.forwardCoord = forwardSegs[0].backwardCoord;
|
|
|
+ }
|
|
|
+
|
|
|
+ // calculate the backwardCoord from the forwardCoord. consider the series
|
|
|
+ seg.backwardCoord = seg.forwardCoord -
|
|
|
+ (seg.forwardCoord - seriesBackwardCoord) / // available width for series
|
|
|
+ (seriesBackwardPressure + 1); // # of segments in the series
|
|
|
+
|
|
|
+ // use this segment's coordinates to computed the coordinates of the less-pressurized
|
|
|
+ // forward segments
|
|
|
+ for (i=0; i<forwardSegs.length; i++) {
|
|
|
+ this.computeFgSegForwardBack(forwardSegs[i], 0, seg.forwardCoord);
|
|
|
+ }
|
|
|
+ }
|
|
|
},
|
|
|
|
|
|
|
|
|
- sortForwardSlotSegs: function(forwardSegs) {
|
|
|
- forwardSegs.sort(proxy(this, 'compareForwardSlotSegs'));
|
|
|
+ sortForwardSegs: function(forwardSegs) {
|
|
|
+ forwardSegs.sort(proxy(this, 'compareForwardSegs'));
|
|
|
},
|
|
|
|
|
|
|
|
|
// A cmp function for determining which forward segment to rely on more when computing coordinates.
|
|
|
- compareForwardSlotSegs: function(seg1, seg2) {
|
|
|
+ compareForwardSegs: function(seg1, seg2) {
|
|
|
// put higher-pressure first
|
|
|
return seg2.forwardPressure - seg1.forwardPressure ||
|
|
|
// put segments that are closer to initial edge first (and favor ones with no coords yet)
|
|
|
(seg1.backwardCoord || 0) - (seg2.backwardCoord || 0) ||
|
|
|
// do normal sorting...
|
|
|
this.compareEventSegs(seg1, seg2);
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ // Given foreground event segments that have already had their position coordinates computed,
|
|
|
+ // assigns position-related CSS values to their elements.
|
|
|
+ assignFgSegHorizontals: function(segs) {
|
|
|
+ var i, seg;
|
|
|
+
|
|
|
+ for (i = 0; i < segs.length; i++) {
|
|
|
+ seg = segs[i];
|
|
|
+ seg.el.css(this.generateFgSegHorizontalCss(seg));
|
|
|
+
|
|
|
+ // if the height is short, add a className for alternate styling
|
|
|
+ if (seg.bottom - seg.top < 30) {
|
|
|
+ seg.el.addClass('fc-short');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ // Generates an object with CSS properties/values that should be applied to an event segment element.
|
|
|
+ // Contains important positioning-related properties that should be applied to any event element, customized or not.
|
|
|
+ generateFgSegHorizontalCss: function(seg) {
|
|
|
+ var shouldOverlap = this.view.opt('slotEventOverlap');
|
|
|
+ var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point
|
|
|
+ var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point
|
|
|
+ var props = this.generateSegVerticalCss(seg); // get top/bottom first
|
|
|
+ var left; // amount of space from left edge, a fraction of the total width
|
|
|
+ var right; // amount of space from right edge, a fraction of the total width
|
|
|
+
|
|
|
+ if (shouldOverlap) {
|
|
|
+ // double the width, but don't go beyond the maximum forward coordinate (1.0)
|
|
|
+ forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.isRTL) {
|
|
|
+ left = 1 - forwardCoord;
|
|
|
+ right = backwardCoord;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ left = backwardCoord;
|
|
|
+ right = 1 - forwardCoord;
|
|
|
+ }
|
|
|
+
|
|
|
+ props.zIndex = seg.level + 1; // convert from 0-base to 1-based
|
|
|
+ props.left = left * 100 + '%';
|
|
|
+ props.right = right * 100 + '%';
|
|
|
+
|
|
|
+ if (shouldOverlap && seg.forwardPressure) {
|
|
|
+ // add padding to the edge so that forward stacked events don't cover the resizer's icon
|
|
|
+ props[this.isRTL ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
|
|
|
+ }
|
|
|
+
|
|
|
+ return props;
|
|
|
}
|
|
|
|
|
|
});
|