GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
dxlib_gui_updater.cpp
[詳解]
1
3
4// Copyright(c) 2023-2025 Design Engineering Laboratory, Saitama University
5// Released under the MIT license
6// https://opensource.org/licenses/mit-license.php
7
8#include "dxlib_gui_updater.h"
9
10#include <vector>
11
12#include <DxLib.h>
13
14#include "dxlib_gui_terminal.h"
15
16
17
18namespace designlab
19{
20
22{
23 // 2回以上呼ばれたら何もしない.
24 if (is_terminal_opened_)
25 {
26 return;
27 }
28
29 // ターミナルに渡すGUIのリストを作成.
30 std::vector<std::shared_ptr<IDxlibGui> > gui_list;
31
32 for (const auto& i : gui_ptrs_)
33 {
34 gui_list.push_back(i.second);
35 }
36
37 // ターミナルを登録.
38 const auto terminal_ptr = std::make_shared<DxlibGuiTerminal>(gui_list);
39 const int terminal_priority = kTopPriority + 1;
40
41 RegisterGui(terminal_ptr, terminal_priority);
42 RegisterClickable(terminal_ptr, terminal_priority);
43
44 is_terminal_opened_ = true;
45}
46
47void DxlibGuiUpdater::Activate(const std::shared_ptr<const Mouse>& mouse_ptr)
48{
49 assert(mouse_ptr != nullptr);
50
51 UpdateGui();
52 ActivateClickable(mouse_ptr);
53 ActivateDraggable(mouse_ptr);
54 ActivateWheelHandler(mouse_ptr);
55}
56
58{
59 // 昇順にDrawする.
60 for (auto i = gui_ptrs_.begin(); i != gui_ptrs_.end(); ++i)
61 {
62 if ((*i).second->IsVisible())
63 {
64 (*i).second->Draw();
65 }
66 }
67}
68
69
70void DxlibGuiUpdater::RegisterGui(
71 const std::shared_ptr<IDxlibGui> gui_ptr, int priority)
72{
73 assert(gui_ptr != nullptr);
74
75 // すでに同じポインタが登録されていたら何もしない.
76 for (const auto& i : gui_ptrs_)
77 {
78 if (i.second == gui_ptr)
79 {
80 return;
81 }
82 }
83
84 // すでに同じ優先度のものがあったら,orderを1つずつずらす.
85 Priority p{ priority, 0 };
86
87 while (gui_ptrs_.find(p) != gui_ptrs_.end())
88 {
89 p.order++;
90 }
91
92 // 登録.
93 gui_ptrs_[p] = gui_ptr;
94}
95
96void DxlibGuiUpdater::RegisterClickable(
97 const std::shared_ptr<IDxlibClickable> clickable_ptr, int priority)
98{
99 assert(clickable_ptr != nullptr);
100
101 // すでに同じポインタが登録されていたら何もしない.
102 for (const auto& i : clickable_ptrs_)
103 {
104 if (i.second == clickable_ptr)
105 {
106 return;
107 }
108 }
109
110 // すでに同じ優先度のものがあったら,orderを1つずつずらす.
111 Priority p{ priority, 0 };
112
113 while (clickable_ptrs_.find(p) != clickable_ptrs_.end())
114 {
115 p.order++;
116 }
117
118 // 登録.
119 clickable_ptrs_[p] = clickable_ptr;
120}
121
122void DxlibGuiUpdater::RegisterDraggable(
123 const std::shared_ptr<IDxlibDraggable> draggable_ptr, int priority)
124{
125 assert(draggable_ptr != nullptr);
126
127 // すでに同じポインタが登録されていたら何もしない.
128 for (const auto& i : draggable_ptrs_)
129 {
130 if (i.second == draggable_ptr)
131 {
132 return;
133 }
134 }
135
136 // すでに同じ優先度のものがあったら,orderを1つずつずらす.
137 Priority p{ priority, 0 };
138
139 while (draggable_ptrs_.find(p) != draggable_ptrs_.end())
140 {
141 p.order++;
142 }
143
144 // 登録.
145 draggable_ptrs_[p] = draggable_ptr;
146}
147
148void DxlibGuiUpdater::RegisterWheelHandler(
149 const std::shared_ptr<IDxlibWheelHandler> wheel_handler_ptr, int priority)
150{
151 assert(wheel_handler_ptr != nullptr);
152
153 // すでに同じポインタが登録されていたら何もしない.
154 for (const auto& i : wheel_handler_ptrs_)
155 {
156 if (i.second == wheel_handler_ptr)
157 {
158 return;
159 }
160 }
161
162 // すでに同じ優先度のものがあったら,orderを1つずつずらす.
163 Priority p{ priority, 0 };
164
165 while (wheel_handler_ptrs_.find(p) != wheel_handler_ptrs_.end())
166 {
167 p.order++;
168 }
169
170 // 登録.
171 wheel_handler_ptrs_[p] = wheel_handler_ptr;
172}
173
174void DxlibGuiUpdater::UpdateGui()
175{
176 // 逆順にUpdateする.
177 for (auto i = gui_ptrs_.rbegin(); i != gui_ptrs_.rend(); ++i)
178 {
179 (*i).second->Update();
180 }
181}
182
183void DxlibGuiUpdater::ActivateClickable(const std::shared_ptr<const Mouse> mouse_ptr)
184{
185 // 優先度の高いものから順にクリック判定を行う.
186 // 昇順(増える順)に並んでいるので,rbegin から rend まで(降順に)走査する.
187
188 for (auto i = clickable_ptrs_.rbegin(); i != clickable_ptrs_.rend(); ++i)
189 {
190 if ((*i).second->CursorOnGui(
191 mouse_ptr->GetCursorPosX(),
192 mouse_ptr->GetCursorPosY()))
193 {
194 (*i).second->ClickedAction({
195 .cursor_x = mouse_ptr->GetCursorPosX(),
196 .cursor_y = mouse_ptr->GetCursorPosY(),
197 .left_pushing_count =
198 mouse_ptr->GetPressingCount(MOUSE_INPUT_LEFT),
199 .middle_pushing_count =
200 mouse_ptr->GetReleasingCount(MOUSE_INPUT_MIDDLE),
201 .right_pushing_count =
202 mouse_ptr->GetPressingCount(MOUSE_INPUT_RIGHT) });
203
204 break;
205 }
206 }
207}
208
209void DxlibGuiUpdater::ActivateDraggable(const std::shared_ptr<const Mouse> mouse_ptr)
210{
211 unsigned int mouse_key{ 0 };
212 int pressing_count{ 0 };
213 std::array<unsigned int, 3> mouse_keys = {
214 MOUSE_INPUT_LEFT, MOUSE_INPUT_MIDDLE, MOUSE_INPUT_RIGHT };
215
216 for (auto i : mouse_keys)
217 {
218 if (mouse_ptr->GetPressingCount(i) > 0)
219 {
220 mouse_key += i;
221 pressing_count =
222 (std::max)(mouse_ptr->GetPressingCount(i), pressing_count);
223 }
224 }
225
226
227 if (pressing_count == 0)
228 {
229 // 左クリックが押されていないならば全てのドラッグを終了する
230 for (auto& i : draggable_ptrs_)
231 {
232 i.second->SetDragged(false);
233 }
234
235 now_dragging_gui_key_ = std::nullopt;
236 }
237 else if (pressing_count == 1)
238 {
239 // 左クリックが押された瞬間,ドラッグを開始する
240 for (auto i = draggable_ptrs_.rbegin(); i != draggable_ptrs_.rend(); ++i)
241 {
242 if ((*i).second->IsDraggable(
243 mouse_ptr->GetCursorPosX(),
244 mouse_ptr->GetCursorPosY()))
245 {
246 (*i).second->SetDragged(true);
247 now_dragging_gui_key_ = (*i).first;
248 break;
249 }
250 }
251 }
252 else if (pressing_count > 0)
253 {
254 // 左クリックが押され続けているならばドラッグ判定を行う.
255 if (now_dragging_gui_key_.has_value() &&
256 draggable_ptrs_.count(now_dragging_gui_key_.value()) == 1)
257 {
258 draggable_ptrs_[now_dragging_gui_key_.value()]->DraggedAction(
259 mouse_ptr->GetDiffPosX(), mouse_ptr->GetDiffPosY(), mouse_key);
260 }
261 }
262 else
263 {
264 assert(false); // 冗長
265 }
266}
267
268void DxlibGuiUpdater::ActivateWheelHandler(
269 const std::shared_ptr<const Mouse> mouse_ptr)
270{
271 if (mouse_ptr->GetWheelRot() == 0) { return; }
272
273 // 優先度の高いものから順にホイール操作判定を行う
274 // 昇順(増える順)に並んでいるので,rbeginからrendまで(降順に)走査する
275
276 for (auto i = wheel_handler_ptrs_.rbegin(); i != wheel_handler_ptrs_.rend(); ++i)
277 {
278 if ((*i).second->CanHandleWheel(
279 mouse_ptr->GetCursorPosX(),
280 mouse_ptr->GetCursorPosY()))
281 {
282 (*i).second->RotMouseWheel(mouse_ptr->GetWheelRot());
283 break;
284 }
285 }
286}
287
288} // namespace designlab
void OpenTerminal()
Terminalを開く. 他のGUIをRegisterした後に呼び出すこと. 2回目以降の呼び出しは無視される. また,Terminalは最も優先度が高い.
void Draw() const
登録済みのGUIのDraw関数を実行する.
void Activate(const std::shared_ptr< const Mouse > &mouse_ptr)
GUIのUpdate関数を実行し,クリック,ドラッグなどの判定を行う. 優先度の高いものから順に各種判定を行う.
static constexpr int kTopPriority
最も優先的に処理される.