Michael_J
Topic Author
Posts: 20
Joined: 02 Apr 2014, 14:22

Creating a button dynamically (C++)

24 Aug 2014, 04:18

Hi. Sorry if this is a noob question:

I'm trying to create a button dynamically and add it to a loaded XAML via this code:

.h
void someCLICKevent(Noesis::Core::BaseComponent* obj, const Noesis::Gui::RoutedEventArgs& args);

Noesis::Ptr<Noesis::Gui::Button> someBTN;
.cpp

void someCLICKevent(Noesis::Core::BaseComponent* obj, const Noesis::Gui::RoutedEventArgs& args)
{
   std::cout << "I've been clicked" << endl;
}

someBTN = *new Noesis::Gui::Button();															
someBTN->SetWidth(40);
someBTN->SetHeight(40);
someBTN->SetVisibility(Noesis::Gui::Visibility_Visible);
someBTN->SetClickMode(Noesis::Gui::ClickMode_Press);
SOMEcanvas->GetChildren()->Add(someBTN .GetPtr());

someBTN->Click() += Noesis::Core::MakeDelegate(this, &DISPLAYShmd::someCLICKevent);
.XAML
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="1000" Height="800" HorizontalAlignment="Left" Margin="0" VerticalAlignment="Top" Background="#FF000000" TextElement.FontSize="14" TextElement.Foreground="Black">

   <Canvas x:Name="SOMEcanvas" Width="1000" Height="800" Canvas.Left="0" Canvas.Top="0">
   </Canvas>
</Canvas>
(Of course, I just cut an pasted the relevant bits of code above)

Everything about creating the button, adding it to the "SOMEcanvas" sub-canvas and having it display works fine. However, when you mouse over it or click it it does nothing. It acts like a static object rather than a button. Buttons that were created in the XAML work fine.

My assumption is that I'm simply overlooking something? Any help would be appreciated. Thanks...

NOTE 1: The reason for the sub-canvas is that the UI in question will have multiple pages, which is very easy to manage simply by hiding or showing the appropriate sub-canvas, obviously.

NOTE 2: I AM updating the location of this button every few frames using SetRenderTransform() as its location in the display is based off the location of a 3D element in the game world. Not sure if that matters or not, but thought I should mention it regardless.

Finally, as a side question, is there a way to make an image click-able? I mean, I can add an image to a button's content and it works fine. I was just wondering if there was a more efficient means... Thanks again...
 
User avatar
jsantos
Site Admin
Posts: 2904
Joined: 20 Jan 2012, 17:18
Contact:

Re: Creating a button dynamically (C++)

25 Aug 2014, 00:03

Hi Michael,

At first I don't see anything wrong. But I am not in front of a computer right now to test the code. One question, does this also happen if you don't change the RenderTransform?

Regarding the click-able image, yes, the button approach is correct. Although if you want to change the visual effects when clicking, hovering, etc you need to provide a style for it. If you need help here just tell us.
 
Michael_J
Topic Author
Posts: 20
Joined: 02 Apr 2014, 14:22

Re: Creating a button dynamically (C++)

25 Aug 2014, 00:43

Yes, still happens regardless if I transform the button or not--I get no reaction from it when I hover or click.

That was my assumption with the click-able image--just wanted to verify. Thanks...
 
User avatar
jsantos
Site Admin
Posts: 2904
Joined: 20 Jan 2012, 17:18
Contact:

Re: Creating a button dynamically (C++)

25 Aug 2014, 13:21

I have created a small sample, using your XAML and your button creation code (without attaching the delegate) and the button works properly. When the mouse hover the button changes visually.

More questions to corner this problem:
  • If the button is created in XAML, does it change the representation on mouse hover?
  • Is this a render to texture?
  • Is the button using the default style?
Thanks!
 
Michael_J
Topic Author
Posts: 20
Joined: 02 Apr 2014, 14:22

Re: Creating a button dynamically (C++)

25 Aug 2014, 14:33

1. If the button is created in XAML then yes, it works properly. I suppose if I had to I could pre-build, say, 20 placeholders and hide them until needed, but creating exactly what is needed at run-time seems more elegant, obviously :)

2. Yes, this is a render to texture (part of an MFD display)

3. Yes, I'm using the default style for everything right now just as placeholder.

I tried creating the button without the delegate and I still get the same results, so it's not that...

Thank you
 
User avatar
jsantos
Site Admin
Posts: 2904
Joined: 20 Jan 2012, 17:18
Contact:

Re: Creating a button dynamically (C++)

25 Aug 2014, 14:39

Yes, of course. Prebuilding the placeholders would be a hack. :)

I need you to do another fast test. Could you create one button in the XAML and another one by code and verify that only the button declared in the XAML is reacting properly?
 
Michael_J
Topic Author
Posts: 20
Joined: 02 Apr 2014, 14:22

Re: Creating a button dynamically (C++)

25 Aug 2014, 15:30

I'm already doing that. There are buttons created in the same XAML directly (mainly the MFD mode buttons) and these work fine. It's definitely the buttons created at run-time that have the issue.

I've also tried creating the dynamic buttons WITHOUT the image content just to make sure that wasn't an issue. No help...
 
Michael_J
Topic Author
Posts: 20
Joined: 02 Apr 2014, 14:22

Re: Creating a button dynamically (C++)

25 Aug 2014, 21:59

I think I found the problem:

Remember in my XAML I have the main canvas, and a sub-canvas.
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="1000" Height="800" HorizontalAlignment="Left" Margin="0" VerticalAlignment="Top" Background="#FF000000" TextElement.FontSize="14" TextElement.Foreground="Black">

   <Canvas x:Name="SubCanvas" Width="1000" Height="800" Canvas.Left="0" Canvas.Top="0">
   <Canvas/>

<Canvas/>
 
Using this code to get the main canvas:
uiRoot = renderer->GetXAML();
ROOTcanvas = NsDynamicCast<Noesis::Gui::Canvas*>(uiRoot);
If I try to create the buttons in the main canvas everything works FINE! If I try to create them in the sub-canvas is when things don't work. This is also true if I create the buttons directly in the XAML. If I create them in the sub-canvas, while it DOES work in the Noesis viewer it does NOT work in game.

Remember that I am using the Leadwerks wrapper (OpenGL). I don't know if the problem lies within that or somewhere within Noesis directly. That it works in the viewer leads me to think it MAY be the wrapper; but obviously that's only an assumption.

Hope this helps you reproduce it there...

Edit: I can reproduce this perfectly by moving buttons created in the XAML from the sub-canvas to the main canvas. They work in the main canvas, and they do NOT work in the sub-canvas. Again, I could work around this by putting everything in the main canvas an specifically hiding each elements when not needed; but again this seems less-than-elegant :)

Edit: I just tested using themes other than default--didn't help...
 
User avatar
sfernandez
Site Admin
Posts: 1912
Joined: 22 Dec 2011, 19:20

Re: Creating a button dynamically (C++)

26 Aug 2014, 02:33

Hi Michael, please add the following after adding the button to the "SubCanvas" (I assume SOMEcanvas variable points to that canvas):
Noesis::Gui::Panel::SetZIndex(SOMEcanvas.GetPtr(), 1000);
Maybe there is another panel that is blocking the buttons to receive the mouse events.
 
Michael_J
Topic Author
Posts: 20
Joined: 02 Apr 2014, 14:22

Re: Creating a button dynamically (C++)

26 Aug 2014, 03:33

Attempting the line above causes an "Expression must have class type" error. I did however try to apply this to each button after they were added but that did not help the situation.

That said, there currently are only two canvases right now, the main canvas and this one "SOMEcanvas" sub-canvas. There aren't any other large containers/elements to get in the way.

Thanks...

Who is online

Users browsing this forum: Bing [Bot] and 2 guests