[olympic/studio/modlib] East const Studio
This commit is contained in:
		| @@ -10,6 +10,6 @@ | |||||||
|  |  | ||||||
| namespace studio { | namespace studio { | ||||||
|  |  | ||||||
| void registerModule(const studio::Module*) noexcept; | void registerModule(studio::Module const*) noexcept; | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -14,7 +14,6 @@ ClawEditor::ClawEditor(ox::CRStringView path, ox::ModelObject obj) noexcept: | |||||||
| } | } | ||||||
|  |  | ||||||
| void ClawEditor::draw(turbine::Context&) noexcept { | void ClawEditor::draw(turbine::Context&) noexcept { | ||||||
| 	//const auto paneSize = ImGui::GetContentRegionAvail(); |  | ||||||
| 	ImGui::BeginChild("PaletteEditor"); | 	ImGui::BeginChild("PaletteEditor"); | ||||||
| 	static constexpr auto flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody; | 	static constexpr auto flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody; | ||||||
| 	if (ImGui::BeginTable("ObjTree", 3, flags)) { | 	if (ImGui::BeginTable("ObjTree", 3, flags)) { | ||||||
| @@ -23,13 +22,13 @@ void ClawEditor::draw(turbine::Context&) noexcept { | |||||||
| 		ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_NoHide); | 		ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_NoHide); | ||||||
| 		ImGui::TableHeadersRow(); | 		ImGui::TableHeadersRow(); | ||||||
| 		ObjPath objPath; | 		ObjPath objPath; | ||||||
| 		drawTree(&objPath, m_obj); | 		drawTree(objPath, m_obj); | ||||||
| 		ImGui::EndTable(); | 		ImGui::EndTable(); | ||||||
| 	} | 	} | ||||||
| 	ImGui::EndChild(); | 	ImGui::EndChild(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void ClawEditor::drawRow(const ox::ModelValue &value) noexcept { | void ClawEditor::drawRow(ox::ModelValue const&value) noexcept { | ||||||
| 	using Str = ox::BasicString<100>; | 	using Str = ox::BasicString<100>; | ||||||
| 	Str val, type; | 	Str val, type; | ||||||
| 	switch (value.type()) { | 	switch (value.type()) { | ||||||
| @@ -93,56 +92,56 @@ void ClawEditor::drawRow(const ox::ModelValue &value) noexcept { | |||||||
| 	ImGui::Text("%s", val.c_str()); | 	ImGui::Text("%s", val.c_str()); | ||||||
| } | } | ||||||
|  |  | ||||||
| void ClawEditor::drawVar(ObjPath *path, ox::CRStringView name, const ox::ModelValue &value) noexcept { | void ClawEditor::drawVar(ObjPath &path, ox::CRStringView name, ox::ModelValue const&value) noexcept { | ||||||
| 	using Str = ox::BasicString<100>; | 	using Str = ox::BasicString<100>; | ||||||
| 	path->push_back(name); | 	path.push_back(name); | ||||||
| 	if (value.type() == ox::ModelValue::Type::Object) { | 	if (value.type() == ox::ModelValue::Type::Object) { | ||||||
| 		drawTree(path, value.get<ox::ModelObject>()); | 		drawTree(path, value.get<ox::ModelObject>()); | ||||||
| 	} else if (value.type() == ox::ModelValue::Type::Vector) { | 	} else if (value.type() == ox::ModelValue::Type::Vector) { | ||||||
| 		const auto &vec = value.get<ox::ModelValueVector>(); | 		auto const&vec = value.get<ox::ModelValueVector>(); | ||||||
| 		const auto pathStr = ox::join<Str>("##", *path).unwrap(); | 		auto const pathStr = ox::join<Str>("##", path).unwrap(); | ||||||
| 		const auto lbl = ox::sfmt<Str>("{}##{}", name, pathStr); | 		auto const lbl = ox::sfmt<Str>("{}##{}", name, pathStr); | ||||||
| 		const auto flags = ImGuiTreeNodeFlags_SpanFullWidth | 		auto const flags = ImGuiTreeNodeFlags_SpanFullWidth | ||||||
| 		                 | ImGuiTreeNodeFlags_OpenOnArrow | 		                 | ImGuiTreeNodeFlags_OpenOnArrow | ||||||
| 		                 | (vec.size() ? 0 : ImGuiTreeNodeFlags_Leaf) | 		                 | (vec.size() ? 0 : ImGuiTreeNodeFlags_Leaf) | ||||||
| 		                 | (false ? ImGuiTreeNodeFlags_Selected : 0); | 		                 | (false ? ImGuiTreeNodeFlags_Selected : 0); | ||||||
| 		const auto open = ImGui::TreeNodeEx(lbl.c_str(), flags); | 		auto const open = ImGui::TreeNodeEx(lbl.c_str(), flags); | ||||||
| 		ImGui::SameLine(); | 		ImGui::SameLine(); | ||||||
| 		drawRow(value); | 		drawRow(value); | ||||||
| 		if (open) { | 		if (open) { | ||||||
| 			for (auto i = 0lu; const auto &e: vec) { | 			for (auto i = 0lu; auto const&e: vec) { | ||||||
| 				const auto iStr = ox::sfmt<Str>("{}", i); | 				auto const iStr = ox::sfmt<Str>("{}", i); | ||||||
| 				path->push_back(iStr); | 				path.push_back(iStr); | ||||||
| 				ImGui::TableNextRow(0, 5); | 				ImGui::TableNextRow(0, 5); | ||||||
| 				ImGui::TableNextColumn(); | 				ImGui::TableNextColumn(); | ||||||
| 				drawVar(path, ox::sfmt<Str>("[{}]", i), e); | 				drawVar(path, ox::sfmt<Str>("[{}]", i), e); | ||||||
| 				path->pop_back(); | 				path.pop_back(); | ||||||
| 				++i; | 				++i; | ||||||
| 			} | 			} | ||||||
| 			ImGui::TreePop(); | 			ImGui::TreePop(); | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		const auto pathStr = ox::join<Str>("##", *path).unwrap(); | 		auto const pathStr = ox::join<Str>("##", path).unwrap(); | ||||||
| 		const auto lbl = ox::sfmt<Str>("{}##{}", name, pathStr); | 		auto const lbl = ox::sfmt<Str>("{}##{}", name, pathStr); | ||||||
| 		const auto flags = ImGuiTreeNodeFlags_SpanFullWidth | 		auto const flags = ImGuiTreeNodeFlags_SpanFullWidth | ||||||
| 		                   | ImGuiTreeNodeFlags_OpenOnArrow | 		                   | ImGuiTreeNodeFlags_OpenOnArrow | ||||||
| 		                   | ImGuiTreeNodeFlags_Leaf | 		                   | ImGuiTreeNodeFlags_Leaf | ||||||
| 		                   | (false ? ImGuiTreeNodeFlags_Selected : 0); | 		                   | (false ? ImGuiTreeNodeFlags_Selected : 0); | ||||||
| 		const auto open = ImGui::TreeNodeEx(lbl.c_str(), flags); | 		auto const open = ImGui::TreeNodeEx(lbl.c_str(), flags); | ||||||
| 		ImGui::SameLine(); | 		ImGui::SameLine(); | ||||||
| 		drawRow(value); | 		drawRow(value); | ||||||
| 		if (open) { | 		if (open) { | ||||||
| 			ImGui::TreePop(); | 			ImGui::TreePop(); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	path->pop_back(); | 	path.pop_back(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void ClawEditor::drawTree(ObjPath *path, const ox::ModelObject &obj) noexcept { | void ClawEditor::drawTree(ObjPath &path, ox::ModelObject const&obj) noexcept { | ||||||
| 	using Str = ox::BasicString<100>; | 	using Str = ox::BasicString<100>; | ||||||
| 	for (const auto &c : obj) { | 	for (const auto &c : obj) { | ||||||
| 		ImGui::TableNextRow(0, 5); | 		ImGui::TableNextRow(0, 5); | ||||||
| 		auto pathStr = ox::join<Str>("##", *path).unwrap(); | 		auto pathStr = ox::join<Str>("##", path).unwrap(); | ||||||
| 		auto lbl = ox::sfmt<Str>("{}##{}", c->name, pathStr); | 		auto lbl = ox::sfmt<Str>("{}##{}", c->name, pathStr); | ||||||
| 		const auto rowSelected = false; | 		const auto rowSelected = false; | ||||||
| 		const auto hasChildren = c->value.type() == ox::ModelValue::Type::Object | 		const auto hasChildren = c->value.type() == ox::ModelValue::Type::Object | ||||||
| @@ -152,13 +151,11 @@ void ClawEditor::drawTree(ObjPath *path, const ox::ModelObject &obj) noexcept { | |||||||
| 		                   | (hasChildren ? 0 : ImGuiTreeNodeFlags_Leaf) | 		                   | (hasChildren ? 0 : ImGuiTreeNodeFlags_Leaf) | ||||||
| 		                   | (rowSelected ? ImGuiTreeNodeFlags_Selected : 0); | 		                   | (rowSelected ? ImGuiTreeNodeFlags_Selected : 0); | ||||||
| 		ImGui::TableNextColumn(); | 		ImGui::TableNextColumn(); | ||||||
| 		if (ImGui::IsItemClicked()) { | 		//if (ImGui::IsItemClicked()) { | ||||||
| 			//model()->setActiveSubsheet(*path); | 		//} | ||||||
| 		} | 		//if (ImGui::IsMouseDoubleClicked(0) && ImGui::IsItemHovered()) { | ||||||
| 		if (ImGui::IsMouseDoubleClicked(0) && ImGui::IsItemHovered()) { | 		//} | ||||||
| 			//showSubsheetEditor(); | 		path.push_back(c->name); | ||||||
| 		} |  | ||||||
| 		path->push_back(c->name); |  | ||||||
| 		if (c->value.type() == ox::ModelValue::Type::Object) { | 		if (c->value.type() == ox::ModelValue::Type::Object) { | ||||||
| 			const auto open = ImGui::TreeNodeEx(lbl.c_str(), flags); | 			const auto open = ImGui::TreeNodeEx(lbl.c_str(), flags); | ||||||
| 			ImGui::SameLine(); | 			ImGui::SameLine(); | ||||||
| @@ -170,7 +167,7 @@ void ClawEditor::drawTree(ObjPath *path, const ox::ModelObject &obj) noexcept { | |||||||
| 		} else { | 		} else { | ||||||
| 			drawVar(path, c->name, c->value); | 			drawVar(path, c->name, c->value); | ||||||
| 		} | 		} | ||||||
| 		path->pop_back(); | 		path.pop_back(); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,11 +21,11 @@ class ClawEditor: public studio::Editor { | |||||||
| 		void draw(turbine::Context&) noexcept final; | 		void draw(turbine::Context&) noexcept final; | ||||||
|  |  | ||||||
| 	private: | 	private: | ||||||
| 		static void drawRow(const ox::ModelValue &value) noexcept; | 		static void drawRow(ox::ModelValue const&value) noexcept; | ||||||
|  |  | ||||||
| 		void drawVar(ObjPath *path, ox::CRStringView name, const ox::ModelValue &value) noexcept; | 		void drawVar(ObjPath &path, ox::CRStringView name, ox::ModelValue const&value) noexcept; | ||||||
|  |  | ||||||
| 		void drawTree(ObjPath *path, const ox::ModelObject &obj) noexcept; | 		void drawTree(ObjPath &path, ox::ModelObject const&obj) noexcept; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ | |||||||
|  |  | ||||||
| namespace studio { | namespace studio { | ||||||
|  |  | ||||||
| class FileDialogManager : public studio::Task { | class FileDialogManager: public studio::Task { | ||||||
| 	private: | 	private: | ||||||
| 		enum class UpdateProjectPathState { | 		enum class UpdateProjectPathState { | ||||||
| 				None, | 				None, | ||||||
| @@ -36,7 +36,7 @@ class FileDialogManager : public studio::Task { | |||||||
| 		studio::TaskState update(turbine::Context &ctx) noexcept final; | 		studio::TaskState update(turbine::Context &ctx) noexcept final; | ||||||
|  |  | ||||||
| 		// signals | 		// signals | ||||||
| 		ox::Signal<ox::Error(const ox::String &)> pathChosen; | 		ox::Signal<ox::Error(ox::String const&)> pathChosen; | ||||||
|  |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -57,7 +57,7 @@ static ox::Error runApp( | |||||||
| 	studioCtx.ui = &ui; | 	studioCtx.ui = &ui; | ||||||
| 	StudioUIDrawer drawer(ui); | 	StudioUIDrawer drawer(ui); | ||||||
| 	turbine::gl::addDrawer(*ctx, &drawer); | 	turbine::gl::addDrawer(*ctx, &drawer); | ||||||
| 	const auto err = turbine::run(*ctx); | 	auto const err = turbine::run(*ctx); | ||||||
| 	turbine::gl::removeDrawer(*ctx, &drawer); | 	turbine::gl::removeDrawer(*ctx, &drawer); | ||||||
| 	return err; | 	return err; | ||||||
| } | } | ||||||
| @@ -66,15 +66,15 @@ ox::Error run( | |||||||
| 		ox::CRStringView appName, | 		ox::CRStringView appName, | ||||||
| 		ox::CRStringView projectDataDir, | 		ox::CRStringView projectDataDir, | ||||||
| 		int, | 		int, | ||||||
| 		const char**) { | 		char const**) { | ||||||
| 	// seed UUID generator | 	// seed UUID generator | ||||||
| 	const auto time = std::time(nullptr); | 	auto const time = std::time(nullptr); | ||||||
| 	ox::UUID::seedGenerator({ | 	ox::UUID::seedGenerator({ | ||||||
| 		static_cast<uint64_t>(time), | 		static_cast<uint64_t>(time), | ||||||
| 		static_cast<uint64_t>(time << 1) | 		static_cast<uint64_t>(time << 1) | ||||||
| 	}); | 	}); | ||||||
| 	// run app | 	// run app | ||||||
| 	const auto err = runApp(appName, projectDataDir, ox::UniquePtr<ox::FileSystem>(nullptr)); | 	auto const err = runApp(appName, projectDataDir, ox::UniquePtr<ox::FileSystem>(nullptr)); | ||||||
| 	oxAssert(err, "Something went wrong..."); | 	oxAssert(err, "Something went wrong..."); | ||||||
| 	return err; | 	return err; | ||||||
| } | } | ||||||
| @@ -88,7 +88,7 @@ ox::Error run( | |||||||
| 		ox::StringView appName, | 		ox::StringView appName, | ||||||
| 		ox::StringView projectDataDir, | 		ox::StringView projectDataDir, | ||||||
| 		int argc, | 		int argc, | ||||||
| 		const char **argv) noexcept { | 		char const**argv) noexcept { | ||||||
| 	return studio::run(ox::sfmt("{} {}", project, appName), projectDataDir, argc, argv); | 	return studio::run(ox::sfmt("{} {}", project, appName), projectDataDir, argc, argv); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -61,8 +61,8 @@ void NewMenu::addItemMaker(ox::UniquePtr<studio::ItemMaker> im) noexcept { | |||||||
|  |  | ||||||
| void NewMenu::drawNewItemType(turbine::Context &ctx) noexcept { | void NewMenu::drawNewItemType(turbine::Context &ctx) noexcept { | ||||||
| 	drawWindow(ctx, &m_open, [this] { | 	drawWindow(ctx, &m_open, [this] { | ||||||
| 		auto items = ox_malloca(m_types.size() * sizeof(const char*), const char*, nullptr); | 		auto items = ox_malloca(m_types.size() * sizeof(char const*), char const*, nullptr); | ||||||
| 		for (auto i = 0u; const auto &im : m_types) { | 		for (auto i = 0u; auto const&im : m_types) { | ||||||
| 			items.get()[i] = im->name.c_str(); | 			items.get()[i] = im->name.c_str(); | ||||||
| 			++i; | 			++i; | ||||||
| 		} | 		} | ||||||
| @@ -73,7 +73,7 @@ void NewMenu::drawNewItemType(turbine::Context &ctx) noexcept { | |||||||
|  |  | ||||||
| void NewMenu::drawNewItemName(turbine::Context &ctx) noexcept { | void NewMenu::drawNewItemName(turbine::Context &ctx) noexcept { | ||||||
| 	drawWindow(ctx, &m_open, [this, &ctx] { | 	drawWindow(ctx, &m_open, [this, &ctx] { | ||||||
| 		const auto typeIdx = static_cast<std::size_t>(m_selectedType); | 		auto const typeIdx = static_cast<std::size_t>(m_selectedType); | ||||||
| 		if (typeIdx < m_types.size()) { | 		if (typeIdx < m_types.size()) { | ||||||
| 			ImGui::InputText("Name", m_itemName.data(), m_itemName.cap()); | 			ImGui::InputText("Name", m_itemName.data(), m_itemName.cap()); | ||||||
| 		} | 		} | ||||||
| @@ -113,7 +113,7 @@ void NewMenu::drawLastPageButtons(turbine::Context &ctx) noexcept { | |||||||
| } | } | ||||||
|  |  | ||||||
| void NewMenu::finish(turbine::Context &ctx) noexcept { | void NewMenu::finish(turbine::Context &ctx) noexcept { | ||||||
| 	const auto err = m_types[static_cast<std::size_t>(m_selectedType)]->write(ctx, m_itemName); | 	auto const err = m_types[static_cast<std::size_t>(m_selectedType)]->write(ctx, m_itemName); | ||||||
| 	if (err) { | 	if (err) { | ||||||
| 		oxLogError(err); | 		oxLogError(err); | ||||||
| 		return; | 		return; | ||||||
|   | |||||||
| @@ -11,17 +11,17 @@ | |||||||
| namespace studio { | namespace studio { | ||||||
|  |  | ||||||
| static ox::Result<ox::UniquePtr<ProjectTreeModel>> | static ox::Result<ox::UniquePtr<ProjectTreeModel>> | ||||||
| buildProjectTreeModel(ProjectExplorer *explorer, ox::StringView name, ox::CRStringView path, ProjectTreeModel *parent) noexcept { | buildProjectTreeModel(ProjectExplorer &explorer, ox::StringView name, ox::CRStringView path, ProjectTreeModel *parent) noexcept { | ||||||
| 	const auto fs = explorer->romFs(); | 	auto const fs = explorer.romFs(); | ||||||
| 	oxRequire(stat, fs->stat(path)); | 	oxRequire(stat, fs->stat(path)); | ||||||
| 	auto out = ox::make_unique<ProjectTreeModel>(explorer, ox::String(name), parent); | 	auto out = ox::make_unique<ProjectTreeModel>(explorer, ox::String(name), parent); | ||||||
| 	if (stat.fileType == ox::FileType::Directory) { | 	if (stat.fileType == ox::FileType::Directory) { | ||||||
| 		oxRequireM(children, fs->ls(path)); | 		oxRequireM(children, fs->ls(path)); | ||||||
| 		std::sort(children.begin(), children.end()); | 		std::sort(children.begin(), children.end()); | ||||||
| 		ox::Vector<ox::UniquePtr<ProjectTreeModel>> outChildren; | 		ox::Vector<ox::UniquePtr<ProjectTreeModel>> outChildren; | ||||||
| 		for (const auto &childName : children) { | 		for (auto const&childName : children) { | ||||||
| 			if (childName[0] != '.') { | 			if (childName[0] != '.') { | ||||||
| 				const auto childPath = ox::sfmt("{}/{}", path, childName); | 				auto const childPath = ox::sfmt("{}/{}", path, childName); | ||||||
| 				oxRequireM(child, buildProjectTreeModel(explorer, childName, childPath, out.get())); | 				oxRequireM(child, buildProjectTreeModel(explorer, childName, childPath, out.get())); | ||||||
| 				outChildren.emplace_back(std::move(child)); | 				outChildren.emplace_back(std::move(child)); | ||||||
| 			} | 			} | ||||||
| @@ -35,7 +35,7 @@ ProjectExplorer::ProjectExplorer(turbine::Context &ctx) noexcept: m_ctx(ctx) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void ProjectExplorer::draw(turbine::Context &ctx) noexcept { | void ProjectExplorer::draw(turbine::Context &ctx) noexcept { | ||||||
| 	const auto viewport = ImGui::GetContentRegionAvail(); | 	auto const viewport = ImGui::GetContentRegionAvail(); | ||||||
| 	ImGui::BeginChild("ProjectExplorer", ImVec2(300, viewport.y), true); | 	ImGui::BeginChild("ProjectExplorer", ImVec2(300, viewport.y), true); | ||||||
| 	ImGui::SetNextItemOpen(true); | 	ImGui::SetNextItemOpen(true); | ||||||
| 	if (m_treeModel) { | 	if (m_treeModel) { | ||||||
| @@ -44,12 +44,12 @@ void ProjectExplorer::draw(turbine::Context &ctx) noexcept { | |||||||
| 	ImGui::EndChild(); | 	ImGui::EndChild(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void ProjectExplorer::setModel(ox::UniquePtr<ProjectTreeModel> model) noexcept { | void ProjectExplorer::setModel(ox::UPtr<ProjectTreeModel> model) noexcept { | ||||||
| 	m_treeModel = std::move(model); | 	m_treeModel = std::move(model); | ||||||
| } | } | ||||||
|  |  | ||||||
| ox::Error ProjectExplorer::refreshProjectTreeModel(ox::CRStringView) noexcept { | ox::Error ProjectExplorer::refreshProjectTreeModel(ox::CRStringView) noexcept { | ||||||
| 	oxRequireM(model, buildProjectTreeModel(this, "Project", "/", nullptr)); | 	oxRequireM(model, buildProjectTreeModel(*this, "Project", "/", nullptr)); | ||||||
| 	setModel(std::move(model)); | 	setModel(std::move(model)); | ||||||
| 	return OxError(0); | 	return OxError(0); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -14,14 +14,14 @@ namespace studio { | |||||||
|  |  | ||||||
| class ProjectExplorer: public studio::Widget { | class ProjectExplorer: public studio::Widget { | ||||||
| 	private: | 	private: | ||||||
| 		ox::UniquePtr<ProjectTreeModel> m_treeModel; | 		ox::UPtr<ProjectTreeModel> m_treeModel; | ||||||
| 		turbine::Context &m_ctx; | 		turbine::Context &m_ctx; | ||||||
| 	public: | 	public: | ||||||
| 		explicit ProjectExplorer(turbine::Context &ctx) noexcept; | 		explicit ProjectExplorer(turbine::Context &ctx) noexcept; | ||||||
|  |  | ||||||
| 		void draw(turbine::Context &ctx) noexcept override; | 		void draw(turbine::Context &ctx) noexcept override; | ||||||
|  |  | ||||||
| 		void setModel(ox::UniquePtr<ProjectTreeModel> model) noexcept; | 		void setModel(ox::UPtr<ProjectTreeModel> model) noexcept; | ||||||
|  |  | ||||||
| 		ox::Error refreshProjectTreeModel(ox::CRStringView = {}) noexcept; | 		ox::Error refreshProjectTreeModel(ox::CRStringView = {}) noexcept; | ||||||
|  |  | ||||||
| @@ -32,7 +32,7 @@ class ProjectExplorer: public studio::Widget { | |||||||
|  |  | ||||||
| 	// slots | 	// slots | ||||||
| 	public: | 	public: | ||||||
| 		ox::Signal<ox::Error(const ox::StringView&)> fileChosen; | 		ox::Signal<ox::Error(ox::StringView const&)> fileChosen; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
|  |  | ||||||
| namespace studio { | namespace studio { | ||||||
|  |  | ||||||
| ProjectTreeModel::ProjectTreeModel(ProjectExplorer *explorer, ox::String name, | ProjectTreeModel::ProjectTreeModel(ProjectExplorer &explorer, ox::String name, | ||||||
|                                    ProjectTreeModel *parent) noexcept: |                                    ProjectTreeModel *parent) noexcept: | ||||||
| 	m_explorer(explorer), | 	m_explorer(explorer), | ||||||
| 	m_parent(parent), | 	m_parent(parent), | ||||||
| @@ -27,17 +27,17 @@ void ProjectTreeModel::draw(turbine::Context &ctx) const noexcept { | |||||||
| 	constexpr auto dirFlags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick; | 	constexpr auto dirFlags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick; | ||||||
| 	if (!m_children.empty()) { | 	if (!m_children.empty()) { | ||||||
| 		if (ImGui::TreeNodeEx(m_name.c_str(), dirFlags)) { | 		if (ImGui::TreeNodeEx(m_name.c_str(), dirFlags)) { | ||||||
| 			for (const auto &child : m_children) { | 			for (auto const&child : m_children) { | ||||||
| 				child->draw(ctx); | 				child->draw(ctx); | ||||||
| 			} | 			} | ||||||
| 			ImGui::TreePop(); | 			ImGui::TreePop(); | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		const auto path = fullPath(); | 		auto const path = fullPath(); | ||||||
| 		const auto name = ox::sfmt<ox::BasicString<255>>("{}##{}", m_name, path); | 		auto const name = ox::sfmt<ox::BasicString<255>>("{}##{}", m_name, path); | ||||||
| 		if (ImGui::TreeNodeEx(name.c_str(), ImGuiTreeNodeFlags_Leaf)) { | 		if (ImGui::TreeNodeEx(name.c_str(), ImGuiTreeNodeFlags_Leaf)) { | ||||||
| 			if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) { | 			if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) { | ||||||
| 				m_explorer->fileChosen.emit(path); | 				m_explorer.fileChosen.emit(path); | ||||||
| 			} | 			} | ||||||
| 			ImGui::TreePop(); | 			ImGui::TreePop(); | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -13,12 +13,12 @@ namespace studio { | |||||||
|  |  | ||||||
| class ProjectTreeModel { | class ProjectTreeModel { | ||||||
| 	private: | 	private: | ||||||
| 		class ProjectExplorer *m_explorer = nullptr; | 		class ProjectExplorer &m_explorer; | ||||||
| 		ProjectTreeModel *m_parent = nullptr; | 		ProjectTreeModel *m_parent = nullptr; | ||||||
| 		ox::String m_name; | 		ox::String m_name; | ||||||
| 		ox::Vector<ox::UniquePtr<ProjectTreeModel>> m_children; | 		ox::Vector<ox::UniquePtr<ProjectTreeModel>> m_children; | ||||||
| 	public: | 	public: | ||||||
| 		explicit ProjectTreeModel(class ProjectExplorer *explorer, ox::String name, | 		explicit ProjectTreeModel(class ProjectExplorer &explorer, ox::String name, | ||||||
| 		                          ProjectTreeModel *parent = nullptr) noexcept; | 		                          ProjectTreeModel *parent = nullptr) noexcept; | ||||||
|  |  | ||||||
| 		ProjectTreeModel(ProjectTreeModel &&other) noexcept; | 		ProjectTreeModel(ProjectTreeModel &&other) noexcept; | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ | |||||||
|  |  | ||||||
| namespace studio { | namespace studio { | ||||||
|  |  | ||||||
| static ox::Vector<const studio::Module*> modules; | static ox::Vector<studio::Module const*> modules; | ||||||
|  |  | ||||||
| void registerModule(studio::Module const*mod) noexcept { | void registerModule(studio::Module const*mod) noexcept { | ||||||
| 	modules.emplace_back(mod); | 	modules.emplace_back(mod); | ||||||
| @@ -52,7 +52,7 @@ StudioUI::StudioUI(turbine::Context &ctx, ox::StringView projectDataDir) noexcep | |||||||
| 	if (!err) { | 	if (!err) { | ||||||
| 		auto const openProjErr = openProject(config.projectPath); | 		auto const openProjErr = openProject(config.projectPath); | ||||||
| 		if (!openProjErr) { | 		if (!openProjErr) { | ||||||
| 			for (const auto &f: config.openFiles) { | 			for (auto const&f: config.openFiles) { | ||||||
| 				auto openFileErr = openFileActiveTab(f, config.activeTabItemName == f); | 				auto openFileErr = openFileActiveTab(f, config.activeTabItemName == f); | ||||||
| 				if (openFileErr) { | 				if (openFileErr) { | ||||||
| 					oxErrorf("\nCould not open editor for file:\n\t{}\nReason:\n\t{}\n", f, toStr(openFileErr)); | 					oxErrorf("\nCould not open editor for file:\n\t{}\nReason:\n\t{}\n", f, toStr(openFileErr)); | ||||||
| @@ -75,7 +75,7 @@ void StudioUI::update() noexcept { | |||||||
| } | } | ||||||
|  |  | ||||||
| void StudioUI::handleKeyEvent(turbine::Key key, bool down) noexcept { | void StudioUI::handleKeyEvent(turbine::Key key, bool down) noexcept { | ||||||
| 	const auto ctrlDown = turbine::buttonDown(m_ctx, turbine::Key::Mod_Ctrl); | 	auto const ctrlDown = turbine::buttonDown(m_ctx, turbine::Key::Mod_Ctrl); | ||||||
| 	for (auto p : m_popups) { | 	for (auto p : m_popups) { | ||||||
| 		if (p->isOpen()) { | 		if (p->isOpen()) { | ||||||
| 			if (key == turbine::Key::Escape) { | 			if (key == turbine::Key::Escape) { | ||||||
| @@ -136,7 +136,7 @@ void StudioUI::handleKeyEvent(turbine::Key key, bool down) noexcept { | |||||||
| void StudioUI::draw() noexcept { | void StudioUI::draw() noexcept { | ||||||
| 	glutils::clearScreen(); | 	glutils::clearScreen(); | ||||||
| 	drawMenu(); | 	drawMenu(); | ||||||
| 	const auto viewport = ImGui::GetMainViewport(); | 	auto const viewport = ImGui::GetMainViewport(); | ||||||
| 	constexpr auto menuHeight = 18; | 	constexpr auto menuHeight = 18; | ||||||
| 	ImGui::SetNextWindowPos(ImVec2(viewport->Pos.x, viewport->Pos.y + menuHeight)); | 	ImGui::SetNextWindowPos(ImVec2(viewport->Pos.x, viewport->Pos.y + menuHeight)); | ||||||
| 	ImGui::SetNextWindowSize(ImVec2(viewport->Size.x, viewport->Size.y - menuHeight)); | 	ImGui::SetNextWindowSize(ImVec2(viewport->Size.x, viewport->Size.y - menuHeight)); | ||||||
| @@ -216,7 +216,7 @@ void StudioUI::drawMenu() noexcept { | |||||||
| } | } | ||||||
|  |  | ||||||
| void StudioUI::drawTabBar() noexcept { | void StudioUI::drawTabBar() noexcept { | ||||||
| 	const auto viewport = ImGui::GetContentRegionAvail(); | 	auto const viewport = ImGui::GetContentRegionAvail(); | ||||||
| 	ImGui::BeginChild("TabWindow##MainWindow##Studio", ImVec2(viewport.x, viewport.y)); | 	ImGui::BeginChild("TabWindow##MainWindow##Studio", ImVec2(viewport.x, viewport.y)); | ||||||
| 	constexpr auto tabBarFlags = ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_TabListPopupButton; | 	constexpr auto tabBarFlags = ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_TabListPopupButton; | ||||||
| 	if (ImGui::BeginTabBar("TabBar##TabWindow##MainWindow##Studio", tabBarFlags)) { | 	if (ImGui::BeginTabBar("TabBar##TabWindow##MainWindow##Studio", tabBarFlags)) { | ||||||
| @@ -230,9 +230,9 @@ void StudioUI::drawTabs() noexcept { | |||||||
| 	for (auto it = m_editors.begin(); it != m_editors.end();) { | 	for (auto it = m_editors.begin(); it != m_editors.end();) { | ||||||
| 		auto const &e = *it; | 		auto const &e = *it; | ||||||
| 		auto open = true; | 		auto open = true; | ||||||
| 		const auto unsavedChanges = e->unsavedChanges() ? ImGuiTabItemFlags_UnsavedDocument : 0; | 		auto const unsavedChanges = e->unsavedChanges() ? ImGuiTabItemFlags_UnsavedDocument : 0; | ||||||
| 		const auto selected = m_activeEditorUpdatePending == e.get() ?  ImGuiTabItemFlags_SetSelected : 0; | 		auto const selected = m_activeEditorUpdatePending == e.get() ?  ImGuiTabItemFlags_SetSelected : 0; | ||||||
| 		const auto flags = unsavedChanges | selected; | 		auto const flags = unsavedChanges | selected; | ||||||
| 		if (ImGui::BeginTabItem(e->itemDisplayName().c_str(), &open, flags)) { | 		if (ImGui::BeginTabItem(e->itemDisplayName().c_str(), &open, flags)) { | ||||||
| 			if (m_activeEditor != e.get()) { | 			if (m_activeEditor != e.get()) { | ||||||
| 				m_activeEditor = e.get(); | 				m_activeEditor = e.get(); | ||||||
| @@ -258,9 +258,9 @@ void StudioUI::drawTabs() noexcept { | |||||||
| 			} | 			} | ||||||
| 			try { | 			try { | ||||||
| 				oxThrowError(m_editors.erase(it).moveTo(it)); | 				oxThrowError(m_editors.erase(it).moveTo(it)); | ||||||
| 			} catch (const ox::Exception &ex) { | 			} catch (ox::Exception const&ex) { | ||||||
| 				oxErrf("Editor tab deletion failed: {} ({}:{})\n", ex.what(), ex.file, ex.line); | 				oxErrf("Editor tab deletion failed: {} ({}:{})\n", ex.what(), ex.file, ex.line); | ||||||
| 			} catch (const std::exception &ex) { | 			} catch (std::exception const&ex) { | ||||||
| 				oxErrf("Editor tab deletion failed: {}\n", ex.what()); | 				oxErrf("Editor tab deletion failed: {}\n", ex.what()); | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
| @@ -275,8 +275,8 @@ void StudioUI::loadEditorMaker(studio::EditorMaker const&editorMaker) noexcept { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void StudioUI::loadModule(const studio::Module *mod) noexcept { | void StudioUI::loadModule(studio::Module const*mod) noexcept { | ||||||
| 	for (const auto &editorMaker : mod->editors(m_ctx)) { | 	for (auto const&editorMaker : mod->editors(m_ctx)) { | ||||||
| 		loadEditorMaker(editorMaker); | 		loadEditorMaker(editorMaker); | ||||||
| 	} | 	} | ||||||
| 	for (auto &im : mod->itemMakers(m_ctx)) { | 	for (auto &im : mod->itemMakers(m_ctx)) { | ||||||
| @@ -363,7 +363,7 @@ ox::Error StudioUI::openFileActiveTab(ox::CRStringView path, bool makeActiveTab) | |||||||
| 		} | 		} | ||||||
| 		editor = ox::make<ClawEditor>(path, std::move(obj)); | 		editor = ox::make<ClawEditor>(path, std::move(obj)); | ||||||
| 	} else { | 	} else { | ||||||
| 		const auto err = m_editorMakers[ext](path).moveTo(editor); | 		auto const err = m_editorMakers[ext](path).moveTo(editor); | ||||||
| 		if (err) { | 		if (err) { | ||||||
| 			if constexpr(!ox::defines::Debug) { | 			if constexpr(!ox::defines::Debug) { | ||||||
| 				oxErrf("Could not open Editor: {}\n", toStr(err)); | 				oxErrf("Could not open Editor: {}\n", toStr(err)); | ||||||
|   | |||||||
| @@ -23,9 +23,9 @@ ox::String configPath(keel::Context const&ctx) noexcept; | |||||||
| template<typename T> | template<typename T> | ||||||
| ox::Result<T> readConfig(keel::Context &ctx, ox::CRStringView name) noexcept { | ox::Result<T> readConfig(keel::Context &ctx, ox::CRStringView name) noexcept { | ||||||
| 	oxAssert(name != "", "Config type has no TypeName"); | 	oxAssert(name != "", "Config type has no TypeName"); | ||||||
| 	const auto path = ox::sfmt("/{}.json", name); | 	auto const path = ox::sfmt("/{}.json", name); | ||||||
| 	ox::PassThroughFS fs(configPath(ctx)); | 	ox::PassThroughFS fs(configPath(ctx)); | ||||||
| 	const auto [buff, err] = fs.read(path); | 	auto const [buff, err] = fs.read(path); | ||||||
| 	if (err) { | 	if (err) { | ||||||
| 		oxErrf("Could not read config file: {}\n", toStr(err)); | 		oxErrf("Could not read config file: {}\n", toStr(err)); | ||||||
| 		return err; | 		return err; | ||||||
| @@ -42,19 +42,19 @@ ox::Result<T> readConfig(keel::Context &ctx) noexcept { | |||||||
| template<typename T> | template<typename T> | ||||||
| ox::Error writeConfig(keel::Context &ctx, ox::CRStringView name, T *data) noexcept { | ox::Error writeConfig(keel::Context &ctx, ox::CRStringView name, T *data) noexcept { | ||||||
| 	oxAssert(name != "", "Config type has no TypeName"); | 	oxAssert(name != "", "Config type has no TypeName"); | ||||||
| 	const auto path = ox::sfmt("/{}.json", name); | 	auto const path = ox::sfmt("/{}.json", name); | ||||||
| 	ox::PassThroughFS fs(configPath(ctx)); | 	ox::PassThroughFS fs(configPath(ctx)); | ||||||
| 	if (const auto err = fs.mkdir("/", true)) { | 	if (auto const err = fs.mkdir("/", true)) { | ||||||
| 		oxErrf("Could not create config directory: {}\n", toStr(err)); | 		oxErrf("Could not create config directory: {}\n", toStr(err)); | ||||||
| 		return err; | 		return err; | ||||||
| 	} | 	} | ||||||
| 	oxRequireM(buff, ox::writeOC(*data)); | 	oxRequireM(buff, ox::writeOC(*data)); | ||||||
| 	*buff.back().value = '\n'; | 	*buff.back().value = '\n'; | ||||||
| 	if (const auto err = fs.write(path, buff.data(), buff.size())) { | 	if (auto const err = fs.write(path, buff.data(), buff.size())) { | ||||||
| 		oxErrf("Could not read config file: {}\n", toStr(err)); | 		oxErrf("Could not read config file: {}\n", toStr(err)); | ||||||
| 		return OxError(2, "Could not read config file"); | 		return OxError(2, "Could not read config file"); | ||||||
| 	} | 	} | ||||||
| 	return OxError(0); | 	return {}; | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename T> | template<typename T> | ||||||
| @@ -66,7 +66,7 @@ ox::Error writeConfig(keel::Context &ctx, T *data) noexcept { | |||||||
| template<typename T, typename Func> | template<typename T, typename Func> | ||||||
| void openConfig(keel::Context &ctx, ox::CRStringView name, Func f) noexcept { | void openConfig(keel::Context &ctx, ox::CRStringView name, Func f) noexcept { | ||||||
| 	oxAssert(name != "", "Config type has no TypeName"); | 	oxAssert(name != "", "Config type has no TypeName"); | ||||||
| 	const auto [c, err] = readConfig<T>(ctx, name); | 	auto const [c, err] = readConfig<T>(ctx, name); | ||||||
| 	oxLogError(err); | 	oxLogError(err); | ||||||
| 	f(&c); | 	f(&c); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -15,9 +15,9 @@ namespace studio { | |||||||
|  |  | ||||||
| class ItemMaker { | class ItemMaker { | ||||||
| 	public: | 	public: | ||||||
| 		const ox::String name; | 		ox::String const name; | ||||||
| 		const ox::String parentDir; | 		ox::String const parentDir; | ||||||
| 		const ox::String fileExt; | 		ox::String const fileExt; | ||||||
| 		constexpr explicit ItemMaker(ox::StringView pName, ox::StringView pParentDir, ox::CRStringView pFileExt) noexcept: | 		constexpr explicit ItemMaker(ox::StringView pName, ox::StringView pParentDir, ox::CRStringView pFileExt) noexcept: | ||||||
| 			name(pName), | 			name(pName), | ||||||
| 			parentDir(pParentDir), | 			parentDir(pParentDir), | ||||||
| @@ -30,8 +30,8 @@ class ItemMaker { | |||||||
| template<typename T> | template<typename T> | ||||||
| class ItemMakerT: public ItemMaker { | class ItemMakerT: public ItemMaker { | ||||||
| 	private: | 	private: | ||||||
| 		const T item; | 		T const item; | ||||||
| 		const ox::ClawFormat fmt; | 		ox::ClawFormat const fmt; | ||||||
| 	public: | 	public: | ||||||
| 		constexpr ItemMakerT( | 		constexpr ItemMakerT( | ||||||
| 				ox::StringView pDisplayName, | 				ox::StringView pDisplayName, | ||||||
| @@ -62,7 +62,7 @@ class ItemMakerT: public ItemMaker { | |||||||
| 			 fmt(pFmt) { | 			 fmt(pFmt) { | ||||||
| 		} | 		} | ||||||
| 		ox::Error write(turbine::Context &ctx, ox::CRStringView pName) const noexcept override { | 		ox::Error write(turbine::Context &ctx, ox::CRStringView pName) const noexcept override { | ||||||
| 			const auto path = ox::sfmt("/{}/{}.{}", parentDir, pName, fileExt); | 			auto const path = ox::sfmt("/{}/{}.{}", parentDir, pName, fileExt); | ||||||
| 			auto sctx = turbine::applicationData<studio::StudioContext>(ctx); | 			auto sctx = turbine::applicationData<studio::StudioContext>(ctx); | ||||||
| 			keel::createUuidMapping(keelCtx(ctx), path, ox::UUID::generate().unwrap()); | 			keel::createUuidMapping(keelCtx(ctx), path, ox::UUID::generate().unwrap()); | ||||||
| 			return sctx->project->writeObj(path, item, fmt); | 			return sctx->project->writeObj(path, item, fmt); | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ class Popup { | |||||||
| 		ox::String m_title; | 		ox::String m_title; | ||||||
| 	public: | 	public: | ||||||
| 		// emits path parameter | 		// emits path parameter | ||||||
| 		ox::Signal<ox::Error(const ox::String&)> finished; | 		ox::Signal<ox::Error(ox::String const&)> finished; | ||||||
|  |  | ||||||
| 		virtual ~Popup() noexcept = default; | 		virtual ~Popup() noexcept = default; | ||||||
|  |  | ||||||
| @@ -43,7 +43,7 @@ class Popup { | |||||||
| 			m_title = std::move(title); | 			m_title = std::move(title); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		constexpr const ox::String &title() const noexcept { | 		constexpr ox::String const&title() const noexcept { | ||||||
| 			return m_title; | 			return m_title; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ enum class ProjectEvent { | |||||||
|  |  | ||||||
| [[nodiscard]] | [[nodiscard]] | ||||||
| constexpr ox::Result<ox::StringView> fileExt(ox::CRStringView path) noexcept { | constexpr ox::Result<ox::StringView> fileExt(ox::CRStringView path) noexcept { | ||||||
| 	const auto extStart = ox::find(path.crbegin(), path.crend(), '.').offset(); | 	auto const extStart = ox::find(path.crbegin(), path.crend(), '.').offset(); | ||||||
| 	if (!extStart) { | 	if (!extStart) { | ||||||
| 		return OxError(1, "Cannot open a file without valid extension."); | 		return OxError(1, "Cannot open a file without valid extension."); | ||||||
| 	} | 	} | ||||||
| @@ -76,7 +76,7 @@ class Project { | |||||||
| 		ox::Error subscribe(ProjectEvent e, ox::SignalHandler *tgt, Functor &&slot) const noexcept; | 		ox::Error subscribe(ProjectEvent e, ox::SignalHandler *tgt, Functor &&slot) const noexcept; | ||||||
|  |  | ||||||
| 		[[nodiscard]] | 		[[nodiscard]] | ||||||
| 		const ox::Vector<ox::String> &fileList(ox::CRStringView ext) noexcept; | 		ox::Vector<ox::String> const&fileList(ox::CRStringView ext) noexcept; | ||||||
|  |  | ||||||
| 	private: | 	private: | ||||||
| 		void buildFileIndex() noexcept; | 		void buildFileIndex() noexcept; | ||||||
| @@ -114,14 +114,14 @@ ox::Error Project::writeObj(ox::CRStringView path, T const&obj, ox::ClawFormat f | |||||||
| 		oxReturnError(ox::buildTypeDef(&m_typeStore, &obj)); | 		oxReturnError(ox::buildTypeDef(&m_typeStore, &obj)); | ||||||
| 	} | 	} | ||||||
| 	// write out type store | 	// write out type store | ||||||
| 	const auto descPath = ox::sfmt("/{}/type_descriptors", m_projectDataDir); | 	auto const descPath = ox::sfmt("/{}/type_descriptors", m_projectDataDir); | ||||||
| 	oxReturnError(mkdir(descPath)); | 	oxReturnError(mkdir(descPath)); | ||||||
| 	for (auto const&t : m_typeStore.typeList()) { | 	for (auto const&t : m_typeStore.typeList()) { | ||||||
| 		oxRequireM(typeOut, ox::writeClaw(*t, ox::ClawFormat::Organic)); | 		oxRequireM(typeOut, ox::writeClaw(*t, ox::ClawFormat::Organic)); | ||||||
| 		// replace garbage last character with new line | 		// replace garbage last character with new line | ||||||
| 		*typeOut.back().value = '\n'; | 		*typeOut.back().value = '\n'; | ||||||
| 		// write to FS | 		// write to FS | ||||||
| 		const auto typePath = ox::sfmt("/{}/{}", descPath, buildTypeId(*t)); | 		auto const typePath = ox::sfmt("/{}/{}", descPath, buildTypeId(*t)); | ||||||
| 		oxReturnError(writeBuff(typePath, typeOut)); | 		oxReturnError(writeBuff(typePath, typeOut)); | ||||||
| 	} | 	} | ||||||
| 	oxReturnError(keel::setAsset(m_ctx, path, obj)); | 	oxReturnError(keel::setAsset(m_ctx, path, obj)); | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ class UndoCommand { | |||||||
| 		virtual void undo() noexcept = 0; | 		virtual void undo() noexcept = 0; | ||||||
| 		[[nodiscard]] | 		[[nodiscard]] | ||||||
| 		virtual int commandId() const noexcept = 0; | 		virtual int commandId() const noexcept = 0; | ||||||
| 		virtual bool mergeWith(const UndoCommand *cmd) noexcept; | 		virtual bool mergeWith(UndoCommand const*cmd) noexcept; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class UndoStack { | class UndoStack { | ||||||
| @@ -43,9 +43,9 @@ class UndoStack { | |||||||
| 			return m_stackIdx; | 			return m_stackIdx; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		ox::Signal<ox::Error(const studio::UndoCommand*)> redoTriggered; | 		ox::Signal<ox::Error(studio::UndoCommand const*)> redoTriggered; | ||||||
| 		ox::Signal<ox::Error(const studio::UndoCommand*)> undoTriggered; | 		ox::Signal<ox::Error(studio::UndoCommand const*)> undoTriggered; | ||||||
| 		ox::Signal<ox::Error(const studio::UndoCommand*)> changeTriggered; | 		ox::Signal<ox::Error(studio::UndoCommand const*)> changeTriggered; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -8,7 +8,6 @@ add_library( | |||||||
| 		project.cpp | 		project.cpp | ||||||
| 		task.cpp | 		task.cpp | ||||||
| 		undostack.cpp | 		undostack.cpp | ||||||
| 		widget.cpp |  | ||||||
| 		filedialog_nfd.cpp | 		filedialog_nfd.cpp | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -23,8 +23,8 @@ constexpr auto ConfigDir = [] { | |||||||
| 	} | 	} | ||||||
| }(); | }(); | ||||||
|  |  | ||||||
| ox::String configPath(const keel::Context &ctx) noexcept { | ox::String configPath(keel::Context const&ctx) noexcept { | ||||||
| 	const auto homeDir = std::getenv(ox::defines::OS == ox::OS::Windows ? "USERPROFILE" : "HOME"); | 	auto const homeDir = std::getenv(ox::defines::OS == ox::OS::Windows ? "USERPROFILE" : "HOME"); | ||||||
| 	return ox::sfmt(ConfigDir, homeDir, ctx.appName); | 	return ox::sfmt(ConfigDir, homeDir, ctx.appName); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -41,7 +41,7 @@ void BaseEditor::close() const { | |||||||
| } | } | ||||||
|  |  | ||||||
| void BaseEditor::save() noexcept { | void BaseEditor::save() noexcept { | ||||||
| 	const auto err = saveItem(); | 	auto const err = saveItem(); | ||||||
| 	if (!err) { | 	if (!err) { | ||||||
| 		setUnsavedChanges(false); | 		setUnsavedChanges(false); | ||||||
| 	} else { | 	} else { | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ static ox::Result<ox::String> toResult(nfdresult_t r, NFD::UniquePathN const&pat | |||||||
| 		case NFD_OKAY: { | 		case NFD_OKAY: { | ||||||
| 			ox::String out; | 			ox::String out; | ||||||
| 			for (auto i = 0u; path.get()[i]; ++i) { | 			for (auto i = 0u; path.get()[i]; ++i) { | ||||||
| 				const auto c = static_cast<char>(path.get()[i]); | 				auto const c = static_cast<char>(path.get()[i]); | ||||||
| 				oxIgnoreError(out.append(&c, 1)); | 				oxIgnoreError(out.append(&c, 1)); | ||||||
| 			} | 			} | ||||||
| 			return out; | 			return out; | ||||||
| @@ -39,7 +39,7 @@ ox::Result<ox::String> saveFile(ox::Vector<FDFilterItem> const&filters) noexcept | |||||||
| 	NFD::Guard const guard; | 	NFD::Guard const guard; | ||||||
| 	NFD::UniquePathN path; | 	NFD::UniquePathN path; | ||||||
| 	ox::Vector<nfdnfilteritem_t, 5> filterItems(filters.size()); | 	ox::Vector<nfdnfilteritem_t, 5> filterItems(filters.size()); | ||||||
| 	for (auto i = 0u; const auto &f : filters) { | 	for (auto i = 0u; auto const&f : filters) { | ||||||
| 		filterItems[i].name = f.name.data(); | 		filterItems[i].name = f.name.data(); | ||||||
| 		filterItems[i].spec = f.spec.data(); | 		filterItems[i].spec = f.spec.data(); | ||||||
| 		++i; | 		++i; | ||||||
|   | |||||||
| @@ -9,10 +9,10 @@ | |||||||
| namespace studio::ig { | namespace studio::ig { | ||||||
|  |  | ||||||
| void centerNextWindow(turbine::Context &ctx) noexcept { | void centerNextWindow(turbine::Context &ctx) noexcept { | ||||||
| 	const auto sz = turbine::getScreenSize(ctx); | 	auto const sz = turbine::getScreenSize(ctx); | ||||||
| 	const auto screenW = static_cast<float>(sz.width); | 	auto const screenW = static_cast<float>(sz.width); | ||||||
| 	const auto screenH = static_cast<float>(sz.height); | 	auto const screenH = static_cast<float>(sz.height); | ||||||
| 	const auto mod = ImGui::GetWindowDpiScale() * 2; | 	auto const mod = ImGui::GetWindowDpiScale() * 2; | ||||||
| 	ImGui::SetNextWindowPos(ImVec2(screenW / mod, screenH / mod), ImGuiCond_Always, ImVec2(0.5f, 0.5f)); | 	ImGui::SetNextWindowPos(ImVec2(screenW / mod, screenH / mod), ImGuiCond_Always, ImVec2(0.5f, 0.5f)); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ | |||||||
| namespace studio { | namespace studio { | ||||||
|  |  | ||||||
| static void generateTypes(ox::TypeStore &ts) noexcept { | static void generateTypes(ox::TypeStore &ts) noexcept { | ||||||
| 	for (const auto mod : keel::modules()) { | 	for (auto const mod : keel::modules()) { | ||||||
| 		for (auto gen : mod->types()) { | 		for (auto gen : mod->types()) { | ||||||
| 			oxLogError(gen(ts)); | 			oxLogError(gen(ts)); | ||||||
| 		} | 		} | ||||||
| @@ -56,7 +56,7 @@ bool Project::exists(ox::CRStringView path) const noexcept { | |||||||
| 	return m_fs.stat(path).error == 0; | 	return m_fs.stat(path).error == 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| const ox::Vector<ox::String> &Project::fileList(ox::CRStringView ext) noexcept { | ox::Vector<ox::String> const&Project::fileList(ox::CRStringView ext) noexcept { | ||||||
| 	return m_fileExtFileMap[ext]; | 	return m_fileExtFileMap[ext]; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -68,7 +68,7 @@ void Project::buildFileIndex() noexcept { | |||||||
| 	} | 	} | ||||||
| 	m_fileExtFileMap.clear(); | 	m_fileExtFileMap.clear(); | ||||||
| 	std::sort(files.begin(), files.end()); | 	std::sort(files.begin(), files.end()); | ||||||
| 	for (const auto &file : files) { | 	for (auto const&file : files) { | ||||||
| 		if (!beginsWith(file, ox::sfmt("/.{}/", m_projectDataDir))) { | 		if (!beginsWith(file, ox::sfmt("/.{}/", m_projectDataDir))) { | ||||||
| 			indexFile(file); | 			indexFile(file); | ||||||
| 		} | 		} | ||||||
| @@ -76,7 +76,7 @@ void Project::buildFileIndex() noexcept { | |||||||
| } | } | ||||||
|  |  | ||||||
| void Project::indexFile(ox::CRStringView path) noexcept { | void Project::indexFile(ox::CRStringView path) noexcept { | ||||||
| 	const auto [ext, err] = fileExt(path); | 	auto const [ext, err] = fileExt(path); | ||||||
| 	if (err) { | 	if (err) { | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| @@ -88,12 +88,12 @@ ox::Error Project::writeBuff(ox::CRStringView path, ox::Buffer const&buff) noexc | |||||||
| 	ox::Buffer outBuff; | 	ox::Buffer outBuff; | ||||||
| 	outBuff.reserve(buff.size() + HdrSz); | 	outBuff.reserve(buff.size() + HdrSz); | ||||||
| 	ox::BufferWriter writer(&outBuff); | 	ox::BufferWriter writer(&outBuff); | ||||||
| 	const auto [uuid, err] = m_ctx.pathToUuid.at(path); | 	auto const [uuid, err] = m_ctx.pathToUuid.at(path); | ||||||
| 	if (!err) { | 	if (!err) { | ||||||
| 		oxReturnError(keel::writeUuidHeader(writer, *uuid)); | 		oxReturnError(keel::writeUuidHeader(writer, *uuid)); | ||||||
| 	} | 	} | ||||||
| 	oxReturnError(writer.write(buff.data(), buff.size())); | 	oxReturnError(writer.write(buff.data(), buff.size())); | ||||||
| 	const auto newFile = m_fs.stat(path).error != 0; | 	auto const newFile = m_fs.stat(path).error != 0; | ||||||
| 	oxReturnError(m_fs.write(path, outBuff.data(), outBuff.size(), ox::FileType::NormalFile)); | 	oxReturnError(m_fs.write(path, outBuff.data(), outBuff.size(), ox::FileType::NormalFile)); | ||||||
| 	if (newFile) { | 	if (newFile) { | ||||||
| 		fileAdded.emit(path); | 		fileAdded.emit(path); | ||||||
| @@ -110,7 +110,7 @@ ox::Result<ox::Buffer> Project::loadBuff(ox::CRStringView path) const noexcept { | |||||||
|  |  | ||||||
| ox::Error Project::lsProcDir(ox::Vector<ox::String> *paths, ox::CRStringView path) const noexcept { | ox::Error Project::lsProcDir(ox::Vector<ox::String> *paths, ox::CRStringView path) const noexcept { | ||||||
| 	oxRequire(files, m_fs.ls(path)); | 	oxRequire(files, m_fs.ls(path)); | ||||||
| 	for (const auto &name : files) { | 	for (auto const&name : files) { | ||||||
| 		auto fullPath = ox::sfmt("{}/{}", path, name); | 		auto fullPath = ox::sfmt("{}/{}", path, name); | ||||||
| 		oxRequire(stat, m_fs.stat(ox::StringView(fullPath))); | 		oxRequire(stat, m_fs.stat(ox::StringView(fullPath))); | ||||||
| 		switch (stat.fileType) { | 		switch (stat.fileType) { | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ namespace studio { | |||||||
|  |  | ||||||
| void TaskRunner::update(turbine::Context &ctx) noexcept { | void TaskRunner::update(turbine::Context &ctx) noexcept { | ||||||
| 	oxIgnoreError(m_tasks.erase(std::remove_if(m_tasks.begin(), m_tasks.end(), [&](ox::UPtr<studio::Task> &t) { | 	oxIgnoreError(m_tasks.erase(std::remove_if(m_tasks.begin(), m_tasks.end(), [&](ox::UPtr<studio::Task> &t) { | ||||||
| 		const auto done = t->update(ctx) == TaskState::Done; | 		auto const done = t->update(ctx) == TaskState::Done; | ||||||
| 		if (done) { | 		if (done) { | ||||||
| 			t->finished.emit(); | 			t->finished.emit(); | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -6,12 +6,12 @@ | |||||||
|  |  | ||||||
| namespace studio { | namespace studio { | ||||||
|  |  | ||||||
| bool UndoCommand::mergeWith(const UndoCommand*) noexcept { | bool UndoCommand::mergeWith(UndoCommand const*) noexcept { | ||||||
| 	return false; | 	return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| void UndoStack::push(ox::UPtr<UndoCommand> &&cmd) noexcept { | void UndoStack::push(ox::UPtr<UndoCommand> &&cmd) noexcept { | ||||||
| 	for (const auto i = m_stackIdx; i < m_stack.size();) { | 	for (auto const i = m_stackIdx; i < m_stack.size();) { | ||||||
| 		oxIgnoreError(m_stack.erase(i)); | 		oxIgnoreError(m_stack.erase(i)); | ||||||
| 	} | 	} | ||||||
| 	cmd->redo(); | 	cmd->redo(); | ||||||
|   | |||||||
| @@ -1,9 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #include <studio/widget.hpp> |  | ||||||
|  |  | ||||||
| namespace studio { |  | ||||||
|  |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user