mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-03-21 17:48:28 -05:00
Wave 9: Form args, alpha move, search, extra slots, move editors
PKMEditor: - Form Argument control (IFormArgument, conditional NumericUpDown) - Alpha Mastered Move selector (PA8/Legends Arceus) - Move Shop editor button (IMoveShop8Mastery) - Tech Records editor button (ITechRecord) - Nickname font warning button SAV Editor: - Box search bar with species name filtering and slot dimming - Extra slots display in Other tab (Daycare, Fused, Ride, etc.) - Save slot info display (type, generation, checksum status) - Slot search opacity and highlight model support
This commit is contained in:
parent
b223d7b1c8
commit
f76c98bfc0
|
|
@ -24,6 +24,20 @@ public partial class SlotModel : ObservableObject
|
|||
[ObservableProperty]
|
||||
private bool _isEmpty = true;
|
||||
|
||||
/// <summary>Whether the slot matches the current search filter.</summary>
|
||||
[ObservableProperty]
|
||||
private bool _isHighlighted;
|
||||
|
||||
/// <summary>Whether a search filter is currently active.</summary>
|
||||
[ObservableProperty]
|
||||
private bool _isSearchActive;
|
||||
|
||||
/// <summary>Opacity to use when a search is active (1.0 if highlighted or no search, 0.3 if not matching).</summary>
|
||||
public double SearchOpacity => IsHighlighted ? 1.0 : (_isSearchActive ? 0.3 : 1.0);
|
||||
|
||||
partial void OnIsHighlightedChanged(bool value) => OnPropertyChanged(nameof(SearchOpacity));
|
||||
partial void OnIsSearchActiveChanged(bool value) => OnPropertyChanged(nameof(SearchOpacity));
|
||||
|
||||
/// <summary>The PKM entity backing this slot, if any.</summary>
|
||||
[ObservableProperty]
|
||||
private PKM? _entity;
|
||||
|
|
@ -38,6 +52,10 @@ public partial class SlotModel : ObservableObject
|
|||
? $"{SpeciesName.GetSpeciesNameGeneration(Entity.Species, 2, Entity.Format)} Lv.{Entity.CurrentLevel}"
|
||||
: "Empty";
|
||||
|
||||
/// <summary>Label describing the slot type (e.g. "Daycare", "Fused Kyurem").</summary>
|
||||
[ObservableProperty]
|
||||
private string _slotLabel = string.Empty;
|
||||
|
||||
partial void OnEntityChanged(PKM? value)
|
||||
{
|
||||
OnPropertyChanged(nameof(ShowdownText));
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using PKHeX.Avalonia.Converters;
|
||||
using PKHeX.Avalonia.ViewModels.Subforms;
|
||||
using PKHeX.Avalonia.Views.Subforms;
|
||||
using PKHeX.Core;
|
||||
using PKHeX.Drawing.PokeSprite.Avalonia;
|
||||
using SkiaSharp;
|
||||
|
|
@ -165,6 +167,19 @@ public partial class PKMEditorViewModel : ObservableObject
|
|||
[ObservableProperty] private bool _isShadow;
|
||||
[ObservableProperty] private bool _hasShadow;
|
||||
|
||||
// Form Argument
|
||||
[ObservableProperty] private uint _formArgument;
|
||||
[ObservableProperty] private bool _hasFormArgument;
|
||||
[ObservableProperty] private uint _formArgumentMax;
|
||||
|
||||
// Alpha Mastered Move (Gen 8a - Legends Arceus)
|
||||
[ObservableProperty] private ComboItem? _selectedAlphaMove;
|
||||
[ObservableProperty] private bool _hasAlphaMove;
|
||||
|
||||
// Move Shop / Tech Record visibility
|
||||
[ObservableProperty] private bool _hasMoveShop;
|
||||
[ObservableProperty] private bool _hasTechRecords;
|
||||
|
||||
// Gen-specific: Catch Rate (Gen 1)
|
||||
[ObservableProperty] private int _catchRate;
|
||||
[ObservableProperty] private bool _hasCatchRate;
|
||||
|
|
@ -950,6 +965,41 @@ public void PopulateFields(PKM pk)
|
|||
PokeStarFame = 0;
|
||||
}
|
||||
|
||||
// Form Argument
|
||||
if (pk is IFormArgument fa)
|
||||
{
|
||||
HasFormArgument = true;
|
||||
FormArgument = fa.FormArgument;
|
||||
FormArgumentMax = FormArgumentUtil.GetFormArgumentMax(pk.Species, pk.Form, pk.Context);
|
||||
if (FormArgumentMax == 0)
|
||||
FormArgumentMax = 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
HasFormArgument = false;
|
||||
FormArgument = 0;
|
||||
FormArgumentMax = 255;
|
||||
}
|
||||
|
||||
// Alpha Mastered Move (Legends Arceus)
|
||||
if (pk is PA8 pa8)
|
||||
{
|
||||
HasAlphaMove = true;
|
||||
var alphaMoveId = pa8.AlphaMove;
|
||||
SelectedAlphaMove = MoveList.FirstOrDefault(m => m.Value == alphaMoveId);
|
||||
}
|
||||
else
|
||||
{
|
||||
HasAlphaMove = false;
|
||||
SelectedAlphaMove = null;
|
||||
}
|
||||
|
||||
// Move Shop (Legends Arceus)
|
||||
HasMoveShop = pk is IMoveShop8Mastery;
|
||||
|
||||
// Tech Records (Gen 8+)
|
||||
HasTechRecords = pk is ITechRecord;
|
||||
|
||||
// Origin Mark indicator
|
||||
var gen = pk.Generation;
|
||||
HasOriginMark = gen >= 3;
|
||||
|
|
@ -1231,9 +1281,51 @@ public void PopulateFields(PKM pk)
|
|||
pb7Save.Mood = (byte)Math.Clamp(Mood7b, 0, 255);
|
||||
}
|
||||
|
||||
// Form Argument
|
||||
if (Entity is IFormArgument faSave)
|
||||
faSave.FormArgument = FormArgument;
|
||||
|
||||
// Alpha Mastered Move (Legends Arceus)
|
||||
if (Entity is PA8 pa8Save && SelectedAlphaMove is not null)
|
||||
pa8Save.AlphaMove = (ushort)SelectedAlphaMove.Value;
|
||||
|
||||
return Entity;
|
||||
}
|
||||
|
||||
// --- Move Shop / Tech Record editor commands ---
|
||||
|
||||
[RelayCommand]
|
||||
private async Task OpenMoveShop()
|
||||
{
|
||||
if (Entity is not IMoveShop8Mastery master || Entity is not IMoveShop8 shop) return;
|
||||
try
|
||||
{
|
||||
PreparePKM();
|
||||
var vm = new MoveShopEditorViewModel(shop, master, Entity);
|
||||
var view = new MoveShopEditorView { DataContext = vm };
|
||||
var mainWindow = (Application.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)?.MainWindow;
|
||||
if (mainWindow != null)
|
||||
await view.ShowDialog(mainWindow);
|
||||
}
|
||||
catch (Exception ex) { LegalityReport = $"Move Shop error: {ex.Message}"; }
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task OpenTechRecords()
|
||||
{
|
||||
if (Entity is not ITechRecord tr) return;
|
||||
try
|
||||
{
|
||||
PreparePKM();
|
||||
var vm = new TechRecordEditorViewModel(tr, Entity);
|
||||
var view = new TechRecordEditorView { DataContext = vm };
|
||||
var mainWindow = (Application.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)?.MainWindow;
|
||||
if (mainWindow != null)
|
||||
await view.ShowDialog(mainWindow);
|
||||
}
|
||||
catch (Exception ex) { LegalityReport = $"Tech Record error: {ex.Message}"; }
|
||||
}
|
||||
|
||||
// --- IV/EV quick-set commands ---
|
||||
|
||||
[RelayCommand]
|
||||
|
|
@ -1402,6 +1494,46 @@ private string GetNatureColor(int statIndex)
|
|||
};
|
||||
}
|
||||
|
||||
// --- Nickname warning ---
|
||||
|
||||
[RelayCommand]
|
||||
private void ShowNicknameWarning()
|
||||
{
|
||||
if (Entity is null) return;
|
||||
var nickname = Nickname ?? string.Empty;
|
||||
var species = Entity.Species;
|
||||
var lang = Entity.Language;
|
||||
var defaultName = SpeciesName.GetSpeciesNameGeneration(species, lang, Entity.Format);
|
||||
|
||||
// Check for non-ASCII characters that might not render in older games
|
||||
bool hasSpecialChars = false;
|
||||
foreach (var c in nickname)
|
||||
{
|
||||
if (c > 0x7E || c < 0x20)
|
||||
{
|
||||
hasSpecialChars = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(nickname))
|
||||
{
|
||||
LegalityReport = "Nickname is empty.";
|
||||
}
|
||||
else if (nickname == defaultName)
|
||||
{
|
||||
LegalityReport = $"Nickname matches default species name: '{defaultName}'.";
|
||||
}
|
||||
else if (hasSpecialChars)
|
||||
{
|
||||
LegalityReport = $"Nickname '{nickname}' contains special characters that may not render correctly in-game. Default name: '{defaultName}'.";
|
||||
}
|
||||
else
|
||||
{
|
||||
LegalityReport = $"Nickname '{nickname}' appears to use standard characters. Default name: '{defaultName}'.";
|
||||
}
|
||||
}
|
||||
|
||||
// --- Sprite context menu commands ---
|
||||
|
||||
[RelayCommand]
|
||||
|
|
|
|||
|
|
@ -127,6 +127,18 @@ public void Redo()
|
|||
[ObservableProperty]
|
||||
private Bitmap? _boxWallpaper;
|
||||
|
||||
// Box search/filter
|
||||
[ObservableProperty] private string _searchText = string.Empty;
|
||||
[ObservableProperty] private string _searchResultText = string.Empty;
|
||||
|
||||
// Extra slots (Other tab)
|
||||
public ObservableCollection<SlotModel> ExtraSlots { get; } = [];
|
||||
[ObservableProperty] private bool _hasExtraSlots;
|
||||
|
||||
// Save slot info
|
||||
[ObservableProperty] private string _saveSlotInfo = string.Empty;
|
||||
[ObservableProperty] private bool _hasSaveSlotInfo;
|
||||
|
||||
public ObservableCollection<SlotModel> BoxSlots { get; } = [];
|
||||
public ObservableCollection<SlotModel> PartySlots { get; } = [];
|
||||
public ObservableCollection<string> BoxNames { get; } = [];
|
||||
|
|
@ -181,6 +193,9 @@ public void LoadSaveFile(SaveFile sav)
|
|||
RefreshParty();
|
||||
UpdateToolVisibility(sav);
|
||||
RefreshDaycare(sav);
|
||||
RefreshExtraSlots(sav);
|
||||
RefreshSaveSlotInfo(sav);
|
||||
SearchText = string.Empty;
|
||||
}
|
||||
|
||||
private void UpdateToolVisibility(SaveFile sav)
|
||||
|
|
@ -455,6 +470,125 @@ private void RefreshDaycare(SaveFile sav)
|
|||
}
|
||||
}
|
||||
|
||||
#region Box Search
|
||||
|
||||
partial void OnSearchTextChanged(string value)
|
||||
{
|
||||
if (_sav is null) return;
|
||||
var searchLower = value.ToLowerInvariant().Trim();
|
||||
var isActive = !string.IsNullOrEmpty(searchLower);
|
||||
int count = 0;
|
||||
|
||||
foreach (var slot in BoxSlots)
|
||||
{
|
||||
slot.IsSearchActive = isActive;
|
||||
if (slot.Entity is null || slot.Entity.Species == 0)
|
||||
{
|
||||
slot.IsHighlighted = false;
|
||||
continue;
|
||||
}
|
||||
if (!isActive)
|
||||
{
|
||||
slot.IsHighlighted = false;
|
||||
continue;
|
||||
}
|
||||
var name = SpeciesName.GetSpeciesNameGeneration(slot.Entity.Species, 2, slot.Entity.Format).ToLowerInvariant();
|
||||
var matches = name.Contains(searchLower);
|
||||
slot.IsHighlighted = matches;
|
||||
if (matches) count++;
|
||||
}
|
||||
|
||||
SearchResultText = isActive ? $"{count} found" : string.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Extra Slots
|
||||
|
||||
private void RefreshExtraSlots(SaveFile sav)
|
||||
{
|
||||
ExtraSlots.Clear();
|
||||
try
|
||||
{
|
||||
var extras = sav.GetExtraSlots(true);
|
||||
if (extras.Count == 0)
|
||||
{
|
||||
HasExtraSlots = false;
|
||||
return;
|
||||
}
|
||||
|
||||
HasExtraSlots = true;
|
||||
foreach (var slotInfo in extras)
|
||||
{
|
||||
var pk = slotInfo.Read(sav);
|
||||
var model = new SlotModel
|
||||
{
|
||||
Slot = slotInfo.Slot,
|
||||
SlotLabel = GetSlotTypeLabel(slotInfo.Type, slotInfo.Slot),
|
||||
};
|
||||
model.Entity = pk;
|
||||
if (pk.Species == 0)
|
||||
{
|
||||
model.SetImage(SpriteUtil.Spriter.None);
|
||||
model.IsEmpty = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var sprite = pk.Sprite();
|
||||
model.SetImage(sprite);
|
||||
model.IsEmpty = false;
|
||||
}
|
||||
ExtraSlots.Add(model);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
HasExtraSlots = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetSlotTypeLabel(StorageSlotType type, int slot) => type switch
|
||||
{
|
||||
StorageSlotType.Daycare => $"Daycare #{slot + 1}",
|
||||
StorageSlotType.GTS => "GTS Upload",
|
||||
StorageSlotType.BattleBox => $"Battle Box #{slot + 1}",
|
||||
StorageSlotType.FusedKyurem => "Fused Kyurem",
|
||||
StorageSlotType.FusedNecrozmaS => "Fused Necrozma (Solgaleo)",
|
||||
StorageSlotType.FusedNecrozmaM => "Fused Necrozma (Lunala)",
|
||||
StorageSlotType.FusedCalyrex => "Fused Calyrex",
|
||||
StorageSlotType.Resort => $"Resort #{slot + 1}",
|
||||
StorageSlotType.Ride => "Ride Legend",
|
||||
StorageSlotType.BattleAgency => $"Battle Agency #{slot + 1}",
|
||||
StorageSlotType.SurpriseTrade => $"Surprise Trade #{slot + 1}",
|
||||
StorageSlotType.Underground => $"Underground #{slot + 1}",
|
||||
StorageSlotType.Scripted => $"Scripted #{slot + 1}",
|
||||
StorageSlotType.PGL => "PGL Upload",
|
||||
StorageSlotType.Pokéwalker => "Pokewalker",
|
||||
StorageSlotType.Shiny => $"Shiny Cache #{slot + 1}",
|
||||
_ => $"{type} #{slot + 1}",
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#region Save Slot Info
|
||||
|
||||
private void RefreshSaveSlotInfo(SaveFile sav)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine($"Type: {sav.GetType().Name}");
|
||||
sb.AppendLine($"Generation: {sav.Generation}");
|
||||
sb.AppendLine($"Version: {sav.Version}");
|
||||
sb.AppendLine($"Boxes: {sav.BoxCount} ({sav.BoxSlotCount} slots each)");
|
||||
if (sav.HasParty)
|
||||
sb.AppendLine($"Party: {sav.PartyCount} Pokemon");
|
||||
sb.AppendLine($"Checksums: {(sav.ChecksumsValid ? "Valid" : "Invalid")}");
|
||||
|
||||
SaveSlotInfo = sb.ToString().TrimEnd();
|
||||
HasSaveSlotInfo = true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Box Management (Sort / Clear)
|
||||
|
||||
[RelayCommand]
|
||||
|
|
|
|||
|
|
@ -69,7 +69,12 @@
|
|||
|
||||
<!-- Nickname -->
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Text="Nickname:" TextAlignment="Right" VerticalAlignment="Center" Margin="0,0,6,0" />
|
||||
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Nickname}" Height="25" Width="144" HorizontalAlignment="Left" />
|
||||
<StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<TextBox Text="{Binding Nickname}" Height="25" Width="144" />
|
||||
<Button Content="?" Command="{Binding ShowNicknameWarningCommand}"
|
||||
Width="20" Height="20" Padding="0" FontSize="10" Margin="2,0,0,0"
|
||||
ToolTip.Tip="Check nickname font compatibility" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- EXP + Level -->
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Text="EXP:" TextAlignment="Right" VerticalAlignment="Center" Margin="0,0,6,0" />
|
||||
|
|
@ -134,6 +139,12 @@
|
|||
<!-- N's Sparkle (Gen 5) -->
|
||||
<CheckBox Grid.Row="14" Grid.Column="1" Content="N's Sparkle" IsChecked="{Binding NSparkle}"
|
||||
IsVisible="{Binding HasNSparkle}" VerticalAlignment="Center" />
|
||||
|
||||
<!-- Form Argument -->
|
||||
<TextBlock Grid.Row="15" Grid.Column="0" Text="Form Arg:" TextAlignment="Right" VerticalAlignment="Center" Margin="0,0,6,0"
|
||||
IsVisible="{Binding HasFormArgument}" />
|
||||
<NumericUpDown Grid.Row="15" Grid.Column="1" Value="{Binding FormArgument}" Minimum="0" Maximum="{Binding FormArgumentMax}" Height="25" Width="80" HorizontalAlignment="Left"
|
||||
IsVisible="{Binding HasFormArgument}" />
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
|
|
@ -349,33 +360,50 @@
|
|||
<TextBlock Text="Moves" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</TabItem.Header>
|
||||
<Grid Margin="8" RowDefinitions="27,27,27,27,27" ColumnDefinitions="52,*,18">
|
||||
<TextBlock Grid.Row="0" Grid.ColumnSpan="3" Text="Current Moves" FontWeight="SemiBold" VerticalAlignment="Center" />
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="Move 1:" VerticalAlignment="Center" />
|
||||
<ComboBox Grid.Row="1" Grid.Column="1" ItemsSource="{Binding MoveList}" SelectedItem="{Binding SelectedMove1}"
|
||||
DisplayMemberBinding="{Binding Text, DataType=core:ComboItem}" Height="25" />
|
||||
<TextBlock Grid.Row="1" Grid.Column="2" Text="!" Foreground="Red" FontWeight="Bold"
|
||||
IsVisible="{Binding !Move1Legal}" VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
ToolTip.Tip="Illegal move" />
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Text="Move 2:" VerticalAlignment="Center" />
|
||||
<ComboBox Grid.Row="2" Grid.Column="1" ItemsSource="{Binding MoveList}" SelectedItem="{Binding SelectedMove2}"
|
||||
DisplayMemberBinding="{Binding Text, DataType=core:ComboItem}" Height="25" />
|
||||
<TextBlock Grid.Row="2" Grid.Column="2" Text="!" Foreground="Red" FontWeight="Bold"
|
||||
IsVisible="{Binding !Move2Legal}" VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
ToolTip.Tip="Illegal move" />
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Text="Move 3:" VerticalAlignment="Center" />
|
||||
<ComboBox Grid.Row="3" Grid.Column="1" ItemsSource="{Binding MoveList}" SelectedItem="{Binding SelectedMove3}"
|
||||
DisplayMemberBinding="{Binding Text, DataType=core:ComboItem}" Height="25" />
|
||||
<TextBlock Grid.Row="3" Grid.Column="2" Text="!" Foreground="Red" FontWeight="Bold"
|
||||
IsVisible="{Binding !Move3Legal}" VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
ToolTip.Tip="Illegal move" />
|
||||
<TextBlock Grid.Row="4" Grid.Column="0" Text="Move 4:" VerticalAlignment="Center" />
|
||||
<ComboBox Grid.Row="4" Grid.Column="1" ItemsSource="{Binding MoveList}" SelectedItem="{Binding SelectedMove4}"
|
||||
DisplayMemberBinding="{Binding Text, DataType=core:ComboItem}" Height="25" />
|
||||
<TextBlock Grid.Row="4" Grid.Column="2" Text="!" Foreground="Red" FontWeight="Bold"
|
||||
IsVisible="{Binding !Move4Legal}" VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
ToolTip.Tip="Illegal move" />
|
||||
</Grid>
|
||||
<StackPanel Margin="8" Spacing="4">
|
||||
<Grid RowDefinitions="27,27,27,27,27" ColumnDefinitions="52,*,18">
|
||||
<TextBlock Grid.Row="0" Grid.ColumnSpan="3" Text="Current Moves" FontWeight="SemiBold" VerticalAlignment="Center" />
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="Move 1:" VerticalAlignment="Center" />
|
||||
<ComboBox Grid.Row="1" Grid.Column="1" ItemsSource="{Binding MoveList}" SelectedItem="{Binding SelectedMove1}"
|
||||
DisplayMemberBinding="{Binding Text, DataType=core:ComboItem}" Height="25" />
|
||||
<TextBlock Grid.Row="1" Grid.Column="2" Text="!" Foreground="Red" FontWeight="Bold"
|
||||
IsVisible="{Binding !Move1Legal}" VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
ToolTip.Tip="Illegal move" />
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Text="Move 2:" VerticalAlignment="Center" />
|
||||
<ComboBox Grid.Row="2" Grid.Column="1" ItemsSource="{Binding MoveList}" SelectedItem="{Binding SelectedMove2}"
|
||||
DisplayMemberBinding="{Binding Text, DataType=core:ComboItem}" Height="25" />
|
||||
<TextBlock Grid.Row="2" Grid.Column="2" Text="!" Foreground="Red" FontWeight="Bold"
|
||||
IsVisible="{Binding !Move2Legal}" VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
ToolTip.Tip="Illegal move" />
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Text="Move 3:" VerticalAlignment="Center" />
|
||||
<ComboBox Grid.Row="3" Grid.Column="1" ItemsSource="{Binding MoveList}" SelectedItem="{Binding SelectedMove3}"
|
||||
DisplayMemberBinding="{Binding Text, DataType=core:ComboItem}" Height="25" />
|
||||
<TextBlock Grid.Row="3" Grid.Column="2" Text="!" Foreground="Red" FontWeight="Bold"
|
||||
IsVisible="{Binding !Move3Legal}" VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
ToolTip.Tip="Illegal move" />
|
||||
<TextBlock Grid.Row="4" Grid.Column="0" Text="Move 4:" VerticalAlignment="Center" />
|
||||
<ComboBox Grid.Row="4" Grid.Column="1" ItemsSource="{Binding MoveList}" SelectedItem="{Binding SelectedMove4}"
|
||||
DisplayMemberBinding="{Binding Text, DataType=core:ComboItem}" Height="25" />
|
||||
<TextBlock Grid.Row="4" Grid.Column="2" Text="!" Foreground="Red" FontWeight="Bold"
|
||||
IsVisible="{Binding !Move4Legal}" VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
ToolTip.Tip="Illegal move" />
|
||||
</Grid>
|
||||
|
||||
<!-- Alpha Mastered Move (Legends Arceus) -->
|
||||
<StackPanel IsVisible="{Binding HasAlphaMove}" Spacing="4" Margin="0,4,0,0">
|
||||
<TextBlock Text="Alpha Mastered Move" FontWeight="SemiBold" />
|
||||
<ComboBox ItemsSource="{Binding MoveList}" SelectedItem="{Binding SelectedAlphaMove}"
|
||||
DisplayMemberBinding="{Binding Text, DataType=core:ComboItem}" Height="25" Width="200" HorizontalAlignment="Left" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Move Shop / Tech Records buttons -->
|
||||
<StackPanel Orientation="Horizontal" Spacing="4" Margin="0,4,0,0">
|
||||
<Button Content="Move Shop" Command="{Binding OpenMoveShopCommand}" Padding="6,2" FontSize="10"
|
||||
IsVisible="{Binding HasMoveShop}" />
|
||||
<Button Content="Tech Records" Command="{Binding OpenTechRecordsCommand}" Padding="6,2" FontSize="10"
|
||||
IsVisible="{Binding HasTechRecords}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
<!-- Cosmetic Tab -->
|
||||
|
|
|
|||
|
|
@ -9,6 +9,13 @@
|
|||
<!-- Box Tab -->
|
||||
<TabItem Header="Box">
|
||||
<DockPanel Margin="2">
|
||||
<!-- Search bar -->
|
||||
<Grid DockPanel.Dock="Top" ColumnDefinitions="*,Auto" Margin="0,2,0,2"
|
||||
IsVisible="{Binding IsLoaded}">
|
||||
<TextBox Text="{Binding SearchText}" Watermark="Search species..." Height="24" FontSize="11" Margin="0,0,4,0" />
|
||||
<TextBlock Grid.Column="1" Text="{Binding SearchResultText}" FontSize="10" VerticalAlignment="Center" Opacity="0.7" />
|
||||
</Grid>
|
||||
|
||||
<!-- Box Navigation: [<<] ComboBox [>>] -->
|
||||
<Grid DockPanel.Dock="Top" ColumnDefinitions="30,*,30" Margin="0,2,0,4">
|
||||
<Button Grid.Column="0" Content="<<" Command="{Binding PreviousBoxCommand}"
|
||||
|
|
@ -88,12 +95,43 @@
|
|||
<TabItem Header="Other">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Margin="4" Spacing="4">
|
||||
<!-- Daycare -->
|
||||
<TextBlock Text="Daycare" FontWeight="SemiBold" FontSize="11" IsVisible="{Binding HasDaycare}" />
|
||||
<TextBlock Text="{Binding DaycareInfo}" FontSize="11" FontFamily="Consolas,monospace"
|
||||
IsVisible="{Binding HasDaycare}" />
|
||||
|
||||
<!-- Extra Slots (Fused, GTS, Battle Box, etc.) -->
|
||||
<Border Height="1" Background="#CCCCCC" Margin="0,4" IsVisible="{Binding HasExtraSlots}" />
|
||||
<TextBlock Text="Extra Slots" FontWeight="SemiBold" FontSize="11" IsVisible="{Binding HasExtraSlots}" />
|
||||
<ItemsControl ItemsSource="{Binding ExtraSlots}" IsVisible="{Binding HasExtraSlots}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Margin="0,1" Padding="2" CornerRadius="2"
|
||||
Background="#08000000">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<Image Source="{Binding Image}" Width="40" Height="30"
|
||||
RenderOptions.BitmapInterpolationMode="None"
|
||||
VerticalAlignment="Center" />
|
||||
<StackPanel VerticalAlignment="Center" Spacing="0">
|
||||
<TextBlock Text="{Binding SlotLabel}" FontSize="10" FontWeight="SemiBold" />
|
||||
<TextBlock Text="{Binding Summary}" FontSize="10" Opacity="0.7" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
<!-- Save Slot Info -->
|
||||
<Border Height="1" Background="#CCCCCC" Margin="0,4" IsVisible="{Binding HasSaveSlotInfo}" />
|
||||
<TextBlock Text="Save Info" FontWeight="SemiBold" FontSize="11" IsVisible="{Binding HasSaveSlotInfo}" />
|
||||
<TextBlock Text="{Binding SaveSlotInfo}" FontSize="10" FontFamily="Consolas,monospace"
|
||||
IsVisible="{Binding HasSaveSlotInfo}" />
|
||||
|
||||
<!-- Fallback -->
|
||||
<TextBlock Text="No additional slots available for this save type."
|
||||
FontSize="11" Opacity="0.6"
|
||||
IsVisible="{Binding !HasDaycare}" />
|
||||
IsVisible="{Binding !IsLoaded}" />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
BorderBrush="{DynamicResource SystemControlForegroundBaseLowBrush}"
|
||||
BorderThickness="1" CornerRadius="0"
|
||||
Cursor="Hand"
|
||||
Opacity="{Binding SearchOpacity}"
|
||||
DragDrop.AllowDrop="True"
|
||||
AutomationProperties.Name="{Binding Summary}">
|
||||
<ToolTip.Tip>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user