├── .github
└── workflows
│ ├── ci.yml
│ ├── develop.yml
│ └── release.yml
├── .gitignore
├── Download-References-Staging.ps1
├── Download-References.ps1
├── LICENSE
├── README.md
└── src
├── Rust.UIFramework.sln
├── Rust.UIFramework
├── Benchmarks
│ └── BenchmarkNetWrite.cs
├── Builder
│ ├── BaseBuilder.cs
│ ├── BaseUiBuilder.Components.cs
│ ├── BaseUiBuilder.Controls.cs
│ ├── BaseUiBuilder.cs
│ ├── Cached
│ │ └── CachedUiBuilder.cs
│ ├── UI
│ │ ├── UiBuilder.CreateBuilders.cs
│ │ └── UiBuilder.cs
│ └── Update
│ │ └── UpdateBuilder.cs
├── Builders
│ └── SendInfoBuilder.cs
├── Cache
│ ├── EnumCache{T}.cs
│ ├── StringCache.cs
│ ├── UiColorCache.cs
│ ├── UiFontCache.cs
│ ├── UiLayerCache.cs
│ ├── UiNameCache.cs
│ └── VectorCache.cs
├── Colors
│ ├── UiColor.cs
│ ├── UiColorConverter.cs
│ └── UiColors.cs
├── Commands
│ └── UiCommand.cs
├── Components
│ ├── BaseComponent.cs
│ ├── BaseImageComponent.cs
│ ├── BasePoolableComponent.cs
│ ├── BaseTextComponent.cs
│ ├── ButtonComponent.cs
│ ├── CountdownComponent.cs
│ ├── IComponent.cs
│ ├── ImageComponent.cs
│ ├── InputComponent.cs
│ ├── ItemIconComponent.cs
│ ├── OutlineComponent.cs
│ ├── PlayerAvatarComponent.cs
│ ├── RawImageComponent.cs
│ ├── RectTransformComponent.cs
│ ├── ScrollViewComponent.cs
│ ├── ScrollViewContentTransformComponent.cs
│ ├── ScrollbarComponent.cs
│ └── TextComponent.cs
├── Controls
│ ├── BaseUiControl.cs
│ ├── Data
│ │ ├── ButtonGroupData.cs
│ │ ├── DropdownMenuData.cs
│ │ ├── TimePickerData.cs
│ │ └── UiBorderWidth.cs
│ ├── NumberPicker
│ │ ├── BaseNumberPicker.cs
│ │ ├── UiIncrementalNumberPicker.cs
│ │ └── UiNumberPicker.cs
│ ├── Popover
│ │ ├── BasePopoverControl.cs
│ │ ├── UiCalenderPicker.cs
│ │ ├── UiColorPickerMenu.cs
│ │ ├── UiDatePickerMenu.cs
│ │ ├── UiDropdownMenu.cs
│ │ ├── UiDropdownMenuItem.cs
│ │ ├── UiPopover.cs
│ │ └── UiTimePickerMenu.cs
│ ├── UiBorder.cs
│ ├── UiButtonGroup.cs
│ ├── UiCheckbox.cs
│ ├── UiColorPicker.cs
│ ├── UiDatePicker.cs
│ ├── UiDropdown.cs
│ ├── UiInputBackground.cs
│ ├── UiLabelBackground.cs
│ ├── UiPaginator.cs
│ ├── UiPicker.cs
│ ├── UiProgressBar.cs
│ ├── UiScrollBar.cs
│ └── UiTimePicker.cs
├── Enums
│ ├── BorderMode.cs
│ ├── ClockMode.cs
│ ├── ColorPickerMode.cs
│ ├── DatePickerDisplayMode.cs
│ ├── DatePickerDisplayOrder.cs
│ ├── InputMode.cs
│ ├── NumberPickerMode.cs
│ ├── PopoverPosition.cs
│ ├── ScrollbarDirection.cs
│ ├── TimePickerDisplayMode.cs
│ ├── TimerFormat.cs
│ ├── UiFont.cs
│ └── UiLayer.cs
├── Exceptions
│ ├── UiFrameworkException.cs
│ └── UiReferenceException.cs
├── Extension
│ ├── Carbon
│ │ └── CarbonExtension.cs
│ └── Oxide
│ │ └── UiFrameworkExtension.cs
├── Extensions
│ ├── ArgExt.cs
│ ├── OxideCuiExt.cs
│ ├── StringBuilderExt.cs
│ ├── TypeExt.cs
│ ├── UiColorExt.cs
│ ├── UiOffsetExt.cs
│ ├── UiPositionExt.cs
│ └── UiReferenceExt.cs
├── Helpers
│ └── GenericMath.cs
├── Json
│ ├── JsonBinaryWriter.cs
│ ├── JsonDefaults.cs
│ ├── JsonFrameworkWriter.cs
│ └── SizedArray.cs
├── Offsets
│ ├── BaseOffset.cs
│ ├── GridOffset.cs
│ ├── GridOffsetBuilder.cs
│ └── UiOffset.cs
├── Pooling
│ ├── BasePool.cs
│ ├── BasePoolable.cs
│ ├── HashPool.cs
│ ├── IPool.cs
│ ├── IPool{T}.cs
│ ├── ListPool.cs
│ ├── ObjectPool.cs
│ ├── StringBuilderPool.cs
│ └── UiFrameworkPool.cs
├── Positions
│ ├── BasePosition.cs
│ ├── GridPosition.cs
│ ├── GridPositionBuilder.cs
│ └── UiPosition.cs
├── Rust.UIFramework.csproj
├── Threading
│ ├── BaseUiRequest.cs
│ ├── IUiRequest.cs
│ ├── OxideCuiRequest.cs
│ ├── SendHandler.cs
│ └── UiSendRequest.cs
├── UiConstants.cs
├── UiElements
│ ├── BaseUiComponent.cs
│ ├── BaseUiImage.cs
│ ├── BaseUiOutline.cs
│ ├── UiButton.cs
│ ├── UiImage.cs
│ ├── UiInput.cs
│ ├── UiItemIcon.cs
│ ├── UiLabel.cs
│ ├── UiPanel.cs
│ ├── UiPlayerAvatar.cs
│ ├── UiRawImage.cs
│ ├── UiReference.cs
│ ├── UiScrollView.cs
│ └── UiSection.cs
└── UiHelpers.cs
└── Rust.UiFramework.Benchmarks
├── Benchmarks.cs
├── Program.cs
└── Rust.UiFramework.Benchmarks.csproj
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches: [ "main" ]
6 | pull_request:
7 | branches: [ "main" ]
8 |
9 | jobs:
10 | build:
11 |
12 | runs-on: windows-latest
13 |
14 | steps:
15 | - name: Checkout
16 | uses: actions/checkout@v4
17 |
18 | - name: Setup .NET
19 | uses: actions/setup-dotnet@v4
20 |
21 | - name: Display .NET version
22 | run: dotnet --version
23 |
24 | - name: Set VERSION variable from tag
25 | run: echo "VERSION=0.0.0" | Out-File -FilePath $env:GITHUB_ENV
26 |
27 | - name: Download References
28 | shell: pwsh
29 | run: |
30 | .\Download-References.ps1
31 |
32 | - name: Build DLLs - Oxide
33 | run: dotnet build Rust.UIFramework.csproj -c Release /p:Platform=Oxide /p:Version=${{ env.VERSION }} -f net48
34 | working-directory: src/Rust.UIFramework
35 |
36 | - name: Build DLLs - Carbon
37 | run: dotnet build Rust.UIFramework.csproj -c Release /p:Platform=Carbon /p:Version=${{ env.VERSION }} -f net48
38 | working-directory: src/Rust.UIFramework
39 |
--------------------------------------------------------------------------------
/.github/workflows/develop.yml:
--------------------------------------------------------------------------------
1 | name: Create Pre Release Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - "v[0-9]+.[0-9]+.[0-9]+-preview.[0-9]+.[0-9]+.[0-9]"
7 |
8 | jobs:
9 | build:
10 |
11 | runs-on: windows-latest
12 |
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v4
16 |
17 | - name: Setup .NET
18 | uses: actions/setup-dotnet@v4
19 |
20 | - name: Set VERSION variable from tag
21 | run: echo "VERSION=${GITHUB_REF/refs\/tags\/v/}" | Out-File -FilePath $env:GITHUB_ENV
22 |
23 | - name: Download References
24 | shell: pwsh
25 | run: |
26 | .\Download-References.ps1
27 |
28 | - name: Build DLLs - Oxide
29 | run: dotnet build Rust.UIFramework.csproj -c Release /p:Platform=Oxide /p:Version=${{ env.VERSION }} -f net48
30 | working-directory: src/Rust.UIFramework
31 |
32 | - name: Build DLLs - Carbon
33 | run: dotnet build Rust.UIFramework.csproj -c Release /p:Platform=Carbon /p:Version=${{ env.VERSION }} -f net48
34 | working-directory: src/Rust.UIFramework
35 |
36 | - name: Move DLLs
37 | run: |
38 | mkdir -p bin
39 | mv Rust.UIFramework/bin/Oxide/Release/net48/Oxide.Ext.UiFramework.dll bin/
40 | mv Rust.UIFramework/bin/Carbon/Release/net48/Carbon.Ext.UiFramework.dll bin/
41 | working-directory: src
42 |
43 | - name: Upload Release Assets
44 | run: |
45 | $TAG=($env:GITHUB_REF -replace 'refs/tags/', '')
46 | $dllPath = Get-ChildItem -Path src/bin -Filter *.dll -File | Select-Object -ExpandProperty FullName
47 | gh release upload $TAG $dllPath
48 | env:
49 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
50 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Create Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - "[0-9]+.[0-9]+.[0-9]+"
7 |
8 | jobs:
9 | build:
10 |
11 | runs-on: windows-latest
12 |
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v4
16 |
17 | - name: Setup .NET
18 | uses: actions/setup-dotnet@v4
19 |
20 | - name: Display .NET version
21 | run: dotnet --version
22 |
23 | - name: Set VERSION variable from tag
24 | run: echo "VERSION=${{github.ref_name}}" | Out-File -FilePath $env:GITHUB_ENV
25 |
26 | - name: Download References
27 | shell: pwsh
28 | run: |
29 | .\Download-References.ps1
30 |
31 | - name: Build DLLs - Oxide
32 | run: dotnet build Rust.UIFramework.csproj -c Release /p:Platform=Oxide /p:Version=${{ env.VERSION }} -f net48
33 | working-directory: src/Rust.UIFramework
34 |
35 | - name: Build DLLs - Carbon
36 | run: dotnet build Rust.UIFramework.csproj -c Release /p:Platform=Carbon /p:Version=${{ env.VERSION }} -f net48
37 | working-directory: src/Rust.UIFramework
38 |
39 | - name: Move DLLs
40 | run: |
41 | mkdir -p bin
42 | mv Rust.UIFramework/bin/Oxide/Release/net48/Oxide.Ext.UiFramework.dll bin/
43 | mv Rust.UIFramework/bin/Carbon/Release/net48/Carbon.Ext.UiFramework.dll bin/
44 | working-directory: src
45 |
46 | - name: Upload Release Assets
47 | run: |
48 | $TAG=($env:GITHUB_REF -replace 'refs/tags/', '')
49 | $dllPath = Get-ChildItem -Path src/bin -Filter *.dll -File | Select-Object -ExpandProperty FullName
50 | gh release upload $TAG $dllPath
51 | env:
52 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
53 |
--------------------------------------------------------------------------------
/Download-References-Staging.ps1:
--------------------------------------------------------------------------------
1 | # Clear the current directory (except the script itself)
2 |
3 | $resourcesDir = Join-Path -Path $PSScriptRoot -ChildPath "src/references"
4 |
5 | New-Item -ItemType Directory -Force -Path $resourcesDir
6 |
7 | Get-ChildItem -Path $resourcesDir | Remove-Item -Force -Recurse
8 |
9 | # Create a temporary folder
10 | $tmpDir = New-Item -ItemType Directory -Force -Path "$env:TEMP\Download-References"
11 |
12 | # Temporary folders for DepotDownloader and Rust DLLs
13 | $depotDir = Join-Path -Path $tmpDir -ChildPath "DepotDownloader"
14 | $rustDir = Join-Path -Path $depotDir -ChildPath "RustDLLs"
15 |
16 | # Create a temporary folder for DepotDownloader and Rust DLLs
17 | New-Item -ItemType Directory -Force -Path $depotDir
18 | New-Item -ItemType Directory -Force -Path $rustDir
19 |
20 | # Download and extract DepotDownloader
21 | Invoke-WebRequest -Uri "https://github.com/SteamRE/DepotDownloader/releases/latest/download/DepotDownloader-windows-x64.zip" -OutFile "$depotDir\DepotDownloader.zip"
22 | Expand-Archive -Path "$depotDir\DepotDownloader.zip" -DestinationPath $depotDir -Force
23 | Remove-Item -Path "$depotDir\DepotDownloader.zip"
24 |
25 | # Create a file named filelist.txt for downloading .dll files
26 | $fileListPath = Join-Path -Path $rustDir -ChildPath "filelist.txt"
27 | @("regex:RustDedicated_Data/Managed/.*\.dll") | Set-Content -Path $fileListPath
28 |
29 | # Download .dll files using DepotDownloader
30 | $depotArgs = "-app 258550 -beta staging -depot 258551 -filelist $fileListPath -dir $rustDir"
31 | Start-Process -FilePath "$depotDir\DepotDownloader.exe" -ArgumentList $depotArgs -NoNewWindow -Wait
32 |
33 | # Move .dll files to the current directory
34 | Move-Item -Path "$rustDir\RustDedicated_Data\Managed\*.dll" -Destination $resourcesDir -Force
35 |
36 | # Download and extract Carbon (presumably for Windows)
37 | $carbonDir = Join-Path -Path $tmpDir -ChildPath "Carbon"
38 | New-Item -ItemType Directory -Force -Path $carbonDir
39 | Invoke-WebRequest -Uri "https://github.com/CarbonCommunity/Carbon/releases/download/production_build/Carbon.Windows.Release.zip" -OutFile "$carbonDir\Carbon.zip"
40 | Expand-Archive -Path "$carbonDir\Carbon.zip" -DestinationPath $carbonDir -Force
41 | Remove-Item -Path "$carbonDir\Carbon.zip"
42 |
43 | # Move .dll files from Carbon to the current directory
44 | Move-Item -Path "$carbonDir\carbon\managed\*.dll" -Destination $resourcesDir -Force
45 |
46 | # Download and extract Oxide (presumably for Windows)
47 | $oxideDir = Join-Path -Path $tmpDir -ChildPath "Oxide"
48 | New-Item -ItemType Directory -Force -Path $oxideDir
49 | Invoke-WebRequest -Uri "https://downloads.oxidemod.com/artifacts/Oxide.Rust/staging/Oxide.Rust.zip" -OutFile "$oxideDir\Oxide.Rust.zip"
50 | Expand-Archive -Path "$oxideDir\Oxide.Rust.zip" -DestinationPath $oxideDir -Force
51 | Remove-Item -Path "$oxideDir\Oxide.Rust.zip"
52 |
53 | # Move .dll files from Oxide to the current directory
54 | Move-Item -Path "$oxideDir\RustDedicated_Data\Managed\*.dll" -Destination $resourcesDir -Force
55 |
56 | # Delete the temporary folder
57 | Remove-Item -Path $tmpDir -Force -Recurse
58 |
59 | # Display a completion message
60 | Write-Host "References downloaded and copied to $PSScriptRoot."
61 |
--------------------------------------------------------------------------------
/Download-References.ps1:
--------------------------------------------------------------------------------
1 | # Clear the current directory (except the script itself)
2 |
3 | $resourcesDir = Join-Path -Path $PSScriptRoot -ChildPath "src/references"
4 |
5 | New-Item -ItemType Directory -Force -Path $resourcesDir
6 |
7 | Get-ChildItem -Path $resourcesDir | Remove-Item -Force -Recurse
8 |
9 | # Create a temporary folder
10 | $tmpDir = New-Item -ItemType Directory -Force -Path "$env:TEMP\Download-References"
11 |
12 | # Temporary folders for DepotDownloader and Rust DLLs
13 | $depotDir = Join-Path -Path $tmpDir -ChildPath "DepotDownloader"
14 | $rustDir = Join-Path -Path $depotDir -ChildPath "RustDLLs"
15 |
16 | # Create a temporary folder for DepotDownloader and Rust DLLs
17 | New-Item -ItemType Directory -Force -Path $depotDir
18 | New-Item -ItemType Directory -Force -Path $rustDir
19 |
20 | # Download and extract DepotDownloader
21 | Invoke-WebRequest -Uri "https://github.com/SteamRE/DepotDownloader/releases/latest/download/DepotDownloader-windows-x64.zip" -OutFile "$depotDir\DepotDownloader.zip"
22 | Expand-Archive -Path "$depotDir\DepotDownloader.zip" -DestinationPath $depotDir -Force
23 | Remove-Item -Path "$depotDir\DepotDownloader.zip"
24 |
25 | # Create a file named filelist.txt for downloading .dll files
26 | $fileListPath = Join-Path -Path $rustDir -ChildPath "filelist.txt"
27 | @("regex:RustDedicated_Data/Managed/.*\.dll") | Set-Content -Path $fileListPath
28 |
29 | # Download .dll files using DepotDownloader
30 | $depotArgs = "-app 258550 -depot 258551 -filelist $fileListPath -dir $rustDir"
31 | Start-Process -FilePath "$depotDir\DepotDownloader.exe" -ArgumentList $depotArgs -NoNewWindow -Wait
32 |
33 | # Move .dll files to the current directory
34 | Move-Item -Path "$rustDir\RustDedicated_Data\Managed\*.dll" -Destination $resourcesDir -Force
35 |
36 | # Download and extract Carbon (presumably for Windows)
37 | $carbonDir = Join-Path -Path $tmpDir -ChildPath "Carbon"
38 | New-Item -ItemType Directory -Force -Path $carbonDir
39 | Invoke-WebRequest -Uri "https://github.com/CarbonCommunity/Carbon/releases/download/production_build/Carbon.Windows.Release.zip" -OutFile "$carbonDir\Carbon.zip"
40 | Expand-Archive -Path "$carbonDir\Carbon.zip" -DestinationPath $carbonDir -Force
41 | Remove-Item -Path "$carbonDir\Carbon.zip"
42 |
43 | # Move .dll files from Carbon to the current directory
44 | Move-Item -Path "$carbonDir\carbon\managed\*.dll" -Destination $resourcesDir -Force
45 |
46 | # Download and extract Oxide (presumably for Windows)
47 | $oxideDir = Join-Path -Path $tmpDir -ChildPath "Oxide"
48 | New-Item -ItemType Directory -Force -Path $oxideDir
49 | Invoke-WebRequest -Uri "https://github.com/OxideMod/Oxide.Rust/releases/latest/download/Oxide.Rust.zip" -OutFile "$oxideDir\Oxide.Rust.zip"
50 | Expand-Archive -Path "$oxideDir\Oxide.Rust.zip" -DestinationPath $oxideDir -Force
51 | Remove-Item -Path "$oxideDir\Oxide.Rust.zip"
52 |
53 | # Move .dll files from Oxide to the current directory
54 | Move-Item -Path "$oxideDir\RustDedicated_Data\Managed\*.dll" -Destination $resourcesDir -Force
55 |
56 | # Delete the temporary folder
57 | Remove-Item -Path $tmpDir -Force -Recurse
58 |
59 | # Display a completion message
60 | Write-Host "References downloaded and copied to $PSScriptRoot."
61 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Josh Dassinger
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Rust UI Framework
2 | UI Framework for Rust (The Game) using the [Oxide/uMod](https://umod.org) plugin platform
3 |
4 | ## Performance Comparison vs Oxide
5 |
6 | This benchmark shows the performance comparison when creating 100 UI Elements and then serializing them to JSON.
7 | UiFramework_Async is 51.31x faster than CUI provided by oxide and 5.66x faster than Oxide AddUiAsync extension method UI Framework provides.
8 | The async option in the framework queues the UI to be serialized and sent on a separate thread while CUI from oxide is all ran on the main thread.
9 | UI Framework also doesn't have any memory allocations from the framework and pooling is used heavily for performance.
10 |
11 | | Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated |
12 | |------------------ |-----------:|----------:|----------:|------:|--------:|--------:|-------:|----------:|
13 | | UiFramework_Async | 6.329 us | 0.0143 us | 0.0214 us | 1.00 | 0.00 | - | - | - |
14 | | Oxide_Async | 35.812 us | 0.2101 us | 0.3145 us | 5.66 | 0.05 | 2.9907 | 0.3052 | 51792 B |
15 | | Oxide_Full | 324.565 us | 1.8106 us | 2.4783 us | 51.31 | 0.33 | 11.7188 | 1.9531 | 204088 B |
16 |
17 |
18 | ## Getting Started
19 |
20 | ### Server Installation
21 | 1. Grab the Oxide.Ext.UiFramework.dll from the latest release
22 | 2. Put the DLL into `RustDedicated_Data\Managed` folder
23 | 3. Restart the server
24 |
25 | ### Developer Install
26 | 1. Grab the Oxide.Ext.UiFramework.dll from the latest release
27 | 2. Add the DLL to your project repo
28 |
29 |
30 | ## Plugin Examples
31 |
32 | ### Generic Example
33 | ```csharp
34 | private const string MainUi = "UI_Name";
35 | private const int TitleFontSize = 20;
36 |
37 | private readonly UiPosition _titleBarPos = new(0, .95f, 1f, 1f);
38 | private readonly UiPosition _closeButtonPos = new(0.95f, 0f, 1f, 1f);
39 |
40 | private void CreateUi(BasePlayer player
41 | {
42 | UiBuilder builder = UiBuilder.Create(UiPosition.MiddleMiddle, new UiOffset(-420, -270, 420, 330), UiColors.Body, MainUi, UiLayer.Hud);
43 |
44 | builder.NeedsMouse();
45 | builder.NeedsKeyboard();
46 |
47 | UiLabelBackground title = builder.LabelBackground(builder.Root, _titleBarPos, Title, TitleFontSize, UiColors.Text, UiColors.BodyHeader);
48 | builder.TextButton(title.Background, _closeButtonPos, "X", TitleFontSize, UiColors.Text, UiColors.CloseButton, nameof(CloseCommand));
49 |
50 | builder.AddUi(player); //By default the builder will auto destroy the previous UI if it exists on the client
51 | }
52 |
53 |
54 | [ConsoleCommand(nameof(CloseCommand))]
55 | private void CloseCommand(ConsoleSystem.Arg arg)
56 | {
57 | BasePlayer player = arg.Player();
58 | if (player)
59 | {
60 | UiBuilder.DestroyUi(player, MainUi);
61 | }
62 | }
63 | ```
--------------------------------------------------------------------------------
/src/Rust.UIFramework.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rust.UIFramework", "Rust.UIFramework\Rust.UIFramework.csproj", "{2CEE08B1-A5BD-4F64-A1A9-5242440758D0}"
4 | EndProject
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rust.UiFramework.Benchmarks", "Rust.UiFramework.Benchmarks\Rust.UiFramework.Benchmarks.csproj", "{6C18B22C-7319-4C3F-B7F9-F9B87B6B244C}"
6 | EndProject
7 | Global
8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 | Release|Oxide = Release|Oxide
10 | Release|Carbon = Release|Carbon
11 | Debug|Carbon = Debug|Carbon
12 | Debug|Oxide = Debug|Oxide
13 | Benchmarks|Oxide = Benchmarks|Oxide
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {2CEE08B1-A5BD-4F64-A1A9-5242440758D0}.Debug|Carbon.ActiveCfg = Debug|Carbon
17 | {2CEE08B1-A5BD-4F64-A1A9-5242440758D0}.Debug|Carbon.Build.0 = Debug|Carbon
18 | {2CEE08B1-A5BD-4F64-A1A9-5242440758D0}.Debug|Oxide.ActiveCfg = Debug|Oxide
19 | {2CEE08B1-A5BD-4F64-A1A9-5242440758D0}.Debug|Oxide.Build.0 = Debug|Oxide
20 | {2CEE08B1-A5BD-4F64-A1A9-5242440758D0}.Release|Carbon.ActiveCfg = Release|Carbon
21 | {2CEE08B1-A5BD-4F64-A1A9-5242440758D0}.Release|Carbon.Build.0 = Release|Carbon
22 | {2CEE08B1-A5BD-4F64-A1A9-5242440758D0}.Release|Oxide.ActiveCfg = Release|Oxide
23 | {2CEE08B1-A5BD-4F64-A1A9-5242440758D0}.Release|Oxide.Build.0 = Release|Oxide
24 | {2CEE08B1-A5BD-4F64-A1A9-5242440758D0}.Benchmarks|Oxide.ActiveCfg = Benchmarks|Oxide
25 | {2CEE08B1-A5BD-4F64-A1A9-5242440758D0}.Benchmarks|Oxide.Build.0 = Benchmarks|Oxide
26 | {6C18B22C-7319-4C3F-B7F9-F9B87B6B244C}.Release|Oxide.ActiveCfg = Release|Oxide
27 | {6C18B22C-7319-4C3F-B7F9-F9B87B6B244C}.Release|Oxide.Build.0 = Release|Oxide
28 | {6C18B22C-7319-4C3F-B7F9-F9B87B6B244C}.Benchmarks|Oxide.ActiveCfg = Benchmarks|Oxide
29 | {6C18B22C-7319-4C3F-B7F9-F9B87B6B244C}.Benchmarks|Oxide.Build.0 = Benchmarks|Oxide
30 | {6C18B22C-7319-4C3F-B7F9-F9B87B6B244C}.Debug|Oxide.ActiveCfg = Debug|Oxide
31 | {6C18B22C-7319-4C3F-B7F9-F9B87B6B244C}.Debug|Oxide.Build.0 = Debug|Oxide
32 | EndGlobalSection
33 | EndGlobal
34 |
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Benchmarks/BenchmarkNetWrite.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using Facepunch;
4 | using Network;
5 | using UnityEngine;
6 |
7 |
8 | namespace Oxide.Ext.UiFramework.Benchmarks;
9 | #if BENCHMARKS
10 | internal class BenchmarkNetWrite : Stream, Pool.IPooled
11 | {
12 | public byte[] Data;
13 | private int _position;
14 | private int _length;
15 |
16 | public override void Flush()
17 | {
18 |
19 | }
20 |
21 | public override long Seek(long offset, SeekOrigin origin)
22 | {
23 | int num;
24 | switch (origin)
25 | {
26 | case SeekOrigin.Current:
27 | num = _position + (int) offset;
28 | break;
29 | case SeekOrigin.End:
30 | num = _length + (int) offset;
31 | break;
32 | default:
33 | num = (int) offset;
34 | break;
35 | }
36 | _position = num >= 0 && num <= _length ? num : throw new ArgumentOutOfRangeException(nameof (offset));
37 | return _position;
38 | }
39 |
40 | public override void SetLength(long value)
41 | {
42 | throw new NotImplementedException();
43 | }
44 |
45 | public override int Read(byte[] buffer, int offset, int count)
46 | {
47 | int max = _length - _position;
48 | int num = Mathf.Clamp(count, 0, max);
49 | Buffer.BlockCopy(Data, _position, buffer, offset, count);
50 | _position += num;
51 | return num;
52 | }
53 |
54 | public override void Write(byte[] buffer, int offset, int count)
55 | {
56 | EnsureCapacity(count);
57 | Buffer.BlockCopy(buffer, offset, Data, _position, count);
58 | _position += count;
59 | if (_position <= _length)
60 | return;
61 | _length = _position;
62 | }
63 |
64 | public override bool CanRead => true;
65 | public override bool CanSeek => true;
66 | public override bool CanWrite => true;
67 | public override long Length => _length;
68 | public override long Position
69 | {
70 | get => _position;
71 | set => Seek(value, SeekOrigin.Begin);
72 | }
73 |
74 | public void EnterPool()
75 | {
76 | if (Data == null)
77 | return;
78 | BaseNetwork.ArrayPool.Return(Data);
79 | Data = null;
80 | }
81 |
82 | public void LeavePool()
83 | {
84 | _position = 0;
85 | _length = 0;
86 | }
87 |
88 | private void EnsureCapacity(int spaceRequired)
89 | {
90 | if (Data == null)
91 | {
92 | int num = spaceRequired <= 2048 ? 2048 : spaceRequired;
93 | int minSize = NextPowerOfTwo(num);
94 | Data = minSize <= 4194304 ? BaseNetwork.ArrayPool.Rent(minSize) : throw new Exception(string.Format("Preventing NetWrite buffer from growing too large (requiredLength={0})", num));
95 | }
96 | else
97 | {
98 | if (Data.Length - _position >= spaceRequired)
99 | return;
100 | int val1 = _position + spaceRequired;
101 | int minSize = NextPowerOfTwo(Math.Max(val1, Data.Length));
102 | byte[] dst = minSize <= 4194304 ? BaseNetwork.ArrayPool.Rent(minSize) : throw new Exception(string.Format("Preventing NetWrite buffer from growing too large (requiredLength={0})", val1));
103 | Buffer.BlockCopy(Data, 0, dst, 0, _length);
104 | BaseNetwork.ArrayPool.Return(Data);
105 | Data = dst;
106 | }
107 | }
108 |
109 | private int NextPowerOfTwo(int value)
110 | {
111 | value -= 1;
112 | value |= value >> 16;
113 | value |= value >> 16;
114 | value |= value >> 8;
115 | value |= value >> 4;
116 | value |= value >> 2;
117 | value |= value >> 1;
118 | return value + 1;
119 | }
120 | }
121 | #endif
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Builder/BaseUiBuilder.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Network;
3 | using Oxide.Ext.UiFramework.Cache;
4 | using Oxide.Ext.UiFramework.Controls;
5 | using Oxide.Ext.UiFramework.Enums;
6 | using Oxide.Ext.UiFramework.Json;
7 | using Oxide.Ext.UiFramework.UiElements;
8 |
9 | namespace Oxide.Ext.UiFramework.Builder;
10 |
11 | public abstract partial class BaseUiBuilder : BaseBuilder
12 | {
13 | protected readonly List Components = new();
14 | protected readonly List Controls = new();
15 | protected readonly List Anchors = new();
16 |
17 | protected string Font;
18 | protected static string GlobalFont;
19 |
20 | static BaseUiBuilder()
21 | {
22 | SetGlobalFont(UiFont.RobotoCondensedRegular);
23 | }
24 |
25 | public void EnsureCapacity(int capacity)
26 | {
27 | if (Components.Capacity < capacity)
28 | {
29 | Components.Capacity = capacity;
30 | }
31 | }
32 |
33 | public void SetCurrentFont(UiFont font)
34 | {
35 | Font = UiFontCache.GetUiFont(font);
36 | }
37 |
38 | public static void SetGlobalFont(UiFont font)
39 | {
40 | GlobalFont = UiFontCache.GetUiFont(font);
41 | }
42 |
43 | public override byte[] GetBytes()
44 | {
45 | JsonFrameworkWriter writer = CreateWriter();
46 | byte[] bytes = writer.ToArray();
47 | writer.Dispose();
48 | return bytes;
49 | }
50 |
51 | internal override void SendUi(SendInfo send)
52 | {
53 | JsonFrameworkWriter writer = CreateWriter();
54 | AddUi(send, writer);
55 | writer.Dispose();
56 | }
57 |
58 | public JsonFrameworkWriter CreateWriter()
59 | {
60 | int count = Controls.Count;
61 | if (count != 0)
62 | {
63 | for (int index = 0; index < count; index++)
64 | {
65 | BaseUiControl control = Controls[index];
66 | control.RenderControl(this);
67 | }
68 | }
69 |
70 | JsonFrameworkWriter writer = JsonFrameworkWriter.Create();
71 | writer.WriteStartArray();
72 | WriteComponentsInternal(writer);
73 | writer.WriteEndArray();
74 | return writer;
75 | }
76 |
77 | protected abstract void WriteComponentsInternal(JsonFrameworkWriter writer);
78 |
79 | protected override void EnterPool()
80 | {
81 | base.EnterPool();
82 | FreeComponents();
83 | Font = null;
84 | }
85 |
86 | private void FreeComponents()
87 | {
88 | int count = Components.Count;
89 | for (int index = 0; index < count; index++)
90 | {
91 | Components[index].Dispose();
92 | }
93 |
94 | Components.Clear();
95 |
96 | count = Controls.Count;
97 | for (int index = 0; index < count; index++)
98 | {
99 | Controls[index].Dispose();
100 | }
101 |
102 | Controls.Clear();
103 |
104 | count = Anchors.Count;
105 | for (int index = 0; index < count; index++)
106 | {
107 | Anchors[index].Dispose();
108 | }
109 |
110 | Anchors.Clear();
111 | }
112 |
113 | protected override void LeavePool()
114 | {
115 | base.LeavePool();
116 | Font = GlobalFont;
117 | }
118 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Builder/Cached/CachedUiBuilder.cs:
--------------------------------------------------------------------------------
1 | using Network;
2 | using Oxide.Ext.UiFramework.Builder.UI;
3 |
4 | namespace Oxide.Ext.UiFramework.Builder.Cached;
5 |
6 | public class CachedUiBuilder : BaseBuilder
7 | {
8 | private readonly byte[] _cachedJson;
9 |
10 | private CachedUiBuilder(UiBuilder builder)
11 | {
12 | _cachedJson = builder.GetBytes();
13 | RootName = builder.GetRootName();
14 | }
15 |
16 | internal static CachedUiBuilder CreateCachedBuilder(UiBuilder builder) => new(builder);
17 |
18 | public override byte[] GetBytes() => _cachedJson;
19 |
20 | internal override void SendUi(SendInfo send)
21 | {
22 | AddUi(send, GetBytes());
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Builder/UI/UiBuilder.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Builder.Cached;
2 | using Oxide.Ext.UiFramework.Cache;
3 | using Oxide.Ext.UiFramework.Exceptions;
4 | using Oxide.Ext.UiFramework.Json;
5 | using Oxide.Ext.UiFramework.UiElements;
6 |
7 | namespace Oxide.Ext.UiFramework.Builder.UI;
8 |
9 | public partial class UiBuilder : BaseUiBuilder
10 | {
11 | public BaseUiComponent Root;
12 |
13 | private bool _needsMouse;
14 | private bool _needsKeyboard;
15 | private bool _autoDestroy = true;
16 |
17 | #region Decontructor
18 | ~UiBuilder()
19 | {
20 | Dispose();
21 | //Need this because there is a global GC class that causes issues
22 | //ReSharper disable once RedundantNameQualifier
23 | System.GC.SuppressFinalize(this);
24 | }
25 | #endregion
26 |
27 | #region Setup
28 | public void SetRoot(BaseUiComponent component, string name, string parent)
29 | {
30 | Root = component;
31 | component.Reference = new UiReference(parent, name);
32 | Components.Add(component);
33 | RootName = name;
34 | }
35 |
36 | public void OverrideRoot(BaseUiComponent component)
37 | {
38 | Root = component;
39 | }
40 |
41 | public void NeedsMouse(bool enabled = true)
42 | {
43 | _needsMouse = enabled;
44 | }
45 |
46 | public void NeedsKeyboard(bool enabled = true)
47 | {
48 | _needsKeyboard = enabled;
49 | }
50 |
51 | public void EnableAutoDestroy(bool enabled = true)
52 | {
53 | _autoDestroy = enabled;
54 | }
55 | #endregion
56 |
57 | #region JSON
58 | public int WriteBuffer(byte[] buffer)
59 | {
60 | JsonFrameworkWriter writer = CreateWriter();
61 | int bytes = writer.WriteTo(buffer);
62 | writer.Dispose();
63 | return bytes;
64 | }
65 |
66 | public CachedUiBuilder ToCachedBuilder(bool dispose = true)
67 | {
68 | CachedUiBuilder cached = CachedUiBuilder.CreateCachedBuilder(this);
69 | if (dispose && !Disposed)
70 | {
71 | Dispose();
72 | }
73 | return cached;
74 | }
75 | #endregion
76 |
77 | #region Add Components
78 | public override void AddComponent(BaseUiComponent component, in UiReference parent)
79 | {
80 | UiReferenceException.ThrowIfInvalidParent(parent);
81 | component.Reference = parent.WithChild(UiNameCache.GetComponentName(RootName, Components.Count));
82 | Components.Add(component);
83 | }
84 |
85 | protected override void AddAnchor(BaseUiComponent component, in UiReference parent)
86 | {
87 | UiReferenceException.ThrowIfInvalidParent(parent);
88 | component.Reference = parent.WithChild(UiNameCache.GetAnchorName(RootName, Anchors.Count));
89 | Anchors.Add(component);
90 | }
91 | #endregion
92 |
93 | protected override void WriteComponentsInternal(JsonFrameworkWriter writer)
94 | {
95 | Components[0].WriteRootComponent(writer, _needsMouse, _needsKeyboard, _autoDestroy);
96 |
97 | int count = Components.Count;
98 | for (int index = 1; index < count; index++)
99 | {
100 | Components[index].WriteComponent(writer);
101 | }
102 |
103 | count = Anchors.Count;
104 | for (int index = 0; index < count; index++)
105 | {
106 | Anchors[index].WriteComponent(writer);
107 | }
108 | }
109 |
110 | protected override void EnterPool()
111 | {
112 | base.EnterPool();
113 | Root = null;
114 | _needsKeyboard = false;
115 | _needsMouse = false;
116 | _autoDestroy = true;
117 | }
118 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Builder/Update/UpdateBuilder.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Exceptions;
2 | using Oxide.Ext.UiFramework.Json;
3 | using Oxide.Ext.UiFramework.Pooling;
4 | using Oxide.Ext.UiFramework.UiElements;
5 |
6 | namespace Oxide.Ext.UiFramework.Builder.Update;
7 |
8 | public class UpdateBuilder : BaseUiBuilder
9 | {
10 | public static UpdateBuilder Create() => UiFrameworkPool.Get();
11 |
12 | protected override void WriteComponentsInternal(JsonFrameworkWriter writer)
13 | {
14 | int count = Components.Count;
15 | for (int index = 0; index < count; index++)
16 | {
17 | Components[index].WriteUpdateComponent(writer);
18 | }
19 |
20 | count = Anchors.Count;
21 | if (count != 0)
22 | {
23 | for (int index = 0; index < count; index++)
24 | {
25 | Anchors[index].WriteUpdateComponent(writer);
26 | }
27 | }
28 | }
29 |
30 | #region Add Components
31 | public override void AddComponent(BaseUiComponent component, in UiReference parent)
32 | {
33 | UiReferenceException.ThrowIfInvalidReference(parent);
34 | component.Reference = parent;
35 | Components.Add(component);
36 | }
37 |
38 | protected override void AddAnchor(BaseUiComponent component, in UiReference parent)
39 | {
40 | UiReferenceException.ThrowIfInvalidReference(parent);
41 | component.Reference = parent;
42 | Anchors.Add(component);
43 | }
44 | #endregion
45 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Builders/SendInfoBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.CompilerServices;
4 | using Network;
5 | using Oxide.Ext.UiFramework.Pooling;
6 |
7 | namespace Oxide.Ext.UiFramework.Builders;
8 |
9 | internal static class SendInfoBuilder
10 | {
11 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
12 | internal static SendInfo Get(BasePlayer player)
13 | {
14 | if (!player) throw new ArgumentNullException(nameof(player));
15 | return Get(player.Connection);
16 | }
17 |
18 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
19 | internal static SendInfo Get(Connection connection)
20 | {
21 | if (connection == null) throw new ArgumentNullException(nameof(connection));
22 | return new SendInfo(connection);
23 | }
24 |
25 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
26 | internal static SendInfo Get(IEnumerable connections)
27 | {
28 | if (connections == null) throw new ArgumentNullException(nameof(connections));
29 | List pooledConnection = ListPool.Instance.Get();
30 | pooledConnection.AddRange(connections);
31 | return new SendInfo(pooledConnection);
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Cache/EnumCache{T}.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Linq;
4 |
5 | namespace Oxide.Ext.UiFramework.Cache;
6 |
7 | public static class EnumCache
8 | {
9 | private static readonly ConcurrentDictionary CachedStrings = new();
10 |
11 | static EnumCache()
12 | {
13 | foreach (T value in Enum.GetValues(typeof(T)).Cast())
14 | {
15 | CachedStrings[value] = value.ToString();
16 | }
17 | }
18 |
19 | public static string ToString(T value)
20 | {
21 | return CachedStrings[value];
22 | }
23 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Cache/StringCache.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Globalization;
4 |
5 | namespace Oxide.Ext.UiFramework.Cache;
6 |
7 | public static class StringCache where T : IFormattable
8 | {
9 | private static readonly ConcurrentDictionary Cache = new();
10 | private static readonly ConcurrentDictionary> FormatCache = new();
11 |
12 | public static string ToString(T value)
13 | {
14 | if (!Cache.TryGetValue(value, out string text))
15 | {
16 | text = value.ToString();
17 | Cache[value] = text;
18 | }
19 |
20 | return text;
21 | }
22 |
23 | public static string ToString(T value, string format)
24 | {
25 | if (!FormatCache.TryGetValue(format, out ConcurrentDictionary values))
26 | {
27 | values = new ConcurrentDictionary();
28 | FormatCache[format] = values;
29 | }
30 |
31 | if (!values.TryGetValue(value, out string text))
32 | {
33 | text = value.ToString(format, NumberFormatInfo.CurrentInfo);
34 | values[value] = text;
35 | }
36 |
37 | return text;
38 | }
39 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Cache/UiColorCache.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Concurrent;
2 | using System.Text;
3 | using Oxide.Ext.UiFramework.Colors;
4 | using Oxide.Ext.UiFramework.Extensions;
5 | using Oxide.Ext.UiFramework.Json;
6 | using Oxide.Ext.UiFramework.Pooling;
7 | using UnityEngine;
8 |
9 | namespace Oxide.Ext.UiFramework.Cache;
10 |
11 | public static class UiColorCache
12 | {
13 | private const string Format = "0.####";
14 | private const char Space = ' ';
15 |
16 | private static readonly ConcurrentDictionary ColorCache = new();
17 |
18 | public static void WriteColor(JsonBinaryWriter writer, UiColor uiColor)
19 | {
20 | int hashCode = uiColor.GetHashCode();
21 | if (!ColorCache.TryGetValue(hashCode, out string color))
22 | {
23 | color = GetColor(uiColor);
24 | ColorCache[hashCode] = color;
25 | }
26 |
27 | writer.Write(color);
28 | }
29 |
30 | private static string GetColor(Color color)
31 | {
32 | StringBuilder builder = UiFrameworkPool.GetStringBuilder();
33 | builder.Append(StringCache.ToString(color.r, Format));
34 | builder.Append(Space);
35 | builder.Append(StringCache.ToString(color.g, Format));
36 | builder.Append(Space);
37 | builder.Append(StringCache.ToString(color.b, Format));
38 | if (color.a < 1f)
39 | {
40 | builder.Append(Space);
41 | builder.Append(StringCache.ToString(color.a, Format));
42 | }
43 |
44 | return builder.ToStringAndFree();
45 | }
46 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Cache/UiFontCache.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Oxide.Ext.UiFramework.Enums;
3 |
4 | namespace Oxide.Ext.UiFramework.Cache;
5 |
6 | public static class UiFontCache
7 | {
8 | private const string DroidSansMono = "droidsansmono.ttf";
9 | private const string PermanentMarker = "permanentmarker.ttf";
10 | private const string RobotoCondensedBold = "robotocondensed-bold.ttf";
11 | private const string RobotoCondensedRegular = "robotocondensed-regular.ttf";
12 | private const string PressStart2PRegular = "PressStart2P-Regular.ttf";
13 |
14 | private static readonly IReadOnlyDictionary Fonts = new Dictionary
15 | {
16 | [UiFont.DroidSansMono] = DroidSansMono,
17 | [UiFont.PermanentMarker] = PermanentMarker,
18 | [UiFont.RobotoCondensedBold] = RobotoCondensedBold,
19 | [UiFont.RobotoCondensedRegular] = RobotoCondensedRegular,
20 | [UiFont.PressStart2PRegular] = PressStart2PRegular
21 | };
22 |
23 | public static string GetUiFont(UiFont font)
24 | {
25 | return Fonts[font];
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Cache/UiLayerCache.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Concurrent;
2 | using Oxide.Ext.UiFramework.Enums;
3 |
4 | namespace Oxide.Ext.UiFramework.Cache;
5 |
6 | public static class UiLayerCache
7 | {
8 | private const string Overall = "Overall";
9 | private const string OverlayNonScaled = "OverlayNonScaled";
10 | private const string Overlay = "Overlay";
11 | private const string Hud = "Hud";
12 | private const string HudMenu = "Hud.Menu";
13 | private const string Under = "Under";
14 | private const string UnderNonScaled = "UnderNonScaled";
15 | private const string Inventory = "Inventory";
16 | private const string Crafting = "Crafting";
17 | private const string Contacts = "Contacts";
18 | private const string Clans = "Clans";
19 | private const string TechTree = "TechTree";
20 | private const string Map = "Map";
21 |
22 | private static readonly ConcurrentDictionary Layers = new()
23 | {
24 | [UiLayer.Overall] = Overall,
25 | [UiLayer.Overlay] = Overlay,
26 | [UiLayer.OverlayNonScaled] = OverlayNonScaled,
27 | [UiLayer.Hud] = Hud,
28 | [UiLayer.HudMenu] = HudMenu,
29 | [UiLayer.Under] = Under,
30 | [UiLayer.UnderNonScaled] = UnderNonScaled,
31 | [UiLayer.Inventory] = Inventory,
32 | [UiLayer.Crafting] = Crafting,
33 | [UiLayer.Contacts] = Contacts,
34 | [UiLayer.Clans] = Clans,
35 | [UiLayer.TechTree] = TechTree,
36 | [UiLayer.Map] = Map,
37 | };
38 |
39 | public static string GetLayer(UiLayer layer)
40 | {
41 | return Layers[layer];
42 | }
43 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Cache/UiNameCache.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Oxide.Ext.UiFramework.Cache;
4 |
5 | public static class UiNameCache
6 | {
7 | private static readonly Dictionary> ComponentNameCache = new();
8 | private static readonly Dictionary> AnchorNameCache = new();
9 |
10 | public static string GetComponentName(string baseName, int index) => GetName(ComponentNameCache, baseName, "_", index);
11 | public static string GetAnchorName(string baseName, int index) => GetName(AnchorNameCache, baseName, "_anchor_", index);
12 |
13 | private static string GetName(Dictionary> cache, string baseName, string splitter, int index)
14 | {
15 | if (!cache.TryGetValue(baseName, out List names))
16 | {
17 | names = [];
18 | cache[baseName] = names;
19 | }
20 |
21 | if (index >= names.Count)
22 | {
23 | for (int i = names.Count; i <= index; i++)
24 | {
25 | names.Add(string.Concat(baseName, splitter, index.ToString()));
26 | }
27 | }
28 |
29 | return names[index];
30 | }
31 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Cache/VectorCache.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using Oxide.Ext.UiFramework.Json;
4 | using UnityEngine;
5 |
6 | namespace Oxide.Ext.UiFramework.Cache;
7 |
8 | public static class VectorCache
9 | {
10 | private const string Format = "0.####";
11 | private const char Space = ' ';
12 | private const short PositionRounder = 10000;
13 |
14 | private static readonly ConcurrentDictionary PositionCache = new();
15 |
16 | public static void WritePosition(JsonBinaryWriter writer, Vector2 pos)
17 | {
18 | WriteFromCache(writer, pos.x);
19 | writer.Write(Space);
20 | WriteFromCache(writer, pos.y);
21 | }
22 |
23 | private static void WriteFromCache(JsonBinaryWriter writer, float pos)
24 | {
25 | string value;
26 | if (!PositionCache.TryGetValue((short)(pos * PositionRounder), out value))
27 | {
28 | value = pos.ToString(Format);
29 | PositionCache[(short)(pos * PositionRounder)] = value;
30 | }
31 |
32 | writer.Write(value);
33 | }
34 |
35 | public static void WriteVector(JsonBinaryWriter writer, Vector2 pos)
36 | {
37 | string formattedPos;
38 | if (!PositionCache.TryGetValue((short)(pos.x * PositionRounder), out formattedPos))
39 | {
40 | formattedPos = pos.x.ToString(Format);
41 | PositionCache[(short)(pos.x * PositionRounder)] = formattedPos;
42 | }
43 |
44 | writer.Write(formattedPos);
45 | writer.Write(Space);
46 |
47 | if (!PositionCache.TryGetValue((short)(pos.y * PositionRounder), out formattedPos))
48 | {
49 | formattedPos = pos.y.ToString(Format);
50 | PositionCache[(short)(pos.y * PositionRounder)] = formattedPos;
51 | }
52 |
53 | writer.Write(formattedPos);
54 | }
55 |
56 | public static void WriteOffset(JsonBinaryWriter writer, Vector2 pos)
57 | {
58 | writer.Write(StringCache.ToString((short)Math.Round(pos.x)));
59 | writer.Write(Space);
60 | writer.Write(StringCache.ToString((short)Math.Round(pos.y)));
61 | }
62 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Colors/UiColorConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Newtonsoft.Json;
3 |
4 | namespace Oxide.Ext.UiFramework.Colors;
5 |
6 | public class UiColorConverter : JsonConverter
7 | {
8 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
9 | {
10 | writer.WriteValue(((UiColor)value).ToHtmlColor());
11 | }
12 |
13 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
14 | {
15 | switch (reader.TokenType)
16 | {
17 | case JsonToken.Null:
18 | if (Nullable.GetUnderlyingType(objectType) != null)
19 | {
20 | return null;
21 | }
22 |
23 | return default(UiColor);
24 |
25 | case JsonToken.String:
26 | return UiColor.ParseHexColor(reader.Value.ToString());
27 | }
28 |
29 | return default(UiColor);
30 | }
31 |
32 | public override bool CanConvert(Type objectType)
33 | {
34 | return objectType == typeof(UiColor);
35 | }
36 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Colors/UiColors.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Extensions;
2 |
3 | namespace Oxide.Ext.UiFramework.Colors;
4 |
5 | public static class UiColors
6 | {
7 | public static class BootStrap
8 | {
9 | public static readonly UiColor Blue = "#007bff";
10 | public static readonly UiColor Indigo = "#6610f2";
11 | public static readonly UiColor Purple = "#6f42c1";
12 | public static readonly UiColor Pink = "#e83e8c";
13 | public static readonly UiColor Red = "#dc3545";
14 | public static readonly UiColor Orange = "#fd7e14";
15 | public static readonly UiColor Yellow = "#ffc107";
16 | public static readonly UiColor Green = "#28a745";
17 | public static readonly UiColor Teal = "#20c997";
18 | public static readonly UiColor Cyan = "#17a2b8";
19 | public static readonly UiColor White = "#fff";
20 | public static readonly UiColor Gray = "#6c757d";
21 | public static readonly UiColor DarkGray = "#343a40";
22 | public static readonly UiColor Primary = "#007bff";
23 | public static readonly UiColor Secondary = "#6c757d";
24 | public static readonly UiColor Success = "#28a745";
25 | public static readonly UiColor Info = "#17a2b8";
26 | public static readonly UiColor Warning = "#ffc107";
27 | public static readonly UiColor Danger = "#dc3545";
28 | public static readonly UiColor Light = "#f8f9fa";
29 | public static readonly UiColor Dark = "#343a40";
30 | }
31 |
32 | public static class Material
33 | {
34 | public static readonly UiColor MatPrimary = "#dfe6e9";
35 | public static readonly UiColor MatPrimaryLight = "#b2bec3";
36 | public static readonly UiColor MatPrimaryDark = "#636e72";
37 | public static readonly UiColor MatSecondary = "#2d3436";
38 | public static readonly UiColor MatSecondaryLight = "#74b9ff";
39 | public static readonly UiColor MatSecondaryDark = "#0984e3";
40 | public static readonly UiColor MatTextOnPrimary = "#0984e3";
41 | public static readonly UiColor MatTextOnSecondary = "#0984e3";
42 | }
43 |
44 | public static class Supreme
45 | {
46 | public static readonly UiColor Lime = "#acfa58";
47 | public static readonly UiColor SilverText = "#e3e3e3";
48 | public static readonly UiColor K1lly0usRed = "#ce422b";
49 | }
50 |
51 | public static class MJSU
52 | {
53 | public static readonly UiColor Orange = "#de8732";
54 | }
55 |
56 | public static class Rust
57 | {
58 | public static readonly UiColor Red = "#cd4632";
59 | public static readonly UiColor Green = "#8cc83c";
60 | public static readonly UiColor Panel = "#CCCCCC";
61 |
62 | public static class Ui
63 | {
64 | public static readonly UiColor Panel = "#A6A6A60F";
65 | public static readonly UiColor Header = "#DBDBDB33";
66 | public static readonly UiColor PanelButton = "#A6A6A60F";
67 | public static readonly UiColor OkButton = "#6A804266";
68 | public static readonly UiColor Button = "#BFBFBF1A";
69 | public static readonly UiColor PanelText = "#E8dED4";
70 | public static readonly UiColor PanelButtonText = "#C4C4C4";
71 | public static readonly UiColor OkButtonText = "#9BB46E";
72 | public static readonly UiColor ButtonText = "#E8DED4CC";
73 | }
74 |
75 | public static class Chat
76 | {
77 | public static readonly UiColor Player = "#55AAFF";
78 | public static readonly UiColor Developer = "#FFAA55";
79 | public static readonly UiColor Admin = "#AAFF55";
80 | }
81 |
82 | public static class Steam
83 | {
84 | public static readonly UiColor InGame = "#A2DB40";
85 | public static readonly UiColor Online = "#60CBF2";
86 | public static readonly UiColor Normal = "#F7EBE1";
87 | }
88 | }
89 |
90 | public static class Form
91 | {
92 | public static readonly UiColor Body = "#00001F";
93 | public static readonly UiColor Header = "#00001F";
94 | public static readonly UiColor Text = UiColor.White;
95 | public static readonly UiColor Panel = "#2B2B2B";
96 | public static readonly UiColor PanelSecondary = "#3f3f3f";
97 | public static readonly UiColor PanelTertiary = "#525252";
98 | public static readonly UiColor ButtonPrimary = Rust.Red;
99 | public static readonly UiColor ButtonSecondary = "#666666";
100 | }
101 |
102 | #region UI Colors
103 | public static readonly UiColor Body = Form.Body.WithAlpha("B2");
104 | public static readonly UiColor BodyHeader = Form.Header;
105 | public static readonly UiColor Text = Form.Text.WithAlpha("80");
106 | public static readonly UiColor Panel = Form.Panel;
107 | public static readonly UiColor PanelSecondary = Form.PanelSecondary;
108 | public static readonly UiColor PanelTertiary = Form.PanelTertiary;
109 | public static readonly UiColor CloseButton = Form.ButtonPrimary;
110 | public static readonly UiColor ButtonPrimary = Form.ButtonPrimary;
111 | public static readonly UiColor ButtonSecondary = Form.ButtonSecondary;
112 | #endregion
113 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/BaseComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Json;
2 |
3 | namespace Oxide.Ext.UiFramework.Components;
4 |
5 | public abstract class BaseComponent : IComponent
6 | {
7 | public bool Enabled = true;
8 |
9 | public virtual void WriteComponent(JsonFrameworkWriter writer)
10 | {
11 | writer.AddField(JsonDefaults.Common.EnabledName, Enabled, true);
12 | }
13 |
14 | public virtual void Reset()
15 | {
16 | Enabled = true;
17 | }
18 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/BaseImageComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Colors;
2 | using Oxide.Ext.UiFramework.Json;
3 |
4 | namespace Oxide.Ext.UiFramework.Components;
5 |
6 | public abstract class BaseImageComponent : BaseComponent
7 | {
8 | public UiColor Color;
9 | public float FadeIn;
10 | public string Sprite;
11 | public string Material;
12 |
13 | public override void WriteComponent(JsonFrameworkWriter writer)
14 | {
15 | writer.AddField(JsonDefaults.BaseImage.SpriteName, Sprite, JsonDefaults.BaseImage.Sprite);
16 | writer.AddField(JsonDefaults.BaseImage.MaterialName, Material, JsonDefaults.BaseImage.Material);
17 | writer.AddField(JsonDefaults.Common.FadeInName, FadeIn, JsonDefaults.Common.FadeIn);
18 | writer.AddField(JsonDefaults.Color.ColorName, Color);
19 | base.WriteComponent(writer);
20 | }
21 |
22 | public override void Reset()
23 | {
24 | base.Reset();
25 | Color = default;
26 | FadeIn = 0;
27 | Sprite = null;
28 | Material = null;
29 | }
30 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/BasePoolableComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Json;
2 | using Oxide.Ext.UiFramework.Pooling;
3 |
4 | namespace Oxide.Ext.UiFramework.Components;
5 |
6 | public abstract class BasePoolableComponent : BasePoolable, IComponent
7 | {
8 | public bool Enabled = true;
9 |
10 | public virtual void WriteComponent(JsonFrameworkWriter writer)
11 | {
12 | writer.AddField(JsonDefaults.Common.EnabledName, Enabled, true);
13 | }
14 |
15 | protected override void EnterPool()
16 | {
17 | Reset();
18 | }
19 |
20 | public virtual void Reset()
21 | {
22 | Enabled = true;
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/BaseTextComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Colors;
2 | using Oxide.Ext.UiFramework.Json;
3 | using UnityEngine;
4 |
5 | namespace Oxide.Ext.UiFramework.Components;
6 |
7 | public abstract class BaseTextComponent : BaseComponent
8 | {
9 | public UiColor Color;
10 | public float FadeIn;
11 | public int FontSize = JsonDefaults.BaseText.FontSize;
12 | public string Font;
13 | public TextAnchor Align;
14 | public string Text;
15 | public VerticalWrapMode VerticalOverflow;
16 |
17 | public override void WriteComponent(JsonFrameworkWriter writer)
18 | {
19 | writer.AddTextField(JsonDefaults.BaseText.TextName, Text);
20 | writer.AddField(JsonDefaults.BaseText.FontSizeName, FontSize, JsonDefaults.BaseText.FontSize);
21 | writer.AddField(JsonDefaults.BaseText.FontName, Font, JsonDefaults.BaseText.FontValue);
22 | writer.AddField(JsonDefaults.BaseText.AlignName, Align);
23 | writer.AddField(JsonDefaults.BaseText.VerticalOverflowName, VerticalOverflow);
24 | writer.AddField(JsonDefaults.Common.FadeInName, FadeIn, JsonDefaults.Common.FadeIn);
25 | writer.AddField(JsonDefaults.Color.ColorName, Color);
26 | base.WriteComponent(writer);
27 | }
28 |
29 | public override void Reset()
30 | {
31 | base.Reset();
32 | Color = default;
33 | FadeIn = 0;
34 | FontSize = JsonDefaults.BaseText.FontSize;
35 | Font = null;
36 | Align = TextAnchor.UpperLeft;
37 | Text = null;
38 | VerticalOverflow = VerticalWrapMode.Truncate;
39 | }
40 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/ButtonComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Json;
2 | using UnityEngine.UI;
3 |
4 | namespace Oxide.Ext.UiFramework.Components;
5 |
6 | public class ButtonComponent : BaseImageComponent
7 | {
8 | private const string Type = "UnityEngine.UI.Button";
9 |
10 | public string Command;
11 | public string Close;
12 | public Image.Type ImageType;
13 |
14 | public override void WriteComponent(JsonFrameworkWriter writer)
15 | {
16 | writer.WriteStartObject();
17 | writer.AddFieldRaw(JsonDefaults.Common.ComponentTypeName, Type);
18 | writer.AddField(JsonDefaults.Common.CommandName, Command, JsonDefaults.Common.NullValue);
19 | writer.AddField(JsonDefaults.Button.CloseName, Close, JsonDefaults.Common.NullValue);
20 | writer.AddField(JsonDefaults.Image.ImageType, ImageType);
21 | base.WriteComponent(writer);
22 | writer.WriteEndObject();
23 | }
24 |
25 | public override void Reset()
26 | {
27 | base.Reset();
28 | Command = null;
29 | Close = null;
30 | ImageType = Image.Type.Simple;
31 | }
32 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/CountdownComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Enums;
2 | using Oxide.Ext.UiFramework.Json;
3 | using Oxide.Ext.UiFramework.Pooling;
4 |
5 | namespace Oxide.Ext.UiFramework.Components;
6 |
7 | public class CountdownComponent : BasePoolable, IComponent
8 | {
9 | private const string Type = "Countdown";
10 |
11 | public float StartTime;
12 | public float EndTime;
13 | public float Step;
14 | public float Interval;
15 | public TimerFormat TimerFormat;
16 | public string NumberFormat;
17 | public bool DestroyIfDone = true;
18 | public string Command;
19 |
20 | public virtual void WriteComponent(JsonFrameworkWriter writer)
21 | {
22 | writer.WriteStartObject();
23 | writer.AddFieldRaw(JsonDefaults.Common.ComponentTypeName, Type);
24 | writer.AddField(JsonDefaults.Countdown.StartTimeName, StartTime, JsonDefaults.Countdown.StartTimeValue);
25 | writer.AddField(JsonDefaults.Countdown.EndTimeName, EndTime, JsonDefaults.Countdown.EndTimeValue);
26 | writer.AddField(JsonDefaults.Countdown.StepName, Step, JsonDefaults.Countdown.StepValue);
27 | writer.AddField(JsonDefaults.Countdown.IntervalName, Interval, JsonDefaults.Countdown.IntervalValue);
28 | writer.AddField(JsonDefaults.Countdown.TimerFormatName, TimerFormat);
29 | writer.AddField(JsonDefaults.Countdown.NumberFormatName, NumberFormat, JsonDefaults.Countdown.NumberFormatValue);
30 | writer.AddField(JsonDefaults.Countdown.DestroyIfDoneName, DestroyIfDone, true);
31 | writer.AddField(JsonDefaults.Countdown.CountdownCommandName, Command, JsonDefaults.Common.NullValue);
32 | writer.WriteEndObject();
33 | }
34 |
35 | public virtual void Reset()
36 | {
37 | StartTime = JsonDefaults.Countdown.StartTimeValue;
38 | EndTime = JsonDefaults.Countdown.EndTimeValue;
39 | Step = JsonDefaults.Countdown.StepValue;
40 | Interval = JsonDefaults.Countdown.IntervalValue;
41 | TimerFormat = TimerFormat.None;
42 | NumberFormat = JsonDefaults.Countdown.NumberFormatValue;
43 | DestroyIfDone = true;
44 | Command = null;
45 | }
46 |
47 | protected override void EnterPool()
48 | {
49 | Reset();
50 | }
51 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/IComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Json;
2 |
3 | namespace Oxide.Ext.UiFramework.Components;
4 |
5 | public interface IComponent
6 | {
7 | void WriteComponent(JsonFrameworkWriter writer);
8 | void Reset();
9 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/ImageComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Json;
2 | using UnityEngine.UI;
3 |
4 | namespace Oxide.Ext.UiFramework.Components;
5 |
6 | public class ImageComponent : BaseImageComponent
7 | {
8 | private const string Type = "UnityEngine.UI.Image";
9 |
10 | public string Png;
11 | public Image.Type ImageType;
12 |
13 | public override void WriteComponent(JsonFrameworkWriter writer)
14 | {
15 | writer.WriteStartObject();
16 | writer.AddFieldRaw(JsonDefaults.Common.ComponentTypeName, Type);
17 | writer.AddField(JsonDefaults.Image.PngName, Png, JsonDefaults.Common.NullValue);
18 | writer.AddField(JsonDefaults.Image.ImageType, ImageType);
19 | base.WriteComponent(writer);
20 | writer.WriteEndObject();
21 | }
22 |
23 | public override void Reset()
24 | {
25 | base.Reset();
26 | Png = JsonDefaults.Common.NullValue;
27 | ImageType = Image.Type.Simple;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/InputComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Enums;
2 | using Oxide.Ext.UiFramework.Json;
3 | using UnityEngine.UI;
4 |
5 | namespace Oxide.Ext.UiFramework.Components;
6 |
7 | public class InputComponent : BaseTextComponent
8 | {
9 | private const string Type = "UnityEngine.UI.InputField";
10 |
11 | public int CharsLimit;
12 | public string Command;
13 | public InputMode Mode;
14 | public InputField.LineType LineType;
15 |
16 | public override void WriteComponent(JsonFrameworkWriter writer)
17 | {
18 | writer.WriteStartObject();
19 | writer.AddFieldRaw(JsonDefaults.Common.ComponentTypeName, Type);
20 | writer.AddField(JsonDefaults.Input.CharacterLimitName, CharsLimit, JsonDefaults.Input.CharacterLimitValue);
21 | writer.AddField(JsonDefaults.Input.LineTypeName, LineType);
22 |
23 | if (HasMode(InputMode.ReadOnly))
24 | {
25 | writer.AddField(JsonDefaults.Input.ReadOnlyName, true, false);
26 | }
27 | else
28 | {
29 | writer.AddField(JsonDefaults.Common.CommandName, Command, JsonDefaults.Common.NullValue);
30 | }
31 |
32 | if (HasMode(InputMode.Password))
33 | {
34 | writer.AddFieldRaw(JsonDefaults.Input.PasswordName, true);
35 | }
36 |
37 | if (HasMode(InputMode.NeedsKeyboard))
38 | {
39 | writer.AddFieldRaw(JsonDefaults.Input.NeedsKeyboardName, true);
40 | }
41 |
42 | if (HasMode(InputMode.HudNeedsKeyboard))
43 | {
44 | writer.AddFieldRaw(JsonDefaults.Input.NeedsHudKeyboardName, true);
45 | }
46 |
47 | if (HasMode(InputMode.AutoFocus))
48 | {
49 | writer.AddKeyField(JsonDefaults.Input.AutoFocusName);
50 | }
51 |
52 | base.WriteComponent(writer);
53 | writer.WriteEndObject();
54 | }
55 |
56 | public bool HasMode(InputMode mode)
57 | {
58 | return (Mode & mode) == mode;
59 | }
60 |
61 | public void SetMode(InputMode mode, bool enabled)
62 | {
63 | if (enabled)
64 | {
65 | Mode |= mode;
66 | }
67 | else
68 | {
69 | Mode &= ~mode;
70 | }
71 | }
72 |
73 | public override void Reset()
74 | {
75 | base.Reset();
76 | CharsLimit = JsonDefaults.Input.CharacterLimitValue;
77 | Command = null;
78 | Mode = default;
79 | LineType = default;
80 | }
81 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/ItemIconComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Json;
2 |
3 | namespace Oxide.Ext.UiFramework.Components;
4 |
5 | public class ItemIconComponent : BaseImageComponent
6 | {
7 | private const string Type = "UnityEngine.UI.Image";
8 |
9 | public int ItemId;
10 | public ulong SkinId;
11 |
12 | public override void WriteComponent(JsonFrameworkWriter writer)
13 | {
14 | writer.WriteStartObject();
15 | writer.AddFieldRaw(JsonDefaults.Common.ComponentTypeName, Type);
16 | writer.AddFieldRaw(JsonDefaults.ItemIcon.ItemIdName, ItemId);
17 | writer.AddField(JsonDefaults.ItemIcon.SkinIdName, SkinId, default);
18 | base.WriteComponent(writer);
19 | writer.WriteEndObject();
20 | }
21 |
22 | public override void Reset()
23 | {
24 | base.Reset();
25 | ItemId = default;
26 | SkinId = default;
27 | }
28 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/OutlineComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Colors;
2 | using Oxide.Ext.UiFramework.Json;
3 | using Oxide.Ext.UiFramework.Pooling;
4 | using UnityEngine;
5 |
6 | namespace Oxide.Ext.UiFramework.Components;
7 |
8 | public class OutlineComponent : BasePoolable, IComponent
9 | {
10 | private const string Type = "UnityEngine.UI.Outline";
11 |
12 | public UiColor Color;
13 | public Vector2 Distance = JsonDefaults.Outline.Distance;
14 | public bool UseGraphicAlpha;
15 |
16 | public virtual void WriteComponent(JsonFrameworkWriter writer)
17 | {
18 | writer.WriteStartObject();
19 | writer.AddFieldRaw(JsonDefaults.Common.ComponentTypeName, Type);
20 | writer.AddField(JsonDefaults.Outline.DistanceName, Distance, JsonDefaults.Outline.FpDistance);
21 | if (UseGraphicAlpha)
22 | {
23 | writer.AddKeyField(JsonDefaults.Outline.UseGraphicAlphaName);
24 | }
25 |
26 | writer.AddField(JsonDefaults.Color.ColorName, Color);
27 | writer.WriteEndObject();
28 | }
29 |
30 | public virtual void Reset()
31 | {
32 | Distance = JsonDefaults.Outline.Distance;
33 | UseGraphicAlpha = false;
34 | Color = default;
35 | }
36 |
37 | protected override void EnterPool()
38 | {
39 | Reset();
40 | }
41 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/PlayerAvatarComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Json;
2 |
3 | namespace Oxide.Ext.UiFramework.Components;
4 |
5 | public class PlayerAvatarComponent : BaseImageComponent
6 | {
7 | private const string Type = "UnityEngine.UI.RawImage";
8 |
9 | public string SteamId;
10 |
11 | public override void WriteComponent(JsonFrameworkWriter writer)
12 | {
13 | writer.WriteStartObject();
14 | writer.AddFieldRaw(JsonDefaults.Common.ComponentTypeName, Type);
15 | writer.AddField(JsonDefaults.PlayerAvatar.SteamIdName, SteamId, default);
16 | base.WriteComponent(writer);
17 | writer.WriteEndObject();
18 | }
19 |
20 | public override void Reset()
21 | {
22 | base.Reset();
23 | SteamId = default;
24 | }
25 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/RawImageComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Colors;
2 | using Oxide.Ext.UiFramework.Json;
3 |
4 | namespace Oxide.Ext.UiFramework.Components;
5 |
6 | public class RawImageComponent : IComponent
7 | {
8 | private const string Type = "UnityEngine.UI.RawImage";
9 |
10 | public UiColor Color;
11 | public float FadeIn;
12 | public string Url;
13 | public string Png;
14 | public string Texture;
15 | public string Material;
16 |
17 | public virtual void WriteComponent(JsonFrameworkWriter writer)
18 | {
19 | writer.WriteStartObject();
20 | writer.AddFieldRaw(JsonDefaults.Common.ComponentTypeName, Type);
21 | writer.AddField(JsonDefaults.BaseImage.SpriteName, Texture, JsonDefaults.RawImage.TextureValue);
22 | writer.AddField(JsonDefaults.BaseImage.MaterialName, Material, JsonDefaults.BaseImage.Material);
23 | if (!string.IsNullOrEmpty(Url))
24 | {
25 | writer.AddFieldRaw(JsonDefaults.Image.UrlName, Url);
26 | }
27 |
28 | if (!string.IsNullOrEmpty(Png))
29 | {
30 | writer.AddFieldRaw(JsonDefaults.Image.PngName, Png);
31 | }
32 |
33 | writer.AddField(JsonDefaults.Common.FadeInName, FadeIn, JsonDefaults.Common.FadeIn);
34 | writer.AddField(JsonDefaults.Color.ColorName, Color);
35 |
36 | writer.WriteEndObject();
37 | }
38 |
39 | public virtual void Reset()
40 | {
41 | Color = default;
42 | FadeIn = 0;
43 | Url = null;
44 | Texture = null;
45 | Material = null;
46 | }
47 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/RectTransformComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Json;
2 | using Oxide.Ext.UiFramework.Offsets;
3 | using Oxide.Ext.UiFramework.Positions;
4 |
5 | namespace Oxide.Ext.UiFramework.Components;
6 |
7 | public abstract class RectTransformComponent : IComponent
8 | {
9 | public UiPosition Position;
10 | public UiOffset Offset;
11 |
12 | public abstract void WriteComponent(JsonFrameworkWriter writer);
13 |
14 | public virtual void Reset()
15 | {
16 | Position = default;
17 | Offset = default;
18 | }
19 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/ScrollViewComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Json;
2 | using UnityEngine.UI;
3 |
4 | namespace Oxide.Ext.UiFramework.Components;
5 |
6 | public class ScrollViewComponent : IComponent
7 | {
8 | private const string Type = "UnityEngine.UI.ScrollView";
9 |
10 | public ScrollViewContentTransformComponent ContentTransform = new();
11 | public bool Horizontal;
12 | public bool Vertical;
13 | public ScrollRect.MovementType MovementType = ScrollRect.MovementType.Clamped;
14 | public float Elasticity = JsonDefaults.ScrollView.Elasticity;
15 | public bool Inertia;
16 | public float DecelerationRate = JsonDefaults.ScrollView.DecelerationRate;
17 | public float ScrollSensitivity = JsonDefaults.ScrollView.ScrollSensitivity;
18 | public ScrollbarComponent HorizontalScrollbar;
19 | public ScrollbarComponent VerticalScrollbar;
20 |
21 | public void WriteComponent(JsonFrameworkWriter writer)
22 | {
23 | writer.WriteStartObject();
24 | writer.AddFieldRaw(JsonDefaults.Common.ComponentTypeName, Type);
25 | writer.AddField(JsonDefaults.ScrollView.Horizontal, Horizontal, false);
26 | writer.AddField(JsonDefaults.ScrollView.Vertical, Vertical, false);
27 | writer.AddField(JsonDefaults.ScrollView.MovementType, MovementType);
28 | writer.AddField(JsonDefaults.ScrollView.ElasticityName, Elasticity, JsonDefaults.ScrollView.Elasticity);
29 | writer.AddField(JsonDefaults.ScrollView.Inertia, Inertia, false);
30 | writer.AddField(JsonDefaults.ScrollView.DecelerationRateName, DecelerationRate, JsonDefaults.ScrollView.DecelerationRate);
31 | writer.AddField(JsonDefaults.ScrollView.ScrollSensitivityName, ScrollSensitivity, JsonDefaults.ScrollView.ScrollSensitivity);
32 |
33 | if (Horizontal)
34 | {
35 | writer.AddComponent(JsonDefaults.ScrollView.HorizontalScrollbar, HorizontalScrollbar);
36 | }
37 |
38 | if (Vertical)
39 | {
40 | writer.AddComponent(JsonDefaults.ScrollView.VerticalScrollbar, VerticalScrollbar);
41 | }
42 |
43 | if (ContentTransform != null)
44 | {
45 | writer.AddComponent(JsonDefaults.ScrollView.ContentTransform, ContentTransform);
46 | }
47 |
48 | writer.WriteEndObject();
49 | }
50 |
51 | public void Reset()
52 | {
53 | ContentTransform.Reset();
54 | Horizontal = false;
55 | Vertical = false;
56 | MovementType = ScrollRect.MovementType.Clamped;
57 | Elasticity = JsonDefaults.ScrollView.Elasticity;
58 | Inertia = false;
59 | DecelerationRate = JsonDefaults.ScrollView.DecelerationRate;
60 | ScrollSensitivity = JsonDefaults.ScrollView.ScrollSensitivity;
61 | HorizontalScrollbar = null;
62 | VerticalScrollbar = null;
63 | }
64 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/ScrollViewContentTransformComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Json;
2 | using Oxide.Ext.UiFramework.Offsets;
3 | using Oxide.Ext.UiFramework.Positions;
4 |
5 | namespace Oxide.Ext.UiFramework.Components;
6 |
7 | public class ScrollViewContentTransformComponent : RectTransformComponent
8 | {
9 | public ScrollViewContentTransformComponent()
10 | {
11 | Position = new UiPosition(0, 0, 1, 1);
12 | Offset = new UiOffset(0, 0, 0, 0);
13 | }
14 |
15 | public override void WriteComponent(JsonFrameworkWriter writer)
16 | {
17 | writer.WriteStartObject();
18 | writer.AddPosition(JsonDefaults.Position.AnchorMinName, Position.Min, JsonDefaults.ScrollView.Min);
19 | writer.AddPosition(JsonDefaults.Position.AnchorMaxName, Position.Max, JsonDefaults.ScrollView.AnchorMax);
20 | writer.AddOffset(JsonDefaults.Offset.OffsetMinName, Offset.Min, JsonDefaults.ScrollView.Min);
21 | writer.AddOffset(JsonDefaults.Offset.OffsetMaxName, Offset.Max, JsonDefaults.ScrollView.OffsetMax);
22 | writer.WriteEndObject();
23 | }
24 |
25 | public override void Reset()
26 | {
27 | Position = new UiPosition(0, 0, 1, 1);
28 | Offset = new UiOffset(0, 0, 0, 0);
29 | }
30 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/ScrollbarComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Colors;
2 | using Oxide.Ext.UiFramework.Json;
3 |
4 | namespace Oxide.Ext.UiFramework.Components;
5 |
6 | public class ScrollbarComponent : BasePoolableComponent
7 | {
8 | public bool Invert;
9 | public bool AutoHide;
10 | public string HandleSprite;
11 | public string TrackSprite;
12 | public float Size = JsonDefaults.ScrollBar.Size;
13 | public UiColor HandleColor = JsonDefaults.ScrollBar.HandleColor;
14 | public UiColor HighlightColor = JsonDefaults.ScrollBar.HighlightColor;
15 | public UiColor PressedColor = JsonDefaults.ScrollBar.PressedColor;
16 | public UiColor TrackColor = JsonDefaults.ScrollBar.TrackColor;
17 |
18 | public override void WriteComponent(JsonFrameworkWriter writer)
19 | {
20 | writer.WriteStartObject();
21 | base.WriteComponent(writer);
22 | writer.AddField(JsonDefaults.ScrollBar.Invert, Invert, false);
23 | writer.AddField(JsonDefaults.ScrollBar.AutoHide, AutoHide, false);
24 | writer.AddField(JsonDefaults.ScrollBar.HandleSprite, HandleSprite, null);
25 | writer.AddField(JsonDefaults.ScrollBar.TrackSprite, TrackSprite, null);
26 | writer.AddField(JsonDefaults.ScrollBar.SizeName, Size, JsonDefaults.ScrollBar.Size);
27 | writer.AddField(JsonDefaults.ScrollBar.HandleColorName, HandleColor, JsonDefaults.ScrollBar.HandleColor);
28 | writer.AddField(JsonDefaults.ScrollBar.HighlightColorName, HighlightColor, JsonDefaults.ScrollBar.HighlightColor);
29 | writer.AddField(JsonDefaults.ScrollBar.PressedColorName, PressedColor, JsonDefaults.ScrollBar.PressedColor);
30 | writer.AddField(JsonDefaults.ScrollBar.TrackColorName, TrackColor, JsonDefaults.ScrollBar.TrackColor);
31 | writer.WriteEndObject();
32 | }
33 |
34 | public override void Reset()
35 | {
36 | base.Reset();
37 | Invert = false;
38 | AutoHide = false;
39 | HandleSprite = null;
40 | TrackSprite = null;
41 | Size = JsonDefaults.ScrollBar.Size;
42 | HandleColor = JsonDefaults.ScrollBar.HandleColor;
43 | HighlightColor = JsonDefaults.ScrollBar.HighlightColor;
44 | PressedColor = JsonDefaults.ScrollBar.PressedColor;
45 | TrackColor = JsonDefaults.ScrollBar.TrackColor;
46 | }
47 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Components/TextComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Json;
2 |
3 | namespace Oxide.Ext.UiFramework.Components;
4 |
5 | public class TextComponent : BaseTextComponent
6 | {
7 | private const string Type = "UnityEngine.UI.Text";
8 |
9 | public override void WriteComponent(JsonFrameworkWriter writer)
10 | {
11 | writer.WriteStartObject();
12 | writer.AddFieldRaw(JsonDefaults.Common.ComponentTypeName, Type);
13 | base.WriteComponent(writer);
14 | writer.WriteEndObject();
15 | }
16 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/BaseUiControl.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Builder;
2 | using Oxide.Ext.UiFramework.Pooling;
3 |
4 | namespace Oxide.Ext.UiFramework.Controls;
5 |
6 | public abstract class BaseUiControl : BasePoolable
7 | {
8 | private bool _hasRendered;
9 |
10 | protected static T CreateControl() where T : BaseUiControl, new()
11 | {
12 | return UiFrameworkPool.Get();
13 | }
14 |
15 | public void RenderControl(BaseUiBuilder builder)
16 | {
17 | if (!_hasRendered)
18 | {
19 | Render(builder);
20 | _hasRendered = true;
21 | }
22 | }
23 |
24 | protected virtual void Render(BaseUiBuilder builder)
25 | {
26 |
27 | }
28 |
29 | protected override void EnterPool()
30 | {
31 | _hasRendered = false;
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/Data/ButtonGroupData.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Controls.Data;
2 |
3 | public readonly struct ButtonGroupData
4 | {
5 | public readonly string DisplayName;
6 | public readonly string CommandArgs;
7 | public readonly bool IsActive;
8 |
9 | public ButtonGroupData(string displayName, string commandArgs, bool isActive = false)
10 | {
11 | DisplayName = displayName;
12 | CommandArgs = commandArgs;
13 | IsActive = isActive;
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/Data/DropdownMenuData.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Controls.Data;
2 |
3 | public readonly struct DropdownMenuData
4 | {
5 | public readonly string DisplayName;
6 | public readonly string CommandArgs;
7 | public readonly bool IsActive;
8 |
9 | public DropdownMenuData(string displayName, string commandArgs, bool isActive = false)
10 | {
11 | DisplayName = displayName;
12 | CommandArgs = commandArgs;
13 | IsActive = isActive;
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/Data/TimePickerData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Oxide.Ext.UiFramework.Controls.Data;
4 |
5 | public struct TimePickerData
6 | {
7 | public byte Hour;
8 | public byte Minute;
9 | public byte Second;
10 |
11 | public TimePickerData(DateTime time)
12 | {
13 | Hour = (byte)time.Hour;
14 | Minute = (byte)time.Minute;
15 | Second = (byte)time.Second;
16 | }
17 |
18 | public TimePickerData(int hour, int minute, int second)
19 | {
20 | Hour = (byte)hour;
21 | Minute = (byte)minute;
22 | Second = (byte)second;
23 | }
24 |
25 | public void Update(int seconds)
26 | {
27 | int abs = Math.Abs(seconds);
28 | if (abs == 1)
29 | {
30 | Second += (byte)seconds;
31 | }
32 | else if (abs == 60)
33 | {
34 | Minute += (byte)(seconds / 60);
35 | }
36 | else
37 | {
38 | Hour += (byte)(seconds / 3600);
39 | }
40 | }
41 |
42 | public DateTime AsDateTime()
43 | {
44 | DateTime now = DateTime.Now;
45 | return new DateTime(now.Year, now.Month, now.Day, Hour, Minute, Second);
46 | }
47 |
48 | public DateTime AsDateTime(DateTime time)
49 | {
50 | return new DateTime(time.Year, time.Month, time.Day, Hour, Minute, Second);
51 | }
52 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/Data/UiBorderWidth.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Controls.Data;
2 |
3 | public readonly struct UiBorderWidth
4 | {
5 | public static readonly UiBorderWidth Default = new(1);
6 |
7 | public readonly float Left;
8 | public readonly float Top;
9 | public readonly float Right;
10 | public readonly float Bottom;
11 |
12 | public UiBorderWidth(float left, float top, float right, float bottom)
13 | {
14 | Left = left;
15 | Top = top;
16 | Right = right;
17 | Bottom = bottom;
18 | }
19 |
20 | public UiBorderWidth(float width, float height) : this(width, height, width, height) { }
21 |
22 | public UiBorderWidth(float width) : this(width, width) { }
23 |
24 | public bool IsEmpty() => Left == 0 || Top == 0 || Right == 0 || Bottom == 0;
25 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/NumberPicker/BaseNumberPicker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Oxide.Ext.UiFramework.Builder;
3 | using Oxide.Ext.UiFramework.Cache;
4 | using Oxide.Ext.UiFramework.Colors;
5 | using Oxide.Ext.UiFramework.Enums;
6 | using Oxide.Ext.UiFramework.Extensions;
7 | using Oxide.Ext.UiFramework.Offsets;
8 | using Oxide.Ext.UiFramework.Positions;
9 | using Oxide.Ext.UiFramework.UiElements;
10 | using UnityEngine;
11 |
12 | namespace Oxide.Ext.UiFramework.Controls.NumberPicker;
13 |
14 | public abstract class BaseNumberPicker : BaseUiControl where T : struct, IConvertible, IFormattable, IComparable
15 | {
16 | public UiPanel Background;
17 | public UiInput Input;
18 |
19 | protected void CreateLeftRightPicker(BaseUiBuilder builder, in UiReference parent, in UiPosition pos, in UiOffset offset, T value, int fontSize, UiColor textColor, UiColor backgroundColor, string command, InputMode mode, float buttonWidth, TextAnchor align, string numberFormat)
20 | {
21 | Background = builder.Panel(parent, pos, offset, backgroundColor);
22 | string displayValue = string.IsNullOrEmpty(numberFormat) ? StringCache.ToString(value) : StringCache.ToString(value, numberFormat);
23 | Input = builder.Input(Background, UiPosition.Full.SliceHorizontal(buttonWidth, 1 - buttonWidth), displayValue, fontSize, textColor, command, align, mode: mode);
24 | }
25 |
26 | protected void CreateUpDownPicker(BaseUiBuilder builder, in UiReference parent, in UiPosition pos, in UiOffset offset, T value, int fontSize, UiColor textColor, UiColor backgroundColor, string command, TextAnchor align, InputMode mode, string numberFormat)
27 | {
28 | Background = builder.Panel(parent, pos, offset, backgroundColor);
29 | string displayValue = string.IsNullOrEmpty(numberFormat) ? StringCache.ToString(value) : StringCache.ToString(value, numberFormat);
30 | Input = builder.Input(Background, UiPosition.HorizontalPaddedFull, displayValue, fontSize, textColor, command, mode: mode, align: align);
31 | }
32 |
33 | protected override void EnterPool()
34 | {
35 | Background = null;
36 | Input = null;
37 | }
38 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/NumberPicker/UiIncrementalNumberPicker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Oxide.Ext.UiFramework.Builder;
4 | using Oxide.Ext.UiFramework.Cache;
5 | using Oxide.Ext.UiFramework.Colors;
6 | using Oxide.Ext.UiFramework.Enums;
7 | using Oxide.Ext.UiFramework.Extensions;
8 | using Oxide.Ext.UiFramework.Helpers;
9 | using Oxide.Ext.UiFramework.Offsets;
10 | using Oxide.Ext.UiFramework.Pooling;
11 | using Oxide.Ext.UiFramework.Positions;
12 | using Oxide.Ext.UiFramework.UiElements;
13 | using UnityEngine;
14 |
15 | namespace Oxide.Ext.UiFramework.Controls.NumberPicker;
16 |
17 | public class UiIncrementalNumberPicker : BaseNumberPicker where T : struct, IConvertible, IFormattable, IComparable
18 | {
19 | public List Subtracts;
20 | public List Adds;
21 |
22 | public static UiIncrementalNumberPicker Create(BaseUiBuilder builder, in UiReference parent, in UiPosition pos, in UiOffset offset, T value, IList increments, int fontSize, UiColor textColor, UiColor backgroundColor, UiColor buttonColor, UiColor disabledButtonColor, string command, TextAnchor align, InputMode mode, T minValue, T maxValue, float buttonWidth, string incrementFormat, string numberFormat)
23 | {
24 | UiIncrementalNumberPicker control = CreateControl>();
25 | int incrementCount = increments.Count;
26 |
27 | control.CreateLeftRightPicker(builder, parent, pos, offset, value, fontSize, textColor, backgroundColor, command, mode, buttonWidth * incrementCount, align, numberFormat);
28 | List subtracts = control.Subtracts;
29 | List adds = control.Adds;
30 | UiPanel background = control.Background;
31 |
32 | for (int i = 0; i < incrementCount; i++)
33 | {
34 | T increment = increments[i];
35 | string incrementValue = StringCache.ToString(increment);
36 | UiPosition subtractSlice = UiPosition.Full.SliceHorizontal(i * buttonWidth, (i + 1) * buttonWidth);
37 | UiPosition addSlice = UiPosition.Full.SliceHorizontal(1 - (buttonWidth * incrementCount) + i * buttonWidth, 1 - (buttonWidth * incrementCount) + (i + 1) * buttonWidth);
38 |
39 | string displayIncrement = StringCache.ToString(increment, incrementFormat);
40 |
41 | if (GenericMath.Subtract(value, increment).CompareTo(minValue) >= 0)
42 | {
43 | subtracts.Add(builder.TextButton(background, subtractSlice, $"-{displayIncrement}", fontSize, textColor, buttonColor, $"{command} -{incrementValue}"));
44 | }
45 | else
46 | {
47 | subtracts.Add(builder.TextButton(background, subtractSlice, $"-{displayIncrement}", fontSize, textColor, disabledButtonColor, string.Empty));
48 | }
49 |
50 | if (GenericMath.Add(value, increment).CompareTo(maxValue) <= 0)
51 | {
52 | adds.Add(builder.TextButton(background, addSlice, displayIncrement, fontSize, textColor, buttonColor, $"{command} {incrementValue}"));
53 | }
54 | else
55 | {
56 | adds.Add(builder.TextButton(background, addSlice, displayIncrement, fontSize, textColor, disabledButtonColor, string.Empty));
57 | }
58 | }
59 |
60 | return control;
61 | }
62 |
63 | protected override void LeavePool()
64 | {
65 | Subtracts = UiFrameworkPool.GetList();
66 | Adds = UiFrameworkPool.GetList();
67 | }
68 |
69 | protected override void EnterPool()
70 | {
71 | UiFrameworkPool.FreeList(Subtracts);
72 | UiFrameworkPool.FreeList(Adds);
73 | }
74 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/NumberPicker/UiNumberPicker.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Builder;
2 | using Oxide.Ext.UiFramework.Colors;
3 | using Oxide.Ext.UiFramework.Enums;
4 | using Oxide.Ext.UiFramework.Extensions;
5 | using Oxide.Ext.UiFramework.Offsets;
6 | using Oxide.Ext.UiFramework.Positions;
7 | using Oxide.Ext.UiFramework.UiElements;
8 | using UnityEngine;
9 |
10 | namespace Oxide.Ext.UiFramework.Controls.NumberPicker;
11 |
12 | public class UiNumberPicker : BaseNumberPicker
13 | {
14 | public UiButton Subtract;
15 | public UiButton Add;
16 |
17 | public static UiNumberPicker Create(BaseUiBuilder builder, in UiReference parent, in UiPosition pos, in UiOffset offset, int value, int fontSize, int buttonFontSize, UiColor textColor, UiColor backgroundColor, UiColor buttonColor, UiColor disabledButtonColor, string command, string incrementCommand, string decrementCommand, int minValue, int maxValue, float buttonWidth, TextAnchor align, InputMode mode, NumberPickerMode numberMode, string numberFormat)
18 | {
19 | UiNumberPicker control = CreateControl();
20 |
21 | if (numberMode == NumberPickerMode.LeftRight)
22 | {
23 | control.CreateLeftRightPicker(builder, parent, pos, offset, value, fontSize, textColor, backgroundColor, command, mode, buttonWidth, align, numberFormat);
24 | UiPosition subtractPosition = UiPosition.Full.SliceHorizontal(0, buttonWidth);
25 | UiPosition addPosition = UiPosition.Full.SliceHorizontal(1 - buttonWidth, 1);
26 | control.CreateAdd(builder, value, maxValue, addPosition, default, "+", buttonFontSize, textColor, buttonColor, disabledButtonColor, incrementCommand);
27 | control.CreateSubtract(builder, value, minValue, subtractPosition, default, "-", buttonFontSize, textColor, buttonColor, disabledButtonColor, decrementCommand);
28 | }
29 | else
30 | {
31 | int width = UiHelpers.TextOffsetWidth(1, buttonFontSize, 4);
32 | UiOffset pickerOffset = offset.SliceHorizontal(0, width);
33 | control.CreateUpDownPicker(builder, parent, pos, pickerOffset, value, fontSize, textColor, backgroundColor, command, align, mode, numberFormat);
34 | UiOffset buttonOffset = new(0, 0, width, 0);
35 | control.CreateAdd(builder, value, maxValue, new UiPosition(1, 0.5f, 1, 1), buttonOffset, "˄", buttonFontSize, textColor, buttonColor, disabledButtonColor, incrementCommand);
36 | control.CreateSubtract(builder, value, minValue, new UiPosition(1, 0, 1, 0.5f), buttonOffset, "˅", buttonFontSize, textColor, buttonColor, disabledButtonColor, decrementCommand);
37 | }
38 |
39 | return control;
40 | }
41 |
42 | private void CreateSubtract(BaseUiBuilder builder, int value, int minValue, in UiPosition position, in UiOffset offset, string text, int fontSize, UiColor textColor, UiColor buttonColor, UiColor disabledButtonColor, string command)
43 | {
44 | if (value > minValue)
45 | {
46 | Subtract = builder.TextButton(Background, position, offset, text, fontSize, textColor, buttonColor, command);
47 | }
48 | else
49 | {
50 | Subtract = builder.TextButton(Background, position, offset, text, fontSize, textColor.MultiplyAlpha(0.5f), disabledButtonColor, null);
51 | }
52 | }
53 |
54 | private void CreateAdd(BaseUiBuilder builder, int value, int maxValue, in UiPosition position, in UiOffset offset, string text, int fontSize, UiColor textColor, UiColor buttonColor, UiColor disabledButtonColor, string command)
55 | {
56 | if (value < maxValue)
57 | {
58 | Add = builder.TextButton(Background, position, offset, text, fontSize, textColor, buttonColor, command);
59 | }
60 | else
61 | {
62 | Add = builder.TextButton(Background, position, offset, text, fontSize, textColor.MultiplyAlpha(0.5f), disabledButtonColor, null);
63 | }
64 | }
65 |
66 | protected override void EnterPool()
67 | {
68 | Subtract = null;
69 | Add = null;
70 | }
71 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/Popover/BasePopoverControl.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Oxide.Ext.UiFramework.Builder.UI;
3 | using Oxide.Ext.UiFramework.Colors;
4 | using Oxide.Ext.UiFramework.Enums;
5 | using Oxide.Ext.UiFramework.Extensions;
6 | using Oxide.Ext.UiFramework.Offsets;
7 | using Oxide.Ext.UiFramework.Positions;
8 | using Oxide.Ext.UiFramework.UiElements;
9 | using UnityEngine;
10 | using UnityEngine.UI;
11 |
12 | namespace Oxide.Ext.UiFramework.Controls.Popover;
13 |
14 | public abstract class BasePopoverControl : BaseUiControl
15 | {
16 | public UiBuilder Builder;
17 | public UiButton OutsideClose;
18 | public UiPanel PopoverBackground;
19 |
20 | public static BasePopoverControl CreateBuilder(BasePopoverControl control, string parentName, Vector2Int size, UiColor backgroundColor, PopoverPosition position = PopoverPosition.Bottom, string menuSprite = UiConstants.Sprites.RoundedBackground2)
21 | {
22 | string name = $"{parentName}_Popover";
23 |
24 | UiBuilder builder = UiBuilder.Create(UiSection.Create(UiPosition.Full, default), name, parentName);
25 |
26 | UiPosition anchor = GetPopoverPosition(position);
27 | UiOffset offset = GetPopoverOffset(position, size);
28 |
29 | control.Builder = builder;
30 | control.OutsideClose = builder.CloseButton(builder.Root, UiPosition.Full, new UiOffset(-1000, -1000, 1000, 1000), UiColor.Clear, name);
31 | control.PopoverBackground = builder.Panel(builder.Root, anchor, offset, backgroundColor);
32 | control.PopoverBackground.SetSpriteMaterialImage(menuSprite, null, Image.Type.Sliced);
33 | control.PopoverBackground.AddElementOutline(UiColor.Black.WithAlpha(0.75f));
34 | builder.OverrideRoot(control.PopoverBackground);
35 |
36 | return control;
37 | }
38 |
39 | public static UiPosition GetPopoverPosition(PopoverPosition position)
40 | {
41 | switch (position)
42 | {
43 | case PopoverPosition.Top:
44 | case PopoverPosition.Left:
45 | return UiPosition.TopLeft;
46 |
47 | case PopoverPosition.Right:
48 | return UiPosition.TopRight;
49 |
50 | case PopoverPosition.Bottom:
51 | return UiPosition.BottomLeft;
52 |
53 | default:
54 | throw new ArgumentOutOfRangeException(nameof(position), position, null);
55 | }
56 | }
57 |
58 | public static UiOffset GetPopoverOffset(PopoverPosition position, Vector2Int size)
59 | {
60 | switch (position)
61 | {
62 | case PopoverPosition.Top:
63 | return new UiOffset(0, 1, 1 + size.x, size.y);
64 |
65 | case PopoverPosition.Left:
66 | return new UiOffset(-size.x, -size.y - 1, 0, -1);
67 |
68 | case PopoverPosition.Right:
69 | return new UiOffset(0, -size.y - 1, size.x, -1);
70 |
71 | case PopoverPosition.Bottom:
72 | return new UiOffset(1, -size.y, 1 + size.x, 0);
73 |
74 | default:
75 | throw new ArgumentOutOfRangeException(nameof(position), position, null);
76 | }
77 | }
78 |
79 | protected override void EnterPool()
80 | {
81 | Builder = null;
82 | OutsideClose = null;
83 | PopoverBackground = null;
84 | }
85 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/Popover/UiDropdownMenu.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Oxide.Ext.UiFramework.Builder.UI;
4 | using Oxide.Ext.UiFramework.Colors;
5 | using Oxide.Ext.UiFramework.Controls.Data;
6 | using Oxide.Ext.UiFramework.Enums;
7 | using Oxide.Ext.UiFramework.Extensions;
8 | using Oxide.Ext.UiFramework.Offsets;
9 | using Oxide.Ext.UiFramework.Positions;
10 | using Oxide.Ext.UiFramework.UiElements;
11 | using UnityEngine;
12 | using UnityEngine.UI;
13 |
14 | namespace Oxide.Ext.UiFramework.Controls.Popover;
15 |
16 | public class UiDropdownMenu : BasePopoverControl
17 | {
18 | public UiSection ScrollBarSection;
19 | public UiScrollBar ScrollBar;
20 | public List Items;
21 |
22 | public static UiDropdownMenu Create(in UiReference reference, List items, int fontSize, UiColor textColor, UiColor backgroundColor, string selectedCommand, string pageCommand = null, int page = 0, int maxValuesPerPage = 100, int minWidth = 100,
23 | PopoverPosition position = PopoverPosition.Bottom, string menuSprite = UiConstants.Sprites.RoundedBackground2)
24 | {
25 | const int itemPadding = 4;
26 | const int menuPadding = 5;
27 |
28 | UiDropdownMenu control = CreateControl();
29 |
30 | int itemCount = Math.Min(items.Count, maxValuesPerPage);
31 | int width = Math.Max(minWidth, control.GetWidth(items, fontSize));
32 | int itemHeight = UiHelpers.TextOffsetHeight(fontSize);
33 | int height = itemCount * (itemHeight + itemPadding) + menuPadding * 2;
34 | int maxPage = UiHelpers.CalculateMaxPage(items.Count, maxValuesPerPage);
35 |
36 | Vector2Int size = new(width, height);
37 | CreateBuilder(control, reference.Parent, size, backgroundColor, position, menuSprite);
38 |
39 | UiBuilder builder = control.Builder;
40 |
41 | UiOffset buttonPos = new(menuPadding, -itemHeight - menuPadding, width + menuPadding, -menuPadding);
42 | if (maxPage > 0)
43 | {
44 | buttonPos = buttonPos.SliceHorizontal(0, 10);
45 | control.ScrollBarSection = builder.Section(builder.Root, UiPosition.Right, new UiOffset(-10, 5, -3, -5));
46 | control.ScrollBar = builder.ScrollBar(control.ScrollBarSection, UiPosition.Full, default, page, maxPage, UiColors.ButtonPrimary, UiColors.PanelSecondary, pageCommand);
47 | control.ScrollBar.SetSpriteMaterialImage(UiConstants.Sprites.RoundedBackground1, null, Image.Type.Sliced);
48 | }
49 |
50 | for (int i = page * maxValuesPerPage; i < page * maxValuesPerPage + itemCount; i++)
51 | {
52 | control.Items.Add(UiDropdownMenuItem.Create(builder, buttonPos, items[i], fontSize, textColor, backgroundColor, selectedCommand));
53 | buttonPos = buttonPos.MoveY(-itemHeight - itemPadding);
54 | }
55 |
56 | return control;
57 | }
58 |
59 | public virtual int GetWidth(List items, int fontSize)
60 | {
61 | int width = 0;
62 | int count = items.Count;
63 | for (int i = 0; i < count; i++)
64 | {
65 | DropdownMenuData item = items[i];
66 | int valueWidth = UiHelpers.TextOffsetWidth(item.DisplayName.Length, fontSize);
67 | if (valueWidth > width)
68 | {
69 | width = valueWidth;
70 | }
71 | }
72 |
73 | return width;
74 | }
75 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/Popover/UiDropdownMenuItem.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Builder.UI;
2 | using Oxide.Ext.UiFramework.Colors;
3 | using Oxide.Ext.UiFramework.Controls.Data;
4 | using Oxide.Ext.UiFramework.Offsets;
5 | using Oxide.Ext.UiFramework.Positions;
6 | using Oxide.Ext.UiFramework.UiElements;
7 |
8 | namespace Oxide.Ext.UiFramework.Controls.Popover;
9 |
10 | public class UiDropdownMenuItem : BaseUiControl
11 | {
12 | public UiButton Button;
13 | public UiLabel Label;
14 |
15 | public static UiDropdownMenuItem Create(UiBuilder builder, in UiOffset position, in DropdownMenuData item, int fontSize, UiColor textColor, UiColor backgroundColor, string selectedCommand)
16 | {
17 | UiDropdownMenuItem control = CreateControl();
18 |
19 | control.Button = builder.CommandButton(builder.Root, UiPosition.TopLeft, position, backgroundColor, $"{selectedCommand} {item.CommandArgs}");
20 | control.Label = builder.Label(control.Button, UiPosition.Full, item.DisplayName, fontSize, textColor);
21 |
22 | return control;
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/Popover/UiPopover.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Colors;
2 | using Oxide.Ext.UiFramework.Enums;
3 | using UnityEngine;
4 |
5 | namespace Oxide.Ext.UiFramework.Controls.Popover;
6 |
7 | public class UiPopover : BasePopoverControl
8 | {
9 | public static UiPopover Create(string parentName, Vector2Int size, UiColor backgroundColor, PopoverPosition position = PopoverPosition.Bottom, string menuSprite = UiConstants.Sprites.RoundedBackground2)
10 | {
11 | UiPopover control = CreateControl();
12 | CreateBuilder(control, parentName, size, backgroundColor, position, menuSprite);
13 | return control;
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/UiBorder.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Builder;
2 | using Oxide.Ext.UiFramework.Colors;
3 | using Oxide.Ext.UiFramework.Controls.Data;
4 | using Oxide.Ext.UiFramework.Enums;
5 | using Oxide.Ext.UiFramework.Offsets;
6 | using Oxide.Ext.UiFramework.Positions;
7 | using Oxide.Ext.UiFramework.UiElements;
8 |
9 | namespace Oxide.Ext.UiFramework.Controls;
10 |
11 | public class UiBorder : BaseUiControl
12 | {
13 | public UiPanel Left;
14 | public UiPanel Right;
15 | public UiPanel Top;
16 | public UiPanel Bottom;
17 |
18 | public static UiBorder Create(BaseUiBuilder builder, in UiReference parent, UiColor color,
19 | in UiBorderWidth width, BorderMode border = BorderMode.All)
20 | {
21 | UiBorder control = CreateControl();
22 | if (width.IsEmpty())
23 | {
24 | return control;
25 | }
26 |
27 | bool top = HasBorderFlag(border, BorderMode.Top);
28 | bool left = HasBorderFlag(border, BorderMode.Left);
29 | bool bottom = HasBorderFlag(border, BorderMode.Bottom);
30 | bool right = HasBorderFlag(border, BorderMode.Right);
31 |
32 | if (top)
33 | {
34 | control.Top = builder.Panel(parent, UiPosition.Top, new UiOffset(left ? -width.Left : 0, 0, right ? width.Right : 0, width.Top), color);
35 | }
36 |
37 | if (left)
38 | {
39 | control.Left = builder.Panel(parent, UiPosition.Left, new UiOffset(-width.Left, bottom ? -width.Bottom : 0, 0, top ? width.Top : 0), color);
40 | }
41 |
42 | if (bottom)
43 | {
44 | control.Bottom = builder.Panel(parent, UiPosition.Bottom, new UiOffset(left ? -width.Left : 0, -width.Bottom, right ? width.Right : 0, 0), color);
45 | }
46 |
47 | if (right)
48 | {
49 | control.Right = builder.Panel(parent, UiPosition.Right, new UiOffset(0, bottom ? -width.Bottom : 0, width.Right, top ? width.Top : 0), color);
50 | }
51 |
52 | return control;
53 | }
54 |
55 | private static bool HasBorderFlag(BorderMode mode, BorderMode flag)
56 | {
57 | return (mode & flag) != 0;
58 | }
59 |
60 | protected override void EnterPool()
61 | {
62 | base.EnterPool();
63 | Left = null;
64 | Top = null;
65 | Right = null;
66 | Bottom = null;
67 | }
68 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/UiButtonGroup.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Oxide.Ext.UiFramework.Builder;
3 | using Oxide.Ext.UiFramework.Cache;
4 | using Oxide.Ext.UiFramework.Colors;
5 | using Oxide.Ext.UiFramework.Controls.Data;
6 | using Oxide.Ext.UiFramework.Extensions;
7 | using Oxide.Ext.UiFramework.Offsets;
8 | using Oxide.Ext.UiFramework.Pooling;
9 | using Oxide.Ext.UiFramework.Positions;
10 | using Oxide.Ext.UiFramework.UiElements;
11 |
12 | namespace Oxide.Ext.UiFramework.Controls;
13 |
14 | public class UiButtonGroup : BaseUiControl
15 | {
16 | public UiSection Base;
17 | public List Buttons;
18 |
19 | public static UiButtonGroup Create(BaseUiBuilder builder, in UiReference parent, in UiPosition pos, in UiOffset offset, List buttons, int textSize, UiColor textColor, UiColor buttonColor, UiColor activeButtonColor, string command)
20 | {
21 | UiButtonGroup control = CreateControl();
22 | control.Base = builder.Section(parent, pos, offset);
23 |
24 | float buttonSize = 1f / (buttons.Count + 1);
25 | for (int i = 0; i < buttons.Count; i++)
26 | {
27 | ButtonGroupData button = buttons[i];
28 |
29 | UiPosition buttonPos = UiPosition.Full.SliceHorizontal(buttonSize * i, buttonSize * (i + 1));
30 | control.Buttons.Add(builder.TextButton(control.Base, buttonPos, button.DisplayName, textSize, textColor, button.IsActive ? activeButtonColor : buttonColor, $"{command} {button.CommandArgs}"));
31 | }
32 |
33 | return control;
34 | }
35 |
36 | public static UiButtonGroup CreateNumeric(BaseUiBuilder builder, in UiReference parent, in UiPosition pos, in UiOffset offset, int value, int minValue, int maxValue, int textSize, UiColor textColor, UiColor buttonColor, UiColor activeButtonColor, string command)
37 | {
38 | List data = UiFrameworkPool.GetList();
39 | for (int i = minValue; i <= maxValue; i++)
40 | {
41 | string num = StringCache.ToString(i);
42 | data.Add(new ButtonGroupData(num, num, i == value));
43 | }
44 |
45 | UiButtonGroup control = Create(builder, parent, pos, offset, data, textSize, textColor, buttonColor, activeButtonColor, command);
46 | UiFrameworkPool.FreeList(data);
47 |
48 | return control;
49 | }
50 |
51 | protected override void LeavePool()
52 | {
53 | base.LeavePool();
54 | Buttons = UiFrameworkPool.GetList();
55 | }
56 |
57 | protected override void EnterPool()
58 | {
59 | base.EnterPool();
60 | UiFrameworkPool.FreeList(Buttons);
61 | Base = null;
62 | }
63 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/UiCheckbox.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Builder;
2 | using Oxide.Ext.UiFramework.Colors;
3 | using Oxide.Ext.UiFramework.Extensions;
4 | using Oxide.Ext.UiFramework.Offsets;
5 | using Oxide.Ext.UiFramework.Positions;
6 | using Oxide.Ext.UiFramework.UiElements;
7 |
8 | namespace Oxide.Ext.UiFramework.Controls;
9 |
10 | public class UiCheckbox : BaseUiControl
11 | {
12 | private const string DefaultCheckmark = "✓";
13 |
14 | public bool IsChecked;
15 | public string Checkmark = DefaultCheckmark;
16 | public UiButton Button;
17 | public UiLabel Label;
18 |
19 | public static UiCheckbox CreateCheckbox(BaseUiBuilder builder, in UiReference parent, in UiPosition pos, in UiOffset offset, bool isChecked, int textSize, UiColor textColor, UiColor backgroundColor, string command)
20 | {
21 | UiCheckbox control = CreateControl();
22 | control.IsChecked = isChecked;
23 | control.Button = builder.CommandButton(parent, pos, offset, backgroundColor, command);
24 | control.Label = builder.Label(control.Button, UiPosition.Full, string.Empty, textSize, textColor);
25 | control.Button.AddElementOutline(UiColor.Black.WithAlpha(0.75f));
26 | return control;
27 | }
28 |
29 | protected override void Render(BaseUiBuilder builder)
30 | {
31 | if (IsChecked)
32 | {
33 | Label.Text.Text = Checkmark;
34 | }
35 | }
36 |
37 | protected override void EnterPool()
38 | {
39 | base.EnterPool();
40 | IsChecked = false;
41 | Button = null;
42 | Label = null;
43 | Checkmark = DefaultCheckmark;
44 | }
45 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/UiColorPicker.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Builder;
2 | using Oxide.Ext.UiFramework.Colors;
3 | using Oxide.Ext.UiFramework.Extensions;
4 | using Oxide.Ext.UiFramework.Offsets;
5 | using Oxide.Ext.UiFramework.Positions;
6 | using Oxide.Ext.UiFramework.UiElements;
7 | using UnityEngine;
8 |
9 | namespace Oxide.Ext.UiFramework.Controls;
10 |
11 | public class UiColorPicker : BaseUiControl
12 | {
13 | public UiSection Anchor;
14 | public UiButton Button;
15 | public UiLabel Text;
16 | public UiPanel Color;
17 |
18 | public static UiColorPicker Create(BaseUiBuilder builder, BaseUiComponent parent, in UiPosition pos, in UiOffset offset, UiColor selectedColor, int fontSize, UiColor textColor, UiColor backgroundColor, string openCommand)
19 | {
20 | UiColorPicker control = CreateControl();
21 | control.Anchor = builder.Anchor(parent, pos, offset);
22 | control.Button = builder.CommandButton(parent, pos, offset, backgroundColor, $"{openCommand} {control.Anchor.Reference.Name}");
23 | control.Text = builder.Label(control.Button, UiPosition.Full, new UiOffset(5, 0, 0, 0), selectedColor.ToHtmlColor(), fontSize, textColor, TextAnchor.MiddleLeft);
24 | control.Color = builder.Panel(control.Button, UiPosition.Full.SliceHorizontal(1f - (pos.Max.y - pos.Min.y), 1), new UiOffset(-4, 4, -4, -4), selectedColor);
25 | return control;
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/UiDatePicker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Oxide.Ext.UiFramework.Builder;
3 | using Oxide.Ext.UiFramework.Colors;
4 | using Oxide.Ext.UiFramework.Offsets;
5 | using Oxide.Ext.UiFramework.Positions;
6 | using Oxide.Ext.UiFramework.UiElements;
7 | using UnityEngine;
8 |
9 | namespace Oxide.Ext.UiFramework.Controls;
10 |
11 | public class UiDatePicker : BaseUiControl
12 | {
13 | public UiSection Anchor;
14 | public UiButton Command;
15 | public UiLabel Text;
16 | public UiLabel Icon;
17 |
18 | public static UiDatePicker Create(BaseUiBuilder builder, in UiReference parent, in UiPosition pos, in UiOffset offset, DateTime date, int fontSize, UiColor textColor, UiColor backgroundColor, string openCommand, string displayFormat = "MM/dd/yyyy")
19 | {
20 | UiDatePicker control = CreateControl();
21 |
22 | control.Anchor = builder.Anchor(parent, pos, offset);
23 | control.Command = builder.CommandButton(parent, pos, offset, backgroundColor, $"{openCommand} {control.Anchor.Reference.Name}");
24 | control.Text = builder.Label(control.Command, UiPosition.Full, new UiOffset(5, 0, 0, 0), date.ToString(displayFormat), fontSize, textColor, TextAnchor.MiddleLeft);
25 | control.Icon = builder.Label(control.Command, UiPosition.Right, new UiOffset(-fontSize - 4, 0, -4 , 0), "⏱", fontSize, textColor);
26 |
27 | return control;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/UiDropdown.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Builder;
2 | using Oxide.Ext.UiFramework.Colors;
3 | using Oxide.Ext.UiFramework.Offsets;
4 | using Oxide.Ext.UiFramework.Positions;
5 | using Oxide.Ext.UiFramework.UiElements;
6 | using UnityEngine;
7 |
8 | namespace Oxide.Ext.UiFramework.Controls;
9 |
10 | public class UiDropdown : BaseUiControl
11 | {
12 | public UiSection Anchor;
13 | public UiButton Command;
14 | public UiLabel Text;
15 | public UiLabel Icon;
16 |
17 | public static UiDropdown Create(BaseUiBuilder builder, in UiReference parent, in UiPosition pos, in UiOffset offset, string displayValue, int fontSize, UiColor textColor, UiColor backgroundColor, string openCommand)
18 | {
19 | UiDropdown control = CreateControl();
20 | control.Anchor = builder.Anchor(parent, pos);
21 | control.Command = builder.CommandButton(parent, pos, offset, backgroundColor, $"{openCommand} {control.Anchor.Reference.Name}");
22 | control.Text = builder.Label(control.Command, UiPosition.Full, new UiOffset(5, 0, 0, 0), displayValue, fontSize, textColor, TextAnchor.MiddleLeft);
23 | control.Icon = builder.Label(control.Command, UiPosition.Right, new UiOffset(-UiHelpers.TextOffsetWidth(1, fontSize) - 4, 0, -4 , 0), "▼", fontSize, textColor);
24 | return control;
25 | }
26 |
27 | protected override void EnterPool()
28 | {
29 | base.EnterPool();
30 | Anchor = null;
31 | Command = null;
32 | Text = null;
33 | Icon = null;
34 | }
35 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/UiInputBackground.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Builder;
2 | using Oxide.Ext.UiFramework.Colors;
3 | using Oxide.Ext.UiFramework.Enums;
4 | using Oxide.Ext.UiFramework.Offsets;
5 | using Oxide.Ext.UiFramework.Positions;
6 | using Oxide.Ext.UiFramework.UiElements;
7 | using UnityEngine;
8 | using UnityEngine.UI;
9 |
10 | namespace Oxide.Ext.UiFramework.Controls;
11 |
12 | public class UiInputBackground : BaseUiControl
13 | {
14 | public UiInput Input;
15 | public UiPanel Background;
16 |
17 | public static UiInputBackground Create(BaseUiBuilder builder, in UiReference parent, in UiPosition pos, in UiOffset offset, string text, int fontSize, UiColor textColor, UiColor backgroundColor, string command, TextAnchor align = TextAnchor.MiddleCenter, int charsLimit = 0, InputMode mode = InputMode.Default, InputField.LineType lineType = InputField.LineType.SingleLine)
18 | {
19 | UiInputBackground control = CreateControl();
20 | control.Background = builder.Panel(parent, pos, offset, backgroundColor);
21 | control.Input = builder.Input(control.Background, UiPosition.HorizontalPaddedFull, text, fontSize, textColor, command, align, charsLimit, mode, lineType);
22 | return control;
23 | }
24 |
25 | protected override void EnterPool()
26 | {
27 | base.EnterPool();
28 | Input = null;
29 | Background = null;
30 | }
31 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/UiLabelBackground.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Builder;
2 | using Oxide.Ext.UiFramework.Colors;
3 | using Oxide.Ext.UiFramework.Offsets;
4 | using Oxide.Ext.UiFramework.Positions;
5 | using Oxide.Ext.UiFramework.UiElements;
6 | using UnityEngine;
7 |
8 | namespace Oxide.Ext.UiFramework.Controls;
9 |
10 | public class UiLabelBackground : BaseUiControl
11 | {
12 | public UiLabel Label;
13 | public UiPanel Background;
14 |
15 | public static UiLabelBackground Create(BaseUiBuilder builder, in UiReference parent, in UiPosition pos, in UiOffset offset, string text, int fontSize, UiColor textColor, UiColor backgroundColor, TextAnchor align = TextAnchor.MiddleCenter)
16 | {
17 | UiLabelBackground control = CreateControl();
18 | control.Background = builder.Panel(parent, pos, offset, backgroundColor);
19 | control.Label = builder.Label(control.Background, UiPosition.HorizontalPaddedFull, text, fontSize, textColor, align);
20 | return control;
21 | }
22 |
23 | protected override void EnterPool()
24 | {
25 | base.EnterPool();
26 | Label = null;
27 | Background = null;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/UiPaginator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Oxide.Ext.UiFramework.Builder;
4 | using Oxide.Ext.UiFramework.Cache;
5 | using Oxide.Ext.UiFramework.Colors;
6 | using Oxide.Ext.UiFramework.Pooling;
7 | using Oxide.Ext.UiFramework.Positions;
8 | using Oxide.Ext.UiFramework.UiElements;
9 |
10 | namespace Oxide.Ext.UiFramework.Controls;
11 |
12 | public class UiPaginator : BaseUiControl
13 | {
14 | public UiButton FirstPage;
15 | public UiButton PreviousPage;
16 | public List PageButtons;
17 | public UiButton NextPage;
18 | public UiButton LastPage;
19 |
20 | public static UiPaginator Create(BaseUiBuilder builder, in UiReference parent, GridPosition grid, int currentPage, int maxPage, int fontSize, UiColor textColor, UiColor buttonColor, UiColor activePageColor, string command)
21 | {
22 | UiPaginator control = CreateControl();
23 | grid.Reset();
24 |
25 | int totalButtons = (int)Math.Round(grid.NumCols, 0);
26 | int pageButtons = totalButtons - 5;
27 |
28 | int startPage = Math.Max(currentPage - pageButtons / 2, 0);
29 | int endPage = Math.Min(maxPage, startPage + pageButtons);
30 | if (endPage - startPage != pageButtons)
31 | {
32 | startPage = Math.Max(endPage - pageButtons, 0);
33 | if (endPage - startPage != pageButtons)
34 | {
35 | grid.MoveCols((pageButtons - endPage - startPage) / 2f);
36 | }
37 | }
38 |
39 | control.FirstPage = builder.TextButton(parent, grid, "<<<", fontSize, textColor, buttonColor, $"{command} 0");
40 | grid.MoveCols(1);
41 | control.PreviousPage = builder.TextButton(parent, grid, "<", fontSize, textColor, buttonColor, $"{command} {StringCache.ToString(Math.Max(0, currentPage - 1))}");
42 | grid.MoveCols(1);
43 |
44 | for (int i = startPage; i <= endPage; i++)
45 | {
46 | control.PageButtons.Add(builder.TextButton(parent, grid, (i + 1).ToString(), fontSize, textColor, i == currentPage ? activePageColor : buttonColor, $"{command} {StringCache.ToString(i)}"));
47 | grid.MoveCols(1);
48 | }
49 |
50 | control.NextPage = builder.TextButton(parent, grid, ">", fontSize, textColor, buttonColor, $"{command} {StringCache.ToString(Math.Min(maxPage, currentPage + 1))}");
51 | grid.MoveCols(1);
52 | control.LastPage = builder.TextButton(parent, grid, ">>>", fontSize, textColor, buttonColor, $"{command} {StringCache.ToString(maxPage)}");
53 |
54 | return control;
55 | }
56 |
57 | protected override void LeavePool()
58 | {
59 | base.LeavePool();
60 | PageButtons = UiFrameworkPool.GetList();
61 | }
62 |
63 | protected override void EnterPool()
64 | {
65 | base.EnterPool();
66 | FirstPage = null;
67 | PreviousPage = null;
68 | UiFrameworkPool.FreeList(PageButtons);
69 | NextPage = null;
70 | LastPage = null;
71 | }
72 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/UiPicker.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Builder;
2 | using Oxide.Ext.UiFramework.Colors;
3 | using Oxide.Ext.UiFramework.Extensions;
4 | using Oxide.Ext.UiFramework.Offsets;
5 | using Oxide.Ext.UiFramework.Positions;
6 | using Oxide.Ext.UiFramework.UiElements;
7 |
8 | namespace Oxide.Ext.UiFramework.Controls;
9 |
10 | public class UiPicker : BaseUiControl
11 | {
12 | public UiButton Previous;
13 | public UiLabel Value;
14 | public UiButton Next;
15 |
16 | public static UiPicker Create(BaseUiBuilder builder, in UiReference parent, in UiOffset pos, string value, int fontSize, UiColor textColor, UiColor backgroundColor, float height, string incrementCommand, string decrementCommand)
17 | {
18 | UiPicker control = CreateControl();
19 |
20 | UiOffset slice = pos.SliceVertical(0, (int)height * 2);
21 | control.Next = builder.TextButton(parent, UiPosition.BottomLeft, slice, "˅", fontSize, textColor, backgroundColor, decrementCommand);
22 | slice = slice.MoveY(height);
23 | control.Value = builder.Label(parent, UiPosition.BottomLeft, slice, value, fontSize, textColor);
24 | slice = slice.MoveY(height);
25 | control.Previous = builder.TextButton(parent, UiPosition.BottomLeft, slice, "˄", fontSize, textColor, backgroundColor, incrementCommand);
26 |
27 | return control;
28 | }
29 |
30 | protected override void EnterPool()
31 | {
32 | base.EnterPool();
33 | Previous = null;
34 | Value = null;
35 | Next = null;
36 | }
37 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/UiProgressBar.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Builder;
2 | using Oxide.Ext.UiFramework.Colors;
3 | using Oxide.Ext.UiFramework.Extensions;
4 | using Oxide.Ext.UiFramework.Offsets;
5 | using Oxide.Ext.UiFramework.Positions;
6 | using Oxide.Ext.UiFramework.UiElements;
7 |
8 | namespace Oxide.Ext.UiFramework.Controls;
9 |
10 | public class UiProgressBar : BaseUiControl
11 | {
12 | public UiPanel BackgroundPanel;
13 | public UiPanel BarPanel;
14 |
15 | public static UiProgressBar Create(BaseUiBuilder builder, in UiReference parent, in UiPosition pos, in UiOffset offset, float percentage, UiColor barColor, UiColor backgroundColor)
16 | {
17 | UiProgressBar control = CreateControl();
18 | control.BackgroundPanel = builder.Panel(parent, pos, offset, backgroundColor);
19 | control.BarPanel = builder.Panel(control.BackgroundPanel, UiPosition.Full.SliceHorizontal(0, percentage), barColor);
20 | return control;
21 | }
22 |
23 | protected override void EnterPool()
24 | {
25 | base.EnterPool();
26 | BackgroundPanel = null;
27 | BarPanel = null;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/UiScrollBar.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Oxide.Ext.UiFramework.Builder;
3 | using Oxide.Ext.UiFramework.Cache;
4 | using Oxide.Ext.UiFramework.Colors;
5 | using Oxide.Ext.UiFramework.Enums;
6 | using Oxide.Ext.UiFramework.Extensions;
7 | using Oxide.Ext.UiFramework.Offsets;
8 | using Oxide.Ext.UiFramework.Pooling;
9 | using Oxide.Ext.UiFramework.Positions;
10 | using Oxide.Ext.UiFramework.UiElements;
11 | using UnityEngine.UI;
12 |
13 | namespace Oxide.Ext.UiFramework.Controls;
14 |
15 | public class UiScrollBar : BaseUiControl
16 | {
17 | public UiPanel Background;
18 | public UiPanel ScrollBar;
19 | public List ScrollButtons;
20 |
21 | public static UiScrollBar Create(BaseUiBuilder builder, in UiReference parent, in UiPosition position, in UiOffset offset, int currentPage, int maxPage, UiColor barColor, UiColor backgroundColor, string command, ScrollbarDirection direction, string sprite)
22 | {
23 | UiScrollBar control = CreateControl();
24 |
25 | control.Background = builder.Panel(parent, position, offset, backgroundColor);
26 | control.Background.SetSpriteMaterialImage(sprite, null, Image.Type.Sliced);
27 | float buttonSize = 1f / (maxPage + 1);
28 | for (int i = 0; i <= maxPage; i++)
29 | {
30 | float min = buttonSize * i;
31 | float max = buttonSize * (i + 1);
32 | UiPosition pagePosition = direction == ScrollbarDirection.Horizontal ? UiPosition.Full.SliceHorizontal(min, max) : new UiPosition(0, 1 - max, 1, 1 - min);
33 |
34 | if (i != currentPage)
35 | {
36 | UiButton button = builder.CommandButton(control.Background, pagePosition, backgroundColor, $"{command} {StringCache.ToString(i)}");
37 | button.SetSpriteMaterialImage(sprite, null, Image.Type.Sliced);
38 | control.ScrollButtons.Add(button);
39 | }
40 | else
41 | {
42 | control.ScrollBar = builder.Panel(control.Background, pagePosition, barColor);
43 | control.ScrollBar.SetSpriteMaterialImage(sprite, null, Image.Type.Sliced);
44 | }
45 | }
46 |
47 | return control;
48 | }
49 |
50 | public void SetSpriteMaterialImage(string sprite = null, string material = null, Image.Type type = Image.Type.Simple)
51 | {
52 | Background.SetSpriteMaterialImage(sprite, material, type);
53 | ScrollBar.SetSpriteMaterialImage(sprite, material, type);
54 | for (int index = 0; index < ScrollButtons.Count; index++)
55 | {
56 | UiButton button = ScrollButtons[index];
57 | button.SetSpriteMaterialImage(sprite, material, type);
58 | }
59 | }
60 |
61 | protected override void LeavePool()
62 | {
63 | base.LeavePool();
64 | ScrollButtons = UiFrameworkPool.GetList();
65 | }
66 |
67 | protected override void EnterPool()
68 | {
69 | base.EnterPool();
70 | Background = null;
71 | ScrollBar = null;
72 | UiFrameworkPool.FreeList(ScrollButtons);
73 | }
74 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Controls/UiTimePicker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Oxide.Ext.UiFramework.Builder;
3 | using Oxide.Ext.UiFramework.Colors;
4 | using Oxide.Ext.UiFramework.Offsets;
5 | using Oxide.Ext.UiFramework.Positions;
6 | using Oxide.Ext.UiFramework.UiElements;
7 | using UnityEngine;
8 |
9 | namespace Oxide.Ext.UiFramework.Controls;
10 |
11 | public class UiTimePicker : BaseUiControl
12 | {
13 | public UiSection Anchor;
14 | public UiButton Command;
15 | public UiLabel Text;
16 | public UiLabel Icon;
17 |
18 | public static UiTimePicker Create(BaseUiBuilder builder, in UiReference parent, in UiPosition pos, in UiOffset offset, DateTime time, int fontSize, UiColor textColor, UiColor backgroundColor, string openCommand, string displayFormat = "hh:mm:ss tt")
19 | {
20 | UiTimePicker control = CreateControl();
21 |
22 | control.Anchor = builder.Anchor(parent, pos, offset);
23 | control.Command = builder.CommandButton(parent, pos, offset, backgroundColor, $"{openCommand} {control.Anchor.Reference.Name}");
24 | control.Text = builder.Label(control.Command, UiPosition.Full, new UiOffset(5, 0, 0, 0), time.ToString(displayFormat), fontSize, textColor, TextAnchor.MiddleLeft);
25 | control.Icon = builder.Label(control.Command, UiPosition.Right, new UiOffset(-fontSize - 4, 0, -4 , 0), "⏱", fontSize, textColor);
26 |
27 | return control;
28 | }
29 |
30 | protected override void EnterPool()
31 | {
32 | base.EnterPool();
33 | Anchor = null;
34 | Command = null;
35 | Text = null;
36 | Icon = null;
37 | }
38 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Enums/BorderMode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Oxide.Ext.UiFramework.Enums;
4 |
5 | [Flags]
6 | public enum BorderMode : byte
7 | {
8 | Top = 1 << 0,
9 | Left = 1 << 1,
10 | Bottom = 1 << 2,
11 | Right = 1 << 3,
12 | All = Top | Left | Bottom | Right
13 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Enums/ClockMode.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Enums;
2 |
3 | public enum ClockMode
4 | {
5 | Hour12,
6 | Hour24
7 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Enums/ColorPickerMode.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Enums;
2 |
3 | public enum ColorPickerMode
4 | {
5 | RGB,
6 | RGBA
7 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Enums/DatePickerDisplayMode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Oxide.Ext.UiFramework.Enums;
4 |
5 | [Flags]
6 | public enum DatePickerDisplayMode : byte
7 | {
8 | Day = 1 << 0,
9 | Month = 1 << 1,
10 | Year = 1 << 2,
11 | All = Day | Month | Year
12 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Enums/DatePickerDisplayOrder.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Enums;
2 |
3 | public enum DatePickerDisplayOrder
4 | {
5 | YearMonthDay,
6 | MonthDayYear,
7 | DayMonthYear,
8 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Enums/InputMode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Oxide.Ext.UiFramework.Enums;
4 |
5 | [Flags]
6 | public enum InputMode : byte
7 | {
8 | Default = 0,
9 | ReadOnly = 1 << 0,
10 | NeedsKeyboard = 1 << 1,
11 | HudNeedsKeyboard = 1 << 2,
12 | Password = 1 << 3,
13 | AutoFocus = 1 << 4
14 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Enums/NumberPickerMode.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Enums;
2 |
3 | public enum NumberPickerMode
4 | {
5 | LeftRight,
6 | UpDown
7 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Enums/PopoverPosition.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Enums;
2 |
3 | public enum PopoverPosition
4 | {
5 | Top,
6 | Left,
7 | Right,
8 | Bottom
9 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Enums/ScrollbarDirection.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Enums;
2 |
3 | public enum ScrollbarDirection
4 | {
5 | Vertical,
6 | Horizontal
7 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Enums/TimePickerDisplayMode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Oxide.Ext.UiFramework.Enums;
4 |
5 | [Flags]
6 | public enum TimePickerDisplayMode : byte
7 | {
8 | Hours = 1 << 0,
9 | Minutes = 1 << 1,
10 | Seconds = 1 << 2,
11 | HoursMinutes = Hours | Minutes,
12 | All = Hours | Minutes | Seconds
13 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Enums/TimerFormat.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Enums;
2 |
3 | public enum TimerFormat
4 | {
5 | None,
6 | SecondsHundreth,
7 | MinutesSeconds,
8 | MinutesSecondsHundreth,
9 | HoursMinutes,
10 | HoursMinutesSeconds,
11 | HoursMinutesSecondsMilliseconds,
12 | HoursMinutesSecondsTenths,
13 | DaysHoursMinutes,
14 | DaysHoursMinutesSeconds,
15 | Custom
16 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Enums/UiFont.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Enums;
2 |
3 | public enum UiFont : byte
4 | {
5 | ///
6 | /// droidsansmono.ttf
7 | ///
8 | DroidSansMono,
9 |
10 | ///
11 | /// permanentmarker.ttf
12 | ///
13 | PermanentMarker,
14 |
15 | ///
16 | /// robotocondensed-bold.ttf
17 | ///
18 | RobotoCondensedBold,
19 |
20 | ///
21 | /// robotocondensed-regular.ttf
22 | ///
23 | RobotoCondensedRegular,
24 |
25 | ///
26 | /// PressStart2P-Regular.ttf
27 | ///
28 | PressStart2PRegular
29 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Enums/UiLayer.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Enums;
2 |
3 | public enum UiLayer : byte
4 | {
5 | Overall,
6 | Overlay,
7 | OverlayNonScaled,
8 | HudMenu,
9 | Hud,
10 | Under,
11 | UnderNonScaled,
12 | Inventory,
13 | Crafting,
14 | Contacts,
15 | Clans,
16 | TechTree,
17 | Map,
18 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Exceptions/UiFrameworkException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Oxide.Ext.UiFramework.Exceptions;
4 |
5 | public class UiFrameworkException : Exception
6 | {
7 | public UiFrameworkException(string message) : base(message) { }
8 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Exceptions/UiReferenceException.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.UiElements;
2 |
3 | namespace Oxide.Ext.UiFramework.Exceptions;
4 |
5 | public class UiReferenceException : UiFrameworkException
6 | {
7 | private UiReferenceException(string message) : base(message) { }
8 |
9 | public static void ThrowIfInvalidParent(in UiReference reference)
10 | {
11 | if (!reference.IsValidParent()) throw new UiReferenceException($"{nameof(UiReference)} parent is not a valid parent reference value. Parent: {reference.Parent}");
12 | }
13 |
14 | public static void ThrowIfInvalidReference(in UiReference reference)
15 | {
16 | if (!reference.IsValidParent()) throw new UiReferenceException($"{nameof(UiReference)} parent is not a valid reference value. Parent: {reference.Parent} Name: {reference.Name}");
17 | }
18 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Extension/Carbon/CarbonExtension.cs:
--------------------------------------------------------------------------------
1 | #if CARBON
2 | using System;
3 | using API.Assembly;
4 | using Carbon;
5 |
6 | namespace Oxide.Ext.UiFramework
7 | {
8 | public class CarbonExtension : ICarbonExtension
9 | {
10 | public void Awake(EventArgs args)
11 | {
12 | Logger.Log("Carbon.Ext.UiFramework Awake");
13 | }
14 |
15 | public void OnLoaded(EventArgs args)
16 | {
17 | Logger.Log("Carbon.Ext.UiFramework Loaded");
18 | }
19 |
20 | public void OnUnloaded(EventArgs args)
21 | {
22 | Logger.Log("Carbon.Ext.UiFramework Unloaded");
23 | }
24 | }
25 | }
26 | #endif
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Extension/Oxide/UiFrameworkExtension.cs:
--------------------------------------------------------------------------------
1 | #if OXIDE
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 | using Oxide.Core;
5 | using Oxide.Core.Extensions;
6 |
7 | // ReSharper disable once CheckNamespace
8 | namespace Oxide.Ext.UiFramework;
9 |
10 | public class UiFrameworkExtension : Extension
11 | {
12 | public override string Name => "UiFramework";
13 | public override string Author => "MJSU";
14 | public override VersionNumber Version { get; }
15 |
16 | public UiFrameworkExtension(ExtensionManager manager) : base(manager)
17 | {
18 | AssemblyName assembly = Assembly.GetExecutingAssembly().GetName();
19 | Version = new VersionNumber(assembly.Version.Major, assembly.Version.Minor, assembly.Version.Build);
20 | }
21 |
22 | public override IEnumerable GetPreprocessorDirectives()
23 | {
24 | string name = Name.ToUpper();
25 | yield return $"{name}_EXT";
26 | for (int i = 0; i <= Version.Minor; i++)
27 | {
28 | yield return $"{name}_EXT_{Version.Major}_{i}";
29 | }
30 | }
31 | }
32 | #endif
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Extensions/ArgExt.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Oxide.Ext.UiFramework.UiElements;
3 |
4 | namespace Oxide.Ext.UiFramework.Extensions;
5 |
6 | public static class ArgExt
7 | {
8 | public static DateTime GetDateTime(this ConsoleSystem.Arg arg, int iArg, DateTime def)
9 | {
10 | string s = arg.GetString(iArg, null);
11 | if (string.IsNullOrEmpty(s))
12 | {
13 | return def;
14 | }
15 |
16 | DateTime date = DateTime.Parse(s);
17 | return date;
18 | }
19 |
20 | public static UiReference GetParentReference(this ConsoleSystem.Arg arg, int iArg)
21 | {
22 | string s = arg.GetString(iArg);
23 | return new UiReference(s, null);
24 | }
25 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Extensions/OxideCuiExt.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Network;
3 | using Oxide.Ext.UiFramework.Builder;
4 | using Oxide.Ext.UiFramework.Builders;
5 | using Oxide.Ext.UiFramework.Threading;
6 | using Oxide.Game.Rust.Cui;
7 |
8 | namespace Oxide.Ext.UiFramework.Extensions;
9 |
10 | public static class OxideCuiExt
11 | {
12 | public static void AddUiAsync(this CuiElementContainer container, BasePlayer player, string destroyUiName = null)
13 | {
14 | SendInfo send = SendInfoBuilder.Get(player);
15 | AddUiAsync(container, send, destroyUiName);
16 | }
17 |
18 | public static void AddUiAsync(this CuiElementContainer container, Connection connection, string destroyUiName = null)
19 | {
20 | SendInfo send = SendInfoBuilder.Get(connection);
21 | AddUiAsync(container, send, destroyUiName);
22 | }
23 |
24 | public static void AddUiAsync(this CuiElementContainer container, IEnumerable connections, string destroyUiName = null)
25 | {
26 | SendInfo send = SendInfoBuilder.Get(connections);
27 | AddUiAsync(container, send, destroyUiName);
28 | }
29 |
30 | public static void AddUiAsync(this CuiElementContainer container, string destroyUiName = null)
31 | {
32 | SendInfo send = SendInfoBuilder.Get(Net.sv.connections);
33 | AddUiAsync(container, send, destroyUiName);
34 | }
35 |
36 | public static void AddUiAsync(this CuiElementContainer container, SendInfo send, string destroyUiName = null)
37 | {
38 | OxideCuiRequest request = OxideCuiRequest.Create(container, send, destroyUiName);
39 | SendHandler.Enqueue(request);
40 | }
41 |
42 | public static void DestroyUi(Connection connection, string destroyUiName = null)
43 | {
44 | SendInfo send = SendInfoBuilder.Get(connection);
45 | DestroyUi(send, destroyUiName);
46 | }
47 |
48 | public static void DestroyUi(IEnumerable connections, string destroyUiName = null)
49 | {
50 | SendInfo send = SendInfoBuilder.Get(connections);
51 | DestroyUi(send, destroyUiName);
52 | }
53 |
54 | public static void DestroyUi(string destroyUiName = null)
55 | {
56 | SendInfo send = SendInfoBuilder.Get(Net.sv.connections);
57 | DestroyUi(send, destroyUiName);
58 | }
59 |
60 | public static void DestroyUi(SendInfo send, string destroyUiName)
61 | {
62 | BaseBuilder.DestroyUi(send, destroyUiName);
63 | }
64 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Extensions/StringBuilderExt.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Oxide.Ext.UiFramework.Pooling;
3 |
4 | namespace Oxide.Ext.UiFramework.Extensions;
5 |
6 | public static class StringBuilderExt
7 | {
8 | ///
9 | /// Frees a back to the pool returning the created
10 | ///
11 | /// with string and being freed
12 | public static string ToStringAndFree(this StringBuilder sb)
13 | {
14 | string result = sb.ToString();
15 | UiFrameworkPool.FreeStringBuilder(sb);
16 | return result;
17 | }
18 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Extensions/TypeExt.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using System.Text;
4 | using Oxide.Ext.UiFramework.Pooling;
5 |
6 | namespace Oxide.Ext.UiFramework.Extensions;
7 |
8 | ///
9 | /// Extensions for
10 | ///
11 | internal static class TypeExt
12 | {
13 | ///
14 | /// Returns if the type is
15 | ///
16 | /// Type to check
17 | /// True if type is ; false otherwise
18 | public static bool IsNullable(this Type objectType) => objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(Nullable<>);
19 |
20 | ///
21 | /// Returns if the type is
22 | ///
23 | /// Type to check
24 | /// True if type is ; false otherwise
25 | public static Type GetNullableType(this Type objectType) => Nullable.GetUnderlyingType(objectType);
26 |
27 | ///
28 | /// Returns if a type is a value type
29 | ///
30 | ///
31 | ///
32 | public static bool IsValueType(this Type source) => source.IsValueType;
33 |
34 | ///
35 | /// Returns the default value for
36 | ///
37 | /// Type to get default value for
38 | /// default value for
39 | public static object GetDefault(this Type type) => type.IsValueType ? Activator.CreateInstance(type) : null;
40 |
41 | internal static T GetAttribute(this Type type, bool inherit) where T : Attribute => type.GetCustomAttribute(typeof(T), inherit) as T;
42 | internal static bool HasAttribute(this Type type, bool inherit) where T : Attribute => GetAttribute(type, inherit) != null;
43 |
44 | public static string GetRealTypeName(this Type t)
45 | {
46 | if (!t.IsGenericType)
47 | {
48 | return t.Name;
49 | }
50 |
51 | StringBuilder sb = StringBuilderPool.Instance.Get();
52 | sb.Append(t.Name.AsSpan().Slice(0, t.Name.IndexOf('`')));
53 | sb.Append('<');
54 | Type[] args = t.GetGenericArguments();
55 | for (int index = 0; index < args.Length; index++)
56 | {
57 | Type arg = args[index];
58 | if (index != 0)
59 | {
60 | sb.Append(',');
61 | }
62 | sb.Append(GetRealTypeName(arg));
63 | }
64 | sb.Append('>');
65 | string type = sb.ToString();
66 | StringBuilderPool.Instance.Free(sb);
67 | return type;
68 | }
69 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Extensions/UiColorExt.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using Oxide.Ext.UiFramework.Colors;
3 | using UnityEngine;
4 |
5 | namespace Oxide.Ext.UiFramework.Extensions;
6 |
7 | public static class UiColorExt
8 | {
9 | public static UiColor WithAlpha(this UiColor color, byte alpha)
10 | {
11 | return new UiColor(color._red, color._green, color._blue, alpha);
12 | }
13 |
14 | public static UiColor WithAlpha(this UiColor color, string hex)
15 | {
16 | return color.WithAlpha(byte.Parse(hex, NumberStyles.HexNumber));
17 | }
18 |
19 | public static UiColor WithAlpha(this UiColor color, int alpha)
20 | {
21 | return color.WithAlpha((byte)alpha);
22 | }
23 |
24 | public static UiColor WithAlpha(this UiColor color, float alpha)
25 | {
26 | return color.WithAlpha((byte)Mathf.Clamp(alpha * 255f, 0, byte.MaxValue));
27 | }
28 |
29 | public static UiColor MultiplyAlpha(this UiColor color, float alpha)
30 | {
31 | return color.WithAlpha((byte)Mathf.Clamp(color._alpha * alpha, 0, byte.MaxValue));
32 | }
33 |
34 | public static UiColor ToGrayScale(this UiColor color)
35 | {
36 | float scale = ((Color)color).grayscale;
37 | return new UiColor(new Color(scale, scale, scale));
38 | }
39 |
40 | public static UiColor Darken(this UiColor color, float percentage)
41 | {
42 | percentage = Mathf.Clamp01(percentage);
43 | byte red = (byte)Mathf.Clamp(color._red * (1 - percentage), 0, byte.MaxValue);
44 | byte green = (byte)Mathf.Clamp(color._green * (1 - percentage), 0, byte.MaxValue);
45 | byte blue = (byte)Mathf.Clamp(color._blue * (1 - percentage), 0, byte.MaxValue);
46 |
47 | return new UiColor(red, green, blue, color._alpha);
48 | }
49 |
50 | public static UiColor Lighten(this UiColor color, float percentage)
51 | {
52 | percentage = Mathf.Clamp01(percentage);
53 | float red = (byte)Mathf.Clamp(byte.MaxValue - color._red * percentage + color._red, 0, byte.MaxValue);
54 | float green = (byte)Mathf.Clamp(byte.MaxValue - color._green * percentage + color._red, 0, byte.MaxValue);
55 | float blue = (byte)Mathf.Clamp(byte.MaxValue - color._blue * percentage + color._red, 0, byte.MaxValue);
56 |
57 | return new UiColor(red, green, blue, color._alpha);
58 | }
59 |
60 | public static UiColor Lerp(this UiColor start, UiColor end, float value)
61 | {
62 | return new UiColor(start._red + (end._red - start._red) * value, start._green + (end._green - start._green) * value, start._blue + (end._blue - start._blue) * value, start._alpha + (end._alpha - start._alpha) * value);
63 | }
64 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Extensions/UiReferenceExt.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.UiElements;
2 |
3 | namespace Oxide.Ext.UiFramework.Extensions;
4 |
5 | public static class UiReferenceExt
6 | {
7 | public static UiReference WithName(in this UiReference element, string name) => new(element.Parent, name);
8 | public static UiReference WithParent(in this UiReference element, string parent) => new(parent, element.Name);
9 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Helpers/GenericMath.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Oxide.Ext.UiFramework.Exceptions;
3 |
4 | namespace Oxide.Ext.UiFramework.Helpers;
5 |
6 | public static class GenericMath
7 | {
8 | public static T Add(T left, T right) where T : struct
9 | {
10 | Type type = typeof(T);
11 | if (type == typeof(int)) return GenericsUtil.Cast( GenericsUtil.Cast(left) + GenericsUtil.Cast(right));
12 | if (type == typeof(float)) return GenericsUtil.Cast( GenericsUtil.Cast(left) + GenericsUtil.Cast(right));
13 | if (type == typeof(double)) return GenericsUtil.Cast( GenericsUtil.Cast(left) + GenericsUtil.Cast(right));
14 | if (type == typeof(long)) return GenericsUtil.Cast( GenericsUtil.Cast(left) + GenericsUtil.Cast(right));
15 | if (type == typeof(uint)) return GenericsUtil.Cast( GenericsUtil.Cast(left) + GenericsUtil.Cast(right));
16 | if (type == typeof(ulong)) return GenericsUtil.Cast( GenericsUtil.Cast(left) + GenericsUtil.Cast(right));
17 |
18 | throw new UiFrameworkException($"{typeof(T).Name} is not a supported numeric type");
19 | }
20 |
21 | public static T Subtract(T left, T right) where T : struct
22 | {
23 | Type type = typeof(T);
24 | if (type == typeof(int)) return GenericsUtil.Cast( GenericsUtil.Cast(left) - GenericsUtil.Cast(right));
25 | if (type == typeof(float)) return GenericsUtil.Cast( GenericsUtil.Cast(left) - GenericsUtil.Cast(right));
26 | if (type == typeof(double)) return GenericsUtil.Cast( GenericsUtil.Cast(left) - GenericsUtil.Cast(right));
27 | if (type == typeof(long)) return GenericsUtil.Cast( GenericsUtil.Cast(left) - GenericsUtil.Cast(right));
28 | if (type == typeof(uint)) return GenericsUtil.Cast( GenericsUtil.Cast(left) - GenericsUtil.Cast(right));
29 | if (type == typeof(ulong)) return GenericsUtil.Cast( GenericsUtil.Cast(left) - GenericsUtil.Cast(right));
30 |
31 | throw new UiFrameworkException($"{typeof(T).Name} is not a supported numeric type");
32 | }
33 |
34 | public static T Multiply(T left, T right) where T : struct
35 | {
36 | Type type = typeof(T);
37 | if (type == typeof(int)) return GenericsUtil.Cast( GenericsUtil.Cast(left) * GenericsUtil.Cast(right));
38 | if (type == typeof(float)) return GenericsUtil.Cast( GenericsUtil.Cast(left) * GenericsUtil.Cast(right));
39 | if (type == typeof(double)) return GenericsUtil.Cast( GenericsUtil.Cast(left) * GenericsUtil.Cast(right));
40 | if (type == typeof(long)) return GenericsUtil.Cast( GenericsUtil.Cast(left) * GenericsUtil.Cast(right));
41 | if (type == typeof(uint)) return GenericsUtil.Cast( GenericsUtil.Cast(left) * GenericsUtil.Cast(right));
42 | if (type == typeof(ulong)) return GenericsUtil.Cast( GenericsUtil.Cast(left) * GenericsUtil.Cast(right));
43 |
44 | throw new UiFrameworkException($"{typeof(T).Name} is not a supported numeric type");
45 | }
46 |
47 | public static T Divide(T left, T right) where T : struct
48 | {
49 | Type type = typeof(T);
50 | if (type == typeof(int)) return GenericsUtil.Cast( GenericsUtil.Cast(left) / GenericsUtil.Cast(right));
51 | if (type == typeof(float)) return GenericsUtil.Cast( GenericsUtil.Cast(left) / GenericsUtil.Cast(right));
52 | if (type == typeof(double)) return GenericsUtil.Cast( GenericsUtil.Cast(left) / GenericsUtil.Cast(right));
53 | if (type == typeof(long)) return GenericsUtil.Cast( GenericsUtil.Cast(left) / GenericsUtil.Cast(right));
54 | if (type == typeof(uint)) return GenericsUtil.Cast( GenericsUtil.Cast(left) / GenericsUtil.Cast(right));
55 | if (type == typeof(ulong)) return GenericsUtil.Cast( GenericsUtil.Cast(left) / GenericsUtil.Cast(right));
56 |
57 | throw new UiFrameworkException($"{typeof(T).Name} is not a supported numeric type");
58 | }
59 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Json/JsonBinaryWriter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Buffers;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Runtime.CompilerServices;
6 | using System.Text;
7 | using Network;
8 | using Oxide.Ext.UiFramework.Benchmarks;
9 | using Oxide.Ext.UiFramework.Pooling;
10 |
11 | namespace Oxide.Ext.UiFramework.Json;
12 |
13 | public class JsonBinaryWriter : BasePoolable
14 | {
15 | private const int SegmentSize = 4096;
16 |
17 | private readonly List> _segments = new(100);
18 | private short _charIndex;
19 | private readonly char[] _charBuffer = new char[SegmentSize * 2];
20 |
21 | public void Write(char character)
22 | {
23 | _charBuffer[_charIndex] = character;
24 | _charIndex++;
25 | if (_charIndex >= SegmentSize)
26 | {
27 | Flush();
28 | }
29 | }
30 |
31 | public void Write(ReadOnlySpan text)
32 | {
33 | int length = text.Length;
34 | Span buffer = _charBuffer.AsSpan();
35 | int charIndex = _charIndex;
36 | for (int i = 0; i < length; i++)
37 | {
38 | buffer[charIndex + i] = text[i];
39 | }
40 | _charIndex += (short)length;
41 | if (_charIndex >= SegmentSize)
42 | {
43 | Flush();
44 | }
45 | }
46 |
47 | private void Flush()
48 | {
49 | if (_charIndex == 0)
50 | {
51 | return;
52 | }
53 |
54 | byte[] segment = ArrayPool.Shared.Rent(SegmentSize * 2);
55 |
56 | int size = Encoding.UTF8.GetBytes(_charBuffer, 0, _charIndex, segment, 0);
57 | _segments.Add(new SizedArray(segment, size));
58 | _charIndex = 0;
59 | }
60 |
61 | public int WriteToArray(byte[] bytes)
62 | {
63 | Flush();
64 | int writeIndex = 0;
65 | for (int i = 0; i < _segments.Count; i++)
66 | {
67 | SizedArray segment = _segments[i];
68 | Buffer.BlockCopy(segment.Array, 0, bytes, writeIndex, segment.Size);
69 | writeIndex += segment.Size;
70 | }
71 |
72 | return writeIndex;
73 | }
74 |
75 | public uint GetSize()
76 | {
77 | uint size = 0;
78 | int count = _segments.Count;
79 | for (int i = 0; i < count; i++)
80 | {
81 | size += (uint)_segments[i].Size;
82 | }
83 |
84 | return size;
85 | }
86 |
87 | public void WriteToNetwork(NetWrite write)
88 | {
89 | Flush();
90 | write.UInt32(GetSize());
91 | WriteToNetwork((Stream)write);
92 | }
93 |
94 | #if BENCHMARKS
95 | internal void WriteToNetwork(BenchmarkNetWrite write)
96 | {
97 | Flush();
98 | WriteToNetwork((Stream)write);
99 | }
100 | #endif
101 |
102 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
103 | private void WriteToNetwork(Stream write)
104 | {
105 | int count = _segments.Count;
106 | for (int i = 0; i < count; i++)
107 | {
108 | SizedArray segment = _segments[i];
109 | write.Write(segment.Array, 0, segment.Size);
110 | }
111 | }
112 |
113 | public byte[] ToArray()
114 | {
115 | Flush();
116 | byte[] bytes = new byte[GetSize()];
117 | WriteToArray(bytes);
118 | return bytes;
119 | }
120 |
121 | protected override void LeavePool()
122 | {
123 |
124 | }
125 |
126 | protected override void EnterPool()
127 | {
128 | for (int index = 0; index < _segments.Count; index++)
129 | {
130 | byte[] bytes = _segments[index].Array;
131 | ArrayPool.Shared.Return(bytes);
132 | }
133 | _segments.Clear();
134 | _charIndex = 0;
135 | }
136 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Json/SizedArray.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Json;
2 |
3 | public readonly struct SizedArray
4 | {
5 | public readonly T[] Array;
6 | public readonly int Size;
7 |
8 | public SizedArray(T[] array, int size)
9 | {
10 | Array = array;
11 | Size = size;
12 | }
13 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Offsets/BaseOffset.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Offsets;
2 |
3 | public abstract class BaseOffset
4 | {
5 | public float XMin;
6 | public float YMin;
7 | public float XMax;
8 | public float YMax;
9 | private readonly UiOffset _initialState;
10 |
11 | protected BaseOffset(float xMin, float yMin, float xMax, float yMax)
12 | {
13 | XMin = xMin;
14 | YMin = yMin;
15 | XMax = xMin + xMax;
16 | YMax = yMin + yMax;
17 | _initialState = new UiOffset(XMin, YMin, XMax, YMax);
18 | }
19 |
20 | public UiOffset ToOffset()
21 | {
22 | return new UiOffset(XMin, YMin, XMax, YMax);
23 | }
24 |
25 | public void Reset()
26 | {
27 | XMin = _initialState.Min.x;
28 | YMin = _initialState.Min.y;
29 | XMax = _initialState.Max.x;
30 | YMax = _initialState.Max.y;
31 | }
32 |
33 | public static implicit operator UiOffset(BaseOffset offset) => offset.ToOffset();
34 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Offsets/GridOffset.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Offsets;
2 |
3 | public class GridOffset : BaseOffset
4 | {
5 | public readonly int NumCols;
6 | public readonly int NumRows;
7 | public readonly float Width;
8 | public readonly float Height;
9 |
10 | public GridOffset(float xMin, float yMin, float xMax, float yMax, int numCols, int numRows, float width, float height) : base(xMin, yMin, xMax, yMax)
11 | {
12 | NumCols = numCols;
13 | NumRows = numRows;
14 | Width = width;
15 | Height = height;
16 | }
17 |
18 | public void MoveCols(int cols)
19 | {
20 | MoveCols((float)cols);
21 | }
22 |
23 | public void MoveCols(float cols)
24 | {
25 | float distance = cols / NumCols * Width;
26 | XMin += distance;
27 | XMax += distance;
28 |
29 | if (XMax > Width)
30 | {
31 | XMin -= Width;
32 | XMax -= Width;
33 | MoveRows(1);
34 | }
35 | }
36 |
37 | public void MoveRows(int rows)
38 | {
39 | float distance = rows / (float)NumRows * Height;
40 | YMin -= distance;
41 | YMax -= distance;
42 | }
43 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Offsets/GridOffsetBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Oxide.Ext.UiFramework.Offsets;
4 |
5 | public class GridOffsetBuilder
6 | {
7 | private readonly int _numCols;
8 | private readonly int _numRows;
9 | private readonly UiOffset _area;
10 | private readonly float _width;
11 | private readonly float _height;
12 | private int _rowHeight = 1;
13 | private int _rowOffset;
14 | private int _colWidth = 1;
15 | private int _colOffset;
16 | private int _xPad;
17 | private int _yPad;
18 |
19 | public GridOffsetBuilder(int size, UiOffset area) : this(size, size, area)
20 | {
21 |
22 | }
23 |
24 | public GridOffsetBuilder(int numCols, int numRows, UiOffset area)
25 | {
26 | if (numCols <= 0) throw new ArgumentOutOfRangeException(nameof(numCols));
27 | if (numRows <= 0) throw new ArgumentOutOfRangeException(nameof(numCols));
28 | _numCols = numCols;
29 | _numRows = numRows;
30 | _area = area;
31 | _width = area.Max.x - area.Min.x;
32 | _height = area.Max.y - area.Min.y;
33 | }
34 |
35 | public GridOffsetBuilder SetRowHeight(int height)
36 | {
37 | if (height <= 0) throw new ArgumentOutOfRangeException(nameof(height));
38 | _rowHeight = height;
39 | return this;
40 | }
41 |
42 | public GridOffsetBuilder SetRowOffset(int offset)
43 | {
44 | if (offset < 0) throw new ArgumentOutOfRangeException(nameof(offset));
45 | _rowOffset = offset;
46 | return this;
47 | }
48 |
49 | public GridOffsetBuilder SetColWidth(int width)
50 | {
51 | if (width <= 0) throw new ArgumentOutOfRangeException(nameof(width));
52 | _colWidth = width;
53 | return this;
54 | }
55 |
56 | public GridOffsetBuilder SetColOffset(int offset)
57 | {
58 | if (offset < 0) throw new ArgumentOutOfRangeException(nameof(offset));
59 | _colOffset = offset;
60 | return this;
61 | }
62 |
63 | public GridOffsetBuilder SetPadding(int padding)
64 | {
65 | _xPad = padding;
66 | _yPad = padding;
67 | return this;
68 | }
69 |
70 | public GridOffsetBuilder SetPadding(int xPad, int yPad)
71 | {
72 | _xPad = xPad;
73 | _yPad = yPad;
74 | return this;
75 | }
76 |
77 | public GridOffsetBuilder SetRowPadding(int padding)
78 | {
79 | _xPad = padding;
80 | return this;
81 | }
82 |
83 | public GridOffsetBuilder SetColPadding(int padding)
84 | {
85 | _yPad = padding;
86 | return this;
87 | }
88 |
89 | public GridOffset Build()
90 | {
91 | float xMin = _area.Min.x;
92 | float yMin = _area.Max.y - _rowHeight / (float)_numRows * _height;
93 | float xMax = _colWidth / (float)_numCols * _width;
94 | float yMax = _rowHeight / (float)_numRows * _height;
95 |
96 | if (_colOffset != 0)
97 | {
98 | int size = (int)(_colOffset / (float)_numCols * _width);
99 | xMin += size;
100 | xMax += size;
101 | }
102 |
103 | if (_rowOffset != 0)
104 | {
105 | int size = (int)(_rowOffset / (float)_numRows * _height);
106 | yMin += size;
107 | yMax += size;
108 | }
109 |
110 | xMin += _xPad;
111 | xMax -= _xPad * 2;
112 | yMin += _yPad;
113 | yMax -= _yPad * 2;
114 |
115 | return new GridOffset(xMin, yMin, xMax, yMax, _numCols, _numRows, _width, _height);
116 | }
117 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Offsets/UiOffset.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Oxide.Ext.UiFramework.Offsets;
4 |
5 | public readonly struct UiOffset
6 | {
7 | public static readonly UiOffset None = new(0, 0, 0, 0);
8 | public static readonly UiOffset Scaled = new(1280, 720);
9 |
10 | public readonly Vector2 Min;
11 | public readonly Vector2 Max;
12 |
13 | public Vector2 Size => Max - Min;
14 | public float Width => Max.x - Min.x;
15 | public float Height => Max.y - Min.y;
16 |
17 | public UiOffset(int width, int height) : this(-width / 2f, -height / 2f, width / 2f, height / 2f) { }
18 |
19 | public UiOffset(float xMin, float yMin, float xMax, float yMax)
20 | {
21 | Min = new Vector2(xMin, yMin);
22 | Max = new Vector2(xMax, yMax);
23 | }
24 |
25 | public static UiOffset CreateRect(int x, int y, int width, int height)
26 | {
27 | return new UiOffset(x, y, x + width, y + height);
28 | }
29 |
30 | public override string ToString()
31 | {
32 | return $"({Min.x:0}, {Min.y:0}) ({Max.x:0}, {Max.y:0}) WxH:({Width} x {Height})";
33 | }
34 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Pooling/BasePool.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Pooling;
2 |
3 | ///
4 | /// Represents a BasePool in UiFramework
5 | ///
6 | /// Type being pooled
7 | public abstract class BasePool : IPool where T : class
8 | {
9 | private readonly T[] _pool;
10 | private readonly object _lock = new();
11 | private int _index;
12 |
13 | ///
14 | /// Base Pool Constructor
15 | ///
16 | /// Max Size of the pool
17 | protected BasePool(int maxSize)
18 | {
19 | _pool = new T[maxSize];
20 | UiFrameworkPool.AddPool(this);
21 | }
22 |
23 | ///
24 | /// Returns an element from the pool if it exists else it creates a new one
25 | ///
26 | ///
27 | public T Get()
28 | {
29 | T item = null;
30 |
31 | lock (_lock)
32 | {
33 | if (_index < _pool.Length)
34 | {
35 | item = _pool[_index];
36 | _pool[_index] = null;
37 | _index++;
38 | }
39 | }
40 |
41 | item ??= CreateNew();
42 | OnGetItem(item);
43 | return item;
44 | }
45 |
46 | ///
47 | /// Creates new type of T
48 | ///
49 | /// Newly created type of T
50 | protected abstract T CreateNew();
51 |
52 | ///
53 | /// Frees an item back to the pool
54 | ///
55 | /// Item being freed
56 | public void Free(T item) => Free(ref item);
57 |
58 | ///
59 | /// Frees an item back to the pool
60 | ///
61 | /// Item being freed
62 | private void Free(ref T item)
63 | {
64 | if (item == null)
65 | {
66 | return;
67 | }
68 |
69 | if (!OnFreeItem(ref item))
70 | {
71 | return;
72 | }
73 |
74 | lock (_lock)
75 | {
76 | if (_index != 0)
77 | {
78 | _index--;
79 | _pool[_index] = item;
80 | }
81 | }
82 |
83 | item = null;
84 | }
85 |
86 | ///
87 | /// Called when an item is retrieved from the pool
88 | ///
89 | /// Item being retrieved
90 | protected virtual void OnGetItem(T item) { }
91 |
92 | ///
93 | /// Returns if an item can be freed to the pool
94 | ///
95 | /// Item to be freed
96 | /// True if can be freed; false otherwise
97 | protected virtual bool OnFreeItem(ref T item) => true;
98 |
99 | public void Clear()
100 | {
101 | lock (_lock)
102 | {
103 | for (int index = 0; index < _pool.Length; index++)
104 | {
105 | _pool[index] = null;
106 | _index = 0;
107 | }
108 | }
109 | }
110 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Pooling/BasePoolable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Oxide.Ext.UiFramework.Pooling;
4 |
5 | ///
6 | /// Represents a poolable object
7 | ///
8 | public abstract class BasePoolable : IDisposable
9 | {
10 | internal bool Disposed;
11 |
12 | ///
13 | /// Returns if the object should be pooled.
14 | /// This field is set to true when leaving the pool.
15 | /// If the object instantiated using new() outside the pool it will be false
16 | ///
17 | private bool _shouldPool;
18 | private IPool _pool;
19 |
20 | internal void OnInit(IPool pool)
21 | {
22 | _pool = pool;
23 | }
24 |
25 | internal void EnterPoolInternal()
26 | {
27 | EnterPool();
28 | _shouldPool = false;
29 | Disposed = true;
30 | }
31 |
32 | internal void LeavePoolInternal()
33 | {
34 | _shouldPool = true;
35 | Disposed = false;
36 | LeavePool();
37 | }
38 |
39 | ///
40 | /// Called when the object is returned to the pool.
41 | /// Can be overriden in child classes to cleanup used data
42 | ///
43 | protected virtual void EnterPool()
44 | {
45 |
46 | }
47 |
48 | ///
49 | /// Called when the object leaves the pool.
50 | /// Can be overriden in child classes to set the initial object state
51 | ///
52 | protected virtual void LeavePool()
53 | {
54 |
55 | }
56 |
57 | public virtual void Dispose()
58 | {
59 | if (!_shouldPool)
60 | {
61 | return;
62 | }
63 |
64 | if (Disposed)
65 | {
66 | throw new ObjectDisposedException(GetType().Name);
67 | }
68 |
69 | _pool.Free(this);
70 | }
71 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Pooling/HashPool.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Plugins;
2 |
3 | namespace Oxide.Ext.UiFramework.Pooling;
4 |
5 | ///
6 | /// Represents a pool for Hash<TKey, TValue>
7 | ///
8 | ///
9 | ///
10 | public class HashPool : BasePool>
11 | {
12 | public static readonly IPool> Instance;
13 |
14 | static HashPool()
15 | {
16 | Instance = new HashPool();
17 | }
18 |
19 | private HashPool() : base(128) { }
20 |
21 | protected override Hash CreateNew() => new();
22 |
23 | ///
24 | protected override bool OnFreeItem(ref Hash item)
25 | {
26 | item.Clear();
27 | return true;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Pooling/IPool.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Pooling;
2 |
3 | ///
4 | /// Represents a pool
5 | ///
6 | public interface IPool
7 | {
8 | void Clear();
9 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Pooling/IPool{T}.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Pooling;
2 |
3 | ///
4 | /// Represents a pool of type T
5 | ///
6 | /// Type to be pooled
7 | public interface IPool : IPool
8 | {
9 | ///
10 | /// Returns the Pooled type or a new instance if pool is empty.
11 | ///
12 | ///
13 | T Get();
14 |
15 | ///
16 | /// Returns the pooled type back to the pool
17 | ///
18 | ///
19 | void Free(T item);
20 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Pooling/ListPool.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Oxide.Ext.UiFramework.Pooling;
4 |
5 | ///
6 | /// Represents a pool for
7 | ///
8 | /// Type that will be in the list
9 | public class ListPool : BasePool>
10 | {
11 | public static readonly IPool> Instance;
12 |
13 | static ListPool()
14 | {
15 | Instance = new ListPool();
16 | }
17 |
18 | private ListPool() : base(128) { }
19 |
20 | protected override List CreateNew() => [];
21 |
22 | ///
23 | protected override bool OnFreeItem(ref List item)
24 | {
25 | item.Clear();
26 | return true;
27 | }
28 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Pooling/ObjectPool.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Pooling;
2 |
3 | public class ObjectPool : BasePool where T : BasePoolable, new()
4 | {
5 | public static readonly IPool Instance = new ObjectPool();
6 |
7 | private ObjectPool() : base(1024) { }
8 |
9 | protected override BasePoolable CreateNew()
10 | {
11 | T obj = new();
12 | obj.OnInit(this);
13 | return obj;
14 | }
15 |
16 | protected override void OnGetItem(BasePoolable item)
17 | {
18 | item.LeavePoolInternal();
19 | }
20 |
21 | protected override bool OnFreeItem(ref BasePoolable item)
22 | {
23 | if (item.Disposed)
24 | {
25 | return false;
26 | }
27 |
28 | item.EnterPoolInternal();
29 | return true;
30 | }
31 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Pooling/StringBuilderPool.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace Oxide.Ext.UiFramework.Pooling;
4 |
5 | ///
6 | /// Pool for StringBuilders
7 | ///
8 | public class StringBuilderPool : BasePool
9 | {
10 | public static readonly IPool Instance;
11 |
12 | static StringBuilderPool()
13 | {
14 | Instance = new StringBuilderPool();
15 | }
16 |
17 | private StringBuilderPool() : base(64) { }
18 |
19 | protected override StringBuilder CreateNew() => new();
20 |
21 | ///
22 | protected override bool OnFreeItem(ref StringBuilder item)
23 | {
24 | item.Length = 0;
25 | return true;
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Pooling/UiFrameworkPool.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Oxide.Plugins;
5 |
6 | namespace Oxide.Ext.UiFramework.Pooling;
7 |
8 | public static class UiFrameworkPool
9 | {
10 | private static readonly Hash Pools = new();
11 |
12 | ///
13 | /// Returns a pooled object of type T
14 | /// Must inherit from and have an empty default constructor
15 | ///
16 | /// Type to be returned
17 | /// Pooled object of type T
18 | public static T Get() where T : BasePoolable, new()
19 | {
20 | return (T)ObjectPool.Instance.Get();
21 | }
22 |
23 | ///
24 | /// Returns a back into the pool
25 | ///
26 | /// Object to free
27 | /// Type of object being freed
28 | internal static void Free(T value) where T : BasePoolable, new()
29 | {
30 | ObjectPool.Instance.Free(value);
31 | }
32 |
33 | ///
34 | /// Returns a pooled
35 | ///
36 | /// Type for the list
37 | /// Pooled List
38 | public static List GetList()
39 | {
40 | return ListPool.Instance.Get();
41 | }
42 |
43 | ///
44 | /// Returns a pooled
45 | ///
46 | /// Type for the key
47 | /// Type for the value
48 | /// Pooled Hash
49 | public static Hash GetHash()
50 | {
51 | return HashPool.Instance.Get();
52 | }
53 |
54 | ///
55 | /// Returns a pooled
56 | ///
57 | /// Pooled
58 | public static StringBuilder GetStringBuilder()
59 | {
60 | return StringBuilderPool.Instance.Get();
61 | }
62 |
63 | ///
64 | /// Free's a pooled
65 | ///
66 | /// List to be freed
67 | /// Type of the list
68 | public static void FreeList(List list)
69 | {
70 | ListPool.Instance.Free(list);
71 | }
72 |
73 | ///
74 | /// Frees a pooled
75 | ///
76 | /// Hash to be freed
77 | /// Type for key
78 | /// Type for value
79 | public static void FreeHash(Hash hash)
80 | {
81 | HashPool.Instance.Free(hash);
82 | }
83 |
84 | ///
85 | /// Frees a back to the pool
86 | ///
87 | /// StringBuilder being freed
88 | public static void FreeStringBuilder(StringBuilder sb)
89 | {
90 | StringBuilderPool.Instance.Free(sb);
91 | }
92 |
93 | public static void AddPool(BasePool pool) where TType : class
94 | {
95 | Pools[typeof(TType)] = pool;
96 | }
97 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Positions/BasePosition.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Positions;
2 |
3 | public abstract class BasePosition
4 | {
5 | public float XMin;
6 | public float YMin;
7 | public float XMax;
8 | public float YMax;
9 | protected readonly UiPosition InitialState;
10 |
11 | protected BasePosition(float xMin, float yMin, float xMax, float yMax)
12 | {
13 | XMin = xMin;
14 | YMin = yMin;
15 | XMax = xMax;
16 | YMax = yMax;
17 | InitialState = new UiPosition(XMin, YMin, XMax, YMax);
18 | }
19 |
20 | public UiPosition ToPosition()
21 | {
22 | return new UiPosition(XMin, YMin, XMax, YMax);
23 | }
24 |
25 | public void Reset()
26 | {
27 | XMin = InitialState.Min.x;
28 | YMin = InitialState.Min.y;
29 | XMax = InitialState.Max.x;
30 | YMax = InitialState.Max.y;
31 | }
32 |
33 | public override string ToString()
34 | {
35 | return $"{XMin.ToString()} {YMin.ToString()} {XMax.ToString()} {YMax.ToString()}";
36 | }
37 |
38 | public static implicit operator UiPosition(BasePosition pos) => pos.ToPosition();
39 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Positions/GridPosition.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.Positions;
2 |
3 | public class GridPosition : BasePosition
4 | {
5 | public readonly float NumCols;
6 | public readonly float NumRows;
7 |
8 | public GridPosition(float xMin, float yMin, float xMax, float yMax, float numCols, float numRows) : base(xMin, yMin, xMax, yMax)
9 | {
10 | NumCols = numCols;
11 | NumRows = numRows;
12 | }
13 |
14 | public void MoveCols(int cols)
15 | {
16 | XMin += cols / NumCols;
17 | XMax += cols / NumCols;
18 |
19 | if (XMax > 1)
20 | {
21 | XMin -= 1;
22 | XMax -= 1;
23 | MoveRows(1);
24 | }
25 | }
26 |
27 | public void MoveCols(float cols)
28 | {
29 | XMin += cols / NumCols;
30 | XMax += cols / NumCols;
31 |
32 | if (XMax > 1)
33 | {
34 | XMin -= 1;
35 | XMax -= 1;
36 | MoveRows(1);
37 | }
38 | }
39 |
40 | public void MoveRows(int rows)
41 | {
42 | YMin -= rows / NumRows;
43 | YMax -= rows / NumRows;
44 | }
45 |
46 | public float GetScrollViewYMin(int totalRows)
47 | {
48 | return InitialState.Min.y - (totalRows / NumRows);
49 | }
50 |
51 | public float GetScrollViewYMin(int count, int countPerRow)
52 | {
53 | int totalRows = count / countPerRow;
54 | if (count % countPerRow != 0)
55 | {
56 | totalRows++;
57 | }
58 |
59 | return GetScrollViewYMin(totalRows);
60 | }
61 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Positions/GridPositionBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Oxide.Ext.UiFramework.Positions;
4 |
5 | public class GridPositionBuilder
6 | {
7 | private readonly float _numCols;
8 | private readonly float _numRows;
9 | private int _rowHeight = 1;
10 | private int _rowOffset;
11 | private int _colWidth = 1;
12 | private int _colOffset;
13 | private float _xPad;
14 | private float _yPad;
15 |
16 | public GridPositionBuilder(int size) : this(size, size)
17 | {
18 | }
19 |
20 | public GridPositionBuilder(int numCols, int numRows)
21 | {
22 | if (numCols <= 0) throw new ArgumentOutOfRangeException(nameof(numCols));
23 | if (numRows <= 0) throw new ArgumentOutOfRangeException(nameof(numCols));
24 | _numCols = numCols;
25 | _numRows = numRows;
26 | }
27 |
28 | public GridPositionBuilder SetRowHeight(int height)
29 | {
30 | if (height <= 0) throw new ArgumentOutOfRangeException(nameof(height));
31 | _rowHeight = height;
32 | return this;
33 | }
34 |
35 | public GridPositionBuilder SetRowOffset(int offset)
36 | {
37 | if (offset < 0) throw new ArgumentOutOfRangeException(nameof(offset));
38 | _rowOffset = offset;
39 | return this;
40 | }
41 |
42 | public GridPositionBuilder SetColWidth(int width)
43 | {
44 | if (width <= 0) throw new ArgumentOutOfRangeException(nameof(width));
45 | _colWidth = width;
46 | return this;
47 | }
48 |
49 | public GridPositionBuilder SetColOffset(int offset)
50 | {
51 | if (offset < 0) throw new ArgumentOutOfRangeException(nameof(offset));
52 | _colOffset = offset;
53 | return this;
54 | }
55 |
56 | public GridPositionBuilder SetPadding(float padding)
57 | {
58 | _xPad = padding;
59 | _yPad = padding;
60 | return this;
61 | }
62 |
63 | public GridPositionBuilder SetPadding(float xPad, float yPad)
64 | {
65 | _xPad = xPad;
66 | _yPad = yPad;
67 | return this;
68 | }
69 |
70 | public GridPositionBuilder SetRowPadding(float padding)
71 | {
72 | _xPad = padding;
73 | return this;
74 | }
75 |
76 | public GridPositionBuilder SetColPadding(float padding)
77 | {
78 | _yPad = padding;
79 | return this;
80 | }
81 |
82 | public GridPosition Build()
83 | {
84 | float xMin = 0;
85 | float yMin = 1 - _rowHeight / _numRows;
86 | float xMax = _colWidth / _numCols;
87 | float yMax = 1;
88 |
89 | if (_colOffset != 0)
90 | {
91 | float size = _colOffset / _numCols;
92 | xMin += size;
93 | xMax += size;
94 | }
95 |
96 | if (_rowOffset != 0)
97 | {
98 | float size = _rowOffset / _numRows;
99 | yMin -= size;
100 | yMax -= size;
101 | }
102 |
103 | xMin += _xPad;
104 | xMax -= _xPad;
105 | yMin += _yPad;
106 | yMax -= _yPad;
107 |
108 | return new GridPosition(xMin, yMin, xMax, yMax, _numCols, _numRows);
109 | }
110 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Positions/UiPosition.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Extensions;
2 | using UnityEngine;
3 |
4 | namespace Oxide.Ext.UiFramework.Positions;
5 |
6 | public readonly struct UiPosition
7 | {
8 | public static readonly UiPosition None = new(0, 0, 0, 0);
9 | public static readonly UiPosition Full = new(0, 0, 1, 1);
10 | public static readonly UiPosition HorizontalPaddedFull = Full.SliceHorizontal(0.01f, 0.99f);
11 | public static readonly UiPosition VerticalPaddedFull = Full.SliceVertical(0.01f, 0.99f);
12 | public static readonly UiPosition TopLeft = new(0, 1, 0, 1);
13 | public static readonly UiPosition MiddleLeft = new(0, .5f, 0, .5f);
14 | public static readonly UiPosition BottomLeft = new(0, 0, 0, 0);
15 | public static readonly UiPosition TopMiddle = new(.5f, 1, .5f, 1);
16 | public static readonly UiPosition MiddleMiddle = new(.5f, .5f, .5f, .5f);
17 | public static readonly UiPosition BottomMiddle = new(.5f, 0, .5f, 0);
18 | public static readonly UiPosition TopRight = new(1, 1, 1, 1);
19 | public static readonly UiPosition MiddleRight = new(1, .5f, 1, .5f);
20 | public static readonly UiPosition BottomRight = new(1, 0, 1, 0);
21 |
22 | public static readonly UiPosition Top = new(0, 1, 1, 1);
23 | public static readonly UiPosition Bottom = new(0, 0, 1, 0);
24 | public static readonly UiPosition Left = new(0, 0, 0, 1);
25 | public static readonly UiPosition Right = new(1, 0, 1, 1);
26 |
27 | public static readonly UiPosition LeftHalf = new(0, 0, 0.5f, 1);
28 | public static readonly UiPosition TopHalf = new(0, 0.5f, 1, 1);
29 | public static readonly UiPosition RightHalf = new(0.5f, 0, 1, 1);
30 | public static readonly UiPosition BottomHalf = new(0, 0, 1, 0.5f);
31 |
32 | public readonly Vector2 Min;
33 | public readonly Vector2 Max;
34 |
35 | public UiPosition(float xMin, float yMin, float xMax, float yMax)
36 | {
37 | Min = new Vector2(xMin, yMin);
38 | Max = new Vector2(xMax, yMax);
39 | }
40 |
41 | public override string ToString()
42 | {
43 | return $"({Min.x:0.####}, {Min.y:0.####}) ({Max.x:0.####}, {Max.y:0.####})";
44 | }
45 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Threading/BaseUiRequest.cs:
--------------------------------------------------------------------------------
1 | using Network;
2 | using Oxide.Ext.UiFramework.Pooling;
3 |
4 | namespace Oxide.Ext.UiFramework.Threading;
5 |
6 | public abstract class BaseUiRequest : BasePoolable
7 | {
8 | protected SendInfo Send;
9 |
10 | protected void Init(SendInfo send)
11 | {
12 | Send = send;
13 | }
14 |
15 | protected override void EnterPool()
16 | {
17 | base.EnterPool();
18 | if (Send.connections != null)
19 | {
20 | ListPool.Instance.Free(Send.connections);
21 | }
22 | Send = default;
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Threading/IUiRequest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Oxide.Ext.UiFramework.Threading;
4 |
5 | public interface IUiRequest : IDisposable
6 | {
7 | public void SendUi();
8 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Threading/OxideCuiRequest.cs:
--------------------------------------------------------------------------------
1 | using Network;
2 | using Oxide.Ext.UiFramework.Pooling;
3 | using Oxide.Game.Rust.Cui;
4 |
5 | namespace Oxide.Ext.UiFramework.Threading;
6 |
7 | public class OxideCuiRequest : BaseUiRequest, IUiRequest
8 | {
9 | private CuiElementContainer _container;
10 | private string _destroyUiName;
11 |
12 | public static OxideCuiRequest Create(CuiElementContainer container, SendInfo send, string destroyUiName)
13 | {
14 | OxideCuiRequest request = UiFrameworkPool.Get();
15 | request.Init(container, send, destroyUiName);
16 | return request;
17 | }
18 |
19 | private void Init(CuiElementContainer container, SendInfo send, string destroyUiName)
20 | {
21 | base.Init(send);
22 | _container = container;
23 | _destroyUiName = destroyUiName;
24 | }
25 |
26 | public void SendUi()
27 | {
28 | if (!string.IsNullOrEmpty(_destroyUiName))
29 | {
30 | CommunityEntity.ServerInstance.ClientRPC(RpcTarget.SendInfo("DestroyUI", Send));
31 | }
32 | CommunityEntity.ServerInstance.ClientRPC(RpcTarget.SendInfo("AddUI", Send), _container.ToJson());
33 | }
34 |
35 | protected override void EnterPool()
36 | {
37 | base.EnterPool();
38 | _container = null;
39 | _destroyUiName = null;
40 | }
41 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Threading/SendHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Threading;
4 | using Oxide.Core;
5 |
6 | namespace Oxide.Ext.UiFramework.Threading;
7 |
8 | internal static class SendHandler
9 | {
10 | private static readonly ConcurrentQueue Queue = new();
11 | private static readonly AutoResetEvent Reset = new(false);
12 | private static readonly Thread _thread;
13 |
14 | static SendHandler()
15 | {
16 | _thread = new Thread(Send)
17 | {
18 | IsBackground = true,
19 | Name = $"UiFramework.{nameof(SendHandler)}",
20 | };
21 | _thread.Start();
22 | }
23 |
24 | internal static void Enqueue(IUiRequest request)
25 | {
26 | Queue.Enqueue(request);
27 | Reset.Set();
28 | }
29 |
30 | private static void Send()
31 | {
32 | while (true)
33 | {
34 | SendInternal();
35 | Reset.WaitOne();
36 | }
37 | }
38 |
39 | private static void SendInternal()
40 | {
41 | while (Queue.TryDequeue(out IUiRequest request))
42 | {
43 | try
44 | {
45 | #if !BENCHMARKS
46 | request.SendUi();
47 | #endif
48 | }
49 | catch (Exception ex)
50 | {
51 | Interface.Oxide.LogException("An error occured during UI Send", ex);
52 | }
53 | finally
54 | {
55 | request.Dispose();
56 | }
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/Threading/UiSendRequest.cs:
--------------------------------------------------------------------------------
1 | using Network;
2 | using Oxide.Ext.UiFramework.Builder;
3 | using Oxide.Ext.UiFramework.Pooling;
4 |
5 | namespace Oxide.Ext.UiFramework.Threading;
6 |
7 | internal class UiSendRequest : BaseUiRequest, IUiRequest
8 | {
9 | public BaseBuilder Builder;
10 |
11 | public static UiSendRequest Create(BaseBuilder builder, SendInfo send)
12 | {
13 | UiSendRequest request = UiFrameworkPool.Get();
14 | request.Init(builder, send);
15 | return request;
16 | }
17 |
18 | private void Init(BaseBuilder builder, SendInfo send)
19 | {
20 | base.Init(send);
21 | Builder = builder;
22 | }
23 |
24 | public void SendUi()
25 | {
26 | Builder.SendUi(Send);
27 | }
28 |
29 | protected override void EnterPool()
30 | {
31 | base.EnterPool();
32 | Builder = null;
33 | }
34 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/UiConstants.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework;
2 |
3 | public class UiConstants
4 | {
5 | public static class RpcFunctions
6 | {
7 | public const string AddUiFunc = "AddUI";
8 | public const string DestroyUiFunc = "DestroyUI";
9 | }
10 |
11 | public static class Materials
12 | {
13 | public const string InGameBlur = "assets/content/ui/uibackgroundblur-ingamemenu.mat";
14 | public const string NoticeBlur = "assets/content/ui/uibackgroundblur-notice.mat";
15 | public const string BackgroundBlur = "assets/content/ui/uibackgroundblur.mat";
16 | public const string Icon = "assets/icons/iconmaterial.mat";
17 | }
18 |
19 | public static class Sprites
20 | {
21 | public const string Default = "Assets/Content/UI/UI.Background.Tile.psd";
22 | public const string Transparent = "Assets/Content/Textures/Generic/fulltransparent.tga";
23 | public const string RoundedBackground1 = "Assets/Content/UI/UI.Rounded.tga";
24 | public const string RoundedBackground2 = "Assets/Content/UI/UI.Background.Rounded.png";
25 | public const string GradientUp = "Assets/Content/UI/UI.Gradient.Up.psd";
26 | public const string BackgroundTransparentLinear = "Assets/Content/UI/UI.Background.Transparent.Linear.png";
27 | public const string BackgroundTransparentLinearLtr = "Assets/Content/UI/UI.Background.Transparent.LinearLTR.png";
28 | public const string White = "Assets/Content/UI/UI.White.tga";
29 | public const string Circle = "Assets/Icons/circle_closed_white.png";
30 | public const string CircleToEdge = "Assets/Icons/circle_closed_white_toEdge.png";
31 | public const string Box = "Assets/Content/UI/UI.Box.tga";
32 | public const string BoxSharp = "Assets/Content/UI/UI.Box.Sharp.tga";
33 | }
34 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/UiElements/BaseUiComponent.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Json;
2 | using Oxide.Ext.UiFramework.Offsets;
3 | using Oxide.Ext.UiFramework.Pooling;
4 | using Oxide.Ext.UiFramework.Positions;
5 |
6 | namespace Oxide.Ext.UiFramework.UiElements;
7 |
8 | public abstract class BaseUiComponent : BasePoolable
9 | {
10 | public UiReference Reference;
11 | public float FadeOut;
12 | public UiPosition Position;
13 | public UiOffset Offset;
14 |
15 | protected static T CreateBase(in UiPosition pos, in UiOffset offset) where T : BaseUiComponent, new()
16 | {
17 | T component = UiFrameworkPool.Get();
18 | component.Position = pos;
19 | component.Offset = offset;
20 | return component;
21 | }
22 |
23 | public void WriteRootComponent(JsonFrameworkWriter writer, bool needsMouse, bool needsKeyboard, bool autoDestroy)
24 | {
25 | writer.WriteStartObject();
26 | writer.AddFieldRaw(JsonDefaults.Common.ComponentName, Reference.Name);
27 | writer.AddFieldRaw(JsonDefaults.Common.ParentName, Reference.Parent);
28 | writer.AddField(JsonDefaults.Common.FadeOutName, FadeOut, JsonDefaults.Common.FadeOut);
29 |
30 | if (autoDestroy)
31 | {
32 | writer.AddFieldRaw(JsonDefaults.Common.AutoDestroy, Reference.Name);
33 | }
34 |
35 | writer.WritePropertyName("components");
36 | writer.WriteStartArray();
37 | WriteComponents(writer);
38 |
39 | if (needsMouse)
40 | {
41 | writer.AddMouse();
42 | }
43 |
44 | if (needsKeyboard)
45 | {
46 | writer.AddKeyboard();
47 | }
48 |
49 | writer.WriteEndArray();
50 | writer.WriteEndObject();
51 | }
52 |
53 | public void WriteUpdateComponent(JsonFrameworkWriter writer)
54 | {
55 | writer.WriteStartObject();
56 | writer.AddFieldRaw(JsonDefaults.Common.ComponentName, Reference.Name);
57 | writer.AddFieldRaw(JsonDefaults.Common.ParentName, Reference.Parent);
58 | writer.AddField(JsonDefaults.Common.FadeOutName, FadeOut, JsonDefaults.Common.FadeOut);
59 | writer.AddFieldRaw(JsonDefaults.Common.AutoDestroy, Reference.Name);
60 |
61 | writer.WritePropertyName("components");
62 | writer.WriteStartArray();
63 | WriteComponents(writer);
64 | writer.WriteEndArray();
65 | writer.WriteEndObject();
66 | }
67 |
68 | public void WriteComponent(JsonFrameworkWriter writer)
69 | {
70 | writer.WriteStartObject();
71 | writer.AddFieldRaw(JsonDefaults.Common.ComponentName, Reference.Name);
72 | writer.AddFieldRaw(JsonDefaults.Common.ParentName, Reference.Parent);
73 | writer.AddField(JsonDefaults.Common.FadeOutName, FadeOut, JsonDefaults.Common.FadeOut);
74 |
75 | writer.WritePropertyName("components");
76 | writer.WriteStartArray();
77 | WriteComponents(writer);
78 | writer.WriteEndArray();
79 | writer.WriteEndObject();
80 | }
81 |
82 | protected virtual void WriteComponents(JsonFrameworkWriter writer)
83 | {
84 | writer.WriteStartObject();
85 | writer.AddFieldRaw(JsonDefaults.Common.ComponentTypeName, JsonDefaults.Common.RectTransformName);
86 | writer.AddPosition(JsonDefaults.Position.AnchorMinName, Position.Min, JsonDefaults.Common.Min);
87 | writer.AddPosition(JsonDefaults.Position.AnchorMaxName, Position.Max, JsonDefaults.Common.Max);
88 | writer.AddOffset(JsonDefaults.Offset.OffsetMinName, Offset.Min, JsonDefaults.Common.Min);
89 | writer.AddOffset(JsonDefaults.Offset.OffsetMaxName, Offset.Max, JsonDefaults.Common.Max);
90 | writer.WriteEndObject();
91 | }
92 |
93 | public void SetFadeOut(float duration)
94 | {
95 | FadeOut = duration;
96 | }
97 |
98 | protected override void EnterPool()
99 | {
100 | Reference = default;
101 | FadeOut = 0;
102 | Position = default;
103 | Offset = default;
104 | }
105 |
106 | public static implicit operator UiReference(BaseUiComponent component) => component.Reference;
107 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/UiElements/BaseUiImage.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Components;
2 | using Oxide.Ext.UiFramework.Json;
3 | using UnityEngine.UI;
4 |
5 | namespace Oxide.Ext.UiFramework.UiElements;
6 |
7 | public abstract class BaseUiImage : BaseUiOutline
8 | {
9 | public readonly ImageComponent Image = new();
10 |
11 | public void SetImageType(Image.Type type)
12 | {
13 | Image.ImageType = type;
14 | }
15 |
16 | public void SetSprite(string sprite)
17 | {
18 | Image.Sprite = sprite;
19 | }
20 |
21 | public void SetMaterial(string material)
22 | {
23 | Image.Material = material;
24 | }
25 |
26 | public void SetSpriteMaterialImage(string sprite = null, string material = null, Image.Type type = UnityEngine.UI.Image.Type.Simple)
27 | {
28 | Image.Sprite = sprite;
29 | Image.Material = material;
30 | Image.ImageType = type;
31 | }
32 |
33 | public void SetFadeIn(float duration)
34 | {
35 | Image.FadeIn = duration;
36 | }
37 |
38 | protected override void WriteComponents(JsonFrameworkWriter writer)
39 | {
40 | Image.WriteComponent(writer);
41 | base.WriteComponents(writer);
42 | }
43 |
44 | protected override void EnterPool()
45 | {
46 | base.EnterPool();
47 | Image.Reset();
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/UiElements/BaseUiOutline.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Colors;
2 | using Oxide.Ext.UiFramework.Components;
3 | using Oxide.Ext.UiFramework.Json;
4 | using Oxide.Ext.UiFramework.Pooling;
5 | using UnityEngine;
6 |
7 | namespace Oxide.Ext.UiFramework.UiElements;
8 |
9 | public abstract class BaseUiOutline : BaseUiComponent
10 | {
11 | public OutlineComponent Outline;
12 |
13 | public void AddElementOutline(UiColor color)
14 | {
15 | Outline = UiFrameworkPool.Get();
16 | Outline.Color = color;
17 | }
18 |
19 | public void AddElementOutline(UiColor color, Vector2 distance)
20 | {
21 | AddElementOutline(color);
22 | Outline.Distance = distance;
23 | }
24 |
25 | public void AddElementOutline(UiColor color, Vector2 distance, bool useGraphicAlpha)
26 | {
27 | AddElementOutline(color, distance);
28 | Outline.UseGraphicAlpha = useGraphicAlpha;
29 | }
30 |
31 | public void RemoveOutline()
32 | {
33 | if (Outline != null)
34 | {
35 | Outline.Dispose();
36 | Outline = null;
37 | }
38 | }
39 |
40 | protected override void WriteComponents(JsonFrameworkWriter writer)
41 | {
42 | Outline?.WriteComponent(writer);
43 | base.WriteComponents(writer);
44 | }
45 |
46 | protected override void EnterPool()
47 | {
48 | RemoveOutline();
49 | }
50 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/UiElements/UiButton.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Colors;
2 | using Oxide.Ext.UiFramework.Components;
3 | using Oxide.Ext.UiFramework.Json;
4 | using Oxide.Ext.UiFramework.Offsets;
5 | using Oxide.Ext.UiFramework.Positions;
6 | using UnityEngine.UI;
7 |
8 | namespace Oxide.Ext.UiFramework.UiElements;
9 |
10 | public class UiButton : BaseUiOutline
11 | {
12 | public readonly ButtonComponent Button = new();
13 |
14 | public static UiButton CreateCommand(in UiPosition pos, in UiOffset offset, UiColor color, string command)
15 | {
16 | UiButton button = CreateBase(pos, offset);
17 | button.Button.Color = color;
18 | button.Button.Command = command;
19 | return button;
20 | }
21 |
22 | public static UiButton CreateClose(in UiPosition pos, in UiOffset offset, UiColor color, string close)
23 | {
24 | UiButton button = CreateBase(pos, offset);
25 | button.Button.Color = color;
26 | button.Button.Close = close;
27 | return button;
28 | }
29 |
30 | public void SetFadeIn(float duration)
31 | {
32 | Button.FadeIn = duration;
33 | }
34 |
35 | public void SetImageType(Image.Type type)
36 | {
37 | Button.ImageType = type;
38 | }
39 |
40 | public void SetSprite(string sprite)
41 | {
42 | Button.Sprite = sprite;
43 | }
44 |
45 | public void SetMaterial(string material)
46 | {
47 | Button.Material = material;
48 | }
49 |
50 | public void SetSpriteMaterialImage(string sprite = null, string material = null, Image.Type type = Image.Type.Simple)
51 | {
52 | Button.Sprite = sprite;
53 | Button.Material = material;
54 | Button.ImageType = type;
55 | }
56 |
57 | protected override void WriteComponents(JsonFrameworkWriter writer)
58 | {
59 | Button.WriteComponent(writer);
60 | base.WriteComponents(writer);
61 | }
62 |
63 | protected override void EnterPool()
64 | {
65 | base.EnterPool();
66 | Button.Reset();
67 | }
68 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/UiElements/UiImage.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Colors;
2 | using Oxide.Ext.UiFramework.Offsets;
3 | using Oxide.Ext.UiFramework.Positions;
4 |
5 | namespace Oxide.Ext.UiFramework.UiElements;
6 |
7 | public class UiImage : BaseUiImage
8 | {
9 | public static UiImage CreateSpriteImage(in UiPosition pos, in UiOffset offset, UiColor color, string sprite)
10 | {
11 | UiImage image = CreateBase(pos, offset);
12 | image.Image.Color = color;
13 | image.Image.Sprite = sprite;
14 | return image;
15 | }
16 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/UiElements/UiInput.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Colors;
2 | using Oxide.Ext.UiFramework.Components;
3 | using Oxide.Ext.UiFramework.Enums;
4 | using Oxide.Ext.UiFramework.Json;
5 | using Oxide.Ext.UiFramework.Offsets;
6 | using Oxide.Ext.UiFramework.Positions;
7 | using UnityEngine;
8 | using UnityEngine.UI;
9 |
10 | namespace Oxide.Ext.UiFramework.UiElements;
11 |
12 | public class UiInput : BaseUiOutline
13 | {
14 | public readonly InputComponent Input = new();
15 |
16 | public static UiInput Create(in UiPosition pos, in UiOffset offset, UiColor textColor, string text, int size, string cmd, string font, TextAnchor align = TextAnchor.MiddleCenter, int charsLimit = 0, InputMode mode = InputMode.Default, InputField.LineType lineType = InputField.LineType.SingleLine)
17 | {
18 | UiInput input = CreateBase(pos, offset);
19 | InputComponent comp = input.Input;
20 | comp.Text = text;
21 | comp.FontSize = size;
22 | comp.Color = textColor;
23 | comp.Align = align;
24 | comp.Font = font;
25 | comp.Command = cmd;
26 | comp.CharsLimit = charsLimit;
27 | comp.Mode = mode;
28 | comp.LineType = lineType;
29 | return input;
30 | }
31 |
32 | public void SetTextAlign(TextAnchor align)
33 | {
34 | Input.Align = align;
35 | }
36 |
37 | public void SetCharsLimit(int limit)
38 | {
39 | Input.CharsLimit = limit;
40 | }
41 |
42 | public void SetIsPassword(bool isPassword)
43 | {
44 | Input.SetMode(InputMode.Password, isPassword);
45 | }
46 |
47 | public void SetIsReadonly(bool isReadonly)
48 | {
49 | Input.SetMode(InputMode.ReadOnly, isReadonly);
50 | }
51 |
52 | public void SetAutoFocus(bool autoFocus)
53 | {
54 | Input.SetMode(InputMode.AutoFocus, autoFocus);
55 | }
56 |
57 | ///
58 | /// Sets if the input should block keyboard input when focused.
59 | /// This should not be used when the loot panel / crafting UI is open. Use SetNeedsHudKeyboard instead
60 | ///
61 | ///
62 | public void SetNeedsKeyboard(bool needsKeyboard)
63 | {
64 | Input.SetMode(InputMode.NeedsKeyboard, needsKeyboard);
65 | }
66 |
67 | ///
68 | /// Sets if the input should block keyboard input when focused a loot panel / crafting ui is open.
69 | /// This should not if a loot panel / crafting ui won't be open when displaying the UI.
70 | ///
71 | ///
72 | public void SetNeedsHudKeyboard(bool needsKeyboard)
73 | {
74 | Input.SetMode(InputMode.HudNeedsKeyboard, needsKeyboard);
75 | }
76 |
77 | public void SetLineType(InputField.LineType lineType)
78 | {
79 | Input.LineType = lineType;
80 | }
81 |
82 | protected override void WriteComponents(JsonFrameworkWriter writer)
83 | {
84 | Input.WriteComponent(writer);
85 | base.WriteComponents(writer);
86 | }
87 |
88 | protected override void EnterPool()
89 | {
90 | base.EnterPool();
91 | Input.Reset();
92 | }
93 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/UiElements/UiItemIcon.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Colors;
2 | using Oxide.Ext.UiFramework.Components;
3 | using Oxide.Ext.UiFramework.Json;
4 | using Oxide.Ext.UiFramework.Offsets;
5 | using Oxide.Ext.UiFramework.Positions;
6 |
7 | namespace Oxide.Ext.UiFramework.UiElements;
8 |
9 | public class UiItemIcon : BaseUiOutline
10 | {
11 | public readonly ItemIconComponent Icon = new();
12 |
13 | public static UiItemIcon Create(in UiPosition pos, in UiOffset offset, UiColor color, int itemId, ulong skinId = 0)
14 | {
15 | UiItemIcon icon = CreateBase(pos, offset);
16 | icon.Icon.Color = color;
17 | icon.Icon.ItemId = itemId;
18 | icon.Icon.SkinId = skinId;
19 | return icon;
20 | }
21 |
22 | public void SetFadeIn(float duration)
23 | {
24 | Icon.FadeIn = duration;
25 | }
26 |
27 | protected override void WriteComponents(JsonFrameworkWriter writer)
28 | {
29 | Icon.WriteComponent(writer);
30 | base.WriteComponents(writer);
31 | }
32 |
33 | protected override void EnterPool()
34 | {
35 | base.EnterPool();
36 | Icon.Reset();
37 | }
38 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/UiElements/UiLabel.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Colors;
2 | using Oxide.Ext.UiFramework.Components;
3 | using Oxide.Ext.UiFramework.Enums;
4 | using Oxide.Ext.UiFramework.Json;
5 | using Oxide.Ext.UiFramework.Offsets;
6 | using Oxide.Ext.UiFramework.Pooling;
7 | using Oxide.Ext.UiFramework.Positions;
8 | using UnityEngine;
9 |
10 | namespace Oxide.Ext.UiFramework.UiElements;
11 |
12 | public class UiLabel : BaseUiOutline
13 | {
14 | public readonly TextComponent Text = new();
15 | public CountdownComponent Countdown;
16 |
17 | public static UiLabel Create(in UiPosition pos, in UiOffset offset, UiColor color, string text, int size, string font, TextAnchor align = TextAnchor.MiddleCenter)
18 | {
19 | UiLabel label = CreateBase(pos, offset);
20 | TextComponent textComp = label.Text;
21 | textComp.Text = text;
22 | textComp.FontSize = size;
23 | textComp.Color = color;
24 | textComp.Align = align;
25 | textComp.Font = font;
26 | return label;
27 | }
28 |
29 | public CountdownComponent AddCountdown(float startTime, float endTime, float step, float interval, TimerFormat timerFormat, string numberFormat, bool destroyIfDone, string command)
30 | {
31 | Countdown = UiFrameworkPool.Get();
32 | Countdown.StartTime = startTime;
33 | Countdown.EndTime = endTime;
34 | Countdown.Step = step;
35 | Countdown.Interval = interval;
36 | Countdown.TimerFormat = timerFormat;
37 | Countdown.NumberFormat = numberFormat;
38 | Countdown.DestroyIfDone = destroyIfDone;
39 | Countdown.Command = command;
40 | return Countdown;
41 | }
42 |
43 | public void SetFadeIn(float duration)
44 | {
45 | Text.FadeIn = duration;
46 | }
47 |
48 | protected override void WriteComponents(JsonFrameworkWriter writer)
49 | {
50 | Text.WriteComponent(writer);
51 | Countdown?.WriteComponent(writer);
52 | base.WriteComponents(writer);
53 | }
54 |
55 | protected override void EnterPool()
56 | {
57 | base.EnterPool();
58 | Text.Reset();
59 | Countdown?.Dispose();
60 | Countdown = null;
61 | }
62 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/UiElements/UiPanel.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Colors;
2 | using Oxide.Ext.UiFramework.Offsets;
3 | using Oxide.Ext.UiFramework.Positions;
4 |
5 | namespace Oxide.Ext.UiFramework.UiElements;
6 |
7 | public class UiPanel : BaseUiImage
8 | {
9 | public static UiPanel Create(in UiPosition pos, in UiOffset offset, UiColor color)
10 | {
11 | UiPanel panel = CreateBase(pos, offset);
12 | panel.Image.Color = color;
13 | return panel;
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/UiElements/UiPlayerAvatar.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Colors;
2 | using Oxide.Ext.UiFramework.Components;
3 | using Oxide.Ext.UiFramework.Json;
4 | using Oxide.Ext.UiFramework.Offsets;
5 | using Oxide.Ext.UiFramework.Positions;
6 |
7 | namespace Oxide.Ext.UiFramework.UiElements;
8 |
9 | public class UiPlayerAvatar : BaseUiOutline
10 | {
11 | public readonly PlayerAvatarComponent Avatar = new();
12 |
13 | public static UiPlayerAvatar Create(in UiPosition pos, in UiOffset offset, UiColor color, string steamId)
14 | {
15 | UiPlayerAvatar icon = CreateBase(pos, offset);
16 | icon.Avatar.Color = color;
17 | icon.Avatar.SteamId = steamId;
18 | return icon;
19 | }
20 |
21 | public void SetFadeIn(float duration)
22 | {
23 | Avatar.FadeIn = duration;
24 | }
25 |
26 | protected override void WriteComponents(JsonFrameworkWriter writer)
27 | {
28 | Avatar.WriteComponent(writer);
29 | base.WriteComponents(writer);
30 | }
31 |
32 | protected override void EnterPool()
33 | {
34 | base.EnterPool();
35 | Avatar.Reset();
36 | }
37 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/UiElements/UiRawImage.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Colors;
2 | using Oxide.Ext.UiFramework.Components;
3 | using Oxide.Ext.UiFramework.Json;
4 | using Oxide.Ext.UiFramework.Offsets;
5 | using Oxide.Ext.UiFramework.Positions;
6 |
7 | namespace Oxide.Ext.UiFramework.UiElements;
8 |
9 | public class UiRawImage : BaseUiOutline
10 | {
11 | public readonly RawImageComponent RawImage = new();
12 |
13 | public static UiRawImage CreateDefault(in UiPosition pos, in UiOffset offset)
14 | {
15 | UiRawImage image = CreateBase(pos, offset);
16 | return image;
17 | }
18 |
19 | public static UiRawImage CreateUrl(in UiPosition pos, in UiOffset offset, UiColor color, string url)
20 | {
21 | UiRawImage image = CreateBase(pos, offset);
22 | image.RawImage.Color = color;
23 | image.RawImage.Url = url;
24 | return image;
25 | }
26 |
27 | public static UiRawImage CreateTexture(in UiPosition pos, in UiOffset offset, UiColor color, string icon)
28 | {
29 | UiRawImage image = CreateBase(pos, offset);
30 | image.RawImage.Color = color;
31 | image.RawImage.Texture = icon;
32 | return image;
33 | }
34 |
35 | public static UiRawImage CreateFileImage(in UiPosition pos, in UiOffset offset, UiColor color, string png)
36 | {
37 | UiRawImage image = CreateBase(pos, offset);
38 | image.RawImage.Color = color;
39 | image.RawImage.Png = png;
40 | return image;
41 | }
42 |
43 | public void SetMaterial(string material)
44 | {
45 | RawImage.Material = material;
46 | }
47 |
48 | public void SetFadeIn(float duration)
49 | {
50 | RawImage.FadeIn = duration;
51 | }
52 |
53 | protected override void WriteComponents(JsonFrameworkWriter writer)
54 | {
55 | RawImage.WriteComponent(writer);
56 | base.WriteComponents(writer);
57 | }
58 |
59 | protected override void EnterPool()
60 | {
61 | base.EnterPool();
62 | RawImage.Reset();
63 | }
64 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/UiElements/UiReference.cs:
--------------------------------------------------------------------------------
1 | namespace Oxide.Ext.UiFramework.UiElements;
2 |
3 | public readonly struct UiReference
4 | {
5 | public readonly string Parent;
6 | public readonly string Name;
7 |
8 | public UiReference(string parent, string name)
9 | {
10 | Parent = parent;
11 | Name = name;
12 | }
13 |
14 | public UiReference WithChild(string name) => new(Name, name);
15 |
16 | public bool IsValidParent() => !string.IsNullOrEmpty(Parent);
17 | public bool IsValidReference() => IsValidParent() && !string.IsNullOrEmpty(Name);
18 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/UiElements/UiScrollView.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Colors;
2 | using Oxide.Ext.UiFramework.Components;
3 | using Oxide.Ext.UiFramework.Json;
4 | using Oxide.Ext.UiFramework.Offsets;
5 | using Oxide.Ext.UiFramework.Pooling;
6 | using Oxide.Ext.UiFramework.Positions;
7 | using UnityEngine.UI;
8 |
9 | namespace Oxide.Ext.UiFramework.UiElements;
10 |
11 | public class UiScrollView : BaseUiComponent
12 | {
13 | public readonly ScrollViewComponent ScrollView = new();
14 |
15 | public UiReference ViewPort => _viewPort ??= Reference.WithChild($"{Reference.Name}___Viewport");
16 | public UiReference Content => _content ??= Reference.WithChild($"{Reference.Name}___Content");
17 |
18 | private UiReference? _viewPort;
19 | private UiReference? _content;
20 |
21 | public static UiScrollView Create(in UiPosition pos, in UiOffset offset, bool horizontal, bool vertical, ScrollRect.MovementType movementType, float elasticity,
22 | bool inertia, float decelerationRate, float scrollSensitivity)
23 | {
24 | UiScrollView scroll = CreateBase(pos, offset);
25 | ScrollViewComponent comp = scroll.ScrollView;
26 | comp.Horizontal = horizontal;
27 | comp.Vertical = vertical;
28 | comp.MovementType = movementType;
29 | comp.Elasticity = elasticity;
30 | comp.Inertia = inertia;
31 | comp.DecelerationRate = decelerationRate;
32 | comp.ScrollSensitivity = scrollSensitivity;
33 | return scroll;
34 | }
35 |
36 | public void UpdateContentTransform(in UiPosition? position = null, in UiOffset? offset = null)
37 | {
38 | if (position.HasValue)
39 | {
40 | ScrollView.ContentTransform.Position = position.Value;
41 | }
42 |
43 | if (offset.HasValue)
44 | {
45 | ScrollView.ContentTransform.Offset = offset.Value;
46 | }
47 | }
48 |
49 | public void AddScrollBars(bool invert = false, bool autoHide = false, string handleSprite = null, string trackSprite = null, float size = 20f,
50 | UiColor? handleColor = null, UiColor? highlightColor = null, UiColor? pressedColor = null, UiColor? trackColor = null)
51 | {
52 | AddHorizontalScrollBar(invert, autoHide, handleSprite, trackSprite, size, handleColor, highlightColor, pressedColor, trackColor);
53 | AddVerticalScrollBar(invert, autoHide, handleSprite, trackSprite, size, handleColor, highlightColor, pressedColor, trackColor);
54 | }
55 |
56 | public ScrollbarComponent AddHorizontalScrollBar(bool invert = false, bool autoHide = false, string handleSprite = null, string trackSprite = null, float size = 20f,
57 | UiColor? handleColor = null, UiColor? highlightColor = null, UiColor? pressedColor = null, UiColor? trackColor = null)
58 | {
59 | ScrollView.Horizontal = true;
60 | ScrollbarComponent bar = CreateScrollBar(invert, autoHide, handleSprite, trackSprite, size, handleColor, highlightColor, pressedColor, trackColor);
61 | ScrollView.HorizontalScrollbar = bar;
62 | return bar;
63 | }
64 |
65 | public ScrollbarComponent AddVerticalScrollBar(bool invert = false, bool autoHide = false, string handleSprite = null, string trackSprite = null, float size = 20f,
66 | UiColor? handleColor = null, UiColor? highlightColor = null, UiColor? pressedColor = null, UiColor? trackColor = null)
67 | {
68 | ScrollView.Vertical = true;
69 | ScrollbarComponent bar = CreateScrollBar(invert, autoHide, handleSprite, trackSprite, size, handleColor, highlightColor, pressedColor, trackColor);
70 | ScrollView.VerticalScrollbar = bar;
71 | return bar;
72 | }
73 |
74 | private ScrollbarComponent CreateScrollBar(bool invert = false, bool autoHide = false, string handleSprite = null, string trackSprite = null, float size = 20f,
75 | UiColor? handleColor = null, UiColor? highlightColor = null, UiColor? pressedColor = null, UiColor? trackColor = null)
76 | {
77 | ScrollbarComponent comp = UiFrameworkPool.Get();
78 | comp.Invert = invert;
79 | comp.AutoHide = autoHide;
80 | comp.HandleSprite = handleSprite;
81 | comp.TrackSprite = trackSprite;
82 | comp.Size = size;
83 | if (handleColor.HasValue)
84 | {
85 | comp.HandleColor = handleColor.Value;
86 | }
87 | if (highlightColor.HasValue)
88 | {
89 | comp.HighlightColor = highlightColor.Value;
90 | }
91 | if (pressedColor.HasValue)
92 | {
93 | comp.PressedColor = pressedColor.Value;
94 | }
95 | if (trackColor.HasValue)
96 | {
97 | comp.TrackColor = trackColor.Value;
98 | }
99 | return comp;
100 | }
101 |
102 | protected override void WriteComponents(JsonFrameworkWriter writer)
103 | {
104 | ScrollView.WriteComponent(writer);
105 | base.WriteComponents(writer);
106 | }
107 |
108 | protected override void EnterPool()
109 | {
110 | base.EnterPool();
111 | ScrollView.HorizontalScrollbar?.Dispose();
112 | ScrollView.HorizontalScrollbar = null;
113 | ScrollView.VerticalScrollbar?.Dispose();
114 | ScrollView.VerticalScrollbar = null;
115 | _viewPort = null;
116 | _content = null;
117 | }
118 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/UiElements/UiSection.cs:
--------------------------------------------------------------------------------
1 | using Oxide.Ext.UiFramework.Offsets;
2 | using Oxide.Ext.UiFramework.Positions;
3 |
4 | namespace Oxide.Ext.UiFramework.UiElements;
5 |
6 | public class UiSection : BaseUiComponent
7 | {
8 | public static UiSection Create(in UiPosition pos, in UiOffset offset)
9 | {
10 | UiSection panel = CreateBase(pos, offset);
11 | return panel;
12 | }
13 | }
--------------------------------------------------------------------------------
/src/Rust.UIFramework/UiHelpers.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Oxide.Ext.UiFramework;
4 |
5 | public static class UiHelpers
6 | {
7 | public static int CalculateMaxPage(int count, int perPage)
8 | {
9 | int maxPage = count / perPage;
10 | if (count % perPage == 0)
11 | {
12 | maxPage -= 1;
13 | }
14 |
15 | return maxPage;
16 | }
17 |
18 | public static int TextOffsetWidth(int length, int fontSize, float padding = 0)
19 | {
20 | return Mathf.CeilToInt(length * fontSize * 0.5f + padding * 2) + 1;
21 | //return (int)(length * fontSize * 1f) + 1;
22 | }
23 |
24 | public static int TextOffsetHeight(int fontSize, float padding = 0)
25 | {
26 | return Mathf.CeilToInt(fontSize * 1.25f + padding * 2);
27 | }
28 | }
--------------------------------------------------------------------------------
/src/Rust.UiFramework.Benchmarks/Benchmarks.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using BenchmarkDotNet.Attributes;
3 | using Facepunch;
4 | using Network;
5 | using Oxide.Ext.UiFramework.Builder.UI;
6 | using Oxide.Ext.UiFramework.Colors;
7 | using Oxide.Ext.UiFramework.Extensions;
8 | using Oxide.Ext.UiFramework.Json;
9 | using Oxide.Ext.UiFramework.Positions;
10 | using Oxide.Game.Rust.Cui;
11 |
12 | namespace Rust.UiFramework.Benchmarks;
13 |
14 | #if BENCHMARKS
15 |
16 | using Oxide.Ext.UiFramework.Benchmarks;
17 |
18 | [MemoryDiagnoser]
19 | public class Benchmarks
20 | {
21 | private const int Iterations = 100;
22 | private readonly List _oxideMins = new();
23 | private readonly List _oxideMaxs = new();
24 | private readonly List _frameworkPos = new();
25 | private readonly Random _random = new();
26 | public readonly byte[] Buffer = new byte[1024 * 1024];
27 | private CuiElementContainer _oxideContainer;
28 | private string _oxideJson;
29 | private UiBuilder _builder;
30 | private UiBuilder _randomBuilder;
31 | private JsonFrameworkWriter _writer;
32 | private JsonFrameworkWriter _randomWriter;
33 | private readonly Connection _connection = new();
34 |
35 | [GlobalSetup]
36 | public void Setup()
37 | {
38 | for (int i = 0; i < Iterations; i++)
39 | {
40 | float xMin = (float)_random.NextDouble();
41 | float xMax = (float)_random.NextDouble();
42 | float yMin = (float)_random.NextDouble();
43 | float yMax = (float)_random.NextDouble();
44 | _oxideMins.Add($"{xMin} {yMin}");
45 | _oxideMaxs.Add($"{xMax} {yMax}");
46 | _frameworkPos.Add(new UiPosition(xMin, yMin, xMax, yMax));
47 | }
48 |
49 | _oxideContainer = GetOxideContainer();
50 | _oxideJson = _oxideContainer.ToJson();
51 | _builder = GetFrameworkBuilder();
52 | //_randomBuilder = GetRandomPositionBuilder();
53 | _writer = _builder.CreateWriter();
54 | //_randomWriter = _randomBuilder.CreateWriter();
55 | }
56 |
57 | // [Benchmark]
58 | // public CuiElementContainer Oxide_CreateContainer()
59 | // {
60 | // return GetOxideContainer();
61 | // }
62 |
63 | // [Benchmark(Baseline = true)]
64 | // public UiBuilder UiFramework_CreateContainer()
65 | // {
66 | // UiBuilder builder = GetFrameworkBuilder();
67 | // builder.Dispose();
68 | // return builder;
69 | // }
70 |
71 | //
72 | // [Benchmark]
73 | // public string Oxide_CreateJson()
74 | // {
75 | // return _oxideContainer.ToJson();
76 | // }
77 | //
78 | // [Benchmark]
79 | // public JsonFrameworkWriter UiFramework_CreateJson()
80 | // {
81 | // JsonFrameworkWriter writer = _builder.CreateWriter();
82 | // writer.Dispose();
83 | // return writer;
84 | // }
85 | //
86 | // [Benchmark]
87 | // public byte[] Oxide_EncodeJson()
88 | // {
89 | // return Encoding.UTF8.GetBytes(_oxideJson);
90 | // }
91 | //
92 | // [Benchmark]
93 | // public int UiFramework_EncodeJson()
94 | // {
95 | // int count = _writer.WriteTo(Buffer);
96 | // return count;
97 | // }
98 |
99 | [Benchmark(Baseline = true)]
100 | public void UiFramework_Async()
101 | {
102 | UiBuilder builder = GetFrameworkBuilder();
103 | builder.AddUi(default(SendInfo));
104 | builder.Dispose();
105 | }
106 |
107 | [Benchmark]
108 | public void Oxide_Async()
109 | {
110 | CuiElementContainer builder = GetOxideContainer();
111 | builder.AddUiAsync(_connection);
112 | }
113 |
114 | //[Benchmark]
115 | public void UiFramework_Full()
116 | {
117 | UiBuilder builder = GetFrameworkBuilder();
118 | JsonFrameworkWriter writer = builder.CreateWriter();
119 | BenchmarkNetWrite write = Pool.Get();
120 | writer.WriteToNetwork(write);
121 | writer.Dispose();
122 | Pool.Free(ref write);
123 | builder.Dispose();
124 | }
125 |
126 | [Benchmark]
127 | public byte[] Oxide_Full()
128 | {
129 | CuiElementContainer builder = GetOxideContainer();
130 | string json = builder.ToJson();
131 | return Encoding.UTF8.GetBytes(json);
132 | }
133 |
134 | private CuiElementContainer GetOxideContainer()
135 | {
136 | CuiElementContainer container = new();
137 | for (int i = 0; i < Iterations; i++)
138 | {
139 | container.Add(new CuiPanel
140 | {
141 | Image =
142 | {
143 | Color = "1.0 1.0 1.0 1.0"
144 | },
145 | RectTransform =
146 | {
147 | AnchorMin = _oxideMins[i],
148 | AnchorMax = _oxideMaxs[i]
149 | }
150 | });
151 | }
152 |
153 | return container;
154 | }
155 |
156 | private UiBuilder GetFrameworkBuilder()
157 | {
158 | UiBuilder builder = UiBuilder.Create(UiPosition.Full, UiColor.Clear, "123");
159 | builder.EnsureCapacity(Iterations);
160 | for (int i = 0; i < Iterations - 1; i++)
161 | {
162 | builder.Panel(builder.Root, _frameworkPos[i], UiColor.Black);
163 | }
164 |
165 | return builder;
166 | }
167 | }
168 | #endif
--------------------------------------------------------------------------------
/src/Rust.UiFramework.Benchmarks/Program.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Configs;
2 | using BenchmarkDotNet.Jobs;
3 | using BenchmarkDotNet.Running;
4 | using BenchmarkDotNet.Toolchains.InProcess.Emit;
5 |
6 | namespace Rust.UiFramework.Benchmarks;
7 |
8 | class Program
9 | {
10 | static void Main(string[] args)
11 | {
12 | #if BENCHMARKS
13 | ManualConfig config = DefaultConfig.Instance.AddJob(Job.Default
14 | .WithToolchain(InProcessEmitToolchain.Instance)
15 | .WithIterationCount(30));
16 | BenchmarkRunner.Run(config, args);
17 | #endif
18 | }
19 | }
--------------------------------------------------------------------------------
/src/Rust.UiFramework.Benchmarks/Rust.UiFramework.Benchmarks.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | enable
5 | enable
6 | 12
7 | true
8 | Debug;Release;Benchmarks
9 | Oxide
10 | Exe
11 | netcoreapp3.0
12 |
13 |
14 |
15 | TRACE;DEBUG;CARBON
16 | Carbon.Ext.UiFramework
17 |
18 |
19 |
20 | TRACE;DEBUG;OXIDE
21 |
22 |
23 |
24 | TRACE;CARBON
25 | Carbon.Ext.UiFramework
26 |
27 |
28 |
29 | TRACE;OXIDE
30 |
31 |
32 |
33 | TRACE;BENCHMARKS
34 | true
35 |
36 |
37 |
38 |
39 | ..\references\Assembly-CSharp.dll
40 |
41 |
42 | ..\references\Facepunch.Network.dll
43 |
44 |
45 | ..\references\Facepunch.System.dll
46 |
47 |
48 | ..\References\mscorlib.dll
49 |
50 |
51 | ..\References\Oxide.Common.dll
52 |
53 |
54 | ..\References\Oxide.Core.dll
55 |
56 |
57 | ..\references\Oxide.CSharp.dll
58 |
59 |
60 | ..\references\Oxide.References.dll
61 |
62 |
63 | ..\References\Oxide.Rust.dll
64 |
65 |
66 | ..\references\System.Memory.dll
67 |
68 |
69 | ..\references\System.Runtime.dll
70 |
71 |
72 | ..\references\UnityEngine.TextRenderingModule.dll
73 |
74 |
75 | ..\references\UnityEngine.UI.dll
76 |
77 |
78 | ..\references\UnityEngine.UIElementsModule.dll
79 |
80 |
81 | ..\references\UnityEngine.UIModule.dll
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------