CPScrollView documentVisibleRect bug or feature ?

45 views
Skip to first unread message

Didier Korthoudt

unread,
May 16, 2015, 3:47:44 AM5/16/15
to objec...@googlegroups.com
Hi all !

I'm coding an org chart class with plenty of fancy features like zoom control, small map view of the org chart, flipping views, and so on. It begins to work and gives something like this :


I'm currently dealing with the blue rectangle you can see in the mini chart. It's supposed to represent the part of the whole org chart the user sees. It should then move when the user scrolls (that's ok) and grow or shrink when the user zooms back and forth (this is where I've a problem).

My problem is that I use CPScrollView documentVisibleRect to determine the position and size of my little blue rectangle. I've finally found that documentVisibleRect does not provide me with the expected value (well, expected in my mind, of course).

Here is a sample AppController.j code to illustrate the "problem" :

/*

 * AppController.j

 * BugOrFeature

 *

 * Created by You on May 16, 2015.

 * Copyright 2015, Your Company All rights reserved.

 */


@import <Foundation/Foundation.j>

@import <AppKit/AppKit.j>



@implementation AppController : CPObject

{

    @outlet CPWindow    theWindow;

}


- (void)applicationDidFinishLaunching:(CPNotification)aNotification

{

    // This is called when the application is done loading.

}


- (void)awakeFromCib

{

    // This is called when the cib is done loading.

    // You can implement this method on any object instantiated from a Cib.

    // It's a useful hook for setting up current UI values, and other things.


    // In this case, we want the window from Cib to become our full browser window

    [theWindow setFullPlatformWindow:YES];

    

    var windowView    = [theWindow contentView];

    var aScrollView   = [[CPScrollView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];

    var aDocumentView = [[CPView alloc]       initWithFrame:CGRectMake(0, 0, 200, 200)];

    var clipView      = [aScrollView contentView];

    

    [aScrollView setDocumentView:aDocumentView];

    

    [windowView addSubview:aScrollView];


    CPLog.trace("scrollView frame    : "+CGStringFromRect([aScrollView frame]));

    CPLog.trace("documentView frame  : "+CGStringFromRect([aDocumentView frame]));

    CPLog.trace("clipView frame      : "+CGStringFromRect([clipView frame]));

    CPLog.trace("documentVisibleRect : "+CGStringFromRect([aScrollView documentVisibleRect]));

    

    var aScale = CGSizeMake(0.5, 0.5);

    

    [aDocumentView setScaleSize:aScale];

    

    CPLog.trace("\n");

    CPLog.trace("scale 0.5");

    CPLog.trace("\n");

    

    CPLog.trace("scrollView frame    : "+CGStringFromRect([aScrollView frame]));

    CPLog.trace("documentView frame  : "+CGStringFromRect([aDocumentView frame]));

    CPLog.trace("clipView frame      : "+CGStringFromRect([clipView frame]));

    CPLog.trace("documentVisibleRect : "+CGStringFromRect([aScrollView documentVisibleRect]));

    

}


@end


If you run this, here is the result :

[Debug] 2015-05-16 09:20:41.154 Cappuccino [trace]: scrollView frame    : {{0, 0}, {100, 100}}
[Debug] 2015-05-16 09:20:41.188 Cappuccino [trace]: documentView frame  : {{0, 0}, {200, 200}}
[Debug] 2015-05-16 09:20:41.189 Cappuccino [trace]: clipView frame      : {{0, 0}, {100, 100}}
[Debug] 2015-05-16 09:20:41.189 Cappuccino [trace]: documentVisibleRect : {{0, 0}, {100, 100}}
[Debug] 2015-05-16 09:20:41.190 Cappuccino [trace]:  
[Debug] 2015-05-16 09:20:41.191 Cappuccino [trace]: scale 0.5 
[Debug] 2015-05-16 09:20:41.191 Cappuccino [trace]:  
[Debug] 2015-05-16 09:20:41.191 Cappuccino [trace]: scrollView frame    : {{0, 0}, {100, 100}} 
[Debug] 2015-05-16 09:20:41.191 Cappuccino [trace]: documentView frame  : {{0, 0}, {200, 200}} 
[Debug] 2015-05-16 09:20:41.191 Cappuccino [trace]: clipView frame      : {{0, 0}, {100, 100}} 
[Debug] 2015-05-16 09:20:41.192 Cappuccino [trace]: documentVisibleRect : {{0, 0}, {50, 50}} 

IMHO, the problem is that, when I apply a 0.5 scale to the document view, the documentVisibleRect is also scaled by 0.5.

I expected that, as this rect represents what portion of the document view is visible, this rect would be 0, 0, 200, 200 (that is scaled by 1/0.5). This would respect what the doc says :

The exposed rectangle of the clip view’s document view, in the document view’s own coordinate system.


Do I miss something somewhere or is this a bug ?

Thank you for your input and have a nice weekend !


Didier.

Didier Korthoudt

unread,
May 16, 2015, 11:41:40 AM5/16/15
to objec...@googlegroups.com
I've found a workaround and compute needed values from various ratios.

But I still think that documentVisibleRect is not correctly implemented...

In CPScrollView :

- (CGRect)documentVisibleRect

{

    return [_contentView documentVisibleRect];

}


In CPClipView :


- (CGRect)documentVisibleRect

{

    return [self convertRect:[self bounds] fromView:_documentView];

}


In CPView :


- (CGRect)convertRect:(CGRect)aRect fromView:(CPView)aView

{

    if (self === aView)

        return aRect;


    return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(aView, self));

}

So the clip view is also "considered" scaled.


Just to explain my point of view : a clip view of 100x100 shows 100x100 pixels of a document view at a 1.0 scale (this is of course OK).


If I apply a 0.5 scale to my document view, the clip view shows 2 times as much pixels so the documentVisibleRect should not be scaled down by 0.5 but scaled up by 2 (1/0.5).


Just my 2¢


Didier.

Didier Korthoudt

unread,
May 16, 2015, 11:44:04 AM5/16/15
to objec...@googlegroups.com
Just to be accurate : the clip view should show 4 times as much pixels (2 times in each direction)...

;-)

Dogild

unread,
May 17, 2015, 1:34:10 PM5/17/15
to objec...@googlegroups.com
Hi Didier,

You are right, there is an issue here.

This is the cocoa result of the same application (only the width are displayed) : 

2015-05-17 10:31:55.428 TestZoom[6532:4078380] scrollView frame    : 100.000000

2015-05-17 10:31:55.428 TestZoom[6532:4078380] documentView frame  : 200.000000

2015-05-17 10:31:55.428 TestZoom[6532:4078380] clipView frame      : 100.000000

2015-05-17 10:31:55.428 TestZoom[6532:4078380] documentVisibleRect : 100.000000

2015-05-17 10:31:55.428 TestZoom[6532:4078380] 

2015-05-17 10:31:55.428 TestZoom[6532:4078380] scale 0.5

2015-05-17 10:31:55.428 TestZoom[6532:4078380] 

2015-05-17 10:31:55.429 TestZoom[6532:4078380] scrollView frame    : 100.000000

2015-05-17 10:31:55.429 TestZoom[6532:4078380] documentView frame  : 200.000000

2015-05-17 10:31:55.429 TestZoom[6532:4078380] clipView frame      : 100.000000

2015-05-17 10:31:55.429 TestZoom[6532:4078380] documentVisibleRect : 200.000000


You can open an issue on github with your example :). Even better you can propose a fix if you know how to fix that ;)


Thanks,

Didier Korthoudt

unread,
May 17, 2015, 2:47:48 PM5/17/15
to objec...@googlegroups.com
Thank you Alexandre ! At least I'm not (too much) mad...

;-)

OK, I'll open an issue right now. I'll also search an acceptable fix.

Didier.

Reply all
Reply to author
Forward
0 new messages