#include "application/editorstate.h" #include "widgets/button.h" #include "widgets/group.h" #include "widgets/menubar.h" #include "widgets/window.h" #include "widgets/editorwidget.h" #include "widgets/bpmcalculatorwidget.h" #include "tools/bpmcalculator.h" #include "core/editor.h" EditorState::EditorState(const std::shared_ptr& core_factory, std::unique_ptr&& editor, Callbacks&& callbacks) : _callbacks(std::move(callbacks)), _core_factory(core_factory), _editor(std::move(editor)) {} EditorState::~EditorState() {} void EditorState::input(const kku::SystemEvent& event) { _group->input(event); } void EditorState::update(const kku::microsec& dt) { _group->update(dt); } void EditorState::display() const { _group->display(); } void EditorState::enter() { _music = _core_factory->getMusic(); _music->open("sources/METEOR.flac"); _music->setVolume(5.f); auto& group = _group; auto& music = _music; auto& editor = _editor; _bpm_calculator = std::make_shared(); auto& bpm_calculator = _bpm_calculator; std::shared_ptr bpm_widget = std::make_shared(_bpm_calculator, _core_factory); auto button_start = std::make_shared("Start", _core_factory); auto button_stop = std::make_shared("Stop", _core_factory); auto button_apply = std::make_shared("Apply", _core_factory); button_start->setCallback([bpm_calculator, button_start, button_stop, &music]() { music->play(); bpm_calculator->start(); button_start->setVisibility(false); button_stop->setVisibility(true); }); button_stop->setCallback([bpm_calculator, button_start, button_stop, &music]() { music->stop(); bpm_calculator->stop(); button_start->setVisibility(true); button_stop->setVisibility(false); }); button_apply->setCallback([&editor, bpm_calculator]() { kku::BPMSection section; const auto& info = bpm_calculator->fetchApproximatedInfo(); section.bpm = info.BPM; section.interval = info.interval; section.fraction = 2; section.offset_start = bpm_calculator->getStartingOffset(); editor->insertBPMSection(std::move(section)); }); BPMCalculatorWidget::Init bpm_widget_init; bpm_widget_init.stop = button_stop; bpm_widget_init.apply = button_apply; bpm_widget_init.start = button_start; bpm_widget_init.current_time = [&music]() -> kku::microsec { return music->fetchOffset(); }; bpm_widget->init(std::move(bpm_widget_init)); const auto bpm_widget_callback = [&group, bpm_widget=bpm_widget, &music]() { music->stop(); bpm_widget->setVisibility(false); group->unblock(); }; const auto render_size = _core_factory->getRenderSize(); const float window_width = render_size.first; auto menu_bar = std::make_shared(_core_factory); auto bpm_button = std::make_shared("Calculate BPM", _core_factory); bpm_button->setCallback([&group, bpm_widget=bpm_widget]() { group->blockBy(bpm_widget); bpm_widget->setVisibility(true); }); bpm_widget->setRect(kku::Area{render_size.first / 3.f, render_size.second / 3.f, render_size.first / 3.f, render_size.second / 3.f}); bpm_widget->addBarButton("X", bpm_widget_callback); bpm_widget->setVisibility(false); auto test_menu_2 = std::make_shared(_core_factory); test_menu_2->setRect(kku::Area{0., 0., 200., 27. * 5.}); auto test_menu_3 = std::make_shared(_core_factory); test_menu_3->setRect(kku::Area{0., 0., 200., 27. * 5.}); auto test_cascade_button = std::make_shared("Show submenu", _core_factory); auto test_cascade_button_2 = std::make_shared("Show submenu 2", _core_factory); auto quit_button = std::make_shared("Quit", _core_factory); quit_button->setCallback(_callbacks.onLeaveEditorState); auto test_menu = std::make_shared(_core_factory); test_menu->setRect(kku::Area{0., 0., 200., 27. * 3.}); menu_bar->setRect(kku::Area{0., 0., window_width, 27.}); menu_bar->addRootSubMenu("test", test_menu); menu_bar->addDependentSubmenu(test_menu_2); menu_bar->addDependentSubmenu(test_menu_3); test_cascade_button->setSubmenu(test_menu_2); test_menu->addPushButton(bpm_button); test_menu->addCascadeButton(test_cascade_button); test_menu->addPushButton(quit_button); test_cascade_button->resetRect(); test_cascade_button_2->setSubmenu(test_menu_3); test_menu_2->addCascadeButton(test_cascade_button_2); test_cascade_button_2->resetRect(); menu_bar->setVisibility(true); EditorWidget::Callbacks callbacks; callbacks.onDisplay = [&editor]() { editor->display(); }; callbacks.onInput = [&editor, &music](const kku::SystemEvent& event) { if (event.type == kku::SystemEvent::Type::KeyRelease && std::get(event.data).view == kku::SystemEvent::Key::Code::Space) music->isPlaying() ? music->pause() : music->play(); else if (event.type == kku::SystemEvent::Type::MouseWheelScroll) { const auto& up = std::get(event.data).scrolled_up; music->moveOffset(up ? 500000 : -500000); editor->recalculate(music->fetchOffset()); } else editor->input(kku::GameEvent{music->fetchOffset(), event}); }; callbacks.onUpdate = [&editor, &music](const kku::microsec& dt) { editor->update(kku::UpdateData{music->fetchOffset(), dt}); }; auto editor_widget = std::make_shared(std::move(callbacks)); _group = std::make_shared(); _group->addChild(editor_widget); _group->addChild(menu_bar); _group->addChild(bpm_widget); } void EditorState::leave() { _group.reset(); _bpm_calculator.reset(); }