-
- ngzaharias
- Posts: 11
- Joined:
How to make a custom TriggerAction
Hi there,
I've been trying to get a trigger action working without success.
(Custom Engine in C++, version 3.2.8-indie)
Using the samples as a reference I need to
1. Create a custom class that inherits from `NoesisApp::TriggerActionT<Noesis::DependencyObject>`
2. Implement the reflection in the .h and .cpp using `NS_DECLARE_REFLECTION` and `NS_IMPLEMENT_REFLECTION`
3. In the reflection, set the name and namespace for the action.
4. In the xaml, make an alias for the namespace using `xmlns:l="clr-namespace:..."`
5. Trigger the action using `<Button.Triggers> <EventTrigger ...> <l:Action ...>`
I've been trying to get a trigger action working without success.
(Custom Engine in C++, version 3.2.8-indie)
Using the samples as a reference I need to
1. Create a custom class that inherits from `NoesisApp::TriggerActionT<Noesis::DependencyObject>`
2. Implement the reflection in the .h and .cpp using `NS_DECLARE_REFLECTION` and `NS_IMPLEMENT_REFLECTION`
3. In the reflection, set the name and namespace for the action.
4. In the xaml, make an alias for the namespace using `xmlns:l="clr-namespace:..."`
5. Trigger the action using `<Button.Triggers> <EventTrigger ...> <l:Action ...>`
Code: Select all
// UIAction.h
#pragma once
#include <NsApp/TriggerAction.h>
#include <NsGui/DependencyObject.h>
namespace eng
{
class UIAction final : public NoesisApp::TriggerActionT<Noesis::DependencyObject>
{
protected:
Noesis::Ptr<Noesis::Freezable> CreateInstanceCore() const override;
void Invoke(Noesis::BaseComponent* parameter) override;
private:
NS_DECLARE_REFLECTION(UIAction, NoesisApp::TriggerActionT<Noesis::DependencyObject>)
};
}
Code: Select all
// UIAction.cpp
#include "EnginePCH.h"
#include "Engine/UIAction.h"
#include <NsCore/ReflectionImplement.h>
#include <NsGui/DependencyData.h>
Noesis::Ptr<Noesis::Freezable> eng::UIAction::CreateInstanceCore() const
{
return *new eng::UIAction();
}
void eng::UIAction::Invoke(Noesis::BaseComponent*)
{
Z_LOG(ELog::Debug, "UIAction");
}
NS_IMPLEMENT_REFLECTION(eng::UIAction, "eng.UIAction")
{
}
Code: Select all
// MainWindow.xaml
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:eng"
Width="400"
Height="200">
<Grid>
<Button Content="Click Me" Width="120" Height="40" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<local:UIAction/>
</EventTrigger>
</Button.Triggers>
</Button>
</Grid>
</Page>
Code: Select all
[NOESIS/INFO] Noesis Init v3.2.8 (Windows on x86_64 Profile)
[NOESIS/INFO] Inspector listening on port 17629
[NOESIS/INFO] 'Themes/Default.Brushes.xaml' loaded
[NOESIS/INFO] 'Themes/Default.Fonts.xaml' loaded
[NOESIS/INFO] 'Themes/Default.Styles.xaml' loaded
[NOESIS/INFO] 'Themes/Default.xaml' loaded
[NOESIS/ERROR] MainWindow.xaml(10,11): Unknown element type 'local:UIAction' (eng.UIAction)
[NOESIS/INFO] 'MainWindow.xaml' loaded
[NOESIS/INFO] 'pack://application:,,,/Noesis.GUI.Extensions;component/Theme/Fonts/#PT Root UI' loaded
[NOESIS/INFO] 'Themes/Default.Brushes.xaml' loaded
[NOESIS/INFO] 'Themes/Default.Fonts.xaml' loaded
[NOESIS/INFO] 'Themes/Default.Styles.xaml' loaded
[NOESIS/INFO] 'Themes/Default.xaml' loaded
[NOESIS/INFO] 'pack://application:,,,/Noesis.GUI.Extensions;component/Theme/Fonts/#PT Root UI' loaded
-
- ngzaharias
- Posts: 11
- Joined:
Re: How to make a custom TriggerAction
I've also tried using the example from the Samples with PlaySoundAction
Code: Select all
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:eng"
Width="400"
Height="200">
<b:Interaction.Triggers>
<b:EventTrigger EventName="Loaded">
<b:PlaySoundAction Source="Login.mp3" Volume="0.5"/>
</b:EventTrigger>
</b:Interaction.Triggers>
<Grid>
<Button Content="Click Me" Width="120" Height="40" HorizontalAlignment="Center" VerticalAlignment="Center">
</Button>
</Grid>
</Page>
Code: Select all
[NOESIS/INFO] Noesis Init v3.2.8 (Windows on x86_64 Profile)
[NOESIS/INFO] Inspector listening on port 17629
[NOESIS/INFO] 'Themes/Default.Brushes.xaml' loaded
[NOESIS/INFO] 'Themes/Default.Fonts.xaml' loaded
[NOESIS/INFO] 'Themes/Default.Styles.xaml' loaded
[NOESIS/INFO] 'Themes/Default.xaml' loaded
[NOESIS/ERROR] MainWindow.xaml(1,1): Unknown property type 'b:Interaction' (NoesisApp.Interaction)
[NOESIS/ERROR] MainWindow.xaml(7,3): Unknown property type 'b:Interaction' (NoesisApp.Interaction)
[NOESIS/INFO] 'MainWindow.xaml' loaded
[NOESIS/INFO] 'pack://application:,,,/Noesis.GUI.Extensions;component/Theme/Fonts/#PT Root UI' loaded
[NOESIS/INFO] 'Themes/Default.Brushes.xaml' loaded
[NOESIS/INFO] 'Themes/Default.Fonts.xaml' loaded
[NOESIS/INFO] 'Themes/Default.Styles.xaml' loaded
[NOESIS/INFO] 'Themes/Default.xaml' loaded
[NOESIS/INFO] 'pack://application:,,,/Noesis.GUI.Extensions;component/Theme/Fonts/#PT Root UI' loaded
Re: How to make a custom TriggerAction
Our C++ SDK includes the source code for the App Framework. It comes with many built-in actions, including the one you mentioned: PlaySoundAction. You can see how it is used in the Buttons sample.
Regarding the error you encountered:
Regarding the error you encountered:
This usually happens because your class hasn’t been registered in the factory. Every extension class must be registered before it can be used in XAML. Please check our samples to see the correct way to register your class.[NOESIS/ERROR] MainWindow.xaml(10,11): Unknown element type 'local:UIAction' (eng.UIAction)
-
- ngzaharias
- Posts: 11
- Joined:
Re: How to make a custom TriggerAction
Hi jsantos, thanks for taking the time to reply!
I'm trying to integrate with Noesis without using the App Framework since I would like to maintain control over windows. I've been trying to use the samples as a reference but I run into blockers that I assume means I've missed some implementation steps, however it is hard to understand exactly what was missed.
Is there something that the App Framework does that I will need to also ensure I do (so far I've followed the integration guide and sample).
On a separate note I'm currently getting the following errors.
The only things I can think of are
1. I'm using the wrong register function and I should be registering this with an Application like you do in the Samples.
(Looking at the macro behind this though, it is just registering it regularly).
2. I need an module + package to make use of these things.
3. I'm not inheriting from TriggerAction correctly.
4. I need to reflect a property or something else.
In the case of 3, below is my source code and can see that I do inherit from TriggerAction the same was that the PlaySoundAction does. The only difference is I don't make use of any properties.
I'm trying to integrate with Noesis without using the App Framework since I would like to maintain control over windows. I've been trying to use the samples as a reference but I run into blockers that I assume means I've missed some implementation steps, however it is hard to understand exactly what was missed.
Is there something that the App Framework does that I will need to also ensure I do (so far I've followed the integration guide and sample).
On a separate note I'm currently getting the following errors.
Code: Select all
[NOESIS/ERROR] MainWindow.xaml(11,11): Cannot add a 'eng.UIAction' to a 'TriggerActionCollection'
Code: Select all
// MainWindow.xaml
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:eng"
Width="400"
Height="200">
<Grid>
<Button Content="Click Me" Width="120" Height="40" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<local:UIAction/>
</EventTrigger>
</Button.Triggers>
</Button>
</Grid>
</Page>
1. I'm using the wrong register function and I should be registering this with an Application like you do in the Samples.
(Looking at the macro behind this though, it is just registering it regularly).
2. I need an module + package to make use of these things.
3. I'm not inheriting from TriggerAction correctly.
4. I need to reflect a property or something else.
In the case of 3, below is my source code and can see that I do inherit from TriggerAction the same was that the PlaySoundAction does. The only difference is I don't make use of any properties.
Code: Select all
// UIAction.h
#include <NsApp/TriggerAction.h>
#include <NsGui/DependencyObject.h>
namespace eng
{
class UIAction final : public NoesisApp::TriggerActionT<Noesis::DependencyObject>
{
public:
UIAction();
protected:
Noesis::Ptr<Noesis::Freezable> CreateInstanceCore() const override;
void Invoke(Noesis::BaseComponent* parameter) override;
private:
NS_DECLARE_REFLECTION(UIAction, NoesisApp::TriggerActionT<Noesis::DependencyObject>)
};
}
Code: Select all
// UIAction.cpp
#include "EnginePCH.h"
#include "Engine/UIAction.h"
#include <NsCore/ReflectionImplement.h>
#include <NsGui/DependencyData.h>
eng::UIAction::UIAction()
{
}
Noesis::Ptr<Noesis::Freezable> eng::UIAction::CreateInstanceCore() const
{
return *new eng::UIAction();
}
void eng::UIAction::Invoke(Noesis::BaseComponent*)
{
Z_LOG(ELog::Debug, "UIAction");
}
NS_IMPLEMENT_REFLECTION(eng::UIAction, "eng.UIAction")
{
NsMeta<Noesis::DependencyData>(Noesis::TypeOf<SelfClass>());
}
Re: How to make a custom TriggerAction
Before analyzing new problems, please try using PlaySoundAction first. Copy it from the app framework into your codebase, register it, and use it in a XAML file. This should work without any issues.
Regarding this error:
But let’s first get PlaySoundAction working. It will be easier to tackle the issues one at a time.
Regarding this error:
You are mixing core triggers with interactivity triggers. This distinction is explained in the Behaviors Tutorial.[NOESIS/ERROR] MainWindow.xaml(11,11): Cannot add a 'eng.UIAction' to a 'TriggerActionCollection'
But let’s first get PlaySoundAction working. It will be easier to tackle the issues one at a time.
-
- ngzaharias
- Posts: 11
- Joined:
Re: How to make a custom TriggerAction
Code: Select all
[NOESIS/INFO] Noesis Init v3.2.8 (Windows on x86_64 Profile)
[NOESIS/INFO] Inspector listening on port 17629
[NOESIS/INFO] 'Themes/Default.Brushes.xaml' loaded
[NOESIS/INFO] 'Themes/Default.Fonts.xaml' loaded
[NOESIS/INFO] 'Themes/Default.Styles.xaml' loaded
[NOESIS/INFO] 'Themes/Default.xaml' loaded
[NOESIS/ERROR] MainWindow.xaml(9,5): Unknown property type 'b:Interaction' (NoesisApp.Interaction)
[NOESIS/ERROR] MainWindow.xaml(10,7): Unknown property type 'b:Interaction' (NoesisApp.Interaction)
[NOESIS/INFO] 'MainWindow.xaml' loaded
[NOESIS/INFO] 'pack://application:,,,/Noesis.GUI.Extensions;component/Theme/Fonts/#PT Root UI' loaded
Code: Select all
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:eng"
Width="400"
Height="200">
<Grid>
<Button Content="Click Me" Width="120" Height="40" HorizontalAlignment="Center" VerticalAlignment="Center">
<b:Interaction.Triggers>
<b:EventTrigger EventName="Click">
<b:PlaySoundAction Source="Sounds/ExitButton.wav"/>
</b:EventTrigger>
</b:Interaction.Triggers>
</Button>
</Grid>
</Page>
Re: How to make a custom TriggerAction
If you are selectively picking things from the Application Framework, make you are registering and initializing everything yourself.
For example, make sure to copy the registration from App.Interactivity.cpp:
For example, make sure to copy the registration from App.Interactivity.cpp:
Code: Select all
NS_REGISTER_REFLECTION(App, Interactivity)
{
// Force creation of metadata
Noesis::TypeOf<NoesisApp::Interaction>();
Noesis::TypeOf<NoesisApp::StyleInteraction>();
NS_REGISTER_COMPONENT(NoesisApp::BehaviorCollection)
NS_REGISTER_COMPONENT(NoesisApp::TriggerCollection)
NS_REGISTER_COMPONENT(NoesisApp::StyleBehaviorCollection)
NS_REGISTER_COMPONENT(NoesisApp::StyleTriggerCollection)
NS_REGISTER_COMPONENT(NoesisApp::EventTrigger)
NS_REGISTER_COMPONENT(NoesisApp::PropertyChangedTrigger)
NS_REGISTER_COMPONENT(NoesisApp::DataTrigger)
NS_REGISTER_COMPONENT(NoesisApp::DataEventTrigger)
NS_REGISTER_COMPONENT(NoesisApp::KeyTrigger)
NS_REGISTER_COMPONENT(NoesisApp::GamepadTrigger)
NS_REGISTER_COMPONENT(NoesisApp::StoryboardCompletedTrigger)
NS_REGISTER_COMPONENT(NoesisApp::TimerTrigger)
NS_REGISTER_COMPONENT(NoesisApp::LoadContentAction)
NS_REGISTER_COMPONENT(NoesisApp::MouseDragElementBehavior)
NS_REGISTER_COMPONENT(NoesisApp::TranslateZoomRotateBehavior)
NS_REGISTER_COMPONENT(NoesisApp::ConditionBehavior)
NS_REGISTER_COMPONENT(NoesisApp::ConditionalExpression)
NS_REGISTER_COMPONENT(NoesisApp::ComparisonCondition)
NS_REGISTER_COMPONENT(NoesisApp::GoToStateAction)
NS_REGISTER_COMPONENT(NoesisApp::InvokeCommandAction)
NS_REGISTER_COMPONENT(NoesisApp::ChangePropertyAction)
NS_REGISTER_COMPONENT(NoesisApp::ControlStoryboardAction)
NS_REGISTER_COMPONENT(NoesisApp::RemoveElementAction)
NS_REGISTER_COMPONENT(NoesisApp::LaunchUriOrFileAction)
NS_REGISTER_COMPONENT(NoesisApp::PlaySoundAction)
NS_REGISTER_COMPONENT(NoesisApp::PlayMediaAction)
NS_REGISTER_COMPONENT(NoesisApp::PauseMediaAction)
NS_REGISTER_COMPONENT(NoesisApp::RewindMediaAction)
NS_REGISTER_COMPONENT(NoesisApp::StopMediaAction)
NS_REGISTER_COMPONENT(NoesisApp::SetFocusAction)
NS_REGISTER_COMPONENT(NoesisApp::MoveFocusAction)
NS_REGISTER_COMPONENT(NoesisApp::SelectAction)
NS_REGISTER_COMPONENT(NoesisApp::SelectAllAction)
NS_REGISTER_COMPONENT(NoesisApp::CollectionFilterBehavior)
NS_REGISTER_COMPONENT(NoesisApp::CollectionSortBehavior)
NS_REGISTER_COMPONENT(NoesisApp::BackgroundEffectBehavior)
NS_REGISTER_COMPONENT(NoesisApp::LineDecorationBehavior)
NS_REGISTER_COMPONENT(Noesis::EnumConverter<NoesisApp::ComparisonConditionType>)
NS_REGISTER_COMPONENT(Noesis::EnumConverter<NoesisApp::ForwardChaining>)
NS_REGISTER_COMPONENT(Noesis::EnumConverter<NoesisApp::KeyTriggerFiredOn>)
NS_REGISTER_COMPONENT(Noesis::EnumConverter<NoesisApp::GamepadTriggerFiredOn>)
NS_REGISTER_COMPONENT(Noesis::EnumConverter<NoesisApp::GamepadButton>)
NS_REGISTER_COMPONENT(Noesis::EnumConverter<NoesisApp::ControlStoryboardOption>)
NS_REGISTER_COMPONENT(Noesis::EnumConverter<NoesisApp::FocusDirection>)
}
-
- ngzaharias
- Posts: 11
- Joined:
Re: How to make a custom TriggerAction
Alright awesome, that was what I was missing (plus calling the NsRegisterReflection and NsInitPackage functions for App + Interactivity).
For anyone else that ends up in the same situation.
If you've followed the integration guide/sample and have Noesis running, the last step that is needed is to reflect and register the App + Interactivity (package + module).
1. Copy App.Interactivity.cpp from the Application Framework.
2. Include the file where you call Noesis::Init
3. Call the functions that are created via the reflection call in init and shutdown.
*note: The Application Framework does this via macros inside the register.cpp.
Thanks for being patient with me jsantos!
For anyone else that ends up in the same situation.
If you've followed the integration guide/sample and have Noesis running, the last step that is needed is to reflect and register the App + Interactivity (package + module).
1. Copy App.Interactivity.cpp from the Application Framework.
2. Include the file where you call Noesis::Init
3. Call the functions that are created via the reflection call in init and shutdown.
*note: The Application Framework does this via macros inside the register.cpp.
Code: Select all
// App.Interactivity.cpp
NS_REGISTER_REFLECTION(App, Interactivity)
{
...
// YourFile.cpp
{
void MyProgram::Init()
{
Noesis::Init();
NsRegisterReflectionAppInteractivity();
NsInitPackageAppInteractivity();
}
void MyProgram::Shutdown()
{
NsShutdownPackageAppInteractivity();
}
Re: How to make a custom TriggerAction
Of course, I’m here to help.
Thank you for your feedback, and I’m glad to hear you were able to resolve the issue.
Thank you for your feedback, and I’m glad to hear you were able to resolve the issue.
Who is online
Users browsing this forum: No registered users and 5 guests