PGButton with image

Hi!!
i try to add an image to a button without text, but the PGButton is flat and the image has a wrong ratio. i’d like to not set the nodepath’s scale manually.
is there a way to workaround my problem?
My code is this

    PT(PGButton) MyButton = new PGButton("button");
    MyButton->setup("", 0.1);
    MyButton->get_region()->set_suppress_flags(MouseWatcherRegion::SF_mouse_button);
    PT(Texture) ButtonReady=TexturePool::load_texture("but.jpg");
 
    PGFrameStyle MyStyle=MyButton->get_frame_style(0);
    MyStyle.set_type(PGFrameStyle::T_flat);
    MyStyle.set_uv_width(128, 128);
   
    MyStyle.set_texture(ButtonReady); MyButton->set_frame_style(0,MyStyle);
    MyStyle.set_texture(ButtonReady); MyButton->set_frame_style(1,MyStyle);
    MyStyle.set_texture(ButtonReady); MyButton->set_frame_style(2,MyStyle);
    MyStyle.set_texture(ButtonReady); MyButton->set_frame_style(3,MyStyle);

    NodePath path = window->get_aspect_2d().attach_new_node(MyButton);
    path.set_scale(1, 1, 2.5); // i set manually here. it's ugly

The PGButton object contains no code to scale an image automatically, but you can write that code yourself, for instance by using NodePath::calc_tight_bounds().

David

I see NodePath::calc_tight_bounds set the min_point and max_point to origin.
Do i override PGButton::calc_tight_bounds method to set my size?

Oh, I’m sorry, I misunderstood your original question. You’re trying to scale the button to match the aspect ratio of the original image file, not trying to scale the button to fit some pre-loaded geometry object.

Use Texture::get_orig_file_x_size() and Texture::get_orig_file_y_size() to determine the appropriate aspect ratio for your button.

David

like this?

[code]
float ratio = ButtonReady->get_orig_file_y_size() / ((float)ButtonReady->get_orig_file_x_size());
cout << ratio << endl;
path.set_scale(0.1ratio, 1, 0.1ratio
);


My texture is 128x128. the ratio is 1. but the image in the button isn't right!!

What do you mean? Is the button not square by default?

David

i do this

    PT(PGButton) button = new PGButton("button");
    button->setup(str, 0.1);
    PT(Texture) ButtonReady=TexturePool::load_texture("but.jpg"); 
  
    PGFrameStyle MyStyle=button->get_frame_style(0); 
    MyStyle.set_type(PGFrameStyle::T_flat);
    
    MyStyle.set_texture(ButtonReady); button->set_frame_style(0,MyStyle); 
    
    NodePath path = window->get_aspect_2d().attach_new_node(button);
    float ratio = ButtonReady->get_orig_file_y_size() / ((float)ButtonReady->get_orig_file_x_size());
    cout << ratio << endl;
    path.set_scale(0.1*ratio, 1, 0.1*ratio);

but the displayed button isn’t square!

PGButton::setup(string) will try to shape the button to fit the given string.

Instead of that, use the PGButton::setup() method that receives a NodePath, and pass it a NodePath that you know is square. For instance, use CardMaker to generate a square. In fact, you could then apply the texture to that square and not have to use PGFrameStyle::set_texture(). (This depends on precisely what look you want to achieve.)

Or, instead of using PGButton::setup(), just use PGButton::set_frame() to specify a square button directly.

David

i have used this

    PT(PGButton) button = new PGButton("button");
    
    PT(Texture) ButtonReady=TexturePool::load_texture("but.jpg"); 
    float ratio = ButtonReady->get_orig_file_y_size() / ((float)ButtonReady->get_orig_file_x_size());
    button->set_frame(LVecBase4(-1/ratio, 1/ratio, -ratio, ratio));
  
    PGFrameStyle MyStyle=button->get_frame_style(0); 
    MyStyle.set_type(PGFrameStyle::T_flat);
    
    MyStyle.set_texture(ButtonReady); button->set_frame_style(0,MyStyle); 
    
    NodePath path = window->get_aspect_2d().attach_new_node(button);
    path.set_scale(0.1);

it’s correct?!

I think you want something more like this:

button->set_frame(LVecBase4(-1, 1, -ratio, ratio)); 

instead of having ratio on both sides. But, yeah, it looks more-or-less correct. Does it work?

David

right!
thanks a lot!!
like always!!! (i think that it says so… :wink: )