Base CFWL_WidgetMgr::Item on TreeNode<>
Ease transition onto GCedTreeNode<> someday.
-- tidy one constructor while at it.
Change-Id: I1b25ccd5d9cb8287f7d1282e2bedb6796d512070
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/72613
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/xfa/fwl/cfwl_widgetmgr.cpp b/xfa/fwl/cfwl_widgetmgr.cpp
index 57fada3..a7beabd 100644
--- a/xfa/fwl/cfwl_widgetmgr.cpp
+++ b/xfa/fwl/cfwl_widgetmgr.cpp
@@ -22,7 +22,11 @@
CFWL_Widget* CFWL_WidgetMgr::GetParentWidget(const CFWL_Widget* pWidget) const {
Item* pItem = GetWidgetMgrItem(pWidget);
- return pItem && pItem->pParent ? pItem->pParent->pWidget : nullptr;
+ if (!pItem)
+ return nullptr;
+
+ Item* pParent = pItem->GetParent();
+ return pParent ? pParent->pWidget : nullptr;
}
CFWL_Widget* CFWL_WidgetMgr::GetOwnerWidget(const CFWL_Widget* pWidget) const {
@@ -35,25 +39,41 @@
if (!pItem)
return nullptr;
- pItem = pItem->pPrevious;
- while (pItem && pItem->pPrevious)
- pItem = pItem->pPrevious;
- return pItem ? pItem->pWidget : nullptr;
+ pItem = pItem->GetPrevSibling(); // Item is never its own first sibling.
+ if (!pItem)
+ return nullptr;
+
+ while (pItem->GetPrevSibling())
+ pItem = pItem->GetPrevSibling();
+
+ return pItem->pWidget;
}
CFWL_Widget* CFWL_WidgetMgr::GetPriorSiblingWidget(CFWL_Widget* pWidget) const {
Item* pItem = GetWidgetMgrItem(pWidget);
- return pItem && pItem->pPrevious ? pItem->pPrevious->pWidget : nullptr;
+ if (!pItem)
+ return nullptr;
+
+ Item* pSibling = pItem->GetPrevSibling();
+ return pSibling ? pSibling->pWidget : nullptr;
}
CFWL_Widget* CFWL_WidgetMgr::GetNextSiblingWidget(CFWL_Widget* pWidget) const {
Item* pItem = GetWidgetMgrItem(pWidget);
- return pItem && pItem->pNext ? pItem->pNext->pWidget : nullptr;
+ if (!pItem)
+ return nullptr;
+
+ Item* pSibling = pItem->GetNextSibling();
+ return pSibling ? pSibling->pWidget : nullptr;
}
CFWL_Widget* CFWL_WidgetMgr::GetFirstChildWidget(CFWL_Widget* pWidget) const {
Item* pItem = GetWidgetMgrItem(pWidget);
- return pItem && pItem->pChild ? pItem->pChild->pWidget : nullptr;
+ if (!pItem)
+ return nullptr;
+
+ Item* pChild = pItem->GetFirstChild();
+ return pChild ? pChild->pWidget : nullptr;
}
CFWL_Widget* CFWL_WidgetMgr::GetLastChildWidget(CFWL_Widget* pWidget) const {
@@ -61,10 +81,8 @@
if (!pItem)
return nullptr;
- pItem = pItem->pChild;
- while (pItem && pItem->pNext)
- pItem = pItem->pNext;
- return pItem ? pItem->pWidget : nullptr;
+ Item* pChild = pItem->GetLastChild();
+ return pChild ? pChild->pWidget : nullptr;
}
CFWL_Widget* CFWL_WidgetMgr::GetSystemFormWidget(CFWL_Widget* pWidget) const {
@@ -72,53 +90,11 @@
while (pItem) {
if (IsAbleNative(pItem->pWidget))
return pItem->pWidget;
- pItem = pItem->pParent;
+ pItem = pItem->GetParent();
}
return nullptr;
}
-void CFWL_WidgetMgr::AppendWidget(CFWL_Widget* pWidget) {
- Item* pItem = GetWidgetMgrItem(pWidget);
- if (!pItem)
- return;
- if (!pItem->pParent)
- return;
-
- Item* pChild = pItem->pParent->pChild;
- int32_t i = 0;
- while (pChild) {
- if (pChild == pItem) {
- if (pChild->pPrevious)
- pChild->pPrevious->pNext = pChild->pNext;
- if (pChild->pNext)
- pChild->pNext->pPrevious = pChild->pPrevious;
- if (pItem->pParent->pChild == pItem)
- pItem->pParent->pChild = pItem->pNext;
-
- pItem->pNext = nullptr;
- pItem->pPrevious = nullptr;
- break;
- }
- if (!pChild->pNext)
- break;
-
- pChild = pChild->pNext;
- ++i;
- }
-
- pChild = pItem->pParent->pChild;
- if (pChild) {
- while (pChild->pNext)
- pChild = pChild->pNext;
-
- pChild->pNext = pItem;
- pItem->pPrevious = pChild;
- } else {
- pItem->pParent->pChild = pItem;
- pItem->pPrevious = nullptr;
- }
- pItem->pNext = nullptr;
-}
void CFWL_WidgetMgr::RepaintWidget(CFWL_Widget* pWidget,
const CFX_RectF& rect) {
@@ -139,70 +115,39 @@
void CFWL_WidgetMgr::InsertWidget(CFWL_Widget* pParent, CFWL_Widget* pChild) {
Item* pParentItem = GetWidgetMgrItem(pParent);
if (!pParentItem) {
- auto item = std::make_unique<Item>(pParent);
- pParentItem = item.get();
- m_mapWidgetItem[pParent] = std::move(item);
-
- pParentItem->pParent = GetWidgetMgrItem(nullptr);
- AppendWidget(pParent);
+ pParentItem = CreateWidgetMgrItem(pParent);
+ GetWidgetMgrRootItem()->AppendLastChild(pParentItem);
}
-
- Item* pItem = GetWidgetMgrItem(pChild);
- if (!pItem) {
- auto item = std::make_unique<Item>(pChild);
- pItem = item.get();
- m_mapWidgetItem[pChild] = std::move(item);
- }
- if (pItem->pParent && pItem->pParent != pParentItem) {
- if (pItem->pPrevious)
- pItem->pPrevious->pNext = pItem->pNext;
- if (pItem->pNext)
- pItem->pNext->pPrevious = pItem->pPrevious;
- if (pItem->pParent->pChild == pItem)
- pItem->pParent->pChild = pItem->pNext;
- }
- pItem->pParent = pParentItem;
- AppendWidget(pChild);
+ Item* pChildItem = GetWidgetMgrItem(pChild);
+ if (!pChildItem)
+ pChildItem = CreateWidgetMgrItem(pChild);
+ pParentItem->AppendLastChild(pChildItem);
}
void CFWL_WidgetMgr::RemoveWidget(CFWL_Widget* pWidget) {
+ ASSERT(pWidget);
Item* pItem = GetWidgetMgrItem(pWidget);
if (!pItem)
return;
- if (pItem->pPrevious)
- pItem->pPrevious->pNext = pItem->pNext;
- if (pItem->pNext)
- pItem->pNext->pPrevious = pItem->pPrevious;
- if (pItem->pParent && pItem->pParent->pChild == pItem)
- pItem->pParent->pChild = pItem->pNext;
- Item* pChild = pItem->pChild;
- while (pChild) {
- Item* pNext = pChild->pNext;
- RemoveWidget(pChild->pWidget);
- pChild = pNext;
- }
+ while (pItem->GetFirstChild())
+ RemoveWidget(pItem->GetFirstChild()->pWidget);
+
+ pItem->RemoveSelfIfParented();
m_mapWidgetItem.erase(pWidget);
}
void CFWL_WidgetMgr::SetParent(CFWL_Widget* pParent, CFWL_Widget* pChild) {
- Item* pParentItem = GetWidgetMgrItem(pParent);
Item* pItem = GetWidgetMgrItem(pChild);
if (!pItem)
return;
- if (pItem->pParent && pItem->pParent != pParentItem) {
- if (pItem->pPrevious)
- pItem->pPrevious->pNext = pItem->pNext;
- if (pItem->pNext)
- pItem->pNext->pPrevious = pItem->pPrevious;
- if (pItem->pParent->pChild == pItem)
- pItem->pParent->pChild = pItem->pNext;
- pItem->pNext = nullptr;
- pItem->pPrevious = nullptr;
+ Item* pParentItem = GetWidgetMgrItem(pParent);
+ if (!pParentItem) {
+ pItem->RemoveSelfIfParented();
+ return;
}
- pItem->pParent = pParentItem;
- AppendWidget(pChild);
+ pParentItem->AppendLastChild(pItem);
}
CFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(CFWL_Widget* parent,
@@ -254,12 +199,24 @@
GetWidgetMgrItem(pWidget)->iRedrawCounter = 0;
}
+CFWL_WidgetMgr::Item* CFWL_WidgetMgr::GetWidgetMgrRootItem() const {
+ return GetWidgetMgrItem(nullptr);
+}
+
CFWL_WidgetMgr::Item* CFWL_WidgetMgr::GetWidgetMgrItem(
const CFWL_Widget* pWidget) const {
auto it = m_mapWidgetItem.find(pWidget);
return it != m_mapWidgetItem.end() ? it->second.get() : nullptr;
}
+CFWL_WidgetMgr::Item* CFWL_WidgetMgr::CreateWidgetMgrItem(
+ CFWL_Widget* pWidget) {
+ auto pOwnedItem = std::make_unique<Item>(pWidget);
+ auto* pItem = pOwnedItem.get();
+ m_mapWidgetItem[pWidget] = std::move(pOwnedItem);
+ return pItem;
+}
+
bool CFWL_WidgetMgr::IsAbleNative(CFWL_Widget* pWidget) const {
if (!pWidget || !pWidget->IsForm())
return false;
@@ -338,7 +295,7 @@
}
}
-CFWL_WidgetMgr::Item::Item() : CFWL_WidgetMgr::Item(nullptr) {}
+CFWL_WidgetMgr::Item::Item() : pWidget(nullptr) {}
CFWL_WidgetMgr::Item::Item(CFWL_Widget* widget) : pWidget(widget) {}
diff --git a/xfa/fwl/cfwl_widgetmgr.h b/xfa/fwl/cfwl_widgetmgr.h
index 4562716..6f4e763 100644
--- a/xfa/fwl/cfwl_widgetmgr.h
+++ b/xfa/fwl/cfwl_widgetmgr.h
@@ -11,6 +11,7 @@
#include <memory>
#include "core/fxcrt/fx_system.h"
+#include "core/fxcrt/tree_node.h"
#include "xfa/fxgraphics/cxfa_graphics.h"
class CFWL_Message;
@@ -64,17 +65,13 @@
CFX_RectF* pPopupRect) const;
private:
- class Item {
+ class Item : public TreeNode<Item> {
public:
Item();
explicit Item(CFWL_Widget* widget);
- ~Item();
+ ~Item() final;
- Item* pParent = nullptr;
Item* pOwner = nullptr;
- Item* pChild = nullptr;
- Item* pPrevious = nullptr;
- Item* pNext = nullptr;
CFWL_Widget* const pWidget;
std::unique_ptr<CXFA_Graphics> pOffscreen;
int32_t iRedrawCounter = 0;
@@ -83,9 +80,11 @@
CFWL_Widget* GetFirstSiblingWidget(CFWL_Widget* pWidget) const;
CFWL_Widget* GetPriorSiblingWidget(CFWL_Widget* pWidget) const;
CFWL_Widget* GetLastChildWidget(CFWL_Widget* pWidget) const;
- Item* GetWidgetMgrItem(const CFWL_Widget* pWidget) const;
- void AppendWidget(CFWL_Widget* pWidget);
+ Item* GetWidgetMgrRootItem() const;
+ Item* GetWidgetMgrItem(const CFWL_Widget* pWidget) const;
+ Item* CreateWidgetMgrItem(CFWL_Widget* pWidget);
+
void ResetRedrawCounts(CFWL_Widget* pWidget);
void DrawChild(CFWL_Widget* pParent,
const CFX_RectF& rtClip,