Mic audio UX: realtime read-only meter + mic picker
- Meter is a READ-ONLY realtime level display: fill = Math.Min(1, AudioLevel * MicVolume) (AudioLevel = live input from the future mixer, 0 with no input; MicVolume is gain on ambient noise). While the slider is dragged the bar previews the slider position (PreviewMouseLeftButtonDown/Up + LostMouseCapture -> SetVolumeAdjusting); on release it returns to the live level (bounces to 0 with no input). Clicking the meter does nothing. - MicVolume drives MicMuted (read-only, muted <=> volume 0): sliding to 0 flips the speaker to the red slashed mute icon, sliding up from 0 clears it; speaker button runs volume to 0 or restores the prior level (_volumeBeforeMute, default 0.8) and flashes the meter to the restored position for ~300ms (BeginVolumeFlash/EndVolumeFlash DispatcherTimer, cancelled if the slider is grabbed). - MIC label opens MicPickerDialog (WinRT audio-capture device enumeration, mirrors camera picker, no new packages); the chosen voice source name shows left-justified INSIDE the meter bar (fill at 75% opacity so text + ruler markings show through). - New files: Services/IMicrophoneEnumerator, MicrophoneDeviceInfo, WinRtMicrophoneEnumerator; ViewModels/MicPickerViewModel; MicPickerDialog. - Docs updated (ai.md, TASKS.md, Services/index.md, ViewModels/index.md); build 0 warnings, 65 tests passing
This commit is contained in:
+57
-8
@@ -268,7 +268,34 @@
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<!-- Slider -->
|
||||
<!-- Slider: slim and dimensional — gradient track, beveled fill, gloss-sphere
|
||||
thumb. The filled side sits on a 5px pill aligned with the track; the
|
||||
click target stays the full track height. -->
|
||||
<LinearGradientBrush x:Key="YtSliderTrackBrush" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Color="#0f1b33" Offset="0"/>
|
||||
<GradientStop Color="#283b60" Offset="1"/>
|
||||
</LinearGradientBrush>
|
||||
|
||||
<LinearGradientBrush x:Key="YtSliderFillBrush" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Color="#4fe097" Offset="0"/>
|
||||
<GradientStop Color="#2dbd7a" Offset="0.5"/>
|
||||
<GradientStop Color="#1a9e63" Offset="1"/>
|
||||
</LinearGradientBrush>
|
||||
|
||||
<RadialGradientBrush x:Key="YtSliderKnobBrush" Center="0.35,0.3" GradientOrigin="0.35,0.3">
|
||||
<GradientStop Color="#ffffff" Offset="0"/>
|
||||
<GradientStop Color="#d7f5e6" Offset="0.22"/>
|
||||
<GradientStop Color="#3ed588" Offset="0.72"/>
|
||||
<GradientStop Color="#137a4d" Offset="1"/>
|
||||
</RadialGradientBrush>
|
||||
|
||||
<RadialGradientBrush x:Key="YtSliderKnobHoverBrush" Center="0.35,0.3" GradientOrigin="0.35,0.3">
|
||||
<GradientStop Color="#ffffff" Offset="0"/>
|
||||
<GradientStop Color="#e6faef" Offset="0.22"/>
|
||||
<GradientStop Color="#57e9a1" Offset="0.72"/>
|
||||
<GradientStop Color="#1b9a63" Offset="1"/>
|
||||
</RadialGradientBrush>
|
||||
|
||||
<Style x:Key="YtSliderTrackButton" TargetType="RepeatButton">
|
||||
<Setter Property="Focusable" Value="False"/>
|
||||
<Setter Property="Template">
|
||||
@@ -280,19 +307,40 @@
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="YtSliderFillButton" TargetType="RepeatButton">
|
||||
<Setter Property="Focusable" Value="False"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="RepeatButton">
|
||||
<Grid>
|
||||
<Border Height="5" VerticalAlignment="Center"
|
||||
Background="{StaticResource YtSliderFillBrush}"
|
||||
BorderBrush="#0f7a4e" BorderThickness="1" CornerRadius="2.5"/>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="YtSliderThumb" TargetType="Thumb">
|
||||
<Setter Property="IsTabStop" Value="False"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Thumb">
|
||||
<Ellipse x:Name="Knob" Width="16" Height="16" Fill="#e94560"
|
||||
Stroke="#ff8fa3" StrokeThickness="1"/>
|
||||
<Grid Width="13" Height="13">
|
||||
<Ellipse x:Name="Knob" Fill="{StaticResource YtSliderKnobBrush}"
|
||||
Stroke="#0b1626" StrokeThickness="1">
|
||||
<Ellipse.Effect>
|
||||
<DropShadowEffect BlurRadius="3" ShadowDepth="1" Opacity="0.55"/>
|
||||
</Ellipse.Effect>
|
||||
</Ellipse>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="Knob" Property="Fill" Value="#ff5b78"/>
|
||||
<Setter TargetName="Knob" Property="Fill" Value="{StaticResource YtSliderKnobHoverBrush}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsDragging" Value="True">
|
||||
<Setter TargetName="Knob" Property="Fill" Value="#ff8fa3"/>
|
||||
<Setter TargetName="Knob" Property="Fill" Value="{StaticResource YtSliderKnobHoverBrush}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
@@ -307,12 +355,13 @@
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Slider">
|
||||
<Grid VerticalAlignment="Center">
|
||||
<Border Height="4" CornerRadius="2" Background="#2a3a5e"
|
||||
VerticalAlignment="Center"/>
|
||||
<Border Height="5" CornerRadius="2.5" VerticalAlignment="Center"
|
||||
Background="{StaticResource YtSliderTrackBrush}"
|
||||
BorderBrush="#0a1424" BorderThickness="1"/>
|
||||
<Track x:Name="PART_Track" Height="18">
|
||||
<Track.DecreaseRepeatButton>
|
||||
<RepeatButton Command="{x:Static Slider.DecreaseLarge}"
|
||||
Style="{StaticResource YtSliderTrackButton}" Tag="#e94560"/>
|
||||
Style="{StaticResource YtSliderFillButton}"/>
|
||||
</Track.DecreaseRepeatButton>
|
||||
<Track.IncreaseRepeatButton>
|
||||
<RepeatButton Command="{x:Static Slider.IncreaseLarge}"
|
||||
|
||||
Reference in New Issue
Block a user