discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: SMDoubleSlider usability on GNUstep


From: Fred Kiefer
Subject: Re: SMDoubleSlider usability on GNUstep
Date: Mon, 26 Feb 2018 23:42:11 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0

As usual it turns out that things are slightly more complicated. There
is a tiny problem with David's test code, he did set "t" as its own
object value instead of using the proxy there. When correcting this I
noticed that the value from the proxy never gets used and extended the
test code slightly and finally testing with different subclasses of
NSCell, not just NSActionCell. They behave violently different. For
NSCell and NSActionCell floatValue and doubleValue always return 0.0
even when setting this value explicitly. NSSliderCell and
NSTextFieldCell behave different, but also not the same way. Looks like
we will need to investigate further and most likely will need to move
the actual value handling code down into the specific NSCell subclasses.
This sounds very ugly to me.

Fred


Am 20.02.2018 um 15:55 schrieb David Chisnall:
> On 20 Feb 2018, at 14:30, Yavor Doganov <yavor@gnu.org> wrote:
>>
>> I think this condition is always false.  _cell.has_valid_object_value
>> is NO and _object_value is nil.  So it jumps to NSCell.m:269 and
>> SMDoubleSliderCell's -stringValue is called which calls -stringHiValue
>> which in turn calls -doubleHiValue and from there the infinite
>> recursion is in place.
>>
>> At least this is what I observe in the debugger.
> 
> Ah, that makes sense - I’d missed that in the trace.  So now the question is 
> what happens when you call -doubleValue on an NSCell in Cocoa when it has a 
> string value?  Here’s a little test program that finds out:
> 
> #import <Cocoa/Cocoa.h>
> 
> @interface Proxy : NSProxy
> {
>       @public
>       id obj;
> }
> @end
> 
> @implementation Proxy
> - (BOOL)respondsToSelector: (SEL)aSelector
> {
>       return [obj respondsToSelector: aSelector];
> }
> - (NSMethodSignature*)methodSignatureForSelector: (SEL)aSelector
> {
>       return [obj methodSignatureForSelector: aSelector];
> }
> - (void)forwardInvocation: (NSInvocation*)anInvocation
> {
>       NSLog(@"%@ set to proxy", anInvocation);
>       [anInvocation invokeWithTarget: obj];
> }
> @end
> 
> @interface Test : NSActionCell @end
> @implementation Test
> - (float)floatValue
> {
>       NSLog(@"-floatValue called\n");
>       return [super floatValue];
> }
> - (NSString*)stringValue
> {
>       NSLog(@"-stringValue called\n");
>       return [super stringValue];
> }
> @end
> 
> int main(void)
> {
>       @autoreleasepool
>       {
>               Test *t = [Test new];
>               Proxy *p = [Proxy alloc];
>               p->obj = @"0.23";
>               [t setObjectValue: t];
>               NSLog(@"Querying");
>               NSLog(@"%f", [t floatValue]);
>       }
> }
> 
> The output is:
> 
> 2018-02-20 14:46:39.917 a.out[85231:11731363] Querying
> 2018-02-20 14:46:39.917 a.out[85231:11731363] -floatValue called
> 2018-02-20 14:46:39.917 a.out[85231:11731363] 0.000000
> 
> 
> So, from this we learn that Cocoa’s NSCell implementation doesn’t call any 
> methods on either itself or the object to find the floating point value.  
> This is a bit odd, but at the very least we should fix GNUstep’s NSCell to 
> query the object and not itself to find the string value.  The correct fix is 
> probably:
> 
> - (float) floatValue
> {
>   if (_cell.has_valid_object_value == YES)
>   {
>     if ([_object_value respondsToSelector: @selector(floatValue)]))
>     {
>       return [_object_value floatValue];
>     }
>     if ([_object_value respondsToSelector: @selector(stringValue)]))
>     {
>       return [[_object_value stringValue] floatValue];
>     }
>   }
>   return 0;
> }
> 
> And apply similar fixes to the other *Value methods in NSCell.
> 
> You can hack around this brokenness by including the above method in a 
> category on NSCell in your application (though please remember to remove it 
> once GNUstep is fixed!).
> 
> David



reply via email to

[Prev in Thread] Current Thread [Next in Thread]