Peoplemon  0.1.0
Peoplemon 3 game source documentation
ScreenKeyboard.cpp
Go to the documentation of this file.
2 
3 #include <BLIB/Engine.hpp>
4 #include <Core/Properties.hpp>
5 
6 namespace core
7 {
8 namespace system
9 {
10 namespace hud
11 {
12 namespace
13 {
14 constexpr float InputAreaHeight = 35.f;
15 }
16 
17 using namespace bl::menu;
18 
19 ScreenKeyboard::ScreenKeyboard(bl::engine::Engine& engine, const OnSubmit& os)
20 : engine(engine)
21 , onSubmit(os)
22 , minLen(0)
23 , maxLen(16)
24 , position() {}
25 
26 void ScreenKeyboard::lazyCreate() {
27  if (background.entity() != bl::ecs::InvalidEntity) { return; }
28 
29  keyboardMenu.create(
30  engine, engine.renderer().getObserver(), ArrowSelector::create(8.f, sf::Color::Black));
31 
32  Item::Ptr space = TextItem::create("(space)", Properties::MenuFont(), sf::Color::Black, 24);
33  space->getSignal(Item::EventType::Activated).willAlwaysCall([this]() {
34  input.push_back(' ');
35  renderedInput.getSection().setString(input);
36  });
37 
38  Item::Ptr del = TextItem::create("(del)", Properties::MenuFont(), sf::Color::Red, 24);
39  del->getSignal(Item::EventType::Activated).willAlwaysCall([this]() {
40  input.pop_back();
41  renderedInput.getSection().setString(input);
42  });
43 
44  Item::Ptr submit = TextItem::create("Submit", Properties::MenuFont(), sf::Color::Green, 24);
45  submit->getSignal(Item::EventType::Activated)
46  .willAlwaysCall(std::bind(&ScreenKeyboard::onEnter, this));
47 
48  std::vector<std::vector<TextItem::Ptr>> keys;
49  keys.resize(4);
50  for (unsigned int i = 0; i < 4; ++i) { keys[i].reserve(static_cast<std::size_t>(13)); }
51 
52  const auto createKey = [this, &keys](unsigned int i, char k) {
53  keys[i].emplace_back(
54  TextItem::create(std::string(1, k), Properties::MenuFont(), sf::Color::Black, 24));
55  keys[i]
56  .back()
57  ->getSignal(Item::EventType::Activated)
58  .willAlwaysCall(std::bind(&ScreenKeyboard::onKeyPress, this, k));
59  };
60 
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); }
65 
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);
74 
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); }
80  }
81  keyboardMenu.attachExisting(keys[0].back().get(), keys[0].front().get(), Item::Left);
82 
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);
87  }
88  else { keyboardMenu.addItem(keys[i][j], keys[i][j - 1].get(), Item::Right); }
89  if (j > 0) {
90  keyboardMenu.attachExisting(keys[i][j].get(), keys[i][j - 1].get(), Item::Right);
91  }
92  }
93  keyboardMenu.attachExisting(keys[i].back().get(), keys[i].front().get(), Item::Left);
94  }
95 
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); }
98  else {
99  keyboardMenu.attachExisting(submit.get(), keys.back()[i].get(), Item::Bottom, false);
100  }
101  }
102  keyboardMenu.setSelectedItem(keys[0][0].get());
103  keyboardMenu.setDepth(0.f);
104 
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);
115 
116  renderedInput.create(engine, core::Properties::MenuFont(), "", 28, sf::Color::Black);
117  renderedInput.getTransform().setPosition(15.f, 5.f);
118  renderedInput.setParent(background);
119 }
120 
122 
123 void ScreenKeyboard::start(unsigned int mn, unsigned int mx) {
124  lazyCreate();
125 
126  minLen = mn;
127  maxLen = mx;
128  input.clear();
129  renderedInput.getSection().setString(input);
130  inputDriver.drive(&keyboardMenu);
131 
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());
136 }
137 
139  inputDriver.drive(nullptr);
140  if (background.entity() != bl::ecs::InvalidEntity) { background.removeFromScene(); }
141 }
142 
143 void ScreenKeyboard::process(unsigned int ctrl, bool ignore) {
144  inputDriver.sendControl(ctrl, ignore);
145 }
146 
147 void ScreenKeyboard::setPosition(const sf::Vector2f& pos) {
148  position = pos;
149  if (background.entity() != bl::ecs::InvalidEntity) {
150  background.getTransform().setPosition(pos.x, pos.y);
151  }
152 }
153 
154 const std::string& ScreenKeyboard::value() const { return input; }
155 
156 sf::Vector2f ScreenKeyboard::getSize() const {
157  return {background.getSize().x, background.getSize().y};
158 }
159 
160 void ScreenKeyboard::onKeyPress(char c) {
161  input.push_back(c);
162  renderedInput.getSection().setString(input);
163 }
164 
165 void ScreenKeyboard::onEnter() {
166  if (input.size() >= minLen && input.size() <= maxLen) { onSubmit(input); }
167 }
168 
169 } // namespace hud
170 } // namespace system
171 } // namespace core
Core classes and functionality for both the editor and game.
static const sf::VulkanFont & MenuFont()
Definition: Properties.cpp:363
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.