Blame synfig-studio/src/gui/docks/dock_soundwave.cpp

Rodolfo Ribeiro Gomes 00c1e8
/* === S Y N F I G ========================================================= */
Rodolfo Ribeiro Gomes 00c1e8
/*!	\file docks/dock_soundwave.cpp
Rodolfo Ribeiro Gomes 00c1e8
**	\brief Dock for display a user-configurable Widget_SoundWave
Rodolfo Ribeiro Gomes 00c1e8
**
Rodolfo Ribeiro Gomes 00c1e8
**	$Id$
Rodolfo Ribeiro Gomes 00c1e8
**
Rodolfo Ribeiro Gomes 00c1e8
**	\legal
Rodolfo Ribeiro Gomes 00c1e8
**	Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
Rodolfo Ribeiro Gomes 00c1e8
**  ......... ... 2019 Rodolfo Ribeiro Gomes
Rodolfo Ribeiro Gomes 00c1e8
**
Rodolfo Ribeiro Gomes 00c1e8
**	This package is free software; you can redistribute it and/or
Rodolfo Ribeiro Gomes 00c1e8
**	modify it under the terms of the GNU General Public License as
Rodolfo Ribeiro Gomes 00c1e8
**	published by the Free Software Foundation; either version 2 of
Rodolfo Ribeiro Gomes 00c1e8
**	the License, or (at your option) any later version.
Rodolfo Ribeiro Gomes 00c1e8
**
Rodolfo Ribeiro Gomes 00c1e8
**	This package is distributed in the hope that it will be useful,
Rodolfo Ribeiro Gomes 00c1e8
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
Rodolfo Ribeiro Gomes 00c1e8
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Rodolfo Ribeiro Gomes 00c1e8
**	General Public License for more details.
Rodolfo Ribeiro Gomes 00c1e8
**	\endlegal
Rodolfo Ribeiro Gomes 00c1e8
*/
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
#ifdef USING_PCH
Rodolfo Ribeiro Gomes 00c1e8
#	include "pch.h"
Rodolfo Ribeiro Gomes 00c1e8
#else
Rodolfo Ribeiro Gomes 00c1e8
#ifdef HAVE_CONFIG_H
Rodolfo Ribeiro Gomes 00c1e8
#	include <config.h></config.h>
Rodolfo Ribeiro Gomes 00c1e8
#endif
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
#include "dock_soundwave.h"
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
#include <widgets widget_soundwave.h=""></widgets>
Rodolfo Ribeiro Gomes 00c1e8
#include <gui canvasview.h=""></gui>
Rodolfo Ribeiro Gomes 00c1e8
#include <gui localization.h=""></gui>
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
#include <synfig general.h=""></synfig>
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
#endif
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
using namespace studio;
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
Dock_SoundWave::Dock_SoundWave()
63a177
	: Dock_CanvasSpecific("soundwave", _("Sound"), Gtk::StockID("synfig-layer_other_sound")),
Rodolfo Ribeiro Gomes 00c1e8
	  current_widget_sound(nullptr)
Rodolfo Ribeiro Gomes 00c1e8
{
Rodolfo Ribeiro Gomes f27fe2
	set_use_scrolled(false);
Rodolfo Ribeiro Gomes f27fe2
Rodolfo Ribeiro Gomes 00c1e8
	widget_kf_list.set_hexpand();
Rodolfo Ribeiro Gomes 00c1e8
	widget_kf_list.show();
Rodolfo Ribeiro Gomes 00c1e8
	widget_timeslider.set_hexpand();
Rodolfo Ribeiro Gomes 00c1e8
	widget_timeslider.show();
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
	file_button.show();
Rodolfo Ribeiro Gomes 00c1e8
	file_button.signal_file_set().connect(sigc::mem_fun(*this, &Dock_SoundWave::on_file_button_clicked));
Rodolfo Ribeiro Gomes 00c1e8
	Glib::RefPtr<gtk::filefilter> filter = Gtk::FileFilter::create();</gtk::filefilter>
Rodolfo Ribeiro Gomes 00c1e8
	filter->add_mime_type("audio/*");
Rodolfo Ribeiro Gomes 00c1e8
	file_button.set_filter(filter);
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
	clear_button.set_label(_("Clear"));
Rodolfo Ribeiro Gomes 00c1e8
//	clear_button.get_style_context()->add_class("button");
Rodolfo Ribeiro Gomes f1be99
	clear_button.show();
Rodolfo Ribeiro Gomes 00c1e8
	clear_button.signal_clicked().connect(sigc::mem_fun(*this, &Dock_SoundWave::on_clear_button_clicked));
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes e306dc
	channel_combo.show();
Rodolfo Ribeiro Gomes e306dc
	channel_combo.set_tooltip_text(_("What sound channel to display"));
Rodolfo Ribeiro Gomes e306dc
	channel_combo.signal_changed().connect(sigc::mem_fun(*this, &Dock_SoundWave::on_channel_combo_changed));
Rodolfo Ribeiro Gomes e306dc
Rodolfo Ribeiro Gomes 8ea794
	label_delay.set_text(_("Delay:"));
Rodolfo Ribeiro Gomes 8ea794
	label_delay.show();
Rodolfo Ribeiro Gomes 8ea794
Rodolfo Ribeiro Gomes 8ea794
	delay_widget.show();
Rodolfo Ribeiro Gomes 8ea794
	delay_widget.signal_value_changed().connect(sigc::mem_fun(*this, &Dock_SoundWave::on_delay_changed));
Rodolfo Ribeiro Gomes 8ea794
Rodolfo Ribeiro Gomes 00c1e8
	vscrollbar.set_vexpand();
Rodolfo Ribeiro Gomes 00c1e8
	vscrollbar.set_hexpand(false);
Rodolfo Ribeiro Gomes 00c1e8
	vscrollbar.show();
Rodolfo Ribeiro Gomes 00c1e8
	hscrollbar.set_hexpand();
Rodolfo Ribeiro Gomes 00c1e8
	hscrollbar.show();
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
	grid.set_column_homogeneous(false);
Rodolfo Ribeiro Gomes 00c1e8
	grid.set_row_homogeneous(false);
Rodolfo Ribeiro Gomes 00c1e8
	add(grid);
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes f1be99
	file_settings_box.set_orientation(Gtk::ORIENTATION_HORIZONTAL);
Rodolfo Ribeiro Gomes f1be99
	file_settings_box.set_homogeneous(false);
Rodolfo Ribeiro Gomes f1be99
	file_settings_box.set_spacing(2);
Rodolfo Ribeiro Gomes f1be99
	file_settings_box.pack_start(clear_button, false, false);
Rodolfo Ribeiro Gomes e306dc
	file_settings_box.pack_start(channel_combo, false, false);
Rodolfo Ribeiro Gomes 8ea794
	file_settings_box.pack_start(label_delay, false, false);
Rodolfo Ribeiro Gomes 8ea794
	file_settings_box.pack_start(delay_widget, false, false);
Rodolfo Ribeiro Gomes f1be99
	file_settings_box.hide();
Rodolfo Ribeiro Gomes f1be99
Rodolfo Ribeiro Gomes 00c1e8
	file_box.set_orientation(Gtk::ORIENTATION_HORIZONTAL);
Rodolfo Ribeiro Gomes 00c1e8
	file_box.set_homogeneous(false);
Rodolfo Ribeiro Gomes 00c1e8
	file_box.set_spacing(2);
Rodolfo Ribeiro Gomes 00c1e8
	file_box.pack_start(file_button, false, false);
Rodolfo Ribeiro Gomes f1be99
	file_box.pack_start(file_settings_box, false, false);
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
	drag_dest_set(Gtk::DEST_DEFAULT_ALL, Gdk::ACTION_COPY);
Rodolfo Ribeiro Gomes 00c1e8
	signal_drag_data_received().connect(sigc::mem_fun(*this,
Rodolfo Ribeiro Gomes 00c1e8
				&Dock_SoundWave::on_drop_drag_data_received) );
Rodolfo Ribeiro Gomes 00c1e8
}
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
void Dock_SoundWave::init_canvas_view_vfunc(etl::loose_handle<canvasview> canvas_view)</canvasview>
Rodolfo Ribeiro Gomes 00c1e8
{
Rodolfo Ribeiro Gomes 00c1e8
	Widget_SoundWave *widget_sound = new Widget_SoundWave();
Rodolfo Ribeiro Gomes 00c1e8
	widget_sound->set_time_model(canvas_view->time_model());
Rodolfo Ribeiro Gomes 00c1e8
	widget_sound->show();
Rodolfo Ribeiro Gomes 00c1e8
	widget_sound->set_hexpand(true);
Rodolfo Ribeiro Gomes 00c1e8
	widget_sound->set_vexpand(true);
Rodolfo Ribeiro Gomes 00c1e8
	widget_sound->signal_file_loaded().connect([=](const std::string &filename) {
Rodolfo Ribeiro Gomes 00c1e8
		if (!filename.empty()) {
Rodolfo Ribeiro Gomes 00c1e8
			file_button.set_uri(filename);
Rodolfo Ribeiro Gomes 00c1e8
		} else {
Rodolfo Ribeiro Gomes 00c1e8
			file_button.unselect_all();
Rodolfo Ribeiro Gomes 00c1e8
		}
Rodolfo Ribeiro Gomes f1be99
		file_settings_box.set_visible(!filename.empty());
Rodolfo Ribeiro Gomes 00c1e8
	});
Rodolfo Ribeiro Gomes 00c1e8
	canvas_view->set_ext_widget(get_name(), widget_sound);
Rodolfo Ribeiro Gomes 00c1e8
}
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
void Dock_SoundWave::changed_canvas_view_vfunc(etl::loose_handle<canvasview> canvas_view)</canvasview>
Rodolfo Ribeiro Gomes 00c1e8
{
Rodolfo Ribeiro Gomes 00c1e8
	std::lock_guard<std::mutex> lock(mutex);</std::mutex>
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
	const std::vector<gtk::widget*> children = grid.get_children();</gtk::widget*>
Rodolfo Ribeiro Gomes 00c1e8
	for (Gtk::Widget * widget : children) {
Rodolfo Ribeiro Gomes 00c1e8
		// CanvasView and Dock_SoundWave will delete widgets when needed
Rodolfo Ribeiro Gomes 00c1e8
		grid.remove(*widget);
Rodolfo Ribeiro Gomes 00c1e8
	}
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
	if( !canvas_view ) {
Rodolfo Ribeiro Gomes 00c1e8
		widget_kf_list.set_time_model( etl::handle<timemodel>() );</timemodel>
Rodolfo Ribeiro Gomes 00c1e8
		widget_kf_list.set_canvas_interface( etl::loose_handle<synfigapp::canvasinterface>() );</synfigapp::canvasinterface>
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
		widget_timeslider.set_canvas_view( CanvasView::Handle() );
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
		current_widget_sound = nullptr; // deleted by its studio::CanvasView::~CanvasView()
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
		file_box.hide();
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
		hscrollbar.unset_adjustment();
Rodolfo Ribeiro Gomes 00c1e8
		vscrollbar.unset_adjustment();
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
		std::vector< Gtk::TargetEntry > targets;
Rodolfo Ribeiro Gomes 00c1e8
		drag_dest_set(targets);
Rodolfo Ribeiro Gomes 00c1e8
	} else {
Rodolfo Ribeiro Gomes 00c1e8
		widget_kf_list.set_time_model(canvas_view->time_model());
Rodolfo Ribeiro Gomes 00c1e8
		widget_kf_list.set_canvas_interface(canvas_view->canvas_interface());
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
		widget_timeslider.set_canvas_view(canvas_view);
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
		current_widget_sound = dynamic_cast<widget_soundwave*>( canvas_view->get_ext_widget(get_name()) );</widget_soundwave*>
Rodolfo Ribeiro Gomes 00c1e8
		current_widget_sound->set_size_request(100, 100);
Rodolfo Ribeiro Gomes 00c1e8
		current_widget_sound->set_hexpand(true);
Rodolfo Ribeiro Gomes 00c1e8
		current_widget_sound->set_vexpand(true);
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
		std::string filename = current_widget_sound->get_filename();
Rodolfo Ribeiro Gomes 00c1e8
		if (filename.empty())
Rodolfo Ribeiro Gomes 00c1e8
			file_button.unselect_all();
Rodolfo Ribeiro Gomes 00c1e8
		else
Rodolfo Ribeiro Gomes 00c1e8
			file_button.set_uri(filename);
Rodolfo Ribeiro Gomes e306dc
Rodolfo Ribeiro Gomes 8ea794
		setup_file_setting_data();
Rodolfo Ribeiro Gomes e306dc
Rodolfo Ribeiro Gomes f1be99
		file_settings_box.set_visible(!filename.empty());
Rodolfo Ribeiro Gomes 00c1e8
		file_box.show();
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
		vscrollbar.set_adjustment(current_widget_sound->get_range_adjustment());
Rodolfo Ribeiro Gomes 00c1e8
		hscrollbar.set_adjustment(canvas_view->time_model()->scroll_time_adjustment());
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
		grid.attach(widget_kf_list,        0, 0, 1, 1);
Rodolfo Ribeiro Gomes 00c1e8
		grid.attach(widget_timeslider,     0, 1, 1, 1);
Rodolfo Ribeiro Gomes 00c1e8
		grid.attach(*current_widget_sound, 0, 2, 1, 1);
Rodolfo Ribeiro Gomes 00c1e8
		grid.attach(file_box,              0, 3, 1, 1);
Rodolfo Ribeiro Gomes 00c1e8
		grid.attach(hscrollbar,            0, 4, 2, 1);
Rodolfo Ribeiro Gomes 00c1e8
		grid.attach(vscrollbar,            1, 0, 1, 4);
Rodolfo Ribeiro Gomes 00c1e8
		grid.show();
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
		std::vector< Gtk::TargetEntry > targets;
Rodolfo Ribeiro Gomes 00c1e8
		drag_dest_set(targets);
Rodolfo Ribeiro Gomes 00c1e8
		drag_dest_add_uri_targets();
Rodolfo Ribeiro Gomes 00c1e8
	}
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
}
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
void Dock_SoundWave::on_drop_drag_data_received(const Glib::RefPtr<gdk::dragcontext>& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time)</gdk::dragcontext>
Rodolfo Ribeiro Gomes 00c1e8
{
Rodolfo Ribeiro Gomes 00c1e8
	bool success = false;
Rodolfo Ribeiro Gomes 00c1e8
	const int length = selection_data.get_length();
Rodolfo Ribeiro Gomes 00c1e8
	if((length >= 0) && (selection_data.get_format() == 8)) {
Rodolfo Ribeiro Gomes 00c1e8
		std::string uri_list_string = selection_data.get_data_as_string();
Rodolfo Ribeiro Gomes 00c1e8
		std::vector<std::string> uris;</std::string>
Rodolfo Ribeiro Gomes 00c1e8
		std::istringstream f(uri_list_string);
Rodolfo Ribeiro Gomes 00c1e8
		std::string s;
Rodolfo Ribeiro Gomes 00c1e8
		while (getline(f, s)) {
Rodolfo Ribeiro Gomes 00c1e8
			// r-trim
Rodolfo Ribeiro Gomes 00c1e8
			s.erase(std::find_if(s.rbegin(), s.rend(),
Rodolfo Ribeiro Gomes 00c1e8
									[](int chr) { return !std::isspace(chr);}).base(),
Rodolfo Ribeiro Gomes 00c1e8
			        s.end()
Rodolfo Ribeiro Gomes 00c1e8
			       );
Rodolfo Ribeiro Gomes 00c1e8
			uris.push_back(s);
Rodolfo Ribeiro Gomes 00c1e8
		}
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
		success = load_sound_file(uris.front());
Rodolfo Ribeiro Gomes 00c1e8
	}
Rodolfo Ribeiro Gomes 00c1e8
	context->drag_finish(success, false, time);
Rodolfo Ribeiro Gomes 00c1e8
}
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
void Dock_SoundWave::on_file_button_clicked()
Rodolfo Ribeiro Gomes 00c1e8
{
Rodolfo Ribeiro Gomes 00c1e8
	load_sound_file(file_button.get_uri());
Rodolfo Ribeiro Gomes 00c1e8
}
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes 00c1e8
void Dock_SoundWave::on_clear_button_clicked()
Rodolfo Ribeiro Gomes 00c1e8
{
Rodolfo Ribeiro Gomes 00c1e8
	std::lock_guard<std::mutex> lock(mutex);</std::mutex>
Rodolfo Ribeiro Gomes 00c1e8
	file_button.unselect_all();
Rodolfo Ribeiro Gomes 00c1e8
	current_widget_sound->clear();
Rodolfo Ribeiro Gomes f1be99
	file_settings_box.hide();
Rodolfo Ribeiro Gomes 00c1e8
}
Rodolfo Ribeiro Gomes 00c1e8
Rodolfo Ribeiro Gomes e306dc
void Dock_SoundWave::on_channel_combo_changed()
Rodolfo Ribeiro Gomes e306dc
{
Rodolfo Ribeiro Gomes e306dc
	if (!current_widget_sound)
Rodolfo Ribeiro Gomes e306dc
		return;
Rodolfo Ribeiro Gomes e306dc
	std::string channel_string = channel_combo.get_active_id();
Rodolfo Ribeiro Gomes e306dc
	if (channel_string.empty())
Rodolfo Ribeiro Gomes e306dc
		return;
Rodolfo Ribeiro Gomes e306dc
	int channel_idx = std::stoi(channel_string);
Rodolfo Ribeiro Gomes e306dc
	current_widget_sound->set_channel_idx(channel_idx);
Rodolfo Ribeiro Gomes e306dc
}
Rodolfo Ribeiro Gomes e306dc
Rodolfo Ribeiro Gomes 8ea794
void Dock_SoundWave::on_delay_changed()
Rodolfo Ribeiro Gomes 8ea794
{
Rodolfo Ribeiro Gomes 8ea794
	if (current_widget_sound)
Rodolfo Ribeiro Gomes 8ea794
		current_widget_sound->set_delay(delay_widget.get_value());
Rodolfo Ribeiro Gomes 8ea794
}
Rodolfo Ribeiro Gomes 8ea794
Rodolfo Ribeiro Gomes 00c1e8
bool Dock_SoundWave::load_sound_file(const std::string& filename)
Rodolfo Ribeiro Gomes 00c1e8
{
Rodolfo Ribeiro Gomes 00c1e8
	file_button.set_sensitive(false);
Rodolfo Ribeiro Gomes 00c1e8
	std::lock_guard<std::mutex> lock(mutex);</std::mutex>
Rodolfo Ribeiro Gomes 00c1e8
	bool ok = current_widget_sound->load(filename);
Rodolfo Ribeiro Gomes 00c1e8
	if (ok) {
Rodolfo Ribeiro Gomes 8ea794
		setup_file_setting_data();
Rodolfo Ribeiro Gomes f1be99
		file_settings_box.show();
Rodolfo Ribeiro Gomes 00c1e8
	} else {
Rodolfo Ribeiro Gomes 00c1e8
		synfig::warning("Audio file not supported");
Rodolfo Ribeiro Gomes 00c1e8
	}
Rodolfo Ribeiro Gomes 00c1e8
	file_button.set_sensitive(true);
Rodolfo Ribeiro Gomes 00c1e8
	return ok;
Rodolfo Ribeiro Gomes 00c1e8
}
Rodolfo Ribeiro Gomes 8ea794
Rodolfo Ribeiro Gomes 8ea794
void Dock_SoundWave::setup_file_setting_data()
Rodolfo Ribeiro Gomes 8ea794
{
Rodolfo Ribeiro Gomes 8ea794
	channel_combo.remove_all();
Rodolfo Ribeiro Gomes 8ea794
	for (int n = 0; n < current_widget_sound->get_channel_number(); n++) {
Rodolfo Ribeiro Gomes 8ea794
		// let us be a bit user-friendly by starting index from 1 instead of 0
Rodolfo Ribeiro Gomes 8ea794
		std::string text = etl::strprintf(_("Channel #%i"), n+1);
Rodolfo Ribeiro Gomes 8ea794
		channel_combo.append(std::to_string(n), text);
Rodolfo Ribeiro Gomes 8ea794
	}
Rodolfo Ribeiro Gomes 8ea794
	channel_combo.set_active_id(std::to_string(current_widget_sound->get_channel_idx()));
Rodolfo Ribeiro Gomes 8ea794
Rodolfo Ribeiro Gomes 8b0f19
	delay_widget.set_fps(current_widget_sound->get_time_model()->get_frame_rate());
Rodolfo Ribeiro Gomes 8ea794
	delay_widget.set_value(current_widget_sound->get_delay());
Rodolfo Ribeiro Gomes 8ea794
}