TDME2  1.9.200
BasePropertiesSubController.cpp
Go to the documentation of this file.
2 
3 #include <map>
4 #include <memory>
5 #include <string>
6 #include <vector>
7 
8 #include <tdme/tdme.h>
12 #include <tdme/engine/Engine.h>
15 #include <tdme/gui/nodes/GUINode.h>
19 #include <tdme/gui/GUI.h>
20 #include <tdme/gui/GUIParser.h>
27 #include <tdme/utilities/Action.h>
28 #include <tdme/utilities/Console.h>
32 
33 using std::make_unique;
34 using std::map;
35 using std::string;
36 using std::unique_ptr;
37 using std::vector;
38 
62 
63 BasePropertiesSubController::BasePropertiesSubController(EditorView* editorView, const string& rootNode)
64 {
65  this->editorView = editorView;
66  this->view = make_unique<BasePropertiesSubView>(this);
67  this->popUps = editorView->getPopUps();
68  this->rootNodeId = rootNode;
69 }
70 
72 }
73 
75 {
76  this->screenNode = screenNode;
77 }
78 
80  if (prototype->getPropertyCount() > 0) {
81  xml+= "<selectbox-parent-option image=\"resources/engine/images/folder.png\" text=\"" + GUIParser::escape("Properties") + "\" value=\"" + GUIParser::escape("properties") + "\">\n";
82  for (auto property: prototype->getProperties()) {
83  xml+= " <selectbox-option image=\"resources/engine/images/script.png\" text=\"" + GUIParser::escape(property->getName() + ": " + property->getValue()) + "\" id=\"" + GUIParser::escape("properties." + property->getName()) + "\" value=\"" + GUIParser::escape("properties." + property->getName()) + "\" />\n";
84  }
85  xml+= "</selectbox-parent-option>\n";
86  }
87 }
88 
91  "<template id=\"details_base\" src=\"resources/engine/gui/template_details_base.xml\" />\n"
92  );
93 
94  try {
95  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("details_base"))->getActiveConditions().add("open");
96  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("base_name"))->getController()->setValue(MutableString(baseProperties->getName()));
97  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("base_description"))->getController()->setValue(MutableString(baseProperties->getDescription()));
98  if (prototype != nullptr) {
99  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("details_base"))->getActiveConditions().add("entity_hierarchy");
100  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("base_prototype_entityhierarchy"))->getController()->setValue(MutableString(prototype->isEntityHierarchy() == true?"1":""));
101  }
102  } catch (Exception& exception) {
103  Console::println("PrototypeBaseSubController::setPrototypeBaseDetails(): An error occurred: " + string(exception.what()));
104  showInfoPopUp("Warning", string(exception.what()));
105  }
106 }
107 
109  try {
110  baseProperties->setName(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("base_name"))->getController()->getValue().getString());
111  baseProperties->setDescription(required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("base_description"))->getController()->getValue().getString());
112  } catch (Exception& exception) {
113  Console::println("PrototypeBaseSubController::applyPrototypeBaseDetails(): An error occurred: " + string(exception.what()));
114  showInfoPopUp("Warning", string(exception.what()));
115  }
116 }
117 
118 void BasePropertiesSubController::setPropertyDetails(BaseProperties* baseProperties, const string& propertyName) {
119  auto property = baseProperties->getProperty(propertyName);
120  if (property == nullptr) return;
121 
123  "<template id=\"details_property\" src=\"resources/engine/gui/template_details_property.xml\" />\n"
124  );
125 
126  try {
127  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("details_property"))->getActiveConditions().add("open");
128  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("property_value"))->getController()->setValue(MutableString(property->getValue()));
129  } catch (Exception& exception) {
130  Console::println("PrototypeBaseSubController::setPropertyDetails(): An error occurred: " + string(exception.what()));
131  showInfoPopUp("Warning", string(exception.what()));
132  }
133 }
134 
135 void BasePropertiesSubController::updateDetails(BaseProperties* baseProperties, const string& outlinerNode, Prototype* prototype) {
136  if (outlinerNode == rootNodeId) {
137  setBasePropertiesDetails(baseProperties, prototype);
138  } else
139  if (StringTools::startsWith(outlinerNode, "properties.") == true) {
140  auto selectedPropertyName = StringTools::substring(outlinerNode, string("properties.").size(), outlinerNode.size());
141  setPropertyDetails(baseProperties, selectedPropertyName);
142  }
143 }
144 
145 void BasePropertiesSubController::applyPropertyDetails(BaseProperties* baseProperties, const string& propertyName) {
146  try {
147  if (baseProperties->updateProperty(
148  propertyName,
149  propertyName,
150  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("property_value"))->getController()->getValue().getString()) == false) {
151  throw ExceptionBase("Could not apply property details");
152  }
153  } catch (Exception& exception) {
154  Console::println("PrototypeBaseSubController::applyPropertyDetails(): An error occurred: " + string(exception.what()));
155  showInfoPopUp("Warning", string(exception.what()));
156  }
157 }
158 
160  auto propertyCreated = false;
161  auto propertyName = string() + "New property";
162  if (baseProperties->addProperty(
163  propertyName,
164  "No value"
165  ) == true) {
166  propertyCreated = true;
167  } else {
168  //
169  for (auto i = 1; i < 10001; i++) {
170  propertyName = string() + "New property " + to_string(i);
171  if (baseProperties->addProperty(
172  propertyName,
173  "No value"
174  ) == true) {
175  propertyCreated = true;
176  //
177  break;
178  }
179  }
180  }
181  try {
182  if (propertyCreated == false) {
183  throw ExceptionBase("Could not create property");
184  }
185  } catch (Exception& exception) {
186  Console::println("PrototypeBaseSubController::createProperty(): An error occurred: " + string(exception.what()));
187  showInfoPopUp("Warning", string(exception.what()));
188  }
189 
190  if (propertyCreated == true) {
191  editorView->reloadTabOutliner(string() + "properties." + propertyName);
193  baseProperties,
194  propertyName
195  );
196  }
197 }
198 
199 void BasePropertiesSubController::startRenameProperty(BaseProperties* baseProperties, const string& propertyName) {
200  auto property = baseProperties->getProperty(propertyName);
201  if (property == nullptr) return;
202  auto selectBoxOptionParentNode = dynamic_cast<GUIParentNode*>(editorView->getScreenController()->getScreenNode()->getNodeById("properties." + propertyName));
203  if (selectBoxOptionParentNode == nullptr) return;
204  renamePropertyName = propertyName;
205  selectBoxOptionParentNode->replaceSubNodes(
206  "<template id=\"tdme.properties.rename_input\" hint=\"Property name\" text=\"" + GUIParser::escape(property->getName()) + "\"src=\"resources/engine/gui/template_outliner_rename.xml\" />\n",
207  true
208  );
209  Engine::getInstance()->getGUI()->setFoccussedNode(dynamic_cast<GUIElementNode*>(editorView->getScreenController()->getScreenNode()->getNodeById("tdme.properties.rename_input")));
210  editorView->getScreenController()->getScreenNode()->forwardChange(required_dynamic_cast<GUIElementNode*>(editorView->getScreenController()->getScreenNode()->getNodeById("selectbox_outliner")));
211 }
212 
214  auto property = baseProperties->getProperty(renamePropertyName);
215  renamePropertyName.clear();
216  if (property != nullptr) {
217  try {
218  if (baseProperties->renameProperty(
219  property->getName(),
220  required_dynamic_cast<GUIElementNode*>(screenNode->getNodeById("tdme.properties.rename_input"))->getController()->getValue().getString()
221  ) == false) {
222  //
223  throw ExceptionBase("Could not rename property");
224  }
225  } catch (Exception& exception) {
226  Console::println("PrototypeBaseSubController::renameProperty(): An error occurred: " + string(exception.what()));
227  showInfoPopUp("Warning", string(exception.what()));
228  }
229  }
230 
231  //
232  editorView->reloadTabOutliner("properties" + (property != nullptr?"." + property->getName():""));
233 }
234 
236 {
237  if (node->getId() == "dropdown_outliner_add") {
238  auto addOutlinerType = node->getController()->getValue().getString();
239  if (addOutlinerType == "property") {
240  createProperty(baseProperties);
241  return true;
242  }
243  } else
244  if (node->getId() == "selectbox_outliner") {
245  auto outlinerNode = editorView->getScreenController()->getOutlinerSelection();
246  if (StringTools::startsWith(outlinerNode, "properties.") == true) {
247  auto selectedPropertyName = StringTools::substring(outlinerNode, string("properties.").size(), outlinerNode.size());
248  setPropertyDetails(baseProperties, selectedPropertyName);
249  return true;
250  }
251  } else
252  if (prototype != nullptr && node->getId() == "base_prototype_entityhierarchy") {
253  prototype->setEntityHierarchy(node->getController()->getValue().equals("1"));
254  return true;
255  }
256  //
257  return false;
258 }
259 
261 {
262  if (type == GUIActionListenerType::PERFORMED) {
263  if (node->getId() == "tdme.properties.rename_input") {
264  renameProperty(baseProperties);
265  return true;
266  }
267  }
268  //
269  return false;
270 }
271 
273  return false;
274 }
275 
277  if (node->getId() == "tdme.properties.rename_input") {
278  renameProperty(baseProperties);
279  return true;
280  } else {
281  for (const auto& applyPropertyNode: applyPropertyNodes) {
282  if (node->getId() == applyPropertyNode) {
283  applyPropertyValue(baseProperties);
284  return true;
285  }
286  }
287  for (const auto& applyBaseNode: applyBaseNodes) {
288  if (node->getId() == applyBaseNode) {
289  applyPropertyDetails(baseProperties);
290  return true;
291  }
292  }
293  }
294  //
295  return false;
296 }
297 
298 void BasePropertiesSubController::onContextMenuRequest(GUIElementNode* node, int mouseX, int mouseY, BaseProperties* baseProperties) {
299  if (node->getId() == "selectbox_outliner") {
300  auto outlinerNode = editorView->getScreenController()->getOutlinerSelection();
301  if (outlinerNode == "properties") {
302  // clear
304  // add
305  class OnAddPropertyAction: public virtual Action
306  {
307  public:
308  void performAction() override {
309  prototypeBaseSubController->createProperty(baseProperties);
310  }
311  OnAddPropertyAction(BasePropertiesSubController* prototypeBaseSubController, BaseProperties* baseProperties): prototypeBaseSubController(prototypeBaseSubController), baseProperties(baseProperties) {
312  }
313  private:
314  BasePropertiesSubController* prototypeBaseSubController;
315  BaseProperties* baseProperties;
316  };
317  popUps->getContextMenuScreenController()->addMenuItem("Add Property", "contextmenu_add", new OnAddPropertyAction(this, baseProperties));
318  //
319  popUps->getContextMenuScreenController()->show(mouseX, mouseY);
320  } else
321  if (StringTools::startsWith(outlinerNode, "properties.") == true) {
322  // clear
324  // rename
325  class OnRenameAction: public virtual Action
326  {
327  public:
328  void performAction() override {
329  auto outlinerNode = prototypeBaseSubController->editorView->getScreenController()->getOutlinerSelection();
330  if (StringTools::startsWith(outlinerNode, "properties.") == true) {
331  prototypeBaseSubController->startRenameProperty(
332  baseProperties,
333  StringTools::substring(outlinerNode, string("properties.").size(), outlinerNode.size())
334  );
335  }
336  }
337  OnRenameAction(BasePropertiesSubController* prototypeBaseSubController, BaseProperties* baseProperties): prototypeBaseSubController(prototypeBaseSubController), baseProperties(baseProperties) {
338  }
339  private:
340  BasePropertiesSubController* prototypeBaseSubController;
341  BaseProperties* baseProperties;
342  };
343  popUps->getContextMenuScreenController()->addMenuItem("Rename", "contextmenu_rename", new OnRenameAction(this, baseProperties));
344 
345  // separator
347 
348  // delete
349  class OnDeleteAction: public virtual Action
350  {
351  public:
352  void performAction() override {
353  auto outlinerNode = prototypeBaseSubController->editorView->getScreenController()->getOutlinerSelection();
354  if (StringTools::startsWith(outlinerNode, "properties.") == true) {
355  auto selectedPropertyName = StringTools::substring(outlinerNode, string("properties.").size(), outlinerNode.size());
356  baseProperties->removeProperty(selectedPropertyName);
357  prototypeBaseSubController->editorView->reloadTabOutliner("properties");
358  }
359  }
360  OnDeleteAction(BasePropertiesSubController* prototypeBaseSubController, BaseProperties* baseProperties): prototypeBaseSubController(prototypeBaseSubController), baseProperties(baseProperties) {
361  }
362  private:
363  BasePropertiesSubController* prototypeBaseSubController;
364  BaseProperties* baseProperties;
365  };
366  popUps->getContextMenuScreenController()->addMenuItem("Delete", "contextmenu_delete", new OnDeleteAction(this, baseProperties));
367 
368  //
369  popUps->getContextMenuScreenController()->show(mouseX, mouseY);
370  }
371  }
372 }
373 
375  auto outlinerNode = editorView->getScreenController()->getOutlinerSelection();
376  auto selectedPropertyName = StringTools::substring(outlinerNode, string("properties.").size(), outlinerNode.size());
377  applyPropertyDetails(baseProperties, selectedPropertyName);
378  editorView->reloadTabOutliner(outlinerNode);
379 }
380 
381 void BasePropertiesSubController::showInfoPopUp(const string& caption, const string& message)
382 {
383  popUps->getInfoDialogScreenController()->show(caption, message);
384 }
Engine main class.
Definition: Engine.h:131
bool updateProperty(const string &oldName, const string &name, const string &value)
Update a property.
void setName(const string &name)
Set up name.
const BaseProperty * getProperty(const string &name) const
Retrieve property by name.
ConstUniquePtrSequenceIterator< BaseProperty > getProperties() const
bool addProperty(const string &name, const string &value)
Add a property.
bool removeProperty(const string &name)
Removes a property.
bool renameProperty(const string &oldName, const string &name)
Rename a property.
void setDescription(const string &description)
Set up description.
Base property model class.
Definition: BaseProperty.h:15
Prototype definition.
Definition: Prototype.h:55
void setEntityHierarchy(bool entityHierarchy)
Set entity hierarchy.
Definition: Prototype.h:250
GUI parser.
Definition: GUIParser.h:40
GUI node controller base class.
virtual const MutableString & getValue()=0
GUI node base class.
Definition: GUINode.h:64
GUINodeController * getController()
Definition: GUINode.h:661
const string & getId()
Definition: GUINode.h:339
GUI parent node base class thats supporting child nodes.
Definition: GUIParentNode.h:42
GUI screen node that represents a screen that can be rendered via GUI system.
Definition: GUIScreenNode.h:72
void forwardChange(GUIElementNode *node)
Forward change event.
GUINode * getNodeById(const string &nodeId)
Get GUI node by id.
void show(int mouseX, int mouseY)
Shows the pop up.
void addMenuItem(const string &text, const string &id, Action *action=nullptr)
Add menu item.
void show(const string &caption, const string &message)
Shows the pop up.
Pop ups controller accessor class.
Definition: PopUps.h:29
ContextMenuScreenController * getContextMenuScreenController()
Definition: PopUps.h:96
InfoDialogScreenController * getInfoDialogScreenController()
Definition: PopUps.h:75
bool onChange(GUIElementNode *node, BaseProperties *baseProperties, Prototype *prototype=nullptr)
On value changed.
void setBasePropertiesDetails(BaseProperties *baseProperties, Prototype *prototype=nullptr)
Set property base details.
void applyPropertyDetails(BaseProperties *baseProperties)
Apply property base details.
bool onUnfocus(GUIElementNode *node, BaseProperties *baseProperties)
On unfocus.
void onContextMenuRequest(GUIElementNode *node, int mouseX, int mouseY, BaseProperties *baseProperties)
On context menu requested.
bool onAction(GUIActionListenerType type, GUIElementNode *node, BaseProperties *baseProperties)
On action performed.
void setPropertyDetails(BaseProperties *baseProperties, const string &propertyName)
Set property details.
bool onFocus(GUIElementNode *node, BaseProperties *baseProperties)
On focus.
void updateDetails(BaseProperties *baseProperties, const string &outlinerNode, Prototype *prototype=nullptr)
Update details panel.
void createBasePropertiesXML(BaseProperties *baseProperties, string &xml)
Create base properties XML for outliner.
void showInfoPopUp(const string &caption, const string &message)
Show the information pop up / modal.
void startRenameProperty(BaseProperties *baseProperties, const string &propertyName)
Start rename property.
EditorScreenController * getScreenController()
Definition: EditorView.h:69
void setDetailsContent(const string &xml)
Set details content.
Definition: EditorView.cpp:404
void reloadTabOutliner(const string &newSelectionValue=string())
Reload tab outliner.
Definition: EditorView.cpp:408
Console class.
Definition: Console.h:29
Exception base class.
Definition: ExceptionBase.h:19
Mutable utf8 aware string class.
Definition: MutableString.h:23
bool equals(const string &s2) const
Equals.
const string & getString() const
String tools class.
Definition: StringTools.h:22
std::exception Exception
Exception base class.
Definition: Exception.h:18
Action Interface.
Definition: Action.h:11