1// Copyright 2016 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#include "xfa/fwl/cfwl_comboboxproxy.h"
8
9#include <memory>
10#include <utility>
11
12#include "xfa/fwl/cfwl_app.h"
13#include "xfa/fwl/cfwl_combobox.h"
14#include "xfa/fwl/cfwl_messagekillfocus.h"
15#include "xfa/fwl/cfwl_messagemouse.h"
16#include "xfa/fwl/cfwl_notedriver.h"
17
18CFWL_ComboBoxProxy::CFWL_ComboBoxProxy(
19    CFWL_ComboBox* pComboBox,
20    const CFWL_App* app,
21    std::unique_ptr<CFWL_WidgetProperties> properties,
22    CFWL_Widget* pOuter)
23    : CFWL_FormProxy(app, std::move(properties), pOuter),
24      m_bLButtonDown(false),
25      m_bLButtonUpSelf(false),
26      m_pComboBox(pComboBox) {}
27
28CFWL_ComboBoxProxy::~CFWL_ComboBoxProxy() {}
29
30void CFWL_ComboBoxProxy::OnProcessMessage(CFWL_Message* pMessage) {
31  if (!pMessage)
32    return;
33
34  switch (pMessage->GetType()) {
35    case CFWL_Message::Type::Mouse: {
36      CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage);
37      switch (pMsg->m_dwCmd) {
38        case FWL_MouseCommand::LeftButtonDown:
39          OnLButtonDown(pMsg);
40          break;
41        case FWL_MouseCommand::LeftButtonUp:
42          OnLButtonUp(pMsg);
43          break;
44        default:
45          break;
46      }
47      break;
48    }
49    case CFWL_Message::Type::KillFocus:
50      OnFocusChanged(pMessage, false);
51      break;
52    case CFWL_Message::Type::SetFocus:
53      OnFocusChanged(pMessage, true);
54      break;
55    default:
56      break;
57  }
58  CFWL_Widget::OnProcessMessage(pMessage);
59}
60
61void CFWL_ComboBoxProxy::OnDrawWidget(CFX_Graphics* pGraphics,
62                                      const CFX_Matrix* pMatrix) {
63  m_pComboBox->DrawStretchHandler(pGraphics, pMatrix);
64}
65
66void CFWL_ComboBoxProxy::OnLButtonDown(CFWL_Message* pMessage) {
67  const CFWL_App* pApp = GetOwnerApp();
68  if (!pApp)
69    return;
70
71  CFWL_NoteDriver* pDriver =
72      static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver());
73  CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage);
74  if (CFX_RectF(0, 0, GetWidgetRect().Size()).Contains(pMsg->m_pos)) {
75    m_bLButtonDown = true;
76    pDriver->SetGrab(this, true);
77  } else {
78    m_bLButtonDown = false;
79    pDriver->SetGrab(this, false);
80    m_pComboBox->ShowDropList(false);
81  }
82}
83
84void CFWL_ComboBoxProxy::OnLButtonUp(CFWL_Message* pMessage) {
85  m_bLButtonDown = false;
86  const CFWL_App* pApp = GetOwnerApp();
87  if (!pApp)
88    return;
89
90  CFWL_NoteDriver* pDriver =
91      static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver());
92  pDriver->SetGrab(this, false);
93  if (!m_bLButtonUpSelf) {
94    m_bLButtonUpSelf = true;
95    return;
96  }
97
98  CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage);
99  if (!CFX_RectF(0, 0, GetWidgetRect().Size()).Contains(pMsg->m_pos) &&
100      m_pComboBox->IsDropListVisible()) {
101    m_pComboBox->ShowDropList(false);
102  }
103}
104
105void CFWL_ComboBoxProxy::OnFocusChanged(CFWL_Message* pMessage, bool bSet) {
106  if (bSet)
107    return;
108
109  CFWL_MessageKillFocus* pMsg = static_cast<CFWL_MessageKillFocus*>(pMessage);
110  if (!pMsg->m_pSetFocus)
111    m_pComboBox->ShowDropList(false);
112}
113