Revision: 29129
          http://sourceforge.net/p/bibdesk/svn/29129
Author:   hofman
Date:     2025-04-18 09:32:25 +0000 (Fri, 18 Apr 2025)
Log Message:
-----------
Calculate iconSize and padding or numberOfColumns and numberOfRows without 
setting them, so we can change them once and change iconSize only when it 
changes, avoiding unnecessary updates

Modified Paths:
--------------
    trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.m

Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.m
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.m      2025-04-17 
16:18:00 UTC (rev 29128)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVFileView.m      2025-04-18 
09:32:25 UTC (rev 29129)
@@ -1214,33 +1214,33 @@
     return ceil( [self _rowHeight] * _numberOfRows + [self _topMargin] + [self 
_bottomMargin] );
 }
 
-- (void)_setPaddingAndIconSizeFromContentWidth:(CGFloat)width {
+- (void)_getIconSize:(NSSize *)iconSize padding:(NSSize *)padding 
fittingContentWidth:(CGFloat)width {
     // calculate the column width, inverting the calculation in _frameWidth
     // make sure fractional widths won't bring back scrollers
     CGFloat colWidth = ( floor(width) - 2 * DEFAULT_MARGIN.width ) / 
_numberOfColumns;
     // guess the iconScale, ignoring the rounding of the variable padding as 
that can't be inverted
     CGFloat iconScale = fmax( MIN_AUTO_ICON_SCALE, ( colWidth - 
DEFAULT_PADDING.width ) / ( DEFAULT_ICON_SIZE.width + PADDING_STRETCH ));
-    _padding = [self _paddingForScale:iconScale];
+    *padding = [self _paddingForScale:iconScale];
     // recalculate exactly based on this padding
-    iconScale = fmax( MIN_AUTO_ICON_SCALE, floor( colWidth - _padding.width ) 
/ DEFAULT_ICON_SIZE.width );
-    _iconSize = NSMakeSize(iconScale * DEFAULT_ICON_SIZE.width, iconScale * 
DEFAULT_ICON_SIZE.height);
+    iconScale = fmax( MIN_AUTO_ICON_SCALE, floor( colWidth - padding->width ) 
/ DEFAULT_ICON_SIZE.width );
+    *iconSize = NSMakeSize(iconScale * DEFAULT_ICON_SIZE.width, iconScale * 
DEFAULT_ICON_SIZE.height);
 }
 
-- (void)_setPaddingAndIconSizeFromContentHeight:(CGFloat)height {
+- (void)_getIconSize:(NSSize *)iconSize padding:(NSSize *)padding 
fittingContentHeight:(CGFloat)height {
     // calculate the row height, inverting the calculation in _frameHeight
     // make sure fractional heights won't bring back scrollers
     CGFloat rowHeight = ( floor(height) - DEFAULT_MARGIN.height ) / 
_numberOfRows;
     // guess the iconScale, ignoring the rounding of the variable padding as 
that can't be inverted
     CGFloat iconScale = fmax( MIN_AUTO_ICON_SCALE, ( rowHeight - 
DEFAULT_PADDING.height - [self _textHeight] ) / ( DEFAULT_ICON_SIZE.height + 
PADDING_STRETCH ) );
-    _padding = [self _paddingForScale:iconScale];
+    *padding = [self _paddingForScale:iconScale];
     // recalculate exactly based on this padding
-    iconScale = fmax( MIN_AUTO_ICON_SCALE, floor( rowHeight - _padding.height 
) / DEFAULT_ICON_SIZE.height );
-    _iconSize = NSMakeSize(iconScale * DEFAULT_ICON_SIZE.width, iconScale * 
DEFAULT_ICON_SIZE.height);
+    iconScale = fmax( MIN_AUTO_ICON_SCALE, floor( rowHeight - padding->height 
) / DEFAULT_ICON_SIZE.height );
+    *iconSize = NSMakeSize(iconScale * DEFAULT_ICON_SIZE.width, iconScale * 
DEFAULT_ICON_SIZE.height);
 }
 
-- (void)_setColumnsAndRowsFromContentWidth:(CGFloat)width {
-    _numberOfColumns = MAX( 1,  (NSInteger)floor( ( width - 2 * 
DEFAULT_MARGIN.width ) / [self _columnWidth] ) );
-    _numberOfRows = ( [self numberOfIcons]  + _numberOfColumns - 1 ) / 
_numberOfColumns;
+- (void)_getColumns:(NSInteger *)numberOfColumns rows:(NSInteger 
*)numberOfRows fittingContentWidth:(CGFloat)width {
+    *numberOfColumns = MAX( 1,  (NSInteger)floor( ( width - 2 * 
DEFAULT_MARGIN.width ) / [self _columnWidth] ) );
+    *numberOfRows = ( [self numberOfIcons]  + *numberOfColumns - 1 ) / 
*numberOfColumns;
 }
 
 static CGFloat _scrollerWidthForScroller(NSScroller *scroller) {
@@ -1284,102 +1284,123 @@
         _numberOfColumns = 1;
         _numberOfRows = [self numberOfIcons];
         
-        [self willChangeValueForKey:@"iconScale"];
+        NSSize iconSize = _iconSize;
+        NSSize padding = _padding;
         
         // if we have an auto-hiding vertical scroller, we may or may not have 
scroll bars, which affects the effective width
         if (autoHidesScrollers && [scrollView hasVerticalScroller]) {
+            // the _frameWidth for the MIN_AUTO_SCALE
             CGFloat minWidth = ceil( [self 
_paddingForScale:MIN_AUTO_ICON_SCALE].width + MIN_AUTO_ICON_SCALE * 
DEFAULT_ICON_SIZE.width + 2 * DEFAULT_MARGIN.width );
             
             // first assume we need a vertical scroller...
             contentSize = 
_contentSizeForScrollViewHavingVerticalScroller(scrollView, minWidth, YES);
-            [self _setPaddingAndIconSizeFromContentWidth:contentSize.width];
+            [self _getIconSize:&iconSize padding:&padding 
fittingContentWidth:contentSize.width];
             
-            if (contentSize.height > [self _frameHeight]) {
+            if (contentSize.height > ceil( (iconSize.height + padding.height) 
* _numberOfRows - DEFAULT_MARGIN.height )) {
                 // we have sufficient height to fit all icons, so recalculate 
without vertical scroller
                 contentSize = 
_contentSizeForScrollViewHavingVerticalScroller(scrollView, minWidth, NO);
-                [self 
_setPaddingAndIconSizeFromContentWidth:contentSize.width];
+                [self _getIconSize:&iconSize padding:&padding 
fittingContentWidth:contentSize.width];
                 
-                if (_numberOfRows > 0 && contentSize.height < [self 
_frameHeight]) {
+                if (_numberOfRows > 0 && contentSize.height < ceil( 
(iconSize.height + padding.height) * _numberOfRows - DEFAULT_MARGIN.height )) {
                     // the height with this wider icons becomes too much, so 
we now recalculate by fitting the height, still without vertical scroller
                     // this should come out in between the previous two 
calculations
-                    [self 
_setPaddingAndIconSizeFromContentHeight:contentSize.height];
+                    [self _getIconSize:&iconSize padding:&padding 
fittingContentHeight:contentSize.height];
                 }
             }
             
         } else {
         
-            [self _setPaddingAndIconSizeFromContentWidth:contentSize.width];
+            [self _getIconSize:&iconSize padding:&padding 
fittingContentWidth:contentSize.width];
             
         }
         
-        [self didChangeValueForKey:@"iconScale"];
+        if (NSEqualSizes(iconSize, _iconSize) == NO) {
+            [self willChangeValueForKey:@"iconScale"];
+            _iconSize = iconSize;
+            [self didChangeValueForKey:@"iconScale"];
 
-        CGLayerRelease(_selectionOverlay);
-        _selectionOverlay = NULL;
-            
+            CGLayerRelease(_selectionOverlay);
+            _selectionOverlay = NULL;
+        }
+        
+        _padding = padding;
+        
     } else if (_fvFlags.displayMode == FVDisplayModeRow) {
         
         _numberOfColumns = [self numberOfIcons];
         _numberOfRows = 1;
         
-        [self willChangeValueForKey:@"iconScale"];
-
+        NSSize iconSize = _iconSize;
+        NSSize padding = _padding;
+        
         // if we have an auto-hiding horizontal scroller, we may or may not 
have scroll bars, which affects the effective height
         if (autoHidesScrollers && [scrollView hasHorizontalScroller]) {
+            // the _frameHeight for the MIN_AUTO_SCALE
             CGFloat minHeight = ceil( [self 
_paddingForScale:MIN_AUTO_ICON_SCALE].height + MIN_AUTO_ICON_SCALE * 
DEFAULT_ICON_SIZE.height + DEFAULT_MARGIN.height );
             
             // first assume we need a horizontal scroller...
             contentSize = 
_contentSizeForScrollViewHavingHorizontalScroller(scrollView, minHeight, YES);
-            [self _setPaddingAndIconSizeFromContentHeight:contentSize.height];
+            [self _getIconSize:&iconSize padding:&padding 
fittingContentHeight:contentSize.height];
             
-            if (contentSize.width > [self _frameWidth]) {
+            if (contentSize.width > ceil( (iconSize.width + padding.width) * 
_numberOfColumns - 2 * DEFAULT_MARGIN.width )) {
                 // we have sufficient width to fit all icons, so recalculate 
without horizontal scroller
                 contentSize = 
_contentSizeForScrollViewHavingHorizontalScroller(scrollView, minHeight, NO);
-                [self 
_setPaddingAndIconSizeFromContentHeight:contentSize.height];
+                [self _getIconSize:&iconSize padding:&padding 
fittingContentHeight:contentSize.height];
                 
-                if (_numberOfColumns > 0 && contentSize.width < [self 
_frameWidth]) {
+                if (_numberOfColumns > 0 && contentSize.width < ceil( 
(iconSize.width + padding.width) * _numberOfColumns - 2 * DEFAULT_MARGIN.width 
)) {
                     // the width with this wider icons becomes too much, so we 
now recalculate by fitting the width, still without horizontal scroller
                     // this should come out in between the previous two 
calculations
-                    [self 
_setPaddingAndIconSizeFromContentWidth:contentSize.width];
+                    [self _getIconSize:&iconSize padding:&padding 
fittingContentWidth:contentSize.width];
                 }
             }
             
         } else {
         
-            [self _setPaddingAndIconSizeFromContentHeight:contentSize.height];
+            [self _getIconSize:&iconSize padding:&padding 
fittingContentHeight:contentSize.height];
             
         }
         
-        [self didChangeValueForKey:@"iconScale"];
+        if (NSEqualSizes(iconSize, _iconSize) == NO) {
+            [self willChangeValueForKey:@"iconScale"];
+            _iconSize = iconSize;
+            [self didChangeValueForKey:@"iconScale"];
+
+            CGLayerRelease(_selectionOverlay);
+            _selectionOverlay = NULL;
+        }
         
-        CGLayerRelease(_selectionOverlay);
-        _selectionOverlay = NULL;
+        padding = _padding;
         
     } else {
         
+        NSInteger numberOfColumns = _numberOfColumns;
+        NSInteger numberOfRows = _numberOfRows;
+        
         _padding = [self _paddingForScale:[self iconScale]];
         
         // if we have an auto-hiding vertical scroller, we may or may not have 
scroll bars, which affects the effective width
         if (autoHidesScrollers && [scrollView hasVerticalScroller]) {
-            // set the number of columns to 1 to calculate the minimal 
required width
-            _numberOfColumns = 1;
-            CGFloat minWidth = [self _frameWidth];
+            // the _frameWidth for a single column
+            CGFloat minWidth = ceil( [self _columnWidth] + 2 * 
DEFAULT_MARGIN.width );
             
             // first assume we don't need a vertical scroller...
             contentSize = 
_contentSizeForScrollViewHavingVerticalScroller(scrollView, minWidth, NO);
-            [self _setColumnsAndRowsFromContentWidth:contentSize.width];
+            [self _getColumns:&numberOfColumns rows:&numberOfRows 
fittingContentWidth:contentSize.width];
             
-            if (contentSize.height < [self _frameHeight]) {
+            if (contentSize.height < ceil( [self _rowHeight] * numberOfRows + 
[self _topMargin] + [self _bottomMargin] )) {
                 // we have insufficient height to fit all icons, so 
recalculate with vertical scroller
                 contentSize = 
_contentSizeForScrollViewHavingVerticalScroller(scrollView, minWidth, YES);
-                [self _setColumnsAndRowsFromContentWidth:contentSize.width];
+                [self _getColumns:&numberOfColumns rows:&numberOfRows 
fittingContentWidth:contentSize.width];
             }
             
         } else {
             
-            [self _setColumnsAndRowsFromContentWidth:contentSize.width];
+            [self _getColumns:&numberOfColumns rows:&numberOfRows 
fittingContentWidth:contentSize.width];
             
         }
+        
+        _numberOfColumns = numberOfColumns;
+        _numberOfRows = numberOfRows;
     }
     
     if (scrollView) {

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
Bibdesk-commit mailing list
Bibdesk-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit

Reply via email to