From 029b2b0222b8ff664fd3347881b3ae385dc4b547 Mon Sep 17 00:00:00 2001 From: Stepland <10530295-Buggyroom@users.noreply.gitlab.com> Date: Mon, 21 Nov 2022 01:24:15 +0100 Subject: [PATCH] Option to color notes according to quantization ! --- src/colors.cpp | 28 +++++++++++++++++ src/colors.hpp | 10 +++++++ src/config.cpp | 4 +++ src/config.hpp | 1 + src/meson.build | 1 + src/widgets/linear_view.cpp | 60 ++++++++++++++++++++++++++++++++----- src/widgets/linear_view.hpp | 18 +++++++++++ 7 files changed, 115 insertions(+), 7 deletions(-) create mode 100644 src/colors.cpp diff --git a/src/colors.cpp b/src/colors.cpp new file mode 100644 index 0000000..26327a0 --- /dev/null +++ b/src/colors.cpp @@ -0,0 +1,28 @@ +#include "colors.hpp" +#include +#include +#include "hsluv/hsluv.h" + +HSLuvColor color_to_hsluv(const sf::Color& rgb) { + HSLuvColor hsl; + rgb2hsluv( + static_cast(rgb.r) / 255.0, + static_cast(rgb.g) / 255.0, + static_cast(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(r*255), + static_cast(g*255), + static_cast(b*255) + }; +} \ No newline at end of file diff --git a/src/colors.hpp b/src/colors.hpp index 2a8d4d8..10722c3 100644 --- a/src/colors.hpp +++ b/src/colors.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include struct ButtonColors { @@ -49,3 +50,12 @@ namespace linear_view { 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); + diff --git a/src/config.cpp b/src/config.cpp index 9eb5f4f..c122161 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -228,6 +228,9 @@ void config::LinearView::load_from_v1_0_0_table(const toml::table& tbl) { if (linear_view_table["zoom"].is_integer()) { zoom = *linear_view_table["zoom"].value(); } + if (linear_view_table["color_notes"].is_boolean()) { + color_notes = *linear_view_table["color_notes"].value(); + } } void config::LinearView::dump_as_v1_0_0(toml::table& tbl) { @@ -236,6 +239,7 @@ void config::LinearView::dump_as_v1_0_0(toml::table& tbl) { 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); } diff --git a/src/config.hpp b/src/config.hpp index 30dc85a..22bc95f 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -40,6 +40,7 @@ namespace config { linear_view::Sizes sizes; linear_view::LaneOrder lane_order; int zoom = 0; + bool color_notes = false; void load_from_v1_0_0_table(const toml::table& tbl); void dump_as_v1_0_0(toml::table& tbl); diff --git a/src/meson.build b/src/meson.build index a7653cf..37caada 100644 --- a/src/meson.build +++ b/src/meson.build @@ -9,6 +9,7 @@ sources += files( 'better_timing.cpp', 'chart_state.cpp', 'clipboard.cpp', + 'colors.cpp', 'config.cpp', 'editor_state.cpp', 'file_dialogs.cpp', diff --git a/src/widgets/linear_view.cpp b/src/widgets/linear_view.cpp index f7e8165..f17afdc 100644 --- a/src/widgets/linear_view.cpp +++ b/src/widgets/linear_view.cpp @@ -1,5 +1,6 @@ #include "linear_view.hpp" +#include #include #include #include @@ -14,6 +15,7 @@ #include #include +#include #include #include #include @@ -46,6 +48,7 @@ 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), lane_order(config_.linear_view.lane_order) { set_zoom(config_.linear_view.zoom); @@ -169,12 +172,22 @@ void LinearView::draw( collizion_zone_width, static_cast(static_cast(collision_zone_height)) }; - auto collision_zone_color = colors.normal_collision_zone; - auto tap_note_color = colors.normal_tap_note; - if (chart_state.chart.notes->is_colliding(tap_note, timing, collision_zone)) { - collision_zone_color = colors.conflicting_collision_zone; - tap_note_color = colors.conflicting_tap_note; - } + const auto collision_zone_color = [&](){ + if (chart_state.chart.notes->is_colliding(tap_note, timing, collision_zone)) { + return colors.conflicting_collision_zone; + } else { + return colors.normal_collision_zone; + } + }(); + 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 { + return colors.normal_tap_note; + } + }(); draw_rectangle( draw_list, origin + collision_zone_pos, @@ -224,7 +237,13 @@ void LinearView::draw( static_cast(static_cast(collision_zone_height)) }; auto collision_zone_color = colors.normal_collision_zone; - auto tap_note_color = colors.normal_tap_note; + auto tap_note_color = [&](){ + if (color_notes) { + return color_of_note(long_note.get_time()); + } else { + return colors.normal_tap_note; + } + }(); auto long_note_color = colors.normal_long_note; if (chart_state.chart.notes->is_colliding(long_note, timing, collision_zone)) { collision_zone_color = colors.conflicting_collision_zone; @@ -398,6 +417,21 @@ void LinearView::display_settings() { if (ImGui::SliderInt("Zoom##Linear View Settings", &zoom, -10, 10, "%d")) { 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) { + feis::ColorEdit4( + fmt::format( + "{}##Colored Quantization", + Toolbox::toOrdinal(quant*4) + ).c_str(), + color + ); + } + feis::ColorEdit4("Other", note_grey); + } + } if (ImGui::CollapsingHeader("Lanes##Linear View Settings")) { if (ImGui::BeginCombo("Order", lane_order_name().c_str())) { if (ImGui::Selectable( @@ -490,6 +524,18 @@ 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(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"; }, diff --git a/src/widgets/linear_view.hpp b/src/widgets/linear_view.hpp index b277b52..aadb493 100644 --- a/src/widgets/linear_view.hpp +++ b/src/widgets/linear_view.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -23,6 +24,18 @@ struct SelectionRectangle { void reset(); }; +const std::map reference_note_colors = {{ + {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}} +}}; +const sf::Color reference_note_grey = {134, 110, 116}; + class LinearView { public: LinearView(std::filesystem::path assets, config::Config& config); @@ -58,6 +71,11 @@ private: int& zoom; + bool& color_notes; + std::map note_colors = reference_note_colors; + sf::Color note_grey = reference_note_grey; + sf::Color color_of_note(const Fraction& time); + SelectionRectangle selection_rectangle; bool started_selection_inside_window = false; bool any_bpm_button_hovered = false;