Page 1 of 1

Updating a textblock

Posted: 10 May 2013, 15:09
by Zeitgeist
I have a textblock and I'd like to change its label based on mouse clicks elsewhere, in code.

For instance:
	TextBlock* pTextblock= NsStaticCast<TextBlock*>(fe->FindName("TB"));
	pTextblock->SetValue<NsString>(TextBlock::TextProperty,"hello");
I've also tried the SetText() variant, which from the documentation I'm assuming just calls the one above.

Yet the GUI doesn't update in response to that. What else needs to happen here?

Re: Updating a textblock

Posted: 10 May 2013, 15:33
by sfernandez
It's strange because we use the same code to modify the text in XamlPlayer stats panel.

I can only think in one possible scenario where a SetValue is not updated to the GUI, and is when the property is being animated. Animation values have more priority than local values.

If that is your case, just do a pTextblock->ClearAnimation<NsString>(TextBlock::TextProperty) before the SetValue.

Re: Updating a textblock

Posted: 11 May 2013, 01:30
by Zeitgeist
Thanks for the response. There's no animation involved here unfortunately; so I think the fault may be due to buffers, so I'll need to do some more digging to see what exactly is going on. And I can confirm that the code worked with a simpler test case.

Re: Updating a textblock

Posted: 11 May 2013, 15:00
by jsantos
Give us the xaml or the source code, here or privately, so that we can examine and verify if there is a bug or something being done wrong.

Thanks.

Re: Updating a textblock

Posted: 13 May 2013, 15:24
by Zeitgeist
Okay, I'm playing around with it some more. It seems to matter where the textblock setting code is called.

So I took the spinning cube sample from the opengl example from Noesis.

These four lines are what I'm using: There's a textblock with the following code added to the UIgl.xaml and built:
	<Grid HorizontalAlignment="Left" Margin="0,120,0,0" Width="176">
		<TextBlock x:Name="TB" Height="20" Margin="0,8,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Foreground="White" HorizontalAlignment="Center"/>
	</Grid>
I am accessing it via code in the spinning cube example provided with Noesis. I'm getting different results depending on the location.
			Ptr<IUIResource> guiResource = NsDynamicCast< Ptr<IUIResource> >(NsGetSystem<IResourceSystem>()->Load("Gui/Samples/SDKTutorial/UIgl.xaml"));
			FrameworkElement *fe = NsStaticCast<FrameworkElement*>(guiResource->GetRoot());
			TextBlock* pTextblock= NsStaticCast<TextBlock*>(fe->FindName("TB"));
			pTextblock->SetValue<NsString>(TextBlock::TextProperty,"hello");
If I put this in before the atexit in the initialization code, the 'hello' persists as the label on the textblock.
int main(int argc, char **argv)
{
  /* Creation of the window */
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  glutInitWindowSize(1000, 1000);
  glutCreateWindow("Spinning cube");
  
#ifdef NOESIS_GUI
    {
        // Install an error handler to catch any problem with NoesisGui
        Noesis::Core::SetErrorHandler(ErrorHandler);
        
        // Force the OpenGL renderer
        NsConfigValue("Render.RenderSystem", "Render", "GL");
        
        // Launch Noesis Kernel
        NsGetKernel()->Init();
        
        // Create a OpenGL context that will be used by NoesisGui.
        HDC hDC = wglGetCurrentDC();
        IGLRenderSystem::SetContext(hDC, wglCreateContext(hDC));
        NsGetKernel()->InitSystems();

        // Load the .xaml resource
        Ptr<IUIResource> guiResource = NsDynamicCast< Ptr<IUIResource> >(NsGetSystem<IResourceSystem>()->Load("Gui/Samples/SDKTutorial/UIgl.xaml"));
        gUIRoot.Reset(NsStaticCast<UIElement*>(guiResource->GetRoot()));

        // Create the UI renderer
        gUIRenderer = CreateRenderer(gUIRoot.GetPtr());
        gUIRenderer->SetAntialiasingMode(Noesis::Gui::AntialiasingMode_PPAA);
        FrameworkElement *fe = NsStaticCast<FrameworkElement*>(guiResource->GetRoot());
        TextBlock* pTextblock= NsStaticCast<TextBlock*>(fe->FindName("TB"));
        pTextblock->SetValue<NsString>(TextBlock::TextProperty,"hello");
        atexit(Shutdown);
    }
#endif




  /* OpenGL settings */
  glClearColor(0, 0, 0, 0);
  glEnable(GL_DEPTH_TEST);

  /* Declaration of the callbacks */
  glutDisplayFunc(&DisplayFunc);
  glutReshapeFunc(&ReshapeFunc);
  glutKeyboardFunc(&KeyboardFunc);
  glutMouseFunc(&MouseFunc);
  glutMotionFunc(&MouseMove);
  glutPassiveMotionFunc(&MouseMove);

  /* Loop */
  glutMainLoop();
  
  /* Never reached */
  return 0;
}

It does not update the textblock label if instead the code is put into the render code before the renderer update: i.e.
void		DisplayFunc(void)
{
  static float alpha = 0;

  /* Clear the buffer, clear the matrix */
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();

  /* A step backward, then spin the cube */
  glTranslatef(0, 0, -10);
  glRotatef(30, 1, 0, 0);
  glRotatef(alpha, 0, 1, 0);

  /* We tell we want to draw quads */
  glBegin(GL_QUADS);

  /* Every four calls to glVertex, a quad is drawn */
  glColor3f(0, 0, 0); glVertex3f(-1, -1, -1);
  glColor3f(0, 0, 1); glVertex3f(-1, -1,  1);
  glColor3f(0, 1, 1); glVertex3f(-1,  1,  1);
  glColor3f(0, 1, 0); glVertex3f(-1,  1, -1);

  glColor3f(1, 0, 0); glVertex3f( 1, -1, -1);
  glColor3f(1, 0, 1); glVertex3f( 1, -1,  1);
  glColor3f(1, 1, 1); glVertex3f( 1,  1,  1);
  glColor3f(1, 1, 0); glVertex3f( 1,  1, -1);

  glColor3f(0, 0, 0); glVertex3f(-1, -1, -1);
  glColor3f(0, 0, 1); glVertex3f(-1, -1,  1);
  glColor3f(1, 0, 1); glVertex3f( 1, -1,  1);
  glColor3f(1, 0, 0); glVertex3f( 1, -1, -1);

  glColor3f(0, 1, 0); glVertex3f(-1,  1, -1);
  glColor3f(0, 1, 1); glVertex3f(-1,  1,  1);
  glColor3f(1, 1, 1); glVertex3f( 1,  1,  1);
  glColor3f(1, 1, 0); glVertex3f( 1,  1, -1);

  glColor3f(0, 0, 0); glVertex3f(-1, -1, -1);
  glColor3f(0, 1, 0); glVertex3f(-1,  1, -1);
  glColor3f(1, 1, 0); glVertex3f( 1,  1, -1);
  glColor3f(1, 0, 0); glVertex3f( 1, -1, -1);

  glColor3f(0, 0, 1); glVertex3f(-1, -1,  1);
  glColor3f(0, 1, 1); glVertex3f(-1,  1,  1);
  glColor3f(1, 1, 1); glVertex3f( 1,  1,  1);
  glColor3f(1, 0, 1); glVertex3f( 1, -1,  1);

  /* No more quads */
  glEnd();

  /* Rotate a bit more */
  alpha = alpha + 0.1;

#ifdef NOESIS_GUI
    // Tick kernel
  Ptr<IUIResource> guiResource = NsDynamicCast< Ptr<IUIResource> >(NsGetSystem<IResourceSystem>()->Load("Gui/Samples/SDKTutorial/UIgl.xaml"));
  FrameworkElement *fe = NsStaticCast<FrameworkElement*>(guiResource->GetRoot());
  TextBlock* pTextblock= NsStaticCast<TextBlock*>(fe->FindName("TB"));
  pTextblock->SetValue<NsString>(TextBlock::TextProperty,"hello");
  NsGetKernel()->Tick();

    // Update renderer
    gUIRenderer->Update(glutGet(GLUT_ELAPSED_TIME) / 1000.0f);
    // ...Do something useful here because Update() is concurrent...
    RenderCommands* commands = gUIRenderer->WaitForUpdate(); 
    
    // Render
    gUIRenderer->Render(commands);
    // ...Do something useful here because Render() is concurrent...
    gUIRenderer->WaitForRender();
#endif

  /* End */
  glFlush();
  glutSwapBuffers();

  /* Update again and again */
  glutPostRedisplay();
}
So I'm not sure how to dynamically update the textblock.

Thanks in advance for any help.

Re: Updating a textblock

Posted: 14 May 2013, 02:25
by sfernandez
I found the problem.

You should save the pointer to the TextBlock during initialization, and in DisplayFunc you would use that pointer to update the text each frame.

If you Load the xaml resource on each frame (the following code):
Ptr<IUIResource> guiResource = NsDynamicCast< Ptr<IUIResource> >(NsGetSystem<IResourceSystem>()->Load("Gui/Samples/SDKTutorial/UIgl.xaml"));
You are getting a new instance of the entire UI tree, and the pointer returned by FindName refers to a TextBlock different from the one that is being updated and rendered by the IUIRenderer you created during initialization.

;)

Re: Updating a textblock

Posted: 14 May 2013, 02:48
by Zeitgeist
Thanks-- that makes sense, should have thought of that one and it fixed it!

I have another question (groan) about Noesis though. I'll post it in a different thread though since it's not really related to the above, but it's more about restructuring Noesis code.

Re: Updating a textblock

Posted: 14 May 2013, 05:57
by jsantos
Sure, we love suggestions from our users.