feat: pulseaudio slider module
This commit is contained in:
parent
c9e129cda2
commit
442a4b0da0
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include "AModule.hpp"
|
||||
#include "gtkmm/scale.h"
|
||||
|
||||
namespace waybar {
|
||||
|
||||
class ASlider : public AModule {
|
||||
public:
|
||||
ASlider(const Json::Value& config, const std::string& name, const std::string& id);
|
||||
virtual void onValueChanged();
|
||||
|
||||
protected:
|
||||
bool vertical_ = false;
|
||||
int min_ = 0, max_ = 100, curr_ = 50;
|
||||
Gtk::Scale scale_;
|
||||
};
|
||||
|
||||
} // namespace waybar
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ASlider.hpp"
|
||||
#include "util/audio_backend.hpp"
|
||||
namespace waybar::modules {
|
||||
|
||||
enum class PulseaudioSliderTarget {
|
||||
Sink,
|
||||
Source,
|
||||
};
|
||||
|
||||
class PulseaudioSlider : public ASlider {
|
||||
public:
|
||||
PulseaudioSlider(const std::string&, const Json::Value&);
|
||||
virtual ~PulseaudioSlider() = default;
|
||||
|
||||
void update() override;
|
||||
void onValueChanged() override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<util::AudioBackend> backend = nullptr;
|
||||
PulseaudioSliderTarget target = PulseaudioSliderTarget::Sink;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules
|
|
@ -66,7 +66,7 @@ class AudioBackend {
|
|||
AudioBackend(std::function<void()> on_updated_cb, private_constructor_tag tag);
|
||||
~AudioBackend();
|
||||
|
||||
void changeVolume(uint16_t volume, uint16_t max_volume = 100);
|
||||
void changeVolume(uint16_t volume, uint16_t min_volume = 0, uint16_t max_volume = 100);
|
||||
void changeVolume(ChangeType change_type, double step = 1, uint16_t max_volume = 100);
|
||||
|
||||
void setIgnoredSinks(const Json::Value& config);
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
waybar-pulseaudio-slider(5)
|
||||
|
||||
# NAME
|
||||
|
||||
waybar - pulseaudio slider module
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
The *pulseaudio slider* module displays and controls the current volume of the default sink or source as a bar.
|
||||
|
||||
The volume can be controlled by dragging the slider accross the bar, or clicking on a specific position.
|
||||
|
||||
# CONFIGURATION
|
||||
|
||||
*min*: ++
|
||||
typeof: int ++
|
||||
default: 0 ++
|
||||
The minimum volume value the slider should display and set.
|
||||
|
||||
*max*: ++
|
||||
typeof: int ++
|
||||
default: 100 ++
|
||||
The maximum volume value the slider should display and set.
|
||||
|
||||
*orientation*: ++
|
||||
typeof: string ++
|
||||
default: horizontal ++
|
||||
The orientation of the slider. Can be either `horizontal` or `vertical`.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
"modules-right": [
|
||||
"pulseaudio-slider",
|
||||
],
|
||||
"pulseaudio/slider": {
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
"orientation": "horizontal"
|
||||
}
|
||||
```
|
||||
|
||||
# STYLE
|
||||
|
||||
The slider is a component with multiple CSS Nodes, of which the following are exposed:
|
||||
|
||||
*#pulseaudio-slider*: ++
|
||||
Controls the style of the box *around* the slider and bar.
|
||||
|
||||
*#pulseaudio-slider slider*: ++
|
||||
Controls the style of the slider handle.
|
||||
|
||||
*#pulseaudio-slider trough*: ++
|
||||
Controls the style of the part of the bar that has not been filled.
|
||||
|
||||
*#pulseaudio-slider highlight*: ++
|
||||
Controls the style of the part of the bar that has been filled.
|
||||
|
||||
## STYLE EXAMPLE
|
||||
|
||||
```
|
||||
#pulseaudio-slider slider {
|
||||
min-height: 0px;
|
||||
min-width: 0px;
|
||||
opacity: 0;
|
||||
background-image: none;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#pulseaudio-slider trough {
|
||||
min-height: 80px;
|
||||
min-width: 10px;
|
||||
border-radius: 5px;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
#pulseaudio-slider highlight {
|
||||
min-width: 10px;
|
||||
border-radius: 5px;
|
||||
background-color: green;
|
||||
}
|
||||
```
|
|
@ -166,6 +166,7 @@ src_files = files(
|
|||
'src/modules/image.cpp',
|
||||
'src/modules/temperature.cpp',
|
||||
'src/modules/user.cpp',
|
||||
'src/ASlider.cpp',
|
||||
'src/main.cpp',
|
||||
'src/bar.cpp',
|
||||
'src/client.cpp',
|
||||
|
@ -274,6 +275,7 @@ endif
|
|||
if libpulse.found()
|
||||
add_project_arguments('-DHAVE_LIBPULSE', language: 'cpp')
|
||||
src_files += 'src/modules/pulseaudio.cpp'
|
||||
src_files += 'src/modules/pulseaudio_slider.cpp'
|
||||
endif
|
||||
|
||||
if libjack.found()
|
||||
|
@ -441,6 +443,7 @@ if scdoc.found()
|
|||
'waybar-mpris.5.scd',
|
||||
'waybar-network.5.scd',
|
||||
'waybar-pulseaudio.5.scd',
|
||||
'waybar-pulseaudio-slider.5.scd',
|
||||
'waybar-river-mode.5.scd',
|
||||
'waybar-river-tags.5.scd',
|
||||
'waybar-river-window.5.scd',
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
#include "ASlider.hpp"
|
||||
|
||||
#include "gtkmm/adjustment.h"
|
||||
#include "gtkmm/enums.h"
|
||||
|
||||
namespace waybar {
|
||||
|
||||
ASlider::ASlider(const Json::Value& config, const std::string& name, const std::string& id)
|
||||
: AModule(config, name, id, false, false),
|
||||
vertical_(config_["orientation"].asString() == "vertical"),
|
||||
scale_(vertical_ ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL) {
|
||||
scale_.set_name(name);
|
||||
if (!id.empty()) {
|
||||
scale_.get_style_context()->add_class(id);
|
||||
}
|
||||
event_box_.add(scale_);
|
||||
scale_.signal_value_changed().connect(sigc::mem_fun(*this, &ASlider::onValueChanged));
|
||||
|
||||
if (config_["min"].isUInt()) {
|
||||
min_ = config_["min"].asUInt();
|
||||
}
|
||||
|
||||
if (config_["max"].isUInt()) {
|
||||
max_ = config_["max"].asUInt();
|
||||
}
|
||||
|
||||
scale_.set_inverted(vertical_);
|
||||
scale_.set_draw_value(false);
|
||||
scale_.set_adjustment(Gtk::Adjustment::create(curr_, min_, max_ + 1, 1, 1, 1));
|
||||
}
|
||||
|
||||
void ASlider::onValueChanged() {}
|
||||
|
||||
} // namespace waybar
|
|
@ -1,5 +1,9 @@
|
|||
#include "factory.hpp"
|
||||
|
||||
#ifdef HAVE_LIBPULSE
|
||||
#include "modules/pulseaudio_slider.hpp"
|
||||
#endif
|
||||
|
||||
waybar::Factory::Factory(const Bar& bar, const Json::Value& config) : bar_(bar), config_(config) {}
|
||||
|
||||
waybar::AModule* waybar::Factory::makeModule(const std::string& name) const {
|
||||
|
@ -136,6 +140,9 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const {
|
|||
if (ref == "pulseaudio") {
|
||||
return new waybar::modules::Pulseaudio(id, config_[name]);
|
||||
}
|
||||
if (ref == "pulseaudio/slider") {
|
||||
return new waybar::modules::PulseaudioSlider(id, config_[name]);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_LIBMPDCLIENT
|
||||
if (ref == "mpd") {
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
#include "modules/pulseaudio_slider.hpp"
|
||||
|
||||
namespace waybar::modules {
|
||||
|
||||
PulseaudioSlider::PulseaudioSlider(const std::string& id, const Json::Value& config)
|
||||
: ASlider(config, "pulseaudio-slider", id) {
|
||||
backend = util::AudioBackend::getInstance([this] { this->dp.emit(); });
|
||||
backend->setIgnoredSinks(config_["ignored-sinks"]);
|
||||
|
||||
if (config_["target"].isString()) {
|
||||
std::string target = config_["target"].asString();
|
||||
if (target == "sink") {
|
||||
this->target = PulseaudioSliderTarget::Sink;
|
||||
} else if (target == "source") {
|
||||
this->target = PulseaudioSliderTarget::Source;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PulseaudioSlider::update() {
|
||||
switch (target) {
|
||||
case PulseaudioSliderTarget::Sink:
|
||||
if (backend->getSinkMuted()) {
|
||||
scale_.set_value(min_);
|
||||
} else {
|
||||
scale_.set_value(backend->getSinkVolume());
|
||||
}
|
||||
break;
|
||||
|
||||
case PulseaudioSliderTarget::Source:
|
||||
if (backend->getSourceMuted()) {
|
||||
scale_.set_value(min_);
|
||||
} else {
|
||||
scale_.set_value(backend->getSourceVolume());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PulseaudioSlider::onValueChanged() {
|
||||
uint16_t volume = scale_.get_value();
|
||||
backend->changeVolume(volume, min_, max_);
|
||||
}
|
||||
|
||||
} // namespace waybar::modules
|
|
@ -204,11 +204,12 @@ void AudioBackend::serverInfoCb(pa_context *context, const pa_server_info *i, vo
|
|||
pa_context_get_source_info_list(context, sourceInfoCb, data);
|
||||
}
|
||||
|
||||
void AudioBackend::changeVolume(uint16_t volume, uint16_t max_volume) {
|
||||
void AudioBackend::changeVolume(uint16_t volume, uint16_t min_volume, uint16_t max_volume) {
|
||||
double volume_tick = static_cast<double>(PA_VOLUME_NORM) / 100;
|
||||
pa_cvolume pa_volume = pa_volume_;
|
||||
|
||||
volume = std::min(volume, max_volume);
|
||||
volume = std::max(volume, min_volume);
|
||||
pa_cvolume_set(&pa_volume, pa_volume_.channels, volume * volume_tick);
|
||||
|
||||
pa_context_set_sink_volume_by_index(context_, sink_idx_, &pa_volume, volumeModifyCb, this);
|
||||
|
|
Loading…
Reference in New Issue