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_combolist.cpp
Go to the documentation of this file.
1// Copyright 2016 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_combolist.h"
8
9#include "third_party/base/check.h"
10#include "xfa/fwl/cfwl_combobox.h"
11#include "xfa/fwl/cfwl_comboedit.h"
12#include "xfa/fwl/cfwl_listbox.h"
13#include "xfa/fwl/cfwl_messagekey.h"
14#include "xfa/fwl/cfwl_messagekillfocus.h"
15#include "xfa/fwl/cfwl_messagemouse.h"
16#include "xfa/fwl/fwl_widgetdef.h"
17
18CFWL_ComboList::CFWL_ComboList(CFWL_App* app,
19 const Properties& properties,
20 CFWL_Widget* pOuter)
21 : CFWL_ListBox(app, properties, pOuter) {
22 DCHECK(pOuter);
23}
24
25CFWL_ComboList::~CFWL_ComboList() = default;
26
27int32_t CFWL_ComboList::MatchItem(WideStringView wsMatch) {
28 if (wsMatch.IsEmpty())
29 return -1;
30
31 int32_t iCount = CountItems(this);
32 for (int32_t i = 0; i < iCount; i++) {
33 CFWL_ListBox::Item* hItem = GetItem(this, i);
34 WideString wsText = hItem ? hItem->GetText() : WideString();
35 auto pos = wsText.Find(wsMatch);
36 if (pos.has_value() && pos.value() == 0)
37 return i;
38 }
39 return -1;
40}
41
42void CFWL_ComboList::ChangeSelected(int32_t iSel) {
43 CFWL_ListBox::Item* hItem = GetItem(this, iSel);
44 CFWL_ListBox::Item* hOld = GetSelItem(0);
45 int32_t iOld = GetItemIndex(this, hOld);
46 if (iOld == iSel)
47 return;
48
49 CFX_RectF rtInvalidate;
50 if (iOld > -1) {
51 if (CFWL_ListBox::Item* hOldItem = GetItem(this, iOld))
52 rtInvalidate = hOldItem->GetRect();
53 SetSelItem(hOld, false);
54 }
55 if (hItem) {
56 if (CFWL_ListBox::Item* hOldItem = GetItem(this, iSel))
57 rtInvalidate.Union(hOldItem->GetRect());
58 CFWL_ListBox::Item* hSel = GetItem(this, iSel);
59 SetSelItem(hSel, true);
60 }
61 if (!rtInvalidate.IsEmpty())
62 RepaintRect(rtInvalidate);
63}
64
65CFX_PointF CFWL_ComboList::ClientToOuter(const CFX_PointF& point) {
66 return point + CFX_PointF(m_WidgetRect.left, m_WidgetRect.top);
67}
68
69void CFWL_ComboList::OnProcessMessage(CFWL_Message* pMessage) {
70 CFWL_Message::Type type = pMessage->GetType();
71 bool backDefault = true;
74 OnDropListFocusChanged(pMessage, type == CFWL_Message::Type::kSetFocus);
75 } else if (type == CFWL_Message::Type::kMouse) {
76 CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage);
77 CFWL_ScrollBar* vertSB = GetVertScrollBar();
78 if (IsShowVertScrollBar() && vertSB) {
79 CFX_RectF rect = vertSB->GetWidgetRect();
80 if (rect.Contains(pMsg->m_pos)) {
81 pMsg->m_pos -= rect.TopLeft();
82 vertSB->GetDelegate()->OnProcessMessage(pMsg);
83 return;
84 }
85 }
86 switch (pMsg->m_dwCmd) {
87 case CFWL_MessageMouse::MouseCommand::kMove:
88 backDefault = false;
89 OnDropListMouseMove(pMsg);
90 break;
91 case CFWL_MessageMouse::MouseCommand::kLeftButtonDown:
92 backDefault = false;
93 OnDropListLButtonDown(pMsg);
94 break;
95 case CFWL_MessageMouse::MouseCommand::kLeftButtonUp:
96 backDefault = false;
97 OnDropListLButtonUp(pMsg);
98 break;
99 default:
100 break;
101 }
102 } else if (type == CFWL_Message::Type::kKey) {
103 backDefault = !OnDropListKey(static_cast<CFWL_MessageKey*>(pMessage));
104 }
105 if (backDefault)
107}
108
109void CFWL_ComboList::OnDropListFocusChanged(CFWL_Message* pMsg, bool bSet) {
110 if (bSet)
111 return;
112
113 CFWL_MessageKillFocus* pKill = static_cast<CFWL_MessageKillFocus*>(pMsg);
114 CFWL_ComboBox* pOuter = static_cast<CFWL_ComboBox*>(GetOuter());
115 if (pKill->IsFocusedOnWidget(pOuter) ||
118 }
119}
120
121void CFWL_ComboList::OnDropListMouseMove(CFWL_MessageMouse* pMsg) {
122 if (GetRTClient().Contains(pMsg->m_pos)) {
123 if (m_bNotifyOwner)
124 m_bNotifyOwner = false;
125
126 CFWL_ScrollBar* vertSB = GetVertScrollBar();
127 if (IsShowVertScrollBar() && vertSB) {
128 CFX_RectF rect = vertSB->GetWidgetRect();
129 if (rect.Contains(pMsg->m_pos))
130 return;
131 }
132
133 CFWL_ListBox::Item* hItem = GetItemAtPoint(pMsg->m_pos);
134 if (!hItem)
135 return;
136
137 ChangeSelected(GetItemIndex(this, hItem));
138 } else if (m_bNotifyOwner) {
139 pMsg->m_pos = ClientToOuter(pMsg->m_pos);
140
141 CFWL_ComboBox* pOuter = static_cast<CFWL_ComboBox*>(GetOuter());
142 pOuter->GetDelegate()->OnProcessMessage(pMsg);
143 }
144}
145
146void CFWL_ComboList::OnDropListLButtonDown(CFWL_MessageMouse* pMsg) {
147 if (GetRTClient().Contains(pMsg->m_pos))
148 return;
149
150 CFWL_ComboBox* pOuter = static_cast<CFWL_ComboBox*>(GetOuter());
152}
153
154void CFWL_ComboList::OnDropListLButtonUp(CFWL_MessageMouse* pMsg) {
155 CFWL_ComboBox* pOuter = static_cast<CFWL_ComboBox*>(GetOuter());
156 if (m_bNotifyOwner) {
157 pMsg->m_pos = ClientToOuter(pMsg->m_pos);
158 pOuter->GetDelegate()->OnProcessMessage(pMsg);
159 return;
160 }
161
162 CFWL_ScrollBar* vertSB = GetVertScrollBar();
163 if (IsShowVertScrollBar() && vertSB) {
164 CFX_RectF rect = vertSB->GetWidgetRect();
165 if (rect.Contains(pMsg->m_pos))
166 return;
167 }
169
170 CFWL_ListBox::Item* hItem = GetItemAtPoint(pMsg->m_pos);
171 if (hItem)
172 pOuter->ProcessSelChanged(true);
173}
174
175bool CFWL_ComboList::OnDropListKey(CFWL_MessageKey* pKey) {
176 CFWL_ComboBox* pOuter = static_cast<CFWL_ComboBox*>(GetOuter());
177 bool bPropagate = false;
178 if (pKey->m_dwCmd == CFWL_MessageKey::KeyCommand::kKeyDown) {
179 uint32_t dwKeyCode = pKey->m_dwKeyCodeOrChar;
180 switch (dwKeyCode) {
182 case XFA_FWL_VKEY_Escape: {
184 return true;
185 }
186 case XFA_FWL_VKEY_Up:
187 case XFA_FWL_VKEY_Down: {
188 OnDropListKeyDown(pKey);
189 pOuter->ProcessSelChanged(false);
190 return true;
191 }
192 default: {
193 bPropagate = true;
194 break;
195 }
196 }
197 } else if (pKey->m_dwCmd == CFWL_MessageKey::KeyCommand::kChar) {
198 bPropagate = true;
199 }
200 if (bPropagate) {
202 pOuter->GetDelegate()->OnProcessMessage(pKey);
203 return true;
204 }
205 return false;
206}
207
208void CFWL_ComboList::OnDropListKeyDown(CFWL_MessageKey* pKey) {
209 auto dwKeyCode = static_cast<XFA_FWL_VKEYCODE>(pKey->m_dwKeyCodeOrChar);
210 switch (dwKeyCode) {
211 case XFA_FWL_VKEY_Up:
214 case XFA_FWL_VKEY_End: {
215 CFWL_ComboBox* pOuter = static_cast<CFWL_ComboBox*>(GetOuter());
216 CFWL_ListBox::Item* hItem = GetItem(this, pOuter->GetCurrentSelection());
217 hItem = GetListItem(hItem, dwKeyCode);
218 if (!hItem)
219 break;
220
221 SetSelection(hItem, hItem, true);
222 ScrollToVisible(hItem);
224 break;
225 }
226 default:
227 break;
228 }
229}
void ProcessSelChanged(bool bLButtonUp)
CFWL_ComboEdit * GetComboEdit() const
int32_t GetCurrentSelection() const
~CFWL_ComboList() override
void ChangeSelected(int32_t iSel)
void OnProcessMessage(CFWL_Message *pMessage) override
int32_t MatchItem(WideStringView wsMatch)
CFX_RectF GetRect() const
WideString GetText() const
void SetSelItem(Item *hItem, bool bSelect)
Item * GetSelItem(int32_t nIndexSel)
int32_t CountItems(const CFWL_Widget *pWidget) const
bool ScrollToVisible(Item *hItem)
int32_t GetItemIndex(CFWL_Widget *pWidget, Item *pItem)
void SetSelection(Item *hStart, Item *hEnd, bool bSelected)
bool IsShowVertScrollBar() const
Item * GetItem(const CFWL_Widget *pWidget, int32_t nIndex) const
Item * GetListItem(Item *hItem, XFA_FWL_VKEYCODE dwKeyCode)
void OnProcessMessage(CFWL_Message *pMessage) override
Item * GetItemAtPoint(const CFX_PointF &point)
CFWL_ScrollBar * GetVertScrollBar() const
CFWL_ListBox(CFWL_App *pApp, const Properties &properties, CFWL_Widget *pOuter)
const CFX_RectF & GetRTClient() const
const KeyCommand m_dwCmd
const uint32_t m_dwKeyCodeOrChar
bool IsFocusedOnWidget(const CFWL_Widget *pWidget) const
const MouseCommand m_dwCmd
Type GetType() const
void SetDstTarget(CFWL_Widget *pWidget)
CFWL_Widget * GetOuter() const
CFX_RectF m_WidgetRect
void RepaintRect(const CFX_RectF &pRect)
virtual CFX_RectF GetWidgetRect()
bool IsEmpty() const
CFX_RectF & operator=(const CFX_RectF &other)=default
constexpr CFX_RectF(float dst_left, float dst_top, float dst_width, float dst_height)
void Union(const CFX_RectF &rt)
XFA_FWL_VKEYCODE
@ XFA_FWL_VKEY_Down
@ XFA_FWL_VKEY_Home
@ XFA_FWL_VKEY_Escape
@ XFA_FWL_VKEY_End
@ XFA_FWL_VKEY_Return
@ XFA_FWL_VKEY_Up