Add options to color_code the notes quantization + customise the palette + save and load it from config

This commit is contained in:
Stepland 2022-11-21 03:31:26 +01:00
parent 029b2b0222
commit f0f15b4e64
17 changed files with 344 additions and 279 deletions

View File

@ -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
View 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
View 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;
}
}

View File

@ -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)
};
}

View File

@ -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);
}

View File

@ -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);

View 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);
}
}

View File

@ -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
View 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);
}
}

View File

@ -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 = {};

View File

@ -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',

View 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);
}
}

View 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 = {};
}

View File

@ -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);
}
}

View File

@ -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{};
}

View File

@ -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"; },

View File

@ -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;