{"id":13678637,"url":"https://github.com/sassembla/LayouTaro","last_synced_at":"2025-04-29T15:32:29.476Z","repository":{"id":141825093,"uuid":"248492375","full_name":"sassembla/LayouTaro","owner":"sassembla","description":"Unity UI Component layout kit.","archived":false,"fork":false,"pushed_at":"2021-04-01T03:44:01.000Z","size":101582,"stargazers_count":19,"open_issues_count":4,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-08-02T13:24:06.135Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sassembla.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-03-19T12:02:36.000Z","updated_at":"2024-07-07T01:21:38.000Z","dependencies_parsed_at":"2024-01-14T17:04:04.736Z","dependency_job_id":"3c5ec328-cadc-44f3-8f64-020589e1ff37","html_url":"https://github.com/sassembla/LayouTaro","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sassembla%2FLayouTaro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sassembla%2FLayouTaro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sassembla%2FLayouTaro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sassembla%2FLayouTaro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sassembla","download_url":"https://codeload.github.com/sassembla/LayouTaro/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224178984,"owners_count":17268983,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T13:00:56.382Z","updated_at":"2024-11-11T21:30:58.742Z","avatar_url":"https://github.com/sassembla.png","language":"C#","funding_links":[],"categories":["C#"],"sub_categories":[],"readme":"# LayouTaro\n\nThe UI layout library for Unity. \n\n![demo image](https://raw.githubusercontent.com/sassembla/LayouTaro/master/screenshot.png \"demo image\")\n\n\nThis library helps:\n* Defining your original elements of UI.\n* Layout it with your original Layouter with the support of BasicLayoutFunctions.\n\n\n## Example\n\nclone this repo and open Sample.scene, then Play unity.  above looking of UI will appear.\n\nsee LayouTaroSample.cs for knowing what's happen.\n\n```csharp\n// Box, Text, Image and Button elenents are already implemented in this sample. Also you can add or edit or delete these definition.\n\n// generate your own data structure with parameters for UI.\nvar box = BoxElement.GO(\n    null,// UI bg with image\n    () =\u003e\n    {\n        Debug.Log(\"root box element is tapped.\");\n    },\n    TextElement.GO(\"hannin is yasu! this is public problem\\U0001F60A! gooooooooooooood \"),// text.\n    ImageElement.GO(null),// image.\n    ButtonElement.GO(null, () =\u003e { Debug.Log(\"button is tapped.\"); })\n);\n\n// generate the layouter which you want to layout your structures.\nvar layouter = new MyLayouter();\n\n// set the default size of content.\nvar size = new Vector2(600, 100);\n\n// do layout with LayouTaro. the GameObject will be returned with layouted structure.\n\nbox = LayouTaro.Layout(\n    canvas.transform,\n    size,\n    box,\n    layouter\n);\n\ngo.transform.SetParent(canvas.transform);\ngo.GetComponent\u003cRectTransform\u003e().anchoredPosition = Vector2.zero;\n\n// update element values and re-layout with same GameObject.\n// box = LayouTaro.RelayoutWithUpdate(\n//     size,\n//     box,\n//     new Dictionary\u003cLTElementType, object\u003e {\n//         {LTElementType.Image, null},\n//         {LTElementType.Text, \"relayout!\"}\n//     },\n//     layouter\n// );\n```\n\nthis code shows the layouted UI. looks simple!. \n\n### Async version\n\nLayouTaro now supports async layout.\n\n```csharp\n// ready async elements.\nvar box = AsyncBoxElement.GO(\n    null,// bg画像\n    () =\u003e\n    {\n        Debug.Log(\"ルートがタップされた\");\n    },\n    AsyncTextElement.GO(\"hannin is yasu! this is public problem! gooooooooooooood\"),// テキスト\n    AsyncImageElement.GO(null),// 画像\n    AsyncButtonElement.GO(null, () =\u003e { Debug.Log(\"ボタンがタップされた\"); })\n);\n\n// generate async layouter.\nvar layouter = new BasicAsyncLayouter();\n\n// set size of content.\nvar size = new Vector2(600, 50);\n\n// do async layout with BasicMissingSpriteCache cache.\nvar done = false;\n\nLayouTaro.LayoutAsync\u003cBasicMissingSpriteCache\u003e(\n    canvas.transform,\n    size,\n    box,\n    layouter,\n    () =\u003e\n    {\n        done = true;\n    }\n);\n```\n\nthat's all.\n\n## Usage\n\n1. Use already defined element definition or define your original element of UI in LayouTaro/LayouTaroElements/LayoutElementType.cs.\n\n```csharp\nnamespace UILayouTaro\n{\n    // add your own element type and then implement the class which extends LTElement or LTRootElement. \n    public enum LTElementType\n    {\n        Box,\n        Image,\n        Text,\n        Button\n    }\n}\n```\n\n2. Define the type which extends LTElement (and adopt ILayoutableText | ILayoutableRect if need to express the element is rect or text.) \n\nfor example, TextElement is defined for example of the kind of UI text.\n\n```csharp\npublic class TextElement : LTElement, ILayoutableText\n{\n    public override LTElementType GetLTElementType()// set the LTElementType which you defined or already defined for detect \"which is this element\" by Layouter code.\n    {\n        return LTElementType.Text;\n    }\n\n    public string TextContent;\n\n    public static TextElement GO(string text)\n    {\n        var prefabName = \"LayouTaroPrefabs/Text\";\n        var res = Resources.Load(prefabName) as GameObject;\n        var r = Instantiate(res).AddComponent\u003cTextElement\u003e();\n\n        r.TextContent = text;\n        return r;\n    }\n\n    /*\n        Text() and GenerateGO methods are required by ILayoutableText.\n\n        this methods are available for your custom layouter.\n    */\n    public string Text()\n    {\n        return TextContent;\n    }\n\n    public GameObject GenerateGO(string text)\n    {\n        var element = GO(text);\n        return element.gameObject;\n    }\n}\n```\n\nin async version, you should use LTAsyncElement and LTRootAsyncElement instead of LTElement and LTRootElement.\n\n3. Define your original Layouter or use already defined sample Layouter(MyLayouter.cs) with implementing ILayouter interface.\n\nhere is example for implementation.\n\n```csharp\npublic class YourLayouter : ILayouter\n{\n    /*\n        Layout method will be called when the LayouTaro.Layout is called.\n        this requires layouting the root element and it's child elements.\n    */\n    public void Layout(Vector2 viewSize, out float originX, out float originY, GameObject rootObject, LTRootElement rootElement, LTElement[] elements, ref float currentLineMaxHeight, ref List\u003cRectTransform\u003e lineContents, ref Vector2 wrappedSize)\n    {\n        // start with initialize element pos.\n        originX = 0f;\n        originY = 0f;\n\n        var originalViewWidth = viewSize.x;\n\n        var viewWidth = viewSize.x;\n\n        // get root element instance from rootObject.\n        var root = rootObject.GetComponent\u003cYourRootElement\u003e();\n        var rootTrans = root.GetComponent\u003cRectTransform\u003e();\n\n        // layout child elements of root element.\n        for (var i = 0; i \u003c elements.Length; i++)\n        {\n            var element = elements[i];\n\n            var currentElementRectTrans = element.GetComponent\u003cRectTransform\u003e();\n            var restWidth = viewWidth - originX;\n\n            lineContents.Add(currentElementRectTrans);\n\n            // easy to load the type of element using GetLTElementType() method.\n            var type = element.GetLTElementType();\n            switch (type)\n            {\n                case LTElementType.YourImage:\n                    var yourImageElement = (YourImageElement)element;\n                    \n                    // do layout here. for example, BasicLayoutFunctions has some helper methods for layout. in this case, if YourImageElement implements ILayoutableRect, BasicLayoutFunctions helps layout for your rect element.\n                    BasicLayoutFunctions.RectLayout(\n                        yourImageElement,\n                        currentElementRectTrans,\n                        yourImageElement.RectSize(),\n                        viewWidth,\n                        ref originX,\n                        ref originY,\n                        ref restWidth,\n                        ref currentLineMaxHeight,\n                        ref lineContents\n                    );\n                    break;\n                case LTElementType.YourText:\n                    var yourTextElement = (YourTextElement)element;\n                    var contentText = youtTextElement.Text();\n\n                    // do layout here...\n                    break;\n                case LTElementType.YourButton:\n                    var yourButtonElement = (YourButtonElement)element;\n\n                    // do layout here...\n                    break;\n\n                case LTElementType.YourRoot:\n                    // do layout here...\n                    break;\n                default:\n                    Debug.LogError(\"unsupported element type:\" + type);\n                    break;\n            }\n        }\n\n        // layout last line if need. LayoutLastLine layouts the element which located the last line of all elements.\n        BasicLayoutFunctions.LayoutLastLine\u003cLTRootElement\u003e(ref originY, currentLineMaxHeight, ref lineContents);\n\n        // if you want to resize the root element to it's containing element size, you can do that here.\n        rootTrans.sizeDelta = new Vector2(wrappedSize.x + outsideSpacing * 2, wrappedSize.y + outsideSpacing * 2);\n    }\n\n    /*\n        UpdateValues method will be called when the LayouTaro.RelayoutWithUpdate is called.\n        this requires you to parse the updateValues which you passed to LayouTaro.RelayoutWithUpdate and need to set it to the once layouted elements.\n        \n        Updated elements will be re-layouted with updated values after the end of this method.\n    */\n    public void UpdateValues(LTElement[] elements, Dictionary\u003cLTElementType, object\u003e updateValues)\n    {\n        foreach (var e in elements)\n        {\n            switch (e.GetLTElementType())\n            {\n                case LTElementType.Image:\n                    var i = (ImageElement)e;\n\n                    // get value from updateValues and cast to the type what you set.\n                    var p = updateValues[LTElementType.Image] as Image;\n                    i.Image = p;\n                    break;\n                case LTElementType.Text:\n                    var t = (TextElement)e;\n\n                    // get value from updateValues and cast to the type what you set.\n                    var tVal = updateValues[LTElementType.Text] as string;\n                    t.TextContent = tVal;\n                    break;\n\n                default:\n                    break;\n            }\n        }\n    }\n```\n\n\n## Detecting and loading missing Character/Emoji/Mark from somewhere outside of the app\nuse async version and set IMissingSpriteCache-implemented class to LayoutAsync method.\n\nBasicMissingSpriteCache is the example of implementation of IMissingSpriteCache.\n\n```csharp\nLayouTaro.LayoutAsync\u003cBasicMissingSpriteCache\u003e(\n    canvas.transform,\n    size,\n    box,\n    layouter,\n    () =\u003e\n    {\n        done = true;\n    }\n);\n```\n\nyou can control the behaviour when missing emoji/mark or text comming.\n\n\n\n## About BasicLayoutFunction\nBasicLayoutFunction are implemented inside of the LayouTaro.\n\nThis functions helps:\n* automatic text line feed.\n* layouts rect with the rest of the width of view.\n* centerlize the elements by the highest element in the line of elements.\n\nand also async version do same things asynchronously.\n\n## Install\n\nuse [Releases.](https://github.com/sassembla/LayouTaro/releases)\n\n## License\n\nsee [here](https://raw.githubusercontent.com/sassembla/LayouTaro/master/LICENSE)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsassembla%2FLayouTaro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsassembla%2FLayouTaro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsassembla%2FLayouTaro/lists"}