Updating a textblock
I have a textblock and I'd like to change its label based on mouse clicks elsewhere, in code.
For instance:
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?
For instance:
Code: Select all
TextBlock* pTextblock= NsStaticCast<TextBlock*>(fe->FindName("TB"));
pTextblock->SetValue<NsString>(TextBlock::TextProperty,"hello");
Yet the GUI doesn't update in response to that. What else needs to happen here?
-
-
sfernandez
Site Admin
- Posts: 2908
- Joined:
Re: Updating a textblock
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.
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
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
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.
Thanks.
Re: Updating a textblock
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:
I am accessing it via code in the spinning cube example provided with Noesis. I'm getting different results depending on the location.
If I put this in before the atexit in the initialization code, the 'hello' persists as the label on the textblock.
It does not update the textblock label if instead the code is put into the render code before the renderer update: i.e.
So I'm not sure how to dynamically update the textblock.
Thanks in advance for any help.
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:
Code: Select all
<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>
Code: Select all
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");
Code: Select all
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.
Code: Select all
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();
}
Thanks in advance for any help.
-
-
sfernandez
Site Admin
- Posts: 2908
- Joined:
Re: Updating a textblock
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):
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.

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):
Code: Select all
Ptr<IUIResource> guiResource = NsDynamicCast< Ptr<IUIResource> >(NsGetSystem<IResourceSystem>()->Load("Gui/Samples/SDKTutorial/UIgl.xaml"));

Re: Updating a textblock
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.
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
Sure, we love suggestions from our users.
Who is online
Users browsing this forum: Bing [Bot] and 4 guests