@startuml
class EffectDropdown {
    + SetEffect(newVal:int) : void
}
class "List`1"<T> {
}
MonoBehaviour <|-- EffectDropdown
EffectDropdown o-> "effectItems<Transform>" "List`1"
class KeybindingManager {
    Update() : void
}
MonoBehaviour <|-- KeybindingManager
class ProjectShaderSettingsManager {
    + SetSetting(id:int, setting:ShaderSetting<T>) : void
    + GetSetting(id:int) : ShaderSetting<T>?
    + SerializeAllSettings() : string
    + DeserializeAllSettings(json:string) : void
}
interface IShaderSettingDeserializer {
    + DeSerialize(serializedSetting:string) : ShaderSetting<T>
}
interface IShaderSettingSerializer {
    + Serialize(setting:ShaderSetting<T>) : string
}
class "ShaderSetting`1"<T> <<struct>> {
    + name : string
    + value : T
    + ShaderSetting(name:string, value:T)
}
class "Dictionary`2"<T1,T2> {
}
MonoBehaviour <|-- ProjectShaderSettingsManager
ProjectShaderSettingsManager o-> "currentSettings<int,string>" "Dictionary`2"
ProjectShaderSettingsManager --> "serializer" IShaderSettingSerializer
ProjectShaderSettingsManager --> "deserializer" IShaderSettingDeserializer
class RuntimeProject {
    + RuntimeProject(serializedProject:Project)
}
RuntimeProject --> "sprite" Texture2D
RuntimeProject --> "serializedProject" Project
class ToolManager {
    + projectIsSaved : bool = true
    + CloseProject() : void
    + New() : void
    + Exit() : void
    + ExitNoSave() : void
}
class "Singleton`1"<T> {
}
"Singleton`1" "<ToolManager>" <|-- ToolManager
ToolManager --> "ssi" ScriptShaderInterface
ToolManager --> "processor" SpriteProcessor
ToolManager --> "mainMenu" Menu
ToolManager --> "exitModal" Transform
class SpriteProcessor {
    + ProcessImage(sprite:Texture2D) : void
}
MonoBehaviour <|-- SpriteProcessor
SpriteProcessor --> "template" Material
SpriteProcessor --> "processed" RenderTexture
class CommandManager {
    + changesBeforeRedoDiscard : int = 1
    + PushCommand(command:ICommand) : void
    + Undo() : void
    + Redo() : void
}
class "Singleton`1"<T> {
}
class "Stack`1"<T> {
}
"Singleton`1" "<CommandManager>" <|-- CommandManager
CommandManager o-> "history<ICommand>" "Stack`1"
CommandManager o-> "redoHistory<ICommand>" "Stack`1"
class ShaderBinding {
    + propertyName : string
    + RestoreLoadedValue() : (bool,T)
    + UpdateValue(val:T) : void
    + PreviewValue(val:T) : void
}
MonoBehaviour <|-- ShaderBinding
interface ICommand {
    + Execute() : void
    + Undo() : void
    + Redo() : void
}
class StringAction <<struct>> {
    + action : string
}
class StringActionRunner {
    + TryRunAction(action:string) : bool
    + RunActionTMP() : void
}
class "List`1"<T> {
}
StringAction --> "reaction" UnityEvent
MonoBehaviour <|-- StringActionRunner
StringActionRunner o-> "actions<StringAction>" "List`1"
class "Singleton`1"<T> {
    + {static} Instance : T <<get>> <<set>>
}
MonoBehaviour <|-- "Singleton`1"
class CLI {
    Awake() : void
    + RunConsoleCommand(command:string, startInfo:ProcessStartInfo) : int
    + NormalizeSlashes(path:string) : string
    + AddQuotesIfRequired(path:string) : string
}
class "Singleton`1"<T> {
}
"Singleton`1" "<CLI>" <|-- CLI
class DropdownToContextMenu {
}
MonoBehaviour <|-- DropdownToContextMenu
class ScriptShaderInterface {
    + SetShaderMode(mode:int) : void
    + Initialize(template:Material) : void
    + HasSetting(name:string) : bool
    + GetSetting(name:string) : ShaderSetting<T>?
    + SetSetting(name:string, value:T, updateProjectFile:bool) : bool
}
class "List`1"<T> {
}
MonoBehaviour <|-- ScriptShaderInterface
ScriptShaderInterface --> "material" Material
ScriptShaderInterface o-> "propertyNames<string>" "List`1"
class CommandBasedDropdown {
    + PokeDropdownDetection(newValue:int) : void
}
class "UnityEvent`1"<T> {
}
MonoBehaviour <|-- CommandBasedDropdown
CommandBasedDropdown --> "onValueChanged<int>" "UnityEvent`1"
class "CommandBasedInputField`1"<T> {
    + CommandBasedInputField(inputField:TMP_InputField, parser:IInputParser<T>, validator:IFieldValidator<T>, callback:Action<T>)
    + LoadValueFromSave() : bool
    + Poke(newValue:string) : void
    + Poke(newValue:string, pushCommand:bool) : void
    + BindToShader(shaderBinding:ShaderBinding) : void
}
class ConnectedSlider {
    + maxValue : float = 1f
    + minValue : float = 0f
    + Poke(newVal:float) : void
}
MonoBehaviour <|-- ConnectedSlider
ConnectedSlider --> "inputField" CommandBasedInputFieldComponent
ConnectedSlider --> "previewBinding" ShaderBinding
class DefaultShaderSettingSerializerDeserializer {
    + Serialize(setting:ShaderSetting<T>) : string
    + DeSerialize(serializedSetting:string) : ShaderSetting<T>
}
ScriptableObject <|-- DefaultShaderSettingSerializerDeserializer
IShaderSettingSerializer <|-- DefaultShaderSettingSerializerDeserializer
IShaderSettingDeserializer <|-- DefaultShaderSettingSerializerDeserializer
class Preview {
    + isBeeingHovered : bool = false
    + OnPointerEnter(eventData:PointerEventData) : void
    + OnPointerExit(eventData:PointerEventData) : void
}
MonoBehaviour <|-- Preview
IPointerEnterHandler <|-- Preview
IPointerExitHandler <|-- Preview
class CameraController {
    + sensitifity : float
}
MonoBehaviour <|-- CameraController
CameraController --> "preview" Preview
class ProjectManager {
    + projectIsOpen : bool
    + CreateProjectWithUI() : void
    + GetProjectPaths() : List<string>
    + GetProjectNames() : List<string>
    + GetProject(projectDirectory:string) : Project
    + CreateProject(name:string, spriteFilePath:string, openProject:bool) : Project
    + SaveCurrent() : void
    + SaveAs() : void
    + ExportCurrent(mode:int) : void
    + Export(p:RuntimeProject, mode:int) : bool
    + OpenProject(p:Project) : void
    + GetOpenProject() : RuntimeProject
}
class "Singleton`1"<T> {
}
"Singleton`1" "<ProjectManager>" <|-- ProjectManager
ProjectManager --> "shaderSettingsManager" ProjectShaderSettingsManager
ProjectManager --> "menuManager" MenuManager
ProjectManager --> "newProjectMenu" Menu
ProjectManager --> "saveAsModal" Transform
ProjectManager --> "saveAsModalInput" TMP_InputField
ProjectManager --> "projectRefreshEvent" Action
class Project <<struct>> {
    + name : string
    + projectDirectory : string
    + originalSpritePath : string
    + shaderSettings : string
}
class ProjectDisplay {
    Start() : void
}
MonoBehaviour <|-- ProjectDisplay
ProjectDisplay --> "templateProject" GameObject
class ProjectButton {
}
MonoBehaviour <|-- ProjectButton
ProjectButton --> "button" Button
ProjectButton --> "label" TMP_Text
class InputValidator {
}
ScriptableObject <|-- InputValidator
interface "IFieldValidator`1"<T> {
    + Invoke(input:T) : T
}
interface "IInputParser`1"<out T> {
    + Parse(from:string) : T
}
abstract class InputParser {
}
ScriptableObject <|-- InputParser
class MenuElement {
    + id : string
}
MonoBehaviour <|-- MenuElement
class Menu {
    + GetMenuElementById(id:string) : T
}
MonoBehaviour <|-- Menu
class MenuManager {
    + SwitchMenu(index:int) : void
}
class "List`1"<T> {
}
MonoBehaviour <|-- MenuManager
MenuManager o-> "menus<Menu>" "List`1"
class IntParser {
    + Parse(from:string) : int
}
class "IInputParser`1"<T> {
}
InputParser <|-- IntParser
"IInputParser`1" "<int>" <|-- IntParser
class FloatValidator {
    + Invoke(input:float) : float
}
class "IFieldValidator`1"<T> {
}
InputValidator <|-- FloatValidator
"IFieldValidator`1" "<float>" <|-- FloatValidator
class IntValidator {
    + Invoke(input:int) : int
}
class "IFieldValidator`1"<T> {
}
InputValidator <|-- IntValidator
"IFieldValidator`1" "<int>" <|-- IntValidator
class FloatParser {
    + Parse(from:string) : float
}
class "IInputParser`1"<T> {
}
InputParser <|-- FloatParser
"IInputParser`1" "<float>" <|-- FloatParser
class "ChangeFieldCommand`1"<T> {
    + ChangeFieldCommand(field:TMP_InputField, from:T, to:T, validator:IFieldValidator<T>, callback:Action<T>)
    + Execute() : void
    + Undo() : void
    + Redo() : void
}
ICommand <|-- "ChangeFieldCommand`1"
class ChangeDropdownCommand {
    + ChangeDropdownCommand(dropdown:TMP_Dropdown, from:int, to:int, callback:Action<int>)
    + Execute() : void
    + Undo() : void
    + Redo() : void
}
ICommand <|-- ChangeDropdownCommand
class "RuntimeCommandBasedInputFieldComponent`1"<T> {
    + Init(inputField:TMP_InputField, parser:InputParser, validator:InputValidator, callback:Action<object>) : void
    + BindToShader(binding:ShaderBinding) : void
}
class "CommandBasedInputField`1"<T> {
}
"RuntimeCommandBasedInputFieldComponent`1" --> "cbif<T>" "CommandBasedInputField`1"
class CommandBasedInputFieldComponent {
    + inputType : string
    + defaultValue : string
}
class "Action`1"<T> {
}
MonoBehaviour <|-- CommandBasedInputFieldComponent
CommandBasedInputFieldComponent --> "parser" InputParser
CommandBasedInputFieldComponent --> "validator" InputValidator
CommandBasedInputFieldComponent --> "callback<object>" "Action`1"
CommandBasedInputFieldComponent --> "rcbifc" dynamic
class ImageDisplayElement {
}
MenuElement <|-- ImageDisplayElement
ImageDisplayElement --> "image" RawImage
class StringInputElement {
}
MenuElement <|-- StringInputElement
StringInputElement --> "InputField" TMP_InputField
class OpenFileName {
    + structSize : int = 0
    + maxCustFilter : int = 0
    + filterIndex : int = 0
    + maxFile : int = 0
    + maxFileTitle : int = 0
    + flags : int = 0
    + fileOffset : short = 0
    + fileExtension : short = 0
    + reservedInt : int = 0
    + flagsEx : int = 0
}
class FileInputElement {
    + FilePath : string <<get>> = null
    + {static} <<extern>> GetOpenFileName(ofn:OpenFileName) : bool
    + {static} GetOpenFileName1(ofn:OpenFileName) : bool
    + {static} <<extern>> GetSaveFileName(ofn:OpenFileName) : bool
    + {static} GetSaveFileName1(ofn:OpenFileName) : bool
    + PickFile() : void
    + UpdatePreviewText() : void
}
OpenFileName o-> "dlgOwner" IntPtr
OpenFileName o-> "instance" IntPtr
OpenFileName o-> "filter" String
OpenFileName o-> "customFilter" String
OpenFileName o-> "file" String
OpenFileName o-> "fileTitle" String
OpenFileName o-> "initialDir" String
OpenFileName o-> "title" String
OpenFileName o-> "defExt" String
OpenFileName o-> "custData" IntPtr
OpenFileName o-> "hook" IntPtr
OpenFileName o-> "templateName" String
OpenFileName o-> "reservedPtr" IntPtr
MenuElement <|-- FileInputElement
FileInputElement --> "previewText" TMP_Text
@enduml
