1// Copyright 2014 PDFium Authors. All rights reserved.
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#ifndef XFA_FWL_CFWL_COMBOBOX_H_
8#define XFA_FWL_CFWL_COMBOBOX_H_
9
10#include <memory>
11
12#include "xfa/fwl/cfwl_comboboxproxy.h"
13#include "xfa/fwl/cfwl_comboedit.h"
14#include "xfa/fwl/cfwl_combolist.h"
15#include "xfa/fwl/cfwl_form.h"
16#include "xfa/fwl/cfwl_listbox.h"
17#include "xfa/fxgraphics/cfx_graphics.h"
18
19class CFWL_WidgetProperties;
20class CFWL_ComboBox;
21class CFWL_ComboBoxProxy;
22class CFWL_FormProxy;
23class CFWL_ListBox;
24class CFWL_Widget;
25
26#define FWL_STYLEEXT_CMB_DropDown (1L << 0)
27#define FWL_STYLEEXT_CMB_Sort (1L << 1)
28#define FWL_STYLEEXT_CMB_OwnerDraw (1L << 3)
29#define FWL_STYLEEXT_CMB_EditHNear 0
30#define FWL_STYLEEXT_CMB_EditHCenter (1L << 4)
31#define FWL_STYLEEXT_CMB_EditVNear 0
32#define FWL_STYLEEXT_CMB_EditVCenter (1L << 6)
33#define FWL_STYLEEXT_CMB_EditVFar (2L << 6)
34#define FWL_STYLEEXT_CMB_EditJustified (1L << 8)
35#define FWL_STYLEEXT_CMB_EditHAlignMask (3L << 4)
36#define FWL_STYLEEXT_CMB_EditVAlignMask (3L << 6)
37#define FWL_STYLEEXT_CMB_ListItemLeftAlign 0
38#define FWL_STYLEEXT_CMB_ListItemCenterAlign (1L << 10)
39#define FWL_STYLEEXT_CMB_ListItemAlignMask (3L << 10)
40#define FWL_STYLEEXT_CMB_ReadOnly (1L << 13)
41
42class CFWL_ComboBox : public CFWL_Widget {
43 public:
44  explicit CFWL_ComboBox(const CFWL_App* pApp);
45  ~CFWL_ComboBox() override;
46
47  // CFWL_Widget
48  FWL_Type GetClassID() const override;
49  void ModifyStylesEx(uint32_t dwStylesExAdded,
50                      uint32_t dwStylesExRemoved) override;
51  void SetStates(uint32_t dwStates) override;
52  void RemoveStates(uint32_t dwStates) override;
53  void Update() override;
54  FWL_WidgetHit HitTest(const CFX_PointF& point) override;
55  void DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) override;
56  void SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) override;
57  void OnProcessMessage(CFWL_Message* pMessage) override;
58  void OnProcessEvent(CFWL_Event* pEvent) override;
59  void OnDrawWidget(CFX_Graphics* pGraphics,
60                    const CFX_Matrix* pMatrix) override;
61
62  CFX_WideString GetTextByIndex(int32_t iIndex) const;
63  int32_t GetCurSel() const { return m_iCurSel; }
64  void SetCurSel(int32_t iSel);
65
66  void AddString(const CFX_WideStringC& wsText);
67  void RemoveAt(int32_t iIndex);
68  void RemoveAll();
69
70  void SetEditText(const CFX_WideString& wsText);
71  CFX_WideString GetEditText() const;
72
73  void OpenDropDownList(bool bActivate);
74
75  bool EditCanUndo() const { return m_pEdit->CanUndo(); }
76  bool EditCanRedo() const { return m_pEdit->CanRedo(); }
77  bool EditUndo() { return m_pEdit->Undo(); }
78  bool EditRedo() { return m_pEdit->Redo(); }
79  bool EditCanCopy() const { return m_pEdit->CountSelRanges() > 0; }
80  bool EditCanCut() const {
81    if (m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly)
82      return false;
83    return EditCanCopy();
84  }
85  bool EditCanSelectAll() const { return m_pEdit->GetTextLength() > 0; }
86  bool EditCopy(CFX_WideString& wsCopy) const { return m_pEdit->Copy(wsCopy); }
87  bool EditCut(CFX_WideString& wsCut) { return m_pEdit->Cut(wsCut); }
88  bool EditPaste(const CFX_WideString& wsPaste) {
89    return m_pEdit->Paste(wsPaste);
90  }
91  void EditSelectAll() { m_pEdit->AddSelRange(0); }
92  void EditDelete() { m_pEdit->ClearText(); }
93  void EditDeSelect() { m_pEdit->ClearSelections(); }
94
95  CFX_RectF GetBBox() const;
96  void EditModifyStylesEx(uint32_t dwStylesExAdded, uint32_t dwStylesExRemoved);
97
98  void DrawStretchHandler(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix);
99  bool IsDropListVisible() const {
100    return m_pComboBoxProxy &&
101           !(m_pComboBoxProxy->GetStates() & FWL_WGTSTATE_Invisible);
102  }
103  void ShowDropList(bool bActivate);
104
105  CFWL_ComboEdit* GetComboEdit() const { return m_pEdit.get(); }
106
107  void ProcessSelChanged(bool bLButtonUp);
108  int32_t GetCurrentSelection() const { return m_iCurSel; }
109
110 private:
111  bool IsDropDownStyle() const {
112    return !!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown);
113  }
114  void MatchEditText();
115  void SyncEditText(int32_t iListItem);
116  void Layout();
117  void ResetTheme();
118  void ResetEditAlignment();
119  void ResetListItemAlignment();
120  void InitProxyForm();
121  void OnFocusChanged(CFWL_Message* pMsg, bool bSet);
122  void OnLButtonDown(CFWL_MessageMouse* pMsg);
123  void OnLButtonUp(CFWL_MessageMouse* pMsg);
124  void OnMouseMove(CFWL_MessageMouse* pMsg);
125  void OnMouseLeave(CFWL_MessageMouse* pMsg);
126  void OnKey(CFWL_MessageKey* pMsg);
127  void DoSubCtrlKey(CFWL_MessageKey* pMsg);
128
129  void DisForm_InitComboList();
130  void DisForm_InitComboEdit();
131  void DisForm_ShowDropList(bool bActivate);
132  bool DisForm_IsDropListVisible() const {
133    return !(m_pListBox->GetStates() & FWL_WGTSTATE_Invisible);
134  }
135  void DisForm_ModifyStylesEx(uint32_t dwStylesExAdded,
136                              uint32_t dwStylesExRemoved);
137  void DisForm_Update();
138  FWL_WidgetHit DisForm_HitTest(const CFX_PointF& point);
139  void DisForm_DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix);
140  CFX_RectF DisForm_GetBBox() const;
141  void DisForm_Layout();
142  void DisForm_OnProcessMessage(CFWL_Message* pMessage);
143  void DisForm_OnLButtonDown(CFWL_MessageMouse* pMsg);
144  void DisForm_OnFocusChanged(CFWL_Message* pMsg, bool bSet);
145  void DisForm_OnKey(CFWL_MessageKey* pMsg);
146
147  CFX_RectF m_rtClient;
148  CFX_RectF m_rtContent;
149  CFX_RectF m_rtBtn;
150  CFX_RectF m_rtList;
151  CFX_RectF m_rtProxy;
152  CFX_RectF m_rtHandler;
153  std::unique_ptr<CFWL_ComboEdit> m_pEdit;
154  std::unique_ptr<CFWL_ComboList> m_pListBox;
155  CFWL_ComboBoxProxy* m_pComboBoxProxy;  // Can this be a unique_ptr?
156  bool m_bLButtonDown;
157  int32_t m_iCurSel;
158  int32_t m_iBtnState;
159};
160
161#endif  // XFA_FWL_CFWL_COMBOBOX_H_
162