mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-26 06:28:35 +01:00
Merge branch 'main' into release
# Conflicts: # build.cake
This commit is contained in:
commit
0fde5b7aa0
97 changed files with 1002 additions and 1108 deletions
8
.githooks/pre-push
Normal file
8
.githooks/pre-push
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'pre-push' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks').\n"; exit 2; }
|
||||||
|
git lfs pre-push "$@"
|
||||||
|
|
||||||
|
if ! git diff origin --name-status | grep -E -q "M\s+CHANGELOG.md"; then
|
||||||
|
echo "The changelog was not updated. Please document your changes in CHANGELOG.md before pushing."
|
||||||
|
exit 1
|
||||||
|
fi
|
11
.github/workflows/enforce-changelog.yml
vendored
Normal file
11
.github/workflows/enforce-changelog.yml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
on: pull_request
|
||||||
|
jobs:
|
||||||
|
enforce-changelog:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: dangoslen/changelog-enforcer@v3
|
||||||
|
with:
|
||||||
|
changeLogPath: CHANGELOG.md
|
||||||
|
missingUpdateErrorMessage: |
|
||||||
|
The changelog was not updated. Please document your changes in CHANGELOG.md.
|
||||||
|
Run `git config core.hooksPath .githooks` to enable a git hook that ensures you updated the changelog before pushing.
|
51
.github/workflows/main.yml
vendored
Normal file
51
.github/workflows/main.yml
vendored
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
build-publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: Setup .NET
|
||||||
|
uses: actions/setup-dotnet@v3
|
||||||
|
with:
|
||||||
|
dotnet-version: '8.0.x'
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
java-version: '17'
|
||||||
|
distribution: 'temurin'
|
||||||
|
- name: Setup Android SDK
|
||||||
|
uses: android-actions/setup-android@v3
|
||||||
|
- name: Restore tools
|
||||||
|
run: dotnet tool restore
|
||||||
|
- name: Run cake
|
||||||
|
uses: coactions/setup-xvfb@v1
|
||||||
|
with:
|
||||||
|
run: dotnet cake --target Publish --branch ${{ github.ref_name }}
|
||||||
|
env:
|
||||||
|
NUGET_KEY: ${{ secrets.NUGET_KEY }}
|
||||||
|
BAGET_KEY: ${{ secrets.BAGET_KEY }}
|
||||||
|
docs:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: Setup .NET
|
||||||
|
uses: actions/setup-dotnet@v3
|
||||||
|
with:
|
||||||
|
dotnet-version: '8.0.x'
|
||||||
|
- name: Restore tools
|
||||||
|
run: dotnet tool restore
|
||||||
|
- name: Run cake
|
||||||
|
run: dotnet cake --target Document --branch $GITHUB_REF_NAME
|
||||||
|
- name: Deploy
|
||||||
|
if: github.event_name == 'push' && github.ref_name == 'release'
|
||||||
|
# this is a beautiful way to deploy a website and i will not take any criticism
|
||||||
|
run: |
|
||||||
|
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb && sudo dpkg -i cloudflared.deb
|
||||||
|
mkdir ~/.ssh && echo "${{ secrets.ELLBOT_KEY }}" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
|
||||||
|
rsync -rv --delete -e 'ssh -o "ProxyCommand cloudflared access ssh --hostname %h" -o "StrictHostKeyChecking=no"' Docs/_site/. ellbot@ssh.ellpeck.de:/var/www/MLEM
|
4
.gitmodules
vendored
4
.gitmodules
vendored
|
@ -1,6 +1,6 @@
|
||||||
[submodule "FNA"]
|
[submodule "FNA"]
|
||||||
path = FNA
|
path = ThirdParty/FNA
|
||||||
url = https://github.com/FNA-XNA/FNA
|
url = https://github.com/FNA-XNA/FNA
|
||||||
[submodule "FontStashSharp"]
|
[submodule "FontStashSharp"]
|
||||||
path = FontStashSharp
|
path = ThirdParty/FontStashSharp
|
||||||
url = https://github.com/FontStashSharp/FontStashSharp
|
url = https://github.com/FontStashSharp/FontStashSharp
|
||||||
|
|
52
CHANGELOG.md
52
CHANGELOG.md
|
@ -2,6 +2,7 @@
|
||||||
MLEM tries to adhere to [semantic versioning](https://semver.org/). Potentially breaking changes are written in **bold**.
|
MLEM tries to adhere to [semantic versioning](https://semver.org/). Potentially breaking changes are written in **bold**.
|
||||||
|
|
||||||
Jump to version:
|
Jump to version:
|
||||||
|
- [6.3.0](#630)
|
||||||
- [6.2.0](#620)
|
- [6.2.0](#620)
|
||||||
- [6.1.0](#610)
|
- [6.1.0](#610)
|
||||||
- [6.0.0](#600)
|
- [6.0.0](#600)
|
||||||
|
@ -10,6 +11,57 @@ Jump to version:
|
||||||
- [5.1.0](#510)
|
- [5.1.0](#510)
|
||||||
- [5.0.0](#500)
|
- [5.0.0](#500)
|
||||||
|
|
||||||
|
## 6.3.0
|
||||||
|
|
||||||
|
### MLEM
|
||||||
|
Additions
|
||||||
|
- Added GraphicsExtensions.WithRenderTargets, a multi-target version of WithRenderTarget
|
||||||
|
- Added Zero, One, Linear and Clamp to Easings
|
||||||
|
- Added GetRandomEntry and GetRandomWeightedEntry to SingleRandom
|
||||||
|
- Added the ability to draw single corners of AutoTiling's extended auto tiles
|
||||||
|
- Added ColorHelper.TryFromHexString, a non-throwing version of FromHexString
|
||||||
|
- Added ToHexStringRgba and ToHexStringRgb to ColorExtensions
|
||||||
|
|
||||||
|
Improvements
|
||||||
|
- Stopped the text formatter throwing if a color can't be parsed
|
||||||
|
- Improved text formatter tokenization performance
|
||||||
|
- Allow using control and arrow keys to move the visible area of a text input
|
||||||
|
- Allow formatting codes applied later to override settings of earlier ones
|
||||||
|
|
||||||
|
Fixes
|
||||||
|
- Fixed TextInput not working correctly when using surrogate pairs
|
||||||
|
- Fixed InputHandler touch states being initialized incorrectly when touch handling is disabled
|
||||||
|
- Fixed empty NinePatch regions stalling when using tile mode
|
||||||
|
- Fixed bold and italic formatting code closing tags working on each other
|
||||||
|
|
||||||
|
### MLEM.Ui
|
||||||
|
Additions
|
||||||
|
- Added UiControls.NavType, which stores the most recently used type of ui navigation
|
||||||
|
- Added SetWidthBasedOnAspect and SetHeightBasedOnAspect to images
|
||||||
|
- Added the ability to set a custom SamplerState for images
|
||||||
|
- Added some useful additional constructors to various elements
|
||||||
|
|
||||||
|
Improvements
|
||||||
|
- Allow scrolling panels to contain other scrolling panels
|
||||||
|
- Allow dropdowns to have scrolling panels
|
||||||
|
- Improved Panel performance when adding and removing a lot of children
|
||||||
|
- Don't reset the caret position of a text field when selecting or deselecting it
|
||||||
|
- Improved UiParser.ParseImage with locks and a callback action
|
||||||
|
|
||||||
|
Fixes
|
||||||
|
- Fixed panels updating their relevant children too much when the scroll bar is hidden
|
||||||
|
- Fixed a stack overflow exception when a panel's scroll bar auto-hiding causes elements to gain height
|
||||||
|
- Fixed scrolling panels calculating their height incorrectly when their first child is hidden
|
||||||
|
|
||||||
|
### MLEM.Extended
|
||||||
|
Improvements
|
||||||
|
- Updated to FontStashSharp 1.3.0's API
|
||||||
|
- Expose character and line spacing in GenericStashFont
|
||||||
|
|
||||||
|
### MLEM.Data
|
||||||
|
Fixes
|
||||||
|
- Fixed various exception types not being wrapped by ContentLoadExceptions when loading raw or JSON content
|
||||||
|
|
||||||
## 6.2.0
|
## 6.2.0
|
||||||
|
|
||||||
### MLEM
|
### MLEM
|
||||||
|
|
|
@ -48,10 +48,10 @@ public class Activity1 : AndroidGameActivity {
|
||||||
base.OnWindowFocusChanged(hasFocus);
|
base.OnWindowFocusChanged(hasFocus);
|
||||||
// hide the status bar
|
// hide the status bar
|
||||||
if (hasFocus) {
|
if (hasFocus) {
|
||||||
#pragma warning disable CA1422
|
#pragma warning disable CS0618
|
||||||
// TODO this is deprecated, find out how to replace it
|
// TODO this is deprecated, find out how to replace it
|
||||||
this.Window.DecorView.SystemUiVisibility = (StatusBarVisibility) (SystemUiFlags.ImmersiveSticky | SystemUiFlags.LayoutStable | SystemUiFlags.LayoutHideNavigation | SystemUiFlags.LayoutFullscreen | SystemUiFlags.HideNavigation | SystemUiFlags.Fullscreen);
|
this.Window.DecorView.SystemUiVisibility = (StatusBarVisibility) (SystemUiFlags.ImmersiveSticky | SystemUiFlags.LayoutStable | SystemUiFlags.LayoutHideNavigation | SystemUiFlags.LayoutFullscreen | SystemUiFlags.HideNavigation | SystemUiFlags.Fullscreen);
|
||||||
#pragma warning restore CA1422
|
#pragma warning restore CS0618
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0-android</TargetFramework>
|
<TargetFramework>net8.0-android</TargetFramework>
|
||||||
<SupportedOSPlatformVersion>31</SupportedOSPlatformVersion>
|
<SupportedOSPlatformVersion>31</SupportedOSPlatformVersion>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<ApplicationId>de.ellpeck.mlem.demos.android</ApplicationId>
|
<ApplicationId>de.ellpeck.mlem.demos.android</ApplicationId>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<ApplicationIcon>Icon.ico</ApplicationIcon>
|
<ApplicationIcon>Icon.ico</ApplicationIcon>
|
||||||
<AssemblyName>MLEM Desktop Demos</AssemblyName>
|
<AssemblyName>MLEM Desktop Demos</AssemblyName>
|
||||||
<RootNamespace>Demos.DesktopGL</RootNamespace>
|
<RootNamespace>Demos.DesktopGL</RootNamespace>
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.1.303" />
|
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.1.303" />
|
||||||
<ProjectReference Include="..\FNA\FNA.Core.csproj" />
|
<ProjectReference Include="..\ThirdParty\FNA\FNA.Core.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
<Content Include="..\Demos\Content\*\**" />
|
<Content Include="..\Demos\Content\*\**" />
|
||||||
<EmbeddedResource Include="Icon.ico" />
|
<EmbeddedResource Include="Icon.ico" />
|
||||||
<EmbeddedResource Include="Icon.bmp" />
|
<EmbeddedResource Include="Icon.bmp" />
|
||||||
<Content Include="../FnaNative/**">
|
<Content Include="../ThirdParty/Native/**">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
<Link>%(Filename)%(Extension)</Link>
|
<Link>%(Filename)%(Extension)</Link>
|
||||||
</Content>
|
</Content>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<ApplicationIcon>Icon.ico</ApplicationIcon>
|
<ApplicationIcon>Icon.ico</ApplicationIcon>
|
||||||
<AssemblyName>MLEM Desktop Demos</AssemblyName>
|
<AssemblyName>MLEM Desktop Demos</AssemblyName>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
|
@ -26,9 +26,4 @@
|
||||||
<EmbeddedResource Include="Icon.ico" />
|
<EmbeddedResource Include="Icon.ico" />
|
||||||
<EmbeddedResource Include="Icon.bmp" />
|
<EmbeddedResource Include="Icon.bmp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="RestoreDotnetTools" BeforeTargets="Restore">
|
|
||||||
<Message Text="Restoring dotnet tools" Importance="High" />
|
|
||||||
<Exec Command="dotnet tool restore" />
|
|
||||||
</Target>
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -12,8 +12,12 @@ Strikethrough with ~~two tildes~~.
|
||||||
[I'm an inline-style link](https://www.google.com)
|
[I'm an inline-style link](https://www.google.com)
|
||||||
<http://www.example.com>
|
<http://www.example.com>
|
||||||
|
|
||||||
|
Logo:
|
||||||
![](https://raw.githubusercontent.com/Ellpeck/MLEM/main/Media/Logo.png)
|
![](https://raw.githubusercontent.com/Ellpeck/MLEM/main/Media/Logo.png)
|
||||||
|
|
||||||
|
Wide logo:
|
||||||
|
![](https://raw.githubusercontent.com/Ellpeck/MLEM/main/Media/Banner.png)
|
||||||
|
|
||||||
Some `inline code` right here
|
Some `inline code` right here
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<RootNamespace>Demos</RootNamespace>
|
<RootNamespace>Demos</RootNamespace>
|
||||||
<DefineConstants>$(DefineConstants);FNA</DefineConstants>
|
<DefineConstants>$(DefineConstants);FNA</DefineConstants>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\FNA\FNA.Core.csproj">
|
<ProjectReference Include="..\ThirdParty\FNA\FNA.Core.csproj">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace Demos {
|
||||||
|
|
||||||
private const string Text =
|
private const string Text =
|
||||||
"MLEM's text formatting system allows for various <b>formatting codes</b> to be applied in the middle of a string. Here's a demonstration of some of them.\n\n" +
|
"MLEM's text formatting system allows for various <b>formatting codes</b> to be applied in the middle of a string. Here's a demonstration of some of them.\n\n" +
|
||||||
"You can write in <b>bold</i>, <i>italics</i>, <u>with an underline</u>, <st>strikethrough</st>, with a <s>drop shadow</s> whose <s #ff0000 4>color</s> and <s #000000 10>offset</s> you can modify in each application of the code, with an <o>outline</o> that you can also <o #ff0000 4>modify</o> <o #ff00ff 2>dynamically</o>, or with various types of <b>combined <c Pink>formatting</c> codes</b>.\n\n" +
|
"You can write in <b>bold</b>, <i>italics</i>, <u>with an underline</u>, <st>strikethrough</st>, with a <s>drop shadow</s> whose <s #ff0000 4>color</s> and <s #000000 10>offset</s> you can modify in each application of the code, with an <o>outline</o> that you can also <o #ff0000 4>modify</o> <o #ff00ff 2>dynamically</o>, or with various types of <b>combined <c Pink>formatting</c> codes</b>.\n\n" +
|
||||||
"You can apply <c CornflowerBlue>custom</c> <c Yellow>colors</c> to text, including all default <c Orange>MonoGame colors</c> and <c #aabb00>inline custom colors</c>.\n\n" +
|
"You can apply <c CornflowerBlue>custom</c> <c Yellow>colors</c> to text, including all default <c Orange>MonoGame colors</c> and <c #aabb00>inline custom colors</c>.\n\n" +
|
||||||
"You can also use animations like <a wobbly>a wobbly one</a>, as well as create custom ones using the <a wobbly>Code class</a>.\n\n" +
|
"You can also use animations like <a wobbly>a wobbly one</a>, as well as create custom ones using the <a wobbly>Code class</a>.\n\n" +
|
||||||
"You can also display <i grass> icons in your text, and use super<sup>script</sup> or sub<sub>script</sub> formatting!\n\n" +
|
"You can also display <i grass> icons in your text, and use super<sup>script</sup> or sub<sub>script</sub> formatting!\n\n" +
|
||||||
|
|
|
@ -223,6 +223,15 @@ namespace Demos {
|
||||||
PositionOffset = new Vector2(0, 1)
|
PositionOffset = new Vector2(0, 1)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var subPanel = this.root.AddChild(new Panel(Anchor.AutoLeft, new Vector2(1, 25), Vector2.Zero, false, true) {
|
||||||
|
PositionOffset = new Vector2(0, 1),
|
||||||
|
Texture = null,
|
||||||
|
ChildPadding = Padding.Empty
|
||||||
|
});
|
||||||
|
subPanel.AddChild(new Paragraph(Anchor.AutoLeft, 1, "This is a nested scrolling panel!"));
|
||||||
|
for (var i = 1; i <= 5; i++)
|
||||||
|
subPanel.AddChild(new Button(Anchor.AutoLeft, new Vector2(1, 10), $"Button {i}") {PositionOffset = new Vector2(0, 1)});
|
||||||
|
|
||||||
const string alignText = "Paragraphs can have <l Left>left</l> aligned text, <l Right>right</l> aligned text and <l Center>center</l> aligned text.";
|
const string alignText = "Paragraphs can have <l Left>left</l> aligned text, <l Right>right</l> aligned text and <l Center>center</l> aligned text.";
|
||||||
this.root.AddChild(new VerticalSpace(3));
|
this.root.AddChild(new VerticalSpace(3));
|
||||||
var alignPar = this.root.AddChild(new Paragraph(Anchor.AutoLeft, 1, alignText));
|
var alignPar = this.root.AddChild(new Paragraph(Anchor.AutoLeft, 1, alignText));
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
"globalMetadata": {
|
"globalMetadata": {
|
||||||
"_appTitle": "MLEM Documentation",
|
"_appTitle": "MLEM Documentation",
|
||||||
"_appLogoPath": "Logo.svg",
|
"_appLogoPath": "Logo.svg",
|
||||||
"_appFooter": "<a href=\"https://github.com/Ellpeck/MLEM\">© 2019-2023 Ellpeck</a> – <a href=\"https://ellpeck.de/impressum\">Impressum</a> – <a href=\"https://ellpeck.de/privacy\">Privacy</a> – <a href=\"https://status.ellpeck.de\">Status</a>",
|
"_appFooter": "<a href=\"https://github.com/Ellpeck/MLEM\">© 2019-2024 Ellpeck</a> – <a href=\"https://ellpeck.de/impressum\">Impressum</a> – <a href=\"https://ellpeck.de/privacy\">Privacy</a> – <a href=\"https://status.ellpeck.de\">Status</a>",
|
||||||
"_enableSearch": true
|
"_enableSearch": true
|
||||||
},
|
},
|
||||||
"dest": "_site",
|
"dest": "_site",
|
||||||
|
|
1
FNA
1
FNA
|
@ -1 +0,0 @@
|
||||||
Subproject commit 697cc63662914c0dc26c500bc9b8498b5ca8a68f
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1 +0,0 @@
|
||||||
Subproject commit f11f97b709e50960dd8ce1f727974744c4f8a0dd
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2019-2023 Ellpeck
|
Copyright (c) 2019-2024 Ellpeck
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
@ -100,7 +100,7 @@ namespace MLEM.Data.Content {
|
||||||
r.Name = assetName;
|
r.Name = assetName;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException) {}
|
} catch (IOException) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new ContentLoadException($"Asset {assetName} not found. Tried files {string.Join(", ", triedFiles)}");
|
throw new ContentLoadException($"Asset {assetName} not found. Tried files {string.Join(", ", triedFiles)}");
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace MLEM.Data {
|
||||||
using (var reader = new JsonTextReader(stream))
|
using (var reader = new JsonTextReader(stream))
|
||||||
return serializerToUse.Deserialize<T>(reader);
|
return serializerToUse.Deserialize<T>(reader);
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException) {}
|
} catch (IOException) {}
|
||||||
}
|
}
|
||||||
throw new ContentLoadException($"Asset {name} not found. Tried files {string.Join(", ", triedFiles)}");
|
throw new ContentLoadException($"Asset {name} not found. Tried files {string.Join(", ", triedFiles)}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net452;netstandard2.0;net7.0</TargetFrameworks>
|
<TargetFrameworks>net452;netstandard2.0;net8.0</TargetFrameworks>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
<IsTrimmable>true</IsTrimmable>
|
<IsAotCompatible Condition="'$(TargetFramework)'=='net8.0'">true</IsAotCompatible>
|
||||||
<RootNamespace>MLEM.Data</RootNamespace>
|
<RootNamespace>MLEM.Data</RootNamespace>
|
||||||
<DefineConstants>$(DefineConstants);FNA</DefineConstants>
|
<DefineConstants>$(DefineConstants);FNA</DefineConstants>
|
||||||
<NoWarn>NU1701</NoWarn>
|
<NoWarn>NU1701</NoWarn>
|
||||||
|
@ -28,14 +28,14 @@
|
||||||
<PackageReference Include="Lidgren.Network" Version="1.0.2">
|
<PackageReference Include="Lidgren.Network" Version="1.0.2">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.2">
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2">
|
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|
||||||
<ProjectReference Include="..\FNA\FNA.csproj">
|
<ProjectReference Include="..\ThirdParty\FNA\FNA.csproj">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net452;netstandard2.0;net7.0</TargetFrameworks>
|
<TargetFrameworks>net452;netstandard2.0;net8.0</TargetFrameworks>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
<IsTrimmable>true</IsTrimmable>
|
<IsAotCompatible Condition="'$(TargetFramework)'=='net8.0'">true</IsAotCompatible>
|
||||||
<NoWarn>NU1701</NoWarn>
|
<NoWarn>NU1701</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace MLEM.Extended.Font {
|
||||||
/// The <see cref="SpriteFontBase"/> that is being wrapped by this generic font
|
/// The <see cref="SpriteFontBase"/> that is being wrapped by this generic font
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly SpriteFontBase Font;
|
public readonly SpriteFontBase Font;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override GenericFont Bold { get; }
|
public override GenericFont Bold { get; }
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -18,6 +19,15 @@ namespace MLEM.Extended.Font {
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override float LineHeight => this.Font.LineHeight;
|
public override float LineHeight => this.Font.LineHeight;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The character spacing that will be passed to the underlying <see cref="Font"/>.
|
||||||
|
/// </summary>
|
||||||
|
public float CharacterSpacing { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// The line spacing that will be passed to the underlying <see cref="Font"/>.
|
||||||
|
/// </summary>
|
||||||
|
public float LineSpacing { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new generic font using <see cref="SpriteFontBase"/>.
|
/// Creates a new generic font using <see cref="SpriteFontBase"/>.
|
||||||
/// Optionally, a bold and italic version of the font can be supplied.
|
/// Optionally, a bold and italic version of the font can be supplied.
|
||||||
|
@ -33,12 +43,12 @@ namespace MLEM.Extended.Font {
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override float MeasureCharacter(int codePoint) {
|
protected override float MeasureCharacter(int codePoint) {
|
||||||
return this.Font.MeasureString(CodePointSource.ToString(codePoint)).X;
|
return this.Font.MeasureString(CodePointSource.ToString(codePoint), null, this.CharacterSpacing, this.LineSpacing).X;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void DrawCharacter(SpriteBatch batch, int codePoint, string character, Vector2 position, Color color, float rotation, Vector2 scale, SpriteEffects effects, float layerDepth) {
|
protected override void DrawCharacter(SpriteBatch batch, int codePoint, string character, Vector2 position, Color color, float rotation, Vector2 scale, SpriteEffects effects, float layerDepth) {
|
||||||
this.Font.DrawText(batch, character, position, color, scale, rotation, Vector2.Zero, layerDepth);
|
this.Font.DrawText(batch, character, position, color, rotation, Vector2.Zero, scale, layerDepth, this.CharacterSpacing, this.LineSpacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>netstandard2.0;net7.0</TargetFrameworks>
|
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
<IsTrimmable>true</IsTrimmable>
|
<IsAotCompatible Condition="'$(TargetFramework)'=='net8.0'">true</IsAotCompatible>
|
||||||
<RootNamespace>MLEM.Extended</RootNamespace>
|
<RootNamespace>MLEM.Extended</RootNamespace>
|
||||||
<DefineConstants>$(DefineConstants);FNA</DefineConstants>
|
<DefineConstants>$(DefineConstants);FNA</DefineConstants>
|
||||||
<NoWarn>NU1702</NoWarn>
|
<NoWarn>NU1702</NoWarn>
|
||||||
|
@ -24,10 +24,10 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\MLEM\MLEM.FNA.csproj" />
|
<ProjectReference Include="..\MLEM\MLEM.FNA.csproj" />
|
||||||
|
|
||||||
<ProjectReference Include="..\FontStashSharp\src\XNA\FontStashSharp.FNA.csproj">
|
<ProjectReference Include="..\ThirdParty\FontStashSharp\src\XNA\FontStashSharp.FNA.csproj">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\FNA\FNA.csproj">
|
<ProjectReference Include="..\ThirdParty\FNA\FNA.csproj">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>netstandard2.0;net7.0</TargetFrameworks>
|
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
<IsTrimmable>true</IsTrimmable>
|
<IsAotCompatible Condition="'$(TargetFramework)'=='net8.0'">true</IsAotCompatible>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<PackageReference Include="MonoGame.Extended.Tiled" Version="3.8.0">
|
<PackageReference Include="MonoGame.Extended.Tiled" Version="3.8.0">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="FontStashSharp.MonoGame" Version="1.2.8">
|
<PackageReference Include="FontStashSharp.MonoGame" Version="1.3.3">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.0.1641">
|
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.0.1641">
|
||||||
|
|
|
@ -44,7 +44,8 @@ namespace MLEM.Extended.Tiled {
|
||||||
/// <param name="key">The key by which to get a property</param>
|
/// <param name="key">The key by which to get a property</param>
|
||||||
/// <returns>The color property</returns>
|
/// <returns>The color property</returns>
|
||||||
public static Color GetColor(this TiledMapProperties properties, string key) {
|
public static Color GetColor(this TiledMapProperties properties, string key) {
|
||||||
return ColorHelper.FromHexString(properties.Get(key));
|
ColorHelper.TryFromHexString(properties.Get(key), out var val);
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -16,11 +16,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.FNA", "Tests\Tests.FN
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MLEM.Extended.FNA", "MLEM.Extended\MLEM.Extended.FNA.csproj", "{A5B22930-DF4B-4A62-93ED-A6549F7B666B}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MLEM.Extended.FNA", "MLEM.Extended\MLEM.Extended.FNA.csproj", "{A5B22930-DF4B-4A62-93ED-A6549F7B666B}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FNA", "FNA\FNA.csproj", "{35253CE1-C864-4CD3-8249-4D1319748E8F}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FNA", "ThirdParty\FNA\FNA.csproj", "{35253CE1-C864-4CD3-8249-4D1319748E8F}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FontStashSharp.FNA", "FontStashSharp\src\XNA\FontStashSharp.FNA.csproj", "{39249E92-EBF2-4951-A086-AB4951C3CCE1}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FontStashSharp.FNA", "ThirdParty\FontStashSharp\src\XNA\FontStashSharp.FNA.csproj", "{39249E92-EBF2-4951-A086-AB4951C3CCE1}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FNA.Core", "FNA\FNA.Core.csproj", "{458FFA5E-A1C4-4B23-A5D8-259385FEECED}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FNA.Core", "ThirdParty\FNA\FNA.Core.csproj", "{458FFA5E-A1C4-4B23-A5D8-259385FEECED}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net452;netstandard2.0;net7.0</TargetFrameworks>
|
<TargetFrameworks>net452;netstandard2.0;net8.0</TargetFrameworks>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
<IsTrimmable>true</IsTrimmable>
|
<IsAotCompatible Condition="'$(TargetFramework)'=='net8.0'">true</IsAotCompatible>
|
||||||
<RootNamespace>MLEM.Startup</RootNamespace>
|
<RootNamespace>MLEM.Startup</RootNamespace>
|
||||||
<DefineConstants>$(DefineConstants);FNA</DefineConstants>
|
<DefineConstants>$(DefineConstants);FNA</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -22,11 +22,11 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Coroutine" Version="2.1.4" />
|
<PackageReference Include="Coroutine" Version="2.1.5" />
|
||||||
<ProjectReference Include="..\MLEM.Ui\MLEM.Ui.FNA.csproj" />
|
<ProjectReference Include="..\MLEM.Ui\MLEM.Ui.FNA.csproj" />
|
||||||
<ProjectReference Include="..\MLEM\MLEM.FNA.csproj" />
|
<ProjectReference Include="..\MLEM\MLEM.FNA.csproj" />
|
||||||
|
|
||||||
<ProjectReference Include="..\FNA\FNA.csproj">
|
<ProjectReference Include="..\ThirdParty\FNA\FNA.csproj">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net452;netstandard2.0;net7.0</TargetFrameworks>
|
<TargetFrameworks>net452;netstandard2.0;net8.0</TargetFrameworks>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
<IsTrimmable>true</IsTrimmable>
|
<IsAotCompatible Condition="'$(TargetFramework)'=='net8.0'">true</IsAotCompatible>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net452;netstandard2.0;net7.0</TargetFrameworks>
|
<TargetFrameworks>net452;netstandard2.0;net8.0</TargetFrameworks>
|
||||||
<IncludeContentInPack>true</IncludeContentInPack>
|
<IncludeContentInPack>true</IncludeContentInPack>
|
||||||
<IncludeBuildOutput>false</IncludeBuildOutput>
|
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||||
<ContentTargetFolders>content</ContentTargetFolders>
|
<ContentTargetFolders>content</ContentTargetFolders>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<IsTrimmable>true</IsTrimmable>
|
|
||||||
<NoWarn>NU5128</NoWarn>
|
<NoWarn>NU5128</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<PublishReadyToRun>false</PublishReadyToRun>
|
<PublishReadyToRun>false</PublishReadyToRun>
|
||||||
<TieredCompilation>false</TieredCompilation>
|
<TieredCompilation>false</TieredCompilation>
|
||||||
<ApplicationIcon>Icon.ico</ApplicationIcon>
|
<ApplicationIcon>Icon.ico</ApplicationIcon>
|
||||||
|
@ -19,9 +19,4 @@
|
||||||
<EmbeddedResource Include="Icon.ico" />
|
<EmbeddedResource Include="Icon.ico" />
|
||||||
<EmbeddedResource Include="Icon.bmp" />
|
<EmbeddedResource Include="Icon.bmp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="RestoreDotnetTools" BeforeTargets="Restore">
|
|
||||||
<Message Text="Restoring dotnet tools" Importance="High" />
|
|
||||||
<Exec Command="dotnet tool restore" />
|
|
||||||
</Target>
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -87,6 +87,13 @@ namespace MLEM.Ui.Elements {
|
||||||
|
|
||||||
private bool isDisabled;
|
private bool isDisabled;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new button with the given settings and no text or tooltip.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="anchor">The button's anchor</param>
|
||||||
|
/// <param name="size">The button's size</param>
|
||||||
|
public Button(Anchor anchor, Vector2 size) : base(anchor, size) {}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new button with the given settings
|
/// Creates a new button with the given settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -94,7 +101,7 @@ namespace MLEM.Ui.Elements {
|
||||||
/// <param name="size">The button's size</param>
|
/// <param name="size">The button's size</param>
|
||||||
/// <param name="text">The text that should be displayed on the button</param>
|
/// <param name="text">The text that should be displayed on the button</param>
|
||||||
/// <param name="tooltipText">The text that should be displayed in a <see cref="Tooltip"/> when hovering over this button</param>
|
/// <param name="tooltipText">The text that should be displayed in a <see cref="Tooltip"/> when hovering over this button</param>
|
||||||
public Button(Anchor anchor, Vector2 size, string text = null, string tooltipText = null) : base(anchor, size) {
|
public Button(Anchor anchor, Vector2 size, string text = null, string tooltipText = null) : this(anchor, size) {
|
||||||
if (text != null) {
|
if (text != null) {
|
||||||
this.Text = new Paragraph(Anchor.Center, 1, text, true);
|
this.Text = new Paragraph(Anchor.Center, 1, text, true);
|
||||||
this.Text.Padding = this.Text.Padding.OrStyle(new Padding(1), 1);
|
this.Text.Padding = this.Text.Padding.OrStyle(new Padding(1), 1);
|
||||||
|
@ -104,6 +111,23 @@ namespace MLEM.Ui.Elements {
|
||||||
this.Tooltip = this.AddTooltip(tooltipText);
|
this.Tooltip = this.AddTooltip(tooltipText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new button with the given settings
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="anchor">The button's anchor</param>
|
||||||
|
/// <param name="size">The button's size</param>
|
||||||
|
/// <param name="textCallback">The text that should be displayed on the button</param>
|
||||||
|
/// <param name="tooltipTextCallback">The text that should be displayed in a <see cref="Tooltip"/> when hovering over this button</param>
|
||||||
|
public Button(Anchor anchor, Vector2 size, Paragraph.TextCallback textCallback = null, Paragraph.TextCallback tooltipTextCallback = null) : this(anchor, size) {
|
||||||
|
if (textCallback != null) {
|
||||||
|
this.Text = new Paragraph(Anchor.Center, 1, textCallback, true);
|
||||||
|
this.Text.Padding = this.Text.Padding.OrStyle(new Padding(1), 1);
|
||||||
|
this.AddChild(this.Text);
|
||||||
|
}
|
||||||
|
if (tooltipTextCallback != null)
|
||||||
|
this.Tooltip = this.AddTooltip(tooltipTextCallback);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) {
|
public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) {
|
||||||
var tex = this.Texture;
|
var tex = this.Texture;
|
||||||
|
|
|
@ -12,8 +12,7 @@ namespace MLEM.Ui.Elements {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The panel that this dropdown contains. It will be displayed upon pressing the dropdown button.
|
/// The panel that this dropdown contains. It will be displayed upon pressing the dropdown button.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly Panel Panel;
|
public Panel Panel { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This property stores whether the dropdown is currently opened or not
|
/// This property stores whether the dropdown is currently opened or not
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -29,6 +28,18 @@ namespace MLEM.Ui.Elements {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GenericCallback OnOpenedOrClosed;
|
public GenericCallback OnOpenedOrClosed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new dropdown with the given settings and no text or tooltip.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="anchor">The dropdown's anchor</param>
|
||||||
|
/// <param name="size">The dropdown button's size</param>
|
||||||
|
/// <param name="panelHeight">The height of the <see cref="Panel"/>. If this is 0, the panel will be set to <see cref="Element.SetHeightBasedOnChildren"/>.</param>
|
||||||
|
/// <param name="scrollPanel">Whether this dropdown's <see cref="Panel"/> should automatically add a scroll bar to scroll towards elements that are beyond the area it covers.</param>
|
||||||
|
/// <param name="autoHidePanelScrollbar">Whether this dropdown's <see cref="Panel"/>'s scroll bar should be hidden automatically if the panel does not contain enough children to allow for scrolling. This only has an effect if <paramref name="scrollPanel"/> is <see langword="true"/>.</param>
|
||||||
|
public Dropdown(Anchor anchor, Vector2 size, float panelHeight = 0, bool scrollPanel = false, bool autoHidePanelScrollbar = true) : base(anchor, size) {
|
||||||
|
this.Initialize(panelHeight, scrollPanel, autoHidePanelScrollbar);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new dropdown with the given settings
|
/// Creates a new dropdown with the given settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -36,31 +47,25 @@ namespace MLEM.Ui.Elements {
|
||||||
/// <param name="size">The dropdown button's size</param>
|
/// <param name="size">The dropdown button's size</param>
|
||||||
/// <param name="text">The text displayed on the dropdown button</param>
|
/// <param name="text">The text displayed on the dropdown button</param>
|
||||||
/// <param name="tooltipText">The text displayed as a tooltip when hovering over the dropdown button</param>
|
/// <param name="tooltipText">The text displayed as a tooltip when hovering over the dropdown button</param>
|
||||||
public Dropdown(Anchor anchor, Vector2 size, string text = null, string tooltipText = null) : base(anchor, size, text, tooltipText) {
|
/// <param name="panelHeight">The height of the <see cref="Panel"/>. If this is 0, the panel will be set to <see cref="Element.SetHeightBasedOnChildren"/>.</param>
|
||||||
this.Panel = this.AddChild(new Panel(Anchor.TopCenter, Vector2.Zero, Vector2.Zero, true) {
|
/// <param name="scrollPanel">Whether this dropdown's <see cref="Panel"/> should automatically add a scroll bar to scroll towards elements that are beyond the area it covers.</param>
|
||||||
IsHidden = true
|
/// <param name="autoHidePanelScrollbar">Whether this dropdown's <see cref="Panel"/>'s scroll bar should be hidden automatically if the panel does not contain enough children to allow for scrolling. This only has an effect if <paramref name="scrollPanel"/> is <see langword="true"/>.</param>
|
||||||
});
|
public Dropdown(Anchor anchor, Vector2 size, string text = null, string tooltipText = null, float panelHeight = 0, bool scrollPanel = false, bool autoHidePanelScrollbar = true) : base(anchor, size, text, tooltipText) {
|
||||||
this.OnAreaUpdated += e => {
|
this.Initialize(panelHeight, scrollPanel, autoHidePanelScrollbar);
|
||||||
this.Panel.Size = new Vector2(e.Area.Width / e.Scale, 0);
|
}
|
||||||
this.Panel.PositionOffset = new Vector2(0, e.Area.Height / e.Scale);
|
|
||||||
};
|
/// <summary>
|
||||||
this.OnOpenedOrClosed += e => this.Priority = this.IsOpen ? 10000 : 0;
|
/// Creates a new dropdown with the given settings
|
||||||
this.OnPressed += e => {
|
/// </summary>
|
||||||
this.IsOpen = !this.IsOpen;
|
/// <param name="anchor">The dropdown's anchor</param>
|
||||||
// close other dropdowns in the same root when we open
|
/// <param name="size">The dropdown button's size</param>
|
||||||
if (this.IsOpen) {
|
/// <param name="textCallback">The text displayed on the dropdown button</param>
|
||||||
this.Root.Element.AndChildren(o => {
|
/// <param name="tooltipTextCallback">The text displayed as a tooltip when hovering over the dropdown button</param>
|
||||||
if (o != this && o is Dropdown d && d.IsOpen)
|
/// <param name="panelHeight">The height of the <see cref="Panel"/>. If this is 0, the panel will be set to <see cref="Element.SetHeightBasedOnChildren"/>.</param>
|
||||||
d.IsOpen = false;
|
/// <param name="scrollPanel">Whether this dropdown's <see cref="Panel"/> should automatically add a scroll bar to scroll towards elements that are beyond the area it covers.</param>
|
||||||
});
|
/// <param name="autoHidePanelScrollbar">Whether this dropdown's <see cref="Panel"/>'s scroll bar should be hidden automatically if the panel does not contain enough children to allow for scrolling. This only has an effect if <paramref name="scrollPanel"/> is <see langword="true"/>.</param>
|
||||||
}
|
public Dropdown(Anchor anchor, Vector2 size, Paragraph.TextCallback textCallback = null, Paragraph.TextCallback tooltipTextCallback = null, float panelHeight = 0, bool scrollPanel = false, bool autoHidePanelScrollbar = true) : base(anchor, size, textCallback, tooltipTextCallback) {
|
||||||
};
|
this.Initialize(panelHeight, scrollPanel, autoHidePanelScrollbar);
|
||||||
this.GetGamepadNextElement = (dir, usualNext) => {
|
|
||||||
// Force navigate down to our first child if we're open
|
|
||||||
if (this.IsOpen && dir == Direction2.Down)
|
|
||||||
return this.Panel.GetChildren().FirstOrDefault(c => c.CanBeSelected) ?? usualNext;
|
|
||||||
return usualNext;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -116,5 +121,32 @@ namespace MLEM.Ui.Elements {
|
||||||
return paragraph;
|
return paragraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Initialize(float panelHeight, bool scrollPanel, bool autoHidePanelScrollbar) {
|
||||||
|
this.Panel = this.AddChild(new Panel(Anchor.TopCenter, Vector2.Zero, panelHeight == 0, scrollPanel, autoHidePanelScrollbar) {
|
||||||
|
IsHidden = true
|
||||||
|
});
|
||||||
|
this.OnAreaUpdated += e => {
|
||||||
|
this.Panel.Size = new Vector2(e.Area.Width / e.Scale, panelHeight);
|
||||||
|
this.Panel.PositionOffset = new Vector2(0, e.Area.Height / e.Scale);
|
||||||
|
};
|
||||||
|
this.OnOpenedOrClosed += e => this.Priority = this.IsOpen ? 10000 : 0;
|
||||||
|
this.OnPressed += e => {
|
||||||
|
this.IsOpen = !this.IsOpen;
|
||||||
|
// close other dropdowns in the same root when we open
|
||||||
|
if (this.IsOpen) {
|
||||||
|
this.Root.Element.AndChildren(o => {
|
||||||
|
if (o != this && o is Dropdown d && d.IsOpen)
|
||||||
|
d.IsOpen = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.GetGamepadNextElement = (dir, usualNext) => {
|
||||||
|
// Force navigate down to our first child if we're open
|
||||||
|
if (this.IsOpen && dir == Direction2.Down)
|
||||||
|
return this.Panel.GetChildren().FirstOrDefault(c => c.CanBeSelected) ?? usualNext;
|
||||||
|
return usualNext;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1236,12 +1236,13 @@ namespace MLEM.Ui.Elements {
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
var ret = this.GetType().ToString();
|
var ret = this.GetType().Name;
|
||||||
// elements will contain their path up to the root (Paragraph@Panel@...@RootName)
|
// elements will contain their path up to the root and their index in each parent
|
||||||
|
// eg Paragraph 2 @ Panel 3 @ ... @ Group RootName
|
||||||
if (this.Parent != null) {
|
if (this.Parent != null) {
|
||||||
ret += $"@{this.Parent}";
|
ret += $" {this.Parent.Children.IndexOf(this)} @ {this.Parent}";
|
||||||
} else if (this.Root?.Element == this) {
|
} else if (this.Root?.Element == this) {
|
||||||
ret += $"@{this.Root.Name}";
|
ret += $" {this.Root.Name}";
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,18 @@ namespace MLEM.Ui.Elements {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="anchor">The group's anchor</param>
|
/// <param name="anchor">The group's anchor</param>
|
||||||
/// <param name="size">The group's size</param>
|
/// <param name="size">The group's size</param>
|
||||||
/// <param name="setHeightBasedOnChildren">Whether the group's height should be based on its children's height</param>
|
/// <param name="setHeightBasedOnChildren">Whether the group's height should be based on its children's height, see <see cref="Element.SetHeightBasedOnChildren"/>.</param>
|
||||||
public Group(Anchor anchor, Vector2 size, bool setHeightBasedOnChildren = true) : base(anchor, size) {
|
public Group(Anchor anchor, Vector2 size, bool setHeightBasedOnChildren = true) : this(anchor, size, false, setHeightBasedOnChildren) {}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new group with the given settings
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="anchor">The group's anchor</param>
|
||||||
|
/// <param name="size">The group's size</param>
|
||||||
|
/// <param name="setWidthBasedOnChildren">Whether the group's width should be based on its children's width, see <see cref="Element.SetWidthBasedOnChildren"/>.</param>
|
||||||
|
/// <param name="setHeightBasedOnChildren">Whether the group's height should be based on its children's height, see <see cref="Element.SetHeightBasedOnChildren"/>.</param>
|
||||||
|
public Group(Anchor anchor, Vector2 size, bool setWidthBasedOnChildren, bool setHeightBasedOnChildren) : base(anchor, size) {
|
||||||
|
this.SetWidthBasedOnChildren = setWidthBasedOnChildren;
|
||||||
this.SetHeightBasedOnChildren = setHeightBasedOnChildren;
|
this.SetHeightBasedOnChildren = setHeightBasedOnChildren;
|
||||||
this.CanBeSelected = false;
|
this.CanBeSelected = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,11 +69,45 @@ namespace MLEM.Ui.Elements {
|
||||||
/// Note that increased rotation does not increase this component's size, even if the rotated texture would go out of bounds of this component.
|
/// Note that increased rotation does not increase this component's size, even if the rotated texture would go out of bounds of this component.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float ImageRotation;
|
public float ImageRotation;
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this image's width should automatically be calculated based on this image's calculated height in relation to its <see cref="Texture"/>'s aspect ratio.
|
||||||
|
/// Note that, if this is <see langword="true"/>, the <see cref="Element.AutoSizeAddedAbsolute"/> value will still be applied to this image's width.
|
||||||
|
/// </summary>
|
||||||
|
public bool SetWidthBasedOnAspect {
|
||||||
|
get => this.setWidthBasedOnAspect;
|
||||||
|
set {
|
||||||
|
if (this.setWidthBasedOnAspect != value) {
|
||||||
|
this.setWidthBasedOnAspect = value;
|
||||||
|
this.SetAreaDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this image's height should automatically be calculated based on this image's calculated width in relation to its <see cref="Texture"/>'s aspect ratio.
|
||||||
|
/// This behavior is useful if an image should take up a certain width, but the aspect ratio of its texture can vary and the image should not take up more height than is necessary.
|
||||||
|
/// Note that, if this is <see langword="true"/>, the <see cref="Element.AutoSizeAddedAbsolute"/> value will still be applied to this image's height.
|
||||||
|
/// </summary>
|
||||||
|
public bool SetHeightBasedOnAspect {
|
||||||
|
get => this.setHeightBasedOnAspect;
|
||||||
|
set {
|
||||||
|
if (this.setHeightBasedOnAspect != value) {
|
||||||
|
this.setHeightBasedOnAspect = value;
|
||||||
|
this.SetAreaDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// The sampler state that this image's <see cref="Texture"/> should be drawn with.
|
||||||
|
/// If this is <see langword="null"/>, the current <see cref="SpriteBatchContext"/>'s <see cref="SpriteBatchContext.SamplerState"/> will be used, which will likely be the same as <see cref="UiSystem.SpriteBatchContext"/>.
|
||||||
|
/// </summary>
|
||||||
|
public SamplerState SamplerState;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool IsHidden => base.IsHidden || this.Texture == null;
|
public override bool IsHidden => base.IsHidden || this.Texture == null;
|
||||||
|
|
||||||
private bool scaleToImage;
|
private bool scaleToImage;
|
||||||
|
private bool setWidthBasedOnAspect;
|
||||||
|
private bool setHeightBasedOnAspect;
|
||||||
private TextureRegion explicitlySetTexture;
|
private TextureRegion explicitlySetTexture;
|
||||||
private TextureRegion displayedTexture;
|
private TextureRegion displayedTexture;
|
||||||
|
|
||||||
|
@ -86,7 +120,7 @@ namespace MLEM.Ui.Elements {
|
||||||
/// <param name="scaleToImage">Whether this image's size should be based on the texture's size</param>
|
/// <param name="scaleToImage">Whether this image's size should be based on the texture's size</param>
|
||||||
public Image(Anchor anchor, Vector2 size, TextureRegion texture, bool scaleToImage = false) : base(anchor, size) {
|
public Image(Anchor anchor, Vector2 size, TextureRegion texture, bool scaleToImage = false) : base(anchor, size) {
|
||||||
this.Texture = texture;
|
this.Texture = texture;
|
||||||
this.scaleToImage = scaleToImage;
|
this.ScaleToImage = scaleToImage;
|
||||||
this.CanBeSelected = false;
|
this.CanBeSelected = false;
|
||||||
this.CanBeMoused = false;
|
this.CanBeMoused = false;
|
||||||
}
|
}
|
||||||
|
@ -95,14 +129,29 @@ namespace MLEM.Ui.Elements {
|
||||||
public Image(Anchor anchor, Vector2 size, TextureCallback getTextureCallback, bool scaleToImage = false) : base(anchor, size) {
|
public Image(Anchor anchor, Vector2 size, TextureCallback getTextureCallback, bool scaleToImage = false) : base(anchor, size) {
|
||||||
this.GetTextureCallback = getTextureCallback;
|
this.GetTextureCallback = getTextureCallback;
|
||||||
this.Texture = getTextureCallback(this);
|
this.Texture = getTextureCallback(this);
|
||||||
this.scaleToImage = scaleToImage;
|
this.ScaleToImage = scaleToImage;
|
||||||
this.CanBeSelected = false;
|
this.CanBeSelected = false;
|
||||||
this.CanBeMoused = false;
|
this.CanBeMoused = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override Vector2 CalcActualSize(RectangleF parentArea) {
|
protected override Vector2 CalcActualSize(RectangleF parentArea) {
|
||||||
return this.Texture != null && this.scaleToImage ? this.Texture.Size.ToVector2() * this.Scale : base.CalcActualSize(parentArea);
|
var ret = base.CalcActualSize(parentArea);
|
||||||
|
if (this.Texture != null) {
|
||||||
|
if (this.ScaleToImage)
|
||||||
|
ret = this.Texture.Size.ToVector2() * this.Scale;
|
||||||
|
if (this.SetWidthBasedOnAspect)
|
||||||
|
ret.X = ret.Y * this.Texture.Width / this.Texture.Height + this.ScaledAutoSizeAddedAbsolute.X;
|
||||||
|
if (this.SetHeightBasedOnAspect)
|
||||||
|
ret.Y = ret.X * this.Texture.Height / this.Texture.Width + this.ScaledAutoSizeAddedAbsolute.Y;
|
||||||
|
} else {
|
||||||
|
// if we don't have a texture and we auto-set width or height, calculate as if we had a texture with a size of 0
|
||||||
|
if (this.SetWidthBasedOnAspect)
|
||||||
|
ret.X = this.ScaledAutoSizeAddedAbsolute.X;
|
||||||
|
if (this.SetHeightBasedOnAspect)
|
||||||
|
ret.Y = this.ScaledAutoSizeAddedAbsolute.Y;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -115,6 +164,14 @@ namespace MLEM.Ui.Elements {
|
||||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) {
|
public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) {
|
||||||
if (this.Texture == null)
|
if (this.Texture == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (this.SamplerState != null) {
|
||||||
|
batch.End();
|
||||||
|
var localContext = context;
|
||||||
|
localContext.SamplerState = this.SamplerState;
|
||||||
|
batch.Begin(localContext);
|
||||||
|
}
|
||||||
|
|
||||||
var center = new Vector2(this.Texture.Width / 2F, this.Texture.Height / 2F);
|
var center = new Vector2(this.Texture.Width / 2F, this.Texture.Height / 2F);
|
||||||
var color = this.Color.OrDefault(Microsoft.Xna.Framework.Color.White) * alpha;
|
var color = this.Color.OrDefault(Microsoft.Xna.Framework.Color.White) * alpha;
|
||||||
if (this.MaintainImageAspect) {
|
if (this.MaintainImageAspect) {
|
||||||
|
@ -125,6 +182,12 @@ namespace MLEM.Ui.Elements {
|
||||||
var scale = new Vector2(1F / this.Texture.Width, 1F / this.Texture.Height) * this.DisplayArea.Size;
|
var scale = new Vector2(1F / this.Texture.Width, 1F / this.Texture.Height) * this.DisplayArea.Size;
|
||||||
batch.Draw(this.Texture, this.DisplayArea.Location + center * scale, color, this.ImageRotation, center, scale * this.ImageScale, this.ImageEffects, 0);
|
batch.Draw(this.Texture, this.DisplayArea.Location + center * scale, color, this.ImageRotation, center, scale * this.ImageScale, this.ImageEffects, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.SamplerState != null) {
|
||||||
|
batch.End();
|
||||||
|
batch.Begin(context);
|
||||||
|
}
|
||||||
|
|
||||||
base.Draw(time, batch, alpha, context);
|
base.Draw(time, batch, alpha, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +197,7 @@ namespace MLEM.Ui.Elements {
|
||||||
return;
|
return;
|
||||||
var nullChanged = this.displayedTexture == null != (newTexture == null);
|
var nullChanged = this.displayedTexture == null != (newTexture == null);
|
||||||
this.displayedTexture = newTexture;
|
this.displayedTexture = newTexture;
|
||||||
if (nullChanged || this.scaleToImage)
|
if (nullChanged || this.ScaleToImage || this.SetWidthBasedOnAspect || this.SetHeightBasedOnAspect)
|
||||||
this.SetAreaDirty();
|
this.SetAreaDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,12 +55,16 @@ namespace MLEM.Ui.Elements {
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly List<Element> relevantChildren = new List<Element>();
|
private readonly List<Element> relevantChildren = new List<Element>();
|
||||||
|
private readonly HashSet<Element> scrolledChildren = new HashSet<Element>();
|
||||||
|
private readonly float[] scrollBarMaxHistory;
|
||||||
private readonly bool scrollOverflow;
|
private readonly bool scrollOverflow;
|
||||||
|
|
||||||
private RenderTarget2D renderTarget;
|
private RenderTarget2D renderTarget;
|
||||||
private bool relevantChildrenDirty;
|
private bool relevantChildrenDirty;
|
||||||
private float scrollBarChildOffset;
|
private float scrollBarChildOffset;
|
||||||
private StyleProp<float> scrollBarOffset;
|
private StyleProp<float> scrollBarOffset;
|
||||||
|
private float lastScrollOffset;
|
||||||
|
private bool childrenDirtyForScroll;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new panel with the given settings.
|
/// Creates a new panel with the given settings.
|
||||||
|
@ -70,7 +74,7 @@ namespace MLEM.Ui.Elements {
|
||||||
/// <param name="positionOffset">The panel's offset from its anchor point</param>
|
/// <param name="positionOffset">The panel's offset from its anchor point</param>
|
||||||
/// <param name="setHeightBasedOnChildren">Whether the panel should automatically calculate its height based on its children's size</param>
|
/// <param name="setHeightBasedOnChildren">Whether the panel should automatically calculate its height based on its children's size</param>
|
||||||
/// <param name="scrollOverflow">Whether this panel should automatically add a scroll bar to scroll towards elements that are beyond the area this panel covers</param>
|
/// <param name="scrollOverflow">Whether this panel should automatically add a scroll bar to scroll towards elements that are beyond the area this panel covers</param>
|
||||||
/// <param name="autoHideScrollbar">Whether the scroll bar should be hidden automatically if the panel does not contain enough children to allow for scrolling</param>
|
/// <param name="autoHideScrollbar">Whether the scroll bar should be hidden automatically if the panel does not contain enough children to allow for scrolling. This only has an effect if <paramref name="scrollOverflow"/> is <see langword="true"/>.</param>
|
||||||
public Panel(Anchor anchor, Vector2 size, Vector2 positionOffset, bool setHeightBasedOnChildren = false, bool scrollOverflow = false, bool autoHideScrollbar = true) : base(anchor, size) {
|
public Panel(Anchor anchor, Vector2 size, Vector2 positionOffset, bool setHeightBasedOnChildren = false, bool scrollOverflow = false, bool autoHideScrollbar = true) : base(anchor, size) {
|
||||||
this.PositionOffset = positionOffset;
|
this.PositionOffset = positionOffset;
|
||||||
this.SetHeightBasedOnChildren = setHeightBasedOnChildren;
|
this.SetHeightBasedOnChildren = setHeightBasedOnChildren;
|
||||||
|
@ -94,9 +98,23 @@ namespace MLEM.Ui.Elements {
|
||||||
this.ScrollToElement(e);
|
this.ScrollToElement(e);
|
||||||
};
|
};
|
||||||
this.AddChild(this.ScrollBar);
|
this.AddChild(this.ScrollBar);
|
||||||
|
|
||||||
|
this.scrollBarMaxHistory = new float[3];
|
||||||
|
for (var i = 0; i < this.scrollBarMaxHistory.Length; i++)
|
||||||
|
this.scrollBarMaxHistory[i] = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new panel with the given settings.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="anchor">The panel's anchor</param>
|
||||||
|
/// <param name="size">The panel's default size</param>
|
||||||
|
/// <param name="setHeightBasedOnChildren">Whether the panel should automatically calculate its height based on its children's size</param>
|
||||||
|
/// <param name="scrollOverflow">Whether this panel should automatically add a scroll bar to scroll towards elements that are beyond the area this panel covers</param>
|
||||||
|
/// <param name="autoHideScrollbar">Whether the scroll bar should be hidden automatically if the panel does not contain enough children to allow for scrolling. This only has an effect if <paramref name="scrollOverflow"/> is <see langword="true"/>.</param>
|
||||||
|
public Panel(Anchor anchor, Vector2 size, bool setHeightBasedOnChildren = false, bool scrollOverflow = false, bool autoHideScrollbar = true) : this(anchor, size, Vector2.Zero, setHeightBasedOnChildren, scrollOverflow, autoHideScrollbar) {}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void ForceUpdateArea() {
|
public override void ForceUpdateArea() {
|
||||||
if (this.scrollOverflow) {
|
if (this.scrollOverflow) {
|
||||||
|
@ -106,11 +124,15 @@ namespace MLEM.Ui.Elements {
|
||||||
foreach (var child in this.Children) {
|
foreach (var child in this.Children) {
|
||||||
if (child != this.ScrollBar && !child.Anchor.IsAuto())
|
if (child != this.ScrollBar && !child.Anchor.IsAuto())
|
||||||
throw new NotSupportedException($"A panel that handles overflow can't contain non-automatic anchors ({child})");
|
throw new NotSupportedException($"A panel that handles overflow can't contain non-automatic anchors ({child})");
|
||||||
if (child is Panel panel && panel.scrollOverflow)
|
|
||||||
throw new NotSupportedException($"A panel that scrolls overflow cannot contain another panel that scrolls overflow ({child})");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
base.ForceUpdateArea();
|
base.ForceUpdateArea();
|
||||||
|
if (this.scrollOverflow) {
|
||||||
|
for (var i = 0; i < this.scrollBarMaxHistory.Length; i++)
|
||||||
|
this.scrollBarMaxHistory[i] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
this.SetScrollBarStyle();
|
this.SetScrollBarStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,8 +158,16 @@ namespace MLEM.Ui.Elements {
|
||||||
|
|
||||||
// when removing children, our scroll bar might have to be hidden
|
// when removing children, our scroll bar might have to be hidden
|
||||||
// if we don't do this before adding children again, they might incorrectly assume that the scroll bar will still be visible and adjust their size accordingly
|
// if we don't do this before adding children again, they might incorrectly assume that the scroll bar will still be visible and adjust their size accordingly
|
||||||
if (this.System != null)
|
this.childrenDirtyForScroll = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override T AddChild<T>(T element, int index = -1) {
|
||||||
|
// if children were recently removed, make sure to update the scroll bar before adding new ones so that they can't incorrectly assume the scroll bar will be visible
|
||||||
|
if (this.childrenDirtyForScroll && this.System != null)
|
||||||
this.ScrollSetup();
|
this.ScrollSetup();
|
||||||
|
|
||||||
|
return base.AddChild(element, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -202,10 +232,10 @@ namespace MLEM.Ui.Elements {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="elementY">The y coordinate to scroll to, which should have this element's <see cref="Element.Scale"/> applied.</param>
|
/// <param name="elementY">The y coordinate to scroll to, which should have this element's <see cref="Element.Scale"/> applied.</param>
|
||||||
public void ScrollToElement(float elementY) {
|
public void ScrollToElement(float elementY) {
|
||||||
var firstChild = this.Children.FirstOrDefault(c => c != this.ScrollBar);
|
var highestValidChild = this.Children.FirstOrDefault(c => c != this.ScrollBar && !c.IsHidden);
|
||||||
if (firstChild == null)
|
if (highestValidChild == null)
|
||||||
return;
|
return;
|
||||||
this.ScrollBar.CurrentValue = (elementY - this.Area.Height / 2 - firstChild.Area.Top) / this.Scale + this.ChildPadding.Value.Height / 2;
|
this.ScrollBar.CurrentValue = (elementY - this.Area.Height / 2 - highestValidChild.Area.Top) / this.Scale + this.ChildPadding.Value.Height / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -234,13 +264,12 @@ namespace MLEM.Ui.Elements {
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void OnChildAreaDirty(Element child, bool grandchild) {
|
protected override void OnChildAreaDirty(Element child, bool grandchild) {
|
||||||
base.OnChildAreaDirty(child, grandchild);
|
base.OnChildAreaDirty(child, grandchild);
|
||||||
// we only need to scroll when a grandchild changes, since all of our children are forced
|
if (grandchild && !this.AreaDirty) {
|
||||||
// to be auto-anchored and so will automatically propagate their changes up to us
|
// we only need to scroll when a grandchild changes, since all of our children are forced
|
||||||
if (grandchild) {
|
// to be auto-anchored and so will automatically propagate their changes up to us
|
||||||
this.ScrollChildren();
|
this.ScrollChildren();
|
||||||
// we also need to re-setup here in case the child is involved in a special GetTotalCoveredArea
|
// we also need to re-setup here in case the child is involved in a special GetTotalCoveredArea
|
||||||
if (!this.AreaDirty)
|
this.ScrollSetup();
|
||||||
this.ScrollSetup();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,32 +286,41 @@ namespace MLEM.Ui.Elements {
|
||||||
/// Prepares the panel for auto-scrolling, creating the render target and setting up the scroll bar's maximum value.
|
/// Prepares the panel for auto-scrolling, creating the render target and setting up the scroll bar's maximum value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual void ScrollSetup() {
|
protected virtual void ScrollSetup() {
|
||||||
|
this.childrenDirtyForScroll = false;
|
||||||
|
|
||||||
if (!this.scrollOverflow || this.IsHidden)
|
if (!this.scrollOverflow || this.IsHidden)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float childrenHeight;
|
float childrenHeight;
|
||||||
if (this.Children.Count > 1) {
|
if (this.Children.Count > 1) {
|
||||||
var firstChild = this.Children.FirstOrDefault(c => c != this.ScrollBar);
|
var highestValidChild = this.Children.FirstOrDefault(c => c != this.ScrollBar && !c.IsHidden);
|
||||||
var lowestChild = this.GetLowestChild(c => c != this.ScrollBar && !c.IsHidden, true);
|
var lowestChild = this.GetLowestChild(c => c != this.ScrollBar && !c.IsHidden, true);
|
||||||
childrenHeight = lowestChild.GetTotalCoveredArea(false).Bottom - firstChild.Area.Top;
|
childrenHeight = lowestChild.GetTotalCoveredArea(false).Bottom - highestValidChild.Area.Top;
|
||||||
} else {
|
} else {
|
||||||
// if we only have one child (the scroll bar), then the children take up no visual height
|
// if we only have one child (the scroll bar), then the children take up no visual height
|
||||||
childrenHeight = 0;
|
childrenHeight = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the max value of the scroll bar is the amount of non-scaled pixels taken up by overflowing components
|
// the max value of the scroll bar is the amount of non-scaled pixels taken up by overflowing components
|
||||||
var scrollBarMax = (childrenHeight - this.ChildPaddedArea.Height) / this.Scale;
|
var scrollBarMax = Math.Max(0, (childrenHeight - this.ChildPaddedArea.Height) / this.Scale);
|
||||||
if (!this.ScrollBar.MaxValue.Equals(scrollBarMax, Element.Epsilon)) {
|
if (!this.ScrollBar.MaxValue.Equals(scrollBarMax, Element.Epsilon)) {
|
||||||
this.ScrollBar.MaxValue = scrollBarMax;
|
// avoid a show/hide oscillation that occurs while updating our area with children that can lose height when the scroll bar is shown (like long paragraphs)
|
||||||
this.relevantChildrenDirty = true;
|
if (!this.scrollBarMaxHistory[0].Equals(this.scrollBarMaxHistory[2], Element.Epsilon) || !this.scrollBarMaxHistory[1].Equals(scrollBarMax, Element.Epsilon)) {
|
||||||
|
this.scrollBarMaxHistory[0] = this.scrollBarMaxHistory[1];
|
||||||
|
this.scrollBarMaxHistory[1] = this.scrollBarMaxHistory[2];
|
||||||
|
this.scrollBarMaxHistory[2] = scrollBarMax;
|
||||||
|
|
||||||
|
this.ScrollBar.MaxValue = scrollBarMax;
|
||||||
|
this.relevantChildrenDirty = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update child padding based on whether the scroll bar is visible
|
// update child padding based on whether the scroll bar is visible
|
||||||
var childOffset = this.ScrollBar.IsHidden ? 0 : this.ScrollerSize.Value.X + this.ScrollBarOffset;
|
var childOffset = this.ScrollBar.IsHidden ? 0 : this.ScrollerSize.Value.X + this.ScrollBarOffset;
|
||||||
if (!this.scrollBarChildOffset.Equals(childOffset, Element.Epsilon)) {
|
var childOffsetDelta = childOffset - this.scrollBarChildOffset;
|
||||||
this.ChildPadding += new Padding(0, -this.scrollBarChildOffset + childOffset, 0, 0);
|
if (!childOffsetDelta.Equals(0, Element.Epsilon)) {
|
||||||
this.scrollBarChildOffset = childOffset;
|
this.scrollBarChildOffset = childOffset;
|
||||||
this.SetAreaDirty();
|
this.ChildPadding += new Padding(0, childOffsetDelta, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// the scroller height has the same relation to the scroll bar height as the visible area has to the total height of the panel's content
|
// the scroller height has the same relation to the scroll bar height as the visible area has to the total height of the panel's content
|
||||||
|
@ -290,15 +328,15 @@ namespace MLEM.Ui.Elements {
|
||||||
this.ScrollBar.ScrollerSize = new Vector2(this.ScrollerSize.Value.X, Math.Max(this.ScrollerSize.Value.Y, scrollerHeight));
|
this.ScrollBar.ScrollerSize = new Vector2(this.ScrollerSize.Value.X, Math.Max(this.ScrollerSize.Value.Y, scrollerHeight));
|
||||||
|
|
||||||
// update the render target
|
// update the render target
|
||||||
var targetArea = (Rectangle) this.GetRenderTargetArea();
|
var area = (Rectangle) this.GetRenderTargetArea();
|
||||||
if (targetArea.Width <= 0 || targetArea.Height <= 0) {
|
if (area.Width <= 0 || area.Height <= 0) {
|
||||||
this.renderTarget?.Dispose();
|
this.renderTarget?.Dispose();
|
||||||
this.renderTarget = null;
|
this.renderTarget = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.renderTarget == null || targetArea.Width != this.renderTarget.Width || targetArea.Height != this.renderTarget.Height) {
|
if (this.renderTarget == null || area.Width != this.renderTarget.Width || area.Height != this.renderTarget.Height) {
|
||||||
this.renderTarget?.Dispose();
|
this.renderTarget?.Dispose();
|
||||||
this.renderTarget = targetArea.IsEmpty ? null : new RenderTarget2D(this.System.Game.GraphicsDevice, targetArea.Width, targetArea.Height);
|
this.renderTarget = new RenderTarget2D(this.System.Game.GraphicsDevice, area.Width, area.Height, false, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.PreserveContents);
|
||||||
this.relevantChildrenDirty = true;
|
this.relevantChildrenDirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -330,7 +368,7 @@ namespace MLEM.Ui.Elements {
|
||||||
}
|
}
|
||||||
|
|
||||||
private RectangleF GetRenderTargetArea() {
|
private RectangleF GetRenderTargetArea() {
|
||||||
var area = this.ChildPaddedArea;
|
var area = this.ChildPaddedArea.OffsetCopy(this.ScaledScrollOffset);
|
||||||
area.X = this.DisplayArea.X;
|
area.X = this.DisplayArea.X;
|
||||||
area.Width = this.DisplayArea.Width;
|
area.Width = this.DisplayArea.Width;
|
||||||
return area;
|
return area;
|
||||||
|
@ -339,9 +377,21 @@ namespace MLEM.Ui.Elements {
|
||||||
private void ScrollChildren() {
|
private void ScrollChildren() {
|
||||||
if (!this.scrollOverflow)
|
if (!this.scrollOverflow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var currentChildren = new HashSet<Element>();
|
||||||
|
// scroll all our children (and cache newly added ones)
|
||||||
// we ignore false grandchildren so that the children of the scroll bar stay in place
|
// we ignore false grandchildren so that the children of the scroll bar stay in place
|
||||||
foreach (var child in this.GetChildren(c => c != this.ScrollBar, true, true))
|
foreach (var child in this.GetChildren(c => c != this.ScrollBar, true, true)) {
|
||||||
child.ScrollOffset.Y = -this.ScrollBar.CurrentValue;
|
// if a child was newly added later, the last scroll offset was never applied
|
||||||
|
if (this.scrolledChildren.Add(child))
|
||||||
|
child.ScrollOffset.Y -= this.lastScrollOffset;
|
||||||
|
child.ScrollOffset.Y += (this.lastScrollOffset - this.ScrollBar.CurrentValue);
|
||||||
|
currentChildren.Add(child);
|
||||||
|
}
|
||||||
|
// remove cached scrolled children that aren't our children anymore
|
||||||
|
this.scrolledChildren.IntersectWith(currentChildren);
|
||||||
|
|
||||||
|
this.lastScrollOffset = this.ScrollBar.CurrentValue;
|
||||||
this.relevantChildrenDirty = true;
|
this.relevantChildrenDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,6 +166,30 @@ namespace MLEM.Ui.Elements {
|
||||||
private float textScaleMultiplier = 1;
|
private float textScaleMultiplier = 1;
|
||||||
private bool autoAdjustWidth;
|
private bool autoAdjustWidth;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new paragraph with the given settings.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="anchor">The paragraph's anchor</param>
|
||||||
|
/// <param name="width">The paragraph's width. Note that its height is automatically calculated.</param>
|
||||||
|
/// <param name="textCallback">The paragraph's text</param>
|
||||||
|
/// <param name="alignment">The paragraph's text alignment.</param>
|
||||||
|
/// <param name="autoAdjustWidth">Whether the paragraph's width should automatically be calculated based on the text within it.</param>
|
||||||
|
public Paragraph(Anchor anchor, float width, TextCallback textCallback, TextAlignment alignment, bool autoAdjustWidth = false) : this(anchor, width, textCallback, autoAdjustWidth) {
|
||||||
|
this.Alignment = alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new paragraph with the given settings.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="anchor">The paragraph's anchor</param>
|
||||||
|
/// <param name="width">The paragraph's width. Note that its height is automatically calculated.</param>
|
||||||
|
/// <param name="text">The paragraph's text</param>
|
||||||
|
/// <param name="alignment">The paragraph's text alignment.</param>
|
||||||
|
/// <param name="autoAdjustWidth">Whether the paragraph's width should automatically be calculated based on the text within it.</param>
|
||||||
|
public Paragraph(Anchor anchor, float width, string text, TextAlignment alignment, bool autoAdjustWidth = false) : this(anchor, width, text, autoAdjustWidth) {
|
||||||
|
this.Alignment = alignment;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new paragraph with the given settings.
|
/// Creates a new paragraph with the given settings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -177,7 +201,13 @@ namespace MLEM.Ui.Elements {
|
||||||
this.GetTextCallback = textCallback;
|
this.GetTextCallback = textCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="Paragraph(Anchor,float,TextCallback,bool)"/>
|
/// <summary>
|
||||||
|
/// Creates a new paragraph with the given settings.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="anchor">The paragraph's anchor</param>
|
||||||
|
/// <param name="width">The paragraph's width. Note that its height is automatically calculated.</param>
|
||||||
|
/// <param name="text">The paragraph's text</param>
|
||||||
|
/// <param name="autoAdjustWidth">Whether the paragraph's width should automatically be calculated based on the text within it.</param>
|
||||||
public Paragraph(Anchor anchor, float width, string text, bool autoAdjustWidth = false) : base(anchor, new Vector2(width, 0)) {
|
public Paragraph(Anchor anchor, float width, string text, bool autoAdjustWidth = false) : base(anchor, new Vector2(width, 0)) {
|
||||||
this.Text = text;
|
this.Text = text;
|
||||||
this.AutoAdjustWidth = autoAdjustWidth;
|
this.AutoAdjustWidth = autoAdjustWidth;
|
||||||
|
@ -232,7 +262,7 @@ namespace MLEM.Ui.Elements {
|
||||||
private void SetTextDirty() {
|
private void SetTextDirty() {
|
||||||
this.tokenizedText = null;
|
this.tokenizedText = null;
|
||||||
// only set our area dirty if our size changed as a result of this action
|
// only set our area dirty if our size changed as a result of this action
|
||||||
if (!this.AreaDirty && !this.CalcActualSize(this.ParentArea).Equals(this.DisplayArea.Size, Element.Epsilon))
|
if (!this.AreaDirty && (this.System == null || !this.CalcActualSize(this.ParentArea).Equals(this.DisplayArea.Size, Element.Epsilon)))
|
||||||
this.SetAreaDirty();
|
this.SetAreaDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,7 @@ namespace MLEM.Ui.Elements {
|
||||||
if (this.isMouseScrolling)
|
if (this.isMouseScrolling)
|
||||||
this.ScrollToPos(this.TransformInverseAll(this.Input.ViewportMousePosition.ToVector2()));
|
this.ScrollToPos(this.TransformInverseAll(this.Input.ViewportMousePosition.ToVector2()));
|
||||||
if (!this.Horizontal) {
|
if (!this.Horizontal) {
|
||||||
if (moused != null && (moused == this.Parent || moused.GetParentTree().Contains(this.Parent))) {
|
if (this.IsMousedForScrolling(moused)) {
|
||||||
var scroll = this.Input.LastScrollWheel - this.Input.ScrollWheel;
|
var scroll = this.Input.LastScrollWheel - this.Input.ScrollWheel;
|
||||||
if (scroll != 0)
|
if (scroll != 0)
|
||||||
this.CurrentValue += this.StepPerScroll * Math.Sign(scroll);
|
this.CurrentValue += this.StepPerScroll * Math.Sign(scroll);
|
||||||
|
@ -244,6 +244,23 @@ namespace MLEM.Ui.Elements {
|
||||||
this.SmoothScrollFactor = this.SmoothScrollFactor.OrStyle(style.ScrollBarSmoothScrollFactor);
|
this.SmoothScrollFactor = this.SmoothScrollFactor.OrStyle(style.ScrollBarSmoothScrollFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsMousedForScrolling(Element moused) {
|
||||||
|
if (moused == null || (moused != this.Parent && !moused.GetParentTree().Contains(this.Parent)))
|
||||||
|
return false;
|
||||||
|
// if we're moused, check if there are any scroll bars deeper than us that should take precedence
|
||||||
|
var foundMe = false;
|
||||||
|
foreach (var child in this.Parent.GetChildren(regardGrandchildren: true)) {
|
||||||
|
if (foundMe) {
|
||||||
|
if (child is ScrollBar b && !b.Horizontal && b.IsMousedForScrolling(moused))
|
||||||
|
return false;
|
||||||
|
} else if (child == this) {
|
||||||
|
// once we found ourselves, all subsequent children are deeper/older!
|
||||||
|
foundMe = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A delegate method used for <see cref="ScrollBar.OnValueChanged"/>
|
/// A delegate method used for <see cref="ScrollBar.OnValueChanged"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -204,8 +204,6 @@ namespace MLEM.Ui.Elements {
|
||||||
if (this.IsSelectedActive && !this.IsHidden && !this.textInput.OnTextInput(key, character) && key == Keys.Enter && !this.Multiline)
|
if (this.IsSelectedActive && !this.IsHidden && !this.textInput.OnTextInput(key, character) && key == Keys.Enter && !this.Multiline)
|
||||||
this.EnterReceiver?.Controls?.PressElement(this.EnterReceiver);
|
this.EnterReceiver?.Controls?.PressElement(this.EnterReceiver);
|
||||||
};
|
};
|
||||||
this.OnDeselected += e => this.CaretPos = 0;
|
|
||||||
this.OnSelected += e => this.CaretPos = this.textInput.Length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net452;netstandard2.0;net7.0</TargetFrameworks>
|
<TargetFrameworks>net452;netstandard2.0;net8.0</TargetFrameworks>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
<IsTrimmable>true</IsTrimmable>
|
<IsAotCompatible Condition="'$(TargetFramework)'=='net8.0'">true</IsAotCompatible>
|
||||||
<RootNamespace>MLEM.Ui</RootNamespace>
|
<RootNamespace>MLEM.Ui</RootNamespace>
|
||||||
<DefineConstants>$(DefineConstants);FNA</DefineConstants>
|
<DefineConstants>$(DefineConstants);FNA</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
<PackageReference Include="TextCopy" Version="6.2.0" Condition="'$(TargetFramework)'!='net452'" />
|
<PackageReference Include="TextCopy" Version="6.2.0" Condition="'$(TargetFramework)'!='net452'" />
|
||||||
<ProjectReference Include="..\MLEM\MLEM.FNA.csproj" />
|
<ProjectReference Include="..\MLEM\MLEM.FNA.csproj" />
|
||||||
|
|
||||||
<ProjectReference Include="..\FNA\FNA.csproj">
|
<ProjectReference Include="..\ThirdParty\FNA\FNA.csproj">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net452;netstandard2.0;net7.0</TargetFrameworks>
|
<TargetFrameworks>net452;netstandard2.0;net8.0</TargetFrameworks>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
<IsTrimmable>true</IsTrimmable>
|
<IsAotCompatible Condition="'$(TargetFramework)'=='net8.0'">true</IsAotCompatible>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
|
@ -139,21 +139,32 @@ namespace MLEM.Ui.Parsers {
|
||||||
/// This method invokes an asynchronouns action, meaning the <see cref="Image"/>'s <see cref="Image.Texture"/> will likely not have loaded in when this method returns.
|
/// This method invokes an asynchronouns action, meaning the <see cref="Image"/>'s <see cref="Image.Texture"/> will likely not have loaded in when this method returns.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">The absolute, relative or web path to the image.</param>
|
/// <param name="path">The absolute, relative or web path to the image.</param>
|
||||||
|
/// <param name="onImageFetched">An action that is invoked with the loaded image once it is fetched. Note that this action will be invoked asynchronously.</param>
|
||||||
/// <returns>The loaded image.</returns>
|
/// <returns>The loaded image.</returns>
|
||||||
/// <exception cref="NullReferenceException">Thrown if <see cref="GraphicsDevice"/> is null, or if there is an <see cref="Exception"/> loading the image and <see cref="ImageExceptionHandler"/> is unset.</exception>
|
/// <exception cref="NullReferenceException">Thrown if <see cref="GraphicsDevice"/> is null, or if there is an <see cref="Exception"/> loading the image and <see cref="ImageExceptionHandler"/> is unset.</exception>
|
||||||
protected Image ParseImage(string path) {
|
protected Image ParseImage(string path, Action<TextureRegion> onImageFetched = null) {
|
||||||
if (this.GraphicsDevice == null)
|
if (this.GraphicsDevice == null)
|
||||||
throw new NullReferenceException("A UI parser requires a GraphicsDevice for parsing images");
|
throw new NullReferenceException("A UI parser requires a GraphicsDevice for parsing images");
|
||||||
|
|
||||||
|
var imageLock = new object();
|
||||||
TextureRegion image = null;
|
TextureRegion image = null;
|
||||||
return new Image(Anchor.AutoLeft, new Vector2(1, -1), _ => image) {
|
return new Image(Anchor.AutoLeft, Vector2.One, _ => {
|
||||||
|
lock (imageLock)
|
||||||
|
return image;
|
||||||
|
}) {
|
||||||
|
SetHeightBasedOnAspect = true,
|
||||||
OnAddedToUi = e => {
|
OnAddedToUi = e => {
|
||||||
if (image == null)
|
bool imageNull;
|
||||||
|
lock (imageLock)
|
||||||
|
imageNull = image == null;
|
||||||
|
if (imageNull)
|
||||||
LoadImageAsync();
|
LoadImageAsync();
|
||||||
},
|
},
|
||||||
OnRemovedFromUi = e => {
|
OnRemovedFromUi = e => {
|
||||||
image?.Texture.Dispose();
|
lock (imageLock) {
|
||||||
image = null;
|
image?.Texture.Dispose();
|
||||||
|
image = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -178,7 +189,12 @@ namespace MLEM.Ui.Parsers {
|
||||||
using (var stream = Path.IsPathRooted(path) ? File.OpenRead(path) : TitleContainer.OpenStream(path))
|
using (var stream = Path.IsPathRooted(path) ? File.OpenRead(path) : TitleContainer.OpenStream(path))
|
||||||
tex = Texture2D.FromStream(this.GraphicsDevice, stream);
|
tex = Texture2D.FromStream(this.GraphicsDevice, stream);
|
||||||
}
|
}
|
||||||
image = new TextureRegion(tex);
|
lock (imageLock) {
|
||||||
|
if (image == null) {
|
||||||
|
image = new TextureRegion(tex);
|
||||||
|
onImageFetched?.Invoke(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (this.ImageExceptionHandler != null) {
|
if (this.ImageExceptionHandler != null) {
|
||||||
this.ImageExceptionHandler.Invoke(path, e);
|
this.ImageExceptionHandler.Invoke(path, e);
|
||||||
|
|
|
@ -103,7 +103,7 @@ namespace MLEM.Ui {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HandleGamepad = true;
|
public bool HandleGamepad = true;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If this value is true, the ui controls are in automatic navigation mode.
|
/// If this value is true, the ui controls are in automatic navigation mode. The state of automatic navigation is usually based on the current <see cref="NavType"/>.
|
||||||
/// This means that the <see cref="UiStyle.SelectionIndicator"/> will be drawn around the <see cref="SelectedElement"/>.
|
/// This means that the <see cref="UiStyle.SelectionIndicator"/> will be drawn around the <see cref="SelectedElement"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsAutoNavMode {
|
public bool IsAutoNavMode {
|
||||||
|
@ -115,12 +115,29 @@ namespace MLEM.Ui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// The current <see cref="NavigationType"/> of these ui controls, which represents the last type of interaction that was used to interact with the underlying <see cref="UiSystem"/>.
|
||||||
|
/// </summary>
|
||||||
|
public NavigationType NavType {
|
||||||
|
get => this.navType;
|
||||||
|
set {
|
||||||
|
if (this.navType != value) {
|
||||||
|
var last = this.navType;
|
||||||
|
this.navType = value;
|
||||||
|
this.NavTypeChanged?.Invoke(last, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An event that is raised when <see cref="IsAutoNavMode"/> is changed.
|
/// An event that is raised when <see cref="IsAutoNavMode"/> is changed.
|
||||||
/// This can be used for custom actions like hiding the mouse cursor when automatic navigation is enabled.
|
/// This can be used for custom actions like hiding the mouse cursor when automatic navigation is enabled.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action<bool> AutoNavModeChanged;
|
public event Action<bool> AutoNavModeChanged;
|
||||||
|
/// <summary>
|
||||||
|
/// An event that is raised when <see cref="NavType"/> is changed. It receives the previous navigation type, as well as the newly set navigation type.
|
||||||
|
/// </summary>
|
||||||
|
public event Action<NavigationType, NavigationType> NavTypeChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This value ist true if the <see cref="InputHandler"/> was created by this ui controls instance, or if it was passed in.
|
/// This value ist true if the <see cref="InputHandler"/> was created by this ui controls instance, or if it was passed in.
|
||||||
|
@ -134,6 +151,7 @@ namespace MLEM.Ui {
|
||||||
|
|
||||||
private readonly Dictionary<string, Element> selectedElements = new Dictionary<string, Element>();
|
private readonly Dictionary<string, Element> selectedElements = new Dictionary<string, Element>();
|
||||||
private bool isAutoNavMode;
|
private bool isAutoNavMode;
|
||||||
|
private NavigationType navType;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of the ui controls.
|
/// Creates a new instance of the ui controls.
|
||||||
|
@ -167,6 +185,7 @@ namespace MLEM.Ui {
|
||||||
|
|
||||||
if (this.Input.IsPressedAvailable(MouseButton.Left)) {
|
if (this.Input.IsPressedAvailable(MouseButton.Left)) {
|
||||||
this.IsAutoNavMode = false;
|
this.IsAutoNavMode = false;
|
||||||
|
this.NavType = NavigationType.Mouse;
|
||||||
var selectedNow = mousedNow != null && mousedNow.CanBeSelected ? mousedNow : null;
|
var selectedNow = mousedNow != null && mousedNow.CanBeSelected ? mousedNow : null;
|
||||||
this.SelectElement(this.ActiveRoot, selectedNow);
|
this.SelectElement(this.ActiveRoot, selectedNow);
|
||||||
if (mousedNow != null && mousedNow.CanBePressed) {
|
if (mousedNow != null && mousedNow.CanBePressed) {
|
||||||
|
@ -175,6 +194,7 @@ namespace MLEM.Ui {
|
||||||
}
|
}
|
||||||
} else if (this.Input.IsPressedAvailable(MouseButton.Right)) {
|
} else if (this.Input.IsPressedAvailable(MouseButton.Right)) {
|
||||||
this.IsAutoNavMode = false;
|
this.IsAutoNavMode = false;
|
||||||
|
this.NavType = NavigationType.Mouse;
|
||||||
if (mousedNow != null && mousedNow.CanBePressed) {
|
if (mousedNow != null && mousedNow.CanBePressed) {
|
||||||
this.PressElement(mousedNow, true);
|
this.PressElement(mousedNow, true);
|
||||||
this.Input.TryConsumePressed(MouseButton.Right);
|
this.Input.TryConsumePressed(MouseButton.Right);
|
||||||
|
@ -187,12 +207,14 @@ namespace MLEM.Ui {
|
||||||
if (this.HandleKeyboard) {
|
if (this.HandleKeyboard) {
|
||||||
if (this.KeyboardButtons.IsPressedAvailable(this.Input, this.GamepadIndex)) {
|
if (this.KeyboardButtons.IsPressedAvailable(this.Input, this.GamepadIndex)) {
|
||||||
if (this.SelectedElement?.Root != null && this.SelectedElement.CanBePressed) {
|
if (this.SelectedElement?.Root != null && this.SelectedElement.CanBePressed) {
|
||||||
|
this.NavType = NavigationType.Keyboard;
|
||||||
// primary or secondary action on element using space or enter
|
// primary or secondary action on element using space or enter
|
||||||
this.PressElement(this.SelectedElement, this.Input.IsModifierKeyDown(ModifierKey.Shift));
|
this.PressElement(this.SelectedElement, this.Input.IsModifierKeyDown(ModifierKey.Shift));
|
||||||
this.KeyboardButtons.TryConsumePressed(this.Input, this.GamepadIndex);
|
this.KeyboardButtons.TryConsumePressed(this.Input, this.GamepadIndex);
|
||||||
}
|
}
|
||||||
} else if (this.Input.IsPressedAvailable(Keys.Tab)) {
|
} else if (this.Input.IsPressedAvailable(Keys.Tab)) {
|
||||||
this.IsAutoNavMode = true;
|
this.IsAutoNavMode = true;
|
||||||
|
this.NavType = NavigationType.Keyboard;
|
||||||
// tab or shift-tab to next or previous element
|
// tab or shift-tab to next or previous element
|
||||||
var backward = this.Input.IsModifierKeyDown(ModifierKey.Shift);
|
var backward = this.Input.IsModifierKeyDown(ModifierKey.Shift);
|
||||||
var next = this.GetTabNextElement(backward);
|
var next = this.GetTabNextElement(backward);
|
||||||
|
@ -208,12 +230,14 @@ namespace MLEM.Ui {
|
||||||
if (this.HandleTouch) {
|
if (this.HandleTouch) {
|
||||||
if (this.Input.GetViewportGesture(GestureType.Tap, out var tap)) {
|
if (this.Input.GetViewportGesture(GestureType.Tap, out var tap)) {
|
||||||
this.IsAutoNavMode = false;
|
this.IsAutoNavMode = false;
|
||||||
|
this.NavType = NavigationType.Touch;
|
||||||
var tapped = this.GetElementUnderPos(tap.Position);
|
var tapped = this.GetElementUnderPos(tap.Position);
|
||||||
this.SelectElement(this.ActiveRoot, tapped);
|
this.SelectElement(this.ActiveRoot, tapped);
|
||||||
if (tapped != null && tapped.CanBePressed)
|
if (tapped != null && tapped.CanBePressed)
|
||||||
this.PressElement(tapped);
|
this.PressElement(tapped);
|
||||||
} else if (this.Input.GetViewportGesture(GestureType.Hold, out var hold)) {
|
} else if (this.Input.GetViewportGesture(GestureType.Hold, out var hold)) {
|
||||||
this.IsAutoNavMode = false;
|
this.IsAutoNavMode = false;
|
||||||
|
this.NavType = NavigationType.Touch;
|
||||||
var held = this.GetElementUnderPos(hold.Position);
|
var held = this.GetElementUnderPos(hold.Position);
|
||||||
this.SelectElement(this.ActiveRoot, held);
|
this.SelectElement(this.ActiveRoot, held);
|
||||||
if (held != null && held.CanBePressed)
|
if (held != null && held.CanBePressed)
|
||||||
|
@ -224,6 +248,7 @@ namespace MLEM.Ui {
|
||||||
foreach (var location in this.Input.ViewportTouchState) {
|
foreach (var location in this.Input.ViewportTouchState) {
|
||||||
var element = this.GetElementUnderPos(location.Position);
|
var element = this.GetElementUnderPos(location.Position);
|
||||||
if (location.State == TouchLocationState.Pressed) {
|
if (location.State == TouchLocationState.Pressed) {
|
||||||
|
this.NavType = NavigationType.Touch;
|
||||||
// start touching an element if we just touched down on it
|
// start touching an element if we just touched down on it
|
||||||
this.SetTouchedElement(element);
|
this.SetTouchedElement(element);
|
||||||
} else if (element != this.TouchedElement) {
|
} else if (element != this.TouchedElement) {
|
||||||
|
@ -239,11 +264,13 @@ namespace MLEM.Ui {
|
||||||
if (this.HandleGamepad) {
|
if (this.HandleGamepad) {
|
||||||
if (this.GamepadButtons.IsPressedAvailable(this.Input, this.GamepadIndex)) {
|
if (this.GamepadButtons.IsPressedAvailable(this.Input, this.GamepadIndex)) {
|
||||||
if (this.SelectedElement?.Root != null && this.SelectedElement.CanBePressed) {
|
if (this.SelectedElement?.Root != null && this.SelectedElement.CanBePressed) {
|
||||||
|
this.NavType = NavigationType.Gamepad;
|
||||||
this.PressElement(this.SelectedElement);
|
this.PressElement(this.SelectedElement);
|
||||||
this.GamepadButtons.TryConsumePressed(this.Input, this.GamepadIndex);
|
this.GamepadButtons.TryConsumePressed(this.Input, this.GamepadIndex);
|
||||||
}
|
}
|
||||||
} else if (this.SecondaryGamepadButtons.IsPressedAvailable(this.Input, this.GamepadIndex)) {
|
} else if (this.SecondaryGamepadButtons.IsPressedAvailable(this.Input, this.GamepadIndex)) {
|
||||||
if (this.SelectedElement?.Root != null && this.SelectedElement.CanBePressed) {
|
if (this.SelectedElement?.Root != null && this.SelectedElement.CanBePressed) {
|
||||||
|
this.NavType = NavigationType.Gamepad;
|
||||||
this.PressElement(this.SelectedElement, true);
|
this.PressElement(this.SelectedElement, true);
|
||||||
this.SecondaryGamepadButtons.TryConsumePressed(this.Input, this.GamepadIndex);
|
this.SecondaryGamepadButtons.TryConsumePressed(this.Input, this.GamepadIndex);
|
||||||
}
|
}
|
||||||
|
@ -286,8 +313,9 @@ namespace MLEM.Ui {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="root">The root element of the <see cref="Element"/></param>
|
/// <param name="root">The root element of the <see cref="Element"/></param>
|
||||||
/// <param name="element">The element to select, or null to deselect the selected element.</param>
|
/// <param name="element">The element to select, or null to deselect the selected element.</param>
|
||||||
/// <param name="autoNav">Whether automatic navigation should be forced on</param>
|
/// <param name="autoNav">Whether automatic navigation should be forced on. If this is <see langword="null"/>, the automatic navigation state will stay the same.</param>
|
||||||
public void SelectElement(RootElement root, Element element, bool? autoNav = null) {
|
/// <param name="navType">An optional <see cref="NavigationType"/> to set. If this is <see langword="null"/>, the navigation type will stay the same.</param>
|
||||||
|
public void SelectElement(RootElement root, Element element, bool? autoNav = null, NavigationType? navType = null) {
|
||||||
if (root == null)
|
if (root == null)
|
||||||
return;
|
return;
|
||||||
if (element != null && !element.CanBeSelected)
|
if (element != null && !element.CanBeSelected)
|
||||||
|
@ -308,6 +336,8 @@ namespace MLEM.Ui {
|
||||||
|
|
||||||
if (autoNav != null)
|
if (autoNav != null)
|
||||||
this.IsAutoNavMode = autoNav.Value;
|
this.IsAutoNavMode = autoNav.Value;
|
||||||
|
if (navType != null)
|
||||||
|
this.NavType = navType.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -444,6 +474,7 @@ namespace MLEM.Ui {
|
||||||
|
|
||||||
private bool HandleGamepadNextElement(Direction2 dir) {
|
private bool HandleGamepadNextElement(Direction2 dir) {
|
||||||
this.IsAutoNavMode = true;
|
this.IsAutoNavMode = true;
|
||||||
|
this.NavType = NavigationType.Gamepad;
|
||||||
var next = this.GetGamepadNextElement(dir);
|
var next = this.GetGamepadNextElement(dir);
|
||||||
if (this.SelectedElement != null)
|
if (this.SelectedElement != null)
|
||||||
next = this.SelectedElement.GetGamepadNextElement(dir, next);
|
next = this.SelectedElement.GetGamepadNextElement(dir, next);
|
||||||
|
@ -454,5 +485,34 @@ namespace MLEM.Ui {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An enumeration type that represents the possible types of navigation that a <see cref="UiControls"/> instance supports.
|
||||||
|
/// This is used by <see cref="UiControls.NavType"/>, which stores the most recently used navigation type for a <see cref="UiSystem"/>.
|
||||||
|
/// </summary>
|
||||||
|
public enum NavigationType {
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An unknown navigation type, which usually means there has not been any ui navigation of any type yet.
|
||||||
|
/// </summary>
|
||||||
|
Unknown = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// Mouse cursor and mouse button navigation.
|
||||||
|
/// </summary>
|
||||||
|
Mouse,
|
||||||
|
/// <summary>
|
||||||
|
/// Keyboard navigation.
|
||||||
|
/// </summary>
|
||||||
|
Keyboard,
|
||||||
|
/// <summary>
|
||||||
|
/// Touch and gesture navigation.
|
||||||
|
/// </summary>
|
||||||
|
Touch,
|
||||||
|
/// <summary>
|
||||||
|
/// Gamepad-style navigation, which may also include arrow key-based navigation based on current <see cref="UiControls"/> settings.
|
||||||
|
/// </summary>
|
||||||
|
Gamepad
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -608,9 +608,10 @@ namespace MLEM.Ui {
|
||||||
/// Optionally, automatic navigation can be forced on, causing the <see cref="UiStyle.SelectionIndicator"/> to be drawn around the element.
|
/// Optionally, automatic navigation can be forced on, causing the <see cref="UiStyle.SelectionIndicator"/> to be drawn around the element.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="element">The element to select, or null to deselect the selected element.</param>
|
/// <param name="element">The element to select, or null to deselect the selected element.</param>
|
||||||
/// <param name="autoNav">Whether automatic navigation should be forced on</param>
|
/// <param name="autoNav">Whether automatic navigation should be forced on. If this is <see langword="null"/>, the automatic navigation state will stay the same.</param>
|
||||||
public void SelectElement(Element element, bool? autoNav = null) {
|
/// <param name="navType">An optional <see cref="UiControls.NavigationType"/> to set. If this is <see langword="null"/>, the navigation type will stay the same.</param>
|
||||||
this.System.Controls.SelectElement(this, element, autoNav);
|
public void SelectElement(Element element, bool? autoNav = null, UiControls.NavigationType? navType = null) {
|
||||||
|
this.System.Controls.SelectElement(this, element, autoNav, navType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
@ -36,6 +37,27 @@ namespace MLEM.Extensions {
|
||||||
return new Color(color.ToVector4() * other.ToVector4());
|
return new Color(color.ToVector4() * other.ToVector4());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the hexadecimal representation of this color as a string in the format <c>#AARRGGBB</c>, or optionally <c>AARRGGBB</c>, without the pound symbol.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">The color to convert.</param>
|
||||||
|
/// <param name="hash">Whether a # should prepend the string.</param>
|
||||||
|
/// <returns>The resulting hex string.</returns>
|
||||||
|
public static string ToHexStringRgba(this Color color, bool hash = true) {
|
||||||
|
return $"{(hash ? "#" : string.Empty)}{color.A:X2}{color.R:X2}{color.G:X2}{color.B:X2}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the hexadecimal representation of this color as a string in the format <c>#RRGGBB</c>, or optionally <c>RRGGBB</c>, without the pound symbol.
|
||||||
|
/// The alpha channel is ignored.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">The color to convert.</param>
|
||||||
|
/// <param name="hash">Whether a # should prepend the string.</param>
|
||||||
|
/// <returns>The resulting hex string.</returns>
|
||||||
|
public static string ToHexStringRgb(this Color color, bool hash = true) {
|
||||||
|
return $"{(hash ? "#" : string.Empty)}{color.R:X2}{color.G:X2}{color.B:X2}";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -64,16 +86,34 @@ namespace MLEM.Extensions {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parses a hexadecimal string into a color.
|
/// Parses a hexadecimal string into a color and throws a <see cref="FormatException"/> if parsing fails.
|
||||||
/// The string can either be formatted as RRGGBB or AARRGGBB and can optionally start with a <c>#</c>.
|
/// The string can either be formatted as <c>RRGGBB</c> or <c>AARRGGBB</c> and can optionally start with a <c>#</c>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">The string to parse.</param>
|
/// <param name="value">The string to parse.</param>
|
||||||
/// <returns>The resulting color.</returns>
|
/// <returns>The resulting color.</returns>
|
||||||
|
/// <exception cref="FormatException">Thrown if parsing fails.</exception>
|
||||||
public static Color FromHexString(string value) {
|
public static Color FromHexString(string value) {
|
||||||
|
if (!ColorHelper.TryFromHexString(value, out var val))
|
||||||
|
throw new FormatException($"Cannot parse hex string {value}");
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to parse a hexadecimal string into a color and returns whether a color was successfully parsed.
|
||||||
|
/// The string can either be formatted as <c>RRGGBB</c> or <c>AARRGGBB</c> and can optionally start with a <c>#</c>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The string to parse.</param>
|
||||||
|
/// <param name="color">The resulting color.</param>
|
||||||
|
/// <returns>Whether parsing was successful.</returns>
|
||||||
|
public static bool TryFromHexString(string value, out Color color) {
|
||||||
if (value.StartsWith("#"))
|
if (value.StartsWith("#"))
|
||||||
value = value.Substring(1);
|
value = value.Substring(1);
|
||||||
var val = int.Parse(value, NumberStyles.HexNumber);
|
if (int.TryParse(value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var val)) {
|
||||||
return value.Length > 6 ? ColorHelper.FromHexRgba(val) : ColorHelper.FromHexRgb(val);
|
color = value.Length > 6 ? ColorHelper.FromHexRgba(val) : ColorHelper.FromHexRgb(val);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
color = default;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,11 +69,22 @@ namespace MLEM.Extensions {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="device">The graphics device</param>
|
/// <param name="device">The graphics device</param>
|
||||||
/// <param name="target">The render target to apply</param>
|
/// <param name="target">The render target to apply</param>
|
||||||
/// <returns></returns>
|
/// <returns>The render target context, to be used in a <c>using</c> statement</returns>
|
||||||
public static TargetContext WithRenderTarget(this GraphicsDevice device, RenderTarget2D target) {
|
public static TargetContext WithRenderTarget(this GraphicsDevice device, RenderTarget2D target) {
|
||||||
return new TargetContext(device, target);
|
return new TargetContext(device, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts a new <see cref="TargetContext"/> using the specified render target bindings.
|
||||||
|
/// The returned context automatically disposes when used in a <c>using</c> statement, which causes any previously applied render targets to be reapplied automatically.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="device">The graphics device</param>
|
||||||
|
/// <param name="targets">The render targets to apply</param>
|
||||||
|
/// <returns>The render target context, to be used in a <c>using</c> statement</returns>
|
||||||
|
public static TargetContext WithRenderTargets(this GraphicsDevice device, params RenderTargetBinding[] targets) {
|
||||||
|
return new TargetContext(device, targets);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a context in which a <see cref="RenderTarget2D"/> is applied.
|
/// Represents a context in which a <see cref="RenderTarget2D"/> is applied.
|
||||||
/// This class should be used with <see cref="GraphicsExtensions.WithRenderTarget"/>.
|
/// This class should be used with <see cref="GraphicsExtensions.WithRenderTarget"/>.
|
||||||
|
@ -88,7 +99,20 @@ namespace MLEM.Extensions {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="device">The graphics device to apply the target on</param>
|
/// <param name="device">The graphics device to apply the target on</param>
|
||||||
/// <param name="target">The target to apply</param>
|
/// <param name="target">The target to apply</param>
|
||||||
public TargetContext(GraphicsDevice device, RenderTarget2D target) {
|
public TargetContext(GraphicsDevice device, RenderTarget2D target) : this(device) {
|
||||||
|
device.SetRenderTarget(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new target context with the given settings.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="device">The graphics device to apply the target on</param>
|
||||||
|
/// <param name="targets">The targets to apply</param>
|
||||||
|
public TargetContext(GraphicsDevice device, RenderTargetBinding[] targets) : this(device) {
|
||||||
|
device.SetRenderTargets(targets);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TargetContext(GraphicsDevice device) {
|
||||||
this.device = device;
|
this.device = device;
|
||||||
#if FNA
|
#if FNA
|
||||||
// RenderTargetCount doesn't exist in FNA but we still want the optimization in MG
|
// RenderTargetCount doesn't exist in FNA but we still want the optimization in MG
|
||||||
|
@ -96,7 +120,6 @@ namespace MLEM.Extensions {
|
||||||
#else
|
#else
|
||||||
this.lastTargets = device.RenderTargetCount <= 0 ? null : device.GetRenderTargets();
|
this.lastTargets = device.RenderTargetCount <= 0 ? null : device.GetRenderTargets();
|
||||||
#endif
|
#endif
|
||||||
device.SetRenderTarget(target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -16,8 +16,7 @@ namespace MLEM.Extensions {
|
||||||
/// <typeparam name="T">The entries' type</typeparam>
|
/// <typeparam name="T">The entries' type</typeparam>
|
||||||
/// <returns>A random entry</returns>
|
/// <returns>A random entry</returns>
|
||||||
public static T GetRandomEntry<T>(this Random random, ICollection<T> entries) {
|
public static T GetRandomEntry<T>(this Random random, ICollection<T> entries) {
|
||||||
// ElementAt internally optimizes for IList access so we don't have to here
|
return RandomExtensions.GetRandomEntry(entries, random.NextSingle());
|
||||||
return entries.ElementAt(random.Next(entries.Count));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -31,28 +30,12 @@ namespace MLEM.Extensions {
|
||||||
/// <returns>A random entry, based on the entries' weight</returns>
|
/// <returns>A random entry, based on the entries' weight</returns>
|
||||||
/// <exception cref="IndexOutOfRangeException">If the weight function returns different weights for the same entry</exception>
|
/// <exception cref="IndexOutOfRangeException">If the weight function returns different weights for the same entry</exception>
|
||||||
public static T GetRandomWeightedEntry<T>(this Random random, ICollection<T> entries, Func<T, int> weightFunc) {
|
public static T GetRandomWeightedEntry<T>(this Random random, ICollection<T> entries, Func<T, int> weightFunc) {
|
||||||
var totalWeight = entries.Sum(weightFunc);
|
return RandomExtensions.GetRandomWeightedEntry(entries, weightFunc, random.NextSingle());
|
||||||
var goalWeight = random.Next(totalWeight);
|
|
||||||
var currWeight = 0;
|
|
||||||
foreach (var entry in entries) {
|
|
||||||
currWeight += weightFunc(entry);
|
|
||||||
if (currWeight > goalWeight)
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
throw new IndexOutOfRangeException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="GetRandomWeightedEntry{T}(System.Random,System.Collections.Generic.ICollection{T},System.Func{T,int})"/>
|
/// <inheritdoc cref="GetRandomWeightedEntry{T}(System.Random,System.Collections.Generic.ICollection{T},System.Func{T,int})"/>
|
||||||
public static T GetRandomWeightedEntry<T>(this Random random, ICollection<T> entries, Func<T, float> weightFunc) {
|
public static T GetRandomWeightedEntry<T>(this Random random, ICollection<T> entries, Func<T, float> weightFunc) {
|
||||||
var totalWeight = entries.Sum(weightFunc);
|
return RandomExtensions.GetRandomWeightedEntry(entries, weightFunc, random.NextSingle());
|
||||||
var goalWeight = random.NextDouble() * totalWeight;
|
|
||||||
var currWeight = 0F;
|
|
||||||
foreach (var entry in entries) {
|
|
||||||
currWeight += weightFunc(entry);
|
|
||||||
if (currWeight > goalWeight)
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
throw new IndexOutOfRangeException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -87,5 +70,32 @@ namespace MLEM.Extensions {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
internal static T GetRandomEntry<T>(ICollection<T> entries, float randomValue) {
|
||||||
|
// ElementAt internally optimizes for IList access so we don't have to here
|
||||||
|
return entries.ElementAt((int) (randomValue * entries.Count));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static T GetRandomWeightedEntry<T>(ICollection<T> entries, Func<T, int> weightFunc, float randomValue) {
|
||||||
|
var goalWeight = randomValue * entries.Sum(weightFunc);
|
||||||
|
var currWeight = 0;
|
||||||
|
foreach (var entry in entries) {
|
||||||
|
currWeight += weightFunc(entry);
|
||||||
|
if (currWeight > goalWeight)
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
throw new IndexOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static T GetRandomWeightedEntry<T>(ICollection<T> entries, Func<T, float> weightFunc, float randomValue) {
|
||||||
|
var goalWeight = randomValue * entries.Sum(weightFunc);
|
||||||
|
var currWeight = 0F;
|
||||||
|
foreach (var entry in entries) {
|
||||||
|
currWeight += weightFunc(entry);
|
||||||
|
if (currWeight > goalWeight)
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
throw new IndexOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,18 @@ namespace MLEM.Font {
|
||||||
return (curr, 1);
|
return (curr, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns an index in this code point source that is as close to <paramref name="index"/> as possible, but not between two members of a surrogate pair. If the <paramref name="index"/> is already not between surrogate pairs, it is returned unchanged.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The index to ensure is not between surrogates.</param>
|
||||||
|
/// <param name="increase">Whether the returned index should be increased by 1 (instead of decreased by 1) when it is between surrogates.</param>
|
||||||
|
/// <returns>An index close to <paramref name="index"/>, but not between surrogates.</returns>
|
||||||
|
public int EnsureSurrogateBoundary(int index, bool increase) {
|
||||||
|
if (index < this.Length && char.IsLowSurrogate(this[index]))
|
||||||
|
return increase || index <= 0 ? index + 1 : index - 1;
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Returns an enumerator that iterates through the collection.</summary>
|
/// <summary>Returns an enumerator that iterates through the collection.</summary>
|
||||||
/// <returns>A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.</returns>
|
/// <returns>A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.</returns>
|
||||||
/// <filterpriority>1</filterpriority>
|
/// <filterpriority>1</filterpriority>
|
||||||
|
|
|
@ -23,9 +23,9 @@ namespace MLEM.Formatting.Codes {
|
||||||
public readonly Match Match;
|
public readonly Match Match;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The tokens that this formatting code is a part of.
|
/// The tokens that this formatting code is a part of.
|
||||||
/// Note that this array only has multiple entries if additional tokens have to be started while this code is still applied.
|
/// Note that this collection only has multiple entries if additional tokens have to be started while this code is still applied.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IList<Token> Tokens { get; internal set; }
|
public readonly List<Token> Tokens = new List<Token>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new formatting code based on a formatting code regex and its match.
|
/// Creates a new formatting code based on a formatting code regex and its match.
|
||||||
|
|
|
@ -18,5 +18,11 @@ namespace MLEM.Formatting.Codes {
|
||||||
return this.font?.Invoke(defaultPick);
|
return this.font?.Invoke(defaultPick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool EndsHere(Code other) {
|
||||||
|
// turning a string bold/italic should only end when that specific code is ended using SimpleEndCode
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ namespace MLEM.Formatting {
|
||||||
this.Codes.Add(new Regex("<b>"), (f, m, r) => new FontCode(m, r, fnt => fnt.Bold));
|
this.Codes.Add(new Regex("<b>"), (f, m, r) => new FontCode(m, r, fnt => fnt.Bold));
|
||||||
this.Codes.Add(new Regex("<i>"), (f, m, r) => new FontCode(m, r, fnt => fnt.Italic));
|
this.Codes.Add(new Regex("<i>"), (f, m, r) => new FontCode(m, r, fnt => fnt.Italic));
|
||||||
this.Codes.Add(new Regex(@"<s(?: #([0-9\w]{6,8}) (([+-.0-9]*)))?>"), (f, m, r) => new ShadowCode(m, r,
|
this.Codes.Add(new Regex(@"<s(?: #([0-9\w]{6,8}) (([+-.0-9]*)))?>"), (f, m, r) => new ShadowCode(m, r,
|
||||||
m.Groups[1].Success ? ColorHelper.FromHexString(m.Groups[1].Value) : this.DefaultShadowColor,
|
ColorHelper.TryFromHexString(m.Groups[1].Value, out var color) ? color : this.DefaultShadowColor,
|
||||||
float.TryParse(m.Groups[2].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var offset) ? new Vector2(offset) : this.DefaultShadowOffset));
|
float.TryParse(m.Groups[2].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var offset) ? new Vector2(offset) : this.DefaultShadowOffset));
|
||||||
this.Codes.Add(new Regex("<u>"), (f, m, r) => new UnderlineCode(m, r, this.LineThickness, this.UnderlineOffset));
|
this.Codes.Add(new Regex("<u>"), (f, m, r) => new UnderlineCode(m, r, this.LineThickness, this.UnderlineOffset));
|
||||||
this.Codes.Add(new Regex("<st>"), (f, m, r) => new UnderlineCode(m, r, this.LineThickness, this.StrikethroughOffset));
|
this.Codes.Add(new Regex("<st>"), (f, m, r) => new UnderlineCode(m, r, this.LineThickness, this.StrikethroughOffset));
|
||||||
|
@ -111,7 +111,7 @@ namespace MLEM.Formatting {
|
||||||
this.Codes.Add(new Regex(@"<sup(?: ([+-.0-9]+))?>"), (f, m, r) => new SubSupCode(m, r,
|
this.Codes.Add(new Regex(@"<sup(?: ([+-.0-9]+))?>"), (f, m, r) => new SubSupCode(m, r,
|
||||||
float.TryParse(m.Groups[1].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var off) ? -off : this.DefaultSupOffset));
|
float.TryParse(m.Groups[1].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var off) ? -off : this.DefaultSupOffset));
|
||||||
this.Codes.Add(new Regex(@"<o(?: #([0-9\w]{6,8}) (([+-.0-9]*)))?>"), (f, m, r) => new OutlineCode(m, r,
|
this.Codes.Add(new Regex(@"<o(?: #([0-9\w]{6,8}) (([+-.0-9]*)))?>"), (f, m, r) => new OutlineCode(m, r,
|
||||||
m.Groups[1].Success ? ColorHelper.FromHexString(m.Groups[1].Value) : this.DefaultOutlineColor,
|
ColorHelper.TryFromHexString(m.Groups[1].Value, out var color) ? color : this.DefaultOutlineColor,
|
||||||
float.TryParse(m.Groups[2].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var thickness) ? thickness : this.DefaultOutlineThickness,
|
float.TryParse(m.Groups[2].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var thickness) ? thickness : this.DefaultOutlineThickness,
|
||||||
this.OutlineDiagonals));
|
this.OutlineDiagonals));
|
||||||
}
|
}
|
||||||
|
@ -124,12 +124,13 @@ namespace MLEM.Formatting {
|
||||||
this.Codes.Add(new Regex($"<c {c.Name}>"), (f, m, r) => new ColorCode(m, r, value));
|
this.Codes.Add(new Regex($"<c {c.Name}>"), (f, m, r) => new ColorCode(m, r, value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.Codes.Add(new Regex(@"<c #([0-9\w]{6,8})>"), (f, m, r) => new ColorCode(m, r, ColorHelper.FromHexString(m.Groups[1].Value)));
|
this.Codes.Add(new Regex(@"<c #([0-9\w]{6,8})>"), (f, m, r) => new ColorCode(m, r,
|
||||||
|
ColorHelper.TryFromHexString(m.Groups[1].Value, out var color) ? color : Color.Red));
|
||||||
}
|
}
|
||||||
|
|
||||||
// animation codes
|
// animation codes
|
||||||
if (hasAnimations) {
|
if (hasAnimations) {
|
||||||
this.Codes.Add(new Regex(@"<a wobbly(?: ([+-.0-9]*) ([+-.0-9]*))?>"), (f, m, r) => new WobblyCode(m, r,
|
this.Codes.Add(new Regex("<a wobbly(?: ([+-.0-9]*) ([+-.0-9]*))?>"), (f, m, r) => new WobblyCode(m, r,
|
||||||
float.TryParse(m.Groups[1].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var mod) ? mod : this.DefaultWobblyModifier,
|
float.TryParse(m.Groups[1].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var mod) ? mod : this.DefaultWobblyModifier,
|
||||||
float.TryParse(m.Groups[2].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var heightMod) ? heightMod : this.DefaultWobblyHeight));
|
float.TryParse(m.Groups[2].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var heightMod) ? heightMod : this.DefaultWobblyHeight));
|
||||||
}
|
}
|
||||||
|
@ -155,11 +156,12 @@ namespace MLEM.Formatting {
|
||||||
// resolve macros
|
// resolve macros
|
||||||
s = this.ResolveMacros(s);
|
s = this.ResolveMacros(s);
|
||||||
var tokens = new List<Token>();
|
var tokens = new List<Token>();
|
||||||
var codes = new List<Code>();
|
var applied = new List<Code>();
|
||||||
|
var allCodes = new List<Code>();
|
||||||
// add the formatting code right at the start of the string
|
// add the formatting code right at the start of the string
|
||||||
var firstCode = this.GetNextCode(s, 0, 0);
|
var firstCode = this.GetNextCode(s, 0, 0);
|
||||||
if (firstCode != null)
|
if (firstCode != null)
|
||||||
codes.Add(firstCode);
|
applied.Add(firstCode);
|
||||||
var index = 0;
|
var index = 0;
|
||||||
var rawIndex = 0;
|
var rawIndex = 0;
|
||||||
while (rawIndex < s.Length) {
|
while (rawIndex < s.Length) {
|
||||||
|
@ -167,24 +169,25 @@ namespace MLEM.Formatting {
|
||||||
// if we've reached the end of the string
|
// if we've reached the end of the string
|
||||||
if (next == null) {
|
if (next == null) {
|
||||||
var sub = s.Substring(rawIndex, s.Length - rawIndex);
|
var sub = s.Substring(rawIndex, s.Length - rawIndex);
|
||||||
tokens.Add(new Token(codes.ToArray(), index, rawIndex, TextFormatter.StripFormatting(font, sub, codes), sub));
|
tokens.Add(new Token(applied.ToArray(), index, rawIndex, TextFormatter.StripFormatting(font, sub, applied), sub));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
allCodes.Add(next);
|
||||||
|
|
||||||
// create a new token for the content up to the next code
|
// create a new token for the content up to the next code
|
||||||
var ret = s.Substring(rawIndex, next.Match.Index - rawIndex);
|
var ret = s.Substring(rawIndex, next.Match.Index - rawIndex);
|
||||||
var strippedRet = TextFormatter.StripFormatting(font, ret, codes);
|
var strippedRet = TextFormatter.StripFormatting(font, ret, applied);
|
||||||
tokens.Add(new Token(codes.ToArray(), index, rawIndex, strippedRet, ret));
|
tokens.Add(new Token(applied.ToArray(), index, rawIndex, strippedRet, ret));
|
||||||
|
|
||||||
// move to the start of the next code
|
// move to the start of the next code
|
||||||
rawIndex = next.Match.Index;
|
rawIndex = next.Match.Index;
|
||||||
index += strippedRet.Length;
|
index += strippedRet.Length;
|
||||||
|
|
||||||
// remove all codes that are incompatible with the next one and apply it
|
// remove all codes that are incompatible with the next one and apply it
|
||||||
codes.RemoveAll(c => c.EndsHere(next) || next.EndsOther(c));
|
applied.RemoveAll(c => c.EndsHere(next) || next.EndsOther(c));
|
||||||
codes.Add(next);
|
applied.Add(next);
|
||||||
}
|
}
|
||||||
return new TokenizedString(font, alignment, s, TextFormatter.StripFormatting(font, s, tokens.SelectMany(t => t.AppliedCodes)), tokens.ToArray());
|
return new TokenizedString(font, alignment, s, TextFormatter.StripFormatting(font, s, allCodes), tokens.ToArray(), allCodes.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
|
@ -14,6 +15,7 @@ namespace MLEM.Formatting {
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The formatting codes that are applied on this token.
|
/// The formatting codes that are applied on this token.
|
||||||
|
/// Codes are stored application order, with the first entry in the array being the code that was most recently applied.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly Code[] AppliedCodes;
|
public readonly Code[] AppliedCodes;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -45,11 +47,14 @@ namespace MLEM.Formatting {
|
||||||
internal float[] InnerOffsets;
|
internal float[] InnerOffsets;
|
||||||
|
|
||||||
internal Token(Code[] appliedCodes, int index, int rawIndex, string substring, string rawSubstring) {
|
internal Token(Code[] appliedCodes, int index, int rawIndex, string substring, string rawSubstring) {
|
||||||
|
Array.Reverse(appliedCodes);
|
||||||
this.AppliedCodes = appliedCodes;
|
this.AppliedCodes = appliedCodes;
|
||||||
this.Index = index;
|
this.Index = index;
|
||||||
this.RawIndex = rawIndex;
|
this.RawIndex = rawIndex;
|
||||||
this.Substring = substring;
|
this.Substring = substring;
|
||||||
this.RawSubstring = rawSubstring;
|
this.RawSubstring = rawSubstring;
|
||||||
|
foreach (var code in appliedCodes)
|
||||||
|
code.Tokens.Add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using MLEM.Extensions;
|
|
||||||
using MLEM.Font;
|
using MLEM.Font;
|
||||||
using MLEM.Formatting.Codes;
|
using MLEM.Formatting.Codes;
|
||||||
using MLEM.Misc;
|
using MLEM.Misc;
|
||||||
|
@ -42,17 +40,11 @@ namespace MLEM.Formatting {
|
||||||
private float initialInnerOffset;
|
private float initialInnerOffset;
|
||||||
private RectangleF area;
|
private RectangleF area;
|
||||||
|
|
||||||
internal TokenizedString(GenericFont font, TextAlignment alignment, string rawString, string strg, Token[] tokens) {
|
internal TokenizedString(GenericFont font, TextAlignment alignment, string rawString, string strg, Token[] tokens, Code[] allCodes) {
|
||||||
this.RawString = rawString;
|
this.RawString = rawString;
|
||||||
this.String = strg;
|
this.String = strg;
|
||||||
this.Tokens = tokens;
|
this.Tokens = tokens;
|
||||||
|
this.AllCodes = allCodes;
|
||||||
// since a code can be present in multiple tokens, we use Distinct here
|
|
||||||
this.AllCodes = tokens.SelectMany(t => t.AppliedCodes).Distinct().ToArray();
|
|
||||||
// TODO this can probably be optimized by keeping track of a code's tokens while tokenizing
|
|
||||||
foreach (var code in this.AllCodes)
|
|
||||||
code.Tokens = new ReadOnlyCollection<Token>(this.Tokens.Where(t => t.AppliedCodes.Contains(code)).ToList());
|
|
||||||
|
|
||||||
this.Realign(font, alignment);
|
this.Realign(font, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using MLEM.Misc;
|
||||||
using MLEM.Textures;
|
using MLEM.Textures;
|
||||||
|
|
||||||
namespace MLEM.Graphics {
|
namespace MLEM.Graphics {
|
||||||
|
@ -86,92 +87,94 @@ namespace MLEM.Graphics {
|
||||||
/// <param name="layerDepth">The layer depth to draw with.</param>
|
/// <param name="layerDepth">The layer depth to draw with.</param>
|
||||||
/// <param name="overlayDepthOffset">An optional depth offset from <paramref name="layerDepth"/> that the overlay should be drawn with</param>
|
/// <param name="overlayDepthOffset">An optional depth offset from <paramref name="layerDepth"/> that the overlay should be drawn with</param>
|
||||||
public static void DrawExtendedAutoTile(SpriteBatch batch, Vector2 pos, TextureRegion backgroundTexture, TextureRegion overlayTexture, ConnectsTo connectsTo, Color backgroundColor, Color overlayColor, Vector2? origin = null, Vector2? scale = null, float layerDepth = 0, float overlayDepthOffset = 0) {
|
public static void DrawExtendedAutoTile(SpriteBatch batch, Vector2 pos, TextureRegion backgroundTexture, TextureRegion overlayTexture, ConnectsTo connectsTo, Color backgroundColor, Color overlayColor, Vector2? origin = null, Vector2? scale = null, float layerDepth = 0, float overlayDepthOffset = 0) {
|
||||||
var orig = origin ?? Vector2.Zero;
|
|
||||||
var sc = scale ?? Vector2.One;
|
|
||||||
var od = layerDepth + overlayDepthOffset;
|
|
||||||
var (r1, r2, r3, r4) = AutoTiling.CalculateExtendedAutoTile(overlayTexture.Area, connectsTo);
|
|
||||||
if (backgroundTexture != null)
|
if (backgroundTexture != null)
|
||||||
batch.Draw(backgroundTexture, pos, backgroundColor, 0, orig, sc, SpriteEffects.None, layerDepth);
|
batch.Draw(backgroundTexture, pos, backgroundColor, 0, origin ?? Vector2.Zero, scale ?? Vector2.One, SpriteEffects.None, layerDepth);
|
||||||
if (r1 != Rectangle.Empty)
|
var od = layerDepth + overlayDepthOffset;
|
||||||
batch.Draw(overlayTexture.Texture, pos, r1, overlayColor, 0, orig, sc, SpriteEffects.None, od);
|
AutoTiling.DrawExtendedAutoTileCorner(batch, pos, overlayTexture, connectsTo, overlayColor, Direction2.UpLeft, origin, scale, od);
|
||||||
if (r2 != Rectangle.Empty)
|
AutoTiling.DrawExtendedAutoTileCorner(batch, pos, overlayTexture, connectsTo, overlayColor, Direction2.UpRight, origin, scale, od);
|
||||||
batch.Draw(overlayTexture.Texture, pos, r2, overlayColor, 0, orig, sc, SpriteEffects.None, od);
|
AutoTiling.DrawExtendedAutoTileCorner(batch, pos, overlayTexture, connectsTo, overlayColor, Direction2.DownLeft, origin, scale, od);
|
||||||
if (r3 != Rectangle.Empty)
|
AutoTiling.DrawExtendedAutoTileCorner(batch, pos, overlayTexture, connectsTo, overlayColor, Direction2.DownRight, origin, scale, od);
|
||||||
batch.Draw(overlayTexture.Texture, pos, r3, overlayColor, 0, orig, sc, SpriteEffects.None, od);
|
}
|
||||||
if (r4 != Rectangle.Empty)
|
|
||||||
batch.Draw(overlayTexture.Texture, pos, r4, overlayColor, 0, orig, sc, SpriteEffects.None, od);
|
/// <summary>
|
||||||
|
/// This method allows for a single corner of a tiled texture to be drawn in an auto-tiling mode.
|
||||||
|
/// This allows, for example, a grass patch on a tilemap to have nice looking edges that transfer over into a path without any hard edges between tiles.
|
||||||
|
///
|
||||||
|
/// For more information, and to draw all four corners at once, see <see cref="DrawExtendedAutoTile(Microsoft.Xna.Framework.Graphics.SpriteBatch,Microsoft.Xna.Framework.Vector2,MLEM.Textures.TextureRegion,MLEM.Textures.TextureRegion,MLEM.Graphics.AutoTiling.ConnectsTo,Microsoft.Xna.Framework.Color,Microsoft.Xna.Framework.Color,System.Nullable{Microsoft.Xna.Framework.Vector2},System.Nullable{Microsoft.Xna.Framework.Vector2},float,float)"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="batch">The sprite batch to use for drawing.</param>
|
||||||
|
/// <param name="pos">The position to draw at.</param>
|
||||||
|
/// <param name="overlayTexture">The first overlay region, as described in the summary.</param>
|
||||||
|
/// <param name="connectsTo">A function that determines whether two positions should connect.</param>
|
||||||
|
/// <param name="overlayColor">The color to draw border and corner textures with.</param>
|
||||||
|
/// <param name="corner">The corner of the auto-tile to draw. Can be <see cref="Direction2.UpLeft"/>, <see cref="Direction2.UpRight"/>, <see cref="Direction2.DownLeft"/> or <see cref="Direction2.DownRight"/>.</param>
|
||||||
|
/// <param name="origin">The origin to draw from.</param>
|
||||||
|
/// <param name="scale">The scale to draw with.</param>
|
||||||
|
/// <param name="layerDepth">The layer depth to draw with.</param>
|
||||||
|
public static void DrawExtendedAutoTileCorner(SpriteBatch batch, Vector2 pos, TextureRegion overlayTexture, ConnectsTo connectsTo, Color overlayColor, Direction2 corner, Vector2? origin = null, Vector2? scale = null, float layerDepth = 0) {
|
||||||
|
var src = AutoTiling.CalculateExtendedAutoTile(overlayTexture.Area, connectsTo, corner);
|
||||||
|
if (src != Rectangle.Empty)
|
||||||
|
batch.Draw(overlayTexture.Texture, pos, src, overlayColor, 0, origin ?? Vector2.Zero, scale ?? Vector2.One, SpriteEffects.None, layerDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="DrawExtendedAutoTile(Microsoft.Xna.Framework.Graphics.SpriteBatch,Microsoft.Xna.Framework.Vector2,MLEM.Textures.TextureRegion,MLEM.Textures.TextureRegion,MLEM.Graphics.AutoTiling.ConnectsTo,Microsoft.Xna.Framework.Color,Microsoft.Xna.Framework.Color,System.Nullable{Microsoft.Xna.Framework.Vector2},System.Nullable{Microsoft.Xna.Framework.Vector2},float,float)"/>
|
/// <inheritdoc cref="DrawExtendedAutoTile(Microsoft.Xna.Framework.Graphics.SpriteBatch,Microsoft.Xna.Framework.Vector2,MLEM.Textures.TextureRegion,MLEM.Textures.TextureRegion,MLEM.Graphics.AutoTiling.ConnectsTo,Microsoft.Xna.Framework.Color,Microsoft.Xna.Framework.Color,System.Nullable{Microsoft.Xna.Framework.Vector2},System.Nullable{Microsoft.Xna.Framework.Vector2},float,float)"/>
|
||||||
public static void DrawExtendedAutoTile(SpriteBatch batch, Vector2 pos, TextureRegion backgroundTexture, Func<int, TextureRegion> overlayTextures, ConnectsTo connectsTo, Color backgroundColor, Color overlayColor, Vector2? origin = null, Vector2? scale = null, float layerDepth = 0, float overlayDepthOffset = 0) {
|
public static void DrawExtendedAutoTile(SpriteBatch batch, Vector2 pos, TextureRegion backgroundTexture, Func<int, TextureRegion> overlayTextures, ConnectsTo connectsTo, Color backgroundColor, Color overlayColor, Vector2? origin = null, Vector2? scale = null, float layerDepth = 0, float overlayDepthOffset = 0) {
|
||||||
var orig = origin ?? Vector2.Zero;
|
|
||||||
var sc = scale ?? Vector2.One;
|
|
||||||
var od = layerDepth + overlayDepthOffset;
|
|
||||||
var (xUl, xUr, xDl, xDr) = AutoTiling.CalculateExtendedAutoTileOffsets(connectsTo);
|
|
||||||
if (backgroundTexture != null)
|
if (backgroundTexture != null)
|
||||||
batch.Draw(backgroundTexture, pos, backgroundColor, 0, orig, sc, SpriteEffects.None, layerDepth);
|
batch.Draw(backgroundTexture, pos, backgroundColor, 0, origin ?? Vector2.Zero, scale ?? Vector2.One, SpriteEffects.None, layerDepth);
|
||||||
if (xUl >= 0)
|
var od = layerDepth + overlayDepthOffset;
|
||||||
batch.Draw(overlayTextures(xUl), pos, overlayColor, 0, orig, sc, SpriteEffects.None, od);
|
AutoTiling.DrawExtendedAutoTileCorner(batch, pos, overlayTextures, connectsTo, overlayColor, Direction2.UpLeft, origin, scale, od);
|
||||||
if (xUr >= 0)
|
AutoTiling.DrawExtendedAutoTileCorner(batch, pos, overlayTextures, connectsTo, overlayColor, Direction2.UpRight, origin, scale, od);
|
||||||
batch.Draw(overlayTextures(xUr), pos, overlayColor, 0, orig, sc, SpriteEffects.None, od);
|
AutoTiling.DrawExtendedAutoTileCorner(batch, pos, overlayTextures, connectsTo, overlayColor, Direction2.DownLeft, origin, scale, od);
|
||||||
if (xDl >= 0)
|
AutoTiling.DrawExtendedAutoTileCorner(batch, pos, overlayTextures, connectsTo, overlayColor, Direction2.DownRight, origin, scale, od);
|
||||||
batch.Draw(overlayTextures(xDl), pos, overlayColor, 0, orig, sc, SpriteEffects.None, od);
|
}
|
||||||
if (xDr >= 0)
|
|
||||||
batch.Draw(overlayTextures(xDr), pos, overlayColor, 0, orig, sc, SpriteEffects.None, od);
|
/// <inheritdoc cref="DrawExtendedAutoTileCorner(Microsoft.Xna.Framework.Graphics.SpriteBatch,Microsoft.Xna.Framework.Vector2,MLEM.Textures.TextureRegion,MLEM.Graphics.AutoTiling.ConnectsTo,Microsoft.Xna.Framework.Color,MLEM.Misc.Direction2,System.Nullable{Microsoft.Xna.Framework.Vector2},System.Nullable{Microsoft.Xna.Framework.Vector2},float)"/>
|
||||||
|
public static void DrawExtendedAutoTileCorner(SpriteBatch batch, Vector2 pos, Func<int, TextureRegion> overlayTextures, ConnectsTo connectsTo, Color overlayColor, Direction2 corner, Vector2? origin = null, Vector2? scale = null, float layerDepth = 0) {
|
||||||
|
var src = AutoTiling.CalculateExtendedAutoTileOffset(connectsTo, corner);
|
||||||
|
if (src >= 0)
|
||||||
|
batch.Draw(overlayTextures(src), pos, overlayColor, 0, origin ?? Vector2.Zero, scale ?? Vector2.One, SpriteEffects.None, layerDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="DrawExtendedAutoTile(Microsoft.Xna.Framework.Graphics.SpriteBatch,Microsoft.Xna.Framework.Vector2,MLEM.Textures.TextureRegion,MLEM.Textures.TextureRegion,MLEM.Graphics.AutoTiling.ConnectsTo,Microsoft.Xna.Framework.Color,Microsoft.Xna.Framework.Color,System.Nullable{Microsoft.Xna.Framework.Vector2},System.Nullable{Microsoft.Xna.Framework.Vector2},float,float)"/>
|
/// <inheritdoc cref="DrawExtendedAutoTile(Microsoft.Xna.Framework.Graphics.SpriteBatch,Microsoft.Xna.Framework.Vector2,MLEM.Textures.TextureRegion,MLEM.Textures.TextureRegion,MLEM.Graphics.AutoTiling.ConnectsTo,Microsoft.Xna.Framework.Color,Microsoft.Xna.Framework.Color,System.Nullable{Microsoft.Xna.Framework.Vector2},System.Nullable{Microsoft.Xna.Framework.Vector2},float,float)"/>
|
||||||
public static void AddExtendedAutoTile(StaticSpriteBatch batch, Vector2 pos, TextureRegion backgroundTexture, TextureRegion overlayTexture, ConnectsTo connectsTo, Color backgroundColor, Color overlayColor, Vector2? origin = null, Vector2? scale = null, float layerDepth = 0, float overlayDepthOffset = 0, ICollection<StaticSpriteBatch.Item> items = null) {
|
public static void AddExtendedAutoTile(StaticSpriteBatch batch, Vector2 pos, TextureRegion backgroundTexture, TextureRegion overlayTexture, ConnectsTo connectsTo, Color backgroundColor, Color overlayColor, Vector2? origin = null, Vector2? scale = null, float layerDepth = 0, float overlayDepthOffset = 0, ICollection<StaticSpriteBatch.Item> items = null) {
|
||||||
var orig = origin ?? Vector2.Zero;
|
|
||||||
var sc = scale ?? Vector2.One;
|
|
||||||
var od = layerDepth + overlayDepthOffset;
|
|
||||||
var (r1, r2, r3, r4) = AutoTiling.CalculateExtendedAutoTile(overlayTexture.Area, connectsTo);
|
|
||||||
if (backgroundTexture != null) {
|
if (backgroundTexture != null) {
|
||||||
var background = batch.Add(backgroundTexture, pos, backgroundColor, 0, orig, sc, SpriteEffects.None, layerDepth);
|
var background = batch.Add(backgroundTexture, pos, backgroundColor, 0, origin ?? Vector2.Zero, scale ?? Vector2.One, SpriteEffects.None, layerDepth);
|
||||||
items?.Add(background);
|
items?.Add(background);
|
||||||
}
|
}
|
||||||
if (r1 != Rectangle.Empty) {
|
var od = layerDepth + overlayDepthOffset;
|
||||||
var o1 = batch.Add(overlayTexture.Texture, pos, r1, overlayColor, 0, orig, sc, SpriteEffects.None, od);
|
AutoTiling.AddExtendedAutoTileCorner(batch, pos, overlayTexture, connectsTo, overlayColor, Direction2.UpLeft, origin, scale, od, items);
|
||||||
items?.Add(o1);
|
AutoTiling.AddExtendedAutoTileCorner(batch, pos, overlayTexture, connectsTo, overlayColor, Direction2.UpRight, origin, scale, od, items);
|
||||||
}
|
AutoTiling.AddExtendedAutoTileCorner(batch, pos, overlayTexture, connectsTo, overlayColor, Direction2.DownLeft, origin, scale, od, items);
|
||||||
if (r2 != Rectangle.Empty) {
|
AutoTiling.AddExtendedAutoTileCorner(batch, pos, overlayTexture, connectsTo, overlayColor, Direction2.DownRight, origin, scale, od, items);
|
||||||
var o2 = batch.Add(overlayTexture.Texture, pos, r2, overlayColor, 0, orig, sc, SpriteEffects.None, od);
|
}
|
||||||
items?.Add(o2);
|
|
||||||
}
|
/// <inheritdoc cref="DrawExtendedAutoTileCorner(Microsoft.Xna.Framework.Graphics.SpriteBatch,Microsoft.Xna.Framework.Vector2,MLEM.Textures.TextureRegion,MLEM.Graphics.AutoTiling.ConnectsTo,Microsoft.Xna.Framework.Color,MLEM.Misc.Direction2,System.Nullable{Microsoft.Xna.Framework.Vector2},System.Nullable{Microsoft.Xna.Framework.Vector2},float)"/>
|
||||||
if (r3 != Rectangle.Empty) {
|
public static void AddExtendedAutoTileCorner(StaticSpriteBatch batch, Vector2 pos, TextureRegion overlayTexture, ConnectsTo connectsTo, Color overlayColor, Direction2 corner, Vector2? origin = null, Vector2? scale = null, float layerDepth = 0, ICollection<StaticSpriteBatch.Item> items = null) {
|
||||||
var o3 = batch.Add(overlayTexture.Texture, pos, r3, overlayColor, 0, orig, sc, SpriteEffects.None, od);
|
var src = AutoTiling.CalculateExtendedAutoTile(overlayTexture.Area, connectsTo, corner);
|
||||||
items?.Add(o3);
|
if (src != Rectangle.Empty) {
|
||||||
}
|
var o4 = batch.Add(overlayTexture.Texture, pos, src, overlayColor, 0, origin ?? Vector2.Zero, scale ?? Vector2.One, SpriteEffects.None, layerDepth);
|
||||||
if (r4 != Rectangle.Empty) {
|
|
||||||
var o4 = batch.Add(overlayTexture.Texture, pos, r4, overlayColor, 0, orig, sc, SpriteEffects.None, od);
|
|
||||||
items?.Add(o4);
|
items?.Add(o4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="DrawExtendedAutoTile(Microsoft.Xna.Framework.Graphics.SpriteBatch,Microsoft.Xna.Framework.Vector2,MLEM.Textures.TextureRegion,Func{int,MLEM.Textures.TextureRegion},MLEM.Graphics.AutoTiling.ConnectsTo,Microsoft.Xna.Framework.Color,Microsoft.Xna.Framework.Color,System.Nullable{Microsoft.Xna.Framework.Vector2},System.Nullable{Microsoft.Xna.Framework.Vector2},float,float)"/>
|
/// <inheritdoc cref="DrawExtendedAutoTile(Microsoft.Xna.Framework.Graphics.SpriteBatch,Microsoft.Xna.Framework.Vector2,MLEM.Textures.TextureRegion,Func{int,MLEM.Textures.TextureRegion},MLEM.Graphics.AutoTiling.ConnectsTo,Microsoft.Xna.Framework.Color,Microsoft.Xna.Framework.Color,System.Nullable{Microsoft.Xna.Framework.Vector2},System.Nullable{Microsoft.Xna.Framework.Vector2},float,float)"/>
|
||||||
public static void AddExtendedAutoTile(StaticSpriteBatch batch, Vector2 pos, TextureRegion backgroundTexture, Func<int, TextureRegion> overlayTextures, ConnectsTo connectsTo, Color backgroundColor, Color overlayColor, Vector2? origin = null, Vector2? scale = null, float layerDepth = 0, float overlayDepthOffset = 0, ICollection<StaticSpriteBatch.Item> items = null) {
|
public static void AddExtendedAutoTile(StaticSpriteBatch batch, Vector2 pos, TextureRegion backgroundTexture, Func<int, TextureRegion> overlayTextures, ConnectsTo connectsTo, Color backgroundColor, Color overlayColor, Vector2? origin = null, Vector2? scale = null, float layerDepth = 0, float overlayDepthOffset = 0, ICollection<StaticSpriteBatch.Item> items = null) {
|
||||||
var orig = origin ?? Vector2.Zero;
|
|
||||||
var sc = scale ?? Vector2.One;
|
|
||||||
var od = layerDepth + overlayDepthOffset;
|
|
||||||
var (xUl, xUr, xDl, xDr) = AutoTiling.CalculateExtendedAutoTileOffsets(connectsTo);
|
|
||||||
if (backgroundTexture != null) {
|
if (backgroundTexture != null) {
|
||||||
var background = batch.Add(backgroundTexture, pos, backgroundColor, 0, orig, sc, SpriteEffects.None, layerDepth);
|
var background = batch.Add(backgroundTexture, pos, backgroundColor, 0, origin ?? Vector2.Zero, scale ?? Vector2.One, SpriteEffects.None, layerDepth);
|
||||||
items?.Add(background);
|
items?.Add(background);
|
||||||
}
|
}
|
||||||
if (xUl >= 0) {
|
var od = layerDepth + overlayDepthOffset;
|
||||||
var o1 = batch.Add(overlayTextures(xUl), pos, overlayColor, 0, orig, sc, SpriteEffects.None, od);
|
AutoTiling.AddExtendedAutoTileCorner(batch, pos, overlayTextures, connectsTo, overlayColor, Direction2.UpLeft, origin, scale, od, items);
|
||||||
items?.Add(o1);
|
AutoTiling.AddExtendedAutoTileCorner(batch, pos, overlayTextures, connectsTo, overlayColor, Direction2.UpRight, origin, scale, od, items);
|
||||||
}
|
AutoTiling.AddExtendedAutoTileCorner(batch, pos, overlayTextures, connectsTo, overlayColor, Direction2.DownLeft, origin, scale, od, items);
|
||||||
if (xUr >= 0) {
|
AutoTiling.AddExtendedAutoTileCorner(batch, pos, overlayTextures, connectsTo, overlayColor, Direction2.DownRight, origin, scale, od, items);
|
||||||
var o2 = batch.Add(overlayTextures(xUr), pos, overlayColor, 0, orig, sc, SpriteEffects.None, od);
|
}
|
||||||
items?.Add(o2);
|
|
||||||
}
|
/// <inheritdoc cref="DrawExtendedAutoTileCorner(Microsoft.Xna.Framework.Graphics.SpriteBatch,Microsoft.Xna.Framework.Vector2,MLEM.Textures.TextureRegion,MLEM.Graphics.AutoTiling.ConnectsTo,Microsoft.Xna.Framework.Color,MLEM.Misc.Direction2,System.Nullable{Microsoft.Xna.Framework.Vector2},System.Nullable{Microsoft.Xna.Framework.Vector2},float)"/>
|
||||||
if (xDl >= 0) {
|
public static void AddExtendedAutoTileCorner(StaticSpriteBatch batch, Vector2 pos, Func<int, TextureRegion> overlayTextures, ConnectsTo connectsTo, Color overlayColor, Direction2 corner, Vector2? origin = null, Vector2? scale = null, float layerDepth = 0, ICollection<StaticSpriteBatch.Item> items = null) {
|
||||||
var o3 = batch.Add(overlayTextures(xDl), pos, overlayColor, 0, orig, sc, SpriteEffects.None, od);
|
var src = AutoTiling.CalculateExtendedAutoTileOffset(connectsTo, corner);
|
||||||
items?.Add(o3);
|
if (src >= 0) {
|
||||||
}
|
var o4 = batch.Add(overlayTextures(src), pos, overlayColor, 0, origin ?? Vector2.Zero, scale ?? Vector2.One, SpriteEffects.None, layerDepth);
|
||||||
if (xDr >= 0) {
|
|
||||||
var o4 = batch.Add(overlayTextures(xDr), pos, overlayColor, 0, orig, sc, SpriteEffects.None, od);
|
|
||||||
items?.Add(o4);
|
items?.Add(o4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,26 +197,36 @@ namespace MLEM.Graphics {
|
||||||
new Vector2(pos.X + w2 * scale.X, pos.Y + h2 * scale.Y), new Rectangle(textureRegion.X + w2 + xDr * w, textureRegion.Y + h2, w2, h2));
|
new Vector2(pos.X + w2 * scale.X, pos.Y + h2 * scale.Y), new Rectangle(textureRegion.X + w2 + xDr * w, textureRegion.Y + h2, w2, h2));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static (int, int, int, int) CalculateExtendedAutoTileOffsets(ConnectsTo connectsTo) {
|
private static int CalculateExtendedAutoTileOffset(ConnectsTo connectsTo, Direction2 corner) {
|
||||||
var up = connectsTo(0, -1);
|
switch (corner) {
|
||||||
var down = connectsTo(0, 1);
|
case Direction2.UpLeft: {
|
||||||
var left = connectsTo(-1, 0);
|
var up = connectsTo(0, -1);
|
||||||
var right = connectsTo(1, 0);
|
var left = connectsTo(-1, 0);
|
||||||
return (
|
return up && left ? connectsTo(-1, -1) ? -1 : 12 : left ? 0 : up ? 8 : 4;
|
||||||
up && left ? connectsTo(-1, -1) ? -1 : 12 : left ? 0 : up ? 8 : 4,
|
}
|
||||||
up && right ? connectsTo(1, -1) ? -1 : 13 : right ? 1 : up ? 9 : 5,
|
case Direction2.UpRight: {
|
||||||
down && left ? connectsTo(-1, 1) ? -1 : 14 : left ? 2 : down ? 10 : 6,
|
var up = connectsTo(0, -1);
|
||||||
down && right ? connectsTo(1, 1) ? -1 : 15 : right ? 3 : down ? 11 : 7);
|
var right = connectsTo(1, 0);
|
||||||
|
return up && right ? connectsTo(1, -1) ? -1 : 13 : right ? 1 : up ? 9 : 5;
|
||||||
|
}
|
||||||
|
case Direction2.DownLeft: {
|
||||||
|
var down = connectsTo(0, 1);
|
||||||
|
var left = connectsTo(-1, 0);
|
||||||
|
return down && left ? connectsTo(-1, 1) ? -1 : 14 : left ? 2 : down ? 10 : 6;
|
||||||
|
}
|
||||||
|
case Direction2.DownRight: {
|
||||||
|
var down = connectsTo(0, 1);
|
||||||
|
var right = connectsTo(1, 0);
|
||||||
|
return down && right ? connectsTo(1, 1) ? -1 : 15 : right ? 3 : down ? 11 : 7;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(corner), corner, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static (Rectangle, Rectangle, Rectangle, Rectangle) CalculateExtendedAutoTile(Rectangle textureRegion, ConnectsTo connectsTo) {
|
private static Rectangle CalculateExtendedAutoTile(Rectangle textureRegion, ConnectsTo connectsTo, Direction2 corner) {
|
||||||
var (xUl, xUr, xDl, xDr) = AutoTiling.CalculateExtendedAutoTileOffsets(connectsTo);
|
var off = AutoTiling.CalculateExtendedAutoTileOffset(connectsTo, corner);
|
||||||
var (w, h) = (textureRegion.Width, textureRegion.Height);
|
return off < 0 ? Rectangle.Empty : new Rectangle(textureRegion.X + off * textureRegion.Width, textureRegion.Y, textureRegion.Width, textureRegion.Height);
|
||||||
return (
|
|
||||||
xUl < 0 ? Rectangle.Empty : new Rectangle(textureRegion.X + xUl * w, textureRegion.Y, w, h),
|
|
||||||
xUr < 0 ? Rectangle.Empty : new Rectangle(textureRegion.X + xUr * w, textureRegion.Y, w, h),
|
|
||||||
xDl < 0 ? Rectangle.Empty : new Rectangle(textureRegion.X + xDl * w, textureRegion.Y, w, h),
|
|
||||||
xDr < 0 ? Rectangle.Empty : new Rectangle(textureRegion.X + xDr * w, textureRegion.Y, w, h));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -121,11 +121,11 @@ namespace MLEM.Input {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains the <see cref="LastTouchState"/>, but with the <see cref="GraphicsDevice.Viewport"/> taken into account.
|
/// Contains the <see cref="LastTouchState"/>, but with the <see cref="GraphicsDevice.Viewport"/> taken into account.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IList<TouchLocation> LastViewportTouchState { get; private set; }
|
public IList<TouchLocation> LastViewportTouchState { get; private set; } = new List<TouchLocation>();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains the <see cref="TouchState"/>, but with the <see cref="GraphicsDevice.Viewport"/> taken into account.
|
/// Contains the <see cref="TouchState"/>, but with the <see cref="GraphicsDevice.Viewport"/> taken into account.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IList<TouchLocation> ViewportTouchState { get; private set; }
|
public IList<TouchLocation> ViewportTouchState { get; private set; } = new List<TouchLocation>();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains the amount of gamepads that are currently connected. Note that this value will be set to 0 if <see cref="HandleGamepads"/> is false.
|
/// Contains the amount of gamepads that are currently connected. Note that this value will be set to 0 if <see cref="HandleGamepads"/> is false.
|
||||||
/// This field is automatically updated in <see cref="Update()"/>.
|
/// This field is automatically updated in <see cref="Update()"/>.
|
||||||
|
@ -342,6 +342,7 @@ namespace MLEM.Input {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.TouchState = new TouchCollection(InputHandler.EmptyTouchLocations);
|
this.TouchState = new TouchCollection(InputHandler.EmptyTouchLocations);
|
||||||
|
this.ViewportTouchState = this.TouchState;
|
||||||
this.gestures.Clear();
|
this.gestures.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,8 @@ namespace MLEM.Input {
|
||||||
set {
|
set {
|
||||||
var val = (int) MathHelper.Clamp(value, 0F, this.text.Length);
|
var val = (int) MathHelper.Clamp(value, 0F, this.text.Length);
|
||||||
if (this.caretPos != val) {
|
if (this.caretPos != val) {
|
||||||
this.caretPos = val;
|
// ensure that we don't move to a location that is between high and low surrogates
|
||||||
|
this.caretPos = new CodePointSource(this.text).EnsureSurrogateBoundary(val, val > this.caretPos);
|
||||||
this.caretBlinkTimer = 0;
|
this.caretBlinkTimer = 0;
|
||||||
this.SetTextDataDirty(false);
|
this.SetTextDataDirty(false);
|
||||||
}
|
}
|
||||||
|
@ -203,6 +204,21 @@ namespace MLEM.Input {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// The maximum amount of lines that can be visible in this text input, based on its <see cref="Size"/>, the used <see cref="Font"/> and its <see cref="TextScale"/>.
|
||||||
|
/// Note that this may return a number higher than 1 even if this is not a <see cref="Multiline"/> text input.
|
||||||
|
/// </summary>
|
||||||
|
public int MaxDisplayedLines => (this.Size.Y / (this.Font.LineHeight * this.TextScale)).Floor();
|
||||||
|
/// <summary>
|
||||||
|
/// The index of the first line that is currently visible.
|
||||||
|
/// This value can be changed using <see cref="ShowLine"/>.
|
||||||
|
/// </summary>
|
||||||
|
public int FirstVisibleLine { get; private set; }
|
||||||
|
/// <summary>
|
||||||
|
/// The total amount of lines of text that this text input currently has, including additional lines added by automatic wrapping.
|
||||||
|
/// If this is not a <see cref="Multiline"/> text input, this value is always 1.
|
||||||
|
/// </summary>
|
||||||
|
public int Lines { get; private set; }
|
||||||
|
/// <summary>
|
||||||
/// A function that is invoked when a string of text should be copied to the clipboard.
|
/// A function that is invoked when a string of text should be copied to the clipboard.
|
||||||
/// MLEM.Ui uses the TextCopy package for this, but other options are available.
|
/// MLEM.Ui uses the TextCopy package for this, but other options are available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -217,10 +233,9 @@ namespace MLEM.Input {
|
||||||
|
|
||||||
private char? maskingCharacter;
|
private char? maskingCharacter;
|
||||||
private double caretBlinkTimer;
|
private double caretBlinkTimer;
|
||||||
private string displayedText;
|
private string visibleText;
|
||||||
private string[] splitText;
|
private string[] multilineSplitText;
|
||||||
private int textOffset;
|
private int textOffset;
|
||||||
private int lineOffset;
|
|
||||||
private int caretPos;
|
private int caretPos;
|
||||||
private int caretLine;
|
private int caretLine;
|
||||||
private int caretPosInLine;
|
private int caretPosInLine;
|
||||||
|
@ -301,9 +316,9 @@ namespace MLEM.Input {
|
||||||
this.CaretPos--;
|
this.CaretPos--;
|
||||||
} else if (this.CaretPos < this.text.Length && input.TryConsumePressed(Keys.Right)) {
|
} else if (this.CaretPos < this.text.Length && input.TryConsumePressed(Keys.Right)) {
|
||||||
this.CaretPos++;
|
this.CaretPos++;
|
||||||
} else if (this.Multiline && input.IsPressedAvailable(Keys.Up) && this.MoveCaretToLine(this.CaretLine - 1)) {
|
} else if (this.Multiline && input.IsPressedAvailable(Keys.Up) && (input.IsModifierKeyDown(ModifierKey.Control) ? this.ShowLine(this.FirstVisibleLine - 1) : this.MoveCaretToLine(this.CaretLine - 1))) {
|
||||||
input.TryConsumePressed(Keys.Up);
|
input.TryConsumePressed(Keys.Up);
|
||||||
} else if (this.Multiline && input.IsPressedAvailable(Keys.Down) && this.MoveCaretToLine(this.CaretLine + 1)) {
|
} else if (this.Multiline && input.IsPressedAvailable(Keys.Down) && (input.IsModifierKeyDown(ModifierKey.Control) ? this.ShowLine(this.FirstVisibleLine + 1) : this.MoveCaretToLine(this.CaretLine + 1))) {
|
||||||
input.TryConsumePressed(Keys.Down);
|
input.TryConsumePressed(Keys.Down);
|
||||||
} else if (this.CaretPos != 0 && input.TryConsumePressed(Keys.Home)) {
|
} else if (this.CaretPos != 0 && input.TryConsumePressed(Keys.Home)) {
|
||||||
this.CaretPos = 0;
|
this.CaretPos = 0;
|
||||||
|
@ -339,12 +354,12 @@ namespace MLEM.Input {
|
||||||
this.UpdateTextDataIfDirty();
|
this.UpdateTextDataIfDirty();
|
||||||
|
|
||||||
var scale = this.TextScale * drawScale;
|
var scale = this.TextScale * drawScale;
|
||||||
this.Font.DrawString(batch, this.displayedText, textPos, textColor, 0, Vector2.Zero, scale, SpriteEffects.None, 0);
|
this.Font.DrawString(batch, this.visibleText, textPos, textColor, 0, Vector2.Zero, scale, SpriteEffects.None, 0);
|
||||||
|
|
||||||
if (caretWidth > 0 && this.caretBlinkTimer < 0.5F) {
|
if (caretWidth > 0 && this.caretBlinkTimer < 0.5F) {
|
||||||
var caretDrawPos = textPos + new Vector2(this.caretDrawOffset * scale, 0);
|
var caretDrawPos = textPos + new Vector2(this.caretDrawOffset * scale, 0);
|
||||||
if (this.Multiline)
|
if (this.Multiline)
|
||||||
caretDrawPos.Y += this.Font.LineHeight * (this.CaretLine - this.lineOffset) * scale;
|
caretDrawPos.Y += this.Font.LineHeight * (this.CaretLine - this.FirstVisibleLine) * scale;
|
||||||
batch.Draw(batch.GetBlankTexture(), new RectangleF(caretDrawPos, new Vector2(caretWidth * drawScale, this.Font.LineHeight * scale)), null, textColor);
|
batch.Draw(batch.GetBlankTexture(), new RectangleF(caretDrawPos, new Vector2(caretWidth * drawScale, this.Font.LineHeight * scale)), null, textColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,7 +375,7 @@ namespace MLEM.Input {
|
||||||
if (!this.FilterText(ref strg, removeMismatching))
|
if (!this.FilterText(ref strg, removeMismatching))
|
||||||
return;
|
return;
|
||||||
if (this.MaximumCharacters != null && strg.Length > this.MaximumCharacters)
|
if (this.MaximumCharacters != null && strg.Length > this.MaximumCharacters)
|
||||||
strg = strg.Substring(0, this.MaximumCharacters.Value);
|
strg = strg.Substring(0, new CodePointSource(strg).EnsureSurrogateBoundary(this.MaximumCharacters.Value, false));
|
||||||
this.text.Clear();
|
this.text.Clear();
|
||||||
this.text.Append(strg);
|
this.text.Append(strg);
|
||||||
this.CaretPos = this.text.Length;
|
this.CaretPos = this.text.Length;
|
||||||
|
@ -378,7 +393,7 @@ namespace MLEM.Input {
|
||||||
if (!this.FilterText(ref strg, removeMismatching))
|
if (!this.FilterText(ref strg, removeMismatching))
|
||||||
return false;
|
return false;
|
||||||
if (this.MaximumCharacters != null && this.text.Length + strg.Length > this.MaximumCharacters)
|
if (this.MaximumCharacters != null && this.text.Length + strg.Length > this.MaximumCharacters)
|
||||||
strg = strg.Substring(0, this.MaximumCharacters.Value - this.text.Length);
|
strg = strg.Substring(0, new CodePointSource(strg).EnsureSurrogateBoundary(this.MaximumCharacters.Value - this.text.Length, false));
|
||||||
this.text.Insert(this.CaretPos, strg);
|
this.text.Insert(this.CaretPos, strg);
|
||||||
this.CaretPos += strg.Length;
|
this.CaretPos += strg.Length;
|
||||||
this.SetTextDataDirty();
|
this.SetTextDataDirty();
|
||||||
|
@ -393,7 +408,8 @@ namespace MLEM.Input {
|
||||||
public bool RemoveText(int index, int length) {
|
public bool RemoveText(int index, int length) {
|
||||||
if (index < 0 || index >= this.text.Length)
|
if (index < 0 || index >= this.text.Length)
|
||||||
return false;
|
return false;
|
||||||
this.text.Remove(index, length);
|
var source = new CodePointSource(this.text);
|
||||||
|
this.text.Remove(source.EnsureSurrogateBoundary(index, false), source.EnsureSurrogateBoundary(index + length, true) - index);
|
||||||
// ensure that caret pos is still in bounds
|
// ensure that caret pos is still in bounds
|
||||||
this.CaretPos = this.CaretPos;
|
this.CaretPos = this.CaretPos;
|
||||||
this.SetTextDataDirty();
|
this.SetTextDataDirty();
|
||||||
|
@ -417,7 +433,7 @@ namespace MLEM.Input {
|
||||||
this.CaretPos = destStart + destAccum.Length;
|
this.CaretPos = destStart + destAccum.Length;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
destAccum += this.text[destStart + destAccum.Length];
|
destAccum += CodePointSource.ToString(new CodePointSource(this.text).GetCodePoint(destStart + destAccum.Length).CodePoint);
|
||||||
}
|
}
|
||||||
// if we don't find a proper position, just move to the end of the destination line
|
// if we don't find a proper position, just move to the end of the destination line
|
||||||
this.CaretPos = destEnd;
|
this.CaretPos = destEnd;
|
||||||
|
@ -426,6 +442,26 @@ namespace MLEM.Input {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Moves visual focus into such bounds that the given line will be the first visible line of this text input.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="line">The first line that should be visible.</param>
|
||||||
|
/// <returns>Whether the line can be the fist visible line, and wasn't already the first visible line.</returns>
|
||||||
|
public bool ShowLine(int line) {
|
||||||
|
if (this.FirstVisibleLine != line && line >= 0 && line < this.Lines - (this.MaxDisplayedLines - 1)) {
|
||||||
|
this.FirstVisibleLine = line;
|
||||||
|
|
||||||
|
// move the caret into visible bounds if necessary
|
||||||
|
var clampedCaretLine = (int) MathHelper.Clamp(this.CaretLine, line, line + this.MaxDisplayedLines - 1F);
|
||||||
|
if (clampedCaretLine != this.CaretLine)
|
||||||
|
this.MoveCaretToLine(clampedCaretLine);
|
||||||
|
|
||||||
|
this.SetTextDataDirty(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private bool FilterText(ref string text, bool removeMismatching) {
|
private bool FilterText(ref string text, bool removeMismatching) {
|
||||||
var result = new StringBuilder();
|
var result = new StringBuilder();
|
||||||
foreach (var codePoint in new CodePointSource(text)) {
|
foreach (var codePoint in new CodePointSource(text)) {
|
||||||
|
@ -458,49 +494,50 @@ namespace MLEM.Input {
|
||||||
|
|
||||||
if (this.Multiline) {
|
if (this.Multiline) {
|
||||||
// soft wrap if we're multiline
|
// soft wrap if we're multiline
|
||||||
this.splitText = this.Font.SplitStringSeparate(visualText, this.Size.X, this.TextScale).ToArray();
|
this.multilineSplitText = this.Font.SplitStringSeparate(visualText, this.Size.X, this.TextScale).ToArray();
|
||||||
this.displayedText = string.Join("\n", this.splitText);
|
this.visibleText = string.Join("\n", this.multilineSplitText);
|
||||||
|
this.Lines = this.visibleText.Count(c => c == '\n') + 1;
|
||||||
this.UpdateCaretData();
|
this.UpdateCaretData();
|
||||||
|
|
||||||
if (this.Font.MeasureString(this.displayedText).Y * this.TextScale > this.Size.Y) {
|
if (this.Font.MeasureString(this.visibleText).Y * this.TextScale > this.Size.Y) {
|
||||||
var maxLines = (this.Size.Y / (this.Font.LineHeight * this.TextScale)).Floor();
|
if (this.FirstVisibleLine > this.CaretLine) {
|
||||||
if (this.lineOffset > this.CaretLine) {
|
|
||||||
// if we're moving up
|
// if we're moving up
|
||||||
this.lineOffset = this.CaretLine;
|
this.FirstVisibleLine = this.CaretLine;
|
||||||
} else if (this.CaretLine >= maxLines) {
|
} else if (this.CaretLine >= this.MaxDisplayedLines) {
|
||||||
// if we're moving down
|
// if we're moving down
|
||||||
var limit = this.CaretLine - (maxLines - 1);
|
var limit = this.CaretLine - (this.MaxDisplayedLines - 1);
|
||||||
if (limit > this.lineOffset)
|
if (limit > this.FirstVisibleLine)
|
||||||
this.lineOffset = limit;
|
this.FirstVisibleLine = limit;
|
||||||
}
|
}
|
||||||
// calculate resulting string
|
// calculate resulting string
|
||||||
var ret = new StringBuilder();
|
var ret = new StringBuilder();
|
||||||
var lines = 0;
|
var lines = 0;
|
||||||
var originalIndex = 0;
|
var originalIndex = 0;
|
||||||
for (var i = 0; i < this.displayedText.Length; i++) {
|
for (var i = 0; i < this.visibleText.Length; i++) {
|
||||||
if (lines >= this.lineOffset) {
|
if (lines >= this.FirstVisibleLine) {
|
||||||
if (ret.Length <= 0)
|
if (ret.Length <= 0)
|
||||||
this.textOffset = originalIndex;
|
this.textOffset = originalIndex;
|
||||||
ret.Append(this.displayedText[i]);
|
ret.Append(this.visibleText[i]);
|
||||||
}
|
}
|
||||||
if (this.displayedText[i] == '\n') {
|
if (this.visibleText[i] == '\n') {
|
||||||
lines++;
|
lines++;
|
||||||
if (visualText[originalIndex] == '\n')
|
if (visualText[originalIndex] == '\n')
|
||||||
originalIndex++;
|
originalIndex++;
|
||||||
} else {
|
} else {
|
||||||
originalIndex++;
|
originalIndex++;
|
||||||
}
|
}
|
||||||
if (lines - this.lineOffset >= maxLines)
|
if (lines - this.FirstVisibleLine >= this.MaxDisplayedLines)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.displayedText = ret.ToString();
|
this.visibleText = ret.ToString();
|
||||||
} else {
|
} else {
|
||||||
this.lineOffset = 0;
|
this.FirstVisibleLine = 0;
|
||||||
this.textOffset = 0;
|
this.textOffset = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.splitText = null;
|
this.multilineSplitText = null;
|
||||||
this.lineOffset = 0;
|
this.FirstVisibleLine = 0;
|
||||||
|
this.Lines = 1;
|
||||||
// not multiline, so scroll horizontally based on caret position
|
// not multiline, so scroll horizontally based on caret position
|
||||||
if (this.Font.MeasureString(visualText).X * this.TextScale > this.Size.X) {
|
if (this.Font.MeasureString(visualText).X * this.TextScale > this.Size.X) {
|
||||||
if (this.textOffset > this.CaretPos) {
|
if (this.textOffset > this.CaretPos) {
|
||||||
|
@ -514,9 +551,9 @@ namespace MLEM.Input {
|
||||||
this.textOffset = bound;
|
this.textOffset = bound;
|
||||||
}
|
}
|
||||||
var visible = visualText.ToString(this.textOffset, visualText.Length - this.textOffset);
|
var visible = visualText.ToString(this.textOffset, visualText.Length - this.textOffset);
|
||||||
this.displayedText = this.Font.TruncateString(visible, this.Size.X, this.TextScale);
|
this.visibleText = this.Font.TruncateString(visible, this.Size.X, this.TextScale);
|
||||||
} else {
|
} else {
|
||||||
this.displayedText = visualText.ToString();
|
this.visibleText = visualText.ToString();
|
||||||
this.textOffset = 0;
|
this.textOffset = 0;
|
||||||
}
|
}
|
||||||
this.UpdateCaretData();
|
this.UpdateCaretData();
|
||||||
|
@ -524,9 +561,9 @@ namespace MLEM.Input {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateCaretData() {
|
private void UpdateCaretData() {
|
||||||
if (this.splitText != null) {
|
if (this.multilineSplitText != null) {
|
||||||
// the code below will never execute if our text is empty, so reset our caret position fully
|
// the code below will never execute if our text is empty, so reset our caret position fully
|
||||||
if (this.splitText.Length <= 0) {
|
if (this.multilineSplitText.Length <= 0) {
|
||||||
this.caretLine = 0;
|
this.caretLine = 0;
|
||||||
this.caretPosInLine = 0;
|
this.caretPosInLine = 0;
|
||||||
this.caretDrawOffset = 0;
|
this.caretDrawOffset = 0;
|
||||||
|
@ -535,9 +572,9 @@ namespace MLEM.Input {
|
||||||
|
|
||||||
var line = 0;
|
var line = 0;
|
||||||
var index = 0;
|
var index = 0;
|
||||||
for (var d = 0; d < this.splitText.Length; d++) {
|
for (var d = 0; d < this.multilineSplitText.Length; d++) {
|
||||||
var startOfLine = 0;
|
var startOfLine = 0;
|
||||||
var split = this.splitText[d];
|
var split = this.multilineSplitText[d];
|
||||||
for (var i = 0; i <= split.Length; i++) {
|
for (var i = 0; i <= split.Length; i++) {
|
||||||
if (index == this.CaretPos) {
|
if (index == this.CaretPos) {
|
||||||
this.caretLine = line;
|
this.caretLine = line;
|
||||||
|
@ -557,20 +594,20 @@ namespace MLEM.Input {
|
||||||
// max width splits
|
// max width splits
|
||||||
line++;
|
line++;
|
||||||
}
|
}
|
||||||
} else if (this.displayedText != null) {
|
} else if (this.visibleText != null) {
|
||||||
this.caretLine = 0;
|
this.caretLine = 0;
|
||||||
this.caretPosInLine = this.CaretPos;
|
this.caretPosInLine = this.CaretPos;
|
||||||
this.caretDrawOffset = this.Font.MeasureString(this.displayedText.Substring(0, this.CaretPos - this.textOffset)).X;
|
this.caretDrawOffset = this.Font.MeasureString(this.visibleText.Substring(0, this.CaretPos - this.textOffset)).X;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private (int, int) GetLineBounds(int boundLine) {
|
private (int, int) GetLineBounds(int boundLine) {
|
||||||
if (this.splitText != null) {
|
if (this.multilineSplitText != null) {
|
||||||
var line = 0;
|
var line = 0;
|
||||||
var index = 0;
|
var index = 0;
|
||||||
var startOfLineIndex = 0;
|
var startOfLineIndex = 0;
|
||||||
for (var d = 0; d < this.splitText.Length; d++) {
|
for (var d = 0; d < this.multilineSplitText.Length; d++) {
|
||||||
var split = this.splitText[d];
|
var split = this.multilineSplitText[d];
|
||||||
for (var i = 0; i < split.Length; i++) {
|
for (var i = 0; i < split.Length; i++) {
|
||||||
index++;
|
index++;
|
||||||
if (split[i] == '\n') {
|
if (split[i] == '\n') {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net452;netstandard2.0;net7.0</TargetFrameworks>
|
<TargetFrameworks>net452;netstandard2.0;net8.0</TargetFrameworks>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
<IsTrimmable>true</IsTrimmable>
|
<IsAotCompatible Condition="'$(TargetFramework)'=='net8.0'">true</IsAotCompatible>
|
||||||
<RootNamespace>MLEM</RootNamespace>
|
<RootNamespace>MLEM</RootNamespace>
|
||||||
<DefineConstants>$(DefineConstants);FNA</DefineConstants>
|
<DefineConstants>$(DefineConstants);FNA</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\FNA\FNA.csproj">
|
<ProjectReference Include="..\ThirdParty\FNA\FNA.csproj">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net452;netstandard2.0;net7.0</TargetFrameworks>
|
<TargetFrameworks>net452;netstandard2.0;net8.0</TargetFrameworks>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
<IsTrimmable>true</IsTrimmable>
|
<IsAotCompatible Condition="'$(TargetFramework)'=='net8.0'">true</IsAotCompatible>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
namespace MLEM.Misc {
|
namespace MLEM.Misc {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -8,6 +9,21 @@ namespace MLEM.Misc {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Easings {
|
public static class Easings {
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An easing function that constantly returns 0, regardless of the input percentage.
|
||||||
|
/// This is useful for chaining using <see cref="AndThen(MLEM.Misc.Easings.Easing,MLEM.Misc.Easings.Easing)"/>.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly Easing Zero = p => 0;
|
||||||
|
/// <summary>
|
||||||
|
/// An easing function that constantly returns 1, regardless of the input percentage.
|
||||||
|
/// This is useful for chaining using <see cref="AndThen(MLEM.Misc.Easings.Easing,MLEM.Misc.Easings.Easing)"/>.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly Easing One = p => 1;
|
||||||
|
/// <summary>
|
||||||
|
/// A linear easing function that returns the input percentage without modifying it.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly Easing Linear = p => p;
|
||||||
|
|
||||||
/// <summary>https://easings.net/#easeInSine</summary>
|
/// <summary>https://easings.net/#easeInSine</summary>
|
||||||
public static readonly Easing InSine = p => 1 - (float) Math.Cos(p * Math.PI / 2);
|
public static readonly Easing InSine = p => 1 - (float) Math.Cos(p * Math.PI / 2);
|
||||||
/// <summary>https://easings.net/#easeOutSine</summary>
|
/// <summary>https://easings.net/#easeOutSine</summary>
|
||||||
|
@ -170,6 +186,17 @@ namespace MLEM.Misc {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Causes output from the easing function to be clamped between the <paramref name="min"/> and <paramref name="max"/> values passed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="easing">The easing function to clamp.</param>
|
||||||
|
/// <param name="min">The minimum output value to clamp to, defaults to 0.</param>
|
||||||
|
/// <param name="max">The maximum output value to clamp to, defaults to 1.</param>
|
||||||
|
/// <returns>A clamped easing function.</returns>
|
||||||
|
public static Easing Clamp(this Easing easing, float min = 0, float max = 1) {
|
||||||
|
return p => MathHelper.Clamp(easing(p), min, max);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A delegate method used by <see cref="Easings"/>.
|
/// A delegate method used by <see cref="Easings"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
namespace MLEM.Misc {
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MLEM.Extensions;
|
||||||
|
|
||||||
|
namespace MLEM.Misc {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The SingleRandom class allows generating single, one-off pseudorandom numbers based on a seed or a <see cref="SeedSource"/>.
|
/// The SingleRandom class allows generating single, one-off pseudorandom numbers based on a seed or a <see cref="SeedSource"/>.
|
||||||
/// The types of numbers that can be generated are <see cref="int"/> and <see cref="float"/>, both of which can be generated with specific minimum and maximum values if desired.
|
/// The types of numbers that can be generated are <see cref="int"/> and <see cref="float"/>, both of which can be generated with specific minimum and maximum values if desired.
|
||||||
|
@ -138,5 +142,35 @@
|
||||||
return (maxValue - minValue) * SingleRandom.Single(source) + minValue;
|
return (maxValue - minValue) * SingleRandom.Single(source) + minValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a random entry from the given collection with uniform chance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entries">The entries to choose from</param>
|
||||||
|
/// <param name="source">The <see cref="SeedSource"/> to use.</param>
|
||||||
|
/// <typeparam name="T">The entries' type</typeparam>
|
||||||
|
/// <returns>A random entry</returns>
|
||||||
|
public static T GetRandomEntry<T>(ICollection<T> entries, SeedSource source) {
|
||||||
|
return RandomExtensions.GetRandomEntry(entries, SingleRandom.Single(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a random entry from the given collection based on the specified weight function.
|
||||||
|
/// A higher weight for an entry increases its likeliness of being picked.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entries">The entries to choose from</param>
|
||||||
|
/// <param name="weightFunc">A function that applies weight to each entry</param>
|
||||||
|
/// <param name="source">The <see cref="SeedSource"/> to use.</param>
|
||||||
|
/// <typeparam name="T">The entries' type</typeparam>
|
||||||
|
/// <returns>A random entry, based on the entries' weight</returns>
|
||||||
|
/// <exception cref="IndexOutOfRangeException">If the weight function returns different weights for the same entry</exception>
|
||||||
|
public static T GetRandomWeightedEntry<T>(ICollection<T> entries, Func<T, int> weightFunc, SeedSource source) {
|
||||||
|
return RandomExtensions.GetRandomWeightedEntry(entries, weightFunc, SingleRandom.Single(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="GetRandomWeightedEntry{T}(System.Collections.Generic.ICollection{T},System.Func{T,int},MLEM.Misc.SeedSource)"/>
|
||||||
|
public static T GetRandomWeightedEntry<T>(ICollection<T> entries, Func<T, float> weightFunc, SeedSource source) {
|
||||||
|
return RandomExtensions.GetRandomWeightedEntry(entries, weightFunc, SingleRandom.Single(source));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,11 +158,13 @@ namespace MLEM.Textures {
|
||||||
case NinePatchMode.Tile:
|
case NinePatchMode.Tile:
|
||||||
var width = src.Width * patchScale;
|
var width = src.Width * patchScale;
|
||||||
var height = src.Height * patchScale;
|
var height = src.Height * patchScale;
|
||||||
for (var x = 0F; x < rect.Width; x += width) {
|
if (width > 0 && height > 0) {
|
||||||
for (var y = 0F; y < rect.Height; y += height) {
|
for (var x = 0F; x < rect.Width; x += width) {
|
||||||
var size = new Vector2(Math.Min(rect.Width - x, width), Math.Min(rect.Height - y, height));
|
for (var y = 0F; y < rect.Height; y += height) {
|
||||||
var srcSize = (size / patchScale).CeilCopy().ToPoint();
|
var size = new Vector2(Math.Min(rect.Width - x, width), Math.Min(rect.Height - y, height));
|
||||||
batch.Draw(texture.Region.Texture, new RectangleF(rect.Location + new Vector2(x, y), size), new Rectangle(src.X, src.Y, srcSize.X, srcSize.Y), color, rotation, origin, effects, layerDepth);
|
var srcSize = (size / patchScale).CeilCopy().ToPoint();
|
||||||
|
batch.Draw(texture.Region.Texture, new RectangleF(rect.Location + new Vector2(x, y), size), new Rectangle(src.X, src.Y, srcSize.X, srcSize.Y), color, rotation, origin, effects, layerDepth);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
<configuration>
|
|
||||||
<config>
|
|
||||||
<add key="globalPackagesFolder" value="./packages" />
|
|
||||||
</config>
|
|
||||||
</configuration>
|
|
|
@ -11,6 +11,7 @@ MLEM is platform-agnostic and multi-targets .NET Standard 2.0, .NET 6.0 and .NET
|
||||||
- See tutorials and API documentation on [the website](https://mlem.ellpeck.de/)
|
- See tutorials and API documentation on [the website](https://mlem.ellpeck.de/)
|
||||||
- Check out [the demos](https://github.com/Ellpeck/MLEM/tree/main/Demos) on [Desktop](https://github.com/Ellpeck/MLEM/tree/main/Demos.DesktopGL) or [Android](https://github.com/Ellpeck/MLEM/tree/main/Demos.Android)
|
- Check out [the demos](https://github.com/Ellpeck/MLEM/tree/main/Demos) on [Desktop](https://github.com/Ellpeck/MLEM/tree/main/Demos.DesktopGL) or [Android](https://github.com/Ellpeck/MLEM/tree/main/Demos.Android)
|
||||||
- See [the changelog](https://github.com/Ellpeck/MLEM/blob/main/CHANGELOG.md) for information on updates
|
- See [the changelog](https://github.com/Ellpeck/MLEM/blob/main/CHANGELOG.md) for information on updates
|
||||||
|
- Join [the Discord server](https://link.ellpeck.de/discordweb) to ask questions
|
||||||
|
|
||||||
# Packages
|
# Packages
|
||||||
- **MLEM** is the base package, which provides various small addons and abstractions for MonoGame and FNA, including a text formatting system and simple input handling
|
- **MLEM** is the base package, which provides various small addons and abstractions for MonoGame and FNA, including a text formatting system and simple input handling
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
|
|
||||||
#-------------------------------- References --------------------------------#
|
#-------------------------------- References --------------------------------#
|
||||||
|
|
||||||
/reference:..\..\packages\monogame.extended.content.pipeline\3.8.0\tools\MonoGame.Extended.Content.Pipeline.dll
|
|
||||||
|
|
||||||
#---------------------------------- Content ---------------------------------#
|
#---------------------------------- Content ---------------------------------#
|
||||||
|
|
||||||
#begin Fonts/Cadman_Roman.otf
|
#begin Fonts/Cadman_Roman.otf
|
||||||
|
@ -20,11 +18,6 @@
|
||||||
#begin Fonts/Symbola-Emoji.ttf
|
#begin Fonts/Symbola-Emoji.ttf
|
||||||
/copy:Fonts/Symbola-Emoji.ttf
|
/copy:Fonts/Symbola-Emoji.ttf
|
||||||
|
|
||||||
#begin Fonts/Regular.fnt
|
|
||||||
/importer:BitmapFontImporter
|
|
||||||
/processor:BitmapFontProcessor
|
|
||||||
/build:Fonts/Regular.fnt
|
|
||||||
|
|
||||||
#begin Fonts/RegularTexture.png
|
#begin Fonts/RegularTexture.png
|
||||||
/importer:TextureImporter
|
/importer:TextureImporter
|
||||||
/processor:TextureProcessor
|
/processor:TextureProcessor
|
||||||
|
@ -64,5 +57,3 @@
|
||||||
|
|
||||||
#begin Textures/Test.png
|
#begin Textures/Test.png
|
||||||
/copy:Textures/Test.png
|
/copy:Textures/Test.png
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,330 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<font>
|
|
||||||
<info face="BitPotionExt" size="-16" bold="0" italic="0" charset="" unicode="1" stretchH="100" smooth="0" aa="1" padding="0,0,0,0" spacing="1,1" outline="0"/>
|
|
||||||
<common lineHeight="14" base="11" scaleW="128" scaleH="128" pages="1" packed="0" alphaChnl="0" redChnl="4" greenChnl="4" blueChnl="4"/>
|
|
||||||
<pages>
|
|
||||||
<page id="0" file="RegularTexture.png" />
|
|
||||||
</pages>
|
|
||||||
<chars count="320">
|
|
||||||
<char id="32" x="41" y="106" width="3" height="1" xoffset="-1" yoffset="13" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="33" x="10" y="95" width="1" height="7" xoffset="0" yoffset="4" xadvance="2" page="0" chnl="15" />
|
|
||||||
<char id="34" x="124" y="98" width="3" height="2" xoffset="0" yoffset="4" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="35" x="12" y="95" width="7" height="6" xoffset="0" yoffset="5" xadvance="8" page="0" chnl="15" />
|
|
||||||
<char id="36" x="35" y="85" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="37" x="45" y="93" width="4" height="6" xoffset="0" yoffset="5" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="38" x="121" y="51" width="6" height="7" xoffset="0" yoffset="4" xadvance="7" page="0" chnl="15" />
|
|
||||||
<char id="39" x="13" y="109" width="1" height="2" xoffset="0" yoffset="4" xadvance="2" page="0" chnl="15" />
|
|
||||||
<char id="40" x="125" y="83" width="2" height="7" xoffset="0" yoffset="4" xadvance="3" page="0" chnl="15" />
|
|
||||||
<char id="41" x="125" y="75" width="2" height="7" xoffset="0" yoffset="4" xadvance="3" page="0" chnl="15" />
|
|
||||||
<char id="42" x="39" y="93" width="5" height="6" xoffset="0" yoffset="4" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="43" x="92" y="92" width="5" height="5" xoffset="0" yoffset="6" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="44" x="109" y="98" width="2" height="3" xoffset="0" yoffset="10" xadvance="3" page="0" chnl="15" />
|
|
||||||
<char id="45" x="27" y="106" width="4" height="1" xoffset="0" yoffset="8" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="46" x="49" y="106" width="1" height="1" xoffset="0" yoffset="10" xadvance="2" page="0" chnl="15" />
|
|
||||||
<char id="47" x="97" y="60" width="5" height="7" xoffset="0" yoffset="4" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="48" x="40" y="85" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="49" x="109" y="84" width="3" height="7" xoffset="0" yoffset="4" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="50" x="45" y="85" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="51" x="50" y="85" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="52" x="55" y="85" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="53" x="65" y="85" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="54" x="70" y="84" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="55" x="80" y="84" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="56" x="33" y="69" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="57" x="43" y="69" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="58" x="81" y="98" width="1" height="5" xoffset="0" yoffset="6" xadvance="2" page="0" chnl="15" />
|
|
||||||
<char id="59" x="0" y="95" width="2" height="7" xoffset="0" yoffset="6" xadvance="3" page="0" chnl="15" />
|
|
||||||
<char id="60" x="30" y="100" width="4" height="5" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="61" x="104" y="98" width="4" height="3" xoffset="0" yoffset="7" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="62" x="50" y="100" width="4" height="5" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="63" x="48" y="69" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="64" x="41" y="61" width="6" height="7" xoffset="0" yoffset="4" xadvance="7" page="0" chnl="15" />
|
|
||||||
<char id="65" x="53" y="69" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="66" x="58" y="69" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="67" x="63" y="69" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="68" x="68" y="68" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="69" x="73" y="68" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="70" x="78" y="68" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="71" x="83" y="68" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="72" x="30" y="85" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="73" x="6" y="95" width="1" height="7" xoffset="0" yoffset="4" xadvance="2" page="0" chnl="15" />
|
|
||||||
<char id="74" x="88" y="68" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="75" x="98" y="68" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="76" x="103" y="68" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="77" x="6" y="71" width="5" height="7" xoffset="0" yoffset="4" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="78" x="108" y="68" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="79" x="113" y="68" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="80" x="118" y="68" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="81" x="123" y="67" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="82" x="0" y="79" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="83" x="5" y="79" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="84" x="93" y="84" width="3" height="7" xoffset="0" yoffset="4" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="85" x="10" y="79" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="86" x="15" y="78" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="87" x="91" y="60" width="5" height="7" xoffset="0" yoffset="4" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="88" x="20" y="77" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="89" x="97" y="84" width="3" height="7" xoffset="0" yoffset="4" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="90" x="25" y="77" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="91" x="121" y="32" width="2" height="9" xoffset="0" yoffset="4" xadvance="3" page="0" chnl="15" />
|
|
||||||
<char id="92" x="61" y="61" width="5" height="7" xoffset="0" yoffset="4" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="93" x="109" y="32" width="2" height="9" xoffset="0" yoffset="4" xadvance="3" page="0" chnl="15" />
|
|
||||||
<char id="94" x="0" y="109" width="3" height="2" xoffset="0" yoffset="4" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="95" x="32" y="106" width="4" height="1" xoffset="0" yoffset="12" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="96" x="4" y="109" width="2" height="2" xoffset="0" yoffset="4" xadvance="3" page="0" chnl="15" />
|
|
||||||
<char id="97" x="40" y="100" width="4" height="5" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="98" x="30" y="77" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="99" x="77" y="98" width="3" height="5" xoffset="0" yoffset="6" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="100" x="35" y="77" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="101" x="35" y="100" width="4" height="5" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="102" x="113" y="84" width="3" height="7" xoffset="0" yoffset="4" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="103" x="40" y="77" width="4" height="7" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="104" x="50" y="77" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="105" x="8" y="95" width="1" height="7" xoffset="0" yoffset="4" xadvance="2" page="0" chnl="15" />
|
|
||||||
<char id="106" x="115" y="32" width="2" height="9" xoffset="-1" yoffset="4" xadvance="2" page="0" chnl="15" />
|
|
||||||
<char id="107" x="73" y="98" width="3" height="5" xoffset="0" yoffset="6" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="108" x="3" y="95" width="2" height="7" xoffset="0" yoffset="4" xadvance="3" page="0" chnl="15" />
|
|
||||||
<char id="109" x="73" y="92" width="6" height="5" xoffset="0" yoffset="6" xadvance="7" page="0" chnl="15" />
|
|
||||||
<char id="110" x="86" y="92" width="5" height="5" xoffset="0" yoffset="6" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="111" x="20" y="100" width="4" height="5" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="112" x="105" y="76" width="4" height="7" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="113" x="55" y="77" width="4" height="7" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="114" x="0" y="103" width="4" height="5" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="115" x="121" y="92" width="4" height="5" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="116" x="116" y="92" width="4" height="5" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="117" x="10" y="103" width="4" height="5" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="118" x="5" y="103" width="4" height="5" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="119" x="80" y="92" width="5" height="5" xoffset="0" yoffset="6" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="120" x="69" y="99" width="3" height="5" xoffset="0" yoffset="6" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="121" x="60" y="77" width="4" height="7" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="122" x="25" y="100" width="4" height="5" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="123" x="30" y="33" width="4" height="9" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="124" x="0" y="44" width="1" height="9" xoffset="0" yoffset="4" xadvance="2" page="0" chnl="15" />
|
|
||||||
<char id="125" x="80" y="32" width="4" height="9" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="126" x="112" y="98" width="6" height="2" xoffset="0" yoffset="7" xadvance="7" page="0" chnl="15" />
|
|
||||||
<char id="160" x="37" y="106" width="3" height="1" xoffset="-1" yoffset="13" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="161" x="124" y="32" width="1" height="9" xoffset="0" yoffset="4" xadvance="2" page="0" chnl="15" />
|
|
||||||
<char id="162" x="70" y="76" width="4" height="7" xoffset="0" yoffset="5" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="163" x="75" y="76" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="164" x="88" y="98" width="4" height="4" xoffset="0" yoffset="5" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="165" x="109" y="60" width="5" height="7" xoffset="0" yoffset="4" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="166" x="126" y="32" width="1" height="9" xoffset="0" yoffset="4" xadvance="2" page="0" chnl="15" />
|
|
||||||
<char id="167" x="85" y="76" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="168" x="45" y="106" width="3" height="1" xoffset="0" yoffset="4" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="169" x="2" y="44" width="7" height="8" xoffset="0" yoffset="3" xadvance="8" page="0" chnl="15" />
|
|
||||||
<char id="170" x="45" y="100" width="4" height="5" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="171" x="104" y="92" width="5" height="5" xoffset="0" yoffset="5" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="172" x="119" y="98" width="4" height="2" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="174" x="10" y="43" width="7" height="8" xoffset="0" yoffset="3" xadvance="8" page="0" chnl="15" />
|
|
||||||
<char id="175" x="22" y="106" width="4" height="1" xoffset="0" yoffset="2" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="176" x="83" y="98" width="4" height="4" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="177" x="27" y="93" width="5" height="6" xoffset="0" yoffset="5" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="178" x="55" y="99" width="4" height="5" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="179" x="60" y="99" width="4" height="5" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="180" x="10" y="109" width="2" height="2" xoffset="1" yoffset="4" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="181" x="90" y="76" width="4" height="7" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="182" x="82" y="22" width="5" height="9" xoffset="0" yoffset="4" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="183" x="7" y="109" width="2" height="2" xoffset="1" yoffset="8" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="184" x="101" y="98" width="2" height="4" xoffset="1" yoffset="10" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="185" x="97" y="98" width="3" height="4" xoffset="0" yoffset="4" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="186" x="15" y="102" width="4" height="5" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="187" x="110" y="92" width="5" height="5" xoffset="0" yoffset="5" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="188" x="68" y="22" width="7" height="9" xoffset="0" yoffset="2" xadvance="8" page="0" chnl="15" />
|
|
||||||
<char id="189" x="60" y="22" width="7" height="9" xoffset="0" yoffset="2" xadvance="8" page="0" chnl="15" />
|
|
||||||
<char id="190" x="8" y="0" width="7" height="10" xoffset="0" yoffset="1" xadvance="8" page="0" chnl="15" />
|
|
||||||
<char id="191" x="95" y="76" width="4" height="7" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="192" x="10" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="193" x="15" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="194" x="45" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="195" x="55" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="196" x="5" y="34" width="4" height="9" xoffset="0" yoffset="2" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="197" x="65" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="198" x="0" y="63" width="8" height="7" xoffset="0" yoffset="4" xadvance="9" page="0" chnl="15" />
|
|
||||||
<char id="199" x="15" y="33" width="4" height="9" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="200" x="80" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="201" x="85" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="202" x="100" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="203" x="20" y="33" width="4" height="9" xoffset="0" yoffset="2" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="204" x="125" y="11" width="2" height="10" xoffset="0" yoffset="1" xadvance="3" page="0" chnl="15" />
|
|
||||||
<char id="205" x="57" y="22" width="2" height="10" xoffset="1" yoffset="1" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="206" x="42" y="22" width="3" height="10" xoffset="0" yoffset="1" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="207" x="120" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="208" x="0" y="71" width="5" height="7" xoffset="0" yoffset="4" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="209" x="0" y="23" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="210" x="5" y="23" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="211" x="15" y="22" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="212" x="20" y="22" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="213" x="28" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="214" x="60" y="32" width="4" height="9" xoffset="0" yoffset="2" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="215" x="65" y="99" width="3" height="5" xoffset="1" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="216" x="18" y="61" width="7" height="7" xoffset="0" yoffset="4" xadvance="8" page="0" chnl="15" />
|
|
||||||
<char id="217" x="53" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="218" x="58" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="219" x="118" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="220" x="25" y="33" width="4" height="9" xoffset="0" yoffset="2" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="221" x="38" y="22" width="3" height="10" xoffset="0" yoffset="1" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="222" x="50" y="93" width="4" height="6" xoffset="0" yoffset="5" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="223" x="60" y="52" width="4" height="8" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="224" x="108" y="42" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="225" x="93" y="42" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="226" x="78" y="42" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="227" x="55" y="52" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="228" x="110" y="76" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="229" x="80" y="51" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="230" x="64" y="93" width="8" height="5" xoffset="0" yoffset="6" xadvance="9" page="0" chnl="15" />
|
|
||||||
<char id="231" x="117" y="84" width="3" height="7" xoffset="0" yoffset="6" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="232" x="98" y="42" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="233" x="103" y="42" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="234" x="35" y="52" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="235" x="115" y="76" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="236" x="118" y="51" width="2" height="8" xoffset="0" yoffset="3" xadvance="3" page="0" chnl="15" />
|
|
||||||
<char id="237" x="115" y="51" width="2" height="8" xoffset="1" yoffset="3" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="238" x="107" y="51" width="3" height="8" xoffset="0" yoffset="3" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="239" x="85" y="84" width="3" height="7" xoffset="0" yoffset="4" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="240" x="90" y="51" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="241" x="67" y="42" width="5" height="8" xoffset="0" yoffset="3" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="242" x="88" y="42" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="243" x="123" y="42" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="244" x="0" y="54" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="245" x="20" y="52" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="246" x="120" y="76" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="247" x="98" y="92" width="5" height="5" xoffset="0" yoffset="5" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="248" x="20" y="93" width="6" height="6" xoffset="0" yoffset="5" xadvance="7" page="0" chnl="15" />
|
|
||||||
<char id="249" x="25" y="52" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="250" x="50" y="52" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="251" x="75" y="51" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="252" x="0" y="87" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="253" x="63" y="0" width="4" height="10" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="254" x="68" y="0" width="4" height="10" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="255" x="108" y="22" width="4" height="9" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="256" x="50" y="33" width="4" height="9" xoffset="0" yoffset="2" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="257" x="5" y="87" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="258" x="83" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="259" x="118" y="42" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="260" x="35" y="33" width="4" height="9" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="261" x="10" y="87" width="4" height="7" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="262" x="0" y="12" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="263" x="99" y="51" width="3" height="8" xoffset="0" yoffset="3" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="264" x="123" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="265" x="103" y="51" width="3" height="8" xoffset="0" yoffset="3" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="266" x="98" y="22" width="4" height="9" xoffset="0" yoffset="2" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="267" x="121" y="84" width="3" height="7" xoffset="0" yoffset="4" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="268" x="113" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="269" x="95" y="51" width="3" height="8" xoffset="0" yoffset="3" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="270" x="103" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="271" x="26" y="61" width="7" height="7" xoffset="0" yoffset="4" xadvance="8" page="0" chnl="15" />
|
|
||||||
<char id="272" x="121" y="59" width="5" height="7" xoffset="0" yoffset="4" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="273" x="61" y="42" width="5" height="8" xoffset="0" yoffset="3" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="274" x="40" y="33" width="4" height="9" xoffset="0" yoffset="2" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="275" x="15" y="86" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="276" x="48" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="277" x="83" y="42" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="278" x="85" y="32" width="4" height="9" xoffset="0" yoffset="2" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="279" x="20" y="85" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="280" x="70" y="32" width="4" height="9" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="281" x="25" y="85" width="4" height="7" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="282" x="38" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="283" x="70" y="51" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="284" x="33" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="285" x="10" y="22" width="4" height="10" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="286" x="95" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="287" x="40" y="11" width="4" height="10" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="288" x="0" y="34" width="4" height="9" xoffset="0" yoffset="2" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="289" x="123" y="22" width="4" height="9" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="290" x="118" y="22" width="4" height="9" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="291" x="88" y="0" width="4" height="10" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="292" x="108" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="293" x="93" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="294" x="34" y="61" width="6" height="7" xoffset="0" yoffset="4" xadvance="7" page="0" chnl="15" />
|
|
||||||
<char id="295" x="49" y="43" width="5" height="8" xoffset="0" yoffset="3" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="296" x="78" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="297" x="5" y="53" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="298" x="94" y="32" width="3" height="9" xoffset="0" yoffset="2" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="299" x="101" y="84" width="3" height="7" xoffset="0" yoffset="4" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="300" x="30" y="22" width="3" height="10" xoffset="0" yoffset="1" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="301" x="111" y="51" width="3" height="8" xoffset="0" yoffset="3" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="302" x="112" y="32" width="2" height="9" xoffset="0" yoffset="4" xadvance="3" page="0" chnl="15" />
|
|
||||||
<char id="303" x="118" y="32" width="2" height="9" xoffset="0" yoffset="4" xadvance="3" page="0" chnl="15" />
|
|
||||||
<char id="304" x="106" y="32" width="2" height="9" xoffset="1" yoffset="2" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="305" x="126" y="91" width="1" height="5" xoffset="1" yoffset="6" xadvance="3" page="0" chnl="15" />
|
|
||||||
<char id="306" x="48" y="61" width="6" height="7" xoffset="1" yoffset="4" xadvance="8" page="0" chnl="15" />
|
|
||||||
<char id="307" x="90" y="32" width="3" height="9" xoffset="1" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="308" x="16" y="0" width="5" height="10" xoffset="0" yoffset="1" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="309" x="50" y="22" width="3" height="10" xoffset="0" yoffset="3" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="310" x="10" y="33" width="4" height="9" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="311" x="89" y="84" width="3" height="7" xoffset="0" yoffset="6" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="312" x="93" y="98" width="3" height="4" xoffset="0" yoffset="7" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="313" x="50" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="314" x="5" y="0" width="2" height="11" xoffset="0" yoffset="0" xadvance="3" page="0" chnl="15" />
|
|
||||||
<char id="315" x="103" y="22" width="4" height="9" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="316" x="54" y="22" width="2" height="10" xoffset="0" yoffset="3" xadvance="3" page="0" chnl="15" />
|
|
||||||
<char id="317" x="18" y="69" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="318" x="23" y="69" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="319" x="28" y="69" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="320" x="105" y="84" width="3" height="7" xoffset="0" yoffset="4" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="321" x="79" y="60" width="5" height="7" xoffset="0" yoffset="4" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="322" x="38" y="69" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="323" x="98" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="324" x="25" y="43" width="5" height="8" xoffset="0" yoffset="3" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="325" x="113" y="22" width="4" height="9" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="326" x="85" y="60" width="5" height="7" xoffset="0" yoffset="6" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="327" x="73" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="328" x="37" y="43" width="5" height="8" xoffset="0" yoffset="3" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="329" x="18" y="43" width="6" height="8" xoffset="0" yoffset="3" xadvance="7" page="0" chnl="15" />
|
|
||||||
<char id="330" x="73" y="60" width="5" height="7" xoffset="0" yoffset="4" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="331" x="67" y="60" width="5" height="7" xoffset="0" yoffset="6" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="332" x="93" y="22" width="4" height="9" xoffset="0" yoffset="2" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="333" x="93" y="68" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="334" x="43" y="0" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="335" x="40" y="52" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="336" x="5" y="12" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="337" x="45" y="52" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="338" x="9" y="62" width="8" height="7" xoffset="0" yoffset="4" xadvance="9" page="0" chnl="15" />
|
|
||||||
<char id="339" x="55" y="93" width="8" height="5" xoffset="0" yoffset="6" xadvance="9" page="0" chnl="15" />
|
|
||||||
<char id="340" x="20" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="341" x="55" y="43" width="5" height="8" xoffset="0" yoffset="3" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="342" x="45" y="33" width="4" height="9" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="343" x="115" y="60" width="5" height="7" xoffset="0" yoffset="6" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="344" x="25" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="345" x="43" y="43" width="5" height="8" xoffset="0" yoffset="3" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="346" x="30" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="347" x="85" y="51" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="348" x="35" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="349" x="60" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="350" x="55" y="33" width="4" height="9" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="351" x="45" y="77" width="4" height="7" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="352" x="70" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="353" x="65" y="51" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="354" x="102" y="32" width="3" height="9" xoffset="0" yoffset="4" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="355" x="65" y="77" width="4" height="7" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="356" x="46" y="22" width="3" height="10" xoffset="0" yoffset="1" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="357" x="33" y="93" width="5" height="6" xoffset="0" yoffset="5" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="358" x="55" y="61" width="5" height="7" xoffset="0" yoffset="4" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="359" x="80" y="76" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="360" x="25" y="22" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="361" x="73" y="42" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="362" x="75" y="32" width="4" height="9" xoffset="0" yoffset="2" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="363" x="100" y="76" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="364" x="75" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="365" x="15" y="52" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="366" x="0" y="0" width="4" height="11" xoffset="0" yoffset="0" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="367" x="65" y="32" width="4" height="9" xoffset="0" yoffset="2" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="368" x="90" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="369" x="113" y="42" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="370" x="76" y="22" width="5" height="9" xoffset="0" yoffset="4" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="371" x="103" y="60" width="5" height="7" xoffset="0" yoffset="6" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="372" x="22" y="0" width="5" height="10" xoffset="0" yoffset="1" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="373" x="31" y="43" width="5" height="8" xoffset="0" yoffset="3" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="374" x="34" y="22" width="3" height="10" xoffset="0" yoffset="1" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="375" x="105" y="11" width="4" height="10" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="376" x="98" y="32" width="3" height="9" xoffset="0" yoffset="2" xadvance="4" page="0" chnl="15" />
|
|
||||||
<char id="377" x="110" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="378" x="10" y="52" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="379" x="88" y="22" width="4" height="9" xoffset="0" yoffset="2" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="380" x="60" y="85" width="4" height="7" xoffset="0" yoffset="4" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="381" x="115" y="11" width="4" height="10" xoffset="0" yoffset="1" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="382" x="30" y="52" width="4" height="8" xoffset="0" yoffset="3" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="956" x="75" y="84" width="4" height="7" xoffset="0" yoffset="6" xadvance="5" page="0" chnl="15" />
|
|
||||||
<char id="8364" x="12" y="70" width="5" height="7" xoffset="0" yoffset="4" xadvance="6" page="0" chnl="15" />
|
|
||||||
<char id="12288" x="15" y="108" width="6" height="1" xoffset="-2" yoffset="13" xadvance="16" page="0" chnl="15" />
|
|
||||||
</chars>
|
|
||||||
</font>
|
|
|
@ -1,274 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<map version="1.2" tiledversion="1.3.1" orientation="orthogonal" renderorder="right-down" compressionlevel="0" width="50" height="50" tilewidth="16" tileheight="16" infinite="0" nextlayerid="7" nextobjectid="32">
|
|
||||||
<tileset firstgid="1" source="Tileset.tsx" />
|
|
||||||
<layer id="1" name="Ground" width="50" height="50">
|
|
||||||
<data encoding="csv">
|
|
||||||
450,450,450,450,450,451,3,36,38,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,132,133,71,102,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
450,450,450,450,450,451,3,36,38,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,132,133,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
450,450,450,450,420,483,3,36,38,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,164,40,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
450,450,450,450,451,3,3,36,38,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,132,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
450,450,450,450,451,3,3,36,38,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,132,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
450,450,450,450,451,3,3,36,38,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,132,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
450,450,450,420,483,3,3,36,38,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,100,72,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
450,450,450,451,3,3,3,36,38,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,100,72,133,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
450,450,450,451,3,3,3,36,38,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,100,72,133,133,39,166,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
450,450,420,483,3,3,3,36,38,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,100,72,133,133,39,166,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
450,450,451,3,3,3,3,36,38,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,132,133,133,39,166,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
450,450,452,419,3,3,3,36,38,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,132,133,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
450,450,450,451,3,3,3,36,38,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,132,133,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
450,450,450,452,419,3,3,36,38,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,132,133,39,166,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
450,450,450,450,451,3,3,36,38,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,132,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
450,450,450,450,451,3,3,36,38,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,132,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
450,450,450,450,451,3,3,36,66,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
|
||||||
450,450,450,420,483,3,3,68,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,35,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
|
|
||||||
450,450,450,451,3,3,3,3,3,3,3,132,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,36,37,34,69,69,69,69,69,69,69,69,69,69,69,69,69,
|
|
||||||
450,450,450,452,419,3,3,3,3,3,100,72,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,417,418,419,3,3,3,3,36,37,38,3,3,3,3,3,3,3,3,3,3,3,417,418,
|
|
||||||
450,450,450,450,451,3,3,3,3,3,132,133,133,134,3,3,3,3,3,3,3,3,3,3,3,3,417,453,450,451,3,3,3,3,36,37,38,3,3,3,3,3,3,3,3,3,3,417,453,2684355010,
|
|
||||||
450,450,450,450,451,3,3,3,3,3,132,133,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,36,37,38,3,3,3,3,3,3,3,3,3,417,453,2684355010,2684355010,
|
|
||||||
450,450,450,450,451,3,3,3,3,3,164,40,133,71,102,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,36,37,38,3,3,3,3,3,3,3,3,3,449,2684355010,2684355010,2684355010,
|
|
||||||
450,450,450,420,483,3,3,3,3,3,3,132,133,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,36,37,38,3,3,3,3,3,3,3,3,417,453,2684355010,2684355010,2684355010,
|
|
||||||
450,450,450,451,3,3,3,3,3,3,3,164,40,133,71,102,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,36,37,38,3,3,3,3,3,3,3,417,453,2684355010,2684355010,2684355010,2684355010,
|
|
||||||
450,450,420,483,3,3,3,3,3,3,3,3,132,133,133,71,102,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,36,37,38,3,3,3,3,3,3,3,449,2684355010,2684355010,2684355010,2684355010,2684355010,
|
|
||||||
450,420,483,3,3,3,3,3,3,3,3,3,164,40,133,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,36,37,38,3,417,418,418,419,3,3,449,2684355010,2684355010,2684355010,2684355010,2684355010,
|
|
||||||
450,451,3,3,3,3,3,3,3,3,3,3,3,164,40,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,36,37,38,3,449,2684355010,2684355010,452,419,3,449,2684355010,2684355010,2684355010,2684355010,2684355010,
|
|
||||||
450,451,3,3,3,3,3,3,3,3,3,3,3,3,132,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,36,37,38,417,453,2684355010,2684355010,2684355010,451,3,449,2684355010,2684355010,2684355010,2684355010,2684355010,
|
|
||||||
450,451,3,3,3,3,3,3,3,3,3,3,3,3,132,133,134,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,36,37,38,449,2684355010,2684355010,2684355010,2684355010,451,3,449,2684355010,2684355010,2684355010,2684355010,2684355010,
|
|
||||||
450,452,419,3,3,3,3,3,3,3,3,3,3,3,132,133,134,3,3,3,3,3,3,3,36,37,38,3,3,3,3,3,3,3,36,37,38,449,2684355010,2684355010,2684355010,2684355010,451,3,481,482,421,2684355010,2684355010,2684355010,
|
|
||||||
450,450,451,3,3,3,3,3,3,3,3,3,3,3,132,133,71,102,3,100,101,101,101,101,36,37,66,5,5,5,5,5,5,5,67,37,38,449,2684355010,2684355010,2684355010,2684355010,451,3,3,3,481,482,482,482,
|
|
||||||
450,450,451,3,3,3,3,3,3,3,3,3,3,100,72,133,133,71,101,72,133,133,133,133,36,37,37,37,37,37,37,37,37,37,37,37,38,481,421,2684355010,2684355010,420,483,3,3,3,3,16,16,16,
|
|
||||||
450,450,451,3,3,3,3,3,3,3,3,3,100,72,133,133,133,133,133,133,133,39,165,165,68,69,69,69,69,69,69,69,69,69,69,69,70,3,481,482,482,483,3,3,16,16,16,16,16,16,
|
|
||||||
450,450,451,3,3,3,132,133,71,101,101,101,72,133,133,133,39,165,165,165,165,166,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,16,16,16,16,16,16,16,
|
|
||||||
450,450,451,3,3,3,132,133,133,133,133,133,133,133,39,165,166,3,3,3,3,3,3,3,417,418,418,418,418,418,418,418,418,418,418,419,3,3,3,3,3,16,16,16,16,16,16,16,16,16,
|
|
||||||
450,450,452,419,3,3,164,165,165,165,165,165,165,165,166,3,3,3,3,3,3,3,3,417,453,2684355010,2684355010,2684355010,2684355010,2684355010,2684355010,2684355010,2684355010,2684355010,2684355010,451,3,3,3,3,16,16,16,16,16,16,16,16,16,16,
|
|
||||||
450,450,450,451,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,481,421,2684355010,2684355010,2684355010,2684355010,2684355010,2684355010,2684355010,2684355010,2684355010,420,483,3,16,16,16,16,16,16,16,16,16,16,16,16,16,
|
|
||||||
450,450,450,451,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,481,482,482,482,482,482,482,482,482,482,483,3,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
|
|
||||||
450,450,450,451,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
|
|
||||||
450,450,450,451,3,3,3,3,3,3,3,3,3,3,3,3,3,3,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,3,
|
|
||||||
450,450,450,451,3,3,3,3,3,3,3,3,3,3,3,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,3,3,3,
|
|
||||||
2684355010,450,420,483,3,3,3,3,3,3,3,3,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,3,3,3,3,3,
|
|
||||||
2684355010,420,483,3,3,3,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,3,3,3,3,3,3,
|
|
||||||
482,483,3,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,3,3,3,3,3,3,3,3,
|
|
||||||
3,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
||||||
16,16,16,16,16,16,16,16,16,16,16,16,16,16,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
|
|
||||||
</data>
|
|
||||||
</layer>
|
|
||||||
<layer id="2" name="Ground1" width="50" height="50">
|
|
||||||
<data encoding="csv">
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,17,17,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,17,17,17,17,17,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,17,17,17,17,17,18,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,17,17,17,17,18,19,19,54,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,17,17,18,19,19,54,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,17,17,17,17,18,54,0,0,0,21,83,83,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,17,17,17,18,19,54,0,0,21,83,84,17,17,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,17,17,17,17,17,18,54,0,0,21,83,84,17,17,17,17,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,18,19,54,0,0,21,84,17,17,17,17,17,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,18,19,54,0,0,0,21,84,17,17,17,17,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,17,17,17,17,17,17,17,18,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,54,0,21,83,83,83,84,17,17,17,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,17,17,17,17,17,17,17,17,17,17,17,18,19,54,0,0,0,0,0,0,0,0,0,0,0,0,0,21,83,83,83,84,17,17,17,17,17,17,0,0,0,0,0,0,
|
|
||||||
0,0,0,17,17,17,17,17,17,17,17,17,17,17,18,19,19,54,0,0,0,0,0,0,0,0,21,83,83,83,83,83,83,84,17,17,17,17,17,17,17,17,0,0,0,0,0,0,0,0,
|
|
||||||
0,17,17,17,17,17,17,17,17,17,17,18,19,19,54,0,0,0,21,83,83,83,83,83,83,83,84,17,17,17,17,17,17,17,17,17,17,17,17,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
17,17,17,17,17,17,18,19,19,19,19,54,0,0,21,83,83,83,84,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
17,17,18,19,19,19,54,0,0,0,21,83,83,83,84,17,17,17,17,17,17,17,17,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
19,19,54,0,0,0,21,83,83,83,84,17,17,17,17,17,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,21,84,17,17,17,17,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
|
||||||
</data>
|
|
||||||
</layer>
|
|
||||||
<layer id="3" name="Objects" width="50" height="50">
|
|
||||||
<data encoding="csv">
|
|
||||||
0,0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,365,430,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,397,0,237,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,368,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,368,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,237,0,
|
|
||||||
0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,397,0,237,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,303,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,366,366,
|
|
||||||
0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,301,302,0,0,0,0,0,0,0,0,0,0,0,0,0,0,397,0,0,
|
|
||||||
0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,397,0,0,
|
|
||||||
0,0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,303,0,0,0,0,199,198,198,198,198,198,199,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,0,0,
|
|
||||||
0,365,366,366,430,0,0,0,0,0,0,0,0,0,0,0,0,0,197,198,198,198,199,198,198,198,198,198,199,198,198,198,200,0,0,0,0,0,0,0,303,0,0,0,0,0,0,397,0,0,
|
|
||||||
0,397,0,301,302,0,0,0,0,0,0,0,0,0,0,0,0,0,197,198,198,198,199,198,198,198,198,198,199,198,198,198,200,0,0,0,0,0,237,0,0,0,0,0,0,0,0,397,0,0,
|
|
||||||
0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,265,266,266,266,267,266,266,266,266,266,267,266,266,266,268,0,0,0,0,0,111,0,0,0,0,0,0,0,0,397,0,0,
|
|
||||||
0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197,198,198,198,199,198,198,198,198,198,199,198,198,198,200,0,0,0,0,0,77,0,0,0,0,0,0,365,366,430,0,0,
|
|
||||||
0,397,0,0,0,0,0,0,0,0,0,301,302,0,0,0,0,0,197,198,198,198,199,198,198,198,198,198,199,198,198,198,200,0,0,0,0,0,77,0,0,0,0,0,0,397,0,0,303,0,
|
|
||||||
303,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,265,266,266,266,267,266,266,290,266,266,267,266,266,266,268,0,0,0,0,0,77,0,0,0,0,0,0,397,0,0,0,0,
|
|
||||||
0,368,0,193,194,195,194,194,194,195,194,196,0,0,0,0,0,0,197,198,198,198,199,198,198,322,198,198,199,198,198,198,200,0,0,0,0,0,77,0,0,0,0,0,0,397,0,0,0,0,
|
|
||||||
0,397,0,193,194,195,194,194,194,195,194,196,0,0,0,0,0,0,0,7,7,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,77,0,301,302,0,0,0,397,0,0,0,0,
|
|
||||||
0,397,0,193,194,195,194,194,194,195,194,196,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,77,0,0,0,0,0,0,397,0,0,0,0,
|
|
||||||
0,397,0,193,194,195,194,290,194,195,194,196,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,77,0,0,0,0,0,0,399,0,97,98,98,
|
|
||||||
0,397,0,193,194,195,194,322,194,195,194,196,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,77,0,0,0,0,0,97,98,98,74,0,0,
|
|
||||||
0,397,301,225,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,77,0,0,0,0,97,74,0,0,0,0,0,
|
|
||||||
0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,237,109,46,46,46,46,46,46,46,46,46,46,46,46,46,110,0,0,97,98,74,0,0,0,0,0,0,
|
|
||||||
0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,303,0,0,0,0,0,0,301,302,0,0,0,0,0,97,74,0,0,0,0,0,0,0,0,
|
|
||||||
0,429,366,367,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,98,98,74,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,397,0,0,0,0,0,0,0,0,301,302,0,0,0,0,0,0,0,301,302,0,0,0,0,0,0,0,0,0,0,0,0,0,97,74,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,98,98,74,0,0,0,0,0,0,0,0,0,0,0,41,162,
|
|
||||||
0,301,302,397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,98,98,98,98,98,98,98,98,98,98,98,98,98,98,74,0,0,0,0,0,0,0,0,0,0,0,0,41,162,163,0,
|
|
||||||
0,0,0,397,0,0,0,0,0,0,0,0,0,0,0,97,98,98,74,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,162,163,0,0,0,
|
|
||||||
0,0,0,397,0,0,0,0,0,0,0,0,97,98,98,74,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,163,0,0,0,0,0,
|
|
||||||
0,0,0,399,0,303,97,98,98,98,98,98,74,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,162,163,0,0,0,301,302,0,
|
|
||||||
0,0,0,97,98,98,74,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,162,162,163,0,0,0,0,0,0,0,0,
|
|
||||||
0,97,98,74,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,163,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
98,74,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,162,162,162,162,162,162,162,162,162,162,162,163,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,162,162,162,162,162,162,163,0,0,301,302,0,0,0,0,0,0,0,0,303,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,41,162,162,162,162,163,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,303,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,41,162,162,162,162,163,0,0,0,0,0,0,0,303,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
|
||||||
</data>
|
|
||||||
</layer>
|
|
||||||
<layer id="4" name="Objects1" width="50" height="50">
|
|
||||||
<data encoding="csv">
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,237,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,7,7,7,7,7,7,7,7,365,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,298,299,300,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,330,331,332,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,362,363,364,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,385,386,387,0,354,0,0,0,354,0,385,386,387,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,104,105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,385,386,387,0,0,135,0,137,0,0,385,386,387,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,135,0,137,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,385,386,387,0,0,0,0,0,0,0,0,0,229,301,302,230,231,230,230,230,230,230,231,303,230,230,232,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,257,258,259,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,354,0,289,0,291,0,354,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,289,0,291,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,302,226,227,226,226,226,227,226,228,0,0,0,0,0,0,0,0,0,0,0,0,7,7,7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
|
||||||
</data>
|
|
||||||
</layer>
|
|
||||||
<layer id="6" name="Above" width="50" height="50">
|
|
||||||
<data encoding="csv">
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,333,335,173,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,205,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,336,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,336,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,173,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,205,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,173,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,173,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,205,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,205,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,271,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,333,334,334,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,261,263,264,0,0,0,0,269,270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,261,262,262,262,262,293,327,296,262,262,262,262,264,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,271,261,293,326,326,326,326,325,327,328,326,326,326,326,296,264,0,0,0,0,0,0,0,0,0,0,0,0,0,0,336,0,0,
|
|
||||||
0,333,334,334,335,0,0,0,0,0,0,0,0,0,0,0,0,292,293,325,326,326,326,326,325,327,328,326,326,326,326,328,296,297,0,0,0,0,173,0,271,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,269,270,0,0,0,0,0,0,0,0,0,0,0,0,356,325,325,326,326,326,326,357,359,360,326,326,326,326,328,328,361,0,0,0,0,205,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,356,325,357,358,358,358,358,389,0,392,358,358,358,358,360,328,361,0,0,0,0,79,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,356,357,389,0,0,0,0,0,0,0,0,0,0,0,392,360,361,0,0,0,0,0,0,0,0,0,0,0,333,334,335,0,0,
|
|
||||||
0,0,0,0,0,261,262,262,262,264,0,269,270,0,0,0,0,388,389,0,0,0,0,0,0,0,0,0,0,0,0,0,392,393,0,0,0,0,0,0,0,0,0,0,0,0,0,0,271,0,
|
|
||||||
271,0,0,261,262,293,326,326,326,296,262,264,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,336,292,293,326,325,326,326,326,328,326,296,297,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,356,325,326,357,358,358,358,360,326,328,361,0,0,0,0,0,0,269,270,0,0,0,0,0,0,0,0,271,0,0,0,0,0,0,0,0,0,0,269,270,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,356,357,358,389,0,0,0,392,358,360,361,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,388,389,0,0,0,0,0,0,0,392,393,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,43,43,43,43,43,43,0,0,0,0,0,0,0,0,336,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,8,2147483656,9,1073741833,3221225545,43,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,269,270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,173,0,0,0,0,0,0,43,43,43,43,43,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,205,13,14,14,14,14,14,14,14,14,14,14,14,14,14,15,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,271,0,0,0,0,0,0,269,270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,333,334,335,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,269,270,0,0,0,0,0,0,0,269,270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,269,270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,336,0,271,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,269,270,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,269,270,0,0,0,0,0,0,0,0,271,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,271,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,271,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
|
||||||
</data>
|
|
||||||
</layer>
|
|
||||||
</map>
|
|
Binary file not shown.
Before Width: | Height: | Size: 46 KiB |
|
@ -1,123 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<tileset version="1.2" tiledversion="1.3.1" name="TownTiles" tilewidth="16" tileheight="16" tilecount="512" columns="32">
|
|
||||||
<image source="Tiles.png" width="512" height="256" />
|
|
||||||
<tile id="3">
|
|
||||||
<properties>
|
|
||||||
<property name="Walkability" type="int" value="30" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="4">
|
|
||||||
<properties>
|
|
||||||
<property name="Walkability" type="int" value="30" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="5">
|
|
||||||
<properties>
|
|
||||||
<property name="Walkability" type="int" value="30" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="7">
|
|
||||||
<objectgroup draworder="index" id="5">
|
|
||||||
<object id="4" x="8" y="3" width="5" height="10" />
|
|
||||||
</objectgroup>
|
|
||||||
</tile>
|
|
||||||
<tile id="8">
|
|
||||||
<objectgroup draworder="index" id="2">
|
|
||||||
<object id="1" x="3" y="2" width="10" height="5" />
|
|
||||||
</objectgroup>
|
|
||||||
</tile>
|
|
||||||
<tile id="15">
|
|
||||||
<animation>
|
|
||||||
<frame tileid="15" duration="1000" />
|
|
||||||
<frame tileid="47" duration="1000" />
|
|
||||||
</animation>
|
|
||||||
</tile>
|
|
||||||
<tile id="33">
|
|
||||||
<properties>
|
|
||||||
<property name="Walkability" type="int" value="30" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="34">
|
|
||||||
<properties>
|
|
||||||
<property name="Walkability" type="int" value="30" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="35">
|
|
||||||
<properties>
|
|
||||||
<property name="Walkability" type="int" value="30" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="36">
|
|
||||||
<properties>
|
|
||||||
<property name="Walkability" type="int" value="30" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="37">
|
|
||||||
<properties>
|
|
||||||
<property name="Walkability" type="int" value="30" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="65">
|
|
||||||
<properties>
|
|
||||||
<property name="Walkability" type="int" value="30" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="66">
|
|
||||||
<properties>
|
|
||||||
<property name="Walkability" type="int" value="30" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="67">
|
|
||||||
<properties>
|
|
||||||
<property name="Walkability" type="int" value="30" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="68">
|
|
||||||
<properties>
|
|
||||||
<property name="Walkability" type="int" value="30" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="69">
|
|
||||||
<properties>
|
|
||||||
<property name="Walkability" type="int" value="30" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="72">
|
|
||||||
<objectgroup draworder="index" id="2">
|
|
||||||
<object id="1" x="12" y="0" width="4" height="4" />
|
|
||||||
</objectgroup>
|
|
||||||
</tile>
|
|
||||||
<tile id="132">
|
|
||||||
<properties>
|
|
||||||
<property name="Walkability" type="int" value="60" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="172">
|
|
||||||
<properties>
|
|
||||||
<property name="LightColor" type="color" value="#ffaa6300" />
|
|
||||||
<property name="LightRadius" type="float" value="5.5" />
|
|
||||||
<property name="LightType" value="Lamp" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="289">
|
|
||||||
<properties>
|
|
||||||
<property name="LightColor" type="color" value="#ff676e73" />
|
|
||||||
<property name="LightRadius" type="float" value="1.5" />
|
|
||||||
<property name="LightType" value="Window" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="353">
|
|
||||||
<properties>
|
|
||||||
<property name="LightColor" type="color" value="#ff676e73" />
|
|
||||||
<property name="LightRadius" type="float" value="2.5" />
|
|
||||||
<property name="LightType" value="Window" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
<tile id="385">
|
|
||||||
<properties>
|
|
||||||
<property name="LightColor" type="color" value="#ff676e73" />
|
|
||||||
<property name="LightRadius" type="float" value="2.5" />
|
|
||||||
<property name="LightType" value="Window" />
|
|
||||||
</properties>
|
|
||||||
</tile>
|
|
||||||
</tileset>
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -19,16 +19,11 @@
|
||||||
<PackageReference Include="MonoGame.Extended.Content.Pipeline" Version="3.8.0" />
|
<PackageReference Include="MonoGame.Extended.Content.Pipeline" Version="3.8.0" />
|
||||||
<PackageReference Include="MonoGame.Extended.Tiled" Version="3.8.0" />
|
<PackageReference Include="MonoGame.Extended.Tiled" Version="3.8.0" />
|
||||||
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.1.303" />
|
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.1.303" />
|
||||||
<PackageReference Include="FontStashSharp.MonoGame" Version="1.2.8" />
|
<PackageReference Include="FontStashSharp.MonoGame" Version="1.3.3" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Content\Fonts\Symbola-Emoji.ttf" />
|
<Content Include="Content\Fonts\Symbola-Emoji.ttf" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="RestoreDotnetTools" BeforeTargets="Restore">
|
|
||||||
<Message Text="Restoring dotnet tools" Importance="High" />
|
|
||||||
<Exec Command="dotnet tool restore" />
|
|
||||||
</Target>
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<VSTestLogger>nunit</VSTestLogger>
|
<VSTestLogger>nunit</VSTestLogger>
|
||||||
<VSTestResultsDirectory>TestResults.FNA</VSTestResultsDirectory>
|
<VSTestResultsDirectory>TestResults.FNA</VSTestResultsDirectory>
|
||||||
<RunSettingsFilePath>Tests.FNA.runsettings</RunSettingsFilePath>
|
<RunSettingsFilePath>Tests.FNA.runsettings</RunSettingsFilePath>
|
||||||
|
@ -18,24 +18,21 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\FNA\FNA.Core.csproj" />
|
<ProjectReference Include="..\ThirdParty\FNA\FNA.Core.csproj" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
|
||||||
<PackageReference Include="coverlet.collector" Version="3.2.0">
|
<PackageReference Include="coverlet.collector" Version="6.0.0" />
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<PackageReference Include="NUnit" Version="3.14.0" />
|
||||||
</PackageReference>
|
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
|
<PackageReference Include="NunitXml.TestLogger" Version="3.1.15" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.3.1" />
|
|
||||||
<PackageReference Include="NunitXml.TestLogger" Version="3.0.127" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Content/**">
|
<Content Include="Content/**">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="../FnaNative/**">
|
<Content Include="../ThirdParty/Native/**">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
<Link>%(Filename)%(Extension)</Link>
|
<Link>%(Filename)%(Extension)</Link>
|
||||||
</Content>
|
</Content>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<VSTestLogger>nunit</VSTestLogger>
|
<VSTestLogger>nunit</VSTestLogger>
|
||||||
<VSTestResultsDirectory>TestResults</VSTestResultsDirectory>
|
<VSTestResultsDirectory>TestResults</VSTestResultsDirectory>
|
||||||
<RunSettingsFilePath>Tests.runsettings</RunSettingsFilePath>
|
<RunSettingsFilePath>Tests.runsettings</RunSettingsFilePath>
|
||||||
|
@ -20,14 +20,11 @@
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="MonoGame.Extended" Version="3.8.0" />
|
<PackageReference Include="MonoGame.Extended" Version="3.8.0" />
|
||||||
|
|
||||||
<PackageReference Include="coverlet.collector" Version="3.2.0">
|
<PackageReference Include="coverlet.collector" Version="6.0.0" />
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<PackageReference Include="NUnit" Version="3.14.0" />
|
||||||
</PackageReference>
|
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
|
<PackageReference Include="NunitXml.TestLogger" Version="3.1.15" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2" />
|
|
||||||
<PackageReference Include="NunitXml.TestLogger" Version="3.0.131" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
1
ThirdParty/FNA
vendored
Submodule
1
ThirdParty/FNA
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 354e2161b759fa052b25e94209d6ea463aaf098f
|
1
ThirdParty/FontStashSharp
vendored
Submodule
1
ThirdParty/FontStashSharp
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 2d40e9f0f681595dbd4341a3e5a64ed6e31f9556
|
BIN
ThirdParty/Native/FAudio.dll
vendored
Normal file
BIN
ThirdParty/Native/FAudio.dll
vendored
Normal file
Binary file not shown.
BIN
ThirdParty/Native/FNA3D.dll
vendored
Normal file
BIN
ThirdParty/Native/FNA3D.dll
vendored
Normal file
Binary file not shown.
BIN
FnaNative/SDL2.dll → ThirdParty/Native/SDL2.dll
vendored
BIN
FnaNative/SDL2.dll → ThirdParty/Native/SDL2.dll
vendored
Binary file not shown.
BIN
ThirdParty/Native/libFAudio.0.dylib
vendored
Normal file
BIN
ThirdParty/Native/libFAudio.0.dylib
vendored
Normal file
Binary file not shown.
BIN
ThirdParty/Native/libFAudio.so.0
vendored
Normal file
BIN
ThirdParty/Native/libFAudio.so.0
vendored
Normal file
Binary file not shown.
BIN
ThirdParty/Native/libFNA3D.0.dylib
vendored
Normal file
BIN
ThirdParty/Native/libFNA3D.0.dylib
vendored
Normal file
Binary file not shown.
BIN
ThirdParty/Native/libFNA3D.so.0
vendored
Normal file
BIN
ThirdParty/Native/libFNA3D.so.0
vendored
Normal file
Binary file not shown.
BIN
ThirdParty/Native/libSDL2-2.0.0.dylib
vendored
Normal file
BIN
ThirdParty/Native/libSDL2-2.0.0.dylib
vendored
Normal file
Binary file not shown.
BIN
ThirdParty/Native/libSDL2-2.0.so.0
vendored
Normal file
BIN
ThirdParty/Native/libSDL2-2.0.so.0
vendored
Normal file
Binary file not shown.
15
build.cake
15
build.cake
|
@ -2,7 +2,7 @@
|
||||||
#tool dotnet:?package=docfx&version=2.70.3
|
#tool dotnet:?package=docfx&version=2.70.3
|
||||||
|
|
||||||
// this is the upcoming version, for prereleases
|
// this is the upcoming version, for prereleases
|
||||||
var version = Argument("version", "6.2.0");
|
var version = Argument("version", "6.3.0");
|
||||||
var target = Argument("target", "Default");
|
var target = Argument("target", "Default");
|
||||||
var branch = Argument("branch", "main");
|
var branch = Argument("branch", "main");
|
||||||
var config = Argument("configuration", "Release");
|
var config = Argument("configuration", "Release");
|
||||||
|
@ -14,8 +14,8 @@ Task("Prepare").Does(() => {
|
||||||
DotNetRestore("MLEM.FNA.sln");
|
DotNetRestore("MLEM.FNA.sln");
|
||||||
|
|
||||||
if (branch != "release") {
|
if (branch != "release") {
|
||||||
var buildNum = EnvironmentVariable("CI_PIPELINE_NUMBER");
|
var buildNum = EnvironmentVariable("GITHUB_RUN_NUMBER");
|
||||||
if (buildNum != null)
|
if (!string.IsNullOrEmpty(buildNum))
|
||||||
version += "-ci." + buildNum;
|
version += "-ci." + buildNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,9 @@ Task("Prepare").Does(() => {
|
||||||
Task("Build").IsDependentOn("Prepare").Does(() =>{
|
Task("Build").IsDependentOn("Prepare").Does(() =>{
|
||||||
var settings = new DotNetBuildSettings {
|
var settings = new DotNetBuildSettings {
|
||||||
Configuration = config,
|
Configuration = config,
|
||||||
ArgumentCustomization = args => args.Append($"/p:Version={version}")
|
ArgumentCustomization = args => args.Append($"/p:Version={version}"),
|
||||||
|
// .net 8 has an issue that causes simultaneous tool restores during build to fail
|
||||||
|
MSBuildSettings = new DotNetMSBuildSettings { MaxCpuCount = 1 }
|
||||||
};
|
};
|
||||||
DotNetBuild("MLEM.sln", settings);
|
DotNetBuild("MLEM.sln", settings);
|
||||||
DotNetBuild("MLEM.FNA.sln", settings);
|
DotNetBuild("MLEM.FNA.sln", settings);
|
||||||
|
@ -34,7 +36,8 @@ Task("Build").IsDependentOn("Prepare").Does(() =>{
|
||||||
Task("Test").IsDependentOn("Build").Does(() => {
|
Task("Test").IsDependentOn("Build").Does(() => {
|
||||||
var settings = new DotNetTestSettings {
|
var settings = new DotNetTestSettings {
|
||||||
Configuration = config,
|
Configuration = config,
|
||||||
Collectors = {"XPlat Code Coverage"}
|
Collectors = {"XPlat Code Coverage"},
|
||||||
|
Loggers = {"console;verbosity=normal"}
|
||||||
};
|
};
|
||||||
DotNetTest("MLEM.sln", settings);
|
DotNetTest("MLEM.sln", settings);
|
||||||
DotNetTest("MLEM.FNA.sln", settings);
|
DotNetTest("MLEM.FNA.sln", settings);
|
||||||
|
@ -49,7 +52,7 @@ Task("Pack").IsDependentOn("Test").Does(() => {
|
||||||
DotNetPack("MLEM.FNA.sln", settings);
|
DotNetPack("MLEM.FNA.sln", settings);
|
||||||
});
|
});
|
||||||
|
|
||||||
Task("Push").WithCriteria(branch == "main" || branch == "release").IsDependentOn("Pack").Does(() => {
|
Task("Push").WithCriteria(branch == "main" || branch == "release", "Not on main or release branch").IsDependentOn("Pack").Does(() => {
|
||||||
DotNetNuGetPushSettings settings;
|
DotNetNuGetPushSettings settings;
|
||||||
if (branch == "release") {
|
if (branch == "release") {
|
||||||
settings = new DotNetNuGetPushSettings {
|
settings = new DotNetNuGetPushSettings {
|
||||||
|
|
Loading…
Reference in a new issue