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
20 const int window_x, const int window_y) :
21 AbstractDxlibGui(kWidth, kHeight),
22 window_x_(window_x),
23 window_y_(window_y),
24 display_node_num_(0),
25 all_node_num_(0),
26 simulation_num_(0),
27 do_auto_animation_(false) {
28 const int button_interval = 10;
29 const int button_width = 40;
30 const int kButtonLeftX = button_width / 2 + gui_left_pos_x_ + 10;
31 const int kButtonTopY =
32 button_width / 2 + gui_top_pos_y_ + kTitleBarHeight + 100;
33
34 // 各種ボタンを作成する.
35 button_.push_back(std::make_unique<SimpleButton>(
36 "<<", kButtonLeftX, kButtonTopY, button_width, button_width));
37 button_.back()->SetActivateFunction([this]() { MoveMostPrevNode(); });
38
39 button_.push_back(std::make_unique<SimpleButton>(
40 "<", kButtonLeftX + (button_interval + button_width) * 1, kButtonTopY,
41 button_width, button_width));
42 button_.back()->SetActivateFunction([this]() { MovePrevNode(); });
43
44 button_.push_back(std::make_unique<SimpleButton>(
45 "再生\n停止",
46 kButtonLeftX + (button_interval + button_width) * 2,
47 kButtonTopY,
48 button_width, button_width));
49 button_.back()->SetActivateFunction(
50 [this]() { do_auto_animation_ = !do_auto_animation_; });
51
52 button_.push_back(std::make_unique<SimpleButton>(
53 ">", kButtonLeftX + (button_interval + button_width) * 3, kButtonTopY,
54 button_width, button_width));
55 button_.back()->SetActivateFunction([this]() { MoveNextNode(); });
56
57 button_.push_back(std::make_unique<SimpleButton>(
58 ">>", kButtonLeftX + (button_interval + button_width) * 4, kButtonTopY,
59 button_width, button_width));
60 button_.back()->SetActivateFunction([this]() { MoveMostNextNode(); });
61
62 button_.push_back(std::make_unique<SimpleButton>(
63 "↓", kButtonLeftX + (button_interval + button_width) * 3,
64 kButtonTopY + (button_interval + button_width),
65 button_width, button_width));
66 button_.back()->SetActivateFunction([this]() {
67 if (animation_speed_ > kAnimeSpeedMin) {
68 --animation_speed_;
69 }
70 });
71
72 button_.push_back(std::make_unique<SimpleButton>(
73 "↑", kButtonLeftX + (button_interval + button_width) * 4,
74 kButtonTopY + (button_interval + button_width),
75 button_width, button_width));
76 button_.back()->SetActivateFunction([this]() {
77 if (animation_speed_ < kAnimeSpeedMax) {
78 ++animation_speed_;
79 }
80 });
81
82 button_.push_back(std::make_unique<SimpleButton>(
83 "Prev Simu",
84 kButtonLeftX + (button_interval + button_width) * 1,
85 kButtonTopY + (button_interval + button_width) * 2,
86 button_width * 2, button_width));
87 button_.back()->SetActivateFunction([this]() { MovePrevSimulation(); });
88
89 button_.push_back(std::make_unique<SimpleButton>(
90 "Next Simu",
91 kButtonLeftX + (button_interval + button_width) * 3,
92 kButtonTopY + (button_interval + button_width) * 2,
93 button_width * 2, button_width));
94 button_.back()->SetActivateFunction([this]() { MoveNextSimulation(); });
95
96 const int close_button_size = 28;
97 const int close_button_x = gui_left_pos_x_ + kWidth - close_button_size / 2 - 2;
98 const int close_button_y = gui_top_pos_y_ + close_button_size / 2 + 2;
99
100 button_.push_back(std::make_unique<SimpleButton>(
101 "×", close_button_x, close_button_y,
102 close_button_size, close_button_size));
103 button_.back()->SetActivateFunction([this]() { SetVisible(false); });
104}
105
107 const size_t node_num, const std::vector<size_t>& simulation_end_index) {
108 all_node_num_ = node_num;
109
110 simulation_end_index_.clear();
111
112 simulation_end_index_ = simulation_end_index;
113}
114
115
117 // 範囲外の値を返さないようにする.
118 if (display_node_num_ > all_node_num_ && all_node_num_ != 0) {
119 return all_node_num_ - 1;
120 }
121
122
123 // 範囲内の値ならば,そのまま返す.
124 return display_node_num_;
125}
126
127
129 ++counter_;
130
131 // 自動再生を行う.
132 if (do_auto_animation_ && !in_animation_) {
133 MoveNextNode();
134 }
135
136 // ボタンを更新する.
137 for (auto& i : button_) {
138 i->Update();
139 }
140
141 if (!IsInWindow()) {
142 SetVisible(false);
143 }
144}
145
147 DrawBackground("NodeSwitcher");
148
149 // ボタンを描画する.
150 for (const auto& i : button_) {
151 i->Draw();
152 }
153
154 // 文字を描画する.
155 const int text_left_x = gui_left_pos_x_ + 10;
156
157 const unsigned int text_color = GetColor(0, 0, 0);
158
159 DrawFormatStringToHandle(
160 text_left_x,
162 text_color,
164 "[シミュレーション%d回目(全%d回)]",
165 simulation_num_ + 1,
166 GetAllSimulationNum(),
167 display_node_num_,
168 all_node_num_);
169
170 int start_node_num = 0;
171 int end_node_num = 0;
172
173 if (simulation_num_ == 0) {
174 start_node_num = 0;
175
176 if (!simulation_end_index_.empty()) {
177 end_node_num = static_cast<int>(simulation_end_index_[0]);
178 }
179 else {
180 end_node_num = static_cast<int>(all_node_num_ - 1);
181 }
182 }
183 else if (simulation_num_ == static_cast<int>(simulation_end_index_.size())) {
184 start_node_num = static_cast<int>(
185 simulation_end_index_[simulation_num_ - 1] + 1);
186 end_node_num = static_cast<int>(all_node_num_ - 1);
187 }
188 else {
189 start_node_num = static_cast<int>(
190 simulation_end_index_[simulation_num_ - 1] + 1);
191 end_node_num = static_cast<int>(simulation_end_index_[simulation_num_]);
192 }
193
194 DrawFormatStringToHandle(
195 text_left_x,
197 text_color,
199 "表示ノード : %d (%d~%d)",
200 display_node_num_, start_node_num, end_node_num, all_node_num_ - 1);
201
202 DrawFormatStringToHandle(
203 text_left_x,
205 text_color,
207 "全ノード : %d ", all_node_num_ - 1);
208
209 DrawFormatStringToHandle(
210 text_left_x,
212 text_color,
214 do_auto_animation_ == true ?
215 "自動再生 : 再生/速度%d" : "自動再生 : 停止/速度%d",
216 animation_speed_);
217
218 DrawFormatStringToHandle(
219 text_left_x,
221 text_color,
223 "アニメーションの\n 速度変更");
224}
225
226
227void DxlibGuiDisplayNodeSwitcher::MoveMostPrevNode() {
228 // 候補.
229 size_t candidate = 0;
230
231 for (size_t i = 0; i < simulation_end_index_.size(); i++) {
232 if (simulation_end_index_[i] < display_node_num_) {
233 candidate = simulation_end_index_[i] + 1;
234 }
235 else {
236 break;
237 }
238 }
239
240 display_node_num_ = candidate;
241}
242
243void DxlibGuiDisplayNodeSwitcher::MovePrevNode() {
244 for (size_t i = 0; i < simulation_end_index_.size(); i++) {
245 if (simulation_end_index_[i] + 1 == display_node_num_) {
246 return;
247 }
248 }
249
250 --display_node_num_;
251
252 display_node_num_ =
253 static_cast<size_t>((std::max)(static_cast<int>(display_node_num_), 0));
254}
255
256void DxlibGuiDisplayNodeSwitcher::MoveMostNextNode() {
257 // 候補.
258 size_t candidate = all_node_num_ - 1;
259
260 for (size_t i = 0; i < simulation_end_index_.size(); i++) {
261 if (simulation_end_index_[i] >= display_node_num_) {
262 candidate = simulation_end_index_[i];
263 break;
264 }
265 }
266
267 display_node_num_ = candidate;
268}
269
270void DxlibGuiDisplayNodeSwitcher::MoveNextNode() {
271 for (size_t i = 0; i < simulation_end_index_.size(); i++) {
272 if (simulation_end_index_[i] == display_node_num_) {
273 return;
274 }
275 }
276
277 ++display_node_num_;
278
279 display_node_num_ = (std::min)(display_node_num_, all_node_num_ - 1);
280}
281
282void DxlibGuiDisplayNodeSwitcher::MovePrevSimulation() {
283 // 前のシミュレーションへ移動する.
284 --simulation_num_;
285
286 simulation_num_ = static_cast<size_t>((std::max)(simulation_num_, 0));
287
288 // ノードをそのシミュレーションの最初のノードに移動する.
289 if (simulation_num_ == 0) {
290 display_node_num_ = 0;
291 }
292 else {
293 display_node_num_ = simulation_end_index_[simulation_num_ - 1] + 1;
294 }
295}
296
297void DxlibGuiDisplayNodeSwitcher::MoveNextSimulation() {
298 // 次のシミュレーションへ移動する.
299 ++simulation_num_;
300
301
302 simulation_num_ = static_cast<size_t>(
303 (std::min)(simulation_num_, GetAllSimulationNum() - 1));
304
305
306 // ノードをそのシミュレーションの最初のノードに移動する.
307 if (simulation_num_ == 0) {
308 display_node_num_ = 0;
309 }
310 else {
311 display_node_num_ = simulation_end_index_[simulation_num_ - 1] + 1;
312 }
313}
314
315int DxlibGuiDisplayNodeSwitcher::GetAllSimulationNum() const {
316 int all_simulation_num = 1;
317
318 if (!simulation_end_index_.empty()) {
319 if (simulation_end_index_.back() == all_node_num_ - 1) {
320 all_simulation_num = static_cast<int>(simulation_end_index_.size());
321 }
322 else {
323 all_simulation_num = static_cast<int>(simulation_end_index_.size()) + 1;
324 }
325 }
326
327 return all_simulation_num;
328}
329
330bool DxlibGuiDisplayNodeSwitcher::IsInWindow() const {
331 return gui_left_pos_x_ < window_x_ && gui_top_pos_y_ < window_y_ &&
332 0 < gui_left_pos_x_ + kWidth && 0 < gui_top_pos_y_ + kHeight;
333}
334
335} // 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に表示するノードの情報を設定する.