[olympic] Add more ImGui helpers, studio::Editor::pushCommand
This commit is contained in:
		@@ -131,6 +131,17 @@ class Editor: public studio::BaseEditor {
 | 
			
		||||
		[[nodiscard]]
 | 
			
		||||
		UndoStack *undoStack() noexcept final;
 | 
			
		||||
 | 
			
		||||
		void pushCommand(ox::UPtr<UndoCommand> &&cmd) noexcept;
 | 
			
		||||
 | 
			
		||||
		template<typename UC, typename ...Args>
 | 
			
		||||
		void pushCommand(Args&&... args) noexcept {
 | 
			
		||||
			try {
 | 
			
		||||
				m_undoStack.push(ox::make_unique<UC>(ox::forward<Args>(args)...));
 | 
			
		||||
			} catch (ox::Exception const&ex) {
 | 
			
		||||
				oxLogError(ex.toError());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		ox::Error markUnsavedChanges(UndoCommand const*) noexcept;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@
 | 
			
		||||
#include <imgui.h>
 | 
			
		||||
 | 
			
		||||
#include <turbine/context.hpp>
 | 
			
		||||
#include <studio/context.hpp>
 | 
			
		||||
 | 
			
		||||
namespace studio::ig {
 | 
			
		||||
 | 
			
		||||
@@ -52,4 +53,41 @@ bool BeginPopup(turbine::Context &ctx, ox::CStringView popupName, bool &show, Im
 | 
			
		||||
 */
 | 
			
		||||
bool ComboBox(ox::CStringView lbl, ox::SpanView<ox::String> list, size_t &selectedIdx) noexcept;
 | 
			
		||||
 | 
			
		||||
bool FileComboBox(
 | 
			
		||||
		ox::CStringView lbl,
 | 
			
		||||
		studio::StudioContext &sctx,
 | 
			
		||||
		ox::StringView fileExt,
 | 
			
		||||
		size_t &selectedIdx) noexcept;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @param name
 | 
			
		||||
 * @param list
 | 
			
		||||
 * @param selIdx
 | 
			
		||||
 * @return true if new value selected, false otherwise
 | 
			
		||||
 */
 | 
			
		||||
bool ListBox(ox::CStringView name, ox::SpanView<ox::String> const&list, size_t &selIdx) noexcept;
 | 
			
		||||
 | 
			
		||||
class FilePicker {
 | 
			
		||||
	private:
 | 
			
		||||
		bool m_show{};
 | 
			
		||||
		studio::StudioContext &m_sctx;
 | 
			
		||||
		ox::String const m_title;
 | 
			
		||||
		ox::String const m_fileExt;
 | 
			
		||||
		ImVec2 const m_size;
 | 
			
		||||
	public:
 | 
			
		||||
		ox::Signal<ox::Error(ox::StringView)> filePicked;
 | 
			
		||||
 | 
			
		||||
		FilePicker(
 | 
			
		||||
				studio::StudioContext &sctx,
 | 
			
		||||
				ox::String title,
 | 
			
		||||
				ox::String fileExt,
 | 
			
		||||
				ImVec2 const&size = {}) noexcept;
 | 
			
		||||
 | 
			
		||||
		void draw() noexcept;
 | 
			
		||||
 | 
			
		||||
		void show() noexcept;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -127,6 +127,10 @@ ox::CStringView Editor::itemDisplayName() const noexcept {
 | 
			
		||||
	return m_itemName;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Editor::pushCommand(ox::UPtr<UndoCommand> &&cmd) noexcept {
 | 
			
		||||
	m_undoStack.push(std::move(cmd));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UndoStack *Editor::undoStack() noexcept {
 | 
			
		||||
	return &m_undoStack;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -92,4 +92,76 @@ bool ComboBox(
 | 
			
		||||
	return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool FileComboBox(
 | 
			
		||||
		ox::CStringView lbl,
 | 
			
		||||
		studio::StudioContext &sctx,
 | 
			
		||||
		ox::StringView fileExt,
 | 
			
		||||
		size_t &selectedIdx) noexcept {
 | 
			
		||||
	auto const&list = sctx.project->fileList(fileExt);
 | 
			
		||||
	bool out{};
 | 
			
		||||
	auto const first = selectedIdx < list.size() ? list[selectedIdx].c_str() : "";
 | 
			
		||||
	if (ImGui::BeginCombo(lbl.c_str(), first, 0)) {
 | 
			
		||||
		for (auto i = 0u; i < list.size(); ++i) {
 | 
			
		||||
			const auto selected = (selectedIdx == i);
 | 
			
		||||
			if (ImGui::Selectable(list[i].c_str(), selected) && selectedIdx != i) {
 | 
			
		||||
				selectedIdx = i;
 | 
			
		||||
				out = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		ImGui::EndCombo();
 | 
			
		||||
	}
 | 
			
		||||
	return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ListBox(ox::CStringView name, ox::SpanView<ox::String> const&list, size_t &selIdx) noexcept {
 | 
			
		||||
	auto out = false;
 | 
			
		||||
	if (ImGui::BeginListBox(name.c_str())) {
 | 
			
		||||
		for (auto i = 0u; auto const&obj : list) {
 | 
			
		||||
			ig::IDStackItem const idStackItem2(static_cast<int>(i));
 | 
			
		||||
			if (ImGui::Selectable(obj.c_str(), selIdx == i)) {
 | 
			
		||||
				if (i != selIdx) {
 | 
			
		||||
					selIdx = i;
 | 
			
		||||
					out = true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			++i;
 | 
			
		||||
		}
 | 
			
		||||
		ImGui::EndListBox();
 | 
			
		||||
	}
 | 
			
		||||
	return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
FilePicker::FilePicker(
 | 
			
		||||
		studio::StudioContext &sctx,
 | 
			
		||||
		ox::String title,
 | 
			
		||||
		ox::String fileExt,
 | 
			
		||||
		ImVec2 const&size) noexcept:
 | 
			
		||||
	m_sctx(sctx),
 | 
			
		||||
	m_title(std::move(title)),
 | 
			
		||||
	m_fileExt(std::move(fileExt)),
 | 
			
		||||
	m_size(size) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FilePicker::draw() noexcept {
 | 
			
		||||
	if (!m_show) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	auto constexpr popupSz = ImVec2{450.f, 0};
 | 
			
		||||
	ig::IDStackItem const idStackItem(m_title.c_str());
 | 
			
		||||
	if (ig::BeginPopup(m_sctx.tctx, m_title.c_str(), m_show, popupSz)) {
 | 
			
		||||
		auto const&list = m_sctx.project->fileList(m_fileExt);
 | 
			
		||||
		size_t selIdx{};
 | 
			
		||||
		ig::ComboBox(m_title.c_str(), list, selIdx);
 | 
			
		||||
		if (ig::PopupControlsOkCancel(popupSz.x, m_show) == ig::PopupResponse::OK) {
 | 
			
		||||
			filePicked.emit(list[selIdx]);
 | 
			
		||||
		}
 | 
			
		||||
		ImGui::EndPopup();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FilePicker::show() noexcept {
 | 
			
		||||
	m_show = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user