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 "core/fxcrt/check.h"
11#include "fxjs/gc/container_trace.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
17namespace pdfium {
18
19CFWL_WidgetMgr::CFWL_WidgetMgr(AdapterIface* pAdapter, CFWL_App* pApp)
20 : m_pAdapter(pAdapter), m_pApp(pApp) {
21 DCHECK(m_pAdapter);
22 m_mapWidgetItem[nullptr] = cppgc::MakeGarbageCollected<Item>(
23 pApp->GetHeap()->GetAllocationHandle(), nullptr);
24}
25
26CFWL_WidgetMgr::~CFWL_WidgetMgr() = default;
27
28void CFWL_WidgetMgr::Trace(cppgc::Visitor* visitor) const {
29 visitor->Trace(m_pApp);
30 visitor->Trace(m_pAdapter);
31 ContainerTrace(visitor, m_mapWidgetItem);
32}
33
34CFWL_Widget* CFWL_WidgetMgr::GetParentWidget(const CFWL_Widget* pWidget) const {
35 Item* pItem = GetWidgetMgrItem(pWidget);
36 if (!pItem)
37 return nullptr;
38
39 Item* pParent = pItem->GetParent();
40 return pParent ? pParent->pWidget : nullptr;
41}
42
43CFWL_Widget* CFWL_WidgetMgr::GetPriorSiblingWidget(CFWL_Widget* pWidget) const {
44 Item* pItem = GetWidgetMgrItem(pWidget);
45 if (!pItem)
46 return nullptr;
47
48 Item* pSibling = pItem->GetPrevSibling();
49 return pSibling ? pSibling->pWidget : nullptr;
50}
51
52CFWL_Widget* CFWL_WidgetMgr::GetNextSiblingWidget(CFWL_Widget* pWidget) const {
53 Item* pItem = GetWidgetMgrItem(pWidget);
54 if (!pItem)
55 return nullptr;
56
57 Item* pSibling = pItem->GetNextSibling();
58 return pSibling ? pSibling->pWidget : nullptr;
59}
60
61CFWL_Widget* CFWL_WidgetMgr::GetFirstChildWidget(CFWL_Widget* pWidget) const {
62 Item* pItem = GetWidgetMgrItem(pWidget);
63 if (!pItem)
64 return nullptr;
65
66 Item* pChild = pItem->GetFirstChild();
67 return pChild ? pChild->pWidget : nullptr;
68}
69
70CFWL_Widget* CFWL_WidgetMgr::GetLastChildWidget(CFWL_Widget* pWidget) const {
71 Item* pItem = GetWidgetMgrItem(pWidget);
72 if (!pItem)
73 return nullptr;
74
75 Item* pChild = pItem->GetLastChild();
76 return pChild ? pChild->pWidget : nullptr;
77}
78
79void CFWL_WidgetMgr::RepaintWidget(CFWL_Widget* pWidget,
80 const CFX_RectF& rect) {
81 CFWL_Widget* pNative = pWidget;
82 CFX_RectF transformedRect = rect;
83 CFWL_Widget* pOuter = pWidget->GetOuter();
84 while (pOuter) {
85 CFX_RectF rtTemp = pNative->GetWidgetRect();
86 transformedRect.left += rtTemp.left;
87 transformedRect.top += rtTemp.top;
88 pNative = pOuter;
89 pOuter = pOuter->GetOuter();
90 }
91 m_pAdapter->RepaintWidget(pNative);
92}
93
94void CFWL_WidgetMgr::InsertWidget(CFWL_Widget* pParent, CFWL_Widget* pChild) {
95 Item* pParentItem = GetWidgetMgrItem(pParent);
96 if (!pParentItem) {
97 pParentItem = CreateWidgetMgrItem(pParent);
98 GetWidgetMgrRootItem()->AppendLastChild(pParentItem);
99 }
100 Item* pChildItem = GetWidgetMgrItem(pChild);
101 if (!pChildItem)
102 pChildItem = CreateWidgetMgrItem(pChild);
103 pParentItem->AppendLastChild(pChildItem);
104}
105
106void CFWL_WidgetMgr::RemoveWidget(CFWL_Widget* pWidget) {
107 DCHECK(pWidget);
108 Item* pItem = GetWidgetMgrItem(pWidget);
109 if (!pItem)
110 return;
111
112 while (pItem->GetFirstChild())
113 RemoveWidget(pItem->GetFirstChild()->pWidget);
114
115 pItem->RemoveSelfIfParented();
116 m_mapWidgetItem.erase(pWidget);
117}
118
119CFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(CFWL_Widget* parent,
120 const CFX_PointF& point) const {
121 if (!parent)
122 return nullptr;
123
124 CFWL_Widget* child = GetLastChildWidget(parent);
125 while (child) {
126 if (child->IsVisible()) {
127 CFX_PointF pos = parent->GetMatrix().GetInverse().Transform(point);
128 CFX_RectF bounds = child->GetWidgetRect();
129 if (bounds.Contains(pos)) {
130 pos -= bounds.TopLeft();
131 return GetWidgetAtPoint(child, pos);
132 }
133 }
134 child = GetPriorSiblingWidget(child);
135 }
136 return parent;
137}
138
139CFWL_Widget* CFWL_WidgetMgr::GetDefaultButton(CFWL_Widget* pParent) const {
140 if (pParent->GetClassID() == FWL_Type::PushButton &&
142 return pParent;
143 }
144
145 CFWL_Widget* child = GetFirstChildWidget(pParent);
146 while (child) {
149 return child;
150 }
151 if (CFWL_Widget* find = GetDefaultButton(child))
152 return find;
153
154 child = GetNextSiblingWidget(child);
155 }
156 return nullptr;
157}
158
159CFWL_WidgetMgr::Item* CFWL_WidgetMgr::GetWidgetMgrRootItem() const {
160 return GetWidgetMgrItem(nullptr);
161}
162
163CFWL_WidgetMgr::Item* CFWL_WidgetMgr::GetWidgetMgrItem(
164 const CFWL_Widget* pWidget) const {
165 auto it = m_mapWidgetItem.find(pWidget);
166 return it != m_mapWidgetItem.end() ? it->second : nullptr;
167}
168
169CFWL_WidgetMgr::Item* CFWL_WidgetMgr::CreateWidgetMgrItem(
170 CFWL_Widget* pWidget) {
171 auto* pItem = cppgc::MakeGarbageCollected<Item>(
172 m_pApp->GetHeap()->GetAllocationHandle(), pWidget);
173 m_mapWidgetItem[pWidget] = pItem;
174 return pItem;
175}
176
177void CFWL_WidgetMgr::GetAdapterPopupPos(CFWL_Widget* pWidget,
178 float fMinHeight,
179 float fMaxHeight,
180 const CFX_RectF& rtAnchor,
181 CFX_RectF* pPopupRect) const {
182 m_pAdapter->GetPopupPos(pWidget, fMinHeight, fMaxHeight, rtAnchor,
183 pPopupRect);
184}
185
186void CFWL_WidgetMgr::OnProcessMessageToForm(CFWL_Message* pMessage) {
187 CFWL_Widget* pDstWidget = pMessage->GetDstTarget();
188 if (!pDstWidget)
189 return;
190
191 CFWL_NoteDriver* pNoteDriver = pDstWidget->GetFWLApp()->GetNoteDriver();
192 pNoteDriver->ProcessMessage(pMessage);
193}
194
195void CFWL_WidgetMgr::OnDrawWidget(CFWL_Widget* pWidget,
196 CFGAS_GEGraphics* pGraphics,
197 const CFX_Matrix& matrix) {
198 if (!pWidget || !pGraphics)
199 return;
200
201 pWidget->GetDelegate()->OnDrawWidget(pGraphics, matrix);
202
203 CFX_RectF clipBounds = pGraphics->GetClipRect();
204 if (!clipBounds.IsEmpty())
205 DrawChildren(pWidget, clipBounds, pGraphics, matrix);
206}
207
208void CFWL_WidgetMgr::DrawChildren(CFWL_Widget* parent,
209 const CFX_RectF& rtClip,
210 CFGAS_GEGraphics* pGraphics,
211 const CFX_Matrix& mtMatrix) {
212 if (!parent)
213 return;
214
215 CFWL_Widget* pNextChild = GetFirstChildWidget(parent);
216 while (pNextChild) {
217 CFWL_Widget* child = pNextChild;
218 pNextChild = GetNextSiblingWidget(child);
219 if (!child->IsVisible())
220 continue;
221
222 CFX_RectF rtWidget = child->GetWidgetRect();
223 if (rtWidget.IsEmpty())
224 continue;
225
226 CFX_Matrix widgetMatrix;
227 CFX_RectF clipBounds(rtWidget);
228 widgetMatrix.Concat(mtMatrix);
229 widgetMatrix.TranslatePrepend(rtWidget.left, rtWidget.top);
230
231 if (IFWL_WidgetDelegate* pDelegate = child->GetDelegate())
232 pDelegate->OnDrawWidget(pGraphics, widgetMatrix);
233
234 DrawChildren(child, clipBounds, pGraphics, widgetMatrix);
235 }
236}
237
238CFWL_WidgetMgr::Item::Item(CFWL_Widget* widget) : pWidget(widget) {}
239
240CFWL_WidgetMgr::Item::~Item() = default;
241
242void CFWL_WidgetMgr::Item::Trace(cppgc::Visitor* visitor) const {
243 GCedTreeNode<Item>::Trace(visitor);
244 visitor->Trace(pWidget);
245}
246
247} // namespace pdfium
#define FWL_STATE_PSB_Default
#define DCHECK
Definition check.h:33
CFX_RectF GetClipRect() const
void TranslatePrepend(float x, float y)
void Concat(const CFX_Matrix &right)
CFX_RectF(const CFX_RectF &other)=default
bool IsEmpty() const
CFWL_NoteDriver * GetNoteDriver() const
Definition cfwl_app.h:49
CFWL_Widget * GetDstTarget() const
void ProcessMessage(CFWL_Message *pMessage)
CFWL_Widget * GetFirstChildWidget(CFWL_Widget *pWidget) const
void RemoveWidget(CFWL_Widget *pWidget)
void OnProcessMessageToForm(CFWL_Message *pMessage)
void RepaintWidget(CFWL_Widget *pWidget, const CFX_RectF &pRect)
void OnDrawWidget(CFWL_Widget *pWidget, CFGAS_GEGraphics *pGraphics, const CFX_Matrix &matrix)
CFWL_Widget * GetDefaultButton(CFWL_Widget *pParent) const
CFWL_Widget * GetNextSiblingWidget(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
CFWL_Widget * GetWidgetAtPoint(CFWL_Widget *pParent, const CFX_PointF &point) const
CFWL_Widget * GetParentWidget(const CFWL_Widget *pWidget) const
virtual CFX_RectF GetWidgetRect()
CFWL_Widget * GetOuter() const
virtual FWL_Type GetClassID() const =0
IFWL_WidgetDelegate * GetDelegate()
uint32_t GetStates() const
CFWL_App * GetFWLApp() const
bool IsVisible() const
virtual void OnDrawWidget(CFGAS_GEGraphics *pGraphics, const CFX_Matrix &matrix)=0
CFX_PTemplate< float > CFX_PointF