ewol/sources/ewol/widget/Widget.cpp

337 lines
11 KiB
C++

/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <ewol/widget/Widget.h>
#include <ewol/eObject/EObjectManager.h>
#include <ewol/widget/WidgetManager.h>
#include <ewol/ewol.h>
#include <ewol/renderer/openGL.h>
#undef __class__
#define __class__ "Widget"
ewol::Widget::Widget(void)
{
m_limitMouseEvent = 3;
m_needRegenerateDisplay = true;
m_origin.x = 0.0;
m_origin.y = 0.0;
m_size.x = 10.0;
m_size.y = 10.0;
m_minSize.x = -1.0;
m_minSize.y = -1.0;
// user settings :
m_userMinSize.x = -1.0;
m_userMinSize.y = -1.0;
SetExpendX();
SetExpendY();
SetFillX();
SetFillY();
m_canFocus = false;
m_hasFocus = false;
m_hide = false;
m_zoom = 1.0;
}
ewol::Widget::~Widget(void)
{
// Remove his own focus...
ewol::widgetManager::Rm(this);
// clean all the short-cut ...
ShortCutClean();
}
void ewol::Widget::Hide(void)
{
m_hide = true;
MarkToRedraw();
ewol::RequestUpdateSize();
}
void ewol::Widget::Show(void)
{
m_hide = false;
MarkToRedraw();
ewol::RequestUpdateSize();
}
bool ewol::Widget::CalculateSize(float availlableX, float availlableY)
{
m_size.x = availlableX;
m_size.y = availlableY;
MarkToRedraw();
return true;
}
bool ewol::Widget::SetFocus(void)
{
if (true == m_canFocus) {
m_hasFocus = true;
OnGetFocus();
return true;
}
return false;
}
bool ewol::Widget::RmFocus(void)
{
if (true == m_canFocus) {
m_hasFocus = false;
OnLostFocus();
return true;
}
return false;
}
void ewol::Widget::SetCanHaveFocus(bool canFocusState)
{
m_canFocus = canFocusState;
if (true == m_hasFocus) {
(void)RmFocus();
}
}
void ewol::Widget::KeepFocus(void)
{
ewol::widgetManager::FocusKeep(this);
}
void ewol::Widget::GenDraw(DrawProperty displayProp)
{
if (true==m_hide){
// widget is hidden ...
return;
}
ewol::openGL::Push();
if( (displayProp.m_origin.x > m_origin.x)
|| (displayProp.m_origin.x + displayProp.m_size.x < m_size.x + m_origin.x) ) {
// here we invert the reference of the standard OpenGl view because the reference in the common display is Top left and not buttom left
int32_t tmpOriginX = etk_max(displayProp.m_origin.x, m_origin.x);
int32_t tmppp1 = displayProp.m_origin.x + displayProp.m_size.x;
int32_t tmppp2 = m_origin.x + m_size.x;
int32_t tmpclipX = etk_min(tmppp1, tmppp2) - tmpOriginX;
int32_t tmpOriginY = etk_max(displayProp.m_origin.y, m_origin.y);
tmppp1 = displayProp.m_origin.y + displayProp.m_size.y;
tmppp2 = m_origin.y + m_size.y;
//int32_t tmpclipY = etk_min(tmppp1, tmppp2) - tmpOriginX;
glViewport( tmpOriginX,
tmpOriginY,
tmpclipX,
m_size.y);
etk::Matrix4 tmpTranslate = etk::Matrix4::Translate(etk::Vector3D<float>((float)(-tmpclipX/2 - (tmpOriginX-m_origin.x)), (float)(-m_size.y/2.0), -1.0f));
etk::Matrix4 tmpScale = etk::Matrix4::Scale(etk::Vector3D<float>(m_zoom, m_zoom, 1.0f));
etk::Matrix4 tmpProjection = etk::Matrix4::Perspective(-tmpclipX/2, tmpclipX/2, -m_size.y/2, m_size.y/2, -1, 1);
etk::Matrix4 tmpMat = tmpProjection * tmpScale * tmpTranslate;
// set internal matrix system :
ewol::openGL::SetMatrix(tmpMat);
// Call the widget drawing methode
displayProp.m_origin.x = tmpOriginX;
displayProp.m_origin.y = tmpOriginY;
displayProp.m_size.x = tmpclipX;
displayProp.m_size.y = m_size.y;
OnDraw(displayProp);
} else {
glViewport( m_origin.x,
m_origin.y,
m_size.x,
m_size.y);
etk::Matrix4 tmpTranslate = etk::Matrix4::Translate(etk::Vector3D<float>(-m_size.x/2, -m_size.y/2, -1.0f));
etk::Matrix4 tmpScale = etk::Matrix4::Scale(etk::Vector3D<float>(m_zoom, m_zoom, 1.0f));
etk::Matrix4 tmpProjection = etk::Matrix4::Perspective(-m_size.x/2, m_size.x/2, -m_size.y/2, m_size.y/2, -1, 1);
etk::Matrix4 tmpMat = tmpProjection * tmpScale * tmpTranslate;
// set internal matrix system :
ewol::openGL::SetMatrix(tmpMat);
// Call the widget drawing methode
displayProp.m_origin = m_origin;
displayProp.m_size = m_size;
OnDraw(displayProp);
}
ewol::openGL::Pop();
return;
}
void ewol::Widget::PeriodicCallSet(bool statusToSet)
{
if (true == statusToSet) {
ewol::widgetManager::PeriodicCallAdd(this);
} else {
ewol::widgetManager::PeriodicCallRm(this);
}
}
void ewol::Widget::MarkToRedraw(void)
{
m_needRegenerateDisplay = true;
ewol::widgetManager::MarkDrawingIsNeeded();
};
// ----------------------------------------------------------------------------------------------------------------
// -- Shortcut : management of the shortcut
// ----------------------------------------------------------------------------------------------------------------
void ewol::Widget::ShortCutAdd(const char * descriptiveString, const char * generateEventId, etk::UString data, bool broadcast)
{
if( NULL==descriptiveString
|| 0==strlen(descriptiveString))
{
EWOL_ERROR("try to add shortcut with no descriptive string ...");
return;
}
EventShortCut* tmpElement = new EventShortCut();
if (NULL == tmpElement) {
EWOL_ERROR("allocation error ... Memory error ...");
return;
}
tmpElement->broadcastEvent = broadcast;
tmpElement->generateEventId = generateEventId;
tmpElement->eventData = data;
// parsing of the string :
//"ctrl+shift+alt+meta+s"
const char * tmp = strstr(descriptiveString, "ctrl");
if(NULL != tmp) {
tmpElement->specialKey.ctrl = true;
}
tmp = strstr(descriptiveString, "shift");
if(NULL != tmp) {
tmpElement->specialKey.shift = true;
}
tmp = strstr(descriptiveString, "alt");
if(NULL != tmp) {
tmpElement->specialKey.alt = true;
}
tmp = strstr(descriptiveString, "meta");
if(NULL != tmp) {
tmpElement->specialKey.meta = true;
}
if(NULL != strstr(descriptiveString, "F12") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardF12;
} else if(NULL != strstr(descriptiveString, "F11") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardF11;
} else if(NULL != strstr(descriptiveString, "F10") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardF10;
} else if(NULL != strstr(descriptiveString, "F9") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardF9;
} else if(NULL != strstr(descriptiveString, "F8") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardF8;
} else if(NULL != strstr(descriptiveString, "F7") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardF7;
} else if(NULL != strstr(descriptiveString, "F6") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardF6;
} else if(NULL != strstr(descriptiveString, "F5") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardF5;
} else if(NULL != strstr(descriptiveString, "F4") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardF4;
} else if(NULL != strstr(descriptiveString, "F3") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardF3;
} else if(NULL != strstr(descriptiveString, "F2") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardF2;
} else if(NULL != strstr(descriptiveString, "F1") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardF1;
} else if(NULL != strstr(descriptiveString, "LEFT") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardLeft;
} else if(NULL != strstr(descriptiveString, "RIGHT") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardRight;
} else if(NULL != strstr(descriptiveString, "UP") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardUp;
} else if(NULL != strstr(descriptiveString, "DOWN") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardDown;
} else if(NULL != strstr(descriptiveString, "PAGE_UP") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardPageUp;
} else if(NULL != strstr(descriptiveString, "PAGE_DOWN") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardPageDown;
} else if(NULL != strstr(descriptiveString, "START") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardStart;
} else if(NULL != strstr(descriptiveString, "END") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardEnd;
} else if(NULL != strstr(descriptiveString, "CENTER") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardCenter;
} else if(NULL != strstr(descriptiveString, "ARRET_DEFIL") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardStopDefil;
} else if(NULL != strstr(descriptiveString, "WAIT") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardWait;
} else if(NULL != strstr(descriptiveString, "INSERT") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardInsert;
} else if(NULL != strstr(descriptiveString, "CAPLOCK") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardCapLock;
} else if(NULL != strstr(descriptiveString, "CONTEXT_MENU") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardContextMenu;
} else if(NULL != strstr(descriptiveString, "VER_NUM") ) {
tmpElement->keyboardMoveValue = ewol::keyEvent::keyboardVerNum;
} else {
tmpElement->unicodeValue = descriptiveString[strlen(descriptiveString) -1];
}
// add it on the List ...
m_localShortcut.PushBack(tmpElement);
}
void ewol::Widget::ShortCutClean(void)
{
for (int32_t iii=0; iii<m_localShortcut.Size(); iii++) {
if (NULL != m_localShortcut[iii]) {
delete(m_localShortcut[iii]);
m_localShortcut[iii]=NULL;
}
}
m_localShortcut.Clear();
}
bool ewol::Widget::OnEventShortCut(ewol::SpecialKey& special, uniChar_t unicodeValue, ewol::keyEvent::keyboard_te kbMove, bool isDown)
{
if (unicodeValue >= 'A' && unicodeValue <='Z') {
unicodeValue += 'a' - 'A';
}
//EWOL_INFO("Try to find generic shortcut ...");
for(int32_t iii=m_localShortcut.Size()-1; iii>=0; iii--) {
if(NULL != m_localShortcut[iii]) {
if( m_localShortcut[iii]->specialKey.shift == special.shift
&& m_localShortcut[iii]->specialKey.ctrl == special.ctrl
&& m_localShortcut[iii]->specialKey.alt == special.alt
&& m_localShortcut[iii]->specialKey.meta == special.meta
&& ( ( m_localShortcut[iii]->keyboardMoveValue == ewol::keyEvent::keyboardUnknow
&& m_localShortcut[iii]->unicodeValue == unicodeValue)
|| ( m_localShortcut[iii]->keyboardMoveValue == kbMove
&& m_localShortcut[iii]->unicodeValue == 0)
) )
{
if (isDown) {
if (true == m_localShortcut[iii]->broadcastEvent) {
// send message at all the widget (exepted this one)
SendMultiCast(m_localShortcut[iii]->generateEventId, m_localShortcut[iii]->eventData);
}
// send message direct to the current widget (in every case, really useful for some generic windows shortcut)
OnReceiveMessage(this, m_localShortcut[iii]->generateEventId, m_localShortcut[iii]->eventData);
} // no else
return true;
}
}
}
return false;
}