Skip to content

Commit

Permalink
Merge pull request #1384 from CaptainSticky/feature/item-view-context…
Browse files Browse the repository at this point in the history
…-menu

Added a context menu to item view with actions for the individual slot.
  • Loading branch information
StoiaCode authored Sep 13, 2024
2 parents 01c21fd + 275858f commit b5724ba
Show file tree
Hide file tree
Showing 8 changed files with 361 additions and 14 deletions.
59 changes: 59 additions & 0 deletions Anamnesis/Actor/Views/ItemView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,65 @@
<TextBlock Text="{Binding Item.Description}" Visibility="{Binding Item.Description, Converter={StaticResource StringHasContentToVisibility}}" />
</StackPanel>
</Grid.ToolTip>
<Grid.ContextMenu>
<ContextMenu>
<!-- Console Games Wiki -->
<MenuItem Click="OnOpenInConsoleGamesWikiClicked" Visibility="{Binding IsValidItemForFanSite, Converter={StaticResource B2V}}">
<MenuItem.Header>
<XivToolsWpf:TextBlock Key="Site_OpenInConsoleGamesWiki"/>
</MenuItem.Header>
<MenuItem.Icon>
<fa:IconImage Icon="ExternalLinkAlt" Foreground="{StaticResource PrimaryHueMidBrush}"/>
</MenuItem.Icon>
</MenuItem>
<!-- Gamer Escape -->
<MenuItem Click="OnOpenInGamerEscapeClicked" Visibility="{Binding IsValidItemForFanSite, Converter={StaticResource B2V}}">
<MenuItem.Header>
<XivToolsWpf:TextBlock Key="Site_OpenInGamerEscape"/>
</MenuItem.Header>
<MenuItem.Icon>
<fa:IconImage Icon="ExternalLinkAlt" Foreground="{StaticResource PrimaryHueMidBrush}"/>
</MenuItem.Icon>
</MenuItem>
<!-- Garland Tools -->
<MenuItem Click="OnOpenInGarlandToolsClicked" Visibility="{Binding IsValidItemForFanSite, Converter={StaticResource B2V}}">
<MenuItem.Header>
<XivToolsWpf:TextBlock Key="Site_OpenInGarlandTools"/>
</MenuItem.Header>
<MenuItem.Icon>
<fa:IconImage Icon="ExternalLinkAlt" Foreground="{StaticResource PrimaryHueMidBrush}"/>
</MenuItem.Icon>
</MenuItem>
<Separator Visibility="{Binding IsValidItemForFanSite, Converter={StaticResource B2V}}"/>
<!-- Copy Item Name -->
<MenuItem Click="OnCopyItemNameClicked" Visibility="{Binding IsValidItemForCopy, Converter={StaticResource B2V}}">
<MenuItem.Header>
<XivToolsWpf:TextBlock Key="Item_CopyName"/>
</MenuItem.Header>
<MenuItem.Icon>
<Image Source="{Binding Item.Icon, Converter={StaticResource Img}}"/>
</MenuItem.Icon>
</MenuItem>
<!-- Reset Slot -->
<MenuItem Click="OnResetSlotClicked">
<MenuItem.Header>
<XivToolsWpf:TextBlock Key="Item_ResetSlot"/>
</MenuItem.Header>
<MenuItem.Icon>
<fa:IconImage Icon="UndoAlt" Foreground="{StaticResource PrimaryHueMidBrush}"/>
</MenuItem.Icon>
</MenuItem>
<!-- Clear Slot -->
<MenuItem Click="OnClearSlotClicked">
<MenuItem.Header>
<XivToolsWpf:TextBlock Key="Item_ClearSlot"/>
</MenuItem.Header>
<MenuItem.Icon>
<fa:IconImage Icon="Circle" Foreground="{StaticResource PrimaryHueMidBrush}"/>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</Grid.ContextMenu>

</Grid>
</Button>
Expand Down
110 changes: 110 additions & 0 deletions Anamnesis/Actor/Views/ItemView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace Anamnesis.Actor.Views;

using System;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
Expand All @@ -16,6 +17,7 @@ namespace Anamnesis.Actor.Views;
using Anamnesis.Memory;
using Anamnesis.Services;
using Anamnesis.Styles.Drawers;
using Anamnesis.Utils;
using PropertyChanged;
using Serilog;
using XivToolsWpf;
Expand Down Expand Up @@ -121,6 +123,51 @@ public bool IsValidWeapon
}
}

public bool IsValidItemForFanSite
{
get
{
// Invalid if Item is null.
if (this.Item == null)
return false;

// Invalid if we're naked in some way other than Emperor's.
ushort[] invalidItems = { 0, 9901, 9903 };
if(invalidItems.Contains(this.Item.ModelBase))
return false;

// Invalid if row Id is 0, which would be the case if we have a
// set/subset combo which doesn't match an actual item.
if(this.Item.RowId == 0)
return false;

// Most items will have the None category. Shop items will be premium, and old items will be deprecated.
// If we aren't one of these, then invalid. CustomEquipment is for things like Forum Attire.
bool isNormalCategory = this.Item.Category.HasFlag(ItemCategories.None) ||
this.Item.Category.HasFlag(ItemCategories.Standard) ||
this.Item.Category.HasFlag(ItemCategories.Premium) ||
this.Item.Category.HasFlag(ItemCategories.Limited);
if (!isNormalCategory)
return false;

return true;
}
}

public bool IsValidItemForCopy
{
get
{
if (this.Item == null)
return false;

if(this.Item.ModelBase == 0)
return false;

return true;
}
}

private static void OnItemModelChanged(ItemView sender, IEquipmentItemMemory? value)
{
if (sender.ItemModel != null)
Expand All @@ -135,6 +182,69 @@ private static void OnItemModelChanged(ItemView sender, IEquipmentItemMemory? va
sender.OnViewModelPropertyChanged(null, null);
}

private void OnOpenInConsoleGamesWikiClicked(object sender, RoutedEventArgs e)
{
this.OpenItemInFanSiteUrl("https://ffxiv.consolegameswiki.com/wiki/" + this.Item?.Name.Replace(" ", "_"));
}

private void OnOpenInGamerEscapeClicked(object sender, RoutedEventArgs e)
{
this.OpenItemInFanSiteUrl("https://ffxiv.gamerescape.com/wiki/" + this.Item?.Name.Replace(" ", "_"));
}

private void OnOpenInGarlandToolsClicked(object sender, RoutedEventArgs e)
{
this.OpenItemInFanSiteUrl("https://www.garlandtools.org/db/#item/" + this.Item?.RowId);
}

private void OpenItemInFanSiteUrl(string url)
{
if (this.Item == null)
return;

if (this.Item.ModelBase == 0)
return;

UrlUtility.Open(url);
}

private async void OnCopyItemNameClicked(object sender, RoutedEventArgs e)
{
if (this.Item == null)
return;

if (this.Item.ModelBase == 0)
return;

try
{
await ClipboardUtility.CopyToClipboardAsync(this.Item.Name);
}
catch (Exception ex)
{
Log.Error(ex, "Error copying item name to clipboard after 3 attempts.");
}
}

private async void OnResetSlotClicked(object sender, RoutedEventArgs e)
{
if (this.Actor == null)
return;

if (this.Actor.Pinned == null)
return;

await this.Actor.Pinned.RestoreCharacterBackup(PinnedActor.BackupModes.Original, this.Slot);
}

private void OnClearSlotClicked(object sender, RoutedEventArgs e)
{
if (this.Actor?.CanRefresh != true)
return;

this.ItemModel?.Clear(this.Actor.IsHuman);
}

private void OnClick(object sender, RoutedEventArgs e)
{
if (this.Actor?.CanRefresh != true)
Expand Down
10 changes: 0 additions & 10 deletions Anamnesis/Data/Equipment.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
[
{
"Name": "Gleaners Attire",
"Id": "9217, 1",
"Slot": "Equipment"
},
{
"Name": "Gleaners Attire (Backpack)",
"Id": "9217, 2",
"Slot": "Body"
},
{
"Name": "Forum Member\u0027s Attire",
"Id": "9214, 1",
Expand Down
120 changes: 120 additions & 0 deletions Anamnesis/Data/ItemCategories.json
Original file line number Diff line number Diff line change
Expand Up @@ -8425,4 +8425,124 @@
"37480": "Limited",
// Common Makai Harrower's Longboots
"37481": "Limited",
// Wake Doctor's Mask
"38228": "Premium, Limited",
// Wake Doctor's White Coat
"38229": "Premium, Limited",
// Wake Doctor's Rubber Gloves
"38230": "Premium, Limited",
// Wake Doctor's Bottoms
"38231": "Premium, Limited",
// Wake Doctor's Shoes
"38232": "Premium, Limited",
// Tonberry Head
"38233": "Premium, Limited",
// Tonberry Body
"38234": "Premium, Limited",
// Tonberry Hands
"38235": "Premium, Limited",
// Tonberry Culottes
"38236": "Premium, Limited",
// Tonberry Boots
"38237": "Premium, Limited",
// Fat Cat Hood
"38238": "Premium",
// Fat Cat Loungewear
"38239": "Premium",
// Fat Cat Halfslops
"38240": "Premium",
// Fat Cat Slippers
"38241": "Premium",
// Fat Cat Shorts
"38242": "Premium",
// Far Northern Headpiece
"38248": "Premium",
// Far Northern Tunic
"38249": "Premium",
// Far Northern Felted Gloves
"38250": "Premium",
// Far Northern Bottoms
"38251": "Premium",
// Far Northern Boots
"38252": "Premium",
// Valentione Emissary's Hat
"38253": "Premium, Limited",
// Valentione Emissary's Jacket
"38254": "Premium, Limited",
// Valentione Emissary's Bottoms
"38255": "Premium, Limited",
// Valentione Emissary's Boots
"38256": "Premium, Limited",
// Valentione Emissary's Dress Hat
"38257": "Premium, Limited",
// Valentione Emissary's Ruffled Dress
"38258": "Premium, Limited",
// Valentione Emissary's Culottes
"38259": "Premium, Limited",
// Valentione Emissary's Dress Boots
"38260": "Premium, Limited",
// Phoenix Riser Helmet
"39245": "Premium, Limited",
// Phoenix Riser Suit
"39246": "Premium, Limited",
// Educand's Cap
"39295": "Premium",
// Educand's Jacket
"39296": "Premium",
// Educand's Slacks
"39297": "Premium",
// Educand's Shoes
"39298": "Premium",
// Educand's Sailor Top
"39299": "Premium",
// Educand's Sailor Skirt
"39300": "Premium",
// Educand's Loafers
"39301": "Premium",
// Magitek Ear Guards
"39303": "Premium",
// Magitek Jacket
"39304": "Premium",
// Magitek Fingerstalls
"39305": "Premium",
// Magitek Bottoms
"39306": "Premium",
// Magitek Shoes
"39307": "Premium",
// Seigneur's Beret
"40421": "Premium",
// Seigneur's Jerkin
"40422": "Premium",
// Seigneur's Gloves
"40423": "Premium",
// Seigneur's Breeches
"40424": "Premium",
// Seigneur's Longboots
"40425": "Premium",
// Iceheart Robe
"40448": "Premium",
// Iceheart Armlets
"40449": "Premium",
// Iceheart Bottoms
"40450": "Premium",
// Iceheart Thighboots
"40451": "Premium",
// Woodland Warden's Top
"41567": "Premium",
// Woodland Warden's Fingerstalls
"41568": "Premium",
// Woodland Warden's Breeches
"41569": "Premium",
// Woodland Warden's Longboots
"41570": "Premium",
// Woodland Warden's Skirt
"41571": "Premium",
// Crystarium Prodigy's Top
"41572": "Premium",
// Crystarium Prodigy's Fingerless Gloves
"41573": "Premium",
// Crystarium Prodigy's Hose
"41574": "Premium",
// Crystarium Prodigy's Thighboots
"41575": "Premium",
}
Loading

0 comments on commit b5724ba

Please sign in to comment.