Annotation of chimera/BookmarksToolbar.mm, revision 1.13

1.13    ! macserv     1: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
        !             2: /* ***** BEGIN LICENSE BLOCK *****
        !             3: * Version: NPL 1.1/GPL 2.0/LGPL 2.1
        !             4: *
        !             5: * The contents of this file are subject to the Netscape Public License
        !             6: * Version 1.1 (the "License"); you may not use this file except in
        !             7: * compliance with the License. You may obtain a copy of the License at
        !             8: * http://www.mozilla.org/NPL/
        !             9: *
        !            10: * Software distributed under the License is distributed on an "AS IS" basis,
        !            11: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
        !            12: * for the specific language governing rights and limitations under the
        !            13: * License.
        !            14: *
        !            15: * The Original Code is mozilla.org code.
        !            16: *
        !            17: * The Initial Developer of the Original Code is
        !            18: * Netscape Communications Corporation.
        !            19: * Portions created by the Initial Developer are Copyright (C) 2002
        !            20: * the Initial Developer. All Rights Reserved.
        !            21: *
        !            22: * Contributor(s):
        !            23: *
        !            24: * Alternatively, the contents of this file may be used under the terms of
        !            25: * either the GNU General Public License Version 2 or later (the "GPL"), or
        !            26: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
        !            27: * in which case the provisions of the GPL or the LGPL are applicable instead
        !            28: * of those above. If you wish to allow use of your version of this file only
        !            29: * under the terms of either the GPL or the LGPL, and not to allow others to
        !            30: * use your version of this file under the terms of the NPL, indicate your
        !            31: * decision by deleting the provisions above and replace them with the notice
        !            32: * and other provisions required by the GPL or the LGPL. If you do not delete
        !            33: * the provisions above, a recipient may use your version of this file under
        !            34: * the terms of any one of the NPL, the GPL or the LGPL.
        !            35: *
        !            36: * ***** END LICENSE BLOCK ***** */
1.1       hyatt      37: 
1.2       hyatt      38: #import "BookmarksButton.h"
1.1       hyatt      39: #import "BookmarksToolbar.h"
1.3       hyatt      40: #import "BookmarksService.h"
1.4       hyatt      41: #include "nsIDOMElement.h"
1.1       hyatt      42: 
                     43: @implementation BookmarksToolbar
                     44: 
                     45: - (id)initWithFrame:(NSRect)frame {
1.13    ! macserv    46:     if ( (self = [super initWithFrame:frame]) ) {
        !            47:         mBookmarks = nsnull;
        !            48:         mButtons = [[NSMutableArray alloc] init];
        !            49:     }
        !            50:     return self;
1.3       hyatt      51: }
                     52: 
                     53: -(void)initializeToolbar
                     54: {
                     55:   // Initialization code here.
                     56:   mBookmarks = new BookmarksService(self);
                     57:   mBookmarks->AddObserver();
1.4       hyatt      58:   mBookmarks->EnsureToolbarRoot();
                     59:   [self buildButtonList];
1.3       hyatt      60: }
                     61: 
                     62: -(void) dealloc
                     63: {
1.5       hyatt      64:   [mButtons autorelease];
1.3       hyatt      65:   mBookmarks->RemoveObserver();
                     66:   delete mBookmarks;
                     67:   [super dealloc];
1.1       hyatt      68: }
                     69: 
                     70: - (void)drawRect:(NSRect)aRect {
                     71:   // Fill the background with our background color.
1.8       hyatt      72:   //[[NSColor colorWithCalibratedWhite: 0.98 alpha: 1.0] set];
                     73:   //NSRectFill(aRect);
1.1       hyatt      74: 
                     75:   //printf("The rect is: %f %f %f %f\n", aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height);
                     76:   
                     77:   if (aRect.origin.y + aRect.size.height ==
                     78:       [self bounds].size.height) {
                     79:     // The personal toolbar is 21 pixels tall.  The bottom two pixels
                     80:     // are a separator.
1.5       hyatt      81:     [[NSColor colorWithCalibratedWhite: 0.90 alpha: 1.0] set];
1.10      hyatt      82:     NSRectFill(NSMakeRect(aRect.origin.x, [self bounds].size.height-2, aRect.size.width, [self bounds].size.height));
1.1       hyatt      83:   }
                     84: 
1.8       hyatt      85:   // The buttons will paint themselves. Just call our base class method.
                     86:   [super drawRect: aRect];
1.1       hyatt      87: }
                     88: 
1.4       hyatt      89: -(void)buildButtonList
                     90: {
                     91:   // Build the buttons, and then lay them all out.
                     92:   nsCOMPtr<nsIDOMNode> child;
                     93:   BookmarksService::gToolbarRoot->GetFirstChild(getter_AddRefs(child));
                     94:   while (child) {
                     95:     nsCOMPtr<nsIDOMElement> childElt(do_QueryInterface(child));
                     96:     if (childElt) {
                     97:       BookmarksButton* button = [[[BookmarksButton alloc] initWithFrame: NSMakeRect(2, 1, 100, 17)] autorelease];
                     98:       [button setElement: childElt];
                     99:       [self addSubview: button];
1.5       hyatt     100:       [mButtons addObject: button];
1.4       hyatt     101:     }
                    102: 
                    103:     nsCOMPtr<nsIDOMNode> temp = child;
                    104:     temp->GetNextSibling(getter_AddRefs(child));
                    105:   }
                    106: 
                    107:   [self reflowButtons];
                    108: }
                    109: 
1.7       hyatt     110: -(void)addButton: (nsIDOMElement*)aElt atIndex: (int)aIndex
                    111: {
                    112:   BookmarksButton* button = [[[BookmarksButton alloc] initWithFrame: NSMakeRect(2, 1, 100, 17)] autorelease];
                    113:   [button setElement: aElt];
                    114:   [self addSubview: button];
                    115:   [mButtons insertObject: button atIndex: aIndex];
                    116:   [self reflowButtonsStartingAtIndex: aIndex];
                    117: }
                    118: 
                    119: -(void)removeButton: (nsIDOMElement*)aElt
                    120: {
                    121:   int count = [mButtons count];
                    122:   for (int i = 0; i < count; i++) {
                    123:     BookmarksButton* button = [mButtons objectAtIndex: i];
                    124:     if ([button element] == aElt) {
                    125:       [mButtons removeObjectAtIndex: i];
                    126:       [button removeFromSuperview];
                    127:       if (count > i)
                    128:         [self reflowButtonsStartingAtIndex: i];
                    129:       break;
                    130:     }
                    131:   }
1.8       hyatt     132: 
                    133:   [self setNeedsDisplay: YES];
1.7       hyatt     134: }
                    135: 
1.4       hyatt     136: -(void)reflowButtons
                    137: {
1.7       hyatt     138:   [self reflowButtonsStartingAtIndex: 0];
                    139: }
                    140: 
                    141: -(void)reflowButtonsStartingAtIndex: (int)aIndex
                    142: {
1.11      hyatt     143:   float oldHeight = [self frame].size.height;
                    144:   float computedHeight = 18;
1.5       hyatt     145:   int count = [mButtons count];
1.10      hyatt     146:   float currY = 1.0;
1.9       pinkerto  147:   float prevX = 2.0;
1.7       hyatt     148:   if (aIndex > 0) {
                    149:     BookmarksButton* prevButton = [mButtons objectAtIndex: (aIndex-1)];
                    150:     prevX += [prevButton frame].origin.x + [prevButton frame].size.width;
1.10      hyatt     151:     currY = [prevButton frame].origin.y;
1.7       hyatt     152:   }
                    153:   for (int i = aIndex; i < count; i++) {
1.5       hyatt     154:     BookmarksButton* button = [mButtons objectAtIndex: i];
                    155:     [button sizeToFit];
1.9       pinkerto  156:     float width = [button frame].size.width;
                    157:     float height = [button frame].size.height;
1.5       hyatt     158:     if (width > 150)
                    159:       width = 150;
1.7       hyatt     160:     if (height < 16)
                    161:       height = 16; // Our folder tiff is only 15 pixels for some reason.
1.10      hyatt     162:     [button setFrame: NSMakeRect(prevX, currY, width, height)];
1.7       hyatt     163: 
1.5       hyatt     164:     prevX += [button frame].size.width + 2;
1.8       hyatt     165: 
1.10      hyatt     166:     if ([self bounds].size.width < prevX) {
                    167:       // The previous button didn't fit.  We need to make a new row.
                    168:       currY += 18;
1.11      hyatt     169:       computedHeight += 18;
                    170:       if (computedHeight > oldHeight) {
                    171:         [self setFrame: NSMakeRect([self frame].origin.x, [self frame].origin.y+(oldHeight-computedHeight),
                    172:                                    [self frame].size.width, computedHeight)];
                    173:         [self setNeedsDisplay: YES];
                    174:       }
                    175:       
1.10      hyatt     176:       prevX = 2;
                    177:       [button setFrame: NSMakeRect(prevX, currY, width, height)];
1.11      hyatt     178:       prevX += [button frame].size.width + 2;
1.10      hyatt     179:     }
                    180:     
1.8       hyatt     181:     [button setNeedsDisplay: YES];
1.5       hyatt     182:   }
1.10      hyatt     183: 
1.11      hyatt     184:   float currentHeight = [self frame].size.height;
                    185:   if (computedHeight != currentHeight) {
                    186:     [self setFrame: NSMakeRect([self frame].origin.x, [self frame].origin.y + (currentHeight - computedHeight),
                    187:                                [self frame].size.width, computedHeight)];
                    188:     [self setNeedsDisplay: YES];
                    189:   }
                    190:   
                    191:   float sizeChange = computedHeight - oldHeight;
1.10      hyatt     192:   if (sizeChange != 0) {
                    193:     // We need to adjust the content area.
                    194:     NSView* view = [[[self window] windowController] getTabBrowser];
                    195:     [view setFrame: NSMakeRect([view frame].origin.x, [view frame].origin.y,
                    196:                                [view frame].size.width, [view frame].size.height - sizeChange)];
                    197:   }
                    198: }
                    199: 
                    200: -(BOOL)isFlipped
                    201: {
                    202:   return YES; // Use flipped coords, so we can layout out from top row to bottom row.
1.4       hyatt     203: }
1.10      hyatt     204: 
                    205: -(void)setFrame:(NSRect)aRect
                    206: {
                    207:   NSRect oldFrame = [self frame];
                    208:   [super setFrame:aRect];
                    209: 
1.11      hyatt     210:   if (oldFrame.size.width == aRect.size.width)
                    211:     return;
                    212: 
                    213:   int count = [mButtons count];
                    214:   if (count <= 2)
                    215:     return; // We have too few buttons to care.
1.10      hyatt     216:   
1.11      hyatt     217:   // Do some optimizations when we have only one row.
                    218:   if (aRect.size.height < 25) // We have only one row.
                    219:   {
                    220:     if (oldFrame.size.width < aRect.size.width)
                    221:       // We got bigger.  If we already only have one row, just bail.
                    222:       // This will optimize for a common resizing case.
                    223:       return;
                    224:     else {
                    225:       // We got smaller.  Just go to the last button and see if it is outside
                    226:       // our bounds.
                    227:       BookmarksButton* button = [mButtons objectAtIndex:(count-1)];
                    228:       if ([button frame].origin.x + [button frame].size.width >
                    229:           [self bounds].size.width - 2) {
                    230:         // The button doesn't fit any more.  Reflow starting at this index.
                    231:         [self reflowButtonsStartingAtIndex:(count-1)];
                    232:       }
                    233:     }
                    234:   }
                    235:   else {
                    236:     // See if we got bigger or smaller.  We could gain or lose a row.
                    237:     [self reflowButtons];
                    238:   }
1.10      hyatt     239: }
                    240: 
1.1       hyatt     241: @end

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>