diff --git a/pd/ssrclient-help.pd b/pd/ssrclient-help.pd
index 464ea4af..c3150b65 100644
--- a/pd/ssrclient-help.pd
+++ b/pd/ssrclient-help.pd
@@ -1,4 +1,4 @@
-#N canvas 1034 376 572 592 10;
+#N canvas 1153 446 572 592 10;
#X obj 98 174 ssrclient;
#X obj 183 174 iemnet/tcpclient;
#X msg 183 71 connect localhost 4711;
@@ -34,7 +34,8 @@
#X text 14 30 Remote-control the SoundScape Renderer via network interface
;
#X text 288 173 alternatively \, [mrpeach/tcpclient] can be used;
-#X obj 98 375 route pos azi model vol mute level weights;
+#X obj 98 375 route pos azi model vol mute level weights selected;
+#X floatatom 441 496 5 0 0 0 selected - -;
#X connect 0 0 24 0;
#X connect 0 1 1 0;
#X connect 1 0 0 1;
@@ -60,4 +61,5 @@
#X connect 33 3 15 0;
#X connect 33 4 14 0;
#X connect 33 5 23 0;
-#X connect 33 7 11 0;
+#X connect 33 7 34 0;
+#X connect 33 8 11 0;
diff --git a/pd/ssrclient.pd_lua b/pd/ssrclient.pd_lua
index 29e932ca..84f028fc 100644
--- a/pd/ssrclient.pd_lua
+++ b/pd/ssrclient.pd_lua
@@ -85,7 +85,7 @@ function SsrClient:initialize(name, atoms)
table.insert(self.command, name)
table.insert(self.command, value)
self:output_command()
- elseif name == "mute" or name == "fixed" then
+ elseif name == "mute" or name == "fixed" or name == "selected" then
self:restore_command()
table.insert(self.command, name)
if value == "true" or value == "1" then
diff --git a/src/boostnetwork/networksubscriber.cpp b/src/boostnetwork/networksubscriber.cpp
index 88c3183e..266f3720 100644
--- a/src/boostnetwork/networksubscriber.cpp
+++ b/src/boostnetwork/networksubscriber.cpp
@@ -144,6 +144,15 @@ ssr::NetworkSubscriber::set_source_mute(id_t id, const bool& mute)
return true;
}
+bool
+ssr::NetworkSubscriber::set_source_selected(id_t id, const bool& mute)
+{
+ std::string ms = "";
+ update_all_clients(ms);
+ return true;
+}
+
bool
ssr::NetworkSubscriber::set_source_name(id_t id, const std::string& name)
{
diff --git a/src/boostnetwork/networksubscriber.h b/src/boostnetwork/networksubscriber.h
index bd6479d9..b27fbc12 100644
--- a/src/boostnetwork/networksubscriber.h
+++ b/src/boostnetwork/networksubscriber.h
@@ -67,6 +67,7 @@ class NetworkSubscriber : public Subscriber
virtual bool set_source_orientation(id_t id, const Orientation& orientation);
virtual bool set_source_gain(id_t id, const float& gain);
virtual bool set_source_mute(id_t id, const bool& mute);
+ virtual bool set_source_selected(id_t id, const bool& mute);
virtual bool set_source_name(id_t id, const std::string& name);
virtual bool set_source_properties_file(id_t id, const std::string& name);
virtual bool set_source_model(id_t id, const Source::model_t& model);
diff --git a/src/controller.h b/src/controller.h
index 1757a496..e4d8646c 100644
--- a/src/controller.h
+++ b/src/controller.h
@@ -153,6 +153,7 @@ class Controller : public Publisher
virtual void set_source_signal_level(const id_t id
, const float level);
virtual void set_source_mute(id_t id, bool mute);
+ virtual void set_source_selected(id_t id, bool selected);
virtual void set_source_name(id_t id, const std::string& name);
virtual void set_source_properties_file(id_t id, const std::string& name);
virtual void set_source_model(id_t id, Source::model_t model);
@@ -1472,6 +1473,13 @@ Controller::set_source_mute(const id_t id, const bool mute)
_publish(&Subscriber::set_source_mute, id, mute);
}
+template
+void
+Controller::set_source_selected(const id_t id, const bool selected)
+{
+ _publish(&Subscriber::set_source_selected, id, selected);
+}
+
template
void
Controller::set_source_name(const id_t id, const std::string& name)
@@ -1804,6 +1812,8 @@ Controller::_add_sources(Node& node
source_node.new_attribute("volume", apf::str::A2S(apf::math::linear2dB(source.gain)));
// TODO: information about mirror sources
+ source_node.new_attribute("selected", apf::str::A2S(source.selected));
+
if (source.properties_file != "")
{
source_node.new_attribute("properties_file"
diff --git a/src/gui/qopenglplotter.cpp b/src/gui/qopenglplotter.cpp
index 061caf28..9951f4c6 100644
--- a/src/gui/qopenglplotter.cpp
+++ b/src/gui/qopenglplotter.cpp
@@ -1033,6 +1033,8 @@ void ssr::QOpenGLPlotter::_select_source(int source, bool add_to_selection)
// make its id directly available
_id_of_last_clicked_source = i->id;
+
+ _controller.set_source_selected(i->id, true);
}
else if (!_alt_pressed)
{
@@ -1064,6 +1066,8 @@ void ssr::QOpenGLPlotter::_select_all_sources()
// make valid id available
_id_of_last_clicked_source = i->id;
+ _controller.set_source_selected(i->id, true);
+
n++;
}
}
@@ -1074,6 +1078,8 @@ void ssr::QOpenGLPlotter::_deselect_source(int source)
// and that id_of_last_clicked_source has a valid value
if (_selected_sources_map.size() > 1)
{
+ _controller.set_source_selected(_selected_sources_map[source], false);
+
_selected_sources_map.erase(source);
_id_of_last_clicked_source = _selected_sources_map.begin()->second;
}
@@ -1081,6 +1087,10 @@ void ssr::QOpenGLPlotter::_deselect_source(int source)
void ssr::QOpenGLPlotter::_deselect_all_sources()
{
+ for (const auto& src: _selected_sources_map)
+ {
+ _controller.set_source_selected(src.second, false);
+ }
_selected_sources_map.clear();
_id_of_last_clicked_source = 0;
}
diff --git a/src/publisher.h b/src/publisher.h
index 6839cb95..9ad8bdf4 100644
--- a/src/publisher.h
+++ b/src/publisher.h
@@ -100,6 +100,7 @@ struct Publisher
virtual void set_source_gain(id_t id, float gain) = 0;
/// mute/unmute source
virtual void set_source_mute(id_t id, bool mute) = 0;
+ virtual void set_source_selected(id_t id, bool mute) = 0;
/// instantaneous level of audio stream
virtual void set_source_signal_level(const id_t id,
const float level) = 0;
diff --git a/src/rendersubscriber.h b/src/rendersubscriber.h
index 06c11e07..8a4debc1 100644
--- a/src/rendersubscriber.h
+++ b/src/rendersubscriber.h
@@ -100,6 +100,11 @@ class RenderSubscriber : public Subscriber
return true;
}
+ virtual bool set_source_selected(id_t, const bool&)
+ {
+ return true;
+ }
+
virtual bool set_source_name(id_t id, const std::string& name)
{
(void) id;
diff --git a/src/scene.cpp b/src/scene.cpp
index cdba5f7d..84f6c8d6 100644
--- a/src/scene.cpp
+++ b/src/scene.cpp
@@ -121,6 +121,11 @@ bool ssr::Scene::set_source_mute(id_t id, const bool& mute)
return _set_source_member(id, &Source::mute, mute);
}
+bool ssr::Scene::set_source_selected(id_t id, const bool& selected)
+{
+ return _set_source_member(id, &Source::selected, selected);
+}
+
bool ssr::Scene::set_source_name(id_t id, const std::string& name)
{
return _set_source_member(id, &Source::name, name);
diff --git a/src/scene.h b/src/scene.h
index 0cf8f556..2d374669 100644
--- a/src/scene.h
+++ b/src/scene.h
@@ -69,6 +69,7 @@ class Scene : public Subscriber
virtual bool set_source_signal_level(id_t id, const float& level);
virtual bool set_source_mute(id_t id, const bool& mute);
+ virtual bool set_source_selected(id_t id, const bool& mute);
virtual bool set_source_name(id_t id, const std::string& name);
virtual bool set_source_properties_file(id_t id, const std::string& name);
virtual bool set_source_model(id_t id, const Source::model_t& model);
diff --git a/src/source.h b/src/source.h
index 8c20e3fc..403786aa 100644
--- a/src/source.h
+++ b/src/source.h
@@ -64,6 +64,7 @@ struct Source : DirectionalPoint
file_length(0),
model(Source::point),
mute(0),
+ selected(0),
gain(1.0),
signal_level(0.0),
output_levels(outputs),
@@ -82,6 +83,7 @@ struct Source : DirectionalPoint
file_length(0),
model(Source::point),
mute(0),
+ selected(0),
gain(1.0),
signal_level(0.0),
has_mirror_sources(false),
@@ -97,6 +99,7 @@ struct Source : DirectionalPoint
long int file_length; ///< length of audio file, 0 if no file exists
model_t model; ///< source model (=type)
bool mute; ///< mute/unmute
+ bool selected;
float gain; ///< source gain (volume)
float signal_level; ///< instantaneous level of audio stream (linear scale, between 0 and 1)
std::vector output_levels;
diff --git a/src/subscriber.h b/src/subscriber.h
index 7821a756..de5ee293 100644
--- a/src/subscriber.h
+++ b/src/subscriber.h
@@ -94,6 +94,8 @@ struct Subscriber
/// _publish() function in the Controller class.
virtual bool set_source_mute(id_t id, const bool& mute) = 0;
+ virtual bool set_source_selected(id_t id, const bool& mute) = 0;
+
/// Set source name.
/// @param id ID of the source
/// @param name new name