3 #include <BLIB/Engine.hpp>
14 constexpr
float InputAreaHeight = 35.f;
17 using namespace bl::menu;
26 void ScreenKeyboard::lazyCreate() {
27 if (background.entity() != bl::ecs::InvalidEntity) {
return; }
30 engine, engine.renderer().getObserver(), ArrowSelector::create(8.f, sf::Color::Black));
33 space->getSignal(Item::EventType::Activated).willAlwaysCall([
this]() {
35 renderedInput.getSection().setString(input);
39 del->getSignal(Item::EventType::Activated).willAlwaysCall([
this]() {
41 renderedInput.getSection().setString(input);
45 submit->getSignal(Item::EventType::Activated)
46 .willAlwaysCall(std::bind(&ScreenKeyboard::onEnter,
this));
48 std::vector<std::vector<TextItem::Ptr>> keys;
50 for (
unsigned int i = 0; i < 4; ++i) { keys[i].reserve(
static_cast<std::size_t
>(13)); }
52 const auto createKey = [
this, &keys](
unsigned int i,
char k) {
57 ->getSignal(Item::EventType::Activated)
58 .willAlwaysCall(std::bind(&ScreenKeyboard::onKeyPress,
this, k));
61 for (
char l =
'A'; l <=
'M'; ++l) { createKey(0, l); }
62 for (
char l =
'N'; l <=
'Z'; ++l) { createKey(1, l); }
63 for (
char l =
'a'; l <=
'm'; ++l) { createKey(2, l); }
64 for (
char l =
'n'; l <=
'z'; ++l) { createKey(3, l); }
66 Item* topRow[3] = {space.get(), del.get(), submit.get()};
67 keyboardMenu.setPosition({3.f, InputAreaHeight - 6.f});
68 keyboardMenu.setMinWidth(28.f);
69 keyboardMenu.setMinHeight(30.f);
70 keyboardMenu.setPadding({18.f, 4.f});
71 keyboardMenu.setRootItem(space);
72 keyboardMenu.addItem(del, space.get(), Item::Right);
73 keyboardMenu.addItem(submit, del.get(), Item::Right);
75 keyboardMenu.addItem(keys[0][0], space.get(), Item::Bottom);
76 for (
unsigned int i = 1; i < keys[0].size(); ++i) {
77 keyboardMenu.addItem(keys[0][i], keys[0][i - 1].get(), Item::Right);
78 if (i < 3) { keyboardMenu.attachExisting(keys[0][i].get(), topRow[i], Item::Bottom); }
79 else { keyboardMenu.attachExisting(submit.get(), keys[0][i].get(), Item::Top,
false); }
81 keyboardMenu.attachExisting(keys[0].back().get(), keys[0].front().get(), Item::Left);
83 for (
unsigned int i = 1; i < 4; ++i) {
84 for (
unsigned int j = 0; j < keys[i].size(); ++j) {
85 if (j < keys[i - 1].size()) {
86 keyboardMenu.addItem(keys[i][j], keys[i - 1][j].get(), Item::Bottom);
88 else { keyboardMenu.addItem(keys[i][j], keys[i][j - 1].get(), Item::Right); }
90 keyboardMenu.attachExisting(keys[i][j].get(), keys[i][j - 1].get(), Item::Right);
93 keyboardMenu.attachExisting(keys[i].back().get(), keys[i].front().get(), Item::Left);
96 for (
unsigned int i = 0; i < keys.back().size(); ++i) {
97 if (i < 3) { keyboardMenu.attachExisting(keys.back()[i].get(), topRow[i], Item::Top); }
99 keyboardMenu.attachExisting(submit.get(), keys.back()[i].get(), Item::Bottom,
false);
102 keyboardMenu.setSelectedItem(keys[0][0].get());
103 keyboardMenu.setDepth(0.f);
105 background.create(engine,
106 {keyboardMenu.getBounds().width + 28.f,
107 keyboardMenu.getBounds().height + InputAreaHeight + 20.f});
108 background.setFillColor(sf::Color::White);
109 background.setOutlineColor(sf::Color::Black);
110 background.setOutlineThickness(2.f);
111 background.getTransform().setPosition(position.x, position.y);
112 background.getTransform().setDepth(bl::cam::OverlayCamera::MinDepth);
113 engine.ecs().setEntityParentDestructionBehavior(
114 background.entity(), bl::ecs::ParentDestructionBehavior::OrphanedByParent);
117 renderedInput.getTransform().setPosition(15.f, 5.f);
118 renderedInput.setParent(background);
129 renderedInput.getSection().setString(input);
130 inputDriver.drive(&keyboardMenu);
132 const auto overlay = engine.renderer().getObserver().getOrCreateSceneOverlay();
133 background.addToScene(overlay, bl::rc::UpdateSpeed::Static);
134 renderedInput.addToScene(overlay, bl::rc::UpdateSpeed::Static);
135 keyboardMenu.addToOverlay(background.entity());
139 inputDriver.drive(
nullptr);
140 if (background.entity() != bl::ecs::InvalidEntity) { background.removeFromScene(); }
144 inputDriver.sendControl(ctrl, ignore);
149 if (background.entity() != bl::ecs::InvalidEntity) {
150 background.getTransform().setPosition(pos.x, pos.y);
157 return {background.getSize().x, background.getSize().y};
160 void ScreenKeyboard::onKeyPress(
char c) {
162 renderedInput.getSection().setString(input);
165 void ScreenKeyboard::onEnter() {
166 if (input.size() >= minLen && input.size() <= maxLen) { onSubmit(input); }
Core classes and functionality for both the editor and game.
static const sf::VulkanFont & MenuFont()
std::function< void(const std::string &)> OnSubmit
sf::Vector2f getSize() const
Returns the size of the screen keyboard.
void start(unsigned int minLen=0, unsigned int maxLen=16)
Subscribes the keyboard to the event bus.
void process(unsigned int ctrl, bool ignoreDebounce)
Handles player input.
void setPosition(const sf::Vector2f &position)
Sets the position of the keyboard. The default is (??)
void stop()
Unsubscribes the keyboard from the event bus.
ScreenKeyboard(bl::engine::Engine &engine, const OnSubmit &onSubmit)
Construct a new Screen Keyboard.
~ScreenKeyboard()
Unsubscribes the keyboard if still subscribed.
const std::string & value() const
Returns the current input value.