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