244 lines
6.5 KiB
C++
244 lines
6.5 KiB
C++
/**
|
|
*******************************************************************************
|
|
* @file ewol/widget/Scene.cpp
|
|
* @brief ewol Scene widget system (Sources)
|
|
* @author Edouard DUPIN
|
|
* @date 01/04/2012
|
|
* @par Project
|
|
* ewol
|
|
*
|
|
* @par Copyright
|
|
* Copyright 2011 Edouard DUPIN, all right reserved
|
|
*
|
|
* This software is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY.
|
|
*
|
|
* Licence summary :
|
|
* You can modify and redistribute the sources code and binaries.
|
|
* You can send me the bug-fix
|
|
*
|
|
* Term of the licence in in the file licence.txt.
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
|
|
#include <ewol/widget/Scene.h>
|
|
#include <math.h>
|
|
|
|
#include <ewol/oObject/OObject.h>
|
|
#include <ewol/widget/WidgetManager.h>
|
|
#include <ewol/openGL/openGL.h>
|
|
|
|
/**
|
|
* @brief Initilise the basic widget property ==> due to the android system
|
|
* @note all widget that have template might have this initializer ...
|
|
* @param ---
|
|
* @return ---
|
|
*/
|
|
void ewol::WIDGET_SceneInit(void)
|
|
{
|
|
|
|
}
|
|
|
|
#undef __class__
|
|
#define __class__ "Scene"
|
|
|
|
ewol::Scene::Scene(void)
|
|
{
|
|
m_isRunning = true;
|
|
SetCanHaveFocus(true);
|
|
PeriodicCallSet(true);
|
|
m_lastCallTime = -1;
|
|
m_zoom = 1.0;
|
|
}
|
|
|
|
|
|
ewol::Scene::~Scene(void)
|
|
{
|
|
|
|
}
|
|
|
|
|
|
void ewol::Scene::OnRegenerateDisplay(void)
|
|
{
|
|
if (true == NeedRedraw()) {
|
|
// clean elements
|
|
for (int32_t iii=0; iii<m_sceneElement.animated.Size(); iii++) {
|
|
if (NULL != m_sceneElement.animated[iii]) {
|
|
m_sceneElement.animated[iii]->Clear();
|
|
}
|
|
}
|
|
for (int32_t jjj=0; jjj<MAX_GROUP_NUMBER; jjj++) {
|
|
for (int32_t iii=0; iii<m_sceneElement.listAnimatedElements[jjj].Size(); iii++) {
|
|
if (NULL != m_sceneElement.listAnimatedElements[jjj][iii]) {
|
|
// find an empty slot ...
|
|
m_sceneElement.listAnimatedElements[jjj][iii]->Draw();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Common widget drawing function (called by the drawing thread [Android, X11, ...])
|
|
* @param ---
|
|
* @return ---
|
|
*/
|
|
//TODO : Il y a un bug : seg fault ... je ne sais pas trop ou ...
|
|
void ewol::Scene::OnDraw(DrawProperty& displayProp)
|
|
{
|
|
//EWOL_ERROR(" On draw : " << m_currentDrawId);
|
|
// draw background :
|
|
// TODO : ...
|
|
//background
|
|
// draw elements
|
|
for (int32_t iii=0; iii<m_sceneElement.animated.Size(); iii++) {
|
|
if (NULL != m_sceneElement.animated[iii]) {
|
|
m_sceneElement.animated[iii]->Draw();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* @brief Periodic call of this widget
|
|
* @param localTime curent system time
|
|
* @return ---
|
|
*/
|
|
void ewol::Scene::PeriodicCall(int64_t localTime)
|
|
{
|
|
// First time :
|
|
if (-1 == m_lastCallTime) {
|
|
m_lastCallTime = localTime;
|
|
}
|
|
// check if the processing is availlable
|
|
if (false == m_isRunning) {
|
|
m_lastCallTime = localTime;
|
|
MarkToRedraw();
|
|
return;
|
|
}
|
|
// cut the processing in small slot of time to prevent error in the real-time Display (Android call us between 30 to 60 fps)
|
|
int32_t deltaTime = (int32_t) (localTime - m_lastCallTime);
|
|
//EWOL_DEBUG(" currentTime = " << localTime << " last=" << m_lastCallTime << " delta=" << deltaTime);
|
|
while (deltaTime >= CYCLIC_CALL_PERIODE_US) {
|
|
//EWOL_DEBUG(" process = " << CYCLIC_CALL_PERIODE_US);
|
|
m_lastCallTime += CYCLIC_CALL_PERIODE_US;
|
|
deltaTime -= CYCLIC_CALL_PERIODE_US;
|
|
ScenePeriodicCall(m_lastCallTime, CYCLIC_CALL_PERIODE_US);
|
|
//EWOL_ERROR("Periodic Call ... " << localTime);
|
|
for (int32_t jjj=0; jjj<MAX_GROUP_NUMBER; jjj++) {
|
|
for (int32_t iii=0; iii<m_sceneElement.listAnimatedElements[jjj].Size(); iii++) {
|
|
if (NULL != m_sceneElement.listAnimatedElements[jjj][iii]) {
|
|
if(true == m_sceneElement.listAnimatedElements[jjj][iii]->IsEnable() ) {
|
|
// check if the element request an auto Kill ...
|
|
if (true == m_sceneElement.listAnimatedElements[jjj][iii]->Process(m_lastCallTime, CYCLIC_CALL_PERIODE_US) ) {
|
|
m_sceneElement.RmElement(jjj, iii);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
MarkToRedraw();
|
|
}
|
|
|
|
/**
|
|
* @brief extern interface to request a draw ... (called by the drawing thread [Android, X11, ...])
|
|
* This function generate a clipping with the viewport openGL system. Like this a widget draw can not draw over an other widget
|
|
* @note This function is virtual for the scrolled widget, and the more complicated OpenGl widget
|
|
* @param ---
|
|
* @return ---
|
|
*/
|
|
void ewol::Scene::GenDraw(DrawProperty displayProp)
|
|
{
|
|
|
|
#ifdef __VIDEO__OPENGL_ES_2
|
|
ewol::openGL::Push();
|
|
#else
|
|
glPushMatrix();
|
|
#endif
|
|
// here we invert the reference of the standard OpenGl view because the reference in the common display is Top left and not buttom left
|
|
glViewport( m_origin.x,
|
|
m_origin.y,
|
|
m_size.x,
|
|
m_size.y);
|
|
float ratio = m_size.x / m_size.y;
|
|
m_zoom = 1.0/1000.0;
|
|
//EWOL_INFO("ratio : " << ratio);
|
|
#ifdef __VIDEO__OPENGL_ES_2
|
|
etk::Matrix tmpProjection;
|
|
|
|
if (ratio >= 1.0) {
|
|
tmpProjection = etk::matrix::Perspective(-ratio, ratio, -1, 1, -1, 1);
|
|
} else {
|
|
ratio = 1.0/ratio;
|
|
tmpProjection = etk::matrix::Perspective(-1, 1, -ratio, ratio, -1, 1);
|
|
}
|
|
etk::Matrix tmpScale = etk::matrix::Scale(m_zoom, m_zoom, m_zoom);
|
|
etk::Matrix tmpMat = tmpProjection * tmpScale;
|
|
// set internal matrix system :
|
|
ewol::openGL::SetMatrix(tmpMat);
|
|
#else
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
if (ratio >= 1.0) {
|
|
glOrthoEwol(-ratio, ratio, -1, 1, -1, 1);
|
|
} else {
|
|
ratio = 1.0/ratio;
|
|
glOrthoEwol(-1, 1, -ratio, ratio, -1, 1);
|
|
}
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
glScalef(m_zoom, m_zoom, m_zoom);
|
|
|
|
#endif
|
|
// Clear the screen with transparency ...
|
|
glClearColor(0.0, 0.0, 0.0, 1.0);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
// Call the widget drawing methode
|
|
OnDraw(displayProp);
|
|
|
|
#ifdef __VIDEO__OPENGL_ES_2
|
|
ewol::openGL::Pop();
|
|
#else
|
|
glPopMatrix();
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Convert the absolute position in the local Position (Relative)
|
|
* @param[in] pos Absolute position that you request convertion
|
|
* @return the relative position
|
|
*/
|
|
Vector2D<float> ewol::Scene::RelativePosition(Vector2D<float> pos)
|
|
{
|
|
// Remove origin of the widget
|
|
pos.x -= m_origin.x;
|
|
pos.y -= m_origin.y;
|
|
// move the position at the center (openGl system
|
|
pos.x -= m_size.x/2;
|
|
pos.y -= m_size.y/2;
|
|
// scale the position with the ratio display of the screen
|
|
float ratio = m_size.x / m_size.y;
|
|
if (ratio >= 1.0) {
|
|
pos.x /= m_size.x;
|
|
pos.x *= ratio;
|
|
pos.y /= m_size.y;
|
|
} else {
|
|
ratio = 1.0/ratio;
|
|
pos.x /= m_size.x;
|
|
pos.y /= m_size.y;
|
|
pos.y *= ratio;
|
|
}
|
|
// integrate zoom
|
|
pos.x /= m_zoom;
|
|
pos.y /= m_zoom;
|
|
// all the position are half the size due to the fact -1 --> 1
|
|
pos.x *= 2;
|
|
pos.y *= 2;
|
|
|
|
return pos;
|
|
};
|
|
|