Add a new example of how to create a custom widget.

This commit is contained in:
Martín Lucas Golini
2024-10-27 03:43:06 -03:00
parent 04fd9d3264
commit cec4c39dbb
2 changed files with 108 additions and 0 deletions

View File

@@ -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++"

View File

@@ -0,0 +1,102 @@
#include <eepp/ee.hpp>
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(
<style>
:root > * { background-color: white; }
#frequency_display { text-color: black; font-size: 24dp; margin: 8dp 0 0 8dp; }
</style>
<RelativeLayout layout_width="match_parent" layout_height="match_parent">
<SineWaveWidget id="wave" layout_width="match_parent" layout_height="match_parent" />
<SineWaveWidget id="wave2" layout_width="match_parent" layout_height="match_parent" />
<TextView id="frequency_display" layout_width="wrap_content" layout_height="wrap_content" />
</RelativeLayout>
)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>();
UISineWaveWidget* sineWaveWidget2 = ui->find( "wave2" )->asType<UISineWaveWidget>();
UITextView* textView = ui->find( "frequency_display" )->asType<UITextView>();
// 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();
}