Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cfwl_widgetmgr.cpp
Go to the documentation of this file.
1// Copyright 2014 The PDFium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#include "xfa/fwl/cfwl_widgetmgr.h"
8
9#include "build/build_config.h"
10#include "fxjs/gc/container_trace.h"
11#include "third_party/base/check.h"
12#include "xfa/fwl/cfwl_app.h"
13#include "xfa/fwl/cfwl_message.h"
14#include "xfa/fwl/cfwl_notedriver.h"
15#include "xfa/fwl/cfwl_pushbutton.h"
16
17CFWL_WidgetMgr::CFWL_WidgetMgr(AdapterIface* pAdapter, CFWL_App* pApp)
18 : m_pAdapter(pAdapter), m_pApp(pApp) {
19 DCHECK(m_pAdapter);
20 m_mapWidgetItem[nullptr] = cppgc::MakeGarbageCollected<Item>(
21 pApp->GetHeap()->GetAllocationHandle(), nullptr);
22}
23
24CFWL_WidgetMgr::~CFWL_WidgetMgr() = default;
25
26void CFWL_WidgetMgr::Trace(cppgc::Visitor* visitor) const {
27 visitor->Trace(m_pApp);
28 visitor->Trace(m_pAdapter);
29 ContainerTrace(visitor, m_mapWidgetItem);
30}
31
32CFWL_Widget* CFWL_WidgetMgr::GetParentWidget(const CFWL_Widget* pWidget) const {
33 Item* pItem = GetWidgetMgrItem(pWidget);
34 if (!pItem)
35 return nullptr;
36
37 Item* pParent = pItem->GetParent();
38 return pParent ? pParent->pWidget : nullptr;
39}
40
41CFWL_Widget* CFWL_WidgetMgr::GetPriorSiblingWidget(CFWL_Widget* pWidget) const {
42 Item* pItem = GetWidgetMgrItem(pWidget);
43 if (!pItem)
44 return nullptr;
45
46 Item* pSibling = pItem->GetPrevSibling();
47 return pSibling ? pSibling->pWidget : nullptr;
48}
49
50CFWL_Widget* CFWL_WidgetMgr::GetNextSiblingWidget(CFWL_Widget* pWidget) const {
51 Item* pItem = GetWidgetMgrItem(pWidget);
52 if (!pItem)
53 return nullptr;
54
55 Item* pSibling = pItem->GetNextSibling();
56 return pSibling ? pSibling->pWidget : nullptr;
57}
58
59CFWL_Widget* CFWL_WidgetMgr::GetFirstChildWidget(CFWL_Widget* pWidget) const {
60 Item* pItem = GetWidgetMgrItem(pWidget);
61 if (!pItem)
62 return nullptr;
63
64 Item* pChild = pItem->GetFirstChild();
65 return pChild ? pChild->pWidget : nullptr;
66}
67
68CFWL_Widget* CFWL_WidgetMgr::GetLastChildWidget(CFWL_Widget* pWidget) const {
69 Item* pItem = GetWidgetMgrItem(pWidget);
70 if (!pItem)
71 return nullptr;
72
73 Item* pChild = pItem->GetLastChild();
74 return pChild ? pChild->pWidget : nullptr;
75}
76
77void CFWL_WidgetMgr::RepaintWidget(CFWL_Widget* pWidget,
78 const CFX_RectF& rect) {
79 CFWL_Widget* pNative = pWidget;
80 CFX_RectF transformedRect = rect;
81 CFWL_Widget* pOuter = pWidget->GetOuter();
82 while (pOuter) {
83 CFX_RectF rtTemp = pNative->GetWidgetRect();
84 transformedRect.left += rtTemp.left;
85 transformedRect.top += rtTemp.top;
86 pNative = pOuter;
87 pOuter = pOuter->GetOuter();
88 }
89 m_pAdapter->RepaintWidget(pNative);
90}
91
92void CFWL_WidgetMgr::InsertWidget(CFWL_Widget* pParent, CFWL_Widget* pChild) {
93 Item* pParentItem = GetWidgetMgrItem(pParent);
94 if (!pParentItem) {
95 pParentItem = CreateWidgetMgrItem(pParent);
96 GetWidgetMgrRootItem()->AppendLastChild(pParentItem);
97 }
98 Item* pChildItem = GetWidgetMgrItem(pChild);
99 if (!pChildItem)
100 pChildItem = CreateWidgetMgrItem(pChild);
101 pParentItem->AppendLastChild(pChildItem);
102}
103
104void CFWL_WidgetMgr::RemoveWidget(CFWL_Widget* pWidget) {
105 DCHECK(pWidget);
106 Item* pItem = GetWidgetMgrItem(pWidget);
107 if (!pItem)
108 return;
109
110 while (pItem->GetFirstChild())
111 RemoveWidget(pItem->GetFirstChild()->pWidget);
112
113 pItem->RemoveSelfIfParented();
114 m_mapWidgetItem.erase(pWidget);
115}
116
117CFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(CFWL_Widget* parent,
118 const CFX_PointF& point) const {
119 if (!parent)
120 return nullptr;
121
122 CFWL_Widget* child = GetLastChildWidget(parent);
123 while (child) {
124 if (child->IsVisible()) {
125 CFX_PointF pos = parent->GetMatrix().GetInverse().Transform(point);
126 CFX_RectF bounds = child->GetWidgetRect();
127 if (bounds.Contains(pos)) {
128 pos -= bounds.TopLeft();
129 return GetWidgetAtPoint(child, pos);
130 }
131 }
132 child = GetPriorSiblingWidget(child);
133 }
134 return parent;
135}
136
137CFWL_Widget* CFWL_WidgetMgr::GetDefaultButton(CFWL_Widget* pParent) const {
138 if (pParent->GetClassID() == FWL_Type::PushButton &&
140 return pParent;
141 }
142
143 CFWL_Widget* child = GetFirstChildWidget(pParent);
144 while (child) {
147 return child;
148 }
149 if (CFWL_Widget* find = GetDefaultButton(child))
150 return find;
151
152 child = GetNextSiblingWidget(child);
153 }
154 return nullptr;
155}
156
157CFWL_WidgetMgr::Item* CFWL_WidgetMgr::GetWidgetMgrRootItem() const {
158 return GetWidgetMgrItem(nullptr);
159}
160
161CFWL_WidgetMgr::Item* CFWL_WidgetMgr::GetWidgetMgrItem(
162 const CFWL_Widget* pWidget) const {
163 auto it = m_mapWidgetItem.find(pWidget);
164 return it != m_mapWidgetItem.end() ? it->second : nullptr;
165}
166
167CFWL_WidgetMgr::Item* CFWL_WidgetMgr::CreateWidgetMgrItem(
168 CFWL_Widget* pWidget) {
169 auto* pItem = cppgc::MakeGarbageCollected<Item>(
170 m_pApp->GetHeap()->GetAllocationHandle(), pWidget);
171 m_mapWidgetItem[pWidget] = pItem;
172 return pItem;
173}
174
175void CFWL_WidgetMgr::GetAdapterPopupPos(CFWL_Widget* pWidget,
176 float fMinHeight,
177 float fMaxHeight,
178 const CFX_RectF& rtAnchor,
179 CFX_RectF* pPopupRect) const {
180 m_pAdapter->GetPopupPos(pWidget, fMinHeight, fMaxHeight, rtAnchor,
181 pPopupRect);
182}
183
184void CFWL_WidgetMgr::OnProcessMessageToForm(CFWL_Message* pMessage) {
185 CFWL_Widget* pDstWidget = pMessage->GetDstTarget();
186 if (!pDstWidget)
187 return;
188
189 CFWL_NoteDriver* pNoteDriver = pDstWidget->GetFWLApp()->GetNoteDriver();
190 pNoteDriver->ProcessMessage(pMessage);
191}
192
193void CFWL_WidgetMgr::OnDrawWidget(CFWL_Widget* pWidget,
194 CFGAS_GEGraphics* pGraphics,
195 const CFX_Matrix& matrix) {
196 if (!pWidget || !pGraphics)
197 return;
198
199 pWidget->GetDelegate()->OnDrawWidget(pGraphics, matrix);
200
201 CFX_RectF clipBounds = pGraphics->GetClipRect();
202 if (!clipBounds.IsEmpty())
203 DrawChildren(pWidget, clipBounds, pGraphics, matrix);
204}
205
206void CFWL_WidgetMgr::DrawChildren(CFWL_Widget* parent,
207 const CFX_RectF& rtClip,
208 CFGAS_GEGraphics* pGraphics,
209 const CFX_Matrix& mtMatrix) {
210 if (!parent)
211 return;
212
213 CFWL_Widget* pNextChild = GetFirstChildWidget(parent);
214 while (pNextChild) {
215 CFWL_Widget* child = pNextChild;
216 pNextChild = GetNextSiblingWidget(child);
217 if (!child->IsVisible())
218 continue;
219
220 CFX_RectF rtWidget = child->GetWidgetRect();
221 if (rtWidget.IsEmpty())
222 continue;
223
224 CFX_Matrix widgetMatrix;
225 CFX_RectF clipBounds(rtWidget);
226 widgetMatrix.Concat(mtMatrix);
227 widgetMatrix.TranslatePrepend(rtWidget.left, rtWidget.top);
228
229 if (IFWL_WidgetDelegate* pDelegate = child->GetDelegate())
230 pDelegate->OnDrawWidget(pGraphics, widgetMatrix);
231
232 DrawChildren(child, clipBounds, pGraphics, widgetMatrix);
233 }
234}
235
236CFWL_WidgetMgr::Item::Item(CFWL_Widget* widget) : pWidget(widget) {}
237
238CFWL_WidgetMgr::Item::~Item() = default;
239
240void CFWL_WidgetMgr::Item::Trace(cppgc::Visitor* visitor) const {
241 GCedTreeNode<Item>::Trace(visitor);
242 visitor->Trace(pWidget);
243}
#define FWL_STATE_PSB_Default
FWL_Type
Definition cfwl_widget.h:46
CFX_RectF GetClipRect() const
CFWL_NoteDriver * GetNoteDriver() const
Definition cfwl_app.h:47
CFWL_Widget * GetDstTarget() const
void ProcessMessage(CFWL_Message *pMessage)
void OnProcessMessageToForm(CFWL_Message *pMessage)
CFWL_Widget * GetNextSiblingWidget(CFWL_Widget *pWidget) const
CFWL_Widget * GetWidgetAtPoint(CFWL_Widget *pParent, const CFX_PointF &point) const
CFWL_Widget * GetDefaultButton(CFWL_Widget *pParent) const
void OnDrawWidget(CFWL_Widget *pWidget, CFGAS_GEGraphics *pGraphics, const CFX_Matrix &matrix)
CFWL_Widget * GetFirstChildWidget(CFWL_Widget *pWidget) const
void InsertWidget(CFWL_Widget *pParent, CFWL_Widget *pChild)
void GetAdapterPopupPos(CFWL_Widget *pWidget, float fMinHeight, float fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF *pPopupRect) const
void RepaintWidget(CFWL_Widget *pWidget, const CFX_RectF &pRect)
CFWL_Widget * GetParentWidget(const CFWL_Widget *pWidget) const
void RemoveWidget(CFWL_Widget *pWidget)
CFWL_Widget * GetOuter() const
uint32_t GetStates() const
bool IsVisible() const
virtual CFX_RectF GetWidgetRect()
virtual FWL_Type GetClassID() const =0
CFWL_App * GetFWLApp() const
IFWL_WidgetDelegate * GetDelegate()
void TranslatePrepend(float x, float y)
void Concat(const CFX_Matrix &right)
CFX_RectF(const CFX_RectF &other)=default
bool IsEmpty() const
virtual void OnDrawWidget(CFGAS_GEGraphics *pGraphics, const CFX_Matrix &matrix)=0