Improve split view delegate error handling.

Fixed: if the split view delegate sent non numeric responses when asked to constrain divider positions, subviews would be resized with corrupt size information, which in turn could lead to infinite loops and redraw errors. These bad results are now handled more gracefully.
This commit is contained in:
Alexander Ljungberg
2011-10-21 15:55:34 +01:00
parent 021f5bb030
commit 68c8d15ed4
2 changed files with 23 additions and 3 deletions
+21 -3
View File
@@ -20,6 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../Foundation/Foundation.h"
@import "CPButtonBar.j"
@import "CPImage.j"
@import "CPView.j"
@@ -603,7 +605,15 @@ var CPSplitViewHorizontalImage = nil,
{
// not sure where this should override other positions?
if ([_delegate respondsToSelector:@selector(splitView:constrainSplitPosition:ofSubviewAt:)])
position = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex];
{
var proposedPosition = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex];
// Silently ignore bad positions which could result from odd delegate responses. We don't want these
// bad results to go into the system and cause havoc with frame sizes as the split view tries to resize
// its subviews.
if (_IS_NUMERIC(proposedPosition))
position = proposedPosition;
}
var proposedMax = [self maxPossiblePositionOfDividerAtIndex:dividerIndex],
proposedMin = [self minPossiblePositionOfDividerAtIndex:dividerIndex],
@@ -611,10 +621,18 @@ var CPSplitViewHorizontalImage = nil,
actualMin = proposedMin;
if ([_delegate respondsToSelector:@selector(splitView:constrainMinCoordinate:ofSubviewAt:)])
actualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
{
var proposedActualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
if (_IS_NUMERIC(proposedActualMin))
actualMin = proposedActualMin;
}
if ([_delegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)])
actualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
{
var proposedActualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
if (_IS_NUMERIC(proposedActualMax))
actualMax = proposedActualMax;
}
var viewA = _subviews[dividerIndex],
realPosition = MAX(MIN(position, actualMax), actualMin);
+2
View File
@@ -0,0 +1,2 @@
// By Christian C. Salvadó, http://stackoverflow.com/questions/18082/validate-numbers-in-javascript-isnumeric/1830844#1830844
#define _IS_NUMERIC(n) (!isNaN(parseFloat(n)) && isFinite(n))