GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
dxlib_gui_terminal.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 <string>
11#include <typeinfo>
12
13#include <DxLib.h>
14
15#include "string_util.h"
16
17
18namespace designlab
19{
20
21DxlibGuiTerminal::DxlibGuiTerminal(std::vector<std::shared_ptr<IDxlibGui>> gui_list) :
22 kTerminalWidth(static_cast<int>(gui_list.size() + 2)* kButtonSize)
23{
25
26 gui_list_ = gui_list;
27
28 // guiの数だけボタンを作成
29 for (int i = 0; i < gui_list_.size(); ++i)
30 {
31 // 型を取得する.
32 std::string class_name = string_util::GetTypeName(*gui_list_[i].get());
33
34 // typeidの返り値は"class DxlibGui~"という文字列になっているので,邪魔な文字を削除する.
35 const std::vector<std::string> unnecessary_words = { "DxlibGui", " ", "const", "*", "&" };
36
37 for (const auto& word : unnecessary_words)
38 {
39 // そもそも文字列に word が含まれていない場合は何もしない
40 if (class_name.find(word) == std::string::npos) { continue; }
41
42 // 文字列に word が含まれている場合は削除
43 class_name.erase(class_name.find(word), word.size());
44 }
45
46 // class_nameを7文字ごとに改行
47 for (int j = 7; j < class_name.size(); j += 7)
48 {
49 class_name.insert(j, "\n");
50 ++j;
51 }
52
53 button_list_.push_back(
54 std::make_shared<SimpleButton>(class_name,
55 kLeftTopX + kButtonSize + i * 100, kLeftTopY + kTerminalHeight / 2, kButtonSize, kButtonSize));
56
57 button_list_.back()->SetActivateFunction([this, i]() { gui_list_[i]->SetVisible(true); });
58
59 button_list_.back()->SetVisible(false);
60 }
61}
62
64{
65 // 各ボタンの更新.
66 for (auto& button : button_list_)
67 {
68 button->Update();
69 }
70}
71
73{
74 if (is_closed_)
75 {
76 DrawClosedTerminal();
77 }
78 else
79 {
80 DrawTerminal();
81
82 // ボタンの描画.
83 for (const auto& button : button_list_)
84 {
85 button->Draw();
86 }
87
88 DrawButtonGuard();
89 }
90}
91
92void DxlibGuiTerminal::SetVisible([[maybe_unused]] bool visible)
93{
94 // 消えない.なので何もしない.
95}
96
98{
99 // 消えない.なので常に true.
100 return true;
101}
102
104{
105 bool is_clicked = false;
106
107 // 各ボタンの処理.
108 for (auto& button : button_list_)
109 {
110 if (button->CursorOnGui(state.cursor_x, state.cursor_y))
111 {
112 button->ClickedAction(state);
113 is_clicked = true;
114 break;
115 }
116 }
117
118 // ボタンが押された場合は終了.
119 if (is_clicked)
120 {
121 return;
122 }
123
124 // ターミナルの処理.
125 if (state.left_pushing_count == 1 && is_closed_)
126 {
127 is_closed_ = false;
128
129 // ボタンを表示.
130 for (auto& button : button_list_)
131 {
132 button->SetVisible(true);
133 }
134 }
135 else if (state.left_pushing_count == 1 && !is_closed_)
136 {
137 is_closed_ = true;
138
139 // ボタンを非表示.
140 for (auto& button : button_list_)
141 {
142 button->SetVisible(false);
143 }
144 }
145}
146
147bool DxlibGuiTerminal::CursorOnGui(int cursor_x, int cursor_y) const noexcept
148{
149 if (is_closed_)
150 {
151 return cursor_x >= kLeftTopX && cursor_x <= kLeftTopX + kClosedTerminalWidth &&
152 cursor_y >= kLeftTopY && cursor_y <= kLeftTopY + kTerminalHeight;
153 }
154 else
155 {
156 return cursor_x >= kLeftTopX && cursor_x <= kLeftTopX + kTerminalWidth &&
157 cursor_y >= kLeftTopY && cursor_y <= kLeftTopY + kTerminalHeight;
158 }
159}
160
161void DxlibGuiTerminal::DrawClosedTerminal() const
162{
163 const int closed_box_width = kClosedTerminalWidth - 20; // 四角形部分の幅.
164
165 const unsigned int base_color = GetColor(255, 255, 255);
166 const unsigned int frame_color = GetColor(30, 30, 30);
167 const unsigned int alpha = 200;
168
169 const int frame_width = 1;
170
171 SetDrawBlendMode(DX_BLENDMODE_ALPHA, alpha);
172
173 DrawBox(kLeftTopX - frame_width, kLeftTopY - frame_width,
174 kLeftTopX + closed_box_width, kLeftTopY + kTerminalHeight + frame_width, frame_color, TRUE);
175 DrawTriangleAA(
176 kLeftTopX + closed_box_width, kLeftTopY - frame_width,
177 kLeftTopX + closed_box_width, kLeftTopY + kTerminalHeight + frame_width,
178 kLeftTopX + kClosedTerminalWidth + frame_width, kLeftTopY + kTerminalHeight / 2,
179 frame_color, TRUE);
180
181 DrawBox(kLeftTopX, kLeftTopY, kLeftTopX + closed_box_width, kLeftTopY + kTerminalHeight, base_color, TRUE);
182 DrawTriangleAA(kLeftTopX + closed_box_width, kLeftTopY, kLeftTopX + closed_box_width, kLeftTopY + kTerminalHeight,
183 kLeftTopX + kClosedTerminalWidth, kLeftTopY + kTerminalHeight / 2, base_color, TRUE);
184
185 SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
186}
187
188void DxlibGuiTerminal::DrawTerminal() const
189{
190 const int closed_box_width = kTerminalWidth - 20; // 四角形部分の幅.
191
192 const unsigned int base_color = GetColor(255, 255, 255);
193 const unsigned int frame_color = GetColor(30, 30, 30);
194 const unsigned int alpha = 200;
195
196 const int frame_width = 1;
197
198 SetDrawBlendMode(DX_BLENDMODE_ALPHA, alpha);
199
200 DrawBox(kLeftTopX - frame_width, kLeftTopY - frame_width,
201 kLeftTopX + closed_box_width, kLeftTopY + kTerminalHeight + frame_width, frame_color, TRUE);
202 DrawTriangleAA(
203 static_cast<float>(kLeftTopX + closed_box_width), static_cast<float>(kLeftTopY - frame_width),
204 static_cast<float>(kLeftTopX + closed_box_width), static_cast<float>(kLeftTopY + kTerminalHeight + frame_width),
205 static_cast<float>(kLeftTopX + kTerminalWidth + frame_width), static_cast<float>(kLeftTopY + kTerminalHeight / 2),
206 frame_color, TRUE);
207
208 DrawBox(kLeftTopX, kLeftTopY, kLeftTopX + closed_box_width, kLeftTopY + kTerminalHeight, base_color, TRUE);
209 DrawTriangleAA(
210 static_cast<float>(kLeftTopX + closed_box_width), static_cast<float>(kLeftTopY),
211 static_cast<float>(kLeftTopX + closed_box_width), static_cast<float>(kLeftTopY + kTerminalHeight),
212 static_cast<float>(kLeftTopX + kTerminalWidth), static_cast<float>(kLeftTopY + kTerminalHeight / 2),
213 base_color, TRUE);
214
215 SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
216}
217
218void DxlibGuiTerminal::DrawButtonGuard() const
219{
220 for (int i = 0; i < button_list_.size(); ++i)
221 {
222 if (gui_list_[i]->IsVisible())
223 {
224 const unsigned int color = GetColor(45, 45, 45);
225 const int alpha = 200;
226
227 SetDrawBlendMode(DX_BLENDMODE_ALPHA, alpha);
228
229 DrawBox(button_list_[i]->GetPosMiddleX() - kButtonSize / 2, button_list_[i]->GetPosMiddleY() - kButtonSize / 2,
230 button_list_[i]->GetPosMiddleX() + kButtonSize / 2, button_list_[i]->GetPosMiddleY() + kButtonSize / 2, color, TRUE);
231
232 SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
233 }
234 }
235}
236
237} // namespace designlab
bool CursorOnGui(int cursor_x, int cursor_y) const noexcept
GUIの上にカーソルがあるかどうかを返す.
void Draw() const override
GUIの描画.
void SetVisible(bool visible)
GUIの表示を行うかどうかを設定する.
void Update() override
GUIの更新,毎フレーム実行すること.
bool IsVisible() const
GUIの表示を行うかどうかを返す.
void ClickedAction(const DxlibMouseState &state)
GUIがクリックされたときに実行される関数. CursorOnGuiが true を返すときに呼び出される. 複数のGUIが重なっている場合は,優先度の高いものから順に呼び出される.
std::string GetTypeName(const T &type)
マウスの状態を表す構造体.
int cursor_y
マウスカーソルのY座標.上端を0とし,下に正の値をとる.
int left_pushing_count
マウスの左ボタンが押されているフレーム数.
int cursor_x
マウスカーソルのX座標.左端を0とし,右に正の値をとる.