layout/xul/grid/nsGridRowLayout.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/xul/grid/nsGridRowLayout.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,193 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +//
    1.10 +// Eric Vaughan
    1.11 +// Netscape Communications
    1.12 +//
    1.13 +// See documentation in associated header file
    1.14 +//
    1.15 +
    1.16 +#include "nsGridRowLayout.h"
    1.17 +#include "nsBoxLayoutState.h"
    1.18 +#include "nsIScrollableFrame.h"
    1.19 +#include "nsBox.h"
    1.20 +#include "nsStackLayout.h"
    1.21 +#include "nsGrid.h"
    1.22 +
    1.23 +nsGridRowLayout::nsGridRowLayout():nsSprocketLayout()
    1.24 +{
    1.25 +}
    1.26 +
    1.27 +void
    1.28 +nsGridRowLayout::ChildrenInserted(nsIFrame* aBox, nsBoxLayoutState& aState,
    1.29 +                                  nsIFrame* aPrevBox,
    1.30 +                                  const nsFrameList::Slice& aNewChildren)
    1.31 +{
    1.32 +  ChildAddedOrRemoved(aBox, aState);
    1.33 +}
    1.34 +
    1.35 +void
    1.36 +nsGridRowLayout::ChildrenAppended(nsIFrame* aBox, nsBoxLayoutState& aState,
    1.37 +                                  const nsFrameList::Slice& aNewChildren)
    1.38 +{
    1.39 +  ChildAddedOrRemoved(aBox, aState);
    1.40 +}
    1.41 +
    1.42 +void
    1.43 +nsGridRowLayout::ChildrenRemoved(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList)
    1.44 +{
    1.45 +  ChildAddedOrRemoved(aBox, aState);
    1.46 +}
    1.47 +
    1.48 +void
    1.49 +nsGridRowLayout::ChildrenSet(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChildList)
    1.50 +{
    1.51 +  ChildAddedOrRemoved(aBox, aState);
    1.52 +}
    1.53 +
    1.54 +nsIGridPart*
    1.55 +nsGridRowLayout::GetParentGridPart(nsIFrame* aBox, nsIFrame** aParentBox)
    1.56 +{
    1.57 +  // go up and find our parent gridRow. Skip and non gridRow
    1.58 +  // parents.
    1.59 +  *aParentBox = nullptr;
    1.60 +  
    1.61 +  // walk up through any scrollboxes
    1.62 +  aBox = nsGrid::GetScrollBox(aBox);
    1.63 +
    1.64 +  // get the parent
    1.65 +  if (aBox)
    1.66 +    aBox = aBox->GetParentBox();
    1.67 +
    1.68 +  if (aBox)
    1.69 +  {
    1.70 +    nsIGridPart* parentGridRow = nsGrid::GetPartFromBox(aBox);
    1.71 +    if (parentGridRow && parentGridRow->CanContain(this)) {
    1.72 +      *aParentBox = aBox;
    1.73 +      return parentGridRow;
    1.74 +    }
    1.75 +  }
    1.76 +
    1.77 +  return nullptr;
    1.78 +}
    1.79 +
    1.80 +
    1.81 +nsGrid*
    1.82 +nsGridRowLayout::GetGrid(nsIFrame* aBox, int32_t* aIndex, nsGridRowLayout* aRequestor)
    1.83 +{
    1.84 +
    1.85 +   if (aRequestor == nullptr)
    1.86 +   {
    1.87 +      nsIFrame* parentBox; // nsIFrame is implemented by nsIFrame and is not refcounted.
    1.88 +      nsIGridPart* parent = GetParentGridPart(aBox, &parentBox);
    1.89 +      if (parent)
    1.90 +         return parent->GetGrid(parentBox, aIndex, this);
    1.91 +      return nullptr;
    1.92 +   }
    1.93 +
    1.94 +   int32_t index = -1;
    1.95 +   nsIFrame* child = aBox->GetChildBox();
    1.96 +   int32_t count = 0;
    1.97 +   while(child)
    1.98 +   {
    1.99 +     // if there is a scrollframe walk inside it to its child
   1.100 +     nsIFrame* childBox = nsGrid::GetScrolledBox(child);
   1.101 +
   1.102 +     nsBoxLayout* layout = childBox->GetLayoutManager();
   1.103 +     nsIGridPart* gridRow = nsGrid::GetPartFromBox(childBox);
   1.104 +     if (gridRow) 
   1.105 +     {
   1.106 +       if (layout == aRequestor) {
   1.107 +          index = count;
   1.108 +          break;
   1.109 +       }
   1.110 +       count += gridRow->GetRowCount();
   1.111 +     } else 
   1.112 +       count++;
   1.113 +
   1.114 +     child = child->GetNextBox();
   1.115 +   }
   1.116 +
   1.117 +   // if we didn't find ourselves then the tree isn't properly formed yet
   1.118 +   // this could happen during initial construction so lets just
   1.119 +   // fail.
   1.120 +   if (index == -1) {
   1.121 +     *aIndex = -1;
   1.122 +     return nullptr;
   1.123 +   }
   1.124 +
   1.125 +   (*aIndex) += index;
   1.126 +
   1.127 +   nsIFrame* parentBox; // nsIFrame is implemented by nsIFrame and is not refcounted.
   1.128 +   nsIGridPart* parent = GetParentGridPart(aBox, &parentBox);
   1.129 +   if (parent)
   1.130 +     return parent->GetGrid(parentBox, aIndex, this);
   1.131 +
   1.132 +   return nullptr;
   1.133 +}
   1.134 +
   1.135 +nsMargin
   1.136 +nsGridRowLayout::GetTotalMargin(nsIFrame* aBox, bool aIsHorizontal)
   1.137 +{
   1.138 +  // get our parents margin
   1.139 +  nsMargin margin(0,0,0,0);
   1.140 +  nsIFrame* parent = nullptr;
   1.141 +  nsIGridPart* part = GetParentGridPart(aBox, &parent);
   1.142 +  if (part && parent) {
   1.143 +    // if we are the first or last child walk upward and add margins.
   1.144 +
   1.145 +    // make sure we check for a scrollbox
   1.146 +    aBox = nsGrid::GetScrollBox(aBox);
   1.147 +
   1.148 +    // see if we have a next to see if we are last
   1.149 +    nsIFrame* next = aBox->GetNextBox();
   1.150 +
   1.151 +    // get the parent first child to see if we are first
   1.152 +    nsIFrame* child = parent->GetChildBox();
   1.153 +
   1.154 +    margin = part->GetTotalMargin(parent, aIsHorizontal);
   1.155 +
   1.156 +    // if first or last
   1.157 +    if (child == aBox || next == nullptr) {
   1.158 +
   1.159 +       // if it's not the first child remove the top margin
   1.160 +       // we don't need it.
   1.161 +       if (child != aBox)
   1.162 +       {
   1.163 +          if (aIsHorizontal)
   1.164 +              margin.top = 0;
   1.165 +          else 
   1.166 +              margin.left = 0;
   1.167 +       }
   1.168 +
   1.169 +       // if it's not the last child remove the bottom margin
   1.170 +       // we don't need it.
   1.171 +       if (next != nullptr)
   1.172 +       {
   1.173 +          if (aIsHorizontal)
   1.174 +              margin.bottom = 0;
   1.175 +          else 
   1.176 +              margin.right = 0;
   1.177 +       }
   1.178 +
   1.179 +    }
   1.180 +  }
   1.181 +    
   1.182 +  // add ours to it.
   1.183 +  nsMargin ourMargin;
   1.184 +  aBox->GetMargin(ourMargin);
   1.185 +  margin += ourMargin;
   1.186 +
   1.187 +  return margin;
   1.188 +}
   1.189 +
   1.190 +NS_IMPL_ADDREF_INHERITED(nsGridRowLayout, nsBoxLayout)
   1.191 +NS_IMPL_RELEASE_INHERITED(nsGridRowLayout, nsBoxLayout)
   1.192 +
   1.193 +NS_INTERFACE_MAP_BEGIN(nsGridRowLayout)
   1.194 +  NS_INTERFACE_MAP_ENTRY(nsIGridPart)
   1.195 +  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIGridPart)
   1.196 +NS_INTERFACE_MAP_END_INHERITING(nsBoxLayout)

mercurial