Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[owo-ui] When the accumulated size of Sizing should be 100%, it could be greater due to rounding #311

Open
Zailer43 opened this issue Sep 23, 2024 · 0 comments

Comments

@Zailer43
Copy link
Contributor

Description

The Sizing#inflate method rounds values when using a sizing relative to screen size. This rounding can cause decimal values to be adjusted, resulting in multiple relative sizes potentially having a larger size than intended. This issue is particularly evident in an LTR flow layout, where components should sum to 100%.

While an LTR flow layout may seem like an unusual case for having components at 100%, in my scenario, I use it alongside an animation where components default to 50%. If they do not meet the minimum size, they expand to 100%, enhancing responsiveness for various screen sizes

public int inflate(int space, Function<Sizing, Integer> contentSizeFunction) {
return switch (this.method) {
case FIXED -> this.value;
case FILL, EXPAND -> Math.round((this.value / 100f) * space);
case CONTENT -> contentSizeFunction.apply(this) + this.value * 2;
};
}

Alternative Solution

One alternative solution could be to reduce each component's size by 1%

Attachments

Video_2024-09-23_18-34-44.mp4

Video code

@Override
    protected void build(FlowLayout rootComponent) {
        rootComponent.horizontalAlignment(HorizontalAlignment.CENTER).verticalAlignment(VerticalAlignment.CENTER);

        var ltrLayouts = Containers.verticalFlow(Sizing.fill(), Sizing.content());
        ltrLayouts.gap(4).margins(Insets.horizontal(10));

        for (int i = 2; i != 9; i++) {
            ltrLayouts.child(this.createLtrLayout(i));
        }

        Animation<?> animatable = ltrLayouts.horizontalSizing().animate(2000, Easing.LINEAR, Sizing.fill(50));
        AtomicBoolean animationState = new AtomicBoolean(false);

        var animateButton = Components.button(Text.literal("Animate"), buttonComponent -> {
            if (animationState.get()) {
                animatable.forwards();
            } else {
                animatable.reverse();
            }
            animationState.set(!animationState.get());
        });

        var addPadding = Components.button(Text.literal("+"), buttonComponent -> {
            Insets previousPadding = ltrLayouts.padding().get();
            ltrLayouts.padding(previousPadding.add(0, 0, 0, 1));
        });

        var removePadding = Components.button(Text.literal("-"), buttonComponent -> {
            Insets previousPadding = ltrLayouts.padding().get();
            if (previousPadding.right() > 0) {
                ltrLayouts.padding(previousPadding.add(0, 0, 0, -1));
            }
        });

        rootComponent.child(
                Containers.horizontalFlow(Sizing.content(), Sizing.content()).children(List.of(animateButton, addPadding, removePadding))
                .gap(4)
        );
        rootComponent.child(ltrLayouts);
    }

    private FlowLayout createLtrLayout(int childrenCount) {
        var result = Containers.ltrTextFlow(Sizing.expand(), Sizing.content());
        var list = this.divideByHundred(childrenCount);

        for (var percentage : list) {
            result.child(
                    Containers.horizontalFlow(Sizing.fill(percentage), Sizing.fixed(20))
                            .child(Components.label(Text.literal(percentage + "%")))
                            .surface(Surface.DARK_PANEL)
                            .padding(Insets.of(3))
            );
        }

        return result;
    }

    public List<Integer> divideByHundred(int count) {
        var result = new ArrayList<Integer>();
        if (count <= 0) {
            throw new IllegalArgumentException("Count must be greater than 0");
        }

        var base = 100 / count;
        var remainder = 100 % count;

        for (int i = 0; i < count; i++) {
            result.add(base);
            if (i < remainder) {
                result.set(i, result.get(i) + 1);
            }
        }

        return result;
    }

Versions

owo-lib = 0.12.14+1.21
fabric-api = 0.104.0+1.21.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant