GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
dxlib_gui_display_node_switcher.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
9
10#include <algorithm>
11
12#include <Dxlib.h>
13
14#include "font_loader.h"
15
16
17namespace designlab
18{
19
21 const int window_x, const int window_y) :
22 AbstractDxlibGui(kWidth, kHeight),
23 window_x_(window_x),
24 window_y_(window_y),
25 display_node_num_(0),
26 all_node_num_(0),
27 simulation_num_(0),
28 do_auto_animation_(false),
29 animation_speed_(kAnimeSpeedMin)
30{
31 const int button_interval = 10;
32 const int button_width = 40;
33 const int kButtonLeftX = button_width / 2 + gui_left_pos_x_ + 10;
34 const int kButtonTopY =
35 button_width / 2 + gui_top_pos_y_ + kTitleBarHeight + 100;
36
37 // 各種ボタンを作成する.
38 button_.push_back(std::make_unique<SimpleButton>(
39 "<<", kButtonLeftX, kButtonTopY, button_width, button_width));
40 button_.back()->SetActivateFunction([this]() { MoveMostPrevNode(); });
41
42 button_.push_back(std::make_unique<SimpleButton>(
43 "<", kButtonLeftX + (button_interval + button_width) * 1, kButtonTopY,
44 button_width, button_width));
45 button_.back()->SetActivateFunction([this]() { MovePrevNode(); });
46
47 button_.push_back(std::make_unique<SimpleButton>(
48 "再生\n停止",
49 kButtonLeftX + (button_interval + button_width) * 2,
50 kButtonTopY,
51 button_width, button_width));
52 button_.back()->SetActivateFunction(
53 [this]() { do_auto_animation_ = !do_auto_animation_; });
54
55 button_.push_back(std::make_unique<SimpleButton>(
56 ">", kButtonLeftX + (button_interval + button_width) * 3, kButtonTopY,
57 button_width, button_width));
58 button_.back()->SetActivateFunction([this]() { MoveNextNode(); });
59
60 button_.push_back(std::make_unique<SimpleButton>(
61 ">>", kButtonLeftX + (button_interval + button_width) * 4, kButtonTopY,
62 button_width, button_width));
63 button_.back()->SetActivateFunction([this]() { MoveMostNextNode(); });
64
65 button_.push_back(std::make_unique<SimpleButton>(
66 "↓", kButtonLeftX + (button_interval + button_width) * 3,
67 kButtonTopY + (button_interval + button_width),
68 button_width, button_width));
69 button_.back()->SetActivateFunction([this]()
70 {
71 if (animation_speed_ > kAnimeSpeedMin)
72 {
73 --animation_speed_;
74 }
75 });
76
77 button_.push_back(std::make_unique<SimpleButton>(
78 "↑", kButtonLeftX + (button_interval + button_width) * 4,
79 kButtonTopY + (button_interval + button_width),
80 button_width, button_width));
81 button_.back()->SetActivateFunction([this]()
82 {
83 if (animation_speed_ < kAnimeSpeedMax)
84 {
85 ++animation_speed_;
86 }
87 });
88
89 button_.push_back(std::make_unique<SimpleButton>(
90 "Prev Simu",
91 kButtonLeftX + (button_interval + button_width) * 1,
92 kButtonTopY + (button_interval + button_width) * 2,
93 button_width * 2, button_width));
94 button_.back()->SetActivateFunction([this]() { MovePrevSimulation(); });
95
96 button_.push_back(std::make_unique<SimpleButton>(
97 "Next Simu",
98 kButtonLeftX + (button_interval + button_width) * 3,
99 kButtonTopY + (button_interval + button_width) * 2,
100 button_width * 2, button_width));
101 button_.back()->SetActivateFunction([this]() { MoveNextSimulation(); });
102
103 const int close_button_size = 28;
104 const int close_button_x = gui_left_pos_x_ + kWidth - close_button_size / 2 - 2;
105 const int close_button_y = gui_top_pos_y_ + close_button_size / 2 + 2;
106
107 button_.push_back(std::make_unique<SimpleButton>(
108 "×", close_button_x, close_button_y,
109 close_button_size, close_button_size));
110 button_.back()->SetActivateFunction([this]() { SetVisible(false); });
111}
112
114 const size_t node_num, const std::vector<size_t>& simulation_end_index)
115{
116 all_node_num_ = node_num;
117
118 simulation_end_index_.clear();
119
120 simulation_end_index_ = simulation_end_index;
121}
122
123
125{
126 // 範囲外の値を返さないようにする.
127 if (display_node_num_ > all_node_num_ && all_node_num_ != 0)
128 {
129 return all_node_num_ - 1;
130 }
131
132
133 // 範囲内の値ならば,そのまま返す.
134 return display_node_num_;
135}
136
137
139{
140 ++counter_;
141
142 // 自動再生を行う.
143 if (do_auto_animation_ && !in_animation_)
144 {
145 MoveNextNode();
146 }
147
148 // ボタンを更新する.
149 for (auto& i : button_)
150 {
151 i->Update();
152 }
153
154 if (!IsInWindow())
155 {
156 SetVisible(false);
157 }
158}
159
161{
162 DrawBackground("NodeSwitcher");
163
164 // ボタンを描画する.
165 for (const auto& i : button_)
166 {
167 i->Draw();
168 }
169
170 // 文字を描画する.
171 const int text_left_x = gui_left_pos_x_ + 10;
172
173 const unsigned int text_color = GetColor(0, 0, 0);
174
175 DrawFormatStringToHandle(
176 text_left_x,
178 text_color,
180 "[シミュレーション%d回目(全%d回)]",
181 simulation_num_ + 1,
182 GetAllSimulationNum(),
183 display_node_num_,
184 all_node_num_);
185
186 int start_node_num = 0;
187 int end_node_num = 0;
188
189 if (simulation_num_ == 0)
190 {
191 start_node_num = 0;
192
193 if (!simulation_end_index_.empty())
194 {
195 end_node_num = static_cast<int>(simulation_end_index_[0]);
196 }
197 else
198 {
199 end_node_num = static_cast<int>(all_node_num_ - 1);
200 }
201 }
202 else if (simulation_num_ == static_cast<int>(simulation_end_index_.size()))
203 {
204 start_node_num = static_cast<int>(
205 simulation_end_index_[simulation_num_ - 1] + 1);
206 end_node_num = static_cast<int>(all_node_num_ - 1);
207 }
208 else
209 {
210 start_node_num = static_cast<int>(
211 simulation_end_index_[simulation_num_ - 1] + 1);
212 end_node_num = static_cast<int>(simulation_end_index_[simulation_num_]);
213 }
214
215 DrawFormatStringToHandle(
216 text_left_x,
218 text_color,
220 "表示ノード : %d (%d~%d)",
221 display_node_num_, start_node_num, end_node_num, all_node_num_ - 1);
222
223 DrawFormatStringToHandle(
224 text_left_x,
226 text_color,
228 "全ノード : %d ", all_node_num_ - 1);
229
230 DrawFormatStringToHandle(
231 text_left_x,
233 text_color,
235 do_auto_animation_ == true ?
236 "自動再生 : 再生/速度%d" : "自動再生 : 停止/速度%d",
237 animation_speed_);
238
239 DrawFormatStringToHandle(
240 text_left_x,
242 text_color,
244 "アニメーションの\n 速度変更");
245}
246
247
248void DxlibGuiDisplayNodeSwitcher::MoveMostPrevNode()
249{
250 // 候補.
251 size_t candidate = 0;
252
253 for (size_t i = 0; i < simulation_end_index_.size(); i++)
254 {
255 if (simulation_end_index_[i] < display_node_num_)
256 {
257 candidate = simulation_end_index_[i] + 1;
258 }
259 else
260 {
261 break;
262 }
263 }
264
265 display_node_num_ = candidate;
266}
267
268void DxlibGuiDisplayNodeSwitcher::MovePrevNode()
269{
270 for (size_t i = 0; i < simulation_end_index_.size(); i++)
271 {
272 if (simulation_end_index_[i] + 1 == display_node_num_)
273 {
274 return;
275 }
276 }
277
278 --display_node_num_;
279
280 display_node_num_ =
281 static_cast<size_t>((std::max)(static_cast<int>(display_node_num_), 0));
282}
283
284void DxlibGuiDisplayNodeSwitcher::MoveMostNextNode()
285{
286 // 候補.
287 size_t candidate = all_node_num_ - 1;
288
289 for (size_t i = 0; i < simulation_end_index_.size(); i++)
290 {
291 if (simulation_end_index_[i] >= display_node_num_)
292 {
293 candidate = simulation_end_index_[i];
294 break;
295 }
296 }
297
298 display_node_num_ = candidate;
299}
300
301void DxlibGuiDisplayNodeSwitcher::MoveNextNode()
302{
303 for (size_t i = 0; i < simulation_end_index_.size(); i++)
304 {
305 if (simulation_end_index_[i] == display_node_num_)
306 {
307 return;
308 }
309 }
310
311 ++display_node_num_;
312
313 display_node_num_ = (std::min)(display_node_num_, all_node_num_ - 1);
314}
315
316void DxlibGuiDisplayNodeSwitcher::MovePrevSimulation()
317{
318 // 前のシミュレーションへ移動する.
319 --simulation_num_;
320
321 simulation_num_ = static_cast<size_t>((std::max)(simulation_num_, 0));
322
323 // ノードをそのシミュレーションの最初のノードに移動する.
324 if (simulation_num_ == 0)
325 {
326 display_node_num_ = 0;
327 }
328 else
329 {
330 display_node_num_ = simulation_end_index_[simulation_num_ - 1] + 1;
331 }
332}
333
334void DxlibGuiDisplayNodeSwitcher::MoveNextSimulation()
335{
336 // 次のシミュレーションへ移動する.
337 ++simulation_num_;
338
339
340 simulation_num_ = static_cast<size_t>(
341 (std::min)(simulation_num_, GetAllSimulationNum() - 1));
342
343
344 // ノードをそのシミュレーションの最初のノードに移動する.
345 if (simulation_num_ == 0)
346 {
347 display_node_num_ = 0;
348 }
349 else
350 {
351 display_node_num_ = simulation_end_index_[simulation_num_ - 1] + 1;
352 }
353}
354
355int DxlibGuiDisplayNodeSwitcher::GetAllSimulationNum() const
356{
357 int all_simulation_num = 1;
358
359 if (!simulation_end_index_.empty())
360 {
361 if (simulation_end_index_.back() == all_node_num_ - 1)
362 {
363 all_simulation_num = static_cast<int>(simulation_end_index_.size());
364 }
365 else
366 {
367 all_simulation_num = static_cast<int>(simulation_end_index_.size()) + 1;
368 }
369 }
370
371 return all_simulation_num;
372}
373
374bool DxlibGuiDisplayNodeSwitcher::IsInWindow() const
375{
376 return gui_left_pos_x_ < window_x_ && gui_top_pos_y_ < window_y_ &&
377 0 < gui_left_pos_x_ + kWidth && 0 < gui_top_pos_y_ + kHeight;
378}
379
380} // namespace designlab
Dxlibを使ったGUIの抽象クラス.
void DrawBackground(const std::string &str) const
int gui_left_pos_x_
GUIの左端の位置.
static constexpr int kTitleBarHeight
タイトルバーの高さ.
int gui_top_pos_y_
GUIの上端の位置.
void SetVisible(bool visible) override
GUIの表示を行うかどうかを設定する.
int font_handle_
フォントハンドル.
std::vector< std::unique_ptr< SimpleButton > > button_
ボタンのリスト.
void Update() override
GUIの更新,毎フレーム実行すること.
size_t GetDisplayNodeNum() const
現在表示するノードの番号を取得する.
void SetGraphData(size_t node_num, const std::vector< size_t > &simulation_end_index)
GUIに表示するノードの情報を設定する.