[DEV] create a better button with test application for it
This commit is contained in:
parent
67e4d5363c
commit
d69a964459
@ -5,6 +5,7 @@ precision mediump int;
|
||||
|
||||
struct displayProperty {
|
||||
vec2 size;
|
||||
vec2 origin;
|
||||
vec2 insidePos;
|
||||
vec2 insideSize;
|
||||
};
|
||||
@ -33,19 +34,21 @@ void main(void) {
|
||||
S_colorFg[0] = vec4(0.5,0.5,0.5,0.3);
|
||||
S_colorFg[1] = vec4(0.7,0.0,0.0,0.4);
|
||||
S_colorFg[2] = vec4(0.0,0.0,0.7,0.4);
|
||||
// prevent origin moving ...
|
||||
vec2 position = v_position - EW_widgetProperty.origin;
|
||||
|
||||
float specialBorder = S_sizeBorder+S_sizePadding;
|
||||
vec2 endStart = EW_widgetProperty.size - vec2(S_sizePadding) - vec2(S_sizeBorder);
|
||||
vec2 endStop = EW_widgetProperty.size - vec2(S_sizePadding);
|
||||
if( v_position.x> S_sizePadding
|
||||
&& v_position.y> S_sizePadding
|
||||
&& v_position.x<= endStop.x
|
||||
&& v_position.y<= endStop.y
|
||||
if( position.x> S_sizePadding
|
||||
&& position.y> S_sizePadding
|
||||
&& position.x<= endStop.x
|
||||
&& position.y<= endStop.y
|
||||
) {
|
||||
if( v_position.x<= specialBorder
|
||||
|| v_position.y<= specialBorder
|
||||
|| v_position.x> endStart.x
|
||||
|| v_position.y> endStart.y
|
||||
if( position.x<= specialBorder
|
||||
|| position.y<= specialBorder
|
||||
|| position.x> endStart.x
|
||||
|| position.y> endStart.y
|
||||
) {
|
||||
gl_FragColor = S_colorBorder;
|
||||
} else {
|
||||
|
@ -5,6 +5,7 @@ precision mediump int;
|
||||
|
||||
struct displayProperty {
|
||||
vec2 size;
|
||||
vec2 origin;
|
||||
vec2 insidePos;
|
||||
vec2 insideSize;
|
||||
};
|
||||
@ -34,19 +35,22 @@ void main(void) {
|
||||
S_colorFg[1] = vec4(1.0,1.0,1.0,0.4);
|
||||
S_colorFg[2] = vec4(0.0,0.0,1.0,0.1);
|
||||
|
||||
// prevent origin moving ...
|
||||
vec2 position = v_position - EW_widgetProperty.origin;
|
||||
|
||||
float specialBorder = S_sizeBorder+S_sizePadding;
|
||||
vec2 endStart = EW_widgetProperty.size - vec2(S_sizePadding) - vec2(S_sizeBorder);
|
||||
vec2 endStop = EW_widgetProperty.size - vec2(S_sizePadding);
|
||||
if( v_position.x> S_sizePadding
|
||||
&& v_position.y> S_sizePadding
|
||||
&& v_position.x<= endStop.x
|
||||
&& v_position.y<= endStop.y
|
||||
if( position.x> S_sizePadding
|
||||
&& position.y> S_sizePadding
|
||||
&& position.x<= endStop.x
|
||||
&& position.y<= endStop.y
|
||||
) {
|
||||
// inside element
|
||||
if( v_position.x<= specialBorder
|
||||
|| v_position.y<= specialBorder
|
||||
|| v_position.x> endStart.x
|
||||
|| v_position.y> endStart.y
|
||||
if( position.x<= specialBorder
|
||||
|| position.y<= specialBorder
|
||||
|| position.x> endStart.x
|
||||
|| position.y> endStart.y
|
||||
) {
|
||||
// border ...
|
||||
gl_FragColor = S_colorBorder;
|
||||
|
@ -5,6 +5,7 @@ precision mediump int;
|
||||
|
||||
struct displayProperty {
|
||||
vec2 size;
|
||||
vec2 origin;
|
||||
vec2 insidePos;
|
||||
vec2 insideSize;
|
||||
};
|
||||
@ -34,6 +35,10 @@ float S_roundedRatio = 10.0;
|
||||
void main(void) {
|
||||
// position form center :
|
||||
vec2 ratio = EW_widgetProperty.size / 2.0;
|
||||
|
||||
// prevent origin moving ...
|
||||
vec2 position = v_position - EW_widgetProperty.origin;
|
||||
|
||||
/* generate a central simetry
|
||||
____ _____
|
||||
\ /
|
||||
@ -41,7 +46,7 @@ void main(void) {
|
||||
\ /
|
||||
-
|
||||
*/
|
||||
vec2 positionCenter = abs(v_position-ratio);
|
||||
vec2 positionCenter = abs(position-ratio);
|
||||
// This is a clip to remove center of the display of the widget
|
||||
vec2 ratioLow = ratio - (S_roundedRatio+S_sizePadding);
|
||||
vec2 circleMode = smoothstep(ratioLow, ratio, positionCenter)*(S_roundedRatio+S_sizePadding);
|
||||
|
@ -5,6 +5,7 @@ precision mediump int;
|
||||
|
||||
struct displayProperty {
|
||||
vec2 size;
|
||||
vec2 origin;
|
||||
vec2 insidePos;
|
||||
vec2 insideSize;
|
||||
};
|
||||
@ -33,7 +34,11 @@ float S_roundedRatio = 10.0;
|
||||
void main(void) {
|
||||
// position form center :
|
||||
vec2 ratio = EW_widgetProperty.size / 2.0;
|
||||
vec2 positionCenter = abs(v_position-ratio);
|
||||
|
||||
// prevent origin moving ...
|
||||
vec2 position = v_position - EW_widgetProperty.origin;
|
||||
|
||||
vec2 positionCenter = abs(position-ratio);
|
||||
vec2 ratioHight = ratio - S_sizePadding;
|
||||
vec2 ratioLow = ratioHight - (S_sizeBorder+S_roundedRatio);
|
||||
vec2 circleMode = smoothstep(ratioLow, ratioHight, positionCenter);
|
||||
|
@ -40,24 +40,7 @@ ewol::Shaper::Shaper(etk::UString shaperName) :
|
||||
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;
|
||||
UpdateVectex();
|
||||
}
|
||||
|
||||
ewol::Shaper::~Shaper(void)
|
||||
@ -101,6 +84,7 @@ void ewol::Shaper::LoadProgram(void)
|
||||
m_GLMatrix = m_GLprogram->GetUniform("EW_MatrixTransformation");
|
||||
// Widget property ==> for the Vertex shader
|
||||
m_GLPropertySize = m_GLprogram->GetUniform("EW_widgetProperty.size");
|
||||
m_GLPropertyOrigin = m_GLprogram->GetUniform("EW_widgetProperty.origin");
|
||||
m_GLPropertyInsidePos = m_GLprogram->GetUniform("EW_widgetProperty.insidePos");
|
||||
m_GLPropertyInsideSize = m_GLprogram->GetUniform("EW_widgetProperty.insideSize");
|
||||
// status property ==> for the fragment shader
|
||||
@ -139,6 +123,7 @@ void ewol::Shaper::Draw(void)
|
||||
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_GLPropertyOrigin, 1, &m_propertyOrigin.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);
|
||||
@ -202,26 +187,29 @@ bool ewol::Shaper::PeriodicCall(int64_t localTime)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ewol::Shaper::UpdateVectex(void)
|
||||
{
|
||||
// set coord ==> must be a static VBO ...
|
||||
m_coord[0].x= m_propertyOrigin.x;
|
||||
m_coord[0].y= m_propertyOrigin.y+m_propertySize.y;
|
||||
m_coord[1].x= m_propertyOrigin.x;
|
||||
m_coord[1].y= m_propertyOrigin.y;
|
||||
m_coord[2].x= m_propertyOrigin.x+m_propertySize.x;
|
||||
m_coord[2].y= m_propertyOrigin.y;
|
||||
|
||||
m_coord[3].x= m_propertyOrigin.x+m_propertySize.x;
|
||||
m_coord[3].y= m_propertyOrigin.y;
|
||||
m_coord[4].x= m_propertyOrigin.x+m_propertySize.x;
|
||||
m_coord[4].y= m_propertyOrigin.y+m_propertySize.y;
|
||||
m_coord[5].x= m_propertyOrigin.x;
|
||||
m_coord[5].y= m_propertyOrigin.y+m_propertySize.y;
|
||||
}
|
||||
|
||||
void ewol::Shaper::SetOrigin(etk::Vector2D<float> newOri)
|
||||
{
|
||||
if (m_propertyOrigin != newOri) {
|
||||
m_propertyOrigin = newOri;
|
||||
EWOL_CRITICAL("Set ori : " << m_propertyOrigin);
|
||||
// set coord ==> must be a static VBO ...
|
||||
m_coord[0].x= m_propertyOrigin.x;
|
||||
m_coord[0].y= m_propertyOrigin.y+m_propertySize.y;
|
||||
m_coord[1].x= m_propertyOrigin.x;
|
||||
m_coord[1].y= m_propertyOrigin.y;
|
||||
m_coord[2].x= m_propertyOrigin.x+m_propertySize.x;
|
||||
m_coord[2].y= m_propertyOrigin.y;
|
||||
|
||||
m_coord[3].x= m_propertyOrigin.x+m_propertySize.x;
|
||||
m_coord[3].y= m_propertyOrigin.y;
|
||||
m_coord[4].x= m_propertyOrigin.x+m_propertySize.x;
|
||||
m_coord[4].y= m_propertyOrigin.y+m_propertySize.y;
|
||||
m_coord[5].x= m_propertyOrigin.x;
|
||||
m_coord[5].y= m_propertyOrigin.x+m_propertySize.y;
|
||||
UpdateVectex();
|
||||
}
|
||||
|
||||
}
|
||||
@ -230,20 +218,7 @@ 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= m_propertyOrigin.x;
|
||||
m_coord[0].y= m_propertyOrigin.y+m_propertySize.y;
|
||||
m_coord[1].x= m_propertyOrigin.x;
|
||||
m_coord[1].y= m_propertyOrigin.y;
|
||||
m_coord[2].x= m_propertyOrigin.x+m_propertySize.x;
|
||||
m_coord[2].y= m_propertyOrigin.y;
|
||||
|
||||
m_coord[3].x= m_propertyOrigin.x+m_propertySize.x;
|
||||
m_coord[3].y= m_propertyOrigin.y;
|
||||
m_coord[4].x= m_propertyOrigin.x+m_propertySize.x;
|
||||
m_coord[4].y= m_propertyOrigin.y+m_propertySize.y;
|
||||
m_coord[5].x= m_propertyOrigin.x;
|
||||
m_coord[5].y= m_propertyOrigin.x+m_propertySize.y;
|
||||
UpdateVectex();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ namespace ewol
|
||||
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_GLPropertyOrigin; //!< openGL id on the element (widget origin)
|
||||
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)
|
||||
@ -128,6 +129,11 @@ namespace ewol
|
||||
* @return the validity od the resources.
|
||||
*/
|
||||
bool HasSources(void);
|
||||
private:
|
||||
/**
|
||||
* @brief Update the internal vertex table.
|
||||
*/
|
||||
void UpdateVectex(void);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -165,6 +165,7 @@ void widget::Button::OnRegenerateDisplay(void)
|
||||
etk::Vector3D<float> tmpOrigin((float)((m_size.x - m_minSize.x) / 2.0),
|
||||
(float)((m_size.y - m_minSize.y) / 2.0),
|
||||
(float)(0.0));
|
||||
|
||||
// no change for the text orogin :
|
||||
etk::Vector3D<float> tmpTextOrigin((float)((m_size.x - m_minSize.x) / 2.0 + padding.x),
|
||||
(float)((m_size.y - m_minSize.y) / 2.0 + padding.y),
|
||||
@ -176,7 +177,7 @@ void widget::Button::OnRegenerateDisplay(void)
|
||||
}
|
||||
if (true==m_userFill.y) {
|
||||
localSize.y = m_size.y;
|
||||
tmpOrigin.y = 0.0;
|
||||
//tmpOrigin.y = 0.0;
|
||||
}
|
||||
tmpOrigin.x += padding.x;
|
||||
tmpOrigin.y += padding.y;
|
||||
@ -209,7 +210,7 @@ void widget::Button::OnRegenerateDisplay(void)
|
||||
|
||||
// clean the element
|
||||
m_displayText.Clear();
|
||||
m_displayText.SetTextAlignement(0, localSize.x + 2*padding.x);
|
||||
m_displayText.SetTextAlignement(0, localSize.x + 2*padding.x, ewol::Text::alignCenter);
|
||||
m_displayText.SetClipping(drawClippingPos, drawClippingSize);
|
||||
if( false == m_toggleMode
|
||||
|| false == m_value) {
|
||||
@ -219,10 +220,16 @@ void widget::Button::OnRegenerateDisplay(void)
|
||||
}
|
||||
m_displayText.Translate(tmpOrigin);
|
||||
|
||||
//m_shaper.SetOrigin(etk::Vector2D<float>(tmpTextOrigin.x-padding.x, tmpTextOrigin.y-padding.y) );
|
||||
localSize.x += 2*padding.x;
|
||||
localSize.y += 2*padding.y;
|
||||
m_shaper.SetSize(localSize);
|
||||
|
||||
if (true==m_userFill.y) {
|
||||
tmpOrigin.y = padding.y;
|
||||
}
|
||||
|
||||
// selection area :
|
||||
m_selectableAreaPos = etk::Vector2D<float>(tmpOrigin.x-padding.x, tmpOrigin.y-padding.y);
|
||||
m_selectableAreaSize = localSize + etk::Vector2D<float>(2,2)*padding;
|
||||
m_shaper.SetOrigin(m_selectableAreaPos );
|
||||
m_shaper.SetSize(m_selectableAreaSize);
|
||||
m_shaper.SetInsidePos(etk::Vector2D<float>(tmpTextOrigin.x, tmpTextOrigin.y) );
|
||||
etk::Vector3D<float> tmpp = m_displayText.CalculateSize(m_label);
|
||||
etk::Vector2D<float> tmpp2(tmpp.x, tmpp.y);
|
||||
@ -234,11 +241,21 @@ void widget::Button::OnRegenerateDisplay(void)
|
||||
|
||||
bool widget::Button::OnEventInput(ewol::keyEvent::type_te type, int32_t IdInput, ewol::keyEvent::status_te typeEvent, etk::Vector2D<float> pos)
|
||||
{
|
||||
if(ewol::keyEvent::statusLeave == typeEvent) {
|
||||
ChangeStatusIn(STATUS_UP);
|
||||
}
|
||||
|
||||
etk::Vector2D<float> 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 ) {
|
||||
return false;
|
||||
}
|
||||
//EWOL_DEBUG("Event on BT ...");
|
||||
if(ewol::keyEvent::statusEnter == typeEvent) {
|
||||
ChangeStatusIn(STATUS_HOVER);
|
||||
}else if(ewol::keyEvent::statusLeave == typeEvent) {
|
||||
ChangeStatusIn(STATUS_UP);
|
||||
}
|
||||
if (1 == IdInput) {
|
||||
if(ewol::keyEvent::statusDown == typeEvent) {
|
||||
|
@ -36,6 +36,9 @@ namespace widget {
|
||||
etk::UString m_labelToggle; //!< Label to display when toggle mode is set ("" whenit is the same).
|
||||
bool m_toggleMode; //!< The button is able to toggle.
|
||||
bool m_value; //!< Current state of the button.
|
||||
// hover area :
|
||||
etk::Vector2D<float> m_selectableAreaPos; //!< Start position of the events
|
||||
etk::Vector2D<float> m_selectableAreaSize; //!< Size of the event positions
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
|
@ -123,7 +123,7 @@ namespace ewol {
|
||||
* @param[in] pos Absolute position that you request convertion
|
||||
* @return the relative position
|
||||
*/
|
||||
virtual etk::Vector2D<float> RelativePosition(etk::Vector2D<float> pos);
|
||||
virtual etk::Vector2D<float> RelativePosition(etk::Vector2D<float> pos);
|
||||
/**
|
||||
* @brief Parrent set the possible diplay size of the current widget whith his own possibilities
|
||||
* By default this save the widget availlable size in the widget size
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include <ewol/widget/List.h>
|
||||
#include <ewol/widget/ContextMenu.h>
|
||||
#include <ewol/widget/PopUp.h>
|
||||
#include <ewol/widget/Spacer.h>
|
||||
#include <ewol/widget/Slider.h>
|
||||
#include <ewol/widget/Menu.h>
|
||||
#include <ewol/widget/meta/FileChooser.h>
|
||||
@ -70,6 +69,13 @@ MainWindows::MainWindows(void)
|
||||
myButton->RegisterOnEvent(this, ewolEventButtonValue, l_eventChangeExpendY);
|
||||
mySizerHori->SubWidgetAdd(myButton);
|
||||
}
|
||||
|
||||
mySizerHori = new widget::SizerHori();
|
||||
if (NULL == mySizerHori) {
|
||||
APPL_DEBUG("Allocation error mySizerHori");
|
||||
return;
|
||||
}
|
||||
mySizerVert->SubWidgetAdd(mySizerHori);
|
||||
myButton = new widget::Button("<center>Fill X (false)</center>");
|
||||
if (NULL != myButton) {
|
||||
myButton->SetToggleMode(true);
|
||||
@ -84,15 +90,70 @@ MainWindows::MainWindows(void)
|
||||
myButton->RegisterOnEvent(this, ewolEventButtonValue, l_eventChangeFillY);
|
||||
mySizerHori->SubWidgetAdd(myButton);
|
||||
}
|
||||
|
||||
m_button = new widget::Button("My Button");
|
||||
if (NULL != m_button) {
|
||||
m_button->SetExpendX(false);
|
||||
m_button->SetExpendY(false);
|
||||
m_button->SetFillX(false);
|
||||
m_button->SetFillY(false);
|
||||
mySizerVert->SubWidgetAdd(m_button);
|
||||
int32_t idSpacer=0;
|
||||
m_spacer[idSpacer] = new widget::Spacer();
|
||||
if (NULL != m_spacer[idSpacer]) {
|
||||
m_spacer[idSpacer]->SetExpendX(false);
|
||||
m_spacer[idSpacer]->SetExpendY(false);
|
||||
m_spacer[idSpacer]->SetFillX(true);
|
||||
m_spacer[idSpacer]->SetFillY(false);
|
||||
m_spacer[idSpacer]->SetSize(10);
|
||||
m_spacer[idSpacer]->SetColor(0xFF000080);
|
||||
mySizerVert->SubWidgetAdd(m_spacer[idSpacer]);
|
||||
}
|
||||
|
||||
mySizerHori = new widget::SizerHori();
|
||||
if (NULL == mySizerHori) {
|
||||
APPL_DEBUG("Allocation error mySizerHori");
|
||||
return;
|
||||
}
|
||||
mySizerVert->SubWidgetAdd(mySizerHori);
|
||||
|
||||
idSpacer++;
|
||||
m_spacer[idSpacer] = new widget::Spacer();
|
||||
if (NULL != m_spacer[idSpacer]) {
|
||||
m_spacer[idSpacer]->SetExpendX(false);
|
||||
m_spacer[idSpacer]->SetExpendY(false);
|
||||
m_spacer[idSpacer]->SetFillX(false);
|
||||
m_spacer[idSpacer]->SetFillY(true);
|
||||
m_spacer[idSpacer]->SetSize(10);
|
||||
m_spacer[idSpacer]->SetColor(0x00FF0080);
|
||||
mySizerHori->SubWidgetAdd(m_spacer[idSpacer]);
|
||||
}
|
||||
|
||||
m_button = new widget::Button("My <font color=\"#FF0000\">Button</font>");
|
||||
if (NULL != m_button) {
|
||||
m_button->SetExpendX(false);
|
||||
m_button->SetExpendY(false);
|
||||
m_button->SetFillX(false);
|
||||
m_button->SetFillY(false);
|
||||
mySizerHori->SubWidgetAdd(m_button);
|
||||
}
|
||||
|
||||
idSpacer++;
|
||||
m_spacer[idSpacer] = new widget::Spacer();
|
||||
if (NULL != m_spacer[idSpacer]) {
|
||||
m_spacer[idSpacer]->SetExpendX(false);
|
||||
m_spacer[idSpacer]->SetExpendY(false);
|
||||
m_spacer[idSpacer]->SetFillX(false);
|
||||
m_spacer[idSpacer]->SetFillY(true);
|
||||
m_spacer[idSpacer]->SetSize(10);
|
||||
m_spacer[idSpacer]->SetColor(0x0000FF80);
|
||||
mySizerHori->SubWidgetAdd(m_spacer[idSpacer]);
|
||||
}
|
||||
|
||||
idSpacer++;
|
||||
m_spacer[idSpacer] = new widget::Spacer();
|
||||
if (NULL != m_spacer[idSpacer]) {
|
||||
m_spacer[idSpacer]->SetExpendX(false);
|
||||
m_spacer[idSpacer]->SetExpendY(false);
|
||||
m_spacer[idSpacer]->SetFillX(true);
|
||||
m_spacer[idSpacer]->SetFillY(false);
|
||||
m_spacer[idSpacer]->SetSize(10);
|
||||
m_spacer[idSpacer]->SetColor(0x00FFFF80);
|
||||
mySizerVert->SubWidgetAdd(m_spacer[idSpacer]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -13,11 +13,13 @@
|
||||
#include <ewol/widget/Widget.h>
|
||||
#include <ewol/widget/Windows.h>
|
||||
#include <ewol/widget/Button.h>
|
||||
#include <ewol/widget/Spacer.h>
|
||||
|
||||
class MainWindows : public ewol::Windows
|
||||
{
|
||||
private:
|
||||
widget::Button* m_button;
|
||||
widget::Spacer* m_spacer[4];
|
||||
public:
|
||||
// Constructeur
|
||||
MainWindows(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user