diff --git a/CHANGELOG.md b/CHANGELOG.md index afea244..875f977 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/color.cpp b/src/color.cpp new file mode 100644 index 0000000..29a9f17 --- /dev/null +++ b/src/color.cpp @@ -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}; +} \ No newline at end of file diff --git a/src/color.hpp b/src/color.hpp new file mode 100644 index 0000000..254a09b --- /dev/null +++ b/src/color.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include + +#include +#include + +toml::array dump_color(const sf::Color& color); + +template +std::optional parse_uint8(const toml_node& node) { + const auto raw_value_opt = node.template value(); + 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(raw_value); +} + +template +std::optional parse_color(const toml_node& node) { + if (not node.is_array()) { + return {}; + } + const auto array = node.template ref(); + 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 +void load_color(const toml_node& node, sf::Color& color) { + const auto parsed = parse_color(node); + if (parsed) { + color = *parsed; + } +} \ No newline at end of file diff --git a/src/colors.cpp b/src/colors.cpp deleted file mode 100644 index 26327a0..0000000 --- a/src/colors.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#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/config.cpp b/src/config.cpp index c122161..3201a09 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -1,68 +1,18 @@ #include "config.hpp" +#include + #include #include -#include #include #include #include -#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 parse_uint8(const toml::node& node) { - const auto raw_value_opt = node.value(); - 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(raw_value); -} - -std::optional config::parse_color(const node_view& node) { - if (not node.is_array()) { - return {}; - } - const auto array = node.ref(); - 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().value_or(sizes.timeline_margin); - sizes.cursor_height = sizes_node["cursor_height"].value().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(); - 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(); - 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(); - 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(); } - if (linear_view_table["color_notes"].is_boolean()) { - color_notes = *linear_view_table["color_notes"].value(); + if (linear_view_table["use_quantization_colors"].is_boolean()) { + use_quantization_colors = *linear_view_table["use_quantization_colors"].value(); } + 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); } diff --git a/src/config.hpp b/src/config.hpp index 22bc95f..ec7ed5b 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -5,19 +5,14 @@ #include -#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; - - toml::array dump_color(const sf::Color& color); - std::optional parse_color(const node_view& node); - void load_color(const node_view& node, sf::Color& color); - struct Marker { std::optional folder; std::optional 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); diff --git a/src/linear_view_colors.cpp b/src/linear_view_colors.cpp new file mode 100644 index 0000000..c7904ae --- /dev/null +++ b/src/linear_view_colors.cpp @@ -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); + } +} diff --git a/src/colors.hpp b/src/linear_view_colors.hpp similarity index 89% rename from src/colors.hpp rename to src/linear_view_colors.hpp index 10722c3..fa66f32 100644 --- a/src/colors.hpp +++ b/src/linear_view_colors.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include 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); - diff --git a/src/linear_view_sizes.cpp b/src/linear_view_sizes.cpp new file mode 100644 index 0000000..1aaf319 --- /dev/null +++ b/src/linear_view_sizes.cpp @@ -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().value_or(timeline_margin); + cursor_height = sizes_node["cursor_height"].value().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); + } +} \ No newline at end of file diff --git a/src/sizes.hpp b/src/linear_view_sizes.hpp similarity index 51% rename from src/sizes.hpp rename to src/linear_view_sizes.hpp index 631c957..6c79389 100644 --- a/src/sizes.hpp +++ b/src/linear_view_sizes.hpp @@ -1,9 +1,14 @@ #pragma once +#include + 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 = {}; diff --git a/src/meson.build b/src/meson.build index 37caada..ca8149d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -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', diff --git a/src/quantization_colors.cpp b/src/quantization_colors.cpp new file mode 100644 index 0000000..1696100 --- /dev/null +++ b/src/quantization_colors.cpp @@ -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(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 new_palette; + const auto parse_pairs = VariantVisitor { + [&](const toml::array& pair){ + if (pair.size() != 2) { + return; + } + const auto quant = pair[0].value(); + 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(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); + } +} diff --git a/src/quantization_colors.hpp b/src/quantization_colors.hpp new file mode 100644 index 0000000..10d5a31 --- /dev/null +++ b/src/quantization_colors.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include + +#include +#include + +#include "special_numeric_types.hpp" + +namespace linear_view { + struct QuantizationColors { + std::map 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 = {}; +} \ No newline at end of file diff --git a/src/widgets/lane_order.cpp b/src/widgets/lane_order.cpp index ad6843f..8de7bb5 100644 --- a/src/widgets/lane_order.cpp +++ b/src/widgets/lane_order.cpp @@ -2,6 +2,8 @@ #include +#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(); + 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(); + 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); + } } \ No newline at end of file diff --git a/src/widgets/lane_order.hpp b/src/widgets/lane_order.hpp index 0b28fb6..6d694aa 100644 --- a/src/widgets/lane_order.hpp +++ b/src/widgets/lane_order.hpp @@ -6,6 +6,8 @@ #include #include +#include + 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; + 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{}; } \ No newline at end of file diff --git a/src/widgets/linear_view.cpp b/src/widgets/linear_view.cpp index f17afdc..9c76ad8 100644 --- a/src/widgets/linear_view.cpp +++ b/src/widgets/linear_view.cpp @@ -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(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 aadb493..5ec2b67 100644 --- a/src/widgets/linear_view.hpp +++ b/src/widgets/linear_view.hpp @@ -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 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;