summaryrefslogtreecommitdiffhomepage
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/editor.cpp78
-rw-r--r--main/editor.hpp19
-rw-r--r--main/menu.cpp2
3 files changed, 98 insertions, 1 deletions
diff --git a/main/editor.cpp b/main/editor.cpp
index 7759b596..58b1e14a 100644
--- a/main/editor.cpp
+++ b/main/editor.cpp
@@ -2,7 +2,9 @@
#include "serialize/json-helper.hpp"
#include "serialize/tile-atlas.hpp"
#include "src/loader.hpp"
+#include "random.hpp"
#include "compat/assert.hpp"
+#include "compat/unreachable.hpp"
#include <filesystem>
#include <vector>
@@ -23,6 +25,7 @@ void tile_type::load_atlases()
Containers::StringView name = atlas->name();
if (auto x = name.findLast('.'); x)
name = name.prefix(x.data());
+ std::get<1>(_permutation).reserve((std::size_t)atlas->num_tiles().product());
_atlases[name] = std::move(atlas);
}
}
@@ -43,6 +46,81 @@ std::shared_ptr<tile_atlas> tile_type::atlas(Containers::StringView str)
ABORT("no such atlas: %s", str.cbegin());
}
+void tile_type::clear_selection()
+{
+ _selected_tile = {};
+ _permutation = {};
+ _selection_mode = sel_none;
+}
+
+void tile_type::select_tile(const std::shared_ptr<tile_atlas>& atlas, std::uint8_t variant)
+{
+ ASSERT(atlas);
+ clear_selection();
+ _selection_mode = sel_tile;
+ _selected_tile = { atlas, variant };
+}
+
+void tile_type::select_tile_permutation(const std::shared_ptr<tile_atlas>& atlas)
+{
+ ASSERT(atlas);
+ clear_selection();
+ _selection_mode = sel_perm;
+ _permutation = { atlas, {} };
+}
+
+bool tile_type::is_tile_selected(const std::shared_ptr<tile_atlas>& atlas, std::uint8_t variant)
+{
+ ASSERT(atlas);
+ return _selection_mode == sel_tile && _selected_tile == std::make_tuple(atlas, variant);
+}
+
+bool tile_type::is_permutation_selected(const std::shared_ptr<tile_atlas>& atlas)
+{
+ ASSERT(atlas);
+ return _selection_mode == sel_perm && std::get<0>(_permutation) == atlas;
+}
+
+template<std::random_access_iterator T>
+void fisher_yates(T begin, T end)
+{
+ const auto N = std::distance(begin, end);
+ for (auto i = N-1; i >= 1; i--)
+ {
+ const auto j = random(i+1);
+ using std::swap;
+ swap(begin[i], begin[j]);
+ }
+}
+
+std::tuple<std::shared_ptr<tile_atlas>, std::uint8_t> tile_type::get_selected_perm()
+{
+ auto& [atlas, vec] = _permutation;
+ const std::size_t N = atlas->num_tiles().product();
+ if (N == 0)
+ return {};
+ if (vec.empty())
+ {
+ for (std::uint8_t i = 0; i < N; i++)
+ vec.push_back(i);
+ fisher_yates(vec.begin(), vec.end());
+ }
+ const auto idx = vec.back();
+ vec.pop_back();
+ return {atlas, idx};
+}
+
+std::optional<std::tuple<std::shared_ptr<tile_atlas>, std::uint8_t>> tile_type::get_selected()
+{
+ switch (_selection_mode)
+ {
+ case sel_none: return std::nullopt;
+ case sel_tile: return _selected_tile;
+ case sel_perm: return get_selected_perm();
+ default: unreachable();
+ }
+}
+
editor_state::editor_state()
{
}
diff --git a/main/editor.hpp b/main/editor.hpp
index 53ecf13a..1f0a0f72 100644
--- a/main/editor.hpp
+++ b/main/editor.hpp
@@ -3,6 +3,7 @@
#include <map>
#include <memory>
#include <tuple>
+#include <optional>
#include <Corrade/Containers/StringView.h>
namespace floormat {
@@ -25,13 +26,31 @@ struct tile_type final
Containers::StringView name() const { return _name; }
editor_mode mode() const { return _mode; }
+ void clear_selection();
+ void select_tile(const std::shared_ptr<tile_atlas>& atlas, std::uint8_t variant);
+ void select_tile_permutation(const std::shared_ptr<tile_atlas>& atlas);
+ bool is_tile_selected(const std::shared_ptr<tile_atlas>& atlas, std::uint8_t variant);
+ bool is_permutation_selected(const std::shared_ptr<tile_atlas>& atlas);
+ std::optional<std::tuple<std::shared_ptr<tile_atlas>, std::uint8_t>> get_selected();
+
private:
+ enum selection_mode : std::uint8_t {
+ sel_none, sel_tile, sel_perm,
+ };
+ enum rotation : std::uint8_t {
+ rot_N, rot_W,
+ };
+
std::string _name;
std::map<std::string, std::shared_ptr<tile_atlas>> _atlases;
std::tuple<std::shared_ptr<tile_atlas>, std::uint32_t> _selected_tile;
+ std::tuple<std::shared_ptr<tile_atlas>, std::vector<std::uint8_t>> _permutation;
+ selection_mode _selection_mode = sel_none;
editor_mode _mode;
+ rotation _rotation{};
void load_atlases();
+ std::tuple<std::shared_ptr<tile_atlas>, std::uint8_t> get_selected_perm();
};
struct editor_state final
diff --git a/main/menu.cpp b/main/menu.cpp
index 3357aa6e..e5f291af 100644
--- a/main/menu.cpp
+++ b/main/menu.cpp
@@ -152,7 +152,7 @@ void app::draw_menu_(tile_type& type, float main_menu_height)
const auto& k_ = k;
const auto& v_ = v;
const auto click_event = [&] {
- if (ImGui::IsItemClicked(ImGuiMouseButton_Right) && ImGui::GetIO().MouseClicked[1])
+ if (ImGui::IsItemClicked(ImGuiMouseButton_Right))
{
Debug{} << "shuffle" << k_.data();
}