389 lines
10 KiB
C++
389 lines
10 KiB
C++
/**
|
|
* @author Edouard DUPIN
|
|
*
|
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
|
*
|
|
* @license BSD v3 (see license file)
|
|
*/
|
|
|
|
|
|
#include <ewol/ewol.h>
|
|
#include <ewol/widget/Button.h>
|
|
#include <ewol/widget/WidgetManager.h>
|
|
|
|
|
|
extern const char * const ewolEventButtonPressed = "ewol-button-Pressed";
|
|
extern const char * const ewolEventButtonDown = "ewol-button-down";
|
|
extern const char * const ewolEventButtonUp = "ewol-button-up";
|
|
extern const char * const ewolEventButtonEnter = "ewol-button-enter";
|
|
extern const char * const ewolEventButtonLeave = "ewol-button-leave";
|
|
extern const char * const ewolEventButtonValue = "ewol-button-value";
|
|
|
|
#undef __class__
|
|
#define __class__ "Button"
|
|
|
|
// DEFINE for the shader display system :
|
|
#define STATUS_UP (0)
|
|
#define STATUS_HOVER (2)
|
|
#define STATUS_PRESSED (1)
|
|
#define STATUS_DOWN (3)
|
|
|
|
|
|
widget::Button::Button(etk::UString newLabel, etk::UString shaperName) :
|
|
m_shaper(shaperName),
|
|
m_label(newLabel),
|
|
m_toggleMode(false),
|
|
m_value(false),
|
|
m_mouseHover(false),
|
|
m_buttonPressed(false),
|
|
m_imageDisplaySize(32)
|
|
{
|
|
AddEventId(ewolEventButtonPressed);
|
|
AddEventId(ewolEventButtonDown);
|
|
AddEventId(ewolEventButtonUp);
|
|
AddEventId(ewolEventButtonEnter);
|
|
AddEventId(ewolEventButtonLeave);
|
|
AddEventId(ewolEventButtonValue);
|
|
|
|
m_shaper.ChangeStatusIn(STATUS_UP);
|
|
|
|
SetCanHaveFocus(true);
|
|
// Limit event at 1:
|
|
SetMouseLimit(1);
|
|
}
|
|
|
|
|
|
widget::Button::~Button(void)
|
|
{
|
|
|
|
}
|
|
|
|
void widget::Button::SetShaperName(etk::UString shaperName)
|
|
{
|
|
m_shaper.SetSource(shaperName);
|
|
}
|
|
|
|
void widget::Button::SetImage(etk::UString imageName, draw::Color color)
|
|
{
|
|
m_imageColor = color;
|
|
m_displayImage.SetSource(imageName);
|
|
MarkToRedraw();
|
|
ewol::RequestUpdateSize();
|
|
}
|
|
|
|
void widget::Button::SetImageToggle(etk::UString imageName, draw::Color color)
|
|
{
|
|
m_imageColorToggle = color;
|
|
m_displayImageToggle.SetSource(imageName);
|
|
MarkToRedraw();
|
|
ewol::RequestUpdateSize();
|
|
}
|
|
|
|
|
|
bool widget::Button::CalculateMinSize(void)
|
|
{
|
|
vec2 padding = m_shaper.GetPadding();
|
|
m_displayText.Clear();
|
|
ivec3 minSize = m_displayText.CalculateSizeDecorated(m_label);
|
|
if( true == m_toggleMode
|
|
&& m_labelToggle.Size()!=0) {
|
|
m_displayText.Clear();
|
|
ivec3 minSizeToggle = m_displayText.CalculateSizeDecorated(m_labelToggle);
|
|
minSize.x = etk_max(minSize.x, minSizeToggle.x);
|
|
minSize.y = etk_max(minSize.y, minSizeToggle.y);
|
|
minSize.z = etk_max(minSize.z, minSizeToggle.z);
|
|
}
|
|
m_minSize.x = padding.x*2 + minSize.x;
|
|
m_minSize.y = padding.y*2 + minSize.y;
|
|
// Add the image element ...
|
|
if( true == m_displayImage.HasSources()
|
|
|| true == m_displayImageToggle.HasSources()) {
|
|
m_minSize.x += padding.x/2 + m_imageDisplaySize;
|
|
}
|
|
MarkToRedraw();
|
|
return true;
|
|
}
|
|
|
|
|
|
void widget::Button::SetLabel(etk::UString newLabel)
|
|
{
|
|
m_label = newLabel;
|
|
MarkToRedraw();
|
|
ewol::RequestUpdateSize();
|
|
}
|
|
|
|
etk::UString widget::Button::GetLabel(void)
|
|
{
|
|
return m_label;
|
|
}
|
|
|
|
void widget::Button::SetLabelToggle(etk::UString newLabel)
|
|
{
|
|
m_labelToggle = newLabel;
|
|
MarkToRedraw();
|
|
ewol::RequestUpdateSize();
|
|
}
|
|
|
|
etk::UString widget::Button::GetLabelToggle(void)
|
|
{
|
|
return m_labelToggle;
|
|
}
|
|
|
|
void widget::Button::SetValue(bool val)
|
|
{
|
|
if (m_value != val) {
|
|
m_value = val;
|
|
MarkToRedraw();
|
|
}
|
|
}
|
|
|
|
bool widget::Button::GetValue(void)
|
|
{
|
|
return m_value;
|
|
}
|
|
|
|
void widget::Button::SetToggleMode(bool togg)
|
|
{
|
|
if (m_toggleMode != togg) {
|
|
m_toggleMode = togg;
|
|
if (m_value == true) {
|
|
m_value = false;
|
|
// TODO : Change display and send event ...
|
|
}
|
|
MarkToRedraw();
|
|
}
|
|
}
|
|
|
|
void widget::Button::OnDraw(ewol::DrawProperty& displayProp)
|
|
{
|
|
m_shaper.Draw();
|
|
if( false == m_toggleMode
|
|
|| false == m_value) {
|
|
m_displayImage.Draw();
|
|
} else {
|
|
m_displayImageToggle.Draw();
|
|
}
|
|
m_displayText.Draw();
|
|
}
|
|
|
|
void widget::Button::OnRegenerateDisplay(void)
|
|
{
|
|
if (true == NeedRedraw()) {
|
|
|
|
vec2 padding = m_shaper.GetPadding();
|
|
// to know the size of one Line :
|
|
ivec3 minSize = m_displayText.CalculateSize('A');
|
|
ivec3 curentTextSize;
|
|
if( false == m_toggleMode
|
|
|| false == m_value
|
|
|| m_labelToggle.Size()==0) {
|
|
curentTextSize = m_displayText.CalculateSizeDecorated(m_label);
|
|
} else {
|
|
curentTextSize = m_displayText.CalculateSizeDecorated(m_labelToggle);
|
|
}
|
|
|
|
m_displayImage.Clear();
|
|
m_displayImageToggle.Clear();
|
|
m_shaper.Clear();
|
|
m_displayText.Clear();
|
|
|
|
ivec2 localSize = m_minSize;
|
|
|
|
vec3 tmpOrigin((m_size.x - m_minSize.x) / 2.0,
|
|
(m_size.y - m_minSize.y) / 2.0,
|
|
0.0);
|
|
|
|
// no change for the text orogin :
|
|
vec3 tmpTextOrigin((m_size.x - m_minSize.x) / 2.0,
|
|
(m_size.y - m_minSize.y) / 2.0,
|
|
0.0);
|
|
|
|
if (true==m_userFill.x) {
|
|
localSize.x = m_size.x;
|
|
tmpOrigin.x = 0.0;
|
|
tmpTextOrigin.x = 0.0;
|
|
}
|
|
if (true==m_userFill.y) {
|
|
localSize.y = m_size.y;
|
|
}
|
|
tmpOrigin.x += padding.x;
|
|
tmpOrigin.y += padding.y;
|
|
tmpTextOrigin.x += padding.x;
|
|
tmpTextOrigin.y += padding.y;
|
|
localSize.x -= 2*padding.x;
|
|
localSize.y -= 2*padding.y;
|
|
|
|
tmpTextOrigin.y += (m_minSize.y-2*padding.y) - minSize.y;
|
|
|
|
vec2 textPos(tmpTextOrigin.x, tmpTextOrigin.y);
|
|
|
|
if( true == m_displayImage.HasSources()
|
|
|| true == m_displayImageToggle.HasSources()) {
|
|
ivec3 imagePos(tmpOrigin.x-padding.x/4,
|
|
tmpOrigin.y-padding.x/4+(m_minSize.y-m_imageDisplaySize-2*padding.y)/2.0,
|
|
0);
|
|
ivec2 imageSize(m_imageDisplaySize,
|
|
m_imageDisplaySize);
|
|
if( false==m_toggleMode
|
|
|| false==m_value) {
|
|
m_displayImage.SetPos(imagePos);
|
|
m_displayImage.SetColor(m_imageColor);
|
|
m_displayImage.Print(imageSize);
|
|
} else {
|
|
m_displayImageToggle.SetPos(imagePos);
|
|
m_displayImageToggle.SetColor(m_imageColorToggle);
|
|
m_displayImageToggle.Print(imageSize);
|
|
}
|
|
// update the text position ...
|
|
tmpTextOrigin.x += padding.x/2 + m_imageDisplaySize;
|
|
}
|
|
|
|
vec3 drawClippingPos(padding.x, padding.y, -0.5);
|
|
vec3 drawClippingSize((float)(m_size.x - padding.x),
|
|
(float)(m_size.y - padding.y),
|
|
(float)1.0);
|
|
|
|
// clean the element
|
|
m_displayText.Reset();
|
|
m_displayText.SetPos(tmpTextOrigin);
|
|
if( true == m_displayImage.HasSources()
|
|
|| true == m_displayImageToggle.HasSources()) {
|
|
m_displayText.SetTextAlignement(tmpTextOrigin.x, tmpTextOrigin.x+localSize.x-m_imageDisplaySize, ewol::Text::alignCenter);
|
|
} else {
|
|
m_displayText.SetTextAlignement(tmpTextOrigin.x, tmpTextOrigin.x+localSize.x, ewol::Text::alignCenter);
|
|
}
|
|
m_displayText.SetClipping(drawClippingPos, drawClippingSize);
|
|
if( false == m_toggleMode
|
|
|| false == m_value
|
|
|| m_labelToggle.Size()==0) {
|
|
m_displayText.PrintDecorated(m_label);
|
|
} else {
|
|
m_displayText.PrintDecorated(m_labelToggle);
|
|
}
|
|
//m_displayText.Translate(tmpOrigin);
|
|
|
|
|
|
if (true==m_userFill.y) {
|
|
tmpOrigin.y = padding.y;
|
|
}
|
|
|
|
// selection area :
|
|
m_selectableAreaPos = vec2(tmpOrigin.x-padding.x, tmpOrigin.y-padding.y);
|
|
m_selectableAreaSize = localSize + vec2(2,2)*padding;
|
|
m_shaper.SetOrigin(m_selectableAreaPos );
|
|
m_shaper.SetSize(m_selectableAreaSize);
|
|
m_shaper.SetInsidePos(vec2(tmpTextOrigin.x, tmpTextOrigin.y) );
|
|
vec3 tmpp = m_displayText.CalculateSize(m_label);
|
|
vec2 tmpp2(tmpp.x, tmpp.y);
|
|
m_shaper.SetInsideSize(tmpp2);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
bool widget::Button::OnEventInput(ewol::keyEvent::type_te type, int32_t IdInput, ewol::keyEvent::status_te typeEvent, vec2 pos)
|
|
{
|
|
bool previousHoverState = m_mouseHover;
|
|
if(ewol::keyEvent::statusLeave == typeEvent) {
|
|
m_mouseHover = false;
|
|
m_buttonPressed = false;
|
|
} else {
|
|
vec2 relativePos = RelativePosition(pos);
|
|
// prevent error from ouside the button
|
|
if( relativePos.x < m_selectableAreaPos.x
|
|
|| relativePos.y < m_selectableAreaPos.y
|
|
|| relativePos.x > m_selectableAreaPos.x + m_selectableAreaSize.x
|
|
|| relativePos.y > m_selectableAreaPos.y + m_selectableAreaSize.y ) {
|
|
m_mouseHover = false;
|
|
m_buttonPressed = false;
|
|
} else {
|
|
m_mouseHover = true;
|
|
}
|
|
}
|
|
bool previousPressed = m_buttonPressed;
|
|
//EWOL_DEBUG("Event on BT ... mouse position : " << m_mouseHover);
|
|
if (true == m_mouseHover) {
|
|
if (1 == IdInput) {
|
|
if(ewol::keyEvent::statusDown == typeEvent) {
|
|
GenerateEventId(ewolEventButtonDown);
|
|
m_buttonPressed = true;
|
|
MarkToRedraw();
|
|
}
|
|
if(ewol::keyEvent::statusUp == typeEvent) {
|
|
GenerateEventId(ewolEventButtonUp);
|
|
m_buttonPressed = false;
|
|
MarkToRedraw();
|
|
}
|
|
if(ewol::keyEvent::statusSingle == typeEvent) {
|
|
// inverse value :
|
|
m_value = (m_value)?false:true;
|
|
GenerateEventId(ewolEventButtonPressed);
|
|
GenerateEventId(ewolEventButtonValue, m_value);
|
|
if( false == m_toggleMode
|
|
&& true == m_value) {
|
|
m_value = false;
|
|
GenerateEventId(ewolEventButtonValue, m_value);
|
|
}
|
|
MarkToRedraw();
|
|
}
|
|
}
|
|
}
|
|
if( m_mouseHover != previousHoverState
|
|
|| m_buttonPressed != previousPressed) {
|
|
if (true==m_buttonPressed) {
|
|
ChangeStatusIn(STATUS_PRESSED);
|
|
} else {
|
|
if (true==m_mouseHover) {
|
|
ChangeStatusIn(STATUS_HOVER);
|
|
} else {
|
|
if (true == m_value) {
|
|
ChangeStatusIn(STATUS_DOWN);
|
|
} else {
|
|
ChangeStatusIn(STATUS_UP);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return m_mouseHover;
|
|
}
|
|
|
|
|
|
bool widget::Button::OnEventKb(ewol::keyEvent::status_te typeEvent, uniChar_t unicodeData)
|
|
{
|
|
//EWOL_DEBUG("BT PRESSED : \"" << UTF8_data << "\" size=" << strlen(UTF8_data));
|
|
if( typeEvent == ewol::keyEvent::statusDown
|
|
&& unicodeData == '\r') {
|
|
GenerateEventId(ewolEventButtonEnter);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
void widget::Button::ChangeStatusIn(int32_t newStatusId)
|
|
{
|
|
if (true == m_shaper.ChangeStatusIn(newStatusId) ) {
|
|
PeriodicCallSet(true);
|
|
MarkToRedraw();
|
|
}
|
|
}
|
|
|
|
|
|
void widget::Button::PeriodicCall(int64_t localTime)
|
|
{
|
|
if (false == m_shaper.PeriodicCall(localTime) ) {
|
|
PeriodicCallSet(false);
|
|
}
|
|
MarkToRedraw();
|
|
}
|
|
|
|
void widget::Button::SetImageSize(int32_t size)
|
|
{
|
|
MarkToRedraw();
|
|
ewol::RequestUpdateSize();
|
|
m_imageDisplaySize = size;
|
|
}
|
|
|
|
|
|
|