LCOV - code coverage report
Current view: directory - layout/xul/base/src - nsListBoxLayout.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 97 0 0.0 %
Date: 2012-06-02 Functions: 7 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       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 Communicator client 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) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   David W. Hyatt (hyatt@netscape.com) (Original Author)
      24                 :  *   Joe Hewitt (hewitt@netscape.com)
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #include "nsListBoxLayout.h"
      41                 : 
      42                 : #include "nsListBoxBodyFrame.h"
      43                 : #include "nsIFrame.h"
      44                 : #include "nsBox.h"
      45                 : #include "nsBoxLayoutState.h"
      46                 : #include "nsIScrollableFrame.h"
      47                 : #include "nsIReflowCallback.h"
      48                 : #include "nsINameSpaceManager.h"
      49                 : #include "nsGkAtoms.h"
      50                 : #include "nsContentUtils.h"
      51                 : 
      52               0 : nsListBoxLayout::nsListBoxLayout() : nsGridRowGroupLayout()
      53                 : {
      54               0 : }
      55                 : 
      56                 : ////////// nsBoxLayout //////////////
      57                 : 
      58                 : nsSize
      59               0 : nsListBoxLayout::GetPrefSize(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState)
      60                 : {
      61               0 :   nsSize pref = nsGridRowGroupLayout::GetPrefSize(aBox, aBoxLayoutState);
      62                 : 
      63               0 :   nsListBoxBodyFrame* frame = static_cast<nsListBoxBodyFrame*>(aBox);
      64               0 :   if (frame) {
      65               0 :     nscoord rowheight = frame->GetRowHeightAppUnits();
      66               0 :     pref.height = frame->GetRowCount() * rowheight;
      67                 :     // Pad the height.
      68               0 :     nscoord y = frame->GetAvailableHeight();
      69               0 :     if (pref.height > y && y > 0 && rowheight > 0) {
      70               0 :       nscoord m = (pref.height-y)%rowheight;
      71               0 :       nscoord remainder = m == 0 ? 0 : rowheight - m;
      72               0 :       pref.height += remainder;
      73                 :     }
      74               0 :     if (nsContentUtils::HasNonEmptyAttr(frame->GetContent(), kNameSpaceID_None,
      75               0 :                                         nsGkAtoms::sizemode)) {
      76               0 :       nscoord width = frame->ComputeIntrinsicWidth(aBoxLayoutState);
      77               0 :       if (width > pref.width)
      78               0 :         pref.width = width;
      79                 :     }
      80                 :   }
      81                 :   return pref;
      82                 : }
      83                 : 
      84                 : nsSize
      85               0 : nsListBoxLayout::GetMinSize(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState)
      86                 : {
      87               0 :   nsSize minSize = nsGridRowGroupLayout::GetMinSize(aBox, aBoxLayoutState);
      88                 : 
      89               0 :   nsListBoxBodyFrame* frame = static_cast<nsListBoxBodyFrame*>(aBox);
      90               0 :   if (frame) {
      91               0 :     nscoord rowheight = frame->GetRowHeightAppUnits();
      92               0 :     minSize.height = frame->GetRowCount() * rowheight;
      93                 :     // Pad the height.
      94               0 :     nscoord y = frame->GetAvailableHeight();
      95               0 :     if (minSize.height > y && y > 0 && rowheight > 0) {
      96               0 :       nscoord m = (minSize.height-y)%rowheight;
      97               0 :       nscoord remainder = m == 0 ? 0 : rowheight - m;
      98               0 :       minSize.height += remainder;
      99                 :     }
     100               0 :     if (nsContentUtils::HasNonEmptyAttr(frame->GetContent(), kNameSpaceID_None,
     101               0 :                                         nsGkAtoms::sizemode)) {
     102               0 :       nscoord width = frame->ComputeIntrinsicWidth(aBoxLayoutState);
     103               0 :       if (width > minSize.width)
     104               0 :         minSize.width = width;
     105                 :     }
     106                 :   }
     107                 :   return minSize;
     108                 : }
     109                 : 
     110                 : nsSize
     111               0 : nsListBoxLayout::GetMaxSize(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState)
     112                 : {
     113               0 :   nsSize maxSize = nsGridRowGroupLayout::GetMaxSize(aBox, aBoxLayoutState);
     114                 : 
     115               0 :   nsListBoxBodyFrame* frame = static_cast<nsListBoxBodyFrame*>(aBox);
     116               0 :   if (frame) {
     117               0 :     nscoord rowheight = frame->GetRowHeightAppUnits();
     118               0 :     maxSize.height = frame->GetRowCount() * rowheight;
     119                 :     // Pad the height.
     120               0 :     nscoord y = frame->GetAvailableHeight();
     121               0 :     if (maxSize.height > y && y > 0 && rowheight > 0) {
     122               0 :       nscoord m = (maxSize.height-y)%rowheight;
     123               0 :       nscoord remainder = m == 0 ? 0 : rowheight - m;
     124               0 :       maxSize.height += remainder;
     125                 :     }
     126                 :   }
     127                 :   return maxSize;
     128                 : }
     129                 : 
     130                 : NS_IMETHODIMP
     131               0 : nsListBoxLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
     132                 : {
     133               0 :   return LayoutInternal(aBox, aState);
     134                 : }
     135                 : 
     136                 : 
     137                 : /////////// nsListBoxLayout /////////////////////////
     138                 : 
     139                 : /**
     140                 :  * Called to layout our our children. Does no frame construction
     141                 :  */
     142                 : NS_IMETHODIMP
     143               0 : nsListBoxLayout::LayoutInternal(nsIBox* aBox, nsBoxLayoutState& aState)
     144                 : {
     145               0 :   PRInt32 redrawStart = -1;
     146                 : 
     147                 :   // Get the start y position.
     148               0 :   nsListBoxBodyFrame* body = static_cast<nsListBoxBodyFrame*>(aBox);
     149               0 :   if (!body) {
     150               0 :     NS_ERROR("Frame encountered that isn't a listboxbody!");
     151               0 :     return NS_ERROR_FAILURE;
     152                 :   }
     153                 : 
     154               0 :   nsMargin margin;
     155                 : 
     156                 :   // Get our client rect.
     157               0 :   nsRect clientRect;
     158               0 :   aBox->GetClientRect(clientRect);
     159                 : 
     160                 :   // Get the starting y position and the remaining available
     161                 :   // height.
     162               0 :   nscoord availableHeight = body->GetAvailableHeight();
     163               0 :   nscoord yOffset = body->GetYPosition();
     164                 :   
     165               0 :   if (availableHeight <= 0) {
     166               0 :     bool fixed = (body->GetFixedRowSize() != -1);
     167               0 :     if (fixed)
     168               0 :       availableHeight = 10;
     169                 :     else
     170               0 :       return NS_OK;
     171                 :   }
     172                 : 
     173                 :   // run through all our currently created children
     174               0 :   nsIBox* box = body->GetChildBox();
     175                 : 
     176                 :   // if the reason is resize or initial we must relayout.
     177               0 :   nscoord rowHeight = body->GetRowHeightAppUnits();
     178                 : 
     179               0 :   while (box) {
     180                 :     // If this box is dirty or if it has dirty children, we
     181                 :     // call layout on it.
     182               0 :     nsRect childRect(box->GetRect());
     183               0 :     box->GetMargin(margin);
     184                 :     
     185                 :     // relayout if we must or we are dirty or some of our children are dirty
     186                 :     //   or the client area is wider than us
     187                 :     // XXXldb There should probably be a resize check here too!
     188               0 :     if (NS_SUBTREE_DIRTY(box) || childRect.width < clientRect.width) {
     189               0 :       childRect.x = 0;
     190               0 :       childRect.y = yOffset;
     191               0 :       childRect.width = clientRect.width;
     192                 :       
     193               0 :       nsSize size = box->GetPrefSize(aState);
     194               0 :       body->SetRowHeight(size.height);
     195                 :       
     196               0 :       childRect.height = rowHeight;
     197                 : 
     198               0 :       childRect.Deflate(margin);
     199               0 :       box->SetBounds(aState, childRect);
     200               0 :       box->Layout(aState);
     201                 :     } else {
     202                 :       // if the child did not need to be relayed out. Then its easy.
     203                 :       // Place the child by just grabbing its rect and adjusting the y.
     204               0 :       PRInt32 newPos = yOffset+margin.top;
     205                 : 
     206                 :       // are we pushing down or pulling up any rows?
     207                 :       // Then we may have to redraw everything below the moved 
     208                 :       // rows.
     209               0 :       if (redrawStart == -1 && childRect.y != newPos)
     210               0 :         redrawStart = newPos;
     211                 : 
     212               0 :       childRect.y = newPos;
     213               0 :       box->SetBounds(aState, childRect);
     214                 :     }
     215                 : 
     216                 :     // Ok now the available size gets smaller and we move the
     217                 :     // starting position of the next child down some.
     218               0 :     nscoord size = childRect.height + margin.top + margin.bottom;
     219                 : 
     220               0 :     yOffset += size;
     221               0 :     availableHeight -= size;
     222                 :     
     223               0 :     box = box->GetNextBox();
     224                 :   }
     225                 :   
     226                 :   // We have enough available height left to add some more rows
     227                 :   // Since we can't do this during layout, we post a callback
     228                 :   // that will be processed after the reflow completes.
     229               0 :   body->PostReflowCallback();
     230                 :     
     231                 :   // if rows were pushed down or pulled up because some rows were added
     232                 :   // before them then redraw everything under the inserted rows. The inserted
     233                 :   // rows will automatically be redrawn because the were marked dirty on insertion.
     234               0 :   if (redrawStart > -1) {
     235               0 :     nsRect bounds(aBox->GetRect());
     236               0 :     nsRect tempRect(0,redrawStart,bounds.width, bounds.height - redrawStart);
     237               0 :     aBox->Redraw(aState, &tempRect);
     238                 :   }
     239                 : 
     240               0 :   return NS_OK;
     241                 : }
     242                 : 
     243                 : // Creation Routines ///////////////////////////////////////////////////////////////////////
     244                 : 
     245               0 : already_AddRefed<nsBoxLayout> NS_NewListBoxLayout()
     246                 : {
     247               0 :   nsBoxLayout* layout = new nsListBoxLayout();
     248               0 :   NS_IF_ADDREF(layout);
     249               0 :   return layout;
     250                 : } 

Generated by: LCOV version 1.7