diff --git a/premake4.lua b/premake4.lua index f680b7d8e..d393068d1 100644 --- a/premake4.lua +++ b/premake4.lua @@ -1439,6 +1439,12 @@ solution "eepp" includedirs { "src/thirdparty" } build_link_configuration( "eepp-http-request", true ) + project "eepp-ui-custom-widget" + set_kind() + language "C++" + files { "src/examples/ui_custom_widget/*.cpp" } + build_link_configuration( "eepp-ui-custom-widget", true ) + project "eepp-ui-hello-world" set_kind() language "C++" diff --git a/src/examples/ui_custom_widget/ui_custom_widget.cpp b/src/examples/ui_custom_widget/ui_custom_widget.cpp new file mode 100644 index 000000000..2f8b55f4d --- /dev/null +++ b/src/examples/ui_custom_widget/ui_custom_widget.cpp @@ -0,0 +1,102 @@ +#include + +class UISineWaveWidget : public UIWidget { + public: + static UISineWaveWidget* New() { return eeNew( UISineWaveWidget, () ); } + + // Implement the widget draw method + void draw() override { + Sizef size = getPixelsSize().asFloat(); + Float centerY = size.getHeight() * 0.5f; + Float amplitude = size.getHeight() / 2 * 0.5f; + BatchRenderer br; + br.lineStripSetColor( mLineColor ); + for ( Float x = 0; x < size.getWidth(); x++ ) + br.batchLineStrip( mPosition.x + x, amplitude * std::sin( mFrequency * x ) + centerY ); + br.draw(); + } + + void setFrequency( Float freq ) { + if ( freq != mFrequency ) { + mFrequency = freq; + onValueChange(); // Trigger the on value change event + invalidateDraw(); // Tell the scene that we need to redraw (UI only redraws when needed) + } + } + + Float frequency() { return mFrequency; } + + void setColor( Color color ) { + if ( color != mLineColor ) { + mLineColor = color; + invalidateDraw(); + } + } + + protected: + Float mFrequency{ 0.f }; + Color mLineColor{ Color::Red }; + Float mDir{ 1 }; + + UISineWaveWidget() : + UIWidget( + "sinewavewidget" ) // parameter is the element tag (for accesing the element from CSS) + {} +}; + +EE_MAIN_FUNC int main( int, char** ) { + // UIApplication allows to quickly initialize the application as an UI application + UIApplication app( { 1280, 768, "eepp - Custom Widget Example" } ); + + UISceneNode* ui = app.getUI(); // Get the UI Scene + + // Register the new widget type into the system, you must provide a name and the creation + // callback. The name will be used as the XML Element name. + // This must be done before loading any XML that refers to this XML element name. + UIWidgetCreator::registerWidget( "SineWaveWidget", UISineWaveWidget::New ); + + // Load the XML document with its styles + ui->loadLayoutFromString( R"xml( + + + + + + + )xml" ); + + // Get the elements created, "find" will search by id, asType is just a cast to its type + UISineWaveWidget* sineWaveWidget = ui->find( "wave" )->asType(); + UISineWaveWidget* sineWaveWidget2 = ui->find( "wave2" )->asType(); + UITextView* textView = ui->find( "frequency_display" )->asType(); + + // Listen for the KeyDown event from the scene element (events are propagated upwards until + // an element process the event (in this example it will propagate until the root element) + ui->on( Event::KeyDown, [sineWaveWidget, sineWaveWidget2, ui]( const Event* event ) { + Float diff = ui->getElapsed().asSeconds() * 0.1f; + if ( event->asKeyEvent()->getKeyCode() == KEY_UP ) { + sineWaveWidget->setFrequency( sineWaveWidget->frequency() + diff ); + sineWaveWidget2->setFrequency( sineWaveWidget2->frequency() - diff ); + } else if ( event->asKeyEvent()->getKeyCode() == KEY_DOWN ) { + sineWaveWidget->setFrequency( sineWaveWidget->frequency() - diff ); + sineWaveWidget2->setFrequency( sineWaveWidget2->frequency() + diff ); + } + } ); + + // Register the on value change event to update the frequency label + sineWaveWidget->on( Event::OnValueChange, [sineWaveWidget, textView]( const Event* ) { + textView->setText( String::format( "frequency is %.2f", sineWaveWidget->frequency() ) ); + } ); + + // Change the second sine wave color + sineWaveWidget2->setColor( Color::Blue ); + + // Set an initial frequency (this will trigger the first on value change) + sineWaveWidget->setFrequency( 0.025f ); + sineWaveWidget2->setFrequency( -0.025f ); // Generate an inverted sine wave + + return app.run(); +}