5 #include "InputBox.hpp"
6 #include "../CardManager.hpp"
7 #include "../../common/Logger.hpp"
8 #include "../../common/unicode.hpp"
10 const size_t InputBox::HISTORY_MAX_SIZE = 50;
12 const int InputBox::DEFAULT_MAX_WIDTH = 600;
14 const int InputBox::TAB_TOP_MARGIN = 7;
15 const int InputBox::TAB_SIDE_MARGIN = 30;
16 const int InputBox::TAB_X_MARGIN = 15;
17 const int InputBox::MESSAGE_TOP_MARGIN = 30;
19 const int InputBox::BOX_MIN_WIDTH = 200;
20 const int InputBox::BOX_TOP_MARGIN = 36;
21 const int InputBox::BOX_BOTTOM_MARGIN = 16;
22 const int InputBox::BOX_SIDE_MARGIN = 6;
24 const int InputBox::KEY_REPEAT_FRAME = 6;
26 const int InputBox::INPUT_MARGIN_X = 8;
27 const int InputBox::INPUT_MARGIN_Y = 6;
29 const int InputBox::IME_BLOCK_SIZE = 32;
30 const int InputBox::IME_MARGIN_BASE = 12;
31 const int InputBox::IME_MARGIN_Y = 16;
32 const int InputBox::IME_MAX_PAGE_SIZE = 6;
33 const int InputBox::IME_MIN_WIDTH = 120;
35 InputBox::InputBox(const ManagerAccessorPtr& manager_accessor) :
37 font_height_(ResourceManager::default_font_size()),
40 drag_resize_offset_x_(-1),
41 drag_resize_offset_y_(-1),
42 min_input_height_(font_height_ + INPUT_MARGIN_Y * 2),
43 selecting_tab_index_(0),
44 manager_accessor_(manager_accessor),
45 card_(std::make_shared<Card>(manager_accessor_, "", "immo", "", "",
46 std::vector<std::string>())),
50 absolute_rect_ = Rect(100, 100, 800, 100);
52 font_handle_ = ResourceManager::default_font_handle();
53 bg_image_handle_ = ResourceManager::LoadCachedDivGraph<4>(
54 _T("system/images/gui/gui_inputbox_bg.png"), 2, 2, 24, 24);
55 tab_bg_image_handle_ = ResourceManager::LoadCachedDivGraph<4>(
56 _T("system/images/gui/gui_inputbox_tab_bg.png"), 2, 2, 12, 12);
57 tab_bg_inactive_image_handle_ = ResourceManager::LoadCachedDivGraph<4>(
58 _T("system/images/gui/gui_inputbox_tab_inactive_bg.png"), 2, 2, 12, 12);
59 ime_image_handle_ = ResourceManager::LoadCachedDivGraph<4>(
60 _T("system/images/gui/gui_inputbox_ime_bg.png"), 2, 2, 12, 12);
62 script_icon_image_handle_ = ResourceManager::LoadCachedGraph(_T("system/images/gui/gui_inputbox_tab_script_icon.png"));
64 int screen_width, screen_height;
65 GetScreenState(&screen_width, &screen_height, nullptr);
66 absolute_rect_.width = std::min(DEFAULT_MAX_WIDTH + 0, (int)(screen_width * 0.4));
67 absolute_rect_.height = input_.height() + BOX_TOP_MARGIN + BOX_BOTTOM_MARGIN;
68 absolute_rect_.x = (screen_width - absolute_rect_.width) / 2;
69 absolute_rect_.y = screen_height - absolute_rect_.height - BOX_BOTTOM_MARGIN;
71 selecting_tab_index_ = 0;
74 if (auto card_manager = manager_accessor_->card_manager().lock()) {
75 card_manager->AddCard(card_);
78 input_.set_on_enter([this](const std::string& text) -> bool{
80 if (input_.text().empty()) {
81 input_.set_active(false);
83 if (selecting_tab_index_ == -1) {
84 card_->Execute(unicode::ToString(input_.text()), "mmo",
85 [&](const v8::Handle<v8::Value>& result, const std::string& error){
86 if (error.size() > 0) {
87 script_tab_.message = unicode::ToTString(error);
88 } else if (!result.IsEmpty()) {
89 script_tab_.message = _T("=> ") +
90 unicode::ToTString(std::string(*String::Utf8Value(result->ToString())));
92 script_tab_.message = _T("");
94 input_.set_message(script_tab_.message);
96 } else if (!tabs_.empty()) {
98 tabs_.at(selecting_tab_index_).card.lock()) {
99 card->onEnter(unicode::ToString(input_.text()));
108 InputBox::~InputBox()
113 void InputBox::DrawTabs()
118 SetDrawArea(absolute_rect_.x, script_tab_.y, script_tab_.x, script_tab_.y + script_tab_.height);
119 BOOST_FOREACH(auto& tab, tabs_) {
121 std::array<ImageHandlePtr, 4>* image_handle;
122 if (selecting_tab_index_ == tab_index) {
123 image_handle = &tab_bg_image_handle_;
125 image_handle = &tab_bg_inactive_image_handle_;
129 int tab_width = tab.width;
130 int tab_height = tab.height;
132 DrawGraph(tab_x, tab_y, *(*image_handle)[0], TRUE);
133 DrawGraph(tab_x + tab_width - 12, tab_y, *(*image_handle)[1], TRUE);
134 DrawGraph(tab_x, tab_y + tab_height - 12, *(*image_handle)[2], TRUE);
135 DrawGraph(tab_x + tab_width - 12, tab_y + tab_height - 12,
136 *(*image_handle)[3], TRUE);
138 DrawRectExtendGraphF(tab_x + 12, tab_y, tab_x + tab_width - 12,
139 tab_y + 12, 0, 0, 1, 12, *(*image_handle)[1], TRUE);
141 DrawRectExtendGraphF(tab_x + 12, tab_y + tab_height - 12,
142 tab_x + tab_width - 12, tab_y + tab_height, 0, 0, 1, 12,
143 *(*image_handle)[3], TRUE);
145 DrawRectExtendGraphF(tab_x, tab_y + 12, tab_x + 12,
146 tab_y + tab_height - 12, 0, 0, 12, 1, *(*image_handle)[2],
149 DrawRectExtendGraphF(tab_x + tab_width - 12, tab_y + 12,
150 tab_x + tab_width, tab_y + tab_height - 12, 0, 0, 12, 1,
151 *(*image_handle)[3], TRUE);
153 DrawRectExtendGraphF(tab_x + 12, tab_y + 12, tab_x + tab_width - 12,
154 tab_y + tab_height - 12, 0, 0, 1, 1, *(*image_handle)[3],
157 SetDrawBlendMode(DX_BLENDMODE_ALPHA, 100);
158 DrawStringToHandle(tab_x + 9, absolute_rect_.y + TAB_TOP_MARGIN + 1, unicode::ToTString(tab.name).c_str(),
159 GetColor(255, 255, 255), font_handle_);
160 SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
162 DrawStringToHandle(tab_x + 9, absolute_rect_.y + TAB_TOP_MARGIN, unicode::ToTString(tab.name).c_str(),
163 GetColor(0, 0, 0), font_handle_);
171 SetDrawBright(210, 47, 47);
173 int tab_x = script_tab_.x;
174 int tab_y = script_tab_.y;
175 int tab_width = script_tab_.width;
176 int tab_height = script_tab_.height;
178 std::array<ImageHandlePtr, 4>* image_handle;
179 if (IsScriptMode()) {
180 image_handle = &tab_bg_image_handle_;
182 image_handle = &tab_bg_inactive_image_handle_;
185 DrawGraph(tab_x, tab_y, *(*image_handle)[0], TRUE);
186 DrawGraph(tab_x + tab_width - 12, tab_y, *(*image_handle)[1], TRUE);
187 DrawGraph(tab_x, tab_y + tab_height - 12, *(*image_handle)[2], TRUE);
188 DrawGraph(tab_x + tab_width - 12, tab_y + tab_height - 12,
189 *(*image_handle)[3], TRUE);
191 DrawRectExtendGraphF(tab_x + 12, tab_y, tab_x + tab_width - 12,
192 tab_y + 12, 0, 0, 1, 12, *(*image_handle)[1], TRUE);
194 DrawRectExtendGraphF(tab_x + 12, tab_y + tab_height - 12,
195 tab_x + tab_width - 12, tab_y + tab_height, 0, 0, 1, 12,
196 *(*image_handle)[3], TRUE);
198 DrawRectExtendGraphF(tab_x, tab_y + 12, tab_x + 12,
199 tab_y + tab_height - 12, 0, 0, 12, 1, *(*image_handle)[2], TRUE);
201 DrawRectExtendGraphF(tab_x + tab_width - 12, tab_y + 12,
202 tab_x + tab_width, tab_y + tab_height - 12, 0, 0, 12, 1,
203 *(*image_handle)[3], TRUE);
205 DrawRectExtendGraphF(tab_x + 12, tab_y + 12, tab_x + tab_width - 12,
206 tab_y + tab_height - 12, 0, 0, 1, 1, *(*image_handle)[3], TRUE);
208 SetDrawBright(255, 255, 255);
210 DrawGraph(absolute_rect_.x + absolute_rect_.width - TAB_SIDE_MARGIN - 16, absolute_rect_.y + TAB_TOP_MARGIN,
211 *script_icon_image_handle_, TRUE);
215 void InputBox::DrawBase()
218 SetDrawBlendMode(DX_BLENDMODE_ADD, 255);
220 SetDrawBlendMode(DX_BLENDMODE_ADD, 150);
223 DrawGraph(absolute_rect_.x, absolute_rect_.y, *bg_image_handle_[0], TRUE);
224 DrawGraph(absolute_rect_.x + absolute_rect_.width - 24, absolute_rect_.y, *bg_image_handle_[1], TRUE);
225 DrawGraph(absolute_rect_.x, absolute_rect_.y + absolute_rect_.height - 24, *bg_image_handle_[2], TRUE);
226 DrawGraph(absolute_rect_.x + absolute_rect_.width - 24, absolute_rect_.y + absolute_rect_.height - 24, *bg_image_handle_[3], TRUE);
228 DrawRectExtendGraphF(absolute_rect_.x + 24, absolute_rect_.y,
229 absolute_rect_.x + absolute_rect_.width - 24, absolute_rect_.y + 24,
230 0, 0, 1, 24, *bg_image_handle_[1], TRUE);
232 DrawRectExtendGraphF(absolute_rect_.x + 24, absolute_rect_.y + absolute_rect_.height - 24,
233 absolute_rect_.x + absolute_rect_.width - 24, absolute_rect_.y + absolute_rect_.height,
234 0, 0, 1, 24, *bg_image_handle_[3], TRUE);
236 DrawRectExtendGraphF(absolute_rect_.x, absolute_rect_.y + 24,
237 absolute_rect_.x + 24, absolute_rect_.y + absolute_rect_.height - 24,
238 0, 0, 24, 1, *bg_image_handle_[2], TRUE);
240 DrawRectExtendGraphF(absolute_rect_.x + absolute_rect_.width - 24, absolute_rect_.y + 24,
241 absolute_rect_.x + absolute_rect_.width, absolute_rect_.y + absolute_rect_.height - 24,
242 0, 0, 24, 1, *bg_image_handle_[3], TRUE);
244 DrawRectExtendGraphF(absolute_rect_.x + 24, absolute_rect_.y + 24,
245 absolute_rect_.x + absolute_rect_.width - 24, absolute_rect_.y + absolute_rect_.height - 24,
246 0, 0, 1, 1, *bg_image_handle_[3], TRUE);
248 SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
251 void InputBox::Draw()
258 int InputBox::multiline() const
263 void InputBox::set_multiline(int multiline)
265 multiline_ = multiline;
268 void InputBox::CancelSelect()
270 input_.CancelSelect();
273 bool InputBox::IsScriptMode()
275 return selecting_tab_index_ == -1;
278 void InputBox::SetScriptMode()
283 void InputBox::SwitchTab(int index)
285 if (selecting_tab_index_ == -1) {
286 script_tab_.text = GetInputString();
287 } else if (!tabs_.empty()) {
288 tabs_.at(selecting_tab_index_).text = GetInputString();
291 selecting_tab_index_ = index;
293 if (selecting_tab_index_ == -1) {
294 SetInputString(script_tab_.text);
295 input_.set_message(script_tab_.message);
296 input_.set_reverse_color(true);
297 } else if (!tabs_.empty()) {
298 SetInputString(tabs_.at(selecting_tab_index_).text);
299 input_.set_message(tabs_.at(selecting_tab_index_).message);
300 input_.set_reverse_color(false);
304 tstring InputBox::GetInputString() const {
305 return input_.text();
308 void InputBox::SetInputString(const tstring& text)
310 input_.set_text(text);
313 void InputBox::ProcessInput(InputManager* input)
319 bool push_mouse_left = (input->GetMouseLeftCount() > 0);
321 bool first_key_shift = (input->GetKeyCount(KEY_INPUT_RSHIFT) == 1
322 || input->GetKeyCount(KEY_INPUT_LSHIFT) == 1);
324 bool push_key_esc = input->GetKeyCount(KEY_INPUT_ESCAPE) > 0;
326 bool push_key_shift = (input->GetKeyCount(KEY_INPUT_RSHIFT) > 0
327 || input->GetKeyCount(KEY_INPUT_LSHIFT) > 0);
329 bool push_key_v = (input->GetKeyCount(KEY_INPUT_V) > 0);
330 bool push_key_ctrl = (input->GetKeyCount(KEY_INPUT_LCONTROL) > 0
331 || input->GetKeyCount(KEY_INPUT_RCONTROL) > 0);
333 bool first_key_return = (input->GetKeyCount(KEY_INPUT_RETURN) == 1);
335 bool push_repeat_key_return = (input->GetKeyCount(KEY_INPUT_RETURN)
336 + KEY_REPEAT_FRAME) % (KEY_REPEAT_FRAME + 1) == 0;
337 bool push_repeat_key_up = (input->GetKeyCount(KEY_INPUT_UP)
338 + KEY_REPEAT_FRAME) % (KEY_REPEAT_FRAME + 1) == 0;
339 bool push_repeat_key_down = (input->GetKeyCount(KEY_INPUT_DOWN)
340 + KEY_REPEAT_FRAME) % (KEY_REPEAT_FRAME + 1) == 0;
341 bool push_long_backspace = (input->GetKeyCount(KEY_INPUT_BACK) > 60 * 1.5);
343 bool empty = input_.text().empty();
344 input_.ProcessInput(input);
346 if (IsActive() && ((first_key_return && !push_key_shift && empty) || push_key_esc)) {
348 } else if (!IsActive() && first_key_return) {
350 } else if (!IsActive() && push_key_v && push_key_ctrl) {
354 ProcessInputTabs(input);
359 int new_height = input_.height() + BOX_TOP_MARGIN + BOX_BOTTOM_MARGIN;
362 GetScreenState(nullptr, &screen_height, nullptr);
363 if (absolute_rect_.y + absolute_rect_.height > screen_height - BOX_TOP_MARGIN) {
364 absolute_rect_.y -= new_height - absolute_rect_.height;
365 // input_.set_y(y_ + BOX_TOP_MARGIN);
368 absolute_rect_.height = new_height;
370 input_.set_y(absolute_rect_.y + BOX_TOP_MARGIN);
371 input_.set_x(absolute_rect_.x + INPUT_MARGIN_X);
372 input_.set_width(absolute_rect_.width - INPUT_MARGIN_X * 2);
374 //line_buffer.clear();
377 //if (push_key_shift && (push_repeat_key_up || push_repeat_key_down)) {
378 // SetKeyInputSelectArea(GetKeyInputCursorPosition(input_handle_),
379 // prev_cursor_pos_, input_handle_);
385 input->CancelKeyCountAll();
389 void InputBox::Update()
394 void InputBox::ReloadTabs()
397 if (auto card_manager = manager_accessor_->card_manager().lock()) {
398 auto card_list = card_manager->cards();
399 int tab_offset_x = 0;
400 for (auto it = card_list.begin(); it != card_list.end(); ++it) {
402 if (card->HasInputEvent()) {
405 tab.name = unicode::ToTString(card->name());
407 tab.x = absolute_rect_.x + TAB_SIDE_MARGIN + tab_offset_x - 9;
408 tab.y = absolute_rect_.y - 3;
409 tab.height = font_height_ + TAB_TOP_MARGIN * 2 + 3 * 2;
411 auto name = unicode::ToTString(tab.name);
412 tab.width = GetDrawStringWidthToHandle(name.c_str(), name.size(),
415 tab_offset_x += tab.width + TAB_X_MARGIN;
417 tabs_.push_back(tab);
423 void InputBox::ProcessInputTabs(InputManager* input)
425 if (input->GetMouseLeftCount() == 1) {
428 for (auto it = tabs_.begin(); it != tabs_.end(); ++it) {
431 bool tab_hover = (tab.x <= input->GetMouseX()
432 && input->GetMouseX() <= tab.x + tab.width
433 && tab.y <= input->GetMouseY()
434 && input->GetMouseY() <= tab.y + tab.height);
437 SwitchTab(tab_index);
444 bool tab_hover = (script_tab_.x <= input->GetMouseX()
445 && input->GetMouseX() <= script_tab_.x + script_tab_.width
446 && script_tab_.y <= input->GetMouseY()
447 && input->GetMouseY() <= script_tab_.y + script_tab_.height);
456 void InputBox::UpdateTabs()
459 // if (input->GetKeyCount(InputManager::KEYBIND_SCRIPT_MODE) == 1) {
464 int tab_offset_x = 0;
465 BOOST_FOREACH(auto& tab, tabs_) {
466 tab.x = absolute_rect_.x + TAB_SIDE_MARGIN + tab_offset_x - 9;
467 tab.y = absolute_rect_.y - 3;
468 tab.height = font_height_ + TAB_TOP_MARGIN * 2 + 3 * 2;
470 auto name = unicode::ToTString(tab.name);
471 tab.width = GetDrawStringWidthToHandle(name.c_str(), name.size(),
474 tab_offset_x += tab.width - 3;
477 script_tab_.x = absolute_rect_.x + absolute_rect_.width - TAB_SIDE_MARGIN - 16 - 9;
478 script_tab_.y = absolute_rect_.y - 3;
479 script_tab_.width = 16 + 18;
480 script_tab_.height = font_height_ + TAB_TOP_MARGIN * 2 + 3 * 2;
484 void InputBox::UpdateBase(InputManager* input)
486 int screen_width, screen_height;
487 GetScreenState(&screen_width, &screen_height, nullptr);
489 bool hover = (absolute_rect_.x <= input->GetMouseX() && input->GetMouseX() <= absolute_rect_.x + absolute_rect_.width
490 && absolute_rect_.y <= input->GetMouseY() && input->GetMouseY() <= absolute_rect_.y + absolute_rect_.height);
492 //bool input_hover = (input_x_ <= input->GetMouseX()
493 // && input->GetMouseX() <= input_x_ + input_width_
494 // && input_y_ <= input->GetMouseY()
495 // && input->GetMouseY() <= input_y_ + input_height_);
497 bool corner_hover = (absolute_rect_.x + absolute_rect_.width - 18 <= input->GetMouseX()
498 && input->GetMouseX() <= absolute_rect_.x + absolute_rect_.width
499 && absolute_rect_.y + absolute_rect_.height - 18 <= input->GetMouseY()
500 && input->GetMouseY() <= absolute_rect_.y + absolute_rect_.height);
503 if (input->GetMouseLeft()) {
504 if (input->GetPrevMouseLeft() == 0 && drag_offset_x_ < 0 && hover
506 drag_offset_x_ = input->GetMouseX() - absolute_rect_.x;
507 drag_offset_y_ = input->GetMouseY() - absolute_rect_.y;
509 if (input->GetPrevMouseLeft() == 0 && drag_resize_offset_x_ < 0
511 drag_resize_offset_x_ = absolute_rect_.x + absolute_rect_.width - input->GetMouseX();
512 drag_resize_offset_y_ = absolute_rect_.y + absolute_rect_.height - input->GetMouseY();
514 if (hover && !IsActive()) {
516 } else if (!hover && IsActive()
517 && (drag_offset_x_ < 0 && drag_resize_offset_x_ < 0)) {
523 drag_resize_offset_x_ = -1;
524 drag_resize_offset_y_ = -1;
527 if (drag_offset_x_ >= 0) {
528 absolute_rect_.x = input->GetMouseX() - drag_offset_x_;
529 absolute_rect_.y = input->GetMouseY() - drag_offset_y_;
530 absolute_rect_.x = std::max(0, absolute_rect_.x); absolute_rect_.x = std::min(screen_width - absolute_rect_.width, absolute_rect_.x);
531 absolute_rect_.y = std::max(0, absolute_rect_.y); absolute_rect_.y = std::min(screen_height - absolute_rect_.height, absolute_rect_.y);
532 input->CancelMouseLeft();
533 } else if (drag_resize_offset_x_ >= 0) {
534 int new_width = input->GetMouseX() - absolute_rect_.x + drag_resize_offset_x_;
535 new_width = std::max(new_width, (BOX_MIN_WIDTH + 0));
536 new_width = std::min(new_width, screen_width - absolute_rect_.x);
537 absolute_rect_.width = new_width;
538 input->CancelMouseLeft();
543 bool InputBox::IsActive()
545 return input_.active();
548 void InputBox::Activate()
550 input_.set_active(true);
553 void InputBox::Inactivate()
555 input_.set_active(false);