From 0272e3e1739162ee9be2f97f9675ea444f237358 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tobias=20Sch=C3=B6ner?= <tobias.stonehead@gmail.com>
Date: Sat, 28 Jan 2023 14:14:31 +0100
Subject: [PATCH] feat: factDisplay can now sort ascending and descending

---
 Assets/Images/Arrow_down.png                  |   3 +
 Assets/Images/Arrow_down.png.meta             | 122 ++++++++
 .../Prefabs/UI/Facts/Factscreen.prefab        | 272 +++++++++++++++++-
 Assets/Scripts/InventoryStuff/DisplayFacts.cs |  82 ++++--
 .../InventoryStuff/ToggleRotateImage.cs       |  23 ++
 .../InventoryStuff/ToggleRotateImage.cs.meta  |  11 +
 6 files changed, 481 insertions(+), 32 deletions(-)
 create mode 100644 Assets/Images/Arrow_down.png
 create mode 100644 Assets/Images/Arrow_down.png.meta
 create mode 100644 Assets/Scripts/InventoryStuff/ToggleRotateImage.cs
 create mode 100644 Assets/Scripts/InventoryStuff/ToggleRotateImage.cs.meta

diff --git a/Assets/Images/Arrow_down.png b/Assets/Images/Arrow_down.png
new file mode 100644
index 00000000..6049debb
--- /dev/null
+++ b/Assets/Images/Arrow_down.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:aa2f9c6f2c5e5005720aec2ab6fd503e607cd14bd8e60043d0d3732178eddb59
+size 1294
diff --git a/Assets/Images/Arrow_down.png.meta b/Assets/Images/Arrow_down.png.meta
new file mode 100644
index 00000000..8a721b42
--- /dev/null
+++ b/Assets/Images/Arrow_down.png.meta
@@ -0,0 +1,122 @@
+fileFormatVersion: 2
+guid: 0dd96be67678e2f47a77a0528b8e0073
+TextureImporter:
+  internalIDToNameTable: []
+  externalObjects: {}
+  serializedVersion: 11
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    sRGBTexture: 1
+    linearTexture: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapsPreserveCoverage: 0
+    alphaTestReferenceValue: 0.5
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: 0.25
+    normalMapFilter: 0
+  isReadable: 0
+  streamingMipmaps: 0
+  streamingMipmapsPriority: 0
+  vTOnly: 0
+  ignoreMasterTextureLimit: 0
+  grayScaleToAlpha: 0
+  generateCubemap: 6
+  cubemapConvolution: 0
+  seamlessCubemap: 0
+  textureFormat: 1
+  maxTextureSize: 2048
+  textureSettings:
+    serializedVersion: 2
+    filterMode: 1
+    aniso: 1
+    mipBias: 0
+    wrapU: 1
+    wrapV: 1
+    wrapW: 0
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 1
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: 0.5, y: 0.5}
+  spritePixelsToUnits: 128
+  spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+  spriteGenerateFallbackPhysicsShape: 1
+  alphaUsage: 1
+  alphaIsTransparency: 1
+  spriteTessellationDetail: -1
+  textureType: 8
+  textureShape: 1
+  singleChannelComponent: 0
+  flipbookRows: 1
+  flipbookColumns: 1
+  maxTextureSizeSet: 0
+  compressionQualitySet: 0
+  textureFormatSet: 0
+  ignorePngGamma: 0
+  applyGammaDecoding: 0
+  platformSettings:
+  - serializedVersion: 3
+    buildTarget: DefaultTexturePlatform
+    maxTextureSize: 2048
+    resizeAlgorithm: 0
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+    androidETC2FallbackOverride: 0
+    forceMaximumCompressionQuality_BC6H_BC7: 0
+  - serializedVersion: 3
+    buildTarget: Standalone
+    maxTextureSize: 2048
+    resizeAlgorithm: 0
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+    androidETC2FallbackOverride: 0
+    forceMaximumCompressionQuality_BC6H_BC7: 0
+  - serializedVersion: 3
+    buildTarget: Server
+    maxTextureSize: 2048
+    resizeAlgorithm: 0
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+    androidETC2FallbackOverride: 0
+    forceMaximumCompressionQuality_BC6H_BC7: 0
+  spriteSheet:
+    serializedVersion: 2
+    sprites: []
+    outline: []
+    physicsShape: []
+    bones: []
+    spriteID: 5e97eb03825dee720800000000000000
+    internalID: 0
+    vertices: []
+    indices: 
+    edges: []
+    weights: []
+    secondaryTextures: []
+    nameFileIdTable: {}
+  spritePackingTag: 
+  pSDRemoveMatte: 0
+  pSDShowRemoveMatteOption: 0
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Resources/Prefabs/UI/Facts/Factscreen.prefab b/Assets/Resources/Prefabs/UI/Facts/Factscreen.prefab
index 235ba987..c980771c 100644
--- a/Assets/Resources/Prefabs/UI/Facts/Factscreen.prefab
+++ b/Assets/Resources/Prefabs/UI/Facts/Factscreen.prefab
@@ -77,6 +77,83 @@ MonoBehaviour:
   m_FillOrigin: 0
   m_UseSpriteMesh: 0
   m_PixelsPerUnitMultiplier: 1
+--- !u!1 &2979354555938402983
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 7432823498290307782}
+  - component: {fileID: 3074710513750764627}
+  - component: {fileID: 2683390173571617878}
+  m_Layer: 5
+  m_Name: Background
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &7432823498290307782
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2979354555938402983}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 2908476680003779928}
+  m_Father: {fileID: 3181479646584942007}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &3074710513750764627
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2979354555938402983}
+  m_CullTransparentMesh: 1
+--- !u!114 &2683390173571617878
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2979354555938402983}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
 --- !u!1 &3076546450216322697
 GameObject:
   m_ObjectHideFlags: 0
@@ -289,6 +366,82 @@ MonoBehaviour:
     type: 3}
   prefab_TestFact: {fileID: 2846439484187545958, guid: 5dc76e187eae4214697491bfb42773e8,
     type: 3}
+--- !u!1 &4600560360496770457
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 2908476680003779928}
+  - component: {fileID: 706978178464878509}
+  - component: {fileID: 1740725454024321523}
+  m_Layer: 5
+  m_Name: Checkmark
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &2908476680003779928
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4600560360496770457}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 7432823498290307782}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: -10, y: -10}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &706978178464878509
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4600560360496770457}
+  m_CullTransparentMesh: 1
+--- !u!114 &1740725454024321523
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4600560360496770457}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.31132078, g: 0.31132078, b: 0.31132078, a: 1}
+  m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 21300000, guid: 0dd96be67678e2f47a77a0528b8e0073, type: 3}
+  m_Type: 0
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
 --- !u!1 &5020678014906925761
 GameObject:
   m_ObjectHideFlags: 0
@@ -395,8 +548,9 @@ RectTransform:
   m_LocalScale: {x: 1, y: 1, z: 1}
   m_ConstrainProportionsScale: 0
   m_Children:
-  - {fileID: 5743690260981541286}
+  - {fileID: 3181479646584942007}
   - {fileID: 4370335918965838469}
+  - {fileID: 5743690260981541286}
   m_Father: {fileID: 3581652732795482907}
   m_RootOrder: 0
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@@ -479,7 +633,7 @@ RectTransform:
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
   m_AnchorMin: {x: 0, y: 0.5}
   m_AnchorMax: {x: 0, y: 0.5}
-  m_AnchoredPosition: {x: 10, y: 0}
+  m_AnchoredPosition: {x: 60, y: 0}
   m_SizeDelta: {x: 150, y: 40}
   m_Pivot: {x: 0, y: 0.5}
 --- !u!114 &4267244877370467227
@@ -775,6 +929,118 @@ MonoBehaviour:
   m_FillOrigin: 0
   m_UseSpriteMesh: 0
   m_PixelsPerUnitMultiplier: 1
+--- !u!1 &8554441590530137953
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 3181479646584942007}
+  - component: {fileID: 3455615182660834939}
+  - component: {fileID: 7247437569943128573}
+  m_Layer: 5
+  m_Name: AscDescToggle
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &3181479646584942007
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8554441590530137953}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 7432823498290307782}
+  m_Father: {fileID: 744038102396434867}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0.5}
+  m_AnchorMax: {x: 0, y: 0.5}
+  m_AnchoredPosition: {x: 10, y: 0}
+  m_SizeDelta: {x: 40, y: 40}
+  m_Pivot: {x: 0, y: 0.5}
+--- !u!114 &3455615182660834939
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8554441590530137953}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 0
+    m_WrapAround: 0
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 0
+  m_Colors:
+    m_NormalColor: {r: 0, g: 0, b: 0, a: 0.27450982}
+    m_HighlightedColor: {r: 0, g: 0, b: 0, a: 0.39215687}
+    m_PressedColor: {r: 0, g: 0, b: 0, a: 0.50980395}
+    m_SelectedColor: {r: 0, g: 0, b: 0, a: 0.27450982}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Selected
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 2683390173571617878}
+  toggleTransition: 0
+  graphic: {fileID: 0}
+  m_Group: {fileID: 0}
+  onValueChanged:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 3581652732795482906}
+        m_TargetAssemblyTypeName: DisplayFacts, Assembly-CSharp
+        m_MethodName: AscDescChanged
+        m_Mode: 2
+        m_Arguments:
+          m_ObjectArgument: {fileID: 3455615182660834939}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.UI.Toggle, UnityEngine.UI
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+  m_IsOn: 0
+--- !u!114 &7247437569943128573
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8554441590530137953}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 7206e8172594200478e26a3e33882072, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  targetGraphic: {fileID: 2908476680003779928}
 --- !u!1 &8566369655810908591
 GameObject:
   m_ObjectHideFlags: 0
@@ -806,7 +1072,7 @@ RectTransform:
   m_Children:
   - {fileID: 6245319588001950992}
   m_Father: {fileID: 744038102396434867}
-  m_RootOrder: 0
+  m_RootOrder: 2
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
   m_AnchorMin: {x: 1, y: 0.5}
   m_AnchorMax: {x: 1, y: 0.5}
diff --git a/Assets/Scripts/InventoryStuff/DisplayFacts.cs b/Assets/Scripts/InventoryStuff/DisplayFacts.cs
index cac01a98..744c331c 100644
--- a/Assets/Scripts/InventoryStuff/DisplayFacts.cs
+++ b/Assets/Scripts/InventoryStuff/DisplayFacts.cs
@@ -15,8 +15,9 @@ public class DisplayFacts : MonoBehaviour
     [SerializeField] private Transform factscreenContent;
     [SerializeField] private GameObject factSpotPrefab;
 
-    private bool showOnlyFavorites = false;
+    private bool sortDescending = false;
     private bool showGrouped = false;
+    private bool showOnlyFavorites = false;
 
     [Header("FactPrefabs")]
     public GameObject prefab_Point;
@@ -78,14 +79,21 @@ void Start()
     }
     #endregion UnityMethods
 
-    #region Implementationö
+    #region Implementation
     public void AddFact(Fact fact) {
-        // index where the new display would be inserted if in showGroup is active
-        int siblingIdx = 0;
+        // index where the new display will be inserted
+        int siblingIdx = sortDescending ? 0 : factscreenContent.childCount;
         if (showGrouped)
         {
             var facts = GetChildObjects(factscreenContent.transform).Select(c => c.GetComponentInChildren<FactWrapper>().fact).ToList();
-            siblingIdx = GetIndexInSortedList(fact, facts);
+            if (!sortDescending)
+                siblingIdx = GetIndexInSortedList(fact, facts);
+            else
+            {
+                facts.Reverse();
+                var _siblingIdx = GetIndexInSortedList(fact, facts);
+                siblingIdx = factscreenContent.childCount - _siblingIdx;
+            }
         }
 
         // create display
@@ -96,9 +104,7 @@ public void AddFact(Fact fact) {
         // disable if showOnlyFavorites is true and fact is no favorite
         display.transform.parent.gameObject.SetActive(!(showOnlyFavorites && !display.GetComponent<FactFavorisation>().IsFavorite));
         
-        // if showGrouped is true: move to correct ordered position
-        if (showGrouped)
-            display.transform.parent.transform.SetSiblingIndex(siblingIdx);
+        display.transform.parent.transform.SetSiblingIndex(siblingIdx);
     }
 
     private GameObject CreateDisplay(Transform transform, Fact fact)
@@ -119,31 +125,20 @@ public void AnimateFact(Fact fact) {
         factIcon.GetComponentInChildren<ImageHintAnimation>().AnimationTrigger();
     }
 
-
-    #region Favorites
-    public void FavoritesFilterChanged(Toggle t)
+    #region Sorting
+    #region AscDesc
+    public void AscDescChanged(Toggle t)
     {
-        showOnlyFavorites = t.isOn;
-        if (!showOnlyFavorites) // show all
-            displayedFacts.Values.ToList().ForEach(nFav => nFav.transform.parent.gameObject.SetActive(!showOnlyFavorites));
-        else
+        sortDescending = !sortDescending;
+
+        // revert current order
+        var children = GetChildObjects(factscreenContent.transform);
+        foreach (var child in children)
         {
-            // hide not favorites
-            var notFavorites = displayedFacts.Values.Where(go => !go.GetComponent<FactFavorisation>().IsFavorite).ToList();
-            notFavorites.ForEach(nFav => nFav.transform.parent.gameObject.SetActive(false));
+            child.SetAsFirstSibling();
         }
     }
-
-    private void OnFavoriteChange(Fact changedFact, bool isFavourite)
-    {
-        if (!showOnlyFavorites)
-            return;
-
-        var id = changedFact.Id;
-        if (displayedFacts.ContainsKey(id))
-            displayedFacts[id].transform.parent.gameObject.SetActive(isFavourite);
-    }
-    #endregion Favorites
+    #endregion AscDesc
 
     #region Grouping
     public void GroupingChanged(Toggle t)
@@ -160,6 +155,9 @@ public void GroupingChanged(Toggle t)
         else
             ordered = vals.OrderBy(tr => displayedFacts.Keys.ToList().IndexOf(tr.GetComponentInChildren<FactWrapper>().fact.Id)).ToList();
 
+        if (sortDescending)
+            ordered.Reverse();
+
         for (int i = 0; i < ordered.Count; i++)
             ordered[i].transform.SetSiblingIndex(i);
     }
@@ -187,6 +185,32 @@ public int Compare(Fact x, Fact y)
         }
     }
     #endregion Grouping
+    #endregion Sorting
+
+    #region Favorites
+    public void FavoritesFilterChanged(Toggle t)
+    {
+        showOnlyFavorites = t.isOn;
+        if (!showOnlyFavorites) // show all
+            displayedFacts.Values.ToList().ForEach(nFav => nFav.transform.parent.gameObject.SetActive(!showOnlyFavorites));
+        else
+        {
+            // hide not favorites
+            var notFavorites = displayedFacts.Values.Where(go => !go.GetComponent<FactFavorisation>().IsFavorite).ToList();
+            notFavorites.ForEach(nFav => nFav.transform.parent.gameObject.SetActive(false));
+        }
+    }
+
+    private void OnFavoriteChange(Fact changedFact, bool isFavourite)
+    {
+        if (!showOnlyFavorites)
+            return;
+
+        var id = changedFact.Id;
+        if (displayedFacts.ContainsKey(id))
+            displayedFacts[id].transform.parent.gameObject.SetActive(isFavourite);
+    }
+    #endregion Favorites
 
     #region Helper
     private static List<Transform> GetChildObjects(Transform parent)
diff --git a/Assets/Scripts/InventoryStuff/ToggleRotateImage.cs b/Assets/Scripts/InventoryStuff/ToggleRotateImage.cs
new file mode 100644
index 00000000..fdb3bfb2
--- /dev/null
+++ b/Assets/Scripts/InventoryStuff/ToggleRotateImage.cs
@@ -0,0 +1,23 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+[ExecuteInEditMode]
+public class ToggleRotateImage : MonoBehaviour {
+    [SerializeField] Transform targetGraphic; 
+
+    Toggle _toggle;
+    Toggle toggle
+    {
+        get { return _toggle ?? (_toggle = GetComponent<Toggle>()); }
+    }
+
+    void Awake()
+    {
+        toggle.onValueChanged.AddListener(OnTargetToggleValueChanged);
+    }
+
+    void OnTargetToggleValueChanged(bool on)
+    {
+        targetGraphic.rotation = on ? Quaternion.Euler(0, 0, 180) : Quaternion.identity;
+    }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/InventoryStuff/ToggleRotateImage.cs.meta b/Assets/Scripts/InventoryStuff/ToggleRotateImage.cs.meta
new file mode 100644
index 00000000..a0a4a44a
--- /dev/null
+++ b/Assets/Scripts/InventoryStuff/ToggleRotateImage.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7206e8172594200478e26a3e33882072
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
-- 
GitLab