293 lines
7.1 KiB
C++
293 lines
7.1 KiB
C++
/*
|
|
* Copyright 2014 (c) Anna Schumaker.
|
|
*/
|
|
#include <core/audio.h>
|
|
#include <core/callback.h>
|
|
#include <core/deck.h>
|
|
#include <core/driver.h>
|
|
#include <core/idle.h>
|
|
#include <core/playlist.h>
|
|
#include <core/print.h>
|
|
|
|
#include <gui/ocarina.h>
|
|
#include <gui/tabs.h>
|
|
|
|
static bool audio_playing = false;
|
|
static Glib::RefPtr<Gtk::Builder> builder;
|
|
static sigc::connection fav_connection;
|
|
static sigc::connection ban_connection;
|
|
void enable_timeout();
|
|
|
|
|
|
|
|
/*
|
|
* Control functions
|
|
*/
|
|
static void on_config_pause()
|
|
{
|
|
Gtk::SpinButton *count = get_widget<Gtk::SpinButton>("o_pause_count");
|
|
Gtk::CheckButton *enabled = get_widget<Gtk::CheckButton>("o_pause_enabled");
|
|
|
|
audio :: pause_after(enabled->get_active(), count->get_value());
|
|
}
|
|
|
|
static void on_play()
|
|
{
|
|
get_widget<Gtk::Button>("o_play")->hide();
|
|
get_widget<Gtk::Button>("o_pause")->show();
|
|
audio_playing = true;
|
|
enable_timeout();
|
|
}
|
|
|
|
static void on_pause()
|
|
{
|
|
get_widget<Gtk::Button>("o_play")->show();
|
|
get_widget<Gtk::Button>("o_pause")->hide();
|
|
audio_playing = false;
|
|
}
|
|
|
|
static void on_next()
|
|
{
|
|
audio :: next();
|
|
audio :: play();
|
|
}
|
|
|
|
static bool on_seek(Gtk::ScrollType type, double value)
|
|
{
|
|
audio :: seek_to(value);
|
|
return true;
|
|
}
|
|
|
|
static void set_label_text(Gtk::Label *label, const std::string &size,
|
|
const std::string &text)
|
|
{
|
|
label->set_markup("<span size='" + size + "'>" +
|
|
Glib::Markup::escape_text(text) + "</span>");
|
|
}
|
|
|
|
static void on_track_loaded(Track *track)
|
|
{
|
|
Gtk::ToggleButton *ban = get_widget<Gtk::ToggleButton>("o_ban");
|
|
Gtk::ToggleButton *fav = get_widget<Gtk::ToggleButton>("o_favorite");
|
|
Gtk::Label *title = get_widget<Gtk::Label>("o_title");
|
|
Gtk::Label *artist = get_widget<Gtk::Label>("o_artist");
|
|
Gtk::Label *album = get_widget<Gtk::Label>("o_album");
|
|
Gtk::Label *duration = get_widget<Gtk::Label>("o_total_time");
|
|
|
|
set_label_text(title, "xx-large", track->title);
|
|
set_label_text(artist, "x-large", "By: " + track->artist->name);
|
|
set_label_text(album, "x-large", "From: " + track->album->name);
|
|
duration->set_text(track->length_str);
|
|
|
|
bool banned = playlist :: has(track, "Banned");
|
|
bool favorite = playlist :: has(track, "Favorites");
|
|
|
|
ban_connection.block();
|
|
fav_connection.block();
|
|
if (ban->get_active() != banned)
|
|
ban->set_active(banned);
|
|
if (fav->get_active() != favorite)
|
|
fav->set_active(favorite);
|
|
ban_connection.unblock();
|
|
fav_connection.unblock();
|
|
}
|
|
|
|
static void on_pause_count_changed(bool enabled, unsigned int count)
|
|
{
|
|
Gtk::CheckButton *p_enabled = get_widget<Gtk::CheckButton>("o_pause_enabled");
|
|
Gtk::SpinButton *p_count = get_widget<Gtk::SpinButton>("o_pause_count");;
|
|
|
|
if (p_enabled->get_active() != enabled)
|
|
p_enabled->set_active(enabled);
|
|
if (p_count->get_value() != count)
|
|
p_count->set_value(count);
|
|
}
|
|
|
|
static void on_ban_toggled()
|
|
{
|
|
Gtk::ToggleButton *ban = get_widget<Gtk::ToggleButton>("o_ban");
|
|
|
|
if (ban->get_active() == true)
|
|
playlist :: add(audio :: current_track(), "Banned");
|
|
else
|
|
playlist :: del(audio::current_track(), "Banned");
|
|
}
|
|
|
|
static void on_fav_toggled()
|
|
{
|
|
Gtk::ToggleButton *fav = get_widget<Gtk::ToggleButton>("o_favorite");
|
|
|
|
if (fav->get_active() == true)
|
|
playlist :: add(audio::current_track(), "Favorites");
|
|
else
|
|
playlist :: del(audio::current_track(), "Favorites");
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Keyboard shortcuts
|
|
*/
|
|
static bool on_window_key_pressed(GdkEventKey *event)
|
|
{
|
|
Gtk::Notebook *notebook = get_widget<Gtk::Notebook>("o_notebook");
|
|
Gtk::Window *window = get_widget<Gtk::Window>("o_window");
|
|
std::string key = gdk_keyval_name(event->keyval);
|
|
|
|
if (key.size() >= 3) {
|
|
if (key.substr(0, 3) == "KP_")
|
|
key = key.substr(3);
|
|
}
|
|
|
|
if (key == "Escape")
|
|
window->set_focus(*window);
|
|
else if (key == "slash")
|
|
tab_focus_search();
|
|
else if (key >= "0" && key <= "9") {
|
|
unsigned int n = atoi(key.c_str());
|
|
if (n < deck::get_queues().size())
|
|
notebook->set_current_page(n);
|
|
} else if (key == "c")
|
|
notebook->set_current_page(deck::get_queues().size());
|
|
else if (key == "h")
|
|
notebook->set_current_page(deck::get_queues().size() + 1);
|
|
else if (key == "m")
|
|
notebook->set_current_page(deck::get_queues().size() + 3);
|
|
else if (key == "n")
|
|
on_next();
|
|
else if (key == "N")
|
|
audio :: prev();
|
|
else if (key == "p")
|
|
notebook->set_current_page(deck::get_queues().size() + 2);
|
|
else
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
static bool on_window_key_released(GdkEventKey *event)
|
|
{
|
|
std::string key = gdk_keyval_name(event->keyval);
|
|
|
|
if (key == "space") {
|
|
if (driver :: get_driver()->is_playing())
|
|
audio :: pause();
|
|
else
|
|
audio :: play();
|
|
} else
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Idle func
|
|
*/
|
|
bool on_idle()
|
|
{
|
|
Gtk::ProgressBar *prog = get_widget<Gtk::ProgressBar>("o_idle_progress");
|
|
bool ret = idle::run_task();
|
|
|
|
if (ret == false)
|
|
prog->hide();
|
|
else {
|
|
prog->show();
|
|
prog->set_fraction(idle::get_progress());
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void enable_idle()
|
|
{
|
|
Glib::signal_idle().connect(sigc::ptr_fun(on_idle));
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Timeout function
|
|
*/
|
|
bool on_timeout()
|
|
{
|
|
Gtk::Label *position = get_widget<Gtk::Label>("o_cur_position");
|
|
Glib::RefPtr<Gtk::Adjustment> bar = get_object<Gtk::Adjustment>("o_progress");
|
|
|
|
position->set_text(audio :: position_str());
|
|
bar->set_upper(audio :: duration());
|
|
bar->set_value(audio :: position());
|
|
|
|
return audio_playing;
|
|
}
|
|
|
|
void enable_timeout()
|
|
{
|
|
Glib::signal_timeout().connect(sigc::ptr_fun(on_timeout), 500);
|
|
}
|
|
|
|
|
|
/*
|
|
* Ocarina functions
|
|
*/
|
|
Glib::RefPtr<Gtk::Builder> &get_builder()
|
|
{
|
|
return builder;
|
|
}
|
|
|
|
void connect_button(const std::string &name, void (*func)())
|
|
{
|
|
get_widget<Gtk::Button>(name)->signal_clicked().connect(sigc::ptr_fun(func));
|
|
}
|
|
|
|
Gtk::Window *setup_gui()
|
|
{
|
|
struct Callbacks *cb = get_callbacks();
|
|
|
|
builder = Gtk::Builder::create();
|
|
builder->add_from_file(share_file("ocarina6.glade"));
|
|
|
|
|
|
/* Controls */
|
|
Gtk::SpinButton *count = get_widget<Gtk::SpinButton>("o_pause_count");
|
|
Gtk::CheckButton *enabled = get_widget<Gtk::CheckButton>("o_pause_enabled");
|
|
Gtk::Scale *position = get_widget<Gtk::Scale>("o_position_scale");
|
|
|
|
cb->on_play = on_play;
|
|
cb->on_pause = on_pause;
|
|
cb->on_track_loaded = on_track_loaded;
|
|
cb->on_pause_count_changed = on_pause_count_changed;
|
|
|
|
connect_button("o_play", audio::play);
|
|
connect_button("o_pause", audio::pause);
|
|
connect_button("o_stop", audio::stop);
|
|
connect_button("o_prev", audio::prev);
|
|
connect_button("o_next", on_next);
|
|
|
|
count->signal_changed().connect(sigc::ptr_fun(on_config_pause));
|
|
enabled->signal_toggled().connect(sigc::ptr_fun(on_config_pause));
|
|
position->signal_change_value().connect(sigc::ptr_fun(on_seek));
|
|
|
|
|
|
/* Keyboard shortcuts */
|
|
Gtk::Window *window = get_widget<Gtk::Window>("o_window");
|
|
|
|
window->signal_key_press_event().connect(sigc::ptr_fun(on_window_key_pressed));
|
|
window->signal_key_release_event().connect(sigc::ptr_fun(on_window_key_released));
|
|
window->set_can_focus();
|
|
window->set_icon_from_file(share_file("ocarina.png"));
|
|
|
|
|
|
/* Favorite and ban buttons */
|
|
Gtk::ToggleButton *ban = get_widget<Gtk::ToggleButton>("o_ban");
|
|
Gtk::ToggleButton *fav = get_widget<Gtk::ToggleButton>("o_favorite");
|
|
|
|
ban_connection = ban->signal_toggled().connect(sigc::ptr_fun(on_ban_toggled));
|
|
fav_connection = fav->signal_toggled().connect(sigc::ptr_fun(on_fav_toggled));
|
|
|
|
|
|
/* Set up other tabs */
|
|
collection_mgr_init();
|
|
init_tabs();
|
|
|
|
return window;
|
|
}
|