summaryrefslogtreecommitdiff
path: root/src/inputManager.cpp
blob: d392081f43b047ce9464ffc702103c6f048848e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include "inputManager.hpp"
#include "IOManager.hpp"
#include "chatManager.hpp"
#include "commandHandler.hpp"
#include "log.hpp"
#include "renderManager.hpp"
#include "scroller.hpp"

CInputManager::CInputManager()
	: m_input(ftxui::Input(&m_szInput, "Type here...", {.transform = [](ftxui::InputState state) {
    state.element |= ftxui::bgcolor(ftxui::Color::HSVA(0, 0, 0, 0));
    state.element |= ftxui::color(ftxui::Color::White);
  return state.element; }, .multiline = false, .on_enter = [&] {
											if (m_szInput.empty())
												return;

											g_pCommandHandler->isCommand(m_szInput) ? g_pCommandHandler->handleCommand(m_szInput) : g_pChatManager->newMessage({.msg = m_szInput, .username = "Server"});
											m_szInput.clear(); }}) // NOLINT
	  )
	, inputComponent(ftxui::Renderer(m_input, [&] {
		return ftxui::hbox({
			ftxui::text("> "),
			m_input->Render(),
		});
	}))
	, logComponent(ftxui::Renderer([] {
		std::vector<ftxui::Element> messages;
		for (const auto &[chat, log, custom] : g_pIOManager->getIO()) {
			if (chat && !chat->msg.empty()) {
				std::string username = chat->username;
				if (username.back() == '\n')
					username.pop_back();
				messages.push_back(ftxui::window(ftxui::text(username), ftxui::paragraph(chat->msg)));
			} else if (log && !log->log.empty())
				messages.push_back(ftxui::window(ftxui::text(NFormatter::fmt(log->type, "")), ftxui::paragraph(log->log)));
			else if (custom)
				messages.push_back(ftxui::window(ftxui::text(custom->first), ftxui::paragraph(custom->second)));
		}

		return ftxui::vbox(messages);
	})) {

	log(LOG, "InputManager: initialized");
}

CInputManager::~CInputManager() {
	log(SYS, "InputManager: bye");
}

void CInputManager::updateIO() {
	logComponent->OnEvent(ftxui::Event::Custom);
	g_pRenderManager->screen.PostEvent(ftxui::Event::Custom);
}

void CInputManager::inputLoop() {
	container = logComponent |= ftxui::Scroller;
	container = ftxui::ResizableSplitBottom(inputComponent, container, &bottomSize);

	// FIXME: this shit spams TakeFocus(not ideal for power etc reasons)
	// consider: custom loop, or just only allow focus to be inputComponent somehow
	container |= ftxui::CatchEvent([&](ftxui::Event) {
		inputComponent->TakeFocus();
		return false;
	});
	g_pRenderManager->setRenderer(ftxui::Renderer(container, [this] {
		return container->Render() | ftxui::border;
	}));
	inputComponent->TakeFocus();
	g_pRenderManager->enterLoop();
}