# HG changeset patch
# Node ID ac0547b56c2c
# Parent  f59a1ebb50ee
diff --git a/pidgin/prefs/pidginvvprefs.c b/pidgin/prefs/pidginvvprefs.c
--- a/pidgin/prefs/pidginvvprefs.c
+++ b/pidgin/prefs/pidginvvprefs.c
@@ -42,11 +42,12 @@ struct _PidginVVPrefs {
 	struct {
 		PidginPrefCombo input;
 		PidginPrefCombo output;
-		GtkWidget *level;
-		GtkWidget *threshold_label;
+		GtkWidget *threshold_row;
 		GtkWidget *threshold;
 		GtkWidget *volume;
 		GtkWidget *test;
+		GtkWidget *level;
+		GtkWidget *drop;
 		GstElement *pipeline;
 	} voice;
 
@@ -61,6 +62,10 @@ struct _PidginVVPrefs {
 
 G_DEFINE_TYPE(PidginVVPrefs, pidgin_vv_prefs, ADW_TYPE_PREFERENCES_PAGE)
 
+/* Keep in sync with voice.level's GtkLevelBar::max-value in the
+ * pidgin/resources/Prefs.vv.ui builder file. */
+#define MAX_AUDIO_LEVEL (19.0)
+
 /******************************************************************************
  * Helpers
  *****************************************************************************/
@@ -181,21 +186,23 @@ gst_bus_cb(GstBus *bus, GstMessage *msg,
 		if (purple_strequal(name, "level")) {
 			gdouble percent;
 			gdouble threshold;
+			gboolean drop;
 			GstElement *valve;
 
 			percent = gst_msg_db_to_percent(msg, "rms");
-			gtk_progress_bar_set_fraction(
-			        GTK_PROGRESS_BAR(prefs->voice.level), percent);
+			gtk_level_bar_set_value(GTK_LEVEL_BAR(prefs->voice.level),
+			                        percent * MAX_AUDIO_LEVEL);
 
 			percent = gst_msg_db_to_percent(msg, "decay");
 			threshold = gtk_range_get_value(GTK_RANGE(
 			                    prefs->voice.threshold)) /
 			            100.0;
+			drop = percent < threshold;
+
 			valve = gst_bin_get_by_name(GST_BIN(GST_ELEMENT_PARENT(src)), "valve");
-			g_object_set(valve, "drop", (percent < threshold), NULL);
-			g_object_set(prefs->voice.level, "text",
-			             (percent < threshold) ? _("DROP") : " ",
-			             NULL);
+			g_object_set(valve, "drop", drop, NULL);
+			gtk_label_set_text(GTK_LABEL(prefs->voice.drop),
+			                   drop ? _("DROP") : "");
 		}
 
 		g_free(name);
@@ -235,7 +242,6 @@ toggle_voice_test_cb(GtkToggleButton *te
 	PidginVVPrefs *prefs = PIDGIN_VV_PREFS(data);
 
 	if (gtk_toggle_button_get_active(test)) {
-		gtk_widget_set_sensitive(prefs->voice.level, TRUE);
 		enable_voice_test(prefs);
 
 		g_signal_connect(prefs->voice.volume, "value-changed",
@@ -243,9 +249,8 @@ toggle_voice_test_cb(GtkToggleButton *te
 		g_signal_connect(test, "destroy",
 		                 G_CALLBACK(voice_test_destroy_cb), prefs);
 	} else {
-		gtk_progress_bar_set_fraction(
-		        GTK_PROGRESS_BAR(prefs->voice.level), 0.0);
-		gtk_widget_set_sensitive(prefs->voice.level, FALSE);
+		gtk_level_bar_set_value(GTK_LEVEL_BAR(prefs->voice.level), 0.0);
+		gtk_label_set_text(GTK_LABEL(prefs->voice.drop), "");
 		g_object_disconnect(prefs->voice.volume,
 		                    "any-signal::value-changed",
 		                    G_CALLBACK(on_volume_change_cb), prefs, NULL);
@@ -271,9 +276,14 @@ threshold_value_changed_cb(GtkScale *sca
 
 	value = (int)gtk_range_get_value(GTK_RANGE(scale));
 	tmp = g_strdup_printf(_("Silence threshold: %d%%"), value);
-	gtk_label_set_label(GTK_LABEL(prefs->voice.threshold_label), tmp);
+	adw_preferences_row_set_title(ADW_PREFERENCES_ROW(prefs->voice.threshold_row),
+	                              tmp);
 	g_free(tmp);
 
+	gtk_level_bar_add_offset_value(GTK_LEVEL_BAR(prefs->voice.level),
+	                               GTK_LEVEL_BAR_OFFSET_LOW,
+	                               value / 100.0 * MAX_AUDIO_LEVEL);
+
 	purple_prefs_set_int("/purple/media/audio/silence_threshold", value);
 }
 
@@ -287,9 +297,19 @@ bind_voice_test(PidginVVPrefs *prefs)
 
 	tmp = g_strdup_printf(_("Silence threshold: %d%%"),
 	                      purple_prefs_get_int("/purple/media/audio/silence_threshold"));
-	gtk_label_set_text(GTK_LABEL(prefs->voice.threshold_label), tmp);
+	adw_preferences_row_set_title(ADW_PREFERENCES_ROW(prefs->voice.threshold_row),
+	                              tmp);
 	g_free(tmp);
 
+	/* Move the default high levels to the end (low is set by
+	 * threshold_value_changed_cb when set below.) */
+	gtk_level_bar_add_offset_value(GTK_LEVEL_BAR(prefs->voice.level),
+	                               GTK_LEVEL_BAR_OFFSET_HIGH,
+	                               MAX_AUDIO_LEVEL);
+	gtk_level_bar_add_offset_value(GTK_LEVEL_BAR(prefs->voice.level),
+	                               GTK_LEVEL_BAR_OFFSET_FULL,
+	                               MAX_AUDIO_LEVEL);
+
 	gtk_range_set_value(GTK_RANGE(prefs->voice.threshold),
 			purple_prefs_get_int("/purple/media/audio/silence_threshold"));
 }
@@ -493,12 +513,14 @@ pidgin_vv_prefs_class_init(PidginVVPrefs
 	gtk_widget_class_bind_template_child(widget_class, PidginVVPrefs,
 	                                     voice.volume);
 	gtk_widget_class_bind_template_child(widget_class, PidginVVPrefs,
-	                                     voice.threshold_label);
+	                                     voice.threshold_row);
 	gtk_widget_class_bind_template_child(widget_class, PidginVVPrefs,
 	                                     voice.threshold);
 	gtk_widget_class_bind_template_child(widget_class, PidginVVPrefs,
 	                                     voice.level);
 	gtk_widget_class_bind_template_child(widget_class, PidginVVPrefs,
+	                                     voice.drop);
+	gtk_widget_class_bind_template_child(widget_class, PidginVVPrefs,
 	                                     voice.test);
 	gtk_widget_class_bind_template_callback(widget_class, volume_changed_cb);
 	gtk_widget_class_bind_template_callback(widget_class,
diff --git a/pidgin/resources/Prefs/vv.ui b/pidgin/resources/Prefs/vv.ui
--- a/pidgin/resources/Prefs/vv.ui
+++ b/pidgin/resources/Prefs/vv.ui
@@ -70,128 +70,114 @@ along with this program; if not, see <ht
       <object class="AdwPreferencesGroup">
         <property name="title" translatable="1">Audio</property>
         <child>
-          <object class="GtkBox">
-            <property name="margin-start">12</property>
-            <property name="orientation">vertical</property>
-            <property name="spacing">6</property>
+          <object class="AdwActionRow">
+            <property name="activatable-widget">voice.input.combo</property>
+            <property name="title" translatable="1" context="Input for Audio">Input Device</property>
             <child>
-              <object class="GtkFrame">
-                <property name="child">
-                  <object class="GtkBox">
-                    <property name="margin-start">12</property>
-                    <property name="spacing">6</property>
-                    <child>
-                      <object class="GtkLabel" id="label1">
-                        <property name="label" translatable="1" context="Device for Audio Input">Device</property>
-                        <property name="xalign">0</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkComboBox" id="voice.input.combo">
-                        <property name="id-column">1</property>
-                        <property name="model">voice.input.store</property>
-                        <child>
-                          <object class="GtkCellRendererText"/>
-                          <attributes>
-                            <attribute name="text">0</attribute>
-                          </attributes>
-                        </child>
-                      </object>
-                    </child>
-                  </object>
-                </property>
-                <child type="label">
-                  <object class="GtkLabel">
-                    <property name="label" translatable="1" context="Input for Audio">Input</property>
-                    <attributes>
-                      <attribute name="weight" value="bold"></attribute>
-                    </attributes>
-                  </object>
+              <object class="GtkComboBox" id="voice.input.combo">
+                <property name="id-column">1</property>
+                <property name="model">voice.input.store</property>
+                <property name="valign">center</property>
+                <child>
+                  <object class="GtkCellRendererText"/>
+                  <attributes>
+                    <attribute name="text">0</attribute>
+                  </attributes>
                 </child>
               </object>
             </child>
+          </object>
+        </child>
+        <child>
+          <object class="AdwActionRow">
+            <property name="activatable-widget">voice.output.combo</property>
+            <property name="title" translatable="1" context="Device for Audio Output">Output Device</property>
             <child>
-              <object class="GtkFrame">
-                <property name="child">
-                  <object class="GtkBox">
-                    <property name="margin-start">12</property>
-                    <property name="spacing">6</property>
-                    <child>
-                      <object class="GtkLabel" id="label2">
-                        <property name="label" translatable="1" context="Device for Audio Output">Device</property>
-                        <property name="xalign">0</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkComboBox" id="voice.output.combo">
-                        <property name="id-column">1</property>
-                        <property name="model">voice.output.store</property>
-                        <child>
-                          <object class="GtkCellRendererText"/>
-                          <attributes>
-                            <attribute name="text">0</attribute>
-                          </attributes>
-                        </child>
-                      </object>
-                    </child>
-                  </object>
-                </property>
-                <child type="label">
-                  <object class="GtkLabel">
-                    <property name="label" translatable="1" context="Output for Audio">Output</property>
-                    <attributes>
-                      <attribute name="weight" value="bold"></attribute>
-                    </attributes>
-                  </object>
+              <object class="GtkComboBox" id="voice.output.combo">
+                <property name="id-column">1</property>
+                <property name="model">voice.output.store</property>
+                <property name="valign">center</property>
+                <child>
+                  <object class="GtkCellRendererText"/>
+                  <attributes>
+                    <attribute name="text">0</attribute>
+                  </attributes>
                 </child>
               </object>
             </child>
+          </object>
+        </child>
+        <child>
+          <object class="AdwActionRow">
+            <property name="activatable-widget">voice.volume</property>
+            <property name="title" translatable="1">Volume</property>
             <child>
-              <object class="GtkBox">
-                <property name="spacing">6</property>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="label" translatable="1">Volume:</property>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkVolumeButton" id="voice.volume">
-                    <property name="focusable">1</property>
-                    <property name="focus-on-click">0</property>
-                    <property name="receives-default">1</property>
-                    <property name="orientation">vertical</property>
-                    <property name="adjustment">adjustment2</property>
-                    <signal name="value-changed" handler="volume_changed_cb" swapped="no"/>
-                  </object>
-                </child>
+              <object class="GtkVolumeButton" id="voice.volume">
+                <property name="focusable">1</property>
+                <property name="focus-on-click">0</property>
+                <property name="receives-default">1</property>
+                <property name="orientation">vertical</property>
+                <property name="valign">center</property>
+                <property name="adjustment">adjustment2</property>
+                <signal name="value-changed" handler="volume_changed_cb" swapped="no"/>
               </object>
             </child>
-            <child>
-              <object class="GtkLabel" id="voice.threshold_label">
-                <property name="label" translatable="1">Silence threshold:</property>
-                <property name="xalign">0</property>
-              </object>
-            </child>
+          </object>
+        </child>
+        <child>
+          <object class="AdwActionRow" id="voice.threshold_row">
+            <property name="activatable-widget">voice.threshold</property>
+            <property name="title" translatable="1">Silence threshold</property>
             <child>
               <object class="GtkScale" id="voice.threshold">
                 <property name="focusable">1</property>
+                <property name="hexpand">1</property>
+                <property name="valign">center</property>
                 <property name="adjustment">adjustment1</property>
                 <property name="round-digits">0</property>
                 <property name="digits">0</property>
                 <signal name="value-changed" handler="threshold_value_changed_cb" object="PidginVVPrefs" swapped="no"/>
               </object>
             </child>
+          </object>
+        </child>
+        <child>
+          <object class="AdwPreferencesRow">
+            <property name="margin-bottom">12</property>
+            <property name="margin-end">12</property>
+            <property name="margin-start">12</property>
+            <property name="margin-top">12</property>
             <child>
-              <object class="GtkToggleButton" id="voice.test">
-                <property name="label" translatable="1">Test Audio</property>
-                <property name="focusable">1</property>
-                <property name="receives-default">1</property>
-                <signal name="toggled" handler="toggle_voice_test_cb" object="PidginVVPrefs" swapped="no"/>
-              </object>
-            </child>
-            <child>
-              <object class="GtkProgressBar" id="voice.level">
-                <property name="sensitive">0</property>
+              <object class="GtkBox">
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkToggleButton" id="voice.test">
+                    <property name="label" translatable="1">Test Audio</property>
+                    <property name="focusable">1</property>
+                    <property name="receives-default">1</property>
+                    <signal name="toggled" handler="toggle_voice_test_cb" object="PidginVVPrefs" swapped="no"/>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkBox">
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLevelBar" id="voice.level">
+                        <property name="hexpand">1</property>
+                        <!-- Keep this maximum in sync with MAX_AUDIO_LEVEL in
+                             pidgin/prefs/pidginvvprefs.c -->
+                        <property name="max-value">19</property>
+                        <property name="mode">discrete</property>
+                        <property name="valign">center</property>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="voice.drop">
+                      </object>
+                    </child>
+                  </object>
+                </child>
               </object>
             </child>
           </object>
@@ -202,98 +188,68 @@ along with this program; if not, see <ht
       <object class="AdwPreferencesGroup">
         <property name="title" translatable="1">Video</property>
         <child>
-          <object class="GtkBox">
-            <property name="margin-start">12</property>
-            <property name="orientation">vertical</property>
-            <property name="spacing">6</property>
+          <object class="AdwActionRow">
+            <property name="activatable-widget">video.input.combo</property>
+            <property name="title" translatable="1" context="Device for Video Input">Input Device</property>
             <child>
-              <object class="GtkFrame">
-                <property name="child">
-                  <object class="GtkBox">
-                    <property name="margin-start">12</property>
-                    <property name="spacing">6</property>
-                    <child>
-                      <object class="GtkLabel" id="label3">
-                        <property name="label" translatable="1" context="Device for Video Input">Device</property>
-                        <property name="xalign">0</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkComboBox" id="video.input.combo">
-                        <property name="id-column">1</property>
-                        <property name="model">video.input.store</property>
-                        <child>
-                          <object class="GtkCellRendererText"/>
-                          <attributes>
-                            <attribute name="text">0</attribute>
-                          </attributes>
-                        </child>
-                      </object>
-                    </child>
-                  </object>
-                </property>
-                <child type="label">
-                  <object class="GtkLabel">
-                    <property name="label" translatable="1" context="Input for Video">Input</property>
-                    <attributes>
-                      <attribute name="weight" value="bold"></attribute>
-                    </attributes>
-                  </object>
+              <object class="GtkComboBox" id="video.input.combo">
+                <property name="id-column">1</property>
+                <property name="hexpand">1</property>
+                <property name="model">video.input.store</property>
+                <property name="valign">center</property>
+                <child>
+                  <object class="GtkCellRendererText"/>
+                  <attributes>
+                    <attribute name="text">0</attribute>
+                  </attributes>
                 </child>
               </object>
             </child>
+          </object>
+        </child>
+        <child>
+          <object class="AdwActionRow">
+            <property name="activatable-widget">video.output.combo</property>
+            <property name="title" translatable="1" context="Device for Video Output">Output Device</property>
             <child>
-              <object class="GtkFrame">
-                <property name="child">
-                  <object class="GtkBox">
-                    <property name="margin-start">12</property>
-                    <property name="spacing">6</property>
-                    <child>
-                      <object class="GtkLabel" id="label4">
-                        <property name="label" translatable="1" context="Device for Video Output">Device</property>
-                        <property name="xalign">0</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkComboBox" id="video.output.combo">
-                        <property name="id-column">1</property>
-                        <property name="model">video.output.store</property>
-                        <child>
-                          <object class="GtkCellRendererText"/>
-                          <attributes>
-                            <attribute name="text">0</attribute>
-                          </attributes>
-                        </child>
-                      </object>
-                    </child>
-                  </object>
-                </property>
-                <child type="label">
-                  <object class="GtkLabel">
-                    <property name="label" translatable="1" context="Output for Video">Output</property>
-                    <attributes>
-                      <attribute name="weight" value="bold"></attribute>
-                    </attributes>
-                  </object>
+              <object class="GtkComboBox" id="video.output.combo">
+                <property name="hexpand">1</property>
+                <property name="id-column">1</property>
+                <property name="valign">center</property>
+                <property name="model">video.output.store</property>
+                <child>
+                  <object class="GtkCellRendererText"/>
+                  <attributes>
+                    <attribute name="text">0</attribute>
+                  </attributes>
                 </child>
               </object>
             </child>
+          </object>
+        </child>
+        <child>
+          <object class="AdwPreferencesRow">
+            <property name="margin-bottom">12</property>
+            <property name="margin-end">12</property>
+            <property name="margin-start">12</property>
+            <property name="margin-top">12</property>
             <child>
-              <object class="GtkAspectFrame" id="video.frame">
-                <property name="valign">fill</property>
-                <property name="vexpand">1</property>
-                <property name="ratio">1.33</property>
+              <object class="GtkBox">
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
                 <child>
-                  <placeholder/>
+                  <object class="GtkToggleButton" id="video.test">
+                    <property name="label" translatable="1">Test Video</property>
+                    <property name="focusable">1</property>
+                    <property name="receives-default">1</property>
+                    <signal name="toggled" handler="toggle_video_test_cb" object="PidginVVPrefs" swapped="no"/>
+                  </object>
                 </child>
-              </object>
-            </child>
-            <child>
-              <object class="GtkToggleButton" id="video.test">
-                <property name="label" translatable="1">Test Video</property>
-                <property name="focusable">1</property>
-                <property name="receives-default">1</property>
-                <signal name="toggled" handler="toggle_video_test_cb" object="PidginVVPrefs" swapped="no"/>
+                <child>
+                  <object class="GtkPicture" id="video.frame">
+                    <property name="keep-aspect-ratio">1</property>
+                  </object>
+                </child>
               </object>
             </child>
           </object>
@@ -301,12 +257,4 @@ along with this program; if not, see <ht
       </object>
     </child>
   </template>
-  <object class="GtkSizeGroup" id="sg">
-    <widgets>
-      <widget name="label1"/>
-      <widget name="label2"/>
-      <widget name="label3"/>
-      <widget name="label4"/>
-    </widgets>
-  </object>
 </interface>
