Gustavo,

I ran into this a few days ago when I was drawing a variable number of 
rectangles to a view, and found that the spacing was not always exact as one 
would expect. In my case the gist of it was that <[each unit]> in essence was a 
<[spacer + rectangleWidth]>

someViewWidthRequired  = <[spacer + rectangleWidth]> * <[number of units]> + 
<[endSpacer]>

unfortunately <[someViewWidthRequired]> is not always equal to 
<[someViewWidthAvailable]>

to figure out the initial rectangleWidth I used :

    w = (rect.size.width - ((noOfBoxes + 1) * spacerX))/noOfBoxes;

Which if you convert :

    (w * noOfBoxes) +  ((noOfBoxes + 1) * spacerX) = rect.size.width;

    rect.size.width = (w * noOfBoxes) + ((noOfBoxes  * spacerX)  + ( 1  * 
spacerX));

    rect.size.width = (noOfBoxes * w) + (noOfBoxes  * spacerX)  + ( 1  * 
spacerX);

    rect.size.width = (noOfBoxes * (w + spacerX))  + ( 1  * spacerX);

is the same as :

   someViewWidthRequired  = <[spacer + rectangleWidth]> * <[number of units]> + 
<[endSpacer]>

but unfortunately, when resizing the window, more often than not, there was a 
nonZero remainder.

So while looping through to draw the rectangles, for the last one in the inner 
loop I made an adjustment to the last rectangle, which is not noticeable, 
rather than have the last spacer (endSpacer) look bad...

if (this is the last rectangle in the inner loop, adjust its size so the spacer 
looks good)
{ 
w = (rect.size.width - ((noOfBoxes + 1) * spacerX) - (i * w));
}

You are welcome to see how I handled this little dilemma at :

   http://discussions.apple.com/forum.jspa?forumID=728&start=0

   The Topic:
   TUTORIAL: NSView flexible dynamic creation and loading of text and images

   The actual post :
    http://discussions.apple.com/thread.jspa?threadID=2421615&tstart=0

or you can download the project at :

    http://www.journey-of-flight.com

   Topic:
    Cocoa - Flexibility of Working with Views 
    Shows how to create Cocoa - Objective C window views, and how to 
dynamically display text and images... 

Best Regards,

Bill Hernandez
Plano, Texas


This is a piece of the method that handles the drawing :

// 
+---------+---------+---------+---------+---------+---------+---------+---------+
- (void)drawRectDemo:(NSRect)rect
{

 <snip>
     . . . 
     . . . 
 </snip>

 // 
+---------+---------+---------+---------+---------+---------+---------+---------+
 // DEFINE AND INITIALIZE MAIN RECT VARIABLES
 // 
+---------+---------+---------+---------+---------+---------+---------+---------+
 NSUInteger i = 0;              // init the inner loop (column) counter
 NSUInteger j = 0;              // init the outer loop (row) counter
 NSUInteger counter = 1;        // init the counter for the total number of 
items

 NSRect boxRect;                // declare a general purpose rectangle
 CGFloat x, y, w, h;            // declare {origin, size} integer variables

 w = 99;                        // Init with bogus width, real width will be 
calculated below

 w = (rect.size.width - ((noOfBoxes + 1) * spacerX))/noOfBoxes;

 // +---------+---------+---------+---------+
 // [5201] ( BEGIN ) outer loop (rows)
 // +---------+---------+---------+---------+    
 for( j = 0; j < noOfRows; j++)
 {    
   if(useDynamicHeight)
   {
     h = (rect.size.height - (heightUsedByHeader + ((noOfRows + 1) * spacerY)));
     h = (h/noOfRows);
   }
   else
   {
     h = fixedBoxHeight;  // if (useDynamicHeight == NO) {use fixed height}
   }

   // 
+---------+---------+---------+---------+---------+---------+---------+---------+
   // var below is initialized, but not used for now, will possibly be used in 
future
   // 
+---------+---------+---------+---------+---------+---------+---------+---------+
   x = spacerX;

   if(showHeaderBox)
   {
     y = heightUsedByHeader + ((j + 1 ) * spacerY) + (j * h);  // leave (2 * 
spacerY) as fixed value
   }
   else
   {
     // These are both the same equation, but they are here in case 
     // you want to do something different if the header {isShown, isNotShown}

     y = heightUsedByHeader + ((j + 1 ) * spacerY) + (j * h);  // leave (2 * 
spacerY) as fixed value
   }
   // +---------+---------+---------+---------+  
   // [5202] ( BEGIN ) inner loop (columns)
   // +---------+---------+---------+---------+    
   for( i = 0; i < noOfBoxes; i++)
   {
     x = (spacerX * (i + 1)) + (w * i);

     if(adjustLastBoxForNonZeroRemainder)
     {
       if (i == (noOfBoxes - 1))
       {
         /*
          // 
+---------+---------+---------+---------+---------+---------+---------+---------+
          * Originally when I was trying to figure out how to do all this, I 
had used 
          * NSUInteger instead of CGFloat vars for the rectangles, and that 
          * caused an uneven last spacer. 
          * 
          * This solved that problem, and it actually worked very well. 
          * It was after I had figured out this little work-around that I 
realized that 
          * I didn't need this at all, by using CGGloats, Cocoa automatically 
took care 
          * of this self induced problem for me. 
          * 
          * Now that I have (corrected) changed the code :
          * 
          * FROM :
          * 
          * NSUInteger x, y, w, h;        // declare {origin, size} as 
NSUInteger variables
          * boxRect = NSMakeRect(x, y, w, h);
          * 
          * TO :
          * 
          * CGFloat x, y, w, h;          // declare {origin, size} as CGFloat 
variables
          * boxRect = NSMakeRect(x, y, w, h);
          * 
          * The code below provides the solution, to my original bufoonery, and 
  
          * like I said before, it actually was a clever, but un-needed 
solution...
          * 
          * Make an adjustment to the last box, so that the last spacer doesn't 
look bad.
          * if there is a remainder, then adjust the width of the last box by 
one or more pixels,
          * which is less noticeable than having the last spacer be off by one 
or more pixels
          * The maximum possible error (number of pixels) at most, will equal 
dX = (noOfBoxes - 1);
          // 
+---------+---------+---------+---------+---------+---------+---------+---------+
          */ 

         w = (rect.size.width - ((noOfBoxes + 1) * spacerX) - (i * w));
       }      
     }
     boxRect = NSMakeRect(x, y, w, h);
     NSLog(@"[4808] w = %.0f", w);
     // NSDottedFrameRect(boxRect);
     NSBezierPath *bp;
     bp = [NSBezierPath bezierPathWithRect:boxRect];
     if(useGradientBackGround == NO)
     {
       [[NSColor lightGrayColor] set];    // set the pen to gray
     }
     else
     {
       [borderColor set];                // set the pen to borderColor (which 
is a variable)
     }
     [bp stroke];

     // +---------+---------+---------+---------+---------+---------+
     // [5203] ( BEGIN ) THIS IS WHERE YOU LOAD EACH BOX
     // +---------+---------+---------+---------+---------+---------+
     // Instead of the dynamic message below, you could do something
     // totally different. 
     // For example : you could have an array with images, text, etc.
     // You could also hide all the checkboxes, popups, etc...
     // +---------+---------+---------+---------+---------+---------+


 <snip>
     . . . 
     . . . 
 </snip>

     // +---------+---------+---------+---------+---------+---------+
     // [5203] ( _END_ ) THIS IS WHERE YOU LOAD EACH BOX
     // +---------+---------+---------+---------+---------+---------+
   }
   // +---------+---------+---------+---------+
   // [5202] ( _END_ ) inner loop (columns)
   // +---------+---------+---------+---------+    
 }
 // +---------+---------+---------+---------+
 // [5201] ( _END_ ) outer loop (rows)
 // +---------+---------+---------+---------+    
}
// 
+---------+---------+---------+---------+---------+---------+---------+---------+



On May 5, 2010, at 10:18 AM, Gustavo Pizano wrote:

> Hello all.
> 
> I have a split view and inside I have custom views, in one subview Im drawing 
> lines with a NSBezierPath, and when I move the divider I  see sometimes the 
> lines very thin some others no, so I  know this last behavior its because Im 
> drawing in half a pixel.
> 
> I was reading the apple docs about this topic,  and I tried at the beginning 
> of my drawRect method I did as in "Converting Coordinate Values" topic 
> suggest to convert my starting drawing point,  but that din't help. I still 
> see the above behavior. 
> I realize then that when I resize the window I  have the same behavior, so 
> what I did was in the windowDelegate  windowWillResize method, I did the 
> following:
> 
>       if((NSInteger)frameSize.width % 2 != 0){
>               frameSize.width += 1.0f;
>               
>       }
>       if((NSInteger)frameSize.height % 2 != 0){
>               frameSize.height += 1.0f;
>       }
> 
> and when I resize the window I don't see hte problem anymore. I tried 
> applying this same to the splitview delegate when resizing, but unfortunately 
> this approach didn't work well, I started getting warnings in the console 
> that the size of the subviews weren't correct and it was being recalculated 
> at the cost of performance.
> 
> So any other idea on what can I do to avoid this behavior? 
> 
> Thanks
> 
> Gustavo
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to