Skip to content

Commit

Permalink
v2 view scaler.
Browse files Browse the repository at this point in the history
  • Loading branch information
stakira committed Sep 23, 2021
1 parent b29ae4b commit 4900feb
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 47 deletions.
22 changes: 19 additions & 3 deletions OpenUtau.App/Controls/TrackHeader.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,30 @@
HorizontalAlignment="Stretch" HorizontalContentAlignment="Left"
Content="{Binding Singer}" Click="SingerButtonClicked">
<Button.ContextMenu>
<ContextMenu Classes="context" Name="SingersMenu" PlacementMode="Bottom" HorizontalOffset="-5"/>
<ContextMenu Classes="context" Name="SingersMenu" PlacementMode="Bottom" HorizontalOffset="-5" Items="{Binding SingerMenuItems}">
<ContextMenu.Styles>
<Style Selector="MenuItem">
<Setter Property="Header" Value="{Binding Header}"/>
<Setter Property="Command" Value="{Binding Command}"/>
<Setter Property="CommandParameter" Value="{Binding CommandParameter}"/>
</Style>
</ContextMenu.Styles>
</ContextMenu>
</Button.ContextMenu>
</Button>
<Button Grid.Row="1" Grid.Column="1" Margin="1" Padding="0" Height="16"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Left"
Content="{Binding Phonemizer}" Click="PhonemizerButtonClicked">
Content="{Binding PhonemizerTag}" Click="PhonemizerButtonClicked">
<Button.ContextMenu>
<ContextMenu Classes="context" Name="PhonemizersMenu" PlacementMode="Bottom" HorizontalOffset="-5"/>
<ContextMenu Classes="context" Name="PhonemizersMenu" PlacementMode="Bottom" HorizontalOffset="-5" Items="{Binding PhonemizerMenuItems}">
<ContextMenu.Styles>
<Style Selector="MenuItem">
<Setter Property="Header" Value="{Binding Header}"/>
<Setter Property="Command" Value="{Binding Command}"/>
<Setter Property="CommandParameter" Value="{Binding CommandParameter}"/>
</Style>
</ContextMenu.Styles>
</ContextMenu>
</Button.ContextMenu>
</Button>
<ToggleButton Grid.Row="0" Grid.Column="2" Margin="1" Padding="0" Height="16" HorizontalAlignment="Stretch" Content="M"/>
Expand Down
41 changes: 4 additions & 37 deletions OpenUtau.App/Controls/TrackHeader.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
Expand Down Expand Up @@ -38,8 +39,6 @@ public Point Offset {
private List<IDisposable> unbinds = new List<IDisposable>();

private UTrack track;
private ContextMenu singerMenu;
private ContextMenu phonemizerMenu;

public TrackHeader() {
InitializeComponent();
Expand Down Expand Up @@ -75,49 +74,17 @@ private void SetPosition() {
void SingerButtonClicked(object sender, RoutedEventArgs args) {
var singerMenu = this.FindControl<ContextMenu>("SingersMenu");
if (DocManager.Inst.Singers.Count > 0) {
singerMenu.Items = DocManager.Inst.Singers.Values.Select(singer => {
var item = new MenuItem() {
Header = singer.Name,
DataContext = singer,
};
item.Classes.Add("context");
item.Click += (o, e) => {
if (track.Singer != singer) {
DocManager.Inst.StartUndoGroup();
DocManager.Inst.ExecuteCmd(new TrackChangeSingerCommand(DocManager.Inst.Project, track, singer));
DocManager.Inst.EndUndoGroup();
}
(DataContext as TrackHeaderViewModel)?.ManuallyRaise();
singerMenu.Close();
};
return item;
});
(DataContext as TrackHeaderViewModel)!.RefreshSingers();
singerMenu.Open();
}
args.Handled = true;
}


void PhonemizerButtonClicked(object sender, RoutedEventArgs args) {
var phonemizerMenu = this.FindControl<ContextMenu>("PhonemizersMenu");
if (DocManager.Inst.Phonemizers.Length > 0) {
phonemizerMenu.Items = DocManager.Inst.Phonemizers.Select(phonemizer => {
var item = new MenuItem() {
Header = phonemizer.ToString(),
DataContext = phonemizer,
};
item.Classes.Add("context");
item.Click += (o, e) => {
if (track.Phonemizer.GetType() != phonemizer.GetType()) {
var newPhonemizer = Activator.CreateInstance(phonemizer.GetType()) as Phonemizer;
DocManager.Inst.StartUndoGroup();
DocManager.Inst.ExecuteCmd(new TrackChangePhonemizerCommand(DocManager.Inst.Project, track, newPhonemizer));
DocManager.Inst.EndUndoGroup();
}
(DataContext as TrackHeaderViewModel)?.ManuallyRaise();
phonemizerMenu.Close();
};
return item;
});
(DataContext as TrackHeaderViewModel)!.RefreshPhonemizers();
phonemizerMenu.Open();
}
args.Handled = true;
Expand Down
9 changes: 9 additions & 0 deletions OpenUtau.App/Controls/ViewScaler.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="20" d:DesignHeight="20"
x:Class="OpenUtau.App.Controls.ViewScaler">
<Path Name="Path" Width="16" Height="16" Stroke="Black" StrokeThickness="1.75"
StrokeLineCap="Flat" StrokeJoin="Miter"/>
</UserControl>
74 changes: 74 additions & 0 deletions OpenUtau.App/Controls/ViewScaler.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Shapes;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using ReactiveUI;

namespace OpenUtau.App.Controls {
public partial class ViewScaler : UserControl {
public static readonly DirectProperty<ViewScaler, double> MaxProperty =
AvaloniaProperty.RegisterDirect<ViewScaler, double>(
nameof(Max),
o => o.Max,
(o, v) => o.Max = v);
public static readonly DirectProperty<ViewScaler, double> MinProperty =
AvaloniaProperty.RegisterDirect<ViewScaler, double>(
nameof(Min),
o => o.Min,
(o, v) => o.Min = v);
public static readonly DirectProperty<ViewScaler, double> ValueProperty =
AvaloniaProperty.RegisterDirect<ViewScaler, double>(
nameof(Value),
o => o.Value,
(o, v) => o.Value = v);

public double Max {
get => max;
set => SetAndRaise(MaxProperty, ref max, value);
}
public double Min {
get => min;
set => SetAndRaise(MinProperty, ref min, value);
}
public double Value {
get => value_;
set => SetAndRaise(ValueProperty, ref value_, value);
}

private double max;
private double min;
private double value_;

private Path path;

public ViewScaler() {
InitializeComponent();
path = this.FindControl<Path>("Path");
}

private void InitializeComponent() {
AvaloniaXamlLoader.Load(this);
}

protected override void OnPropertyChanged<T>(AvaloniaPropertyChangedEventArgs<T> change) {
base.OnPropertyChanged(change);
if (!change.IsEffectiveValueChange) {
return;
}
if (change.Property == MaxProperty || change.Property == MinProperty || change.Property == ValueProperty) {
UpdatePath();
}
}

private void UpdatePath() {
double offset = 7 * Math.Log(ViewConstants.TrackHeightMax / Value, 2) / Math.Log(ViewConstants.TrackHeightMax / ViewConstants.TrackHeightMin, 2);
double size = offset < 4 ? 4 : 8 - offset;
if (double.IsNaN(offset) || double.IsNaN(size) ||
double.IsInfinity(offset) || double.IsInfinity(size)) return;
path.Data = Geometry.Parse(FormattableString.Invariant(
$"M {8 - size} {offset + size} L 8 {offset} L {8 + size} {offset + size} M {8 - size} {16 - size - offset} L 8 {16 - offset} L {8 + size} {16 - size - offset}"));
}
}
}
11 changes: 11 additions & 0 deletions OpenUtau.App/ViewModels/MenuItemViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Collections.Generic;
using System.Windows.Input;

namespace OpenUtau.App.ViewModels {
public class MenuItemViewModel {
public string? Header { get; set; }
public ICommand? Command { get; set; }
public object? CommandParameter { get; set; }
public IList<MenuItemViewModel>? Items { get; set; }
}
}
49 changes: 45 additions & 4 deletions OpenUtau.App/ViewModels/TrackHeaderViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using OpenUtau.Core;
using OpenUtau.Core.Ustx;
using ReactiveUI;
Expand All @@ -9,8 +11,11 @@ public class TrackHeaderViewModel : ViewModelBase {
public int TrackNo => track.TrackNo;
public USinger Singer => track.Singer;
public Phonemizer Phonemizer => track.Phonemizer;
public IEnumerable<USinger> Singers => DocManager.Inst.SingersOrdered;
public IEnumerable<Phonemizer> Phonemizers => DocManager.Inst.Phonemizers;
public string PhonemizerTag => track.Phonemizer.Tag;
public IReadOnlyList<MenuItemViewModel> SingerMenuItems { get; set; }
public ReactiveCommand<USinger, Unit> SelectSingerCommand { get; }
public IReadOnlyList<MenuItemViewModel> PhonemizerMenuItems { get; set; }
public ReactiveCommand<Phonemizer, Unit> SelectPhonemizerCommand { get; }

private readonly UTrack track;

Expand All @@ -19,14 +24,50 @@ public TrackHeaderViewModel() {

public TrackHeaderViewModel(UTrack track) {
this.track = track;
SelectSingerCommand = ReactiveCommand.Create<USinger>(singer => {
if (track.Singer != singer) {
DocManager.Inst.StartUndoGroup();
DocManager.Inst.ExecuteCmd(new TrackChangeSingerCommand(DocManager.Inst.Project, track, singer));
DocManager.Inst.EndUndoGroup();
}
this.RaisePropertyChanged(nameof(Singer));
});
SelectPhonemizerCommand = ReactiveCommand.Create<Phonemizer>(phonemizer => {
if (track.Phonemizer.GetType() != phonemizer.GetType()) {
var newPhonemizer = Activator.CreateInstance(phonemizer.GetType()) as Phonemizer;
DocManager.Inst.StartUndoGroup();
DocManager.Inst.ExecuteCmd(new TrackChangePhonemizerCommand(DocManager.Inst.Project, track, newPhonemizer));
DocManager.Inst.EndUndoGroup();
}
this.RaisePropertyChanged(nameof(Phonemizer));
this.RaisePropertyChanged(nameof(PhonemizerTag));
});
}

public void RefreshSingers() {
SingerMenuItems = DocManager.Inst.Singers.Values.Select(singer => new MenuItemViewModel() {
Header = singer.Name,
Command = SelectSingerCommand,
CommandParameter = singer,
}).ToArray();
this.RaisePropertyChanged(nameof(SingerMenuItems));
}

public void RefreshPhonemizers() {
PhonemizerMenuItems = DocManager.Inst.Phonemizers.Select(phonemizer => new MenuItemViewModel() {
Header = phonemizer.ToString(),
Command = SelectPhonemizerCommand,
CommandParameter = phonemizer,
}).ToArray();
this.RaisePropertyChanged(nameof(PhonemizerMenuItems));
}

public void ManuallyRaise() {
this.RaisePropertyChanged(nameof(Singer));
this.RaisePropertyChanged(nameof(Phonemizer));
this.RaisePropertyChanged(nameof(PhonemizerTag));
}


public void Remove() {
DocManager.Inst.StartUndoGroup();
DocManager.Inst.ExecuteCmd(new RemoveTrackCommand(DocManager.Inst.Project, track));
Expand Down
2 changes: 2 additions & 0 deletions OpenUtau.App/Views/ExpressionsDialog.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ private void ApplyButtonClicked(object sender, RoutedEventArgs _) {
(DataContext as ExpressionsViewModel)?.Apply();
Close();
} catch (ArgumentException e) {
MessageBox.Show(this, e.Message, "Error", MessageBox.MessageBoxButtons.Ok);
} catch (Exception e) {
MessageBox.Show(this, e.ToString(), "Error", MessageBox.MessageBoxButtons.Ok);
}
}
Expand Down
6 changes: 3 additions & 3 deletions OpenUtau.App/Views/MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<MenuItem Header="{DynamicResource menu.file.exportust}"/>
</MenuItem>
<MenuItem Header="{DynamicResource menu.tools}">
<MenuItem Header="{StaticResource menu.tools.project.expressions}"/>
<MenuItem Header="{StaticResource menu.tools.project.expressions}" Click="OnMenuExpressionss"/>
<MenuItem Header="{DynamicResource menu.tools.singers}" Click="OnMenuSingers"/>
<MenuItem Header="{DynamicResource menu.tools.singer.install}" Click="OnMenuInstallSinger"/>
<MenuItem Header="{DynamicResource menu.tools.prefs}" Click="OnMenuPreferences"/>
Expand Down Expand Up @@ -122,8 +122,8 @@
<Border Grid.Row="1" Grid.RowSpan="2" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Transparent"
BoxShadow="inset 0 0 5 0.75 Gray" ClipToBounds="True" IsHitTestVisible="False">
</Border>
<Border Grid.Row="1" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="0" Height="24" Background="Wheat"
PointerWheelChanged="ZoomerPointerWheelChanged">
<Border Grid.Row="1" Grid.Column="2" Background="Transparent" HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="0" Height="24" PointerWheelChanged="ZoomerPointerWheelChanged">
<c:ViewScaler Grid.Row="1" Grid.Column="2" DataContext="{Binding TracksViewModel}" Value="{Binding TrackHeight}"/>
</Border>
<TextBlock Grid.Row="3" Grid.ColumnSpan="3" VerticalAlignment="Center" HorizontalAlignment="Stretch" Height="20" Text="{Binding ProgressText}"/>
<ProgressBar Grid.Row="4" Grid.ColumnSpan="3" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Value="{Binding Progress}"/>
Expand Down
7 changes: 7 additions & 0 deletions OpenUtau.App/Views/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,13 @@ async void OnMenuImportMidi(object sender, RoutedEventArgs args) {
}
}

void OnMenuExpressionss(object sender, RoutedEventArgs args) {
var dialog = new ExpressionsDialog() {
DataContext = new ExpressionsViewModel(),
};
dialog.ShowDialog(this);
}

void OnMenuSingers(object sender, RoutedEventArgs args) {
var dialog = new SingersDialog() {
DataContext = new SingersViewModel(),
Expand Down

0 comments on commit 4900feb

Please sign in to comment.