summaryrefslogtreecommitdiffstats
path: root/layout/xul/nsSprocketLayout.h
blob: e1e7fe377eb6ab16280290fceacf673b5ed8f51b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef nsSprocketLayout_h___
#define nsSprocketLayout_h___

#include "mozilla/Attributes.h"
#include "nsBoxLayout.h"
#include "nsCOMPtr.h"
#include "nsFrameState.h"

class nsIFrame;
struct nsRect;

class nsBoxSize {
 public:
  nsBoxSize();

  nscoord pref;
  nscoord min;
  nscoord max;
  nscoord flex;
  nscoord left;
  nscoord right;
  bool collapsed;
  bool bogus;

  nsBoxSize* next;

  void* operator new(size_t sz, nsBoxLayoutState& aState) noexcept(true);
  void operator delete(void* aPtr, size_t sz);
};

class nsComputedBoxSize {
 public:
  nsComputedBoxSize();

  nscoord size;
  bool valid;
  bool resized;
  nsComputedBoxSize* next;

  void* operator new(size_t sz, nsBoxLayoutState& aState) noexcept(true);
  void operator delete(void* aPtr, size_t sz);
};

#define GET_WIDTH(size, isHorizontal) (isHorizontal ? size.width : size.height)
#define GET_HEIGHT(size, isHorizontal) (isHorizontal ? size.height : size.width)
#define GET_X(size, isHorizontal) (isHorizontal ? size.x : size.y)
#define GET_Y(size, isHorizontal) (isHorizontal ? size.y : size.x)
#define GET_COORD(aX, aY, isHorizontal) (isHorizontal ? aX : aY)

#define SET_WIDTH(size, coord, isHorizontal) \
  if (isHorizontal) {                        \
    (size).width = (coord);                  \
  } else {                                   \
    (size).height = (coord);                 \
  }
#define SET_HEIGHT(size, coord, isHorizontal) \
  if (isHorizontal) {                         \
    (size).height = (coord);                  \
  } else {                                    \
    (size).width = (coord);                   \
  }
#define SET_X(size, coord, isHorizontal) \
  if (isHorizontal) {                    \
    (size).x = (coord);                  \
  } else {                               \
    (size).y = (coord);                  \
  }
#define SET_Y(size, coord, isHorizontal) \
  if (isHorizontal) {                    \
    (size).y = (coord);                  \
  } else {                               \
    (size).x = (coord);                  \
  }

#define SET_COORD(aX, aY, coord, isHorizontal) \
  if (isHorizontal) {                          \
    aX = (coord);                              \
  } else {                                     \
    aY = (coord);                              \
  }

nsresult NS_NewSprocketLayout(nsCOMPtr<nsBoxLayout>& aNewLayout);

class nsSprocketLayout : public nsBoxLayout {
 public:
  friend nsresult NS_NewSprocketLayout(nsCOMPtr<nsBoxLayout>& aNewLayout);
  static void Shutdown();

  NS_IMETHOD XULLayout(nsIFrame* aBox, nsBoxLayoutState& aState) override;

  virtual nsSize GetXULPrefSize(nsIFrame* aBox,
                                nsBoxLayoutState& aBoxLayoutState) override;
  virtual nsSize GetXULMinSize(nsIFrame* aBox,
                               nsBoxLayoutState& aBoxLayoutState) override;
  virtual nsSize GetXULMaxSize(nsIFrame* aBox,
                               nsBoxLayoutState& aBoxLayoutState) override;
  virtual nscoord GetAscent(nsIFrame* aBox,
                            nsBoxLayoutState& aBoxLayoutState) override;

  nsSprocketLayout();

  static bool IsXULHorizontal(nsIFrame* aBox);

  static void SetLargestSize(nsSize& aSize1, const nsSize& aSize2,
                             bool aIsHorizontal);
  static void SetSmallestSize(nsSize& aSize1, const nsSize& aSize2,
                              bool aIsHorizontal);

  static void AddLargestSize(nsSize& aSize, const nsSize& aSizeToAdd,
                             bool aIsHorizontal);
  static void AddSmallestSize(nsSize& aSize, const nsSize& aSizeToAdd,
                              bool aIsHorizontal);
  static void AddCoord(nscoord& aCoord, nscoord aCoordToAdd);

 protected:
  void ComputeChildsNextPosition(nsIFrame* aBox, const nscoord& aCurX,
                                 const nscoord& aCurY, nscoord& aNextX,
                                 nscoord& aNextY, const nsRect& aChildSize);

  void ChildResized(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChild,
                    nsBoxSize* aChildBoxSize,
                    nsComputedBoxSize* aChildComputedBoxSize,
                    nsBoxSize* aBoxSizes, nsComputedBoxSize* aComputedBoxSizes,
                    const nsRect& aChildLayoutRect, nsRect& aChildActualRect,
                    nsRect& aContainingRect, int32_t aFlexes, bool& aFinished);

  void AlignChildren(nsIFrame* aBox, nsBoxLayoutState& aState);

  virtual void ComputeChildSizes(nsIFrame* aBox, nsBoxLayoutState& aState,
                                 nscoord& aGivenSize, nsBoxSize* aBoxSizes,
                                 nsComputedBoxSize*& aComputedBoxSizes);

  virtual void PopulateBoxSizes(nsIFrame* aBox,
                                nsBoxLayoutState& aBoxLayoutState,
                                nsBoxSize*& aBoxSizes, nscoord& aMinSize,
                                nscoord& aMaxSize, int32_t& aFlexes);

  virtual void InvalidateComputedSizes(nsComputedBoxSize* aComputedBoxSizes);

  virtual bool GetDefaultFlex(int32_t& aFlex);

  virtual void GetFrameState(nsIFrame* aBox, nsFrameState& aState);

 private:
  // because the sprocket layout manager has no instance variables. We
  // can make a static one and reuse it everywhere.
  static nsBoxLayout* gInstance;
};

#endif