Impl saving image with "S"
This commit is contained in:
parent
099b0e65d6
commit
3d266137d7
3 changed files with 154 additions and 62 deletions
|
@ -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
|
||||
|
|
180
src/state.cpp
180
src/state.cpp
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue