├── .github └── FUNDING.yml ├── CHANGELOG.md ├── CHANGELOG.md.meta ├── LICENSE.md ├── LICENSE.md.meta ├── README.md ├── README.md.meta ├── Source.meta ├── Source ├── IGUIItem.cs ├── IGUIItem.cs.meta ├── LayoutController.cs ├── LayoutController.cs.meta ├── QFSW.QGUI.asmdef ├── QFSW.QGUI.asmdef.meta ├── QGUILayout.cs └── QGUILayout.cs.meta ├── package.json └── package.json.meta /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: QFSW 2 | patreon: QFSW 3 | custom: paypal.me/QFSW 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | V1.0.1 2 | 3 | Addition 0001: added QGUILayout.LabelAuto 4 | Bug Fix 0001: fixed ReserveHorizontal not accounting for padding properly 5 | 6 | V1.0.0 7 | 8 | Initial release -------------------------------------------------------------------------------- /CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 731ffc25efcc97944a4c179ffff13cfe 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 QFSW 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 | -------------------------------------------------------------------------------- /LICENSE.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e8a9fd034744e9c46baa44961e39a4b5 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QGUI ![](https://img.shields.io/github/issues-closed-raw/QFSW/QGUI.svg?color=51c414) ![](https://img.shields.io/github/issues-raw/QFSW/QGUI.svg?color=c41414&style=popout) 2 | A simple but effective IMGUI library for the Unity Engine for when EditorGUILayout is unavailable. It was created for internal use within my various tools and plugins 3 | - [Quantum Console](https://assetstore.unity.com/packages/tools/utilities/quantum-console-128881) 4 | - [Quantum Hierarchy](https://github.com/QFSW/QuantumHierarchy) 5 | 6 | QGUI provides the `LayoutController` that eases working with Rects by being able to reserve the demanded space within the rect, automatically applying padding and offsets for you 7 | 8 | ### Example Usage 9 | 10 | The following is an example of using QGUI's `LayoutController` to emulate a `HorizontalLayoutGroup` where `EditorGUILayout` is unavailable 11 | 12 | `EditorGUILayout` 13 | 14 | ```csharp 15 | EditorGUILayout.BeginHorizontal(); 16 | val1 = EditorGUILayout.Toggle(label1, val1, GUILayout.Width(100)); 17 | val2 = EditorGUILayout.Toggle(label2, val2); 18 | EditorGUILayout.EndHorizontal(); 19 | ``` 20 | 21 | `QGUI` 22 | 23 | ```csharp 24 | LayoutController layout = new LayoutController(rect); 25 | val1 = EditorGUI.Toggle(layout.ReserveHorizontal(100), label1, val1); 26 | val2 = EditorGUI.Toggle(layout.CurrentRect, label2, val2); 27 | ``` 28 | 29 | ### Installation via Package Manager 30 | 31 | #### 2019.3+ 32 | Starting with Unity 2019.3, the package manager UI has support for git packages 33 | 34 | Click the `+` to add a new git package and add `https://github.com/QFSW/QGUI.git` as the source 35 | 36 | #### 2018.3 - 2019.2 37 | To install via package manager, add the file `Packages/manifest.json` and add the following line to the `"dependencies"` 38 | ``` 39 | "com.qfsw.qgui": "https://github.com/QFSW/QGUI.git" 40 | ``` 41 | Your file should end up like this 42 | ``` 43 | { 44 | "dependencies": { 45 | "com.qfsw.qgui": "https://github.com/QFSW/QGUI.git", 46 | ... 47 | }, 48 | } 49 | ``` 50 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 70f5b99b2eae95b4ebace7089ac9ac24 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Source.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 35977e093b957054ab3ff49cc6e55694 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Source/IGUIItem.cs: -------------------------------------------------------------------------------- 1 | namespace QFSW.QGUI 2 | { 3 | public interface IGUIItem 4 | { 5 | void DrawGUI(LayoutController layout); 6 | } 7 | } -------------------------------------------------------------------------------- /Source/IGUIItem.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c8a5c4ade951bcc439706f59d5f8d7b2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Source/LayoutController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEditor; 3 | using UnityEngine; 4 | 5 | namespace QFSW.QGUI 6 | { 7 | public class LayoutController 8 | { 9 | public static float HorizontalPadding => 4; 10 | public static float RowPadding => EditorGUIUtility.standardVerticalSpacing; 11 | public static float RowHeight => EditorGUIUtility.singleLineHeight; 12 | 13 | public bool IsValid 14 | { 15 | get 16 | { 17 | if (_currentRect.width < 0) { return false; } 18 | if (_currentRect.height < 0) { return false; } 19 | if (_currentRect.x < TotalDrawRect.x) { return false; } 20 | if (_currentRect.y < TotalDrawRect.y) { return false; } 21 | if (_currentRect.x + _currentRect.width > TotalDrawRect.x + TotalDrawRect.width) { return false; } 22 | if (_currentRect.y + _currentRect.height > TotalDrawRect.y + TotalDrawRect.height) { return false; } 23 | 24 | return true; 25 | } 26 | } 27 | 28 | public Rect TotalDrawRect { get; } 29 | public Rect CurrentRect => _currentRect; 30 | 31 | private Rect _currentRect; 32 | private readonly Stack _undoStack = new Stack(); 33 | 34 | public LayoutController(Rect drawRect) 35 | { 36 | TotalDrawRect = drawRect; 37 | _currentRect = drawRect; 38 | _currentRect.height = RowHeight; 39 | } 40 | 41 | private void PushToUndoStack() 42 | { 43 | _undoStack.Push(_currentRect); 44 | } 45 | 46 | public void Undo() 47 | { 48 | if (_undoStack.Count > 0) 49 | { 50 | _currentRect = _undoStack.Pop(); 51 | } 52 | } 53 | 54 | public Rect BeginNewLine() 55 | { 56 | PushToUndoStack(); 57 | _currentRect.y += RowPadding + RowHeight; 58 | _currentRect.x = TotalDrawRect.x; 59 | _currentRect.width = TotalDrawRect.width; 60 | return _currentRect; 61 | } 62 | 63 | public Rect ReserveHorizontal(float width) 64 | { 65 | Rect drawRect = _currentRect; 66 | drawRect.width = width; 67 | 68 | PushToUndoStack(); 69 | width += HorizontalPadding; 70 | _currentRect.x += width; 71 | _currentRect.width -= width; 72 | 73 | return drawRect; 74 | } 75 | 76 | public Rect ReserveHorizontalPercentage(float widthPercentage) 77 | { 78 | float width = _currentRect.width * widthPercentage; 79 | return ReserveHorizontal(width); 80 | } 81 | 82 | public Rect ReserveHorizontalReversed(float width) 83 | { 84 | Rect drawRect = _currentRect; 85 | drawRect.x += drawRect.width; 86 | drawRect.x -= width; 87 | drawRect.width = width; 88 | 89 | PushToUndoStack(); 90 | width += HorizontalPadding; 91 | _currentRect.width -= width; 92 | 93 | return drawRect; 94 | } 95 | 96 | public Rect ReserveHorizontalReversedPercentage(float widthPercentage) 97 | { 98 | float width = _currentRect.width * widthPercentage; 99 | return ReserveHorizontalReversed(width); 100 | } 101 | 102 | public Rect ResizeRectHeight(Rect rect, float height) 103 | { 104 | rect.y += (rect.height - height) / 2; 105 | rect.height = height; 106 | 107 | return rect; 108 | } 109 | 110 | public Rect ReserveHorizontal(float width, float height) 111 | { 112 | return ResizeRectHeight(ReserveHorizontal(width), height); 113 | } 114 | 115 | public Rect ReserveHorizontalReversed(float width, float height) 116 | { 117 | return ResizeRectHeight(ReserveHorizontalReversed(width), height); 118 | } 119 | 120 | public Rect ReserveSquare() 121 | { 122 | return ReserveHorizontal(RowHeight); 123 | } 124 | 125 | public Rect ReserveSquareReversed() 126 | { 127 | return ReserveHorizontalReversed(RowHeight); 128 | } 129 | 130 | public Rect ReserveAuto(GUIContent content, GUIStyle style) 131 | { 132 | Vector2 size = style.CalcSize(content); 133 | return ReserveHorizontal(size.x, size.y); 134 | } 135 | 136 | public Rect ReserveAutoReversed(GUIContent content, GUIStyle style) 137 | { 138 | Vector2 size = style.CalcSize(content); 139 | return ReserveHorizontalReversed(size.x, size.y); 140 | } 141 | 142 | public void SpliceRow(int colCount, ref Rect[] rects) 143 | { 144 | float width = _currentRect.width / colCount; 145 | for (int i = 0; i < rects.Length; i++) 146 | { 147 | rects[i] = ReserveHorizontal(width); 148 | } 149 | } 150 | 151 | public Rect[] SpliceRow(int colCount) 152 | { 153 | Rect[] rects = new Rect[colCount]; 154 | SpliceRow(colCount, ref rects); 155 | return rects; 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /Source/LayoutController.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 023e4c58eff2d4c4aa4fea1cd338c7ed 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Source/QFSW.QGUI.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "QFSW.QGUI", 3 | "references": [], 4 | "optionalUnityReferences": [], 5 | "includePlatforms": [ 6 | "Editor" 7 | ], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": false, 10 | "overrideReferences": false, 11 | "precompiledReferences": [], 12 | "autoReferenced": true, 13 | "defineConstraints": [] 14 | } -------------------------------------------------------------------------------- /Source/QFSW.QGUI.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 07a6494aeec726b43b82feaed858492e 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Source/QGUILayout.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor; 3 | using UnityEngine; 4 | 5 | namespace QFSW.QGUI 6 | { 7 | public static class QGUILayout 8 | { 9 | public static T EnumPopup(T selected, params GUILayoutOption[] options) where T : struct, Enum 10 | { 11 | return (T)EditorGUILayout.EnumPopup(selected, options); 12 | } 13 | 14 | public static T EnumPopup(GUIContent content, T selected, params GUILayoutOption[] options) where T : struct, Enum 15 | { 16 | return (T)EditorGUILayout.EnumPopup(content, selected, options); 17 | } 18 | 19 | public static T EnumFlagsField(GUIContent content, T enumValue, params GUILayoutOption[] options) where T : struct, Enum 20 | { 21 | return (T)EditorGUILayout.EnumFlagsField(content, enumValue, options); 22 | } 23 | 24 | public static bool ButtonAuto(GUIContent content, GUIStyle style) 25 | { 26 | Vector2 size = style.CalcSize(content); 27 | return GUILayout.Button(content, style, GUILayout.Width(size.x)); 28 | } 29 | 30 | public static bool ButtonAuto(LayoutController layout, GUIContent content, GUIStyle style) 31 | { 32 | Rect rect = layout.ReserveAuto(content, style); 33 | return GUI.Button(rect, content, style); 34 | } 35 | 36 | public static void LabelAuto(GUIContent content, GUIStyle style) 37 | { 38 | Vector2 size = style.CalcSize(content); 39 | GUILayout.Label(content, style, GUILayout.Width(size.x)); 40 | } 41 | 42 | public static void LabelAuto(LayoutController layout, GUIContent content, GUIStyle style) 43 | { 44 | Rect rect = layout.ReserveAuto(content, style); 45 | GUI.Label(rect, content, style); 46 | } 47 | 48 | public static Vector2 GetMaxContentSize(GUIStyle style, params GUIContent[] contents) 49 | { 50 | Vector2 maxSize = new Vector2(); 51 | foreach (GUIContent content in contents) 52 | { 53 | Vector2 size = style.CalcSize(content); 54 | maxSize.x = Mathf.Max(maxSize.x, size.x); 55 | maxSize.y = Mathf.Max(maxSize.y, size.y); 56 | } 57 | 58 | return maxSize; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Source/QGUILayout.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f264e8ded685e3441b4003fd44ea5139 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.qfsw.qgui", 3 | 4 | "displayName": "QGUI", 5 | "author": "QFSW", 6 | "description": "A simple but effective IMGUI library for when EditorGUILayout is unavailable.", 7 | 8 | "bugs": { 9 | "email": "support@qfsw.co.uk", 10 | "url": "https://github.com/QFSW/QGUI/issues" 11 | }, 12 | 13 | "version": "1.0.1", 14 | "unity": "2018.3", 15 | 16 | "license": "LICENSE.md", 17 | "readme": "README.md" 18 | } -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c7e7c25c45596e043bf35afcb4bbb611 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------