[OpenFL] How to set backgroundImage ( for button) for not embedded images?

Would it be possible to share your project ?

sure: https://haxeui.org/shared/haxeui-core-bitmap-buttons.zip

Background of the button is not hidden

You need to remove the background with a style (you dont need css for this technically, you could use custom style, but css makes it simpler :wink: )

On click position of the background not change

This you will need to use css for since its a state (ie, :down)

I can’t apply bitmap button data style ( Error: String should be haxe.ui.styles.Style )

Make sure you pull latest haxeui-core and haxeui-openfl

For completeness, here is my full app (2 files):

<vbox style="padding: 5px;">
    <style>
        .bitmap-button {
            color: #ffffff;
            background-color: none;
            border: none;
            padding: 15px 15px;
            
            background-image: lookup('bitmap-button-normal');
            background-image-slice-top: lookup('bitmap-button-slice-top');
            background-image-slice-left: lookup('bitmap-button-slice-left');
            background-image-slice-bottom: lookup('bitmap-button-slice-bottom');
            background-image-slice-right: lookup('bitmap-button-slice-right');
        }

        .bitmap-button .label, .bitmap-button .image {
            margin-top: -5px;
        }

        .bitmap-button:hover {
            background-image: lookup('bitmap-button-over');
        }

        .bitmap-button:down {
            background-position: 1px 1px;
        }

        .bitmap-button:down .label, .bitmap-button:down .image {
            margin-top: -4px;
            margin-left: 1px;
        }
    </style>
    <hbox>
        <button text="Bitmap Button" styleName="bitmap-button" width="120" height="50" />
        <vbox>
            <button text="Bitmap Button" styleName="bitmap-button" width="240" height="50" />
            <button text="Bitmap Button" styleName="bitmap-button" width="240" height="50" />
        </vbox>    
        <button text="Bitmap Button" styleName="bitmap-button" width="200" height="105" />
    </hbox>    

    <hbox>
        <button text="Bitmap Button (Autosized)" styleName="bitmap-button" />
        <button text="Bitmap Button (Fixed Width)\n\nWith a hard break" width="140" styleName="bitmap-button" />
        
        <grid columns="2">
            <button text="Left" styleName="bitmap-button" icon="haxeui-core/styles/default/haxeui_small.png" />
            <button text="Right" styleName="bitmap-button" icon="haxeui-core/styles/default/haxeui_small.png" iconPosition="right" />
            <button text="Top" styleName="bitmap-button" icon="haxeui-core/styles/default/haxeui_small.png" iconPosition="top" width="100%" />
            <button text="Bottom" styleName="bitmap-button" icon="haxeui-core/styles/default/haxeui_small.png" iconPosition="bottom" width="100%" />
        </grid>
    </hbox>    
</vbox>
package ;

import haxe.ui.containers.VBox;
import haxe.ui.styles.StyleLookupMap;
import openfl.display.BitmapData;
import openfl.geom.Matrix;

@:build(haxe.ui.ComponentBuilder.build("assets/main-view.xml"))
class MainView extends VBox {
    public function new() {
        super();
        
        var scale = .25;
        StyleLookupMap.instance.set("bitmap-button-normal", scaleBitmap(BitmapData.fromFile(Sys.getCwd() + "/../../../../assets/buttonBackground.png"), scale));
        StyleLookupMap.instance.set("bitmap-button-over", scaleBitmap(BitmapData.fromFile(Sys.getCwd() + "/../../../../assets/buttonBackground_over.png"), scale));
        StyleLookupMap.instance.set("bitmap-button-slice-top", 58 * scale);
        StyleLookupMap.instance.set("bitmap-button-slice-left", 75 * scale);
        StyleLookupMap.instance.set("bitmap-button-slice-bottom", 110 * scale);
        StyleLookupMap.instance.set("bitmap-button-slice-right", 400 * scale);
        
    }
    
    private function scaleBitmap(bitmap:BitmapData, scale:Float):BitmapData {
        var cx = Std.int(bitmap.width * scale);
        var cy = Std.int(bitmap.height * scale);
        
        var scaleX:Float = cx / bitmap.width;
        var scaleY:Float = cy / bitmap.height;
        var matrix:Matrix = new Matrix();
        matrix.scale(scaleX, scaleY);
        var resizedBitamp = new BitmapData(cx, cy);
        resizedBitamp.draw(bitmap, matrix, null, null, null, true);
        return resizedBitamp;
    }
}

image

OK, so i had to make a number of changes to your app to get it to work:

  • its styleNames not style to set the css style name, eg: bitmapButton.styleNames = "bitmap-button"
  • i had to change your loading order, the problem was you creating the buttons, which are expecting the bitmaps to be loaded (via lookup) but then you are loading the images and setting them in the map, so changed this to:
    private function drawGUI():Void 
    {
        Assets.loadBitmapData("img/btExample.png" ).onComplete(imageLoaded);
    }

    private function imageLoaded( bitmapData:BitmapData ):Void
        {
            if (bitmapData != null)
            {
                var scale = .25;
                StyleLookupMap.instance.set("bitmap-button-normal", scaleBitmap(bitmapData, scale));
                StyleLookupMap.instance.set("bitmap-button-over", scaleBitmap(bitmapData, scale));
                StyleLookupMap.instance.set("bitmap-button-slice-top", 58 * scale);
                StyleLookupMap.instance.set("bitmap-button-slice-left", 75 * scale);
                StyleLookupMap.instance.set("bitmap-button-slice-bottom", 110 * scale);
                StyleLookupMap.instance.set("bitmap-button-slice-right", 400 * scale);

                vbox = new VBox();
                vbox.x = 100;
                vbox.y = 100;
        
                testButton2 = new Button();
                testButton2.width = 120;
                testButton2.height = 50;
                testButton2.text = "Test2 button";
                testButton2.onClick =  function(e) { trace("onClick"); };
                testButton2.styleNames = "bitmap-button";
        
                bitmapButton = new Button();
                bitmapButton.width = 120;
                bitmapButton.height = 50;
                bitmapButton.text = "Bitmap button";
                bitmapButton.x = 400;
                bitmapButton.y = 400;
                bitmapButton.styleNames = "bitmap-button";
        
                vbox.addComponent(testButton2);
                vbox.addComponent(bitmapButton);
                Screen.instance.addComponent(vbox);
            }
        }
  • i changed the scaleBitmap function as it wasnt preserving transparency:
var resizedBitamp = new BitmapData(cx, cy, true, 0x00000000);

After that, everything seemed fine:
image

The buttons look dithered, but thats because (im assuming) of the openfl scaling for html5, you can fix that by adding <window width="0" height="0" if="html5" /> to your project / application.xml

image

Thank you!
Your example with lookup works, but I want to test the other case without lookup.

Creating button in drawGUI() and set the background image in imageLoaded. It mostly works, but when add backgroundImageSliceTop background image disappear.

The code is:

    private function drawGUI():Void 
    {
        vbox = new VBox();
        vbox.x = 100;
        vbox.y = 100;

        testButton2 = new Button();
        testButton2.width = 120;
        testButton2.height = 50;
        testButton2.text = "Test2 button";
		testButton2.onClick =  function(e) { trace("onClick"); };

        Assets.loadBitmapData("img/btExample.png" ).onComplete(imageLoaded);
        
        vbox.addComponent(testButton2);
		Screen.instance.addComponent(vbox);
    }
	
	
	 private function imageLoaded( bitmapData:BitmapData ):Void
        {
            if (bitmapData != null)
            {
                testButton2.styleNames = "bitmap-button";
                testButton2.backgroundImage = scaleBitmap(bitmapData, .25);
				// How to set with properties ?
				/*
				testButton2.backgroundImageSliceTop = 58 * .25;
				testButton2.backgroundImageSliceLeft = 75 * .25;
				testButton2.backgroundImageSliceBottom = 110 * .25;
				testButton2.backgroundImageSliceRight = 400 * .25;
				*/
				// Only customStyle supports ?
				testButton2.customStyle = {
                    backgroundImageSliceTop: 58 * .25,
                    backgroundImageSliceLeft: 75 * .25,
                    backgroundImageSliceBottom: 110 * .25,
                    backgroundImageSliceRight: 400 * .25
                };
			}
		}

I also remove from the css lookup function and now is:

.bitmap-button {
    color: #ffffff;
    background-color: none;
    border: none;
    padding: 15px 15px;  
 }

I think , I can’t set directly, as property , backgroundImageSliceTop, … left, …bottom, … right from the code and need to use customStyle ?

The problem i think is that custom style is replacing the style,

try something like:

testButton2.customStyle.backgroundImageSliceTop ...
...
...
...
1 Like

Yes, that works.
Thank you again and sorry for taking up so much of your time.

1 Like