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
qwasmwindowstack.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
5
7
8QWasmWindowStack::QWasmWindowStack(WindowOrderChangedCallbackType windowOrderChangedCallback)
9 : m_windowOrderChangedCallback(std::move(windowOrderChangedCallback)),
10 m_regularWindowsBegin(m_windowStack.begin()),
11 m_alwaysOnTopWindowsBegin(m_windowStack.begin())
12{
13}
14
15QWasmWindowStack::~QWasmWindowStack() = default;
16
17void QWasmWindowStack::pushWindow(QWasmWindow *window, PositionPreference position)
18{
19 Q_ASSERT(m_windowStack.count(window) == 0);
20
21 if (position == PositionPreference::StayOnTop) {
22 const auto stayOnTopDistance =
23 std::distance(m_windowStack.begin(), m_alwaysOnTopWindowsBegin);
24 const auto regularDistance = std::distance(m_windowStack.begin(), m_regularWindowsBegin);
25 m_windowStack.push_back(window);
26 m_alwaysOnTopWindowsBegin = m_windowStack.begin() + stayOnTopDistance;
27 m_regularWindowsBegin = m_windowStack.begin() + regularDistance;
28 } else if (position == PositionPreference::Regular) {
29 const auto regularDistance = std::distance(m_windowStack.begin(), m_regularWindowsBegin);
30 m_alwaysOnTopWindowsBegin = m_windowStack.insert(m_alwaysOnTopWindowsBegin, window) + 1;
31 m_regularWindowsBegin = m_windowStack.begin() + regularDistance;
32 } else {
33 const auto stayOnTopDistance =
34 std::distance(m_windowStack.begin(), m_alwaysOnTopWindowsBegin);
35 m_regularWindowsBegin = m_windowStack.insert(m_regularWindowsBegin, window) + 1;
36 m_alwaysOnTopWindowsBegin = m_windowStack.begin() + stayOnTopDistance + 1;
37 }
38
39 m_windowOrderChangedCallback();
40}
41
42void QWasmWindowStack::removeWindow(QWasmWindow *window)
43{
44 Q_ASSERT(m_windowStack.count(window) == 1);
45
46 auto it = std::find(m_windowStack.begin(), m_windowStack.end(), window);
47 const auto position = getWindowPositionPreference(it);
48 const auto stayOnTopDistance = std::distance(m_windowStack.begin(), m_alwaysOnTopWindowsBegin);
49 const auto regularDistance = std::distance(m_windowStack.begin(), m_regularWindowsBegin);
50
51 m_windowStack.erase(it);
52
53 m_alwaysOnTopWindowsBegin = m_windowStack.begin() + stayOnTopDistance
54 - (position != PositionPreference::StayOnTop ? 1 : 0);
55 m_regularWindowsBegin = m_windowStack.begin() + regularDistance
56 - (position == PositionPreference::StayOnBottom ? 1 : 0);
57
58 m_windowOrderChangedCallback();
59}
60
61void QWasmWindowStack::raise(QWasmWindow *window)
62{
63 Q_ASSERT(m_windowStack.count(window) == 1);
64
65 if (window == topWindow())
66 return;
67
68 auto it = std::find(m_windowStack.begin(), m_windowStack.end(), window);
69 auto itEnd = ([this, position = getWindowPositionPreference(it)]() {
70 switch (position) {
71 case PositionPreference::StayOnTop:
72 return m_windowStack.end();
73 case PositionPreference::Regular:
74 return m_alwaysOnTopWindowsBegin;
75 case PositionPreference::StayOnBottom:
76 return m_regularWindowsBegin;
77 }
78 })();
79 std::rotate(it, it + 1, itEnd);
80 m_windowOrderChangedCallback();
81}
82
83void QWasmWindowStack::lower(QWasmWindow *window)
84{
85 Q_ASSERT(m_windowStack.count(window) == 1);
86
87 if (window == *m_windowStack.begin())
88 return;
89
90 auto it = std::find(m_windowStack.begin(), m_windowStack.end(), window);
91 auto itBegin = ([this, position = getWindowPositionPreference(it)]() {
92 switch (position) {
93 case PositionPreference::StayOnTop:
94 return m_alwaysOnTopWindowsBegin;
95 case PositionPreference::Regular:
96 return m_regularWindowsBegin;
97 case PositionPreference::StayOnBottom:
98 return m_windowStack.begin();
99 }
100 })();
101
102 std::rotate(itBegin, it, it + 1);
103 m_windowOrderChangedCallback();
104}
105
106void QWasmWindowStack::windowPositionPreferenceChanged(QWasmWindow *window,
107 PositionPreference position)
108{
109 auto it = std::find(m_windowStack.begin(), m_windowStack.end(), window);
110 const auto currentPosition = getWindowPositionPreference(it);
111
112 const auto zones = static_cast<int>(position) - static_cast<int>(currentPosition);
113 Q_ASSERT(zones != 0);
114
115 if (zones < 0) {
116 // Perform right rotation so that the window lands on top of regular windows
117 const auto begin = std::make_reverse_iterator(it + 1);
118 const auto end = position == PositionPreference::Regular
119 ? std::make_reverse_iterator(m_alwaysOnTopWindowsBegin)
120 : std::make_reverse_iterator(m_regularWindowsBegin);
121 std::rotate(begin, begin + 1, end);
122 if (zones == -2) {
123 ++m_alwaysOnTopWindowsBegin;
124 ++m_regularWindowsBegin;
125 } else if (position == PositionPreference::Regular) {
126 ++m_alwaysOnTopWindowsBegin;
127 } else {
128 ++m_regularWindowsBegin;
129 }
130 } else {
131 // Perform left rotation so that the window lands at the bottom of always on top windows
132 const auto begin = it;
133 const auto end = position == PositionPreference::Regular ? m_regularWindowsBegin
134 : m_alwaysOnTopWindowsBegin;
135 std::rotate(begin, begin + 1, end);
136 if (zones == 2) {
137 --m_alwaysOnTopWindowsBegin;
138 --m_regularWindowsBegin;
139 } else if (position == PositionPreference::Regular) {
140 --m_regularWindowsBegin;
141 } else {
142 --m_alwaysOnTopWindowsBegin;
143 }
144 }
145 m_windowOrderChangedCallback();
146}
147
148QWasmWindowStack::iterator QWasmWindowStack::begin()
149{
150 return m_windowStack.rbegin();
151}
152
153QWasmWindowStack::iterator QWasmWindowStack::end()
154{
155 return m_windowStack.rend();
156}
157
158QWasmWindowStack::const_iterator QWasmWindowStack::begin() const
159{
160 return m_windowStack.rbegin();
161}
162
163QWasmWindowStack::const_iterator QWasmWindowStack::end() const
164{
165 return m_windowStack.rend();
166}
167
168QWasmWindowStack::const_reverse_iterator QWasmWindowStack::rbegin() const
169{
170 return m_windowStack.begin();
171}
172
173QWasmWindowStack::const_reverse_iterator QWasmWindowStack::rend() const
174{
175 return m_windowStack.end();
176}
177
178bool QWasmWindowStack::empty() const
179{
180 return m_windowStack.empty();
181}
182
183size_t QWasmWindowStack::size() const
184{
185 return m_windowStack.size();
186}
187
188QWasmWindow *QWasmWindowStack::topWindow() const
189{
190 return m_windowStack.empty() ? nullptr : m_windowStack.last();
191}
192
193QWasmWindowStack::PositionPreference
194QWasmWindowStack::getWindowPositionPreference(StorageType::iterator windowIt) const
195{
196 if (windowIt >= m_alwaysOnTopWindowsBegin)
197 return PositionPreference::StayOnTop;
198 if (windowIt >= m_regularWindowsBegin)
199 return PositionPreference::Regular;
200 return PositionPreference::StayOnBottom;
201}
202
203QT_END_NAMESPACE
Combined button and popup list for selecting options.