[DEV] create shaper to simplify widget theme creation

This commit is contained in:
Edouard DUPIN 2012-11-27 21:27:47 +01:00
parent 4f296ba2b9
commit fb3973915f
9 changed files with 407 additions and 197 deletions

View File

@ -3,7 +3,10 @@ PaddingX=8
PaddingY=8
# change status in ms
ChangeTime=356
# if an image is needed :
#image=plop.png
# the associated openGL ES-2 program :
program=widgetButton.prog

View File

@ -3,6 +3,10 @@ PaddingX=13
PaddingY=7
# change status in ms
ChangeTime=356
# if an image is needed :
#image=plop.png
# the associated openGL ES-2 program :
program=widgetButton.prog

View File

@ -12,6 +12,9 @@
#include <ewol/compositing/Image.h>
#include <ewol/config.h>
#undef __class__
#define __class__ "ewol::Image"
ewol::Image::Image(etk::UString imageName) :
m_position(0.0, 0.0, 0.0),
m_clippingPosStart(0.0, 0.0, 0.0),

View File

@ -0,0 +1,248 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <tinyXML/tinyxml.h>
#include <etk/os/FSNode.h>
#include <ewol/debug.h>
#include <ewol/compositing/Shaper.h>
#include <ewol/config.h>
#undef __class__
#define __class__ "ewol::Shaper"
ewol::Shaper::Shaper(etk::UString shaperName) :
m_name(shaperName),
m_config(NULL),
m_confIdPaddingX(-1),
m_confIdPaddingY(-1),
m_confIdChangeTime(-1),
m_confProgramFile(-1),
m_GLprogram(NULL),
m_GLPosition(-1),
m_GLMatrix(-1),
m_GLPropertySize(-1),
m_GLPropertyInsidePos(-1),
m_GLPropertyInsideSize(-1),
m_GLStateOld(-1),
m_GLStateNew(-1),
m_GLStateTransition(-1),
m_nextStatusRequested(-1),
m_time(-1),
m_stateOld(0),
m_stateNew(0),
m_stateTransition(1.0)
{
LoadProgram();
m_coord[0].x= 0;
m_coord[0].y= m_propertySize.y;
m_coord[1].x= 0;
m_coord[1].y= 0;
m_coord[2].x= m_propertySize.x;
m_coord[2].y= 0;
m_coord[3].x= m_propertySize.x;
m_coord[3].y= 0;
m_coord[4].x= m_propertySize.x;
m_coord[4].y= m_propertySize.y;
m_coord[5].x= 0;
m_coord[5].y= m_propertySize.y;
}
ewol::Shaper::~Shaper(void)
{
if (NULL != m_GLprogram) {
ewol::resource::Release(m_GLprogram);
m_GLprogram = NULL;
}
if (NULL != m_config) {
ewol::resource::Release(m_config);
m_config = NULL;
}
}
void ewol::Shaper::LoadProgram(void)
{
if (m_name=="") {
EWOL_DEBUG("no Shaper set for loading resources ...");
return;
}
if (true == ewol::resource::Keep(m_name, m_config) ) {
m_confIdPaddingX = m_config->Request("PaddingX");
m_confIdPaddingY = m_config->Request("PaddingY");
m_confIdChangeTime = m_config->Request("ChangeTime");
m_confProgramFile = m_config->Request("program");
}
etk::UString basicShaderFile = m_config->GetString(m_confProgramFile);
// Get the relative position of the current file ...
etk::FSNode file(m_name);
etk::UString tmpFilename = file.GetRelativeFolder() + basicShaderFile;
EWOL_DEBUG("Shaper try load shader : " << tmpFilename << " with base : " << basicShaderFile);
// get the shader resource :
m_GLPosition = 0;
if (true == ewol::resource::Keep(tmpFilename, m_GLprogram) ) {
m_GLPosition = m_GLprogram->GetAttribute("EW_coord2d");
m_GLMatrix = m_GLprogram->GetUniform("EW_MatrixTransformation");
// Widget property ==> for the Vertex shader
m_GLPropertySize = m_GLprogram->GetUniform("EW_widgetProperty.size");
m_GLPropertyInsidePos = m_GLprogram->GetUniform("EW_widgetProperty.insidePos");
m_GLPropertyInsideSize = m_GLprogram->GetUniform("EW_widgetProperty.insideSize");
// status property ==> for the fragment shader
m_GLStateOld = m_GLprogram->GetUniform("EW_status.stateOld");
m_GLStateNew = m_GLprogram->GetUniform("EW_status.stateNew");
m_GLStateTransition = m_GLprogram->GetUniform("EW_status.transition");
}
}
void ewol::Shaper::Draw(void)
{
if (m_config == NULL) {
// this is a normale case ... the user can choice to have no config basic file ...
return;
}
if (m_GLprogram==NULL) {
EWOL_ERROR("No shader ...");
return;
}
//glScalef(m_scaling.x, m_scaling.y, 1.0);
m_GLprogram->Use();
// set Matrix : translation/positionMatrix
etk::Matrix4 tmpMatrix = ewol::openGL::GetMatrix();
m_GLprogram->UniformMatrix4fv(m_GLMatrix, 1, tmpMatrix.m_mat);
// position :
// Note : Must be all the time a [-1..1] square ...
// TODO : plop ...
m_GLprogram->SendAttribute(m_GLPosition, 2/*x,y*/, m_coord);
// all entry parameters :
m_GLprogram->Uniform2fv(m_GLPropertySize, 1, &m_propertySize.x);
m_GLprogram->Uniform2fv(m_GLPropertyInsidePos, 1, &m_propertyInsidePosition.x);
m_GLprogram->Uniform2fv(m_GLPropertyInsideSize, 1, &m_propertyInsideSize.x);
m_GLprogram->Uniform1i(m_GLStateOld, m_stateOld);
m_GLprogram->Uniform1i(m_GLStateNew, m_stateNew);
m_GLprogram->Uniform1f(m_GLStateTransition, m_stateTransition);
// Request the draw of the elements :
glDrawArrays(GL_TRIANGLES, 0, 6);
m_GLprogram->UnUse();
}
void ewol::Shaper::Clear(void)
{
// nothing to do ...
}
bool ewol::Shaper::ChangeStatusIn(int32_t newStatusId)
{
m_nextStatusRequested = newStatusId;
return true;
}
bool ewol::Shaper::PeriodicCall(int64_t localTime)
{
// start :
if (m_time == -1) {
m_time = localTime;
m_stateOld = m_stateNew;
m_stateNew = m_nextStatusRequested;
m_nextStatusRequested = -1;
m_stateTransition = 0.0;
EWOL_VERBOSE(" ##### START ##### ");
}
int64_t offset = localTime - m_time;
float timeRelativity = m_config->GetFloat(m_confIdChangeTime)*1000.0;
if (offset > timeRelativity) {
// check if no new state requested:
if (m_nextStatusRequested != -1) {
m_time = localTime;
m_stateOld = m_stateNew;
m_stateNew = m_nextStatusRequested;
m_nextStatusRequested = -1;
m_stateTransition = 0.0;
} else {
m_stateTransition = 1.0;
EWOL_VERBOSE(" ##### STOP ##### ");
return false;
m_time = -1;
}
} else {
m_stateTransition = (float)offset / timeRelativity;
EWOL_VERBOSE("time=" << offset << " in " << timeRelativity << " Transition : " << m_stateTransition);
}
return true;
}
void ewol::Shaper::SetSize(etk::Vector2D<float> newSize)
{
if (m_propertySize != newSize) {
m_propertySize = newSize;
// set coord ==> must be a static VBO ...
m_coord[0].x= 0;
m_coord[0].y= m_propertySize.y;
m_coord[1].x= 0;
m_coord[1].y= 0;
m_coord[2].x= m_propertySize.x;
m_coord[2].y= 0;
m_coord[3].x= m_propertySize.x;
m_coord[3].y= 0;
m_coord[4].x= m_propertySize.x;
m_coord[4].y= m_propertySize.y;
m_coord[5].x= 0;
m_coord[5].y= m_propertySize.y;
}
}
void ewol::Shaper::SetInsideSize(etk::Vector2D<float> newInsideSize)
{
m_propertyInsideSize = newInsideSize;
}
void ewol::Shaper::SetInsidePos(etk::Vector2D<float> newInsidePos)
{
m_propertyInsidePosition = newInsidePos;
}
etk::Vector2D<float> ewol::Shaper::GetPadding(void)
{
etk::Vector2D<float> padding;
padding.x = m_config->GetFloat(m_confIdPaddingX);
padding.y = m_config->GetFloat(m_confIdPaddingY);
return padding;
}
void ewol::Shaper::SetSource(etk::UString newFile)
{
Clear();
if (NULL != m_GLprogram) {
ewol::resource::Release(m_GLprogram);
m_GLprogram = NULL;
}
if (NULL != m_config) {
ewol::resource::Release(m_config);
m_config = NULL;
}
LoadProgram();
}
bool ewol::Shaper::HasSources(void)
{
return m_GLprogram!=NULL;
}

View File

@ -0,0 +1,125 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#ifndef __EWOL_COMPOSITING_SHAPER_H__
#define __EWOL_COMPOSITING_SHAPER_H__
#include <ewol/debug.h>
#include <ewol/compositing/Compositing.h>
#include <ewol/renderer/ResourceManager.h>
namespace ewol
{
/**
* @brief the Shaper system is a basic theme configuration for every widget, it corespond at a background display described by a pool of files
*/
// TODO : Load image
// TODO : Abstaraction between states (call by name and the system greate IDs
class Shaper : public ewol::Compositing
{
private:
etk::UString m_name; //!< Name of the configuration of the shaper.
// External theme config:
ewol::ConfigFile* m_config; //!< pointer on the config file resources
int32_t m_confIdPaddingX; //!< ConfigFile padding property X
int32_t m_confIdPaddingY; //!< ConfigFile padding property Y
int32_t m_confIdChangeTime; //!< ConfigFile padding transition time property
int32_t m_confProgramFile; //!< ConfigFile OpengGl program Name
// OpenGL shaders programs:
ewol::Program* m_GLprogram; //!< pointer on the opengl display program
int32_t m_GLPosition; //!< openGL id on the element (vertex buffer)
int32_t m_GLMatrix; //!< openGL id on the element (transformation matrix)
int32_t m_GLPropertySize; //!< openGL id on the element (widget size)
int32_t m_GLPropertyInsidePos; //!< openGL id on the element (widget internal element position)
int32_t m_GLPropertyInsideSize; //!< openGL id on the element (widget internal element size)
int32_t m_GLStateOld; //!< openGL id on the element (old state displayed)
int32_t m_GLStateNew; //!< openGL id on the element (new state displayed)
int32_t m_GLStateTransition; //!< openGL id on the element (transition ofset [0.0..1.0] )
// internal needed data :
int32_t m_nextStatusRequested; //!< when status is changing, this represent the next step of it
int64_t m_time; //!< The last time of the dispaly (-1 if nothing progressing)
etk::Vector2D<float> m_propertySize; //!< widget size
etk::Vector2D<float> m_propertyInsidePosition; //!< internal subwidget position
etk::Vector2D<float> m_propertyInsideSize; //!< internal subwidget size
int32_t m_stateOld; //!< previous state
int32_t m_stateNew; //!< destination state
float m_stateTransition; //!< working state between 2 states
etk::Vector2D<float> m_coord[6]; //!< the double triangle coordonates
private:
/**
* @brief Load the openGL program and get all the ID needed
*/
void LoadProgram(void);
public:
/**
* @brief generic constructor
* @param[in] imageName Name of the file that might be loaded
*/
Shaper(etk::UString shaperName="");
/**
* @brief generic destructor
*/
~Shaper(void);
public:
/**
* @brief Draw All the refistered text in the current element on openGL
*/
void Draw(void);
/**
* @brief Clear alll tre registered element in the current element
*/
void Clear(void);
/**
* @brief change the current status in an other
* @param[in] the next new status requested
* @return true The widget must call this fuction periodicly (and redraw itself)
* @return false No need to request the periodic call.
*/
bool ChangeStatusIn(int32_t newStatusId);
/**
* @brief Same as the widfget periodic call (this is for change display)
* @param[in] localTime The current time of the call.
* @return true The widget must call this fuction periodicly (and redraw itself)
* @return false No need to request the periodic call.
*/
bool PeriodicCall(int64_t localTime);
/**
* @brief Set the widget size (needed fot the display)
* @param[in] newSize : the new widget size
*/
void SetSize(etk::Vector2D<float> newSize);
/**
* @brief Set the internal widget size
* @param[in] newInsidePos : the subelement size.
*/
void SetInsideSize(etk::Vector2D<float> newInsideSize);
/**
* @brief Set the internal widget position
* @param[in] newInsidePos : the subelement position
*/
void SetInsidePos(etk::Vector2D<float> newInsidePos);
/**
* @brief Get the padding declared by the user in the config file
* @return the padding property
*/
etk::Vector2D<float> GetPadding(void);
/**
* @brief Change the image Source ==> can not be done to display 2 images at the same time ...
* @param[in] newFile New file of the Image
*/
void SetSource(etk::UString newFile);
/**
* @brief Sometimes the user declare an image but not allocate the ressources all the time, this is to know it ..
* @return the validity od the resources.
*/
bool HasSources(void);
};
};
#endif

View File

@ -18,6 +18,7 @@ void ewol::SimpleConfigElement::Parse(etk::UString value)
m_valuefloat = 0;
sscanf(tmp, "%d", &m_valueInt);
sscanf(tmp, "%f", &m_valuefloat);
m_value = tmp;
}

View File

@ -21,8 +21,11 @@ extern const char * const ewolEventButtonLeave = "ewol-button-leave";
#define __class__ "Button"
void widget::Button::Init(void)
widget::Button::Button(etk::UString newLabel) :
m_shaper("THEME:GUI:widgetButton.conf")
{
m_label = newLabel;
AddEventId(ewolEventButtonPressed);
AddEventId(ewolEventButtonDown);
AddEventId(ewolEventButtonUp);
@ -30,51 +33,13 @@ void widget::Button::Init(void)
AddEventId(ewolEventButtonLeave);
m_alignement = widget::TEXT_ALIGN_CENTER;
m_status.m_stateOld = 0;
m_status.m_stateNew = 0;
m_status.m_transition = 1.0;
m_time = -1;
m_nextStatusRequested = -1;
m_textColorFg = draw::color::black;
SetCanHaveFocus(true);
etk::UString tmpString("THEME:GUI:widgetButton.conf");
if (true == ewol::resource::Keep(tmpString, m_config) ) {
m_confIdPaddingX = m_config->Request("PaddingX");
m_confIdPaddingY = m_config->Request("PaddingY");
m_confIdChangeTime = m_config->Request("ChangeTime");
}
tmpString ="THEME:GUI:widgetButton.prog";
// get the shader resource :
m_GLPosition = 0;
if (true == ewol::resource::Keep(tmpString, m_GLprogram) ) {
m_GLPosition = m_GLprogram->GetAttribute("EW_coord2d");
m_GLMatrix = m_GLprogram->GetUniform("EW_MatrixTransformation");
// Widget property ==> for the Vertex shader
m_GLwidgetProperty.m_size = m_GLprogram->GetUniform("EW_widgetProperty.size");
m_GLwidgetProperty.m_insidePos = m_GLprogram->GetUniform("EW_widgetProperty.insidePos");
m_GLwidgetProperty.m_insideSize = m_GLprogram->GetUniform("EW_widgetProperty.insideSize");
// status property ==> for the fragment shader
m_GLstatus.m_stateOld = m_GLprogram->GetUniform("EW_status.stateOld");
m_GLstatus.m_stateNew = m_GLprogram->GetUniform("EW_status.stateNew");
m_GLstatus.m_transition = m_GLprogram->GetUniform("EW_status.transition");
}
// Limit event at 1:
SetMouseLimit(1);
}
widget::Button::Button(void)
{
m_label = "No Label";
Init();
}
widget::Button::Button(etk::UString newLabel)
{
m_label = newLabel;
Init();
}
widget::Button::~Button(void)
{
@ -96,9 +61,7 @@ void widget::Button::SetImageToggle(etk::UString imageName)
bool widget::Button::CalculateMinSize(void)
{
etk::Vector2D<int32_t> padding;
padding.x = m_config->GetInteger(m_confIdPaddingX);
padding.y = m_config->GetInteger(m_confIdPaddingY);
etk::Vector2D<float> padding = m_shaper.GetPadding();
etk::Vector3D<int32_t> minSize = m_displayText.CalculateSize(m_label);
m_minSize.x = padding.x*2 + minSize.x;
@ -138,63 +101,9 @@ bool widget::Button::GetValue(void)
}
void widget::Button::SetPoint(float x, float y)
{
etk::Vector2D<float> triangle(x, y);
m_coord.PushBack(triangle);
}
void widget::Button::Rectangle(float x, float y, float w, float h)
{
m_coord.Clear();
/* Bitmap position
* xA xB
* yC *------*
* | |
* | |
* yD *------*
*/
float dxA = x;
float dxB = x + w;
float dyC = y;
float dyD = y + h;
SetPoint(dxA, dyD);
SetPoint(dxA, dyC);
SetPoint(dxB, dyC);
SetPoint(dxB, dyC);
SetPoint(dxB, dyD);
SetPoint(dxA, dyD);
}
void widget::Button::OnDraw(ewol::DrawProperty& displayProp)
{
if (m_GLprogram==NULL) {
EWOL_ERROR("No shader ...");
return;
}
//glScalef(m_scaling.x, m_scaling.y, 1.0);
m_GLprogram->Use();
// set Matrix : translation/positionMatrix
etk::Matrix4 tmpMatrix = ewol::openGL::GetMatrix();
m_GLprogram->UniformMatrix4fv(m_GLMatrix, 1, tmpMatrix.m_mat);
// position :
// Note : Must be all the time a [-1..1] square ...
// TODO : plop ...
m_GLprogram->SendAttribute(m_GLPosition, 2/*x,y*/, &m_coord[0]);
// all entry parameters :
m_GLprogram->Uniform2fv(m_GLwidgetProperty.m_size, 1, &m_size.x);
m_GLprogram->Uniform2fv(m_GLwidgetProperty.m_insidePos, 1, &m_widgetProperty.m_insidePos.x);
m_GLprogram->Uniform2fv(m_GLwidgetProperty.m_insideSize, 1, &m_widgetProperty.m_insideSize.x);
m_GLprogram->Uniform1i(m_GLstatus.m_stateOld, m_status.m_stateOld);
m_GLprogram->Uniform1i(m_GLstatus.m_stateNew, m_status.m_stateNew);
m_GLprogram->Uniform1f(m_GLstatus.m_transition, m_status.m_transition);
// Request the draw of the elements :
glDrawArrays(GL_TRIANGLES, 0, m_coord.Size());
m_GLprogram->UnUse();
m_shaper.Draw();
#warning generate the Toggle
if (true) {
m_displayImage.Draw();
@ -208,12 +117,11 @@ void widget::Button::OnRegenerateDisplay(void)
{
if (true == NeedRedraw()) {
etk::Vector2D<int32_t> padding;
padding.x = m_config->GetInteger(m_confIdPaddingX);
padding.y = m_config->GetInteger(m_confIdPaddingY);
etk::Vector2D<float> padding = m_shaper.GetPadding();
m_displayImage.Clear();
m_displayImageToggle.Clear();
m_shaper.Clear();
int32_t tmpSizeX = m_minSize.x;
int32_t tmpSizeY = m_minSize.y;
@ -268,12 +176,12 @@ void widget::Button::OnRegenerateDisplay(void)
m_displayText.Translate(tmpTextOrigin);
m_widgetProperty.m_insidePos = textPos;
m_shaper.SetSize(m_size);
m_shaper.SetInsidePos(textPos);
etk::Vector3D<float> tmpp = m_displayText.CalculateSize(m_label);
etk::Vector2D<float> tmpp2(tmpp.x, tmpp.y);
m_widgetProperty.m_insideSize = tmpp2;
m_shaper.SetInsideSize(tmpp2);
Rectangle(0, 0, m_size.x, m_size.y);
}
}
@ -321,42 +229,17 @@ bool widget::Button::OnEventKb(ewol::keyEvent::status_te typeEvent, uniChar_t un
void widget::Button::ChangeStatusIn(int32_t newStatusId)
{
m_nextStatusRequested = newStatusId;
PeriodicCallSet(true);
MarkToRedraw();
if (true == m_shaper.ChangeStatusIn(newStatusId) ) {
PeriodicCallSet(true);
MarkToRedraw();
}
}
void widget::Button::PeriodicCall(int64_t localTime)
{
// start :
if (m_time == -1) {
m_time = localTime;
m_status.m_stateOld = m_status.m_stateNew;
m_status.m_stateNew = m_nextStatusRequested;
m_nextStatusRequested = -1;
m_status.m_transition = 0.0;
//EWOL_ERROR(" ##### START ##### ");
}
int64_t offset = localTime - m_time;
float timeRelativity = m_config->GetFloat(m_confIdChangeTime)*1000.0;
if (offset > timeRelativity) {
// check if no new state requested:
if (m_nextStatusRequested != -1) {
m_time = localTime;
m_status.m_stateOld = m_status.m_stateNew;
m_status.m_stateNew = m_nextStatusRequested;
m_nextStatusRequested = -1;
m_status.m_transition = 0.0;
} else {
m_status.m_transition = 1.0;
//EWOL_ERROR(" ##### STOP ##### ");
PeriodicCallSet(false);
m_time = -1;
}
} else {
m_status.m_transition = (float)offset / timeRelativity;
//EWOL_DEBUG("time=" << offset << " in " << timeRelativity << " Transition : " << m_status.m_transition);
if (false == m_shaper.PeriodicCall(localTime) ) {
PeriodicCallSet(false);
}
MarkToRedraw();
}

View File

@ -15,6 +15,7 @@
#include <ewol/widget/Widget.h>
#include <ewol/compositing/Text.h>
#include <ewol/compositing/Image.h>
#include <ewol/compositing/Shaper.h>
extern const char * const ewolEventButtonPressed;
extern const char * const ewolEventButtonDown;
@ -22,42 +23,6 @@ extern const char * const ewolEventButtonUp;
extern const char * const ewolEventButtonEnter;
extern const char * const ewolEventButtonLeave;
namespace ewol {
class WidgetPosProperty
{
public:
etk::Vector2D<float> m_insidePos;
etk::Vector2D<float> m_insideSize;
};
class GLWidgetPosProperty
{
public:
int32_t m_size;
int32_t m_insidePos;
int32_t m_insideSize;
};
// DATA
class WidgetStateProperty
{
public:
int32_t m_stateOld;
int32_t m_stateNew;
float m_transition;
};
// ID of the UNIFORM element
class GLWidgetStateProperty
{
public:
int32_t m_stateOld;
int32_t m_stateNew;
int32_t m_transition;
};
};
namespace widget {
typedef enum {
TEXT_ALIGN_LEFT,
@ -66,26 +31,7 @@ namespace widget {
class Button : public ewol::Widget
{
private:
// External theme config:
ewol::ConfigFile* m_config;
int32_t m_confIdPaddingX;
int32_t m_confIdPaddingY;
int32_t m_confIdChangeTime;
// OpenGL shaders programs:
ewol::Program* m_GLprogram;
int32_t m_GLPosition;
int32_t m_GLMatrix;
// widget property
ewol::GLWidgetPosProperty m_GLwidgetProperty; // id of the uniform
ewol::WidgetPosProperty m_widgetProperty; // structure of this uniform
// state property
ewol::GLWidgetStateProperty m_GLstatus;
ewol::WidgetStateProperty m_status;
etk::Vector<etk::Vector2D<float> > m_coord; //!< internal coord of the object
void SetPoint(float x, float y);
void Rectangle(float x, float y, float w, float h);
private:
ewol::Shaper m_shaper;
ewol::Text m_displayText;
ewol::Image m_displayImage;
ewol::Image m_displayImageToggle;
@ -93,11 +39,9 @@ namespace widget {
etk::UString m_label;
draw::Color m_textColorFg; //!< Text color
public:
Button(void);
Button(etk::UString newLabel);
Button(etk::UString newLabel="No Label");
// Derived function
virtual const char * const GetObjectType(void) { return "EwolButton"; };
void Init(void);
virtual ~Button(void);
// Derived function
virtual bool CalculateMinSize(void);
@ -119,9 +63,7 @@ namespace widget {
// Derived function
virtual bool OnEventKb(ewol::keyEvent::status_te typeEvent, uniChar_t unicodeData);
private:
int32_t m_nextStatusRequested;
void ChangeStatusIn(int32_t newStatusId);
int64_t m_time;
// Derived function
virtual void PeriodicCall(int64_t localTime);
};

View File

@ -43,7 +43,8 @@ FILE_LIST+= ewol/compositing/Compositing.cpp \
ewol/compositing/Drawing.cpp \
ewol/compositing/Image.cpp \
ewol/compositing/Sprite.cpp \
ewol/compositing/Mesh.cpp
ewol/compositing/Mesh.cpp \
ewol/compositing/Shaper.cpp
# all widgets