source: filezilla/trunk/fuentes/src/interface/drop_target_ex.cpp @ 130

Last change on this file since 130 was 130, checked in by jrpelegrina, 4 years ago

First release to xenial

File size: 4.0 KB
Line 
1#include <filezilla.h>
2#include "drop_target_ex.h"
3
4#include "listctrlex.h"
5#include "treectrlex.h"
6
7template<class Control>
8CScrollableDropTarget<Control>::CScrollableDropTarget(Control* pCtrl)
9        : m_pCtrl(pCtrl)
10        , m_count()
11{
12        m_timer.SetOwner(this);
13}
14
15
16template<class Control>
17bool CScrollableDropTarget<Control>::OnDrop(wxCoord, wxCoord)
18{
19        m_timer.Stop();
20        return true;
21}
22
23template<class Control>
24wxDragResult CScrollableDropTarget<Control>::OnDragOver(wxCoord x, wxCoord y, wxDragResult def)
25{
26        def = FixupDragResult(def);
27        if (!m_timer.IsRunning() && IsScroll(wxPoint(x, y))) {
28                m_timer.Start(100, true);
29                m_count = 0;
30        }
31        return def;
32}
33
34template<class Control>
35void CScrollableDropTarget<Control>::OnLeave()
36{
37        m_timer.Stop();
38}
39
40template<class Control>
41wxDragResult CScrollableDropTarget<Control>::OnEnter(wxCoord x, wxCoord y, wxDragResult def)
42{
43        def = FixupDragResult(def);
44        if (!m_timer.IsRunning() && IsScroll(wxPoint(x, y))) {
45                m_timer.Start(100, true);
46                m_count = 0;
47        }
48        return def;
49}
50
51template<class Control>
52bool CScrollableDropTarget<Control>::IsScroll(wxPoint p) const
53{
54        return IsTopScroll(p) || IsBottomScroll(p);
55}
56
57template<class Control>
58bool CScrollableDropTarget<Control>::IsTopScroll(wxPoint p) const
59{
60        if (!m_pCtrl->GetItemCount()) {
61                return false;
62        }
63
64        wxRect itemRect;
65        if (!m_pCtrl->GetItemRect(m_pCtrl->GetTopItem(), itemRect))
66                return false;
67
68        wxRect windowRect = m_pCtrl->GetActualClientRect();
69
70        if (itemRect.GetTop() < 0) {
71                itemRect.SetTop(0);
72        }
73        if (itemRect.GetHeight() > windowRect.GetHeight() / 4) {
74                itemRect.SetHeight(wxMax(windowRect.GetHeight() / 4, 8));
75        }
76
77        if (p.y < 0 || p.y >= itemRect.GetBottom())
78                return false;
79
80        if (p.x < 0 || p.x > windowRect.GetWidth())
81                return false;
82
83        auto top = m_pCtrl->GetTopItem();
84        if (!m_pCtrl->Valid(top) || top == m_pCtrl->GetFirstItem()) {
85                return false;
86        }
87
88        wxASSERT(m_pCtrl->GetTopItem() != m_pCtrl->GetFirstItem());
89
90        return true;
91}
92
93template<class Control>
94bool CScrollableDropTarget<Control>::IsBottomScroll(wxPoint p) const
95{
96        if (!m_pCtrl->GetItemCount()) {
97                return false;
98        }
99
100        wxRect itemRect;
101        if (!m_pCtrl->GetItemRect(m_pCtrl->GetFirstItem(), itemRect))
102                return false;
103
104        wxRect const windowRect = m_pCtrl->GetActualClientRect();
105
106        int scrollHeight = itemRect.GetHeight();
107        if (scrollHeight > windowRect.GetHeight() / 4) {
108                scrollHeight = wxMax(windowRect.GetHeight() / 4, 8);
109        }
110
111        if (p.y > windowRect.GetBottom() || p.y < windowRect.GetBottom() - scrollHeight)
112                return false;
113
114        if (p.x < 0 || p.x > windowRect.GetWidth())
115                return false;
116
117        auto bottom = m_pCtrl->GetBottomItem();
118        if (!m_pCtrl->Valid(bottom) || bottom == m_pCtrl->GetLastItem()) {
119                return false;
120        }
121
122        wxASSERT(m_pCtrl->GetLastItem() != m_pCtrl->GetBottomItem());
123
124        return true;
125}
126
127template<class Control>
128void CScrollableDropTarget<Control>::OnTimer(wxTimerEvent& /*event*/)
129{
130        if (!m_pCtrl->GetItemCount()) {
131                return;
132        }
133
134        wxPoint p = wxGetMousePosition();
135        wxWindow* ctrl = m_pCtrl->GetMainWindow();
136        p = ctrl->ScreenToClient(p);
137
138        if (IsTopScroll(p)) {
139                auto top = m_pCtrl->GetTopItem();
140                wxASSERT(m_pCtrl->Valid(top));
141                wxASSERT(top != m_pCtrl->GetFirstItem());
142                m_pCtrl->EnsureVisible(m_pCtrl->GetPrevItemSimple(top));
143        }
144        else if (IsBottomScroll(p)) {
145                auto bottom = m_pCtrl->GetBottomItem();
146                wxASSERT(m_pCtrl->Valid(bottom));
147                wxASSERT(bottom != m_pCtrl->GetLastItem());
148                m_pCtrl->EnsureVisible(m_pCtrl->GetNextItemSimple(bottom));
149        }
150        else {
151                return;
152        }
153
154        DisplayDropHighlight(p);
155
156        if (m_count < 90)
157                ++m_count;
158        m_timer.Start(100 - m_count, true);
159}
160
161template<class Control>
162wxDragResult CScrollableDropTarget<Control>::FixupDragResult(wxDragResult res)
163{
164#ifdef __WXMAC__
165        if (res == wxDragNone && wxGetKeyState(WXK_CONTROL)) {
166                res = wxDragCopy;
167        }
168#endif
169
170        if (res == wxDragLink) {
171                res = wxGetKeyState(WXK_CONTROL) ? wxDragCopy : wxDragMove;
172        }
173
174        return res;
175}
176
177BEGIN_EVENT_TABLE_TEMPLATE1(CScrollableDropTarget, wxEvtHandler, Control)
178EVT_TIMER(wxID_ANY, CScrollableDropTarget::OnTimer)
179END_EVENT_TABLE()
180
181template class CScrollableDropTarget<wxTreeCtrlEx>;
182template class CScrollableDropTarget<wxListCtrlEx>;
Note: See TracBrowser for help on using the repository browser.