New UI Widgets

Appreciate that, is there a usage sample or how do we actually use it?

Like this:

public class TestSafeArea : MonoBehaviour
{
	[SerializeField]
	SafeArea area;

	[SerializeField]
	RectTransform left;

	[SerializeField]
	RectTransform right;

	[SerializeField]
	RectTransform top;

	[SerializeField]
	RectTransform bottom;

	void Start()
	{
		area.OnScreenChange.AddListener(UpdateBorders);
	}

	void OnDestroy()
	{
		if (area != null)
		{
			area.OnScreenChange.RemoveListener(UpdateBorders);
		}
	}

	void UpdateBorders(SafeArea.Borders borders)
	{
		UpdateBorder(left, borders.Left);
		UpdateBorder(right, borders.Right);
		UpdateBorder(top, borders.Top);
		UpdateBorder(bottom, borders.Bottom);
	}

	void UpdateBorder(RectTransform rt, Rect rect)
	{
		if (rt == null)
		{
			return;
		}
		rt.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Left, rect.xMin, rect.width);
		rt.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Bottom, rect.yMin, rect.height);
	}

Result:
The safe area is dark.
The left and right RectTransforms are green and outside of the safe area.
The top and bottom RectTransforms are blue and also outside of the safe area. In this orientation, the top has zero height and not visible.

1 Like

Released v1.17.15

Changelog:

  • InputAdapter: added workaround to properly update layout because TMP_InputField does not call LayoutRebuilder.MarkLayoutForRebuild() when it should be
  • ListView: the RetainScrollPosition option now correctly works with the enabled ReversedOrder option
  • Project Settings: removed performance impact on enter/exit play mode
  • Rating: fixed error on Value = 0
  • Rating: now interactable works properly
  • SafeArea: added OnScreenChange event with information about borders
  • Swipe: added OnTap event
  • UIThemes: added the “Attach UI Only” option in “Project Settings… / UI Themes”, if enabled ThemeTarget component will be added only to game objects with RectTransform component

Hi there, I have a strange issue with the rounded corners component. On Windows, adding the rounded corners with a border does not affect the background colour of the image. On Mac though, the exact same thing causes the background colour to be washed out, as though the rounded corners component was overlaid on top.

I’ve tried changing position of the rounded corners within the game object but it makes no difference.

Is this something known?

As an example, two images below, first one is on Windows and you can see both images are same colour. The second image is on Mac and you can see the image with the border is washed out. Removing the rounded corners component completely fixes everything.

Thank you so much, all the best, John

Please try to replace UIRoundedCorners.shader in the New UI Widgets / Assets / Shaders with the attached version.
Upd.: All shaders fixed in v1.17.16b1.

If it does not solve the problem, please tell me what settings you are using for both Windows and Mac:

  • Unity version
  • Color Space (Project Settings… / Player / Rendering)
  • HDR (OS settings)

You can also try changing the Color Space and HDR to check if it fixes the problem; this will help find the cause of the problem.

Oh wow that was so fast, thank you.

Yes this is working correctly now!

For reference I am using:

Unity 6 (6000.0.28f1)
Color Space Linear
Built in RP
Mac mini m4, Sequoia 15.1.1

John

Good.
I fixed all other shaders in the v1.17.16b1.

Just to confirm, Safe area set its size with pivot in centre and anchors to bottom left?
Now lets suppose i have one safe area component and whenever it gets updated on OnScreenChange. I have multiple other rectransforms which i want to then set so they appear like safe area (rather than using multiple safe area components)

So a code example that set x, y and width height with anchors to bottom left.

Thanks

In the callback for the OnScreenChange event add such code to copy RectTransform values from SafeArea component to other:

foreach (var target_rt in RectTransforms)
{
	target_rt.anchorMin = safearea_rt.anchorMin;
	target_rt.anchorMax = safearea_rt.anchorMax;
	target_rt.sizeDelta = safearea_rt.sizeDelta;
	target_rt.anchoredPosition = safearea_rt.anchoredPosition;
}
1 Like

So when this event triggers safe area component’d have already set its position and everything, right?

Yes, the event triggers after position and size are set.

1 Like

Hey, it’s been a while, I’ve played a lot more with the asset, tested it and have some thoughts and found some bugs. I hope I don’t bore you with questions and the feedback will be useful.

  1. With reference to that problem you helped me with then, to only display one item per page:

I added the ListViewDefaultItemAutoResize component as you recommended and everything works as long as the ‘Default Item’ does not have the anchors set to ‘Stretch’. When the object is not Anchored everything works, but it’s much harder to adjust items inside the Default Item when we resize the parent object (List/Page/Canvas). I think it’s worth adding a safety feature to the ListViewDefaultItemAutoResize component that checks if the Default Item is not anchored (or e.g. remove anchors for the Default Item on Awake()), otherwise all sorts of weird things happen. Not anchored (difficult to work with):

Looking at this problem of only displaying one item on a single page, I find the workflow with this component in general to be unintuitive. And I find this case quite standard, but that’s my own opinion. Without your help, I certainly wouldn’t have solved it myself. What do you think? Is it possible to simplify it somehow? Maybe integrate it into the ListViewPaginator component?

  1. Shader bug

UIRoundedCorners.shader
UIRoundedCornersX4.shader

The VR application throws an error when building. There is simply a typo in the i->IN shader.

  1. Vertex color always in gamma color space

I think I have a similar problem to the colleague above. When I use the corner rounding component on elements, the colour of the whole element changes to not what it is in Inspector. With that recent fix, has the problem been resolved?

  1. I either dynamically add items to the ListViewCustom using ListViewCustom.Add(…) or I change the whole DataSource. How do I scroll the ListView to the very bottom? What ListView control options do I have?

I need this for the In-Game Console, which is based on a ListView and dynamically adds new logs as they appear. The logic I would like is that if the console is scrolled to the very bottom (the last item visible) then the console automatically scrolls to the bottom when new logs appear. However, when the user has scrolled somewhere higher, then it no longer scrolls automatically until the user scrolls to the very bottom of the console again. Exactly the same mechanics as the console built into Unity ;p

  1. Data Bind for Unity support

I like your asset ‘New UI Widgets’ so much that until I switch directly to UI Toolkit, I use it on every personal and corporate project. I saw that you have support for the ‘Data Bind for Unity’ package, I’ve always been looking for something similar (I’m jealous that UI Toolkit has it built in :P). I convinced a company to buy ‘Data Bind’ and have started using it for about 3 weeks now.

I have a problem with a custom ListView. I have managed to use the ContextHolder on the main ListView object so as to bind the DataSource, however I am unable to bind the ‘Default Item’ element. I would like the ‘Default Item’ to also use data bind as it is in the Data Bind asset example. They use the [DB] Game Object Items Setter component, and on the ‘Item Unity’ prefab itself they have another [DB] Context Holder which already points to the context of the specific item. How to do this in conjunction with New UI Widgets? My guess is that this [DB] Game Object Items Setter sets this context for individual items. I couldn’t find anything similar in the auto-generated DataBindSupport folder. Could you please direct me?

Root collection object:

Item setter:

Item context holder:

6 Last thing, could you add fields to the ‘Widget Generator’ window:

  • root write folder path - where to generate the scripts (you can see from the screenshot that, for example, I would like to have the auto-generated scripts in the UI folder)
  • widget namespace - namespace where the auto-generated scripts should be placed
  • widget editor namespace - namespace where the auto-generated editor scripts should be placed (currently I have only seen the ‘MenuOptions[T]’ script)
  • optionally specify the assembly definition for the ‘Editor’ folder, see I have an assembly reference next to the ‘MenuOptionsLogMessageData’ file on the screenshot, it’s nice if the generation process creates an assembly reference to this assembly if specified, otherwise I get a generation error, create the assembly reference manually and only then the error is fixed

Unless you are suggesting a different file structure, it seems to me though that such options would be a good extension to the widget generation window, which I personally use often :smiley:

Here’s another suggestion I picked up from the Unity Atoms package, where they also have a script generator. As there would be a lot of fields in the Widget Generator, maybe it would be better to just make the generator in the form of a ScriptableObject (instead of a separate window like now), where all the settings of a given type generation would be preserved? Screenshot of what I mean (ScriptableObject storing generation settings with (Re)Generate button):

=====
Thanks for making it to the end! :smiley:

Greetings, IceTrooper

Can you give more details on this? For now, I do not fully understand the problem.

I’ll think about how it can be simplified.

Thanks, fixed in v1.17.16b2

Yes, it should be fixed.

Added the KeepScrollAtBottom option in v1.17.16b2.

The ListView{DataType}Component script displays item data, so in most cases, DataBind is unnecessary.

In case you need this:

  • create a context script
  • add an event to the component script
  • create a provider script
  • add created provider components, ContextDataUpdater and ContextHolder with your context script to the DefaultItem game object

ListViewIconsItemDescription and ListViewIconsItemComponent should be replaced with your types.

Context script:

using Slash.Unity.DataBind.Core.Data;
using UIWidgets;

public class DefaultItemContext : Context
{
	private readonly Property<ListViewIconsItemDescription> itemProperty = new Property<ListViewIconsItemDescription>();

	public ListViewIconsItemDescription Item
	{
		get => itemProperty.Value;
		set => itemProperty.Value = value;
	}
}

Changes in component script:

public UnityEvent OnItemChanged = new UnityEvent(); // added line

public virtual void SetData(ListViewIconsItemDescription item)
{
	Item = item;
	OnItemChanged.Invoke(); // added line

Provider script:

using Slash.Unity.DataBind.Foundation.Providers.Getters;
using UIWidgets;
using UnityEngine;

[AddComponentMenu("Data Bind/New UI Widgets/Getters/[DB] ListViewIconsItemComponent Item Provider")]
public class DefaultItemProvider : ComponentDataProvider<ListViewIconsItemComponent, ListViewIconsItemDescription>
{
	protected override void AddListener(ListViewIconsItemComponent target) => target.OnItemChanged.AddListener(OnTargetValueChanged);

	protected override ListViewIconsItemDescription GetValue(ListViewIconsItemComponent target) => target.Item;

	protected override void RemoveListener(ListViewIconsItemComponent target) => target.OnItemChanged.RemoveListener(OnTargetValueChanged);
}

Then add those components to the DefaultItem:

I’ll think about it.
There are a few possible problems with it:

  • currently, file and class names are unique because they are relative to folder and namespace, but custom names can have duplicates, which will cause script errors or override wrong files
  • ScriptableObject is not a very good solution: the data type can be renamed, and ScriptableObject will not work after it because it uses the old name. It is possible to add those settings as the data type’s attributes, as done for the fields and properties.

Hi @ilih
please make following classes partial in next update (no hurry though), as as everytime i import, i hv to make them partial myself.

  • RatingStar
  • Switch
  • Swipe

I’ll add it.
Is it cannot be solved with extension methods?

1 Like

Actually im using it for these reasons, for example

    public partial class RatingStar:IRectTransformCached, ILayoutElement, IMultiSelectable, IPoolAbleClassAuto

    public partial class Swipe:IPoolAbleClassAuto, IRectTransformCached

But i can live “switch” without being partial
Thanks

Ok, I understand.

1 Like