Peoplemon  0.1.0
Peoplemon 3 game source documentation
ItemEditorWindow.cpp
Go to the documentation of this file.
2 
3 namespace editor
4 {
5 namespace component
6 {
7 namespace
8 {
9 template<typename T>
10 T parseInput(const bl::gui::TextEntry::Ptr& input) {
11  const long long val = std::atoll(input->getInput().c_str());
12  return static_cast<T>(val);
13 }
14 } // namespace
15 using namespace bl::gui;
16 
18 : itemDb(db)
19 , onChange(onChange) {
20  window = Window::create(LinePacker::create(LinePacker::Vertical, 4.f), "Editing Item");
21  window->getSignal(Event::Closed).willAlwaysCall(std::bind(&ItemEditorWindow::onCancel, this));
22 
23  LinePacker::Ptr rowPack = LinePacker::create(LinePacker::Horizontal, 4.f);
24  const auto onEdit = std::bind(&ItemEditorWindow::makeDirty, this);
25  applyBut = Button::create("Save");
26 
27  window->pack(Label::create("ID ranges:\n\t[1, 100] - Regular Items\n\t[101, 200] - Key "
28  "Items\n\t [201, inf] - TM's (MoveId = ItemId - 200)"));
29 
30  Box::Ptr row = Box::create(rowPack);
31  idEntry = TextEntry::create();
32  idEntry->setMode(TextEntry::Mode::Unsigned | TextEntry::Mode::Integer);
33  idEntry->getSignal(Event::TextEntered).willAlwaysCall(onEdit);
34  idEntry->setRequisition({60.f, 1.f});
35  nameEntry = TextEntry::create();
36  nameEntry->getSignal(Event::TextEntered).willAlwaysCall(onEdit);
37  nameEntry->setRequisition({160.f, 1.f});
38  valueEntry = TextEntry::create();
39  valueEntry->setMode(TextEntry::Mode::Unsigned | TextEntry::Mode::Integer);
40  valueEntry->getSignal(Event::TextEntered).willAlwaysCall(onEdit);
41  valueEntry->setRequisition({60.f, 1.f});
42  row->pack(Label::create("Id:"), false, true);
43  row->pack(idEntry, false, true);
44  row->pack(Label::create("Name:"), false, true);
45  row->pack(nameEntry, false, true);
46  row->pack(Label::create("Value:"), false, true);
47  row->pack(valueEntry, false, true);
48  window->pack(row, true, false);
49 
50  row = Box::create(rowPack);
51  descEntry = TextEntry::create();
52  descEntry->getSignal(Event::TextEntered).willAlwaysCall(onEdit);
53  descEntry->setRequisition({400.f, 1.f});
54  row->pack(Label::create("Description:"), false, true);
55  row->pack(descEntry, false, true);
56  window->pack(row, true, false);
57 
58  row = Box::create(LinePacker::create(
59  LinePacker::Horizontal, 4.f, LinePacker::Compact, LinePacker::RightAlign));
60  Button::Ptr cancelBut = Button::create("Cancel");
61  cancelBut->getSignal(Event::LeftClicked)
62  .willAlwaysCall(std::bind(&ItemEditorWindow::onCancel, this));
63  row->pack(cancelBut, false, true);
64  applyBut->getSignal(Event::LeftClicked)
65  .willAlwaysCall(std::bind(&ItemEditorWindow::onSave, this));
66  row->pack(applyBut, false, true);
67  window->pack(row, true, false);
68 }
69 
70 void ItemEditorWindow::open(bl::gui::GUI* parent, core::item::Id item) {
71  using Item = core::item::Item;
72 
73  openId = item;
74  doingNewItem = item == core::item::Id::Unknown;
75 
76  idEntry->setInput(doingNewItem ? "" : std::to_string(static_cast<int>(item)));
77  nameEntry->setInput(doingNewItem ? "" : Item::getName(item));
78  descEntry->setInput(doingNewItem ? "" : Item::getDescription(item));
79  valueEntry->setInput(doingNewItem ? "100" : std::to_string(Item::getValue(item)));
80 
81  dirty = false;
82  applyBut->setColor(sf::Color(20, 240, 50), sf::Color::Black);
83  parent->pack(window);
84  window->setForceFocus(true);
85 }
86 
87 void ItemEditorWindow::makeDirty() {
88  dirty = true;
89  applyBut->setColor(sf::Color(230, 30, 30), sf::Color::Black);
90 }
91 
92 void ItemEditorWindow::onSave() {
93  const auto error = [](const std::string& e) {
94  bl::dialog::tinyfd_messageBox("Error", e.c_str(), "ok", "error", 1);
95  };
96 
97  const core::item::Id id = parseInput<core::item::Id>(idEntry);
98  const int value = parseInput<int>(valueEntry);
99 
100  if (nameEntry->getInput().empty()) {
101  error("Please enter a name");
102  return;
103  }
104  if (descEntry->getInput().empty()) {
105  error("Please enter a description");
106  return;
107  }
108  if (idEntry->getInput().empty()) {
109  error("Please enter an id");
110  return;
111  }
112  if (valueEntry->getInput().empty()) { error("Please enter a value"); }
113  if (openId != id && itemDb.names.find(id) != itemDb.names.end()) {
114  if (1 != bl::dialog::tinyfd_messageBox(
115  "Warning", "Id already exists. Overwrite it?", "yesno", "warning", 0)) {
116  return;
117  }
118  }
119 
120  itemDb.names[id] = nameEntry->getInput();
121  itemDb.descriptions[id] = descEntry->getInput();
122  itemDb.values[id] = value;
123 
124  onChange();
125  close();
126 }
127 
128 void ItemEditorWindow::onCancel() {
129  if (dirty) {
130  if (1 != bl::dialog::tinyfd_messageBox(
131  "Warning", "Discard unsaved changes?", "yesno", "warning", 0)) {
132  return;
133  }
134  }
135  close();
136 }
137 
138 void ItemEditorWindow::close() {
139  window->setForceFocus(false);
140  window->remove();
141 }
142 
143 } // namespace component
144 } // namespace editor
Id
Represents an item in its simplist form.
Definition: Id.hpp:24
All classes and functionality used for implementing the game editor.
Definition: Tile.hpp:11
Loads and stores metadata surrounding items in the game.
Definition: ItemDB.hpp:24
std::unordered_map< item::Id, std::string > names
Definition: ItemDB.hpp:65
std::unordered_map< item::Id, std::string > descriptions
Definition: ItemDB.hpp:66
std::unordered_map< item::Id, std::int32_t > values
Definition: ItemDB.hpp:67
Collection of static methods centered around items.
Definition: Item.hpp:25
void open(bl::gui::GUI *parent, core::item::Id item)
Open the editor window.
std::function< void()> OnChange
Callback signature for when an item is modified.
ItemEditorWindow(core::file::ItemDB &db, const OnChange &onChange)
Construct a new Item Editor Window.