mirror of
https://gitlab.com/square-game-liberation-front/F.E.I.S.git
synced 2025-02-28 15:30:32 +01:00
Add options to color_code the notes quantization + customise the palette + save and load it from config
This commit is contained in:
parent
029b2b0222
commit
f0f15b4e64
@ -9,6 +9,7 @@
|
||||
- Linear View
|
||||
- new settings
|
||||
- lane order
|
||||
- color notes according to quantization
|
||||
- cursor height
|
||||
- Frendlier error message when the UI font is not found in the assets folder
|
||||
- Playback position is kept instead of being reset to zero when you change charts or reload the audio file
|
||||
|
6
src/color.cpp
Normal file
6
src/color.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "color.hpp"
|
||||
|
||||
|
||||
toml::array dump_color(const sf::Color& color) {
|
||||
return toml::array{color.r, color.g, color.b, color.a};
|
||||
}
|
57
src/color.hpp
Normal file
57
src/color.hpp
Normal file
@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <SFML/Graphics/Color.hpp>
|
||||
#include <toml++/toml.h>
|
||||
|
||||
toml::array dump_color(const sf::Color& color);
|
||||
|
||||
template<class toml_node>
|
||||
std::optional<sf::Uint8> parse_uint8(const toml_node& node) {
|
||||
const auto raw_value_opt = node.template value<int>();
|
||||
if (not raw_value_opt) {
|
||||
return {};
|
||||
}
|
||||
const auto raw_value = *raw_value_opt;
|
||||
if (raw_value < 0 or raw_value > 255) {
|
||||
return {};
|
||||
}
|
||||
return static_cast<sf::Uint8>(raw_value);
|
||||
}
|
||||
|
||||
template<class toml_node>
|
||||
std::optional<sf::Color> parse_color(const toml_node& node) {
|
||||
if (not node.is_array()) {
|
||||
return {};
|
||||
}
|
||||
const auto array = node.template ref<toml::array>();
|
||||
if (array.size() != 4) {
|
||||
return {};
|
||||
}
|
||||
const auto r = parse_uint8(array[0]);
|
||||
if (not r) {
|
||||
return {};
|
||||
}
|
||||
const auto g = parse_uint8(array[1]);
|
||||
if (not g) {
|
||||
return {};
|
||||
}
|
||||
const auto b = parse_uint8(array[2]);
|
||||
if (not b) {
|
||||
return {};
|
||||
}
|
||||
const auto a = parse_uint8(array[3]);
|
||||
if (not a) {
|
||||
return {};
|
||||
}
|
||||
return sf::Color(*r, *g, *b, *a);
|
||||
}
|
||||
|
||||
template<class toml_node>
|
||||
void load_color(const toml_node& node, sf::Color& color) {
|
||||
const auto parsed = parse_color(node);
|
||||
if (parsed) {
|
||||
color = *parsed;
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
#include "colors.hpp"
|
||||
#include <SFML/Config.hpp>
|
||||
#include <algorithm>
|
||||
#include "hsluv/hsluv.h"
|
||||
|
||||
HSLuvColor color_to_hsluv(const sf::Color& rgb) {
|
||||
HSLuvColor hsl;
|
||||
rgb2hsluv(
|
||||
static_cast<double>(rgb.r) / 255.0,
|
||||
static_cast<double>(rgb.g) / 255.0,
|
||||
static_cast<double>(rgb.b) / 255.0,
|
||||
&hsl.h, &hsl.s, &hsl.l
|
||||
);
|
||||
return hsl;
|
||||
}
|
||||
|
||||
sf::Color hslub_to_color(const HSLuvColor& hsl) {
|
||||
double r, g, b;
|
||||
hsluv2rgb(hsl.h, hsl.s, hsl.l, &r, &g, &b);
|
||||
r = std::clamp(r, 0.0, 1.0);
|
||||
g = std::clamp(g, 0.0, 1.0);
|
||||
b = std::clamp(b, 0.0, 1.0);
|
||||
return {
|
||||
static_cast<sf::Uint8>(r*255),
|
||||
static_cast<sf::Uint8>(g*255),
|
||||
static_cast<sf::Uint8>(b*255)
|
||||
};
|
||||
}
|
209
src/config.cpp
209
src/config.cpp
@ -1,68 +1,18 @@
|
||||
#include "config.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include <SFML/Config.hpp>
|
||||
#include <SFML/System/Time.hpp>
|
||||
#include <filesystem>
|
||||
#include <fmt/format.h>
|
||||
#include <toml++/toml.h>
|
||||
#include <variant>
|
||||
|
||||
#include "colors.hpp"
|
||||
#include "linear_view_colors.hpp"
|
||||
#include "marker.hpp"
|
||||
#include "toml++/impl/toml_formatter.h"
|
||||
#include "variant_visitor.hpp"
|
||||
#include "widgets/lane_order.hpp"
|
||||
|
||||
toml::array config::dump_color(const sf::Color& color) {
|
||||
return toml::array{color.r, color.g, color.b, color.a};
|
||||
}
|
||||
|
||||
std::optional<sf::Uint8> parse_uint8(const toml::node& node) {
|
||||
const auto raw_value_opt = node.value<int>();
|
||||
if (not raw_value_opt) {
|
||||
return {};
|
||||
}
|
||||
const auto raw_value = *raw_value_opt;
|
||||
if (raw_value < 0 or raw_value > 255) {
|
||||
return {};
|
||||
}
|
||||
return static_cast<sf::Uint8>(raw_value);
|
||||
}
|
||||
|
||||
std::optional<sf::Color> config::parse_color(const node_view& node) {
|
||||
if (not node.is_array()) {
|
||||
return {};
|
||||
}
|
||||
const auto array = node.ref<toml::array>();
|
||||
if (array.size() != 4) {
|
||||
return {};
|
||||
}
|
||||
const auto r = parse_uint8(array[0]);
|
||||
if (not r) {
|
||||
return {};
|
||||
}
|
||||
const auto g = parse_uint8(array[1]);
|
||||
if (not g) {
|
||||
return {};
|
||||
}
|
||||
const auto b = parse_uint8(array[2]);
|
||||
if (not b) {
|
||||
return {};
|
||||
}
|
||||
const auto a = parse_uint8(array[3]);
|
||||
if (not a) {
|
||||
return {};
|
||||
}
|
||||
return sf::Color(*r, *g, *b, *a);
|
||||
}
|
||||
|
||||
void config::load_color(const node_view& node, sf::Color& color) {
|
||||
const auto parsed = config::parse_color(node);
|
||||
if (parsed) {
|
||||
color = *parsed;
|
||||
}
|
||||
}
|
||||
|
||||
void config::Marker::load_from_v1_0_0_table(const toml::table &tbl) {
|
||||
const auto marker_node = tbl["marker"];
|
||||
const auto folder_node = marker_node["folder"];
|
||||
@ -90,157 +40,32 @@ void config::Marker::dump_as_v1_0_0(toml::table &tbl) {
|
||||
tbl.insert_or_assign("marker", marker_table);
|
||||
}
|
||||
|
||||
linear_view::Colors config::load_linear_view_colors_from_v1_0_0_table(const toml::table& linear_view) {
|
||||
auto colors = linear_view::default_colors;
|
||||
const auto colors_node = linear_view["colors"];
|
||||
load_color(colors_node["cursor"], colors.cursor);
|
||||
load_color(colors_node["tab_selection"]["fill"], colors.tab_selection.fill);
|
||||
load_color(colors_node["tab_selection"]["border"], colors.tab_selection.border);
|
||||
load_color(colors_node["normal_tap_note"], colors.normal_tap_note);
|
||||
load_color(colors_node["conflicting_tap_note"], colors.conflicting_tap_note);
|
||||
load_color(colors_node["normal_collision_zone"], colors.normal_collision_zone);
|
||||
load_color(colors_node["conflicting_collision_zone"], colors.conflicting_collision_zone);
|
||||
load_color(colors_node["normal_long_note"], colors.normal_long_note);
|
||||
load_color(colors_node["conflicting_long_note"], colors.conflicting_long_note);
|
||||
load_color(colors_node["selected_note_fill"], colors.selected_note_fill);
|
||||
load_color(colors_node["selected_note_outline"], colors.selected_note_outline);
|
||||
load_color(colors_node["measure_line"], colors.measure_line);
|
||||
load_color(colors_node["measure_number"], colors.measure_number);
|
||||
load_color(colors_node["beat_line"], colors.beat_line);
|
||||
load_color(colors_node["bpm_button"]["text"], colors.bpm_button.text);
|
||||
load_color(colors_node["bpm_button"]["button"], colors.bpm_button.button);
|
||||
load_color(colors_node["bpm_button"]["hover"], colors.bpm_button.hover);
|
||||
load_color(colors_node["bpm_button"]["active"], colors.bpm_button.active);
|
||||
load_color(colors_node["bpm_button"]["border"], colors.bpm_button.border);
|
||||
load_color(colors_node["selection_rect"]["fill"], colors.selection_rect.fill);
|
||||
load_color(colors_node["selection_rect"]["border"], colors.selection_rect.border);
|
||||
return colors;
|
||||
}
|
||||
|
||||
void config::dump_linear_view_colors_as_v1_0_0(const linear_view::Colors& colors, toml::table& linear_view) {
|
||||
toml::table colors_table{
|
||||
{"cursor", dump_color(colors.cursor)},
|
||||
{"tab_selection", toml::table{
|
||||
{"fill", dump_color(colors.tab_selection.fill)},
|
||||
{"border", dump_color(colors.tab_selection.border)},
|
||||
}},
|
||||
{"normal_tap_note", dump_color(colors.normal_tap_note)},
|
||||
{"conflicting_tap_note", dump_color(colors.conflicting_tap_note)},
|
||||
{"normal_collision_zone", dump_color(colors.normal_collision_zone)},
|
||||
{"conflicting_collision_zone", dump_color(colors.conflicting_collision_zone)},
|
||||
{"normal_long_note", dump_color(colors.normal_long_note)},
|
||||
{"conflicting_long_note", dump_color(colors.conflicting_long_note)},
|
||||
{"selected_note_fill", dump_color(colors.selected_note_fill)},
|
||||
{"selected_note_outline", dump_color(colors.selected_note_outline)},
|
||||
{"measure_line", dump_color(colors.measure_line)},
|
||||
{"measure_number", dump_color(colors.measure_number)},
|
||||
{"beat_line", dump_color(colors.beat_line)},
|
||||
{"bpm_button", toml::table{
|
||||
{"text", dump_color(colors.bpm_button.text)},
|
||||
{"button", dump_color(colors.bpm_button.button)},
|
||||
{"hover", dump_color(colors.bpm_button.hover)},
|
||||
{"active", dump_color(colors.bpm_button.active)},
|
||||
{"border", dump_color(colors.bpm_button.border)},
|
||||
}},
|
||||
{"selection_rect", toml::table{
|
||||
{"fill", dump_color(colors.selection_rect.fill)},
|
||||
{"border", dump_color(colors.selection_rect.border)},
|
||||
}}
|
||||
};
|
||||
linear_view.insert_or_assign("colors", colors_table);
|
||||
}
|
||||
|
||||
linear_view::Sizes config::load_linear_view_sizes_from_v1_0_0_table(const toml::table& linear_view) {
|
||||
auto sizes = linear_view::default_sizes;
|
||||
const auto sizes_node = linear_view["sizes"];
|
||||
sizes.timeline_margin = sizes_node["timeline_margin"].value<int>().value_or(sizes.timeline_margin);
|
||||
sizes.cursor_height = sizes_node["cursor_height"].value<int>().value_or(sizes.cursor_height);
|
||||
return sizes;
|
||||
}
|
||||
|
||||
void config::dump_linear_view_sizes_as_v1_0_0(const linear_view::Sizes& sizes, toml::table& linear_view) {
|
||||
toml::table sizes_table{
|
||||
{"timeline_margin", sizes.timeline_margin},
|
||||
{"cursor_height", sizes.cursor_height},
|
||||
};
|
||||
linear_view.insert_or_assign("sizes", sizes_table);
|
||||
}
|
||||
|
||||
linear_view::LaneOrder config::load_linear_view_lane_order_from_v1_0_0_table(const toml::table& linear_view) {
|
||||
auto lane_order = linear_view::default_lane_order;
|
||||
const auto lane_order_node = linear_view["lane_order"];
|
||||
const auto type = lane_order_node["type"].value<std::string>();
|
||||
if (not type) {
|
||||
return lane_order;
|
||||
}
|
||||
|
||||
if (*type == "default") {
|
||||
return linear_view::lane_order::Default{};
|
||||
} else if (*type == "vertical") {
|
||||
return linear_view::lane_order::Vertical{};
|
||||
} else if (*type == "custom") {
|
||||
const auto order_as_string = lane_order_node["order"].value<std::string>();
|
||||
if (order_as_string) {
|
||||
return linear_view::lane_order::Custom{*order_as_string};
|
||||
}
|
||||
}
|
||||
|
||||
return lane_order;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void config::dump_linear_view_lane_order_as_v1_0_0(const linear_view::LaneOrder& lane_order, toml::table& linear_view) {
|
||||
const auto _dump = VariantVisitor {
|
||||
[&](const linear_view::lane_order::Default&) {
|
||||
linear_view.insert_or_assign(
|
||||
"lane_order",
|
||||
toml::table{{"type", "default"}}
|
||||
);
|
||||
},
|
||||
[&](const linear_view::lane_order::Vertical&) {
|
||||
linear_view.insert_or_assign(
|
||||
"lane_order",
|
||||
toml::table{{"type", "vertical"}}
|
||||
);
|
||||
},
|
||||
[&](const linear_view::lane_order::Custom& custom) {
|
||||
linear_view.insert_or_assign(
|
||||
"lane_order",
|
||||
toml::table{
|
||||
{"type", "custom"},
|
||||
{"order", custom.as_string}
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
std::visit(_dump, lane_order);
|
||||
}
|
||||
|
||||
void config::LinearView::load_from_v1_0_0_table(const toml::table& tbl) {
|
||||
if (not tbl["linear_view"].is_table()) {
|
||||
return;
|
||||
}
|
||||
const auto linear_view_table = tbl["linear_view"].ref<toml::table>();
|
||||
colors = load_linear_view_colors_from_v1_0_0_table(linear_view_table);
|
||||
sizes = load_linear_view_sizes_from_v1_0_0_table(linear_view_table);
|
||||
lane_order = load_linear_view_lane_order_from_v1_0_0_table(linear_view_table);
|
||||
colors.load_from_v1_0_0_table(linear_view_table);
|
||||
sizes.load_from_v1_0_0_table(linear_view_table);
|
||||
lane_order = linear_view::lane_order::load_from_v1_0_0_table(linear_view_table);
|
||||
if (linear_view_table["zoom"].is_integer()) {
|
||||
zoom = *linear_view_table["zoom"].value<int>();
|
||||
}
|
||||
if (linear_view_table["color_notes"].is_boolean()) {
|
||||
color_notes = *linear_view_table["color_notes"].value<bool>();
|
||||
if (linear_view_table["use_quantization_colors"].is_boolean()) {
|
||||
use_quantization_colors = *linear_view_table["use_quantization_colors"].value<bool>();
|
||||
}
|
||||
quantization_colors.load_from_v1_0_0_table(linear_view_table);
|
||||
}
|
||||
|
||||
void config::LinearView::dump_as_v1_0_0(toml::table& tbl) {
|
||||
toml::table linear_view;
|
||||
dump_linear_view_colors_as_v1_0_0(colors, linear_view);
|
||||
dump_linear_view_sizes_as_v1_0_0(sizes, linear_view);
|
||||
dump_linear_view_lane_order_as_v1_0_0(lane_order, linear_view);
|
||||
linear_view.insert_or_assign("zoom", zoom);
|
||||
linear_view.insert_or_assign("color_notes", color_notes);
|
||||
tbl.insert_or_assign("linear_view", linear_view);
|
||||
toml::table linear_view_table;
|
||||
colors.dump_as_v1_0_0(linear_view_table);
|
||||
sizes.dump_as_v1_0_0(linear_view_table);
|
||||
linear_view::lane_order::dump_as_v1_0_0(lane_order, linear_view_table);
|
||||
linear_view_table.insert_or_assign("zoom", zoom);
|
||||
linear_view_table.insert_or_assign("use_quantization_colors", use_quantization_colors);
|
||||
quantization_colors.dump_as_v1_0_0(linear_view_table);
|
||||
tbl.insert_or_assign("linear_view", linear_view_table);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,19 +5,14 @@
|
||||
|
||||
#include <toml++/toml.h>
|
||||
|
||||
#include "colors.hpp"
|
||||
#include "sizes.hpp"
|
||||
#include "quantization_colors.hpp"
|
||||
#include "linear_view_colors.hpp"
|
||||
#include "linear_view_sizes.hpp"
|
||||
#include "marker.hpp"
|
||||
#include "widgets/lane_order.hpp"
|
||||
|
||||
|
||||
namespace config {
|
||||
using node_view = toml::node_view<const toml::node>;
|
||||
|
||||
toml::array dump_color(const sf::Color& color);
|
||||
std::optional<sf::Color> parse_color(const node_view& node);
|
||||
void load_color(const node_view& node, sf::Color& color);
|
||||
|
||||
struct Marker {
|
||||
std::optional<std::filesystem::path> folder;
|
||||
std::optional<Judgement> ending_state;
|
||||
@ -26,21 +21,13 @@ namespace config {
|
||||
void dump_as_v1_0_0(toml::table& tbl);
|
||||
};
|
||||
|
||||
linear_view::Colors load_linear_view_colors_from_v1_0_0_table(const toml::table& linear_view);
|
||||
void dump_linear_view_colors_as_v1_0_0(const linear_view::Colors& colors, toml::table& linear_view);
|
||||
|
||||
linear_view::Sizes load_linear_view_sizes_from_v1_0_0_table(const toml::table& linear_view);
|
||||
void dump_linear_view_sizes_as_v1_0_0(const linear_view::Sizes& sizes, toml::table& linear_view);
|
||||
|
||||
linear_view::LaneOrder load_linear_view_lane_order_from_v1_0_0_table(const toml::table& linear_view);
|
||||
void dump_linear_view_lane_order_as_v1_0_0(const linear_view::LaneOrder& lane_order, toml::table& linear_view);
|
||||
|
||||
struct LinearView {
|
||||
linear_view::Colors colors;
|
||||
linear_view::Sizes sizes;
|
||||
linear_view::LaneOrder lane_order;
|
||||
int zoom = 0;
|
||||
bool color_notes = false;
|
||||
bool use_quantization_colors = false;
|
||||
linear_view::QuantizationColors quantization_colors;
|
||||
|
||||
void load_from_v1_0_0_table(const toml::table& tbl);
|
||||
void dump_as_v1_0_0(toml::table& tbl);
|
||||
|
63
src/linear_view_colors.cpp
Normal file
63
src/linear_view_colors.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
#include "linear_view_colors.hpp"
|
||||
|
||||
#include "color.hpp"
|
||||
|
||||
namespace linear_view {
|
||||
void Colors::load_from_v1_0_0_table(const toml::table& linear_view_table) {
|
||||
const auto colors_node = linear_view_table["colors"];
|
||||
load_color(colors_node["cursor"], cursor);
|
||||
load_color(colors_node["tab_selection"]["fill"], tab_selection.fill);
|
||||
load_color(colors_node["tab_selection"]["border"], tab_selection.border);
|
||||
load_color(colors_node["normal_tap_note"], normal_tap_note);
|
||||
load_color(colors_node["conflicting_tap_note"], conflicting_tap_note);
|
||||
load_color(colors_node["normal_collision_zone"], normal_collision_zone);
|
||||
load_color(colors_node["conflicting_collision_zone"], conflicting_collision_zone);
|
||||
load_color(colors_node["normal_long_note"], normal_long_note);
|
||||
load_color(colors_node["conflicting_long_note"], conflicting_long_note);
|
||||
load_color(colors_node["selected_note_fill"], selected_note_fill);
|
||||
load_color(colors_node["selected_note_outline"], selected_note_outline);
|
||||
load_color(colors_node["measure_line"], measure_line);
|
||||
load_color(colors_node["measure_number"], measure_number);
|
||||
load_color(colors_node["beat_line"], beat_line);
|
||||
load_color(colors_node["bpm_button"]["text"], bpm_button.text);
|
||||
load_color(colors_node["bpm_button"]["button"], bpm_button.button);
|
||||
load_color(colors_node["bpm_button"]["hover"], bpm_button.hover);
|
||||
load_color(colors_node["bpm_button"]["active"], bpm_button.active);
|
||||
load_color(colors_node["bpm_button"]["border"], bpm_button.border);
|
||||
load_color(colors_node["selection_rect"]["fill"], selection_rect.fill);
|
||||
load_color(colors_node["selection_rect"]["border"], selection_rect.border);
|
||||
}
|
||||
|
||||
void Colors::dump_as_v1_0_0(toml::table& linear_view_table) {
|
||||
toml::table colors_table{
|
||||
{"cursor", dump_color(cursor)},
|
||||
{"tab_selection", toml::table{
|
||||
{"fill", dump_color(tab_selection.fill)},
|
||||
{"border", dump_color(tab_selection.border)},
|
||||
}},
|
||||
{"normal_tap_note", dump_color(normal_tap_note)},
|
||||
{"conflicting_tap_note", dump_color(conflicting_tap_note)},
|
||||
{"normal_collision_zone", dump_color(normal_collision_zone)},
|
||||
{"conflicting_collision_zone", dump_color(conflicting_collision_zone)},
|
||||
{"normal_long_note", dump_color(normal_long_note)},
|
||||
{"conflicting_long_note", dump_color(conflicting_long_note)},
|
||||
{"selected_note_fill", dump_color(selected_note_fill)},
|
||||
{"selected_note_outline", dump_color(selected_note_outline)},
|
||||
{"measure_line", dump_color(measure_line)},
|
||||
{"measure_number", dump_color(measure_number)},
|
||||
{"beat_line", dump_color(beat_line)},
|
||||
{"bpm_button", toml::table{
|
||||
{"text", dump_color(bpm_button.text)},
|
||||
{"button", dump_color(bpm_button.button)},
|
||||
{"hover", dump_color(bpm_button.hover)},
|
||||
{"active", dump_color(bpm_button.active)},
|
||||
{"border", dump_color(bpm_button.border)},
|
||||
}},
|
||||
{"selection_rect", toml::table{
|
||||
{"fill", dump_color(selection_rect.fill)},
|
||||
{"border", dump_color(selection_rect.border)},
|
||||
}}
|
||||
};
|
||||
linear_view_table.insert_or_assign("colors", colors_table);
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <hsluv/hsluv.h>
|
||||
#include <toml++/toml.h>
|
||||
#include <SFML/Graphics/Color.hpp>
|
||||
|
||||
struct ButtonColors {
|
||||
@ -45,17 +45,11 @@ namespace linear_view {
|
||||
.fill = {144, 189, 255, 64},
|
||||
.border = {144, 189, 255}
|
||||
};
|
||||
|
||||
void load_from_v1_0_0_table(const toml::table& linear_view_table);
|
||||
void dump_as_v1_0_0(toml::table& linear_view_table);
|
||||
};
|
||||
|
||||
const linear_view::Colors default_colors = {};
|
||||
};
|
||||
|
||||
struct HSLuvColor {
|
||||
double h;
|
||||
double s;
|
||||
double l;
|
||||
};
|
||||
|
||||
HSLuvColor color_to_hsluv(const sf::Color& rgb);
|
||||
sf::Color hslub_to_color(const HSLuvColor& hsl);
|
||||
|
17
src/linear_view_sizes.cpp
Normal file
17
src/linear_view_sizes.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include "linear_view_sizes.hpp"
|
||||
|
||||
namespace linear_view {
|
||||
void Sizes::load_from_v1_0_0_table(const toml::table& linear_view_table) {
|
||||
const auto sizes_node = linear_view_table["sizes"];
|
||||
timeline_margin = sizes_node["timeline_margin"].value<int>().value_or(timeline_margin);
|
||||
cursor_height = sizes_node["cursor_height"].value<int>().value_or(cursor_height);
|
||||
}
|
||||
|
||||
void Sizes::dump_as_v1_0_0(toml::table& linear_view_table) {
|
||||
toml::table sizes_table{
|
||||
{"timeline_margin", timeline_margin},
|
||||
{"cursor_height", cursor_height},
|
||||
};
|
||||
linear_view_table.insert_or_assign("sizes", sizes_table);
|
||||
}
|
||||
}
|
@ -1,9 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <toml++/toml.h>
|
||||
|
||||
namespace linear_view {
|
||||
struct Sizes {
|
||||
int timeline_margin = 130;
|
||||
int cursor_height = 100;
|
||||
|
||||
void load_from_v1_0_0_table(const toml::table& linear_view_table);
|
||||
void dump_as_v1_0_0(toml::table& linear_view_table);
|
||||
};
|
||||
|
||||
const Sizes default_sizes = {};
|
@ -9,13 +9,16 @@ sources += files(
|
||||
'better_timing.cpp',
|
||||
'chart_state.cpp',
|
||||
'clipboard.cpp',
|
||||
'colors.cpp',
|
||||
'quantization_colors.cpp',
|
||||
'color.cpp',
|
||||
'config.cpp',
|
||||
'editor_state.cpp',
|
||||
'file_dialogs.cpp',
|
||||
'history_item.cpp',
|
||||
'imgui_extras.cpp',
|
||||
'json_decimal_handling.cpp',
|
||||
'linear_view_colors.cpp',
|
||||
'linear_view_sizes.cpp',
|
||||
'ln_marker.cpp',
|
||||
'long_note_dummy.cpp',
|
||||
'main.cpp',
|
||||
|
56
src/quantization_colors.cpp
Normal file
56
src/quantization_colors.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include "quantization_colors.hpp"
|
||||
#include "color.hpp"
|
||||
#include "toml++/impl/forward_declarations.h"
|
||||
#include "variant_visitor.hpp"
|
||||
|
||||
namespace linear_view {
|
||||
sf::Color QuantizationColors::color_at_beat(const Fraction& time) {
|
||||
const auto denominator = time.denominator();
|
||||
if (denominator > palette.rbegin()->first) {
|
||||
return default_;
|
||||
}
|
||||
const auto& it = palette.find(static_cast<unsigned int>(denominator.get_ui()));
|
||||
if (it == palette.end()) {
|
||||
return default_;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void QuantizationColors::load_from_v1_0_0_table(const toml::table& linear_view_table) {
|
||||
const auto quant_colors_node = linear_view_table["quantization_colors"];
|
||||
const auto palette_node = quant_colors_node["palette"];
|
||||
if (const toml::array* arr = palette_node.as_array()) {
|
||||
std::map<unsigned int, sf::Color> new_palette;
|
||||
const auto parse_pairs = VariantVisitor {
|
||||
[&](const toml::array& pair){
|
||||
if (pair.size() != 2) {
|
||||
return;
|
||||
}
|
||||
const auto quant = pair[0].value<unsigned int>();
|
||||
const auto color = parse_color(pair[1]);
|
||||
if (quant and color) {
|
||||
new_palette.emplace(*quant, *color);
|
||||
}
|
||||
},
|
||||
[&](const auto&){}
|
||||
};
|
||||
arr->for_each(parse_pairs);
|
||||
if (not new_palette.empty()) {
|
||||
palette = std::move(new_palette);
|
||||
}
|
||||
}
|
||||
load_color(quant_colors_node["default"], default_);
|
||||
}
|
||||
|
||||
void QuantizationColors::dump_as_v1_0_0(toml::table& linear_view_table) {
|
||||
toml::array palette_node;
|
||||
for (const auto& [quant, color] : palette) {
|
||||
palette_node.emplace_back<toml::array>(quant, dump_color(color));
|
||||
}
|
||||
toml::table quantization_colors_table{
|
||||
{"palette", palette_node},
|
||||
{"default", dump_color(default_)}
|
||||
};
|
||||
linear_view_table.insert_or_assign("quantization_colors", quantization_colors_table);
|
||||
}
|
||||
}
|
30
src/quantization_colors.hpp
Normal file
30
src/quantization_colors.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <toml++/toml.h>
|
||||
#include <SFML/Graphics/Color.hpp>
|
||||
|
||||
#include "special_numeric_types.hpp"
|
||||
|
||||
namespace linear_view {
|
||||
struct QuantizationColors {
|
||||
std::map<unsigned int, sf::Color> palette = {{
|
||||
{1, {255, 40, 40}},
|
||||
{2, {34, 140, 255}},
|
||||
{3, {156, 0, 254}},
|
||||
{4, {248, 236, 18}},
|
||||
{6, {255, 131, 189}},
|
||||
{8, {254, 135, 0}},
|
||||
{12, {0, 254, 207}},
|
||||
{16, {68, 254, 0}}
|
||||
}};
|
||||
sf::Color default_ = {156, 156, 156};
|
||||
sf::Color color_at_beat(const Fraction& time);
|
||||
|
||||
void load_from_v1_0_0_table(const toml::table& linear_view_table);
|
||||
void dump_as_v1_0_0(toml::table& linear_view_table);
|
||||
};
|
||||
|
||||
const QuantizationColors default_quantization_colors = {};
|
||||
}
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "../variant_visitor.hpp"
|
||||
|
||||
|
||||
linear_view::lane_order::Custom::Custom() :
|
||||
lane_to_button({0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15})
|
||||
@ -58,4 +60,55 @@ void linear_view::lane_order::Custom::update_from_string() {
|
||||
button_to_lane[button] = lane;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace linear_view::lane_order {
|
||||
LaneOrder load_from_v1_0_0_table(const toml::table& linear_view) {
|
||||
auto lane_order = linear_view::default_lane_order;
|
||||
const auto lane_order_node = linear_view["lane_order"];
|
||||
const auto type = lane_order_node["type"].value<std::string>();
|
||||
if (not type) {
|
||||
return lane_order;
|
||||
}
|
||||
|
||||
if (*type == "default") {
|
||||
return Default{};
|
||||
} else if (*type == "vertical") {
|
||||
return Vertical{};
|
||||
} else if (*type == "custom") {
|
||||
const auto order_as_string = lane_order_node["order"].value<std::string>();
|
||||
if (order_as_string) {
|
||||
return Custom{*order_as_string};
|
||||
}
|
||||
}
|
||||
|
||||
return lane_order;
|
||||
}
|
||||
|
||||
void dump_as_v1_0_0(const LaneOrder& lane_order, toml::table& linear_view) {
|
||||
const auto _dump = VariantVisitor {
|
||||
[&](const Default&) {
|
||||
linear_view.insert_or_assign(
|
||||
"lane_order",
|
||||
toml::table{{"type", "default"}}
|
||||
);
|
||||
},
|
||||
[&](const Vertical&) {
|
||||
linear_view.insert_or_assign(
|
||||
"lane_order",
|
||||
toml::table{{"type", "vertical"}}
|
||||
);
|
||||
},
|
||||
[&](const Custom& custom) {
|
||||
linear_view.insert_or_assign(
|
||||
"lane_order",
|
||||
toml::table{
|
||||
{"type", "custom"},
|
||||
{"order", custom.as_string}
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
std::visit(_dump, lane_order);
|
||||
}
|
||||
}
|
@ -6,6 +6,8 @@
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
#include <toml++/toml.h>
|
||||
|
||||
namespace linear_view {
|
||||
namespace lane_order {
|
||||
struct Default {};
|
||||
@ -34,9 +36,14 @@ namespace linear_view {
|
||||
{'9', 8}, {'a', 9}, {'b', 10}, {'c', 11},
|
||||
{'d', 12}, {'e', 13}, {'f', 14}, {'g', 15},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
using LaneOrder = std::variant<lane_order::Default, lane_order::Vertical, lane_order::Custom>;
|
||||
|
||||
namespace lane_order {
|
||||
linear_view::LaneOrder load_from_v1_0_0_table(const toml::table& linear_view);
|
||||
void dump_as_v1_0_0(const linear_view::LaneOrder& lane_order, toml::table& linear_view);
|
||||
}
|
||||
|
||||
const LaneOrder default_lane_order = lane_order::Default{};
|
||||
}
|
@ -25,13 +25,11 @@
|
||||
#include "../better_timing.hpp"
|
||||
#include "../better_note.hpp"
|
||||
#include "../chart_state.hpp"
|
||||
#include "../colors.hpp"
|
||||
#include "../imgui_extras.hpp"
|
||||
#include "../long_note_dummy.hpp"
|
||||
#include "../special_numeric_types.hpp"
|
||||
#include "../toolbox.hpp"
|
||||
#include "../variant_visitor.hpp"
|
||||
#include "sizes.hpp"
|
||||
#include "widgets/lane_order.hpp"
|
||||
|
||||
|
||||
@ -48,7 +46,8 @@ LinearView::LinearView(std::filesystem::path assets, config::Config& config_) :
|
||||
collision_zone(config_.editor.collision_zone),
|
||||
beats_to_pixels_proportional(0, 1, 0, 100),
|
||||
zoom(config_.linear_view.zoom),
|
||||
color_notes(config_.linear_view.color_notes),
|
||||
use_quantization_colors(config_.linear_view.use_quantization_colors),
|
||||
quantization_colors(config_.linear_view.quantization_colors),
|
||||
lane_order(config_.linear_view.lane_order)
|
||||
{
|
||||
set_zoom(config_.linear_view.zoom);
|
||||
@ -182,8 +181,8 @@ void LinearView::draw(
|
||||
const auto tap_note_color = [&](){
|
||||
if (chart_state.chart.notes->is_colliding(tap_note, timing, collision_zone)) {
|
||||
return colors.conflicting_tap_note;
|
||||
} else if (color_notes) {
|
||||
return color_of_note(tap_note.get_time());
|
||||
} else if (use_quantization_colors) {
|
||||
return quantization_colors.color_at_beat(tap_note.get_time());
|
||||
} else {
|
||||
return colors.normal_tap_note;
|
||||
}
|
||||
@ -238,8 +237,8 @@ void LinearView::draw(
|
||||
};
|
||||
auto collision_zone_color = colors.normal_collision_zone;
|
||||
auto tap_note_color = [&](){
|
||||
if (color_notes) {
|
||||
return color_of_note(long_note.get_time());
|
||||
if (use_quantization_colors) {
|
||||
return quantization_colors.color_at_beat(long_note.get_time());
|
||||
} else {
|
||||
return colors.normal_tap_note;
|
||||
}
|
||||
@ -418,9 +417,9 @@ void LinearView::display_settings() {
|
||||
set_zoom(zoom);
|
||||
}
|
||||
if (ImGui::CollapsingHeader("Notes##Linear View Settings")) {
|
||||
ImGui::Checkbox("Colored Quantization", &color_notes);
|
||||
if (color_notes) {
|
||||
for (auto& [quant, color] : note_colors) {
|
||||
ImGui::Checkbox("Colored Quantization", &use_quantization_colors);
|
||||
if (use_quantization_colors) {
|
||||
for (auto& [quant, color] : quantization_colors.palette) {
|
||||
feis::ColorEdit4(
|
||||
fmt::format(
|
||||
"{}##Colored Quantization",
|
||||
@ -429,7 +428,10 @@ void LinearView::display_settings() {
|
||||
color
|
||||
);
|
||||
}
|
||||
feis::ColorEdit4("Other", note_grey);
|
||||
feis::ColorEdit4("Other", quantization_colors.default_);
|
||||
if (ImGui::Button("Reset##Colored Quantization")) {
|
||||
quantization_colors = linear_view::default_quantization_colors;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ImGui::CollapsingHeader("Lanes##Linear View Settings")) {
|
||||
@ -524,18 +526,6 @@ void LinearView::reload_transforms() {
|
||||
};
|
||||
}
|
||||
|
||||
sf::Color LinearView::color_of_note(const Fraction& time) {
|
||||
const auto denominator = time.denominator();
|
||||
if (denominator > note_colors.rbegin()->first) {
|
||||
return note_grey;
|
||||
}
|
||||
const auto& it = note_colors.find(static_cast<unsigned int>(denominator.get_ui()));
|
||||
if (it == note_colors.end()) {
|
||||
return note_grey;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
std::string LinearView::lane_order_name() {
|
||||
const auto name = VariantVisitor {
|
||||
[](linear_view::lane_order::Default) { return "Default"; },
|
||||
|
@ -12,9 +12,10 @@
|
||||
#include "../better_timing.hpp"
|
||||
#include "../chart_state.hpp"
|
||||
#include "../toolbox.hpp"
|
||||
#include "../colors.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "../sizes.hpp"
|
||||
#include "../linear_view_sizes.hpp"
|
||||
#include "../linear_view_colors.hpp"
|
||||
#include "quantization_colors.hpp"
|
||||
#include "lane_order.hpp"
|
||||
|
||||
struct SelectionRectangle {
|
||||
@ -71,10 +72,8 @@ private:
|
||||
|
||||
int& zoom;
|
||||
|
||||
bool& color_notes;
|
||||
std::map<unsigned int, sf::Color> note_colors = reference_note_colors;
|
||||
sf::Color note_grey = reference_note_grey;
|
||||
sf::Color color_of_note(const Fraction& time);
|
||||
bool& use_quantization_colors;
|
||||
linear_view::QuantizationColors& quantization_colors;
|
||||
|
||||
SelectionRectangle selection_rectangle;
|
||||
bool started_selection_inside_window = false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user