// MassBuilderSaveTool // Copyright (C) 2021 Guillaume Jacquemin // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include "../Maps/StyleNames.h" #include "../FontAwesome/IconsFontAwesome5.h" #include "SaveTool.h" void SaveTool::drawMassViewer() { if(!_currentMass || _currentMass->state() != Mass::State::Valid) { _currentMass = nullptr; _uiState = UiState::MainManager; _queue.addToast(Toast::Type::Error, "The selected M.A.S.S. isn't valid anymore."); return; } ImGui::SetNextWindowPos({0.0f, ImGui::GetItemRectSize().y}, ImGuiCond_Always); ImGui::SetNextWindowSize({Float(windowSize().x()), Float(windowSize().y()) - ImGui::GetItemRectSize().y}, ImGuiCond_Always); if(!ImGui::Begin("##MainWindow", nullptr, ImGuiWindowFlags_NoDecoration|ImGuiWindowFlags_NoMove| ImGuiWindowFlags_NoBackground|ImGuiWindowFlags_NoBringToFrontOnFocus)) { ImGui::End(); return; } ImGui::Text("Current M.A.S.S.: %s (%s)", (*_currentMass->name()).c_str(), _currentMass->filename().c_str()); ImGui::SameLine(); if(ImGui::SmallButton(ICON_FA_ARROW_LEFT " Back to main manager")) { _currentMass = nullptr; _uiState = UiState::MainManager; } ImGui::TextColored(ImColor(255, 255, 0), ICON_FA_EXCLAMATION_TRIANGLE); ImGui::SameLine(); ImGui::TextWrapped("WARNING: Colours in this app may look different from in-game colours, due to unavoidable differences in the rendering pipeline."); ImGui::TextColored(ImColor(255, 255, 0), ICON_FA_EXCLAMATION_TRIANGLE); ImGui::SameLine(); ImGui::TextWrapped("Real-time updates are disabled while on this screen. %s", _currentMass->dirty() ? "The save file has been changed." : ""); if(_currentMass->dirty()) { ImGui::SameLine(); if(ImGui::SmallButton(ICON_FA_SYNC_ALT " Refresh")) { _currentMass->refreshValues(); _currentMass->setDirty(false); } } if(ImGui::BeginChild("##MassInfo", {ImGui::GetContentRegionAvailWidth() * 0.60f, 0.0f}, true, ImGuiWindowFlags_MenuBar)) { if(ImGui::BeginMenuBar()) { ImGui::TextUnformatted("M.A.S.S. Information"); ImGui::EndMenuBar(); } if(ImGui::BeginTabBar("##MassTabBar")) { if(ImGui::BeginTabItem("Frame")) { drawFrameInfo(); ImGui::EndTabItem(); } ImGui::EndTabBar(); } } ImGui::EndChild(); ImGui::SameLine(); if(ImGui::BeginChild("##GlobalStyles", {0.0f, 0.0f}, true, ImGuiWindowFlags_MenuBar)) { if(ImGui::BeginMenuBar()) { ImGui::TextUnformatted("Global styles"); ImGui::EndMenuBar(); } ImGui::TextUnformatted("Placeholder"); } ImGui::EndChild(); ImGui::End(); } void SaveTool::drawFrameInfo() { if(!_currentMass || _currentMass->state() != Mass::State::Valid) { return; } ImGui::TextUnformatted("Frame type: Skeleton"); // Placeholder for now, replace with actual code once other frames are implemented. drawJointSliders(); drawFramePaint(); } void SaveTool::drawJointSliders() { if(!ImGui::CollapsingHeader("Joint sliders")) { return; } static Joints sliders = _currentMass->jointSliders(); static bool joints_edit = false; static bool joints_dirty = false; ImGui::TextWrapped("In-game values are multiplied by 100.\nFor example, 0.500 here is equal to 50 in-game."); if(ImGui::BeginTable("##JointSliderTable", 2, ImGuiTableFlags_Borders)) { ImGui::TableSetupColumn("##SliderLabel", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("##Sliders", ImGuiTableColumnFlags_WidthStretch); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::AlignTextToFramePadding(); ImGui::TextUnformatted("Neck"); ImGui::TableSetColumnIndex(1); if(joints_edit) { ImGui::SetNextItemWidth(-1.0f); if(ImGui::SliderFloat("##NeckSlider", &sliders.neck, 0.0f, 1.0f)) { joints_dirty = true; } } else { ImGui::AlignTextToFramePadding(); ImGui::Text("%.3f", Double(_currentMass->jointSliders().neck)); } ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::AlignTextToFramePadding(); ImGui::TextUnformatted("Body"); ImGui::TableSetColumnIndex(1); if(joints_edit) { ImGui::SetNextItemWidth(-1.0f); if(ImGui::SliderFloat("##BodySlider", &sliders.body, 0.0f, 1.0f)) { joints_dirty = true; } } else { ImGui::AlignTextToFramePadding(); ImGui::Text("%.3f", Double(_currentMass->jointSliders().body)); } ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::AlignTextToFramePadding(); ImGui::TextUnformatted("Shoulders"); ImGui::TableSetColumnIndex(1); if(joints_edit) { ImGui::SetNextItemWidth(-1.0f); if(ImGui::SliderFloat("##ShouldersSlider", &sliders.shoulders, 0.0f, 1.0f)) { joints_dirty = true; } } else { ImGui::AlignTextToFramePadding(); ImGui::Text("%.3f", Double(_currentMass->jointSliders().shoulders)); } ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::AlignTextToFramePadding(); ImGui::TextUnformatted("Hips"); ImGui::TableSetColumnIndex(1); if(joints_edit) { ImGui::SetNextItemWidth(-1.0f); if(ImGui::SliderFloat("##HipsSlider", &sliders.hips, 0.0f, 1.0f)) { joints_dirty = true; } } else { ImGui::AlignTextToFramePadding(); ImGui::Text("%.3f", Double(_currentMass->jointSliders().hips)); } ImGui::TableNextRow(); ImGui::TableSetColumnIndex(1); if(ImGui::BeginTable("##UpperLowerLayoutTable", 2, ImGuiTableFlags_BordersInnerV)) { ImGui::TableSetupColumn("##Upper", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##Lower", ImGuiTableColumnFlags_WidthStretch); ImGui::TableNextColumn(); ImGui::AlignTextToFramePadding(); ImGui::TextUnformatted("Upper"); ImGui::TableNextColumn(); ImGui::AlignTextToFramePadding(); ImGui::TextUnformatted("Lower"); ImGui::EndTable(); } ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::AlignTextToFramePadding(); ImGui::TextUnformatted("Arms"); ImGui::TableSetColumnIndex(1); if(ImGui::BeginTable("##UpperLowerArmsLayoutTable", 2, ImGuiTableFlags_BordersInnerV)) { ImGui::TableSetupColumn("##UpperArms", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##LowerArms", ImGuiTableColumnFlags_WidthStretch); ImGui::TableNextColumn(); if(joints_edit) { ImGui::SetNextItemWidth(-1.0f); if(ImGui::SliderFloat("##UpperArmsSlider", &sliders.upperArms, 0.0f, 1.0f)) { joints_dirty = true; } } else { ImGui::AlignTextToFramePadding(); ImGui::Text("%.3f", Double(_currentMass->jointSliders().upperArms)); } ImGui::TableNextColumn(); if(joints_edit) { ImGui::SetNextItemWidth(-1.0f); if(ImGui::SliderFloat("##LowerArmsSlider", &sliders.lowerArms, 0.0f, 1.0f)) { joints_dirty = true; } } else { ImGui::AlignTextToFramePadding(); ImGui::Text("%.3f", Double(_currentMass->jointSliders().lowerArms)); } ImGui::EndTable(); } ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::AlignTextToFramePadding(); ImGui::TextUnformatted("Legs"); ImGui::TableSetColumnIndex(1); if(ImGui::BeginTable("##UpperLowerLegsLayoutTable", 2, ImGuiTableFlags_BordersInnerV)) { ImGui::TableSetupColumn("##UpperLegs", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##LowerLegs", ImGuiTableColumnFlags_WidthStretch); ImGui::TableNextColumn(); if(joints_edit) { ImGui::SetNextItemWidth(-1.0f); if(ImGui::SliderFloat("##UpperLegsSlider", &sliders.upperLegs, 0.0f, 1.0f)) { joints_dirty = true; } } else { ImGui::AlignTextToFramePadding(); ImGui::Text("%.3f", Double(_currentMass->jointSliders().upperLegs)); } ImGui::TableNextColumn(); if(joints_edit) { ImGui::SetNextItemWidth(-1.0f); if(ImGui::SliderFloat("##LowerLegsSlider", &sliders.lowerLegs, 0.0f, 1.0f)) { joints_dirty = true; } } else { ImGui::AlignTextToFramePadding(); ImGui::Text("%.3f", Double(_currentMass->jointSliders().lowerLegs)); } ImGui::EndTable(); } ImGui::EndTable(); } if(joints_edit) { if(!joints_dirty) { ImGui::BeginDisabled(); ImGui::Button(ICON_FA_SAVE " Save changes"); ImGui::SameLine(); ImGui::Button(ICON_FA_UNDO " Reset sliders"); ImGui::EndDisabled(); } else { if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save changes"); })) { if(!_currentMass->setSliders(sliders)) { _queue.addToast(Toast::Type::Error, "Error writing the joint sliders."); } joints_dirty = false; joints_edit = false; } ImGui::SameLine(); if(ImGui::Button(ICON_FA_UNDO " Reset sliders")) { sliders = _currentMass->jointSliders(); joints_dirty = false; } } ImGui::SameLine(); if(ImGui::Button(ICON_FA_TIMES " Cancel editing")) { sliders = _currentMass->jointSliders(); joints_dirty = false; joints_edit = false; } ImGui::TextUnformatted("To input out-of-range values, hold Ctrl and click on a slider."); } else { if(ImGui::Button(ICON_FA_EDIT " Edit sliders")) { sliders = _currentMass->jointSliders(); joints_edit = true; } } } void SaveTool::drawFramePaint() { if(!ImGui::CollapsingHeader("Paint")) { return; } ImGui::TextUnformatted("Frame styles:"); for(Int i = 0; i < 4; i++) { ImGui::AlignTextToFramePadding(); ImGui::Text("Slot %d:", i + 1); ImGui::SameLine(); ImGui::PushID(i); GameState game_state = _gameState; if(!_unsafeMode && game_state != GameState::NotRunning) { ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.5f); } if(ImGui::BeginCombo("##Style", style_names.at(_currentMass->frameStyles()[i]))) { for(const auto& style : style_names) { if(ImGui::Selectable(style.second, _currentMass->frameStyles()[i] == style.first)) { if(!_currentMass->setFrameStyle(i, style.first)) { _queue.addToast(Toast::Type::Error, Mass::lastError()); } else { _currentMass->refreshValues(); } } } ImGui::EndCombo(); } if(!_unsafeMode && game_state != GameState::NotRunning) { ImGui::PopItemFlag(); ImGui::PopStyleVar(); } ImGui::PopID(); } ImGui::Separator(); static bool eye_flare_edit = false; static bool eye_flare_dirty = false; static Color4 eye_flare = _currentMass->eyeFlareColour(); ImGui::AlignTextToFramePadding(); ImGui::TextUnformatted("Eye flare colour:"); ImGui::SameLine(); ImGui::BeginGroup(); if(eye_flare_edit) { if(ImGui::ColorEdit3("##EyeFlarePicker", &eye_flare.x())) { eye_flare_dirty = true; } ImGui::SameLine(); drawHelpMarker("Right-click for more option, click the coloured square for the full picker.", 250.0f); if(!eye_flare_dirty) { ImGui::BeginDisabled(); ImGui::Button(ICON_FA_SAVE " Save"); ImGui::SameLine(); ImGui::Button(ICON_FA_UNDO " Reset"); ImGui::EndDisabled(); } else { if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) { if(!_currentMass->setEyeFlareColour(eye_flare)) { _queue.addToast(Toast::Type::Error, "Error writing the eye flare colour."); } eye_flare_dirty = false; eye_flare_edit = false; } ImGui::SameLine(); if(ImGui::Button(ICON_FA_UNDO " Reset")) { eye_flare = _currentMass->eyeFlareColour(); eye_flare_dirty = false; } } ImGui::SameLine(); if(ImGui::Button(ICON_FA_TIMES " Cancel")) { eye_flare = _currentMass->eyeFlareColour(); eye_flare_dirty = false; eye_flare_edit = false; } } else { ImGui::BeginDisabled(); ImColor colour{_currentMass->eyeFlareColour()}; ImGui::ColorEdit3("##EyeFlarePicker", &colour.Value.x); ImGui::EndDisabled(); if(ImGui::Button(ICON_FA_EDIT " Edit")) { eye_flare = _currentMass->eyeFlareColour(); eye_flare_edit = true; } } ImGui::EndGroup(); }