Skip to content

Commit

Permalink
Merge pull request #977 from VladiStep/stringTabTitleFix
Browse files Browse the repository at this point in the history
String-related fixes and improvements.
  • Loading branch information
Grossley authored Jun 16, 2022
2 parents f38b9b4 + a532fec commit d21ba69
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 35 deletions.
8 changes: 4 additions & 4 deletions UndertaleModLib/UndertaleData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ public object this[Type resourceType]
{
get
{
if (!typeof(UndertaleNamedResource).IsAssignableFrom(resourceType))
throw new NotSupportedException($"\"{resourceType.FullName}\" is not a UndertaleNamedResource.");
if (!typeof(UndertaleResource).IsAssignableFrom(resourceType))
throw new NotSupportedException($"\"{resourceType.FullName}\" is not an UndertaleResource.");

var property = GetType().GetProperties().Where(x => x.PropertyType.Name == "IList`1")
.FirstOrDefault(x => x.PropertyType.GetGenericArguments()[0] == resourceType);
Expand All @@ -67,8 +67,8 @@ public object this[Type resourceType]
}
set
{
if (!typeof(UndertaleNamedResource).IsAssignableFrom(resourceType))
throw new NotSupportedException($"\"{resourceType.FullName}\" is not a UndertaleNamedResource.");
if (!typeof(UndertaleResource).IsAssignableFrom(resourceType))
throw new NotSupportedException($"\"{resourceType.FullName}\" is not an UndertaleResource.");

var property = GetType().GetProperties().Where(x => x.PropertyType.Name == "IList`1")
.FirstOrDefault(x => x.PropertyType.GetGenericArguments()[0] == resourceType);
Expand Down
4 changes: 4 additions & 0 deletions UndertaleModTool/Converters/StringTitleConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ namespace UndertaleModTool
public class StringTitleConverter : IValueConverter
{
public static readonly Regex NewLineRegex = new(@"\r\n?|\n", RegexOptions.Compiled);
public static StringTitleConverter Instance { get; } = new();

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is not string str)
return null;

if (str.Length == 0)
return "(empty string)";

if (str.Length > 256)
str = str[..256] + "...";
str = NewLineRegex.Replace(str, " ");
Expand Down
11 changes: 2 additions & 9 deletions UndertaleModTool/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -426,15 +426,8 @@
<TabControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:Tab}">
<StackPanel Orientation="Horizontal">
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource TabTitleConverter}" Mode="OneWay">
<Binding Mode="OneTime"/>
<Binding Path="OpenedObject" Mode="OneWay"/>
<!-- for notification only -->
<Binding Path="OpenedObject.Name.Content" Mode="OneWay"/>
</MultiBinding>
</TextBlock.Text>
<TextBlock Initialized="TabTitleText_Initialized" DataContextChanged="TabTitleText_DataContextChanged">
<!-- "TextBlock.Text" binding is set in code-behind -->
</TextBlock>
<Button Background="Transparent" Width="16" Height="16" BorderThickness="0" Margin="12,0,0,0"
Click="TabCloseButton_OnClick" MouseEnter="TabCloseButton_MouseEnter" MouseLeave="TabCloseButton_MouseLeave">
Expand Down
120 changes: 98 additions & 22 deletions UndertaleModTool/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,17 @@ public static string GetTitleForObject(object obj)
else if (obj is UndertaleString str)
{
string stringFirstLine = str.Content;
int stringLength = StringTitleConverter.NewLineRegex.Match(stringFirstLine).Index;
if (stringLength != -1)
stringFirstLine = stringFirstLine[..stringLength] + " ...";
if (stringFirstLine is not null)
{
if (stringFirstLine.Length == 0)
stringFirstLine = "(empty string)";
else
{
int stringLength = StringTitleConverter.NewLineRegex.Match(stringFirstLine).Index;
if (stringLength != 0)
stringFirstLine = stringFirstLine[..stringLength] + " ...";
}
}

title = "String - " + stringFirstLine;
}
Expand All @@ -167,8 +175,16 @@ public static string GetTitleForObject(object obj)
Debug.WriteLine($"Could not handle type {obj.GetType()}");
}

if (title.Length > 64)
title = title[..64] + "...";
if (title is not null)
{
// "\t" is displayed as 8 spaces.
// So, replace all "\t" with spaces,
// in order to properly shorten the title.
title = title.Replace("\t", " ");

if (title.Length > 64)
title = title[..64] + "...";
}

return title;
}
Expand All @@ -181,13 +197,15 @@ public override string ToString()
}
public class TabTitleConverter : IMultiValueConverter
{
public static TabTitleConverter Instance { get; } = new();

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values[0] is not Tab tab)
return null;

if (!tab.IsCustomTitle)
tab.TabTitle = Tab.GetTitleForObject(values[1]);
tab.TabTitle = Tab.GetTitleForObject(tab.OpenedObject);

return tab.TabTitle;
}
Expand Down Expand Up @@ -1710,10 +1728,17 @@ private void DeleteItem(UndertaleObject obj)
}
}
}
private void CopyItemName(UndertaleNamedResource namedRes)
private void CopyItemName(object obj)
{
if (namedRes.Name?.Content is not null)
Clipboard.SetText(namedRes.Name.Content);
string name = null;

if (obj is UndertaleNamedResource namedRes)
name = namedRes.Name?.Content;
else if (obj is UndertaleString str && str.Content?.Length > 0)
name = StringTitleConverter.Instance.Convert(str.Content, null, null, null) as string;

if (name is not null)
Clipboard.SetText(name);
else
this.ShowWarning("Item name is null.");
}
Expand Down Expand Up @@ -1798,8 +1823,7 @@ private void MenuItem_OpenInNewTab_Click(object sender, RoutedEventArgs e)
}
private void MenuItem_CopyName_Click(object sender, RoutedEventArgs e)
{
if (Highlighted is UndertaleNamedResource namedRes)
CopyItemName(namedRes);
CopyItemName(Highlighted);
}
private void MenuItem_Delete_Click(object sender, RoutedEventArgs e)
{
Expand Down Expand Up @@ -1894,6 +1918,8 @@ private void MenuItem_Add_Click(object sender, RoutedEventArgs e)
(obj as UndertaleNamedResource).Name = new UndertaleString(notDataNewName); // not Data.MakeString!
}
}
else if (obj is UndertaleString str)
str.Content = "string" + list.Count;
list.Add(obj);
UpdateTree();
HighlightObject(obj);
Expand Down Expand Up @@ -3026,8 +3052,11 @@ public void HighlightObject(object obj, bool silent = true)
UndertaleResource res = obj as UndertaleResource;
if (res is null)
{
if (!silent)
this.ShowWarning($"Can't highlight the object - it's null or isn't a UndertaleResource.");
string msg = $"Can't highlight the object - it's null or isn't an UndertaleResource.";
if (silent)
Debug.WriteLine(msg);
else
this.ShowWarning(msg);

return;
}
Expand All @@ -3053,16 +3082,22 @@ public void HighlightObject(object obj, bool silent = true)
}
catch (Exception ex)
{
if (!silent)
this.ShowWarning($"Can't highlight the object \"{objName}\".\nError - {ex.Message}");
string msg = $"Can't highlight the object \"{objName}\".\nError - {ex.Message}";
if (silent)
Debug.WriteLine(msg);
else
this.ShowWarning(msg);

return;
}

if (resListView is null)
{
if (!silent)
this.ShowWarning($"Can't highlight the object \"{objName}\" - element with object list not found.");
string msg = $"Can't highlight the object \"{objName}\" - element with object list not found.";
if (silent)
Debug.WriteLine(msg);
else
this.ShowWarning(msg);

return;
}
Expand Down Expand Up @@ -3561,6 +3596,52 @@ private void CloseOtherTabsMenuItem_Click(object sender, RoutedEventArgs e)
Tabs = new() { tab };
CurrentTabIndex = 0;
}

private void TabTitleText_Initialized(object sender, EventArgs e)
{
SetTabTitleBinding(sender, null);
}
private void TabTitleText_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
SetTabTitleBinding(sender, e.OldValue);
}
private void SetTabTitleBinding(object sender, object prevObj)
{
TextBlock textBlock = sender as TextBlock;
object obj = (textBlock.DataContext as Tab)?.OpenedObject;
if (obj is null || obj == DependencyProperty.UnsetValue)
return;

bool objNamed = obj is UndertaleNamedResource;
bool objString = obj is UndertaleString;

prevObj = (prevObj as Tab)?.OpenedObject;
if (prevObj is not null)
{
bool pObjNamed = prevObj is UndertaleNamedResource;
bool pObjString = prevObj is UndertaleString;

// if both objects have the same type (one of above)
// or both objects are not "UndertaleNamedResource",
// then there's no need for changing the binding
if (pObjNamed && objNamed || pObjString && objString || !(pObjNamed || objNamed))
return;
}

MultiBinding binding = new()
{
Converter = TabTitleConverter.Instance,
Mode = BindingMode.OneWay
};
binding.Bindings.Add(new Binding() { Mode = BindingMode.OneTime });

if (objNamed)
binding.Bindings.Add(new Binding("OpenedObject.Name.Content") { Mode = BindingMode.OneWay });
else if (objString)
binding.Bindings.Add(new Binding("OpenedObject.Content") { Mode = BindingMode.OneWay });

textBlock.SetBinding(TextBlock.TextProperty, binding);
}
}

public class GeneralInfoEditor
Expand Down Expand Up @@ -3602,11 +3683,6 @@ public class DescriptionView
public string Heading { get; private set; }
public string Description { get; private set; }

// Used only by the "TabTitleConverter" to prevent the following WPF binding warning:
// "Name property not found on object of type DescriptionView".
// (within "TabControl.ItemTemplate")
public UndertaleString Name { get; } = new();

public DescriptionView(string heading, string description)
{
Heading = heading;
Expand Down

0 comments on commit d21ba69

Please sign in to comment.