mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 04:57:03 +00:00
FIXED : CPBinder subclasses were keeping references to the source object in a class var.
This could cause memory leaks and was unnecessarily verbose. CPPopUpButton , CPRadio and CPSegmentedControl now use a generic CPBinder method for searching the binder involved when the control is asked to reverse set the binding, typically after a user interaction. Fixes #2199 TODO: prevent user to bind multiple selection bindings when these bindings are exclusive.
This commit is contained in:
+1
-23
@@ -773,7 +773,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
|
||||
|
||||
- (void)_reverseSetBinding
|
||||
{
|
||||
[_CPPopUpButtonSelectionBinder reverseSetValueForObject:self];
|
||||
[_CPPopUpButtonSelectionBinder _reverseSetValueFromExclusiveBinderForObject:self];
|
||||
|
||||
[super _reverseSetBinding];
|
||||
}
|
||||
@@ -929,30 +929,8 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
|
||||
|
||||
@end
|
||||
|
||||
var binderForObject = {};
|
||||
|
||||
@implementation _CPPopUpButtonSelectionBinder : CPBinder
|
||||
{
|
||||
CPString _selectionBinding @accessors;
|
||||
}
|
||||
|
||||
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
|
||||
{
|
||||
self = [super initWithBinding:aBinding name:aName to:aDestination keyPath:aKeyPath options:options from:aSource];
|
||||
|
||||
if (self)
|
||||
{
|
||||
binderForObject[[aSource UID]] = self;
|
||||
_selectionBinding = aName;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (void)reverseSetValueForObject:(id)aSource
|
||||
{
|
||||
var binder = binderForObject[[aSource UID]];
|
||||
[binder reverseSetValueFor:[binder _selectionBinding]];
|
||||
}
|
||||
|
||||
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
|
||||
|
||||
+1
-23
@@ -356,7 +356,7 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
|
||||
[_selectedRadio setState:CPOffState];
|
||||
|
||||
_selectedRadio = aRadio;
|
||||
[_CPRadioGroupSelectionBinder reverseSetValueForObject:self];
|
||||
[_CPRadioGroupSelectionBinder _reverseSetValueFromExclusiveBinderForObject:self];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -409,30 +409,8 @@ var CPRadioGroupRadiosKey = @"CPRadioGroupRadiosKey",
|
||||
|
||||
@end
|
||||
|
||||
var binderForObject = {};
|
||||
|
||||
@implementation _CPRadioGroupSelectionBinder : CPBinder
|
||||
{
|
||||
CPString _selectionBinding @accessors;
|
||||
}
|
||||
|
||||
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
|
||||
{
|
||||
self = [super initWithBinding:aBinding name:aName to:aDestination keyPath:aKeyPath options:options from:aSource];
|
||||
|
||||
if (self)
|
||||
{
|
||||
binderForObject[[aSource UID]] = self;
|
||||
_selectionBinding = aName;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (void)reverseSetValueForObject:(id)aSource
|
||||
{
|
||||
var binder = binderForObject[[aSource UID]];
|
||||
[binder reverseSetValueFor:[binder _selectionBinding]];
|
||||
}
|
||||
|
||||
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
|
||||
|
||||
+13
-25
@@ -49,6 +49,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
|
||||
unsigned _trackingSegment;
|
||||
BOOL _trackingHighlighted;
|
||||
BOOL _hasBinding;
|
||||
}
|
||||
|
||||
+ (CPString)defaultThemeClass
|
||||
@@ -107,14 +108,22 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
|
||||
{
|
||||
if ([[self class] _isSelectionBinding:aBinding] && _trackingMode !== CPSegmentSwitchTrackingSelectOne)
|
||||
{
|
||||
CPLog.warn("Binding " + aBinding + " needs CPSegmentSwitchTrackingSelectOne tracking mode");
|
||||
else
|
||||
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
|
||||
return;
|
||||
}
|
||||
|
||||
if (_hasBinding)
|
||||
[_CPSegmentedControlBinder unbindAllForObject:self];
|
||||
|
||||
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
|
||||
|
||||
_hasBinding = YES;
|
||||
}
|
||||
|
||||
- (void)_reverseSetBinding
|
||||
{
|
||||
[_CPSegmentedControlBinder reverseSetValueForObject:self];
|
||||
[_CPSegmentedControlBinder _reverseSetValueFromExclusiveBinderForObject:self];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -948,31 +957,10 @@ var CPSegmentedControlSegmentsKey = "CPSegmentedControlSegmentsKey",
|
||||
|
||||
@end
|
||||
|
||||
var CPSegmentedControlBindersMap = {},
|
||||
CPSegmentedControlNoSelectionPlaceholder = "CPSegmentedControlNoSelectionPlaceholder";
|
||||
var CPSegmentedControlNoSelectionPlaceholder = "CPSegmentedControlNoSelectionPlaceholder";
|
||||
|
||||
@implementation _CPSegmentedControlBinder : CPBinder
|
||||
{
|
||||
CPString _selectionBinding @accessors(readonly, getter=selectionBinding);
|
||||
}
|
||||
|
||||
+ (void)reverseSetValueForObject:(id)aSource
|
||||
{
|
||||
var binder = CPSegmentedControlBindersMap[[aSource UID]];
|
||||
[binder reverseSetValueFor:[binder selectionBinding]];
|
||||
}
|
||||
|
||||
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
|
||||
{
|
||||
self = [super initWithBinding:aBinding name:aName to:aDestination keyPath:aKeyPath options:options from:aSource];
|
||||
|
||||
if (self)
|
||||
{
|
||||
CPSegmentedControlBindersMap[[aSource UID]] = self;
|
||||
_selectionBinding = aName;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
* Copyright 2012, Your Company All rights reserved.
|
||||
*/
|
||||
|
||||
CPLogRegister(CPLogConsole)
|
||||
|
||||
@import <Foundation/CPObject.j>
|
||||
|
||||
@implementation AppController : CPObject
|
||||
@@ -30,10 +32,10 @@
|
||||
|
||||
- (id)newObject
|
||||
{
|
||||
var randIndex = FLOOR(RAND()*3),
|
||||
randLabel = ["un", "deux", "trois", nil][FLOOR(RAND()*4)],
|
||||
randTag = FLOOR(RAND()*3);
|
||||
|
||||
var randIndex = FLOOR(RAND() * 3),
|
||||
randLabel = ["Label1", "Label2", "Label3", nil][FLOOR(RAND() * 4)],
|
||||
randTag = FLOOR(RAND() * 3);
|
||||
|
||||
return [CPDictionary dictionaryWithObjectsAndKeys:randIndex, @"index", randLabel, @"label", randTag, @"tag"];
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user