/* * Copyright (c) 2018-2020, Andreas Kling * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "NoVisualizationWidget.h" #include "Player.h" #include "SampleWidget.h" #include "SoundPlayerWidgetAdvancedView.h" #include #include #include #include #include #include #include #include #include int main(int argc, char** argv) { if (pledge("stdio recvfd sendfd accept rpath thread unix cpath fattr", nullptr) < 0) { perror("pledge"); return 1; } auto app = GUI::Application::construct(argc, argv); if (pledge("stdio recvfd sendfd accept rpath thread unix", nullptr) < 0) { perror("pledge"); return 1; } auto audio_client = Audio::ClientConnection::construct(); audio_client->handshake(); if (pledge("stdio recvfd sendfd accept rpath thread", nullptr) < 0) { perror("pledge"); return 1; } PlaybackManager playback_manager(audio_client); PlayerState initial_player_state { true, true, false, false, false, 44100, 1.0, audio_client, playback_manager, "" }; auto app_icon = GUI::Icon::default_icon("app-sound-player"); auto window = GUI::Window::construct(); window->set_title("Sound Player"); window->set_icon(app_icon.bitmap_for_size(16)); auto menubar = GUI::MenuBar::construct(); auto& app_menu = menubar->add_menu("File"); auto& playlist_menu = menubar->add_menu("Playlist"); String path = argv[1]; // start in advanced view by default Player* player = &window->set_main_widget(window, initial_player_state); if (argc > 1) { player->open_file(path); } app_menu.add_action(GUI::CommonActions::make_open_action([&](auto&) { Optional path = GUI::FilePicker::get_open_filepath(window, "Open sound file..."); if (path.has_value()) { player->open_file(path.value()); } })); auto linear_volume_slider = GUI::Action::create_checkable("Nonlinear volume slider", [&](auto& action) { static_cast(player)->set_nonlinear_volume_slider(action.is_checked()); }); app_menu.add_action(linear_volume_slider); auto playlist_toggle = GUI::Action::create_checkable("Show playlist", [&](auto& action) { static_cast(player)->set_playlist_visible(action.is_checked()); }); playlist_menu.add_action(playlist_toggle); if (path.ends_with(".m3u") || path.ends_with(".m3u8")) playlist_toggle->set_checked(true); playlist_menu.add_separator(); auto playlist_loop_toggle = GUI::Action::create_checkable("Loop playlist", [&](auto& action) { static_cast(player)->set_looping_playlist(action.is_checked()); }); playlist_menu.add_action(playlist_loop_toggle); app_menu.add_separator(); app_menu.add_action(GUI::CommonActions::make_quit_action([&](auto&) { app->quit(); })); auto& playback_menu = menubar->add_menu("Playback"); auto loop = GUI::Action::create_checkable("Loop", { Mod_Ctrl, Key_R }, [&](auto& action) { player->set_looping_file(action.is_checked()); }); playback_menu.add_action(move(loop)); auto& visualization_menu = menubar->add_menu("Visualization"); Vector> visualization_checkmarks; GUI::Action* checked_vis = nullptr; auto uncheck_all_but = [&](GUI::Action& one) {for (auto& a : visualization_checkmarks) if (a != &one) a->set_checked(false); }; auto bars = GUI::Action::create_checkable("Bars", [&](auto& action) { uncheck_all_but(action); if (checked_vis == &action) { action.set_checked(true); return; } checked_vis = &action; static_cast(player)->set_visualization(); }); bars->set_checked(true); visualization_menu.add_action(bars); visualization_checkmarks.append(bars); auto samples = GUI::Action::create_checkable("Samples", [&](auto& action) { uncheck_all_but(action); if (checked_vis == &action) { action.set_checked(true); return; } checked_vis = &action; static_cast(player)->set_visualization(); }); visualization_menu.add_action(samples); visualization_checkmarks.append(samples); auto none = GUI::Action::create_checkable("None", [&](auto& action) { uncheck_all_but(action); if (checked_vis == &action) { action.set_checked(true); return; } checked_vis = &action; static_cast(player)->set_visualization(); }); visualization_menu.add_action(none); visualization_checkmarks.append(none); auto& help_menu = menubar->add_menu("Help"); help_menu.add_action(GUI::CommonActions::make_about_action("Sound Player", app_icon, window)); window->set_menubar(move(menubar)); window->show(); return app->exec(); }