OnChange mode doesn't work using initially hidden hierarchies and prefabs.
I also found that in Update() for OnChange, you need to set to add:
if (activeChildren.Count != activeChildCount)
m_bNeedsLateResize = true;
So that all children also get resized if any sizes changed due to the new child count.
And I think a helpful addition to Responsive item would be a way to also set the other axis as well. Example:
If I have a RC for horizontal axis and on a child I have a responsive item set to 20%, it would also be nice to be able to set the vertical size with options:
- None (don't modify height) - This is the current action.
- Fill - size to same as parent container
- a percentage of the the parent container height
You probably don't actually need #2 since you can get the same result with #3. Not sure if "Preferred" should be an option.
- Edited
dtappe Yes, this is what I actually added:
// Detects if children have been resized since last frame // or if this container have been resized // or if any children have been activated or deactivated float newFlexibleSpace = CalculateSpaceBetweenItemsY(true, false, out float totalFlexibleSpaceBetweenItemsPercent, out float minContainerHeightNeeded);
newFlexibleSpace += CalculateSpaceBetweenItemsX(true, false,
out totalFlexibleSpaceBetweenItemsPercent,
out minContainerHeightNeeded);
float newContainerSize = container.GetHeight() + container.GetWidth();
// detect if active children count has changed since last frame
List<RectTransform> activeChildren = GetChildrenFirstDepth(container);
bool activeChildrenCountChanged = activeChildren.Count != activeChildCount;
if (lastRefreshItemsSpace != newFlexibleSpace ||
lastRefreshContainerSize != newContainerSize ||
activeChildrenCountChanged ||
needsLateResize)
{
Resize(activeChildrenCountChanged || needsLateResize);
lastRefreshItemsSpace = newFlexibleSpace;
lastRefreshContainerSize = newContainerSize;
}
- Edited
Anthony float newContainerSize = container.GetHeight() + container.GetWidth();
Probably won't happen too often, but this will not always detect a size change. For example, if you started out with a square object and then reduced height by 5 and increased width by 5.
You may be better off just keeping both the height and width to do a comparison.
- Edited
FYI, I did just find that
float changedVal = CalculateSpaceBetweenItemsY(...)
can return a NaN, and that causes continuous refreshes.
Taking a quick look at the code, it would return a NaN everytime activeChildCount
was 1, and a negative number if it was 0. There may be other ways as well, I didn't look too close.
In the sample project I sent, you may want to change LoadFiles() to sometimes return an empty list so you can also test how the control changes. Something like the following is simple, but not very predictive:
var oFiles = (UnityEngine.Random.Range(0.0f, 1.0f) < 0.5f) ? new List<string>() : new List<string>()
{
"File_1",
"File_2",
"File_3",
"File_4",
"File_5",
"File_6",
"File_7",
};
You will see that as the new "error" row is added, the "Process" button moves up, but is not resized (nor are the other rows.
- Edited
Anthony,
I downloaded 1.0.4 and used it unmodified on the sample project. Here is a video that shows that when the "Process" button is pressed the newly visible objects are not properly contained within their parent containers.
I'm not sure how to make the sample project any simpler and still reproduce the issue. You should just be able to run it and press the "process" button to see this particular improper behavior.
The sample project is built to demonstrate using common Responsive UI prefabs in different UI layouts, which means the runtime view is different than the inspector view.
Here is the updated sample project as a package, with Exoa and TMP removed:
It will now toggle the behavior of "Process" between:
- Showing progress bar of files being processed.
- Showing an error that no files were found.
NOTE: The following functions still return NaNs when the division counts are 1, making a divide by 0 (Infinity) NaN. Also, if the counts are 0 or percentages are just over 100%, they make a Negative number which would also be bad. I believe these functions should only return >= 0 . This also applies to the "out" variables.
- CalculateSpaceBetweenItemsY
- CalculateSpaceBetweenItemsX
- CalculateFlexibleItemSpaceX
- CalculateFlexibleItemSpaceY
EDIT: I have some changes I made if you are interested in seeing them, just let me know where I should send them.
EDIT 2: I expect one problem may be that when the "Process" button is pressed and the active state of "Directory" and "Process" game object is changed, then parent of "Process" and "Directory" does not detect a change since there is still only 1 child active, but it is a different child than what was active previously. Possibly creating a hash of the active children using their UUID's may let this be detected.
I also notice that with the 1.0.4 update, the refresh type gets changed to "Manual", so no updates take place.
I'm not trying to offend you, just trying to offer some constructive criticism. You market this as a "Professional" tool, and as such, it needs the effort associated with a professional tool. This means you need to do full testing of changes, including edge cases and various scenarios, as well as regression testing so that you do not break existing projects when you post an update.
You have been very responsive to issues, which is VERY MUCH appreciated. You just need to spend more time verifying that changes work as expected and don't break other features or behavior of existing code.
dtappe Hi! Thanks for the feedback and new demo.
I tested my changes against my demo scenes and didn't notice issues. Now bugs and edge cases will always happen so that's why I opened this support forum and try to fix bugs as quick as possible.
Switching the refresh mode to manual on sub containers is a new feature to cascade the Resize() from parent to sub containers as you suggested.
I will look into your demo asap.
thanks!
ok so it turns out that this was causing the issue:
ResponsiveContainer parentRC = transform.parent.GetComponent<ResponsiveContainer>(); if (parentRC != null) { refreshType = RefreshType.Manual; }
Anthony,
I figured that was an issue. Seemed like changing to "Manual" mode behavior should be more of a run time thing and not changing actual configuration. For me, "Manual" should mean that the user is responsible for calling Resize, not some other mode.
Also FYI, on the above video, the button text is also not showing for the blue button. I believe this is also a responsive UI issue.
Sorry for the late response, I somehow missed your post notification.