| 1 |
#include "ImGuiPlotterViewer.hh" |
| 2 |
|
| 3 |
#include "Connector.hh" |
| 4 |
#include "ImGuiManager.hh" |
| 5 |
#include "ImGuiUtils.hh" |
| 6 |
#include "MSXMotherBoard.hh" |
| 7 |
#include "Plotter.hh" |
| 8 |
#include "Pluggable.hh" |
| 9 |
#include "PluggingController.hh" |
| 10 |
|
| 11 |
#include <imgui.h> |
| 12 |
|
| 13 |
using namespace std::literals; |
| 14 |
|
| 15 |
namespace openmsx { |
| 16 |
|
| 17 |
ImGuiPlotterViewer::ImGuiPlotterViewer(ImGuiManager& manager_) |
| 18 |
: ImGuiPart(manager_) |
| 19 |
{ |
| 20 |
} |
| 21 |
|
| 22 |
void ImGuiPlotterViewer::save(ImGuiTextBuffer& buf) |
| 23 |
{ |
| 24 |
savePersistent(buf, *this, persistentElements); |
| 25 |
} |
| 26 |
|
| 27 |
void ImGuiPlotterViewer::loadLine(std::string_view name, zstring_view value) |
| 28 |
{ |
| 29 |
loadOnePersistent(name, value, *this, persistentElements); |
| 30 |
} |
| 31 |
|
| 32 |
void ImGuiPlotterViewer::paint(MSXMotherBoard* motherBoard) |
| 33 |
{ |
| 34 |
if (!show) return; |
| 35 |
|
| 36 |
ImGui::SetNextWindowSize({480, 720}, ImGuiCond_FirstUseEver); |
| 37 |
im::Window("Plotter viewer", &show, [&]{ |
| 38 |
if (!motherBoard) { |
| 39 |
ImGui::TextUnformatted("No machine present."); |
| 40 |
return; |
| 41 |
} |
| 42 |
|
| 43 |
|
| 44 |
MSXPlotter* plotter = nullptr; |
| 45 |
const auto& controller = motherBoard->getPluggingController(); |
| 46 |
for (auto* connector : controller.getConnectors()) { |
| 47 |
if (auto* pluggable = &connector->getPlugged()) { |
| 48 |
if (auto* p = dynamic_cast<MSXPlotter*>(pluggable)) { |
| 49 |
plotter = p; |
| 50 |
break; |
| 51 |
} |
| 52 |
} |
| 53 |
} |
| 54 |
|
| 55 |
if (!plotter) { |
| 56 |
ImGui::TextUnformatted("Plotter not plugged in."); |
| 57 |
return; |
| 58 |
} |
| 59 |
|
| 60 |
auto* paper = plotter->getPaper(); |
| 61 |
if (!paper) { |
| 62 |
ImGui::TextUnformatted("Plotter has no paper."); |
| 63 |
return; |
| 64 |
} |
| 65 |
|
| 66 |
|
| 67 |
const auto& style = ImGui::GetStyle(); |
| 68 |
auto panelHeight = 2.0f * ImGui::GetTextLineHeight() + 4.0f * style.ItemSpacing.y + 2.0f * style.FramePadding.y + 2.0f; |
| 69 |
auto availableSize = max(ImGui::GetContentRegionAvail() - gl::vec2{0.0f, panelHeight}, gl::vec2{0.0f}); |
| 70 |
|
| 71 |
auto paperSize = gl::vec2(paper->size()); |
| 72 |
auto scaleVec = availableSize / paperSize; |
| 73 |
float scale = min_component(scaleVec); |
| 74 |
auto displaySize = paperSize * scale; |
| 75 |
|
| 76 |
auto screenPos = ImGui::GetCursorScreenPos(); |
| 77 |
auto& texture = paper->updateTexture(max(trunc(displaySize), gl::ivec2{1})); |
| 78 |
ImGui::Image(texture.getImGui(), displaySize); |
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
auto plotPos = plotter->getPlotterPos(); |
| 84 |
auto paperPos = gl::vec2{MSXPlotter::MARGIN.x, MSXPlotter::FULL_AREA.y - MSXPlotter::MARGIN.y} |
| 85 |
+ plotPos * gl::vec2{1, -1}; |
| 86 |
auto stepToPixel = paperSize / MSXPlotter::FULL_AREA; |
| 87 |
auto penScrnPos = screenPos + (paperPos * stepToPixel * scale); |
| 88 |
|
| 89 |
auto* drawList = ImGui::GetWindowDrawList(); |
| 90 |
float crossSize = 10.0f; |
| 91 |
drawList->AddLine(penScrnPos + gl::vec2{-crossSize, 0.0f}, |
| 92 |
penScrnPos + gl::vec2{ crossSize, 0.0f}, 0xFF0000FF); |
| 93 |
drawList->AddLine(penScrnPos + gl::vec2{0.0f, -crossSize}, |
| 94 |
penScrnPos + gl::vec2{0.0f, crossSize}, 0xFF0000FF); |
| 95 |
|
| 96 |
ImGui::Separator(); |
| 97 |
auto pen = plotter->getSelectedPen(); |
| 98 |
static constexpr std::array<std::string_view, 4> penNames = { |
| 99 |
"Black", "Blue", "Green", "Red" |
| 100 |
}; |
| 101 |
ImGui::StrCat("Pen: ", penNames[pen]); |
| 102 |
ImGui::SameLine(); |
| 103 |
auto c = gl::vec4{gl::vec3(1.0f) - MSXPlotter::inkColors[pen], 1.0f}; |
| 104 |
ImGui::ColorButton("##pencolor", c, ImGuiColorEditFlags_NoTooltip, |
| 105 |
gl::vec2{ImGui::GetFontSize()}); |
| 106 |
ImGui::SameLine(); |
| 107 |
ImGui::Text(" Pos: (%.1f, %.1f)", double(plotPos.x), double(plotPos.y)); |
| 108 |
ImGui::SameLine(); |
| 109 |
ImGui::StrCat(" Mode: ", plotter->isGraphicMode() ? "Graphic"sv : "Text"sv); |
| 110 |
|
| 111 |
ImGui::Separator(); |
| 112 |
if (ImGui::Button("Cycle Pen")) { |
| 113 |
plotter->cyclePen(); |
| 114 |
} |
| 115 |
ImGui::SameLine(); |
| 116 |
if (ImGui::Button("Up")) { |
| 117 |
plotter->moveStep({0.0f, 10.0f}); |
| 118 |
} |
| 119 |
ImGui::SameLine(); |
| 120 |
if (ImGui::Button("Down")) { |
| 121 |
plotter->moveStep({0.0f, -10.0f}); |
| 122 |
} |
| 123 |
ImGui::SameLine(); |
| 124 |
if (ImGui::Button("Eject Paper")) { |
| 125 |
plotter->ejectPaper(); |
| 126 |
} |
| 127 |
}); |
| 128 |
} |
| 129 |
|
| 130 |
} |