浏览代码

Base+MenuApplet: Add new controls and icons for AudioApplet

Adds a classic volume slider to the AudioApplet. Percent text
and mute state can now be toggled via checkboxes. Left click opens,
right click mutes. Updates existing icons and adds unique icons for
muted vs zero volume states.
thankyouverycool 5 年之前
父节点
当前提交
bbcdab2baa

二进制
Base/res/icons/audio-volume-high.png


二进制
Base/res/icons/audio-volume-low.png


二进制
Base/res/icons/audio-volume-medium.png


二进制
Base/res/icons/audio-volume-muted.png


二进制
Base/res/icons/audio-volume-zero.png


+ 108 - 12
MenuApplets/Audio/main.cpp

@@ -26,7 +26,11 @@
 
 
 #include <LibAudio/ClientConnection.h>
 #include <LibAudio/ClientConnection.h>
 #include <LibGUI/Application.h>
 #include <LibGUI/Application.h>
+#include <LibGUI/BoxLayout.h>
+#include <LibGUI/CheckBox.h>
+#include <LibGUI/Label.h>
 #include <LibGUI/Painter.h>
 #include <LibGUI/Painter.h>
+#include <LibGUI/Slider.h>
 #include <LibGUI/Widget.h>
 #include <LibGUI/Widget.h>
 #include <LibGUI/Window.h>
 #include <LibGUI/Window.h>
 #include <LibGfx/Bitmap.h>
 #include <LibGfx/Bitmap.h>
@@ -42,6 +46,8 @@ public:
         m_audio_client->on_muted_state_change = [this](bool muted) {
         m_audio_client->on_muted_state_change = [this](bool muted) {
             if (m_audio_muted == muted)
             if (m_audio_muted == muted)
                 return;
                 return;
+            m_mute_box->set_checked(!m_audio_muted);
+            m_slider->set_enabled(!muted);
             m_audio_muted = muted;
             m_audio_muted = muted;
             update();
             update();
         };
         };
@@ -52,21 +58,88 @@ public:
                 update();
                 update();
         };
         };
 
 
-        m_volume_level_bitmaps.append({66, Gfx::Bitmap::load_from_file("/res/icons/audio-volume-high.png")});
-        m_volume_level_bitmaps.append({33, Gfx::Bitmap::load_from_file("/res/icons/audio-volume-medium.png")});
-        m_volume_level_bitmaps.append({1,  Gfx::Bitmap::load_from_file("/res/icons/audio-volume-low.png")});
-        m_volume_level_bitmaps.append({0,  Gfx::Bitmap::load_from_file("/res/icons/audio-volume-muted.png")});
+        m_volume_level_bitmaps.append({ 66, Gfx::Bitmap::load_from_file("/res/icons/audio-volume-high.png") });
+        m_volume_level_bitmaps.append({ 33, Gfx::Bitmap::load_from_file("/res/icons/audio-volume-medium.png") });
+        m_volume_level_bitmaps.append({ 1, Gfx::Bitmap::load_from_file("/res/icons/audio-volume-low.png") });
+        m_volume_level_bitmaps.append({ 0, Gfx::Bitmap::load_from_file("/res/icons/audio-volume-zero.png") });
+        m_volume_level_bitmaps.append({ 0, Gfx::Bitmap::load_from_file("/res/icons/audio-volume-muted.png") });
+
+        m_slider_window = add<GUI::Window>(window());
+        m_slider_window->set_frameless(true);
+        m_slider_window->set_resizable(false);
+        m_slider_window->set_minimizable(false);
+        m_slider_window->on_active_input_change = [this](bool is_active_input) {
+            if (!is_active_input)
+                close();
+        };
+
+        m_root_container = m_slider_window->set_main_widget<GUI::Label>();
+        m_root_container->set_fill_with_background_color(true);
+        m_root_container->set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
+        m_root_container->set_layout<GUI::VerticalBoxLayout>();
+        m_root_container->layout()->set_margins({ 0, 4, 0, 4 });
+        m_root_container->layout()->set_spacing(0);
+        m_root_container->set_frame_thickness(2);
+        m_root_container->set_frame_shape(Gfx::FrameShape::Container);
+        m_root_container->set_frame_shadow(Gfx::FrameShadow::Raised);
+
+        m_percent_box = m_root_container->add<GUI::CheckBox>("\xE2\x84\xB9");
+        m_percent_box->set_size_policy(GUI::SizePolicy::Fixed, GUI::SizePolicy::Fixed);
+        m_percent_box->set_preferred_size(27, 16);
+        m_percent_box->set_checked(false);
+        m_percent_box->set_tooltip("Show percent");
+        m_percent_box->on_checked = [&](bool show_percent) {
+            m_show_percent = show_percent;
+            if (!m_show_percent) {
+                window()->resize(16, 16);
+                m_percent_box->set_tooltip("Show percent");
+            } else {
+                window()->resize(44, 16);
+                m_percent_box->set_tooltip("Hide percent");
+            }
+            reposition_slider_window();
+            GUI::Application::the()->hide_tooltip();
+        };
+
+        m_slider = m_root_container->add<GUI::VerticalSlider>();
+        m_slider->set_max(20);
+        m_slider->set_value(0);
+        m_slider->set_knob_size_mode(GUI::Slider::KnobSizeMode::Proportional);
+        m_slider->set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
+        m_slider->on_value_changed = [&](int value) {
+            int volume = clamp((20 - value) * 5, 0, 100);
+            m_audio_client->set_main_mix_volume(volume);
+            update();
+        };
+
+        m_mute_box = m_root_container->add<GUI::CheckBox>("\xE2\x9D\x8C");
+        m_mute_box->set_size_policy(GUI::SizePolicy::Fixed, GUI::SizePolicy::Fixed);
+        m_mute_box->set_preferred_size(27, 16);
+        m_mute_box->set_checked(false);
+        m_mute_box->set_tooltip("Mute");
+        m_mute_box->on_checked = [&](bool is_muted) {
+            m_mute_box->set_tooltip(is_muted ? "Unmute" : "Mute");
+            m_audio_client->set_muted(is_muted);
+            GUI::Application::the()->hide_tooltip();
+        };
     }
     }
 
 
-    virtual ~AudioWidget() override {}
+    virtual ~AudioWidget() override { }
 
 
 private:
 private:
     virtual void mousedown_event(GUI::MouseEvent& event) override
     virtual void mousedown_event(GUI::MouseEvent& event) override
     {
     {
-        if (event.button() != GUI::MouseButton::Left)
+        if (event.button() == GUI::MouseButton::Left) {
+            if (!m_slider_window->is_visible())
+                open();
+            else
+                close();
             return;
             return;
-        m_audio_client->set_muted(!m_audio_muted);
-        update();
+        }
+        if (event.button() == GUI::MouseButton::Right) {
+            m_audio_client->set_muted(!m_audio_muted);
+            update();
+        }
     }
     }
 
 
     virtual void mousewheel_event(GUI::MouseEvent& event) override
     virtual void mousewheel_event(GUI::MouseEvent& event) override
@@ -75,6 +148,7 @@ private:
             return;
             return;
         int volume = clamp(m_audio_volume - event.wheel_delta() * 5, 0, 100);
         int volume = clamp(m_audio_volume - event.wheel_delta() * 5, 0, 100);
         m_audio_client->set_main_mix_volume(volume);
         m_audio_client->set_main_mix_volume(volume);
+        m_slider->set_value(20 - (volume / 5));
         update();
         update();
     }
     }
 
 
@@ -87,8 +161,21 @@ private:
         auto& audio_bitmap = choose_bitmap_from_volume();
         auto& audio_bitmap = choose_bitmap_from_volume();
         painter.blit({}, audio_bitmap, audio_bitmap.rect());
         painter.blit({}, audio_bitmap, audio_bitmap.rect());
 
 
-        auto volume_text = m_audio_muted ? "Mut" : String::format("%d%%", m_audio_volume);
-        painter.draw_text({16, 3, 24, 16}, volume_text, Gfx::Font::default_font(), Gfx::TextAlignment::TopLeft, palette().window_text());
+        if (m_show_percent) {
+            auto volume_text = m_audio_muted ? "mute" : String::format("%d%%", m_audio_volume);
+            painter.draw_text({ 16, 3, 24, 16 }, volume_text, Gfx::Font::default_fixed_width_font(), Gfx::TextAlignment::TopLeft, palette().window_text());
+        }
+    }
+
+    void open()
+    {
+        reposition_slider_window();
+        m_slider_window->show();
+    }
+
+    void close()
+    {
+        m_slider_window->hide();
     }
     }
 
 
     Gfx::Bitmap& choose_bitmap_from_volume()
     Gfx::Bitmap& choose_bitmap_from_volume()
@@ -103,15 +190,24 @@ private:
         ASSERT_NOT_REACHED();
         ASSERT_NOT_REACHED();
     }
     }
 
 
+    void reposition_slider_window() { m_slider_window->set_rect(window()->rect_in_menubar().x() - 20, 19, 50, 100); }
+
     struct VolumeBitmapPair {
     struct VolumeBitmapPair {
         int volume_threshold { 0 };
         int volume_threshold { 0 };
         RefPtr<Gfx::Bitmap> bitmap;
         RefPtr<Gfx::Bitmap> bitmap;
     };
     };
 
 
     NonnullRefPtr<Audio::ClientConnection> m_audio_client;
     NonnullRefPtr<Audio::ClientConnection> m_audio_client;
-    Vector<VolumeBitmapPair, 4> m_volume_level_bitmaps;
+    Vector<VolumeBitmapPair, 5> m_volume_level_bitmaps;
+    bool m_show_percent { false };
     bool m_audio_muted { false };
     bool m_audio_muted { false };
     int m_audio_volume { 100 };
     int m_audio_volume { 100 };
+
+    RefPtr<GUI::Slider> m_slider;
+    RefPtr<GUI::Window> m_slider_window;
+    RefPtr<GUI::CheckBox> m_mute_box;
+    RefPtr<GUI::CheckBox> m_percent_box;
+    RefPtr<GUI::Label> m_root_container;
 };
 };
 
 
 int main(int argc, char** argv)
 int main(int argc, char** argv)
@@ -132,7 +228,7 @@ int main(int argc, char** argv)
     window->set_has_alpha_channel(true);
     window->set_has_alpha_channel(true);
     window->set_title("Audio");
     window->set_title("Audio");
     window->set_window_type(GUI::WindowType::MenuApplet);
     window->set_window_type(GUI::WindowType::MenuApplet);
-    window->resize(42, 16);
+    window->resize(16, 16);
 
 
     window->set_main_widget<AudioWidget>();
     window->set_main_widget<AudioWidget>();
     window->show();
     window->show();