IconComponent texture scaling

I’m using the IconComponent as the background for a Button. The base image size used in the IconComponent is larger than the desired button size, when the IconComponent is set as the background, the image does not appear to scale down to fit within the button size. I have HAlign and VAlign set to bottom left and overlay is set false.

Am I missing something or do I have to set the scale of the IconComponent manually in this case?

[java]
float moveRightWidth = (float)(settings.getWidth()) / 10f;
float moveRightHeight = moveRightWidth;
float moveRightLocationX = settings.getWidth() - moveRightWidth - 10f;
float moveRightLocationY = sliderBackgroundPic.getLocalTranslation().y + sliderBackgroundPic.getHeight() + 10f + 300f;

    GuiLayout layout = new SpringGridLayout(Axis.Y, Axis.X, FillMode.NONE, FillMode.EVEN);
    Container moveRightContainer = new Container(layout);
    moveRightContainer.setLocalTranslation(moveRightLocationX, moveRightLocationY, 0f);
    nodePositionControls.attachChild(moveRightContainer);

    IconComponent icon = new IconComponent("Interface/RightArrow.png");
    icon.setOverlay(false);
    icon.setHAlignment(HAlignment.LEFT);
    icon.setVAlignment(VAlignment.BOTTOM);
    
    // calculate icon scale to fit within desired button size
    Image iconImage = icon.getImageTexture().getImage();
    float scaleX = moveRightWidth / iconImage.getWidth();
    float scaleY = moveRightHeight / iconImage.getHeight();
    logger.log(Level.INFO, "button size x: {0}, y: {1}",
            new Object[]{moveRightWidth, moveRightHeight});
    logger.log(Level.INFO, "icon size x: {0}, y: {1}",
            new Object[]{iconImage.getWidth(), iconImage.getHeight()});
    logger.log(Level.INFO, "icon scale x: {0}, y: {1}",
            new Object[]{scaleX, scaleY});

// icon.setIconScale(Math.min(scaleX, scaleY));

    Button buttonMoveRight = new Button("");
    buttonMoveRight.setPreferredSize(new Vector3f(moveRightWidth, moveRightHeight, 0f));
    buttonMoveRight.setBackground(icon);
    moveRightContainer.addChild(buttonMoveRight);

[/java]

The log of the sizes are:
[java]
INFO: button size x: 80, y: 80
INFO: icon size x: 128, y: 128
INFO: icon scale x: 0.625, y: 0.625
[/java]

It may be a bug. Can you try setting the background before you set the preferred size and see if it changes anything?

You are trying to use this to add an icon to a button and not to make a stretchy background, right?

Actually, looking at the code again, IconComponent is designed purposely to keep the icon a specific size because it’s part of how the button is sized. It’s actually tricky for it to decide if it should stretch or just factor into the button’s size.

Call setIconScale() to set it to the size that you desire. I see that you have the commented out, though.

I originally had it in and it definitely makes the icon the right size. I had it commented out until I was sure I needed to do it.

@iwgeric said: I originally had it in and it definitely makes the icon the right size. I had it commented out until I was sure I needed to do it.

Don’t let me forget to add an easier way to set an icon size in pixels.

I’d say sorry for necroing an old thread, but…

… so here’s the reminder. :wink:

I just hit this issue. Pretty standard setup, so I don’t think there’ll be any surprises, but here’s my use-case. I’m designing an icon set. All buttons share a common background (a 64x64 bullseye texture) image. Specific icons are made to be centered on top of this background - for example, there’s a checkmark icon for “accept” buttons, and these icons are saved as 64x64 PNGs without the background. This way, background changes don’t require reworking the entire icon set, and there’s greater flexibility at runtime for things like re-coloring and other goofiness. I’d like to just create a text-less button, set the background to the bullseye texture and the icon to whatever it’s supposed to be and then re-scale the entire shooting match to take up, say, 30x30 pixels on screen without having to separately scale the button/background at the icon. It’s not hard to get the same effect, but it adds extra clutter to my style file that would be nice to avoid.

I think you had me up until this last bit.

The proposed add-on in this thread would be something like a setIconSize() that essentially does the same thing as setIconScale() except it would determine the scale based on the current icon’s size. So if you setIconSize(64, 64) and then give it an icon that is 32, 32 it would internally scale by 2.

Would that help you?

It seems like maybe you are asking for something different since it’s a relatively small change to calling code to do one or the other when the IconComponent is created.

Yes, that’s exactly what I’m trying to describe. In my particular case (for this particular button) I’m trying to scale down, not up, but it’s the same situation - it would be really handy to express icon scale in terms of pixels rather than in terms of ratios of the original size.

Cool. It’s just your description of how you worked around it that confused me… because it’s generally just a one line change either way. One just requires math.

1 Like

And that’s what happens when I post when tired. :wink:

Totally… it would just (imho) make things slightly more pleasant to use if the math wasn’t needed and if it was consistent with the QuadBackgroundComponent usage.

Yes, I agree. I was just making sure we were talking about the same things.

Edit: though note that QuadBackgroundComponent fills a different role. And you can use that as an Icon too if that fits your needs better than IconComponent.

I added setIconSize() to IconComponent. You can use it if you build from Lemur master.

Commit: Added IconComponent.setIconSize() that will force the icon to be a pa… · jMonkeyEngine-Contributions/Lemur@6893a15 · GitHub

Commit where I add an Icon demo to the demo: Added a demo of the IconComponent to show how the different · jMonkeyEngine-Contributions/Lemur@2ac40c4 · GitHub

Screencap of it in action:

2 Likes

I’ve been using the latest release (1.10.1), but I might give a build from master a go in the next couple weeks.

Thanks for adding it!