2014-07-14 00:24:57 +08:00
|
|
|
// Aseprite Code Generator
|
2017-02-02 00:47:16 +08:00
|
|
|
// Copyright (c) 2014-2017 David Capello
|
2014-07-14 00:24:57 +08:00
|
|
|
//
|
|
|
|
// This file is released under the terms of the MIT license.
|
|
|
|
// Read LICENSE.txt for more information.
|
|
|
|
|
2015-02-16 02:29:16 +08:00
|
|
|
#include "gen/ui_class.h"
|
|
|
|
|
2014-07-14 00:24:57 +08:00
|
|
|
#include "base/exception.h"
|
|
|
|
#include "base/file_handle.h"
|
2016-11-02 06:14:05 +08:00
|
|
|
#include "base/fs.h"
|
2014-07-14 00:24:57 +08:00
|
|
|
#include "base/string.h"
|
2014-12-15 07:19:31 +08:00
|
|
|
#include "gen/common.h"
|
2014-07-14 00:24:57 +08:00
|
|
|
|
|
|
|
#include <iostream>
|
2014-12-15 07:19:31 +08:00
|
|
|
#include <vector>
|
2014-07-14 00:24:57 +08:00
|
|
|
|
|
|
|
typedef std::vector<TiXmlElement*> XmlElements;
|
|
|
|
|
|
|
|
static TiXmlElement* find_element_by_id(TiXmlElement* elem, const std::string& thisId)
|
|
|
|
{
|
|
|
|
const char* id = elem->Attribute("id");
|
|
|
|
if (id && id == thisId)
|
|
|
|
return elem;
|
|
|
|
|
|
|
|
TiXmlElement* child = elem->FirstChildElement();
|
|
|
|
while (child) {
|
|
|
|
TiXmlElement* match = find_element_by_id(child, thisId);
|
|
|
|
if (match)
|
|
|
|
return match;
|
|
|
|
|
|
|
|
child = child->NextSiblingElement();
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void collect_widgets_with_ids(TiXmlElement* elem, XmlElements& widgets)
|
|
|
|
{
|
|
|
|
TiXmlElement* child = elem->FirstChildElement();
|
|
|
|
while (child) {
|
|
|
|
const char* id = child->Attribute("id");
|
|
|
|
if (id)
|
|
|
|
widgets.push_back(child);
|
|
|
|
collect_widgets_with_ids(child, widgets);
|
|
|
|
child = child->NextSiblingElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static std::string convert_type(const std::string& name)
|
|
|
|
{
|
2015-12-17 05:14:04 +08:00
|
|
|
static std::string parent;
|
|
|
|
if (name != "item")
|
|
|
|
parent = name;
|
|
|
|
|
2014-07-14 00:24:57 +08:00
|
|
|
if (name == "box") return "ui::Box";
|
|
|
|
if (name == "button") return "ui::Button";
|
2014-09-08 13:27:41 +08:00
|
|
|
if (name == "buttonset") return "app::ButtonSet";
|
2014-07-14 00:24:57 +08:00
|
|
|
if (name == "check") return "ui::CheckBox";
|
2015-02-20 22:42:59 +08:00
|
|
|
if (name == "colorpicker") return "app::ColorButton";
|
2014-07-14 00:24:57 +08:00
|
|
|
if (name == "combobox") return "ui::ComboBox";
|
2015-03-20 02:21:28 +08:00
|
|
|
if (name == "dropdownbutton") return "app::DropDownButton";
|
2014-07-14 00:24:57 +08:00
|
|
|
if (name == "entry") return "ui::Entry";
|
2015-03-20 01:39:37 +08:00
|
|
|
if (name == "grid") return "ui::Grid";
|
2014-07-14 00:24:57 +08:00
|
|
|
if (name == "hbox") return "ui::HBox";
|
2015-12-17 05:14:04 +08:00
|
|
|
if (name == "item" && parent == "buttonset") return "app::ButtonSet::Item";
|
2014-07-14 00:24:57 +08:00
|
|
|
if (name == "label") return "ui::Label";
|
2014-08-10 12:12:31 +08:00
|
|
|
if (name == "link") return "ui::LinkLabel";
|
2014-07-14 00:24:57 +08:00
|
|
|
if (name == "listbox") return "ui::ListBox";
|
2014-08-10 12:12:31 +08:00
|
|
|
if (name == "panel") return "ui::Panel";
|
2015-12-11 03:51:48 +08:00
|
|
|
if (name == "popupwindow") return "ui::PopupWindow";
|
2014-07-14 00:24:57 +08:00
|
|
|
if (name == "radio") return "ui::RadioButton";
|
2015-12-01 02:08:18 +08:00
|
|
|
if (name == "search") return "app::SearchEntry";
|
2017-02-02 00:47:16 +08:00
|
|
|
if (name == "separator") return "ui::Separator";
|
2014-07-14 00:24:57 +08:00
|
|
|
if (name == "slider") return "ui::Slider";
|
2015-03-03 01:43:44 +08:00
|
|
|
if (name == "splitter") return "ui::Splitter";
|
2015-12-11 03:51:48 +08:00
|
|
|
if (name == "tipwindow") return "ui::TipWindow";
|
2014-07-14 00:24:57 +08:00
|
|
|
if (name == "vbox") return "ui::VBox";
|
|
|
|
if (name == "view") return "ui::View";
|
|
|
|
if (name == "window") return "ui::Window";
|
|
|
|
throw base::Exception("unknown widget name: " + name);
|
|
|
|
}
|
|
|
|
|
2016-12-23 01:18:25 +08:00
|
|
|
void gen_ui_class(TiXmlDocument* doc,
|
|
|
|
const std::string& inputFn,
|
|
|
|
const std::string& widgetId)
|
2014-07-14 00:24:57 +08:00
|
|
|
{
|
|
|
|
std::cout
|
|
|
|
<< "// Don't modify, generated file from " << inputFn << "\n"
|
|
|
|
<< "\n";
|
|
|
|
|
|
|
|
TiXmlHandle handle(doc);
|
|
|
|
TiXmlElement* elem = handle.FirstChild("gui").ToElement();
|
|
|
|
elem = find_element_by_id(elem, widgetId);
|
|
|
|
if (!elem) {
|
|
|
|
std::cout << "#error Widget not found: " << widgetId << "\n";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
XmlElements widgets;
|
|
|
|
collect_widgets_with_ids(elem, widgets);
|
|
|
|
|
|
|
|
std::string className = convert_xmlid_to_cppid(widgetId, true);
|
|
|
|
std::string fnUpper = base::string_to_upper(base::get_file_title(inputFn));
|
|
|
|
std::string widgetType = convert_type(elem->Value());
|
|
|
|
|
|
|
|
std::cout
|
|
|
|
<< "#ifndef GENERATED_" << fnUpper << "_H_INCLUDED\n"
|
|
|
|
<< "#define GENERATED_" << fnUpper << "_H_INCLUDED\n"
|
|
|
|
<< "#pragma once\n"
|
|
|
|
<< "\n"
|
|
|
|
<< "#include \"app/find_widget.h\"\n"
|
|
|
|
<< "#include \"app/load_widget.h\"\n"
|
|
|
|
<< "#include \"ui/ui.h\"\n"
|
|
|
|
<< "\n"
|
|
|
|
<< "namespace app {\n"
|
|
|
|
<< "namespace gen {\n"
|
|
|
|
<< "\n"
|
|
|
|
<< " class " << className << " : public " << widgetType << " {\n"
|
|
|
|
<< " public:\n"
|
|
|
|
<< " " << className << "()";
|
|
|
|
|
|
|
|
// Special ctor for base class
|
|
|
|
if (widgetType == "ui::Window") {
|
2015-03-03 01:43:44 +08:00
|
|
|
const char* desktop = elem->Attribute("desktop");
|
|
|
|
if (desktop && std::string(desktop) == "true")
|
|
|
|
std::cout
|
|
|
|
<< " : ui::Window(ui::Window::DesktopWindow)";
|
|
|
|
else
|
|
|
|
std::cout
|
|
|
|
<< " : ui::Window(ui::Window::WithTitleBar)";
|
2014-07-14 00:24:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
std::cout
|
|
|
|
<< " {\n"
|
|
|
|
<< " app::load_widget(\"" << base::get_file_name(inputFn) << "\", \"" << widgetId << "\", this);\n"
|
|
|
|
<< " app::finder(this)\n";
|
|
|
|
|
2016-12-23 01:18:25 +08:00
|
|
|
for (TiXmlElement* elem : widgets) {
|
|
|
|
const char* id = elem->Attribute("id");
|
2014-07-14 00:24:57 +08:00
|
|
|
std::string cppid = convert_xmlid_to_cppid(id, false);
|
|
|
|
std::cout
|
|
|
|
<< " >> \"" << id << "\" >> m_" << cppid << "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cout
|
|
|
|
<< " ;\n"
|
|
|
|
<< " }\n"
|
|
|
|
<< "\n";
|
|
|
|
|
2016-12-23 01:18:25 +08:00
|
|
|
for (TiXmlElement* elem : widgets) {
|
|
|
|
std::string childType = convert_type(elem->Value());
|
|
|
|
const char* id = elem->Attribute("id");
|
2014-07-14 00:24:57 +08:00
|
|
|
std::string cppid = convert_xmlid_to_cppid(id, false);
|
|
|
|
std::cout
|
2015-03-20 03:20:33 +08:00
|
|
|
<< " " << childType << "* " << cppid << "() const { return m_" << cppid << "; }\n";
|
2014-07-14 00:24:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
std::cout
|
|
|
|
<< "\n"
|
|
|
|
<< " private:\n";
|
|
|
|
|
2016-12-23 01:18:25 +08:00
|
|
|
for (TiXmlElement* elem : widgets) {
|
|
|
|
std::string childType = convert_type(elem->Value());
|
|
|
|
const char* id = elem->Attribute("id");
|
2014-07-14 00:24:57 +08:00
|
|
|
std::string cppid = convert_xmlid_to_cppid(id, false);
|
|
|
|
std::cout
|
|
|
|
<< " " << childType << "* m_" << cppid << ";\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cout
|
|
|
|
<< " };\n"
|
|
|
|
<< "\n"
|
|
|
|
<< "} // namespace gen\n"
|
|
|
|
<< "} // namespace app\n"
|
|
|
|
<< "\n"
|
|
|
|
<< "#endif\n";
|
|
|
|
}
|