1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef nsTreeColumns_h__
8 #define nsTreeColumns_h__
9 
10 #include "mozilla/Attributes.h"
11 #include "mozilla/RefPtr.h"
12 #include "nsCoord.h"
13 #include "nsCycleCollectionParticipant.h"
14 #include "nsQueryObject.h"
15 #include "nsWrapperCache.h"
16 #include "nsString.h"
17 
18 class nsAtom;
19 class nsTreeBodyFrame;
20 class nsTreeColumns;
21 class nsIFrame;
22 class nsIContent;
23 struct nsRect;
24 
25 namespace mozilla {
26 enum class StyleTextAlignKeyword : uint8_t;
27 using StyleTextAlign = StyleTextAlignKeyword;
28 class ErrorResult;
29 namespace dom {
30 class Element;
31 class XULTreeElement;
32 }  // namespace dom
33 }  // namespace mozilla
34 
35 #define NS_TREECOLUMN_IMPL_CID                       \
36   { /* 02cd1963-4b5d-4a6c-9223-814d3ade93a3 */       \
37     0x02cd1963, 0x4b5d, 0x4a6c, {                    \
38       0x92, 0x23, 0x81, 0x4d, 0x3a, 0xde, 0x93, 0xa3 \
39     }                                                \
40   }
41 
42 // This class is our column info.  We use it to iterate our columns and to
43 // obtain information about each column.
44 class nsTreeColumn final : public nsISupports, public nsWrapperCache {
45  public:
46   nsTreeColumn(nsTreeColumns* aColumns, mozilla::dom::Element* aElement);
47 
48   NS_DECLARE_STATIC_IID_ACCESSOR(NS_TREECOLUMN_IMPL_CID)
49 
50   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
51   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsTreeColumn)
52 
53   // WebIDL
54   nsIContent* GetParentObject() const;
55   virtual JSObject* WrapObject(JSContext* aCx,
56                                JS::Handle<JSObject*> aGivenProto) override;
57 
58   mozilla::dom::Element* Element();
59 
GetColumns()60   nsTreeColumns* GetColumns() const { return mColumns; }
61 
62   int32_t GetX(mozilla::ErrorResult& aRv);
63   int32_t GetWidth(mozilla::ErrorResult& aRv);
64 
65   void GetId(nsAString& aId) const;
Index()66   int32_t Index() const { return mIndex; }
67 
Primary()68   bool Primary() const { return mIsPrimary; }
Cycler()69   bool Cycler() const { return mIsCycler; }
Editable()70   bool Editable() const { return mIsEditable; }
Type()71   int16_t Type() const { return mType; }
72 
GetNext()73   nsTreeColumn* GetNext() const { return mNext; }
GetPrevious()74   nsTreeColumn* GetPrevious() const { return mPrevious; }
75 
76   already_AddRefed<nsTreeColumn> GetPreviousColumn();
77 
78   void Invalidate(mozilla::ErrorResult& aRv);
79 
80   friend class nsTreeBodyFrame;
81   friend class nsTreeColumns;
82 
83  protected:
84   ~nsTreeColumn();
85   nsIFrame* GetFrame();
86   nsIFrame* GetFrame(nsTreeBodyFrame* aBodyFrame);
87   // Don't call this if GetWidthInTwips or GetRect fails
88   bool IsLastVisible(nsTreeBodyFrame* aBodyFrame);
89 
90   /**
91    * Returns a rect with x and width taken from the frame's rect and specified
92    * y and height. May fail in case there's no frame for the column.
93    */
94   nsresult GetRect(nsTreeBodyFrame* aBodyFrame, nscoord aY, nscoord aHeight,
95                    nsRect* aResult);
96 
97   nsresult GetXInTwips(nsTreeBodyFrame* aBodyFrame, nscoord* aResult);
98   nsresult GetWidthInTwips(nsTreeBodyFrame* aBodyFrame, nscoord* aResult);
99 
SetColumns(nsTreeColumns * aColumns)100   void SetColumns(nsTreeColumns* aColumns) { mColumns = aColumns; }
101 
102  public:
GetId()103   const nsAString& GetId() const { return mId; }
GetAtom()104   nsAtom* GetAtom() { return mAtom; }
GetIndex()105   int32_t GetIndex() { return mIndex; }
106 
107  protected:
IsPrimary()108   bool IsPrimary() { return mIsPrimary; }
IsCycler()109   bool IsCycler() { return mIsCycler; }
IsEditable()110   bool IsEditable() { return mIsEditable; }
Overflow()111   bool Overflow() { return mOverflow; }
112 
GetType()113   int16_t GetType() { return mType; }
114 
GetCropStyle()115   int8_t GetCropStyle() { return mCropStyle; }
GetTextAlignment()116   mozilla::StyleTextAlign GetTextAlignment() { return mTextAlignment; }
117 
SetNext(nsTreeColumn * aNext)118   void SetNext(nsTreeColumn* aNext) {
119     NS_ASSERTION(!mNext, "already have a next sibling");
120     mNext = aNext;
121   }
SetPrevious(nsTreeColumn * aPrevious)122   void SetPrevious(nsTreeColumn* aPrevious) { mPrevious = aPrevious; }
123 
124  private:
125   /**
126    * Non-null nsIContent for the associated <treecol> element.
127    */
128   RefPtr<mozilla::dom::Element> mContent;
129 
130   nsTreeColumns* mColumns;
131 
132   nsString mId;
133   RefPtr<nsAtom> mAtom;
134 
135   int32_t mIndex;
136 
137   bool mIsPrimary;
138   bool mIsCycler;
139   bool mIsEditable;
140   bool mOverflow;
141 
142   int16_t mType;
143 
144   int8_t mCropStyle;
145   mozilla::StyleTextAlign mTextAlignment;
146 
147   RefPtr<nsTreeColumn> mNext;
148   nsTreeColumn* mPrevious;
149 };
150 
NS_DEFINE_STATIC_IID_ACCESSOR(nsTreeColumn,NS_TREECOLUMN_IMPL_CID)151 NS_DEFINE_STATIC_IID_ACCESSOR(nsTreeColumn, NS_TREECOLUMN_IMPL_CID)
152 
153 class nsTreeColumns final : public nsISupports, public nsWrapperCache {
154  private:
155   ~nsTreeColumns();
156 
157  public:
158   explicit nsTreeColumns(nsTreeBodyFrame* aTree);
159 
160   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
161   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsTreeColumns)
162 
163   nsIContent* GetParentObject() const;
164   virtual JSObject* WrapObject(JSContext* aCx,
165                                JS::Handle<JSObject*> aGivenProto) override;
166 
167   // WebIDL
168   mozilla::dom::XULTreeElement* GetTree() const;
169   uint32_t Count();
170   uint32_t Length() { return Count(); }
171 
172   nsTreeColumn* GetFirstColumn() {
173     EnsureColumns();
174     return mFirstColumn;
175   }
176   nsTreeColumn* GetLastColumn();
177 
178   nsTreeColumn* GetPrimaryColumn();
179   nsTreeColumn* GetSortedColumn();
180   nsTreeColumn* GetKeyColumn();
181 
182   nsTreeColumn* GetColumnFor(mozilla::dom::Element* aElement);
183 
184   nsTreeColumn* IndexedGetter(uint32_t aIndex, bool& aFound);
185   nsTreeColumn* GetColumnAt(uint32_t aIndex);
186   nsTreeColumn* NamedGetter(const nsAString& aId, bool& aFound);
187   nsTreeColumn* GetNamedColumn(const nsAString& aId);
188   void GetSupportedNames(nsTArray<nsString>& aNames);
189 
190   void InvalidateColumns();
191 
192   friend class nsTreeBodyFrame;
193 
194  protected:
195   void SetTree(nsTreeBodyFrame* aTree) { mTree = aTree; }
196 
197   // Builds our cache of column info.
198   void EnsureColumns();
199 
200  private:
201   nsTreeBodyFrame* mTree;
202 
203   /**
204    * The first column in the list of columns. All of the columns are supposed
205    * to be "alive", i.e. have a frame. This is achieved by clearing the columns
206    * list each time an nsTreeColFrame is destroyed.
207    *
208    * XXX this means that new nsTreeColumn objects are unnecessarily created
209    *     for untouched columns.
210    */
211   RefPtr<nsTreeColumn> mFirstColumn;
212 };
213 
214 #endif  // nsTreeColumns_h__
215