[nostalgia/core/studio] Cleanup and decouple main TileSheetEditor drawing from ImGui

This commit is contained in:
2022-02-13 02:25:14 -06:00
parent 779dd1fd05
commit 7370b23c9d
10 changed files with 123 additions and 128 deletions
+85 -55
View File
@@ -23,8 +23,8 @@ TileSheetEditor::TileSheetEditor(Context *ctx, const ox::String &path) {
oxThrowError(m_pixelsDrawer.buildShader());
oxThrowError(m_pixelGridDrawer.buildShader());
oxRequireT(img, readObj<NostalgiaGraphic>(ctx, m_itemPath.c_str()));
oxThrowError(readObj<NostalgiaPalette>(ctx, img->defaultPalette).moveTo(&m_pal));
m_img = *img;
m_img = std::move(*img);
oxThrowError(readObj<NostalgiaPalette>(ctx, m_img.defaultPalette).moveTo(&m_pal));
}
ox::String TileSheetEditor::itemName() const noexcept {
@@ -49,57 +49,16 @@ void TileSheetEditor::paste() {
void TileSheetEditor::draw(core::Context*) noexcept {
const auto paneSize = ImGui::GetContentRegionAvail();
const auto sizei = common::Size(static_cast<int>(paneSize.x), static_cast<int>(paneSize.y));
if (m_framebuffer.width != sizei.width || m_framebuffer.height != sizei.height) {
m_framebuffer = glutils::generateFrameBuffer(sizei.width, sizei.height);
m_pixelsDrawer.initBufferSet(m_img, *m_pal);
m_pixelGridDrawer.initBufferSet(m_img);
} else if (m_updated) {
m_pixelsDrawer.initBufferSet(m_img, *m_pal);
m_pixelGridDrawer.initBufferSet(m_img);
}
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glViewport(0, 0, sizei.width, sizei.height);
glDraw();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
ImGui::Image(reinterpret_cast<void*>(m_framebuffer.color.id), paneSize, ImVec2(0, 1), ImVec2(1, 0));
// handle input, this must come after drawing
if (ImGui::IsItemHovered()) {
const auto &io = ImGui::GetIO();
const auto wheel = io.MouseWheel;
const auto wheelh = io.MouseWheelH;
if (wheel != 0) {
const auto zoomMod = ox::defines::OS == ox::OS::Darwin ? io.KeySuper : io.KeyCtrl;
const auto pixelSize = m_pixelsDrawer.pixelSize(paneSize);
const ImVec2 sheetSize(pixelSize.x * static_cast<float>(m_img.columns) * TileWidth,
pixelSize.y * static_cast<float>(m_img.rows) * TileHeight);
if (zoomMod) {
m_pixelSizeMod = ox::clamp(m_pixelSizeMod + wheel * 0.02f, 0.55f, 2.f);
m_pixelsDrawer.setPixelSizeMod(m_pixelSizeMod);
m_pixelGridDrawer.setPixelSizeMod(m_pixelSizeMod);
m_updated = true;
} else {
m_scrollOffset.y -= wheel * 0.1f;
}
// adjust scroll offset in both cases because the image can be zoomed
// or scrolled off screen
m_scrollOffset.y = ox::clamp(m_scrollOffset.y, 0.f, sheetSize.y / 2);
}
if (wheelh != 0) {
const auto pixelSize = m_pixelsDrawer.pixelSize(paneSize);
const ImVec2 sheetSize(pixelSize.x * static_cast<float>(m_img.columns) * TileWidth,
pixelSize.y * static_cast<float>(m_img.rows) * TileHeight);
m_scrollOffset.x += wheelh * 0.1f;
m_scrollOffset.x = ox::clamp(m_scrollOffset.x, -(sheetSize.x / 2), 0.f);
}
if (io.MouseDown[0]) {
auto clickPos = io.MousePos;
const auto &winPos = ImGui::GetWindowPos();
clickPos.x -= winPos.x + 8;
clickPos.y -= winPos.y + 31;
clickPixel(paneSize, clickPos.x, clickPos.y);
}
}
const auto tileSheetParentSize = ImVec2(paneSize.x - m_palViewWidth, paneSize.y);
const auto fbSize = common::Vec2(tileSheetParentSize.x - 16, tileSheetParentSize.y - 16);
ImGui::BeginChild("child1", ImVec2(tileSheetParentSize.x, tileSheetParentSize.y), true);
drawTileSheet(fbSize);
ImGui::EndChild();
ImGui::SameLine();
// draw palette/color picker
ImGui::BeginChild("child2", ImVec2(m_palViewWidth - 8, paneSize.y), true);
drawPalettePicker();
ImGui::EndChild();
}
void TileSheetEditor::glDraw() noexcept {
@@ -148,11 +107,82 @@ void TileSheetEditor::getFillPixels(bool *pixels, common::Point pt, int oldColor
}
}
void TileSheetEditor::clickPixel(const ImVec2 &paneSize, float x, float y) noexcept {
void TileSheetEditor::drawTileSheet(const common::Vec2 &fbSize) noexcept {
const auto fbSizei = common::Size(static_cast<int>(fbSize.x), static_cast<int>(fbSize.y));
if (m_framebuffer.width != fbSizei.width || m_framebuffer.height != fbSizei.height) {
m_framebuffer = glutils::generateFrameBuffer(fbSizei.width, fbSizei.height);
m_pixelsDrawer.initBufferSet(common::Vec2(fbSize), m_img, *m_pal);
m_pixelGridDrawer.initBufferSet(common::Vec2(fbSize), m_img);
} else if (m_updated) {
m_pixelsDrawer.initBufferSet(common::Vec2(fbSize), m_img, *m_pal);
m_pixelGridDrawer.initBufferSet(common::Vec2(fbSize), m_img);
}
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glViewport(0, 0, fbSizei.width, fbSizei.height);
glDraw();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
ImGui::Image(reinterpret_cast<void*>(m_framebuffer.color.id), static_cast<ImVec2>(fbSize), ImVec2(0, 1), ImVec2(1, 0));
// handle input, this must come after drawing
if (ImGui::IsItemHovered()) {
const auto &io = ImGui::GetIO();
const auto wheel = io.MouseWheel;
const auto wheelh = io.MouseWheelH;
if (wheel != 0) {
const auto zoomMod = ox::defines::OS == ox::OS::Darwin ? io.KeySuper : io.KeyCtrl;
const auto pixelSize = m_pixelsDrawer.pixelSize(common::Vec2(fbSize));
const ImVec2 sheetSize(pixelSize.x * static_cast<float>(m_img.columns) * TileWidth,
pixelSize.y * static_cast<float>(m_img.rows) * TileHeight);
if (zoomMod) {
m_pixelSizeMod = ox::clamp(m_pixelSizeMod + wheel * 0.02f, 0.55f, 2.f);
m_pixelsDrawer.setPixelSizeMod(m_pixelSizeMod);
m_pixelGridDrawer.setPixelSizeMod(m_pixelSizeMod);
m_updated = true;
} else {
m_scrollOffset.y -= wheel * 0.1f;
}
// adjust scroll offset in both cases because the image can be zoomed
// or scrolled off screen
m_scrollOffset.y = ox::clamp(m_scrollOffset.y, 0.f, sheetSize.y / 2);
}
if (wheelh != 0) {
const auto pixelSize = m_pixelsDrawer.pixelSize(common::Vec2(fbSize));
const ImVec2 sheetSize(pixelSize.x * static_cast<float>(m_img.columns) * TileWidth,
pixelSize.y * static_cast<float>(m_img.rows) * TileHeight);
m_scrollOffset.x += wheelh * 0.1f;
m_scrollOffset.x = ox::clamp(m_scrollOffset.x, -(sheetSize.x / 2), 0.f);
}
if (io.MouseDown[0]) {
auto clickPos = common::Vec2(io.MousePos);
const auto &winPos = ImGui::GetWindowPos();
clickPos.x -= winPos.x + 10;
clickPos.y -= winPos.y + 10;
clickPixel(fbSize, clickPos);
}
}
}
void TileSheetEditor::drawPalettePicker() noexcept {
// header
ImGui::BeginTable("PaletteTable", 2);
ImGui::TableSetupColumn("No.", 0, 0.35);
ImGui::TableSetupColumn("Color16", 0, 3);
ImGui::TableHeadersRow();
for (auto i = 1; auto c : m_pal->colors) {
ImGui::TableNextColumn();
ImGui::Text("%d", i);
ImGui::TableNextColumn();
ImGui::Text("(%d, %d, %d)", red16(c), green16(c), blue16(c));
++i;
}
ImGui::EndTable();
}
void TileSheetEditor::clickPixel(const common::Vec2 &paneSize, const common::Vec2 &clickPos) noexcept {
auto [x, y] = clickPos;
const auto pixDrawSz = m_pixelsDrawer.pixelSize(paneSize);
x /= paneSize.x;
y /= paneSize.y;
x += m_scrollOffset.x / 2;
x += -m_scrollOffset.x / 2;
y += m_scrollOffset.y / 2;
x /= pixDrawSz.x;
y /= pixDrawSz.y;