Impl saving image with "S"

This commit is contained in:
Stephen Seo 2020-07-22 18:19:34 +09:00
parent 099b0e65d6
commit 3d266137d7
3 changed files with 154 additions and 62 deletions

View file

@ -29,6 +29,7 @@ namespace Tri {
ImGui::Text("Press \"R\" to undo.");
ImGui::Text("Press \"C\" to change colors");
ImGui::Text("Press \"B\" to change background color");
ImGui::Text("Press \"S\" to save what was drawn as a png image");
ImGui::End();
}
}
@ -68,6 +69,26 @@ namespace Tri {
ImGui::End();
}
}
inline void draw_save(Tri::State *state) {
if(state->get_flags().test(6)) {
auto *filenameBuffer = state->get_save_filename_buffer();
ImGui::Begin("Save");
ImGui::InputText("Filename", filenameBuffer->data(), filenameBuffer->size() - 1);
if(ImGui::Button("Save")) {
if(state->do_save()) {
state->close_save();
}
} else if(ImGui::Button("Cancel")) {
state->close_save();
}
auto string_view = state->failed_save_message();
if(!string_view.empty()) {
ImGui::TextUnformatted(string_view.data(), string_view.data() + string_view.size());
}
ImGui::End();
}
}
}
#endif

View file

@ -2,6 +2,7 @@
#include <cstring>
#include <cassert>
#include <string>
#include <imgui-SFML.h>
@ -35,6 +36,8 @@ bgColor(sf::Color::Black)
pointCircle.setFillColor(sf::Color::White);
pointCircle.setOutlineColor(sf::Color::Black);
pointCircle.setOutlineThickness(1.0f);
saveFilenameBuffer.fill(0);
}
Tri::State::~State() {
@ -49,60 +52,64 @@ void Tri::State::handle_events() {
window.close();
flags.reset(1);
} else if(event.type == sf::Event::KeyPressed) {
if(event.key.code == sf::Keyboard::H) {
flags.flip(0);
} else if(event.key.code == sf::Keyboard::U) {
if(currentTri_state > 0) {
switch(currentTri_state) {
case FIRST:
currentTri_state = CurrentState::NONE;
break;
case SECOND:
currentTri_state = CurrentState::FIRST;
break;
default:
assert(!"Unreachable code");
break;
if(!flags.test(6)) {
if(event.key.code == sf::Keyboard::H) {
flags.flip(0);
} else if(event.key.code == sf::Keyboard::U) {
if(currentTri_state > 0) {
switch(currentTri_state) {
case FIRST:
currentTri_state = CurrentState::NONE;
break;
case SECOND:
currentTri_state = CurrentState::FIRST;
break;
default:
assert(!"Unreachable code");
break;
}
} else if(trisIndex > 0) {
--trisIndex;
}
} else if(trisIndex > 0) {
--trisIndex;
} else if(event.key.code == sf::Keyboard::R) {
if(currentTri_state != CurrentState::NONE
&& currentTri_state < currentTri_maxState) {
switch(currentTri_state) {
case NONE:
currentTri_state = CurrentState::FIRST;
break;
case FIRST:
currentTri_state = CurrentState::SECOND;
break;
default:
assert(!"Unreachable code");
break;
}
} else if(tris.size() > trisIndex) {
++trisIndex;
} else if(currentTri_state < currentTri_maxState) {
switch(currentTri_state) {
case NONE:
currentTri_state = CurrentState::FIRST;
break;
case FIRST:
currentTri_state = CurrentState::SECOND;
break;
default:
assert(!"Unreachable code");
break;
}
}
} else if(event.key.code == sf::Keyboard::C) {
flags.flip(2);
} else if(event.key.code == sf::Keyboard::B) {
flags.flip(5);
} else if(event.key.code == sf::Keyboard::S) {
flags.flip(6);
}
} else if(event.key.code == sf::Keyboard::R) {
if(currentTri_state != CurrentState::NONE
&& currentTri_state < currentTri_maxState) {
switch(currentTri_state) {
case NONE:
currentTri_state = CurrentState::FIRST;
break;
case FIRST:
currentTri_state = CurrentState::SECOND;
break;
default:
assert(!"Unreachable code");
break;
}
} else if(tris.size() > trisIndex) {
++trisIndex;
} else if(currentTri_state < currentTri_maxState) {
switch(currentTri_state) {
case NONE:
currentTri_state = CurrentState::FIRST;
break;
case FIRST:
currentTri_state = CurrentState::SECOND;
break;
default:
assert(!"Unreachable code");
break;
}
}
} else if(event.key.code == sf::Keyboard::C) {
flags.flip(2);
} else if(event.key.code == sf::Keyboard::B) {
flags.flip(5);
}
} else if(event.type == sf::Event::MouseButtonPressed) {
if(!flags.test(2) && !flags.test(5)) {
if(!flags.test(2) && !flags.test(5) && !flags.test(6)) {
switch(currentTri_state) {
case CurrentState::NONE:
currentTri[0] = sf::Vector2f(event.mouseButton.x, event.mouseButton.y);
@ -170,24 +177,14 @@ void Tri::State::update() {
Tri::draw_show_help(this);
Tri::draw_color_picker(this);
Tri::draw_bg_color_picker(this);
Tri::draw_save(this);
Tri::draw_help(this);
ImGui::EndFrame();
}
void Tri::State::draw() {
window.clear(bgColor);
// draw tris
for(unsigned int i = 0; i < trisIndex; ++i) {
window.draw(tris[i]);
}
// draw points
for(unsigned int i = 0; i < currentTri_state; ++i) {
pointCircle.setPosition(currentTri[i]);
window.draw(pointCircle);
}
draw_to_target(&window);
// draw gui stuff
ImGui::SFML::Render(window);
@ -195,6 +192,23 @@ void Tri::State::draw() {
window.display();
}
void Tri::State::draw_to_target(sf::RenderTarget *target, bool draw_points) {
target->clear(bgColor);
// draw tris
for(unsigned int i = 0; i < trisIndex; ++i) {
target->draw(tris[i]);
}
// draw points
if(draw_points) {
for(unsigned int i = 0; i < currentTri_state; ++i) {
pointCircle.setPosition(currentTri[i]);
target->draw(pointCircle);
}
}
}
unsigned int Tri::State::get_width() const {
return width;
}
@ -220,3 +234,45 @@ float* Tri::State::get_bg_color() {
flags.set(4);
return bgColorPickerColor;
}
Tri::State::FilenameBufferType* Tri::State::get_save_filename_buffer() {
return &saveFilenameBuffer;
}
bool Tri::State::do_save() {
sf::RenderTexture saveTexture;
if(!saveTexture.create(width, height)) {
#ifndef NDEBUG
puts("ERROR: Failed to create texture for saving");
#endif
failedSaveMessage = std::string("Failed to create texture for saving");
return false;
}
draw_to_target(&saveTexture, false);
saveTexture.display();
sf::Image saveImage = saveTexture.getTexture().copyToImage();
std::string filename = std::string(saveFilenameBuffer.data());
if(saveImage.saveToFile(filename)) {
#ifndef NDEBUG
printf("Saved to \"%s\"\n", filename.c_str());
#endif
failedSaveMessage.clear();
return true;
} else {
#ifndef NDEBUG
printf("ERROR: Failed to save \"%s\"\n", filename.c_str());
#endif
failedSaveMessage = std::string("Failed to save (does the name end in \".png\"?)");
return false;
}
}
std::string_view Tri::State::failed_save_message() const {
return failedSaveMessage;
}
void Tri::State::close_save() {
flags.reset(6);
}

View file

@ -3,6 +3,7 @@
#include <bitset>
#include <vector>
#include <array>
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
@ -22,6 +23,7 @@ namespace Tri {
* 3 - color picker color dirty
* 4 - bg color picker color dirty
* 5 - display bg color picker
* 6 - draw save
*/
typedef std::bitset<64> BitsetType;
BitsetType flags;
@ -44,11 +46,19 @@ namespace Tri {
float bgColorPickerColor[3];
sf::Color bgColor;
typedef std::array<char, 256> FilenameBufferType;
FilenameBufferType saveFilenameBuffer;
std::string failedSaveMessage;
public:
void handle_events();
void update();
void draw();
private:
void draw_to_target(sf::RenderTarget *target, bool draw_points = true);
public:
unsigned int get_width() const;
unsigned int get_height() const;
@ -58,6 +68,11 @@ namespace Tri {
float* get_color();
float* get_bg_color();
FilenameBufferType* get_save_filename_buffer();
bool do_save();
std::string_view failed_save_message() const;
void close_save();
};
}