ewol/sources/ewol/widget/Widget.h

779 lines
27 KiB
C++

/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#ifndef __EWOL_WIDGET_H__
#define __EWOL_WIDGET_H__
#include <ewol/renderer/EObject.h>
#include <ewol/Dimension.h>
namespace ewol {
class Widget;
namespace widget {
class Manager;
class Windows;
};
};
#include <etk/types.h>
#include <vector>
#include <etk/math/Vector2D.h>
#include <ewol/debug.h>
#include <ewol/clipBoard.h>
#include <ewol/key.h>
#include <ewol/cursor.h>
#include <ewol/renderer/EventInput.h>
#include <ewol/renderer/EventEntry.h>
#include <ewol/renderer/EventTime.h>
#define ULTIMATE_MAX_SIZE (99999999)
namespace ewol {
//namespace widget {
class DrawProperty{
/*
/--> m_windowsSize
*--------------------------------------------------*
| g |
| |
| m_size |
| / |
| o-------------------o |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| o-------------------o |
| / |
| m_origin |
| |
*--------------------------------------------------*
/
(0,0)
*/
public :
ivec2 m_windowsSize; //!< Windows compleate size
ivec2 m_origin; //!< Windows clipping upper widget (can not be <0)
ivec2 m_size; //!< Windows clipping upper widget (can not be <0 and >m_windowsSize)
void limit(const vec2& _origin, const vec2& _size);
};
etk::CCout& operator <<(etk::CCout& _os, const ewol::DrawProperty& _obj);
/**
* @brief Gravity of the widget property
*/
enum gravity {
gravityCenter=0x00, //!< gravity is in certer
gravityTopLeft=0x05,
gravityTop=0x01,
gravityTopRight=0x03,
gravityRight=0x02,
gravityButtomRight=0x06,
gravityButtom=0x04,
gravityButtomLeft=0x0C,
gravityLeft=0x08,
};
etk::CCout& operator <<(etk::CCout& _os, const enum ewol::gravity _obj);
std::string gravityToString(const enum ewol::gravity _obj);
enum ewol::gravity stringToGravity(const std::string& _obj);
class EventShortCut {
public:
bool broadcastEvent; //!< if it is true, then the message is sent to all the system
const char* generateEventId; //!< Local generated event
std::string eventData; //!< data link with the event
ewol::SpecialKey specialKey; //!< special board key
char32_t unicodeValue; //!< 0 if not used
enum ewol::keyEvent::keyboard keyboardMoveValue; //!< ewol::EVENT_KB_MOVE_TYPE_NONE if not used
EventShortCut(void) {
broadcastEvent = false;
generateEventId = NULL;
eventData = "";
unicodeValue = 0;
keyboardMoveValue = ewol::keyEvent::keyboardUnknow;
};
~EventShortCut(void) { };
};
/**
* @ingroup ewolWidgetGroup
*/
class Widget : public ewol::EObject {
public:
// Config list of properties
static const char* const configFill;
static const char* const configExpand;
static const char* const configHide;
static const char* const configFocus;
static const char* const configMinSize;
static const char* const configMaxSize;
static const char* const configGravity;
public:
/**
* @brief Constructor of the widget classes
* @return (no execption generated (not managed in embended platform))
*/
Widget(void);
/**
* @brief Destructor of the widget classes
*/
virtual ~Widget(void);
// ----------------------------------------------------------------------------------------------------------------
// -- Hierarchy management:
// ----------------------------------------------------------------------------------------------------------------
protected:
ewol::Widget* m_up; //!< uppper widget in the tree of widget
public:
/**
* @brief set the upper widget of this widget.
* @param[in] _upper Father widget (only keep the last and write error if a previous was set) == > disable with NULL.
*/
void setUpperWidget(ewol::Widget* _upper);
/**
* @brief remove the upper widget of this widget.
*/
void removeUpperWidget(void) {
setUpperWidget(NULL);
};
/**
* @brief get the upper widget (father).
* @ return the requested widget (if NULL , 2 case : root widget or error implementation).
*/
ewol::Widget* getUpperWidget(void) {
return m_up;
};
// ----------------------------------------------------------------------------------------------------------------
// -- Widget size:
// ----------------------------------------------------------------------------------------------------------------
protected:
vec2 m_size; //!< internal : current size of the widget
vec2 m_minSize; //!< internal : minimum size of the widget
vec2 m_maxSize; //!< internal : maximum size of the widget
public:
/**
* @brief convert the absolute position in the local Position (Relative)
* @param[in] _pos Absolute position that you request convertion
* @return the relative position
*/
virtual vec2 relativePosition(const vec2& _pos);
/**
* @brief Parent set the possible diplay size of the current widget whith his own possibilities
* By default this save the widget available size in the widget size
* @param[in] _available Available x&y pixel size
* @note : INTERNAL EWOL SYSTEM
*/
virtual void calculateSize(const vec2& _available);
/**
* @brief get the widget size
* @return Requested size
* @note : INTERNAL EWOL SYSTEM
*/
virtual vec2 getSize(void);
/**
* @brief calculate the minimum and maximum size (need to estimate expend properties of the widget)
* @note : INTERNAL EWOL SYSTEM
*/
virtual void calculateMinMaxSize(void);
/**
* @brief get the widget minimum size calculated
* @return Requested size
* @note : INTERNAL EWOL SYSTEM
*/
virtual vec2 getCalculateMinSize(void);
/**
* @brief get the widget maximum size calculated
* @return Requested size
* @note : INTERNAL EWOL SYSTEM
*/
virtual vec2 getCalculateMaxSize(void);
protected:
vec2 m_offset; //!< Offset of the display in the viewport
public:
/**
* @brief set the zoom property of the widget.
* @param[in] _newVal offset value.
*/
virtual void setOffset(const vec2& _newVal);
/**
* @brief get the offset property of the widget.
* @return The current offset value.
*/
virtual const vec2& getOffset(void) {
return m_offset;
};
protected:
// internal element calculated by the system
float m_zoom; //!< generic widget zoom
public:
/**
* @brief set the zoom property of the widget
* @param[in] _newVal newZoom value
*/
virtual void setZoom(float _newVal);
/**
* @brief get the zoom property of the widget
* @return the current zoom value
*/
virtual float getZoom(void);
protected:
vec2 m_origin; //!< internal ... I do not really known how i can use it ...
public:
/**
* @brief set origin at the widget (must be an parrent widget that set this parameter).
* This represent the absolute origin in the program windows
* @param[in] _pos Position of the origin
* @note : INTERNAL EWOL SYSTEM
*/
virtual void setOrigin(const vec2& _pos);
/**
* @brief get the origin (obsolute position in the windows)
* @return coordonate of the origin requested
*/
virtual vec2 getOrigin(void);
protected:
ewol::Dimension m_userMinSize; //!< user define the minimum size of the widget
public:
/**
* @brief User set the minimum size he want to set the display
* @param[in] _size set minimum size (none : 0)
*/
void setMinSize(const ewol::Dimension& _size);
/**
* @brief User set No minimum size.
*/
void setNoMinSize(void);
/**
* @brief get the current calculated min size
* @return the size requested
*/
const ewol::Dimension& getMinSize(void) {
return m_userMinSize;
};
/**
* @brief Check if the current min size is compatible with the user minimum size
* If it is not the user minimum size will overWrite the minimum size set.
* @note : INTERNAL EWOL SYSTEM
*/
virtual void checkMinSize(void);
protected:
ewol::Dimension m_userMaxSize; //!< user define the maximum size of the widget
public:
/**
* @brief User set the maximum size he want to set the display
* @param[in] _size The new maximum size requested (vec2(0,0) to unset)
*/
void setMaxSize(const ewol::Dimension& _size);
/**
* @brief User set No maximum size.
*/
void setNoMaxSize(void);
/**
* @brief get the current maximum size
* @return the size requested
*/
const ewol::Dimension& getMaxSize(void) {
return m_userMaxSize;
};
/**
* @brief Check if the current max size is compatible with the user maximum size
* If it is not the user maximum size will overWrite the maximum size set.
* @note : INTERNAL EWOL SYSTEM
*/
virtual void checkMaxSize(void);
protected:
bvec2 m_userExpand;
public:
/**
* @brief set the expend capabilities (x&y)
* @param[in] _newExpend 2D boolean repensent the capacity to expend
*/
virtual void setExpand(const bvec2& _newExpand);
/**
* @brief get the expend capabilities (x&y) (set by the user)
* @return 2D boolean repensent the capacity to expend
*/
virtual bvec2 getExpand(void) {
return m_userExpand;
};
/**
* @brief get the expend capabilities (x&y)
* @return 2D boolean repensent the capacity to expend
* @note : INTERNAL EWOL SYSTEM
*/
virtual bvec2 canExpand(void);
protected:
bvec2 m_userFill;
public:
/**
* @brief set the x&y filling capacity
* @param[in] _newFill new x&y fill state
*/
virtual void setFill(const bvec2& _newFill);
/**
* @brief set the x&y filling capacity set by the user
* @return bvec2 repensent the capacity to x&y filling (set by the user)
*/
virtual const bvec2& getFill(void) {
return m_userFill;
};
/**
* @brief get the filling capabilities x&y
* @return bvec2 repensent the capacity to x&y filling
* @note : INTERNAL EWOL SYSTEM
*/
const bvec2& canFill(void);
protected:
bool m_hide; //!< hide a widget on the display
public:
/**
* @brief set the widget hidden
*/
virtual void hide(void);
/**
* @brief set the widget visible
*/
virtual void show(void);
/**
* @brief get the visibility of the widget
* @return true: if the widget is hiden, false: it is visible
*/
virtual bool isHide(void) {
return m_hide;
};
protected:
enum ewol::gravity m_gravity; //!< Gravity of the widget
public:
/**
* @brief set the widget gravity
* @param[in] _gravity New gravity of the widget
*/
virtual void setGravity(enum ewol::gravity _gravity);
/**
* @brief get the widget gravity
* @return the gravity type
*/
virtual enum ewol::gravity getGravity(void) {
return m_gravity;
};
// ----------------------------------------------------------------------------------------------------------------
// -- focus Area
// ----------------------------------------------------------------------------------------------------------------
private:
bool m_hasFocus; //!< set the focus on this widget
bool m_canFocus; //!< the focus can be done on this widget
public:
/**
* @brief get the focus state of the widget
* @return focus state
*/
virtual bool getFocus(void) {
return m_hasFocus;
};
/**
* @brief get the capability to have focus
* @return State capability to have focus
*/
virtual bool canHaveFocus(void) {
return m_canFocus;
};
/**
* @brief set focus on this widget
* @return return true if the widget keep the focus
*/
virtual bool setFocus(void);
/**
* @brief remove the focus on this widget
* @return return true if the widget have release his focus (if he has it)
*/
virtual bool rmFocus(void);
/**
* @brief set the capability to have the focus
* @param[in] _canFocusState new focus capability
*/
virtual void setCanHaveFocus(bool _canFocusState);
/**
* @brief keep the focus on this widget == > this remove the previous focus on all other widget
*/
virtual void keepFocus(void);
protected:
/**
* @brief Event of the focus has been grep by the current widget
*/
virtual void onGetFocus(void) {};
/**
* @brief Event of the focus has been lost by the current widget
*/
virtual void onLostFocus(void) {};
// ----------------------------------------------------------------------------------------------------------------
// -- Mouse event properties Area
// ----------------------------------------------------------------------------------------------------------------
private:
int32_t m_limitMouseEvent; //!< this is to limit the number of mouse event that the widget can supported
public:
/**
* @brief get the number of mouse event supported
* @return return the number of event that the mouse supported [0..3]
*/
virtual int32_t getMouseLimit(void) {
return m_limitMouseEvent;
};
/**
* @brief get the number of mouse event supported
* @param[in] _numberState The number of event that the mouse supported [0..3]
*/
virtual void setMouseLimit(int32_t _numberState) {
m_limitMouseEvent = _numberState;
};
// ----------------------------------------------------------------------------------------------------------------
// -- keyboard event properties Area
// ----------------------------------------------------------------------------------------------------------------
private:
bool m_allowRepeateKeyboardEvent; //!< This remove the repeating keybord event due to the constant pressing key.
public:
/**
* @brief get the keyboard repeating event supporting.
* @return true : the event can be repeated.
* @return false : the event must not be repeated.
*/
virtual bool getKeyboardRepeate(void) {
return m_allowRepeateKeyboardEvent;
};
protected:
/**
* @brief set the keyboard repeating event supporting.
* @param[in] _state The repeating status (true: enable, false disable).
*/
virtual void setKeyboardRepeate(bool _state) {
m_allowRepeateKeyboardEvent = _state;
};
/**
* @brief display the virtual keyboard (if needed)
*/
virtual void showKeyboard(void);
/**
* @brief Hide the virtual keyboard (if needed)
*/
virtual void hideKeyboard(void);
// ----------------------------------------------------------------------------------------------------------------
// -- periodic call Area
// ----------------------------------------------------------------------------------------------------------------
private:
int64_t m_periodicCallDeltaTime; //!< -1 : disable / 0 : every time / else in US
int64_t m_periodicCallTime; //!< Last call time
protected:
/**
* @brief disable the periodic call.
*/
void periodicCallDisable(void);
/**
* @brief disable the periodic call.
* @param[in] _callInSecond periodic call in second (float)
*/
void periodicCallEnable(float _callInSecond=0);
public:
/**
* @brief {SYSTEM} get a reference of the periodic call delta time
* @return the perodic time delta call -1 : disable / 0 : every time / else in US
*/
int64_t systemGetCallDeltaTime(void) const {
return m_periodicCallDeltaTime;
};
/**
* @brief {SYSTEM} get a reference of the periodic call time
* @return Last call from the periodic call
*/
int64_t systemGetLastCallTime(void) const {
return m_periodicCallTime;
};
/**
* @brief {SYSTEM} get a reference of the periodic call time
* @return Last call from the periodic call
*/
void systemSetLastCallTime(int64_t _time) {
m_periodicCallTime=_time;
};
/**
* @brief periodic call of this widget
* @param _event Current time property
*/
virtual void periodicCall(const ewol::EventTime& _event) {
};
public:
/**
* @brief get the widget at the specific windows absolute position
* @param[in] _pos gAbsolute position of the requested widget knowledge
* @return NULL No widget found
* @return pointer on the widget found
* @note : INTERNAL EWOL SYSTEM
*/
virtual ewol::Widget* getWidgetAtPos(const vec2& _pos) {
if (false == isHide()) {
return this;
}
return NULL;
};
/**
* @brief get the widget if it have this name or one of the subwidget with the same name
* @param[in] _widgetName name of the widget
* @return the requested pointer on the node (or NULL pointer)
*/
virtual ewol::Widget* getWidgetNamed(const std::string& _widgetName);
// event section:
public:
/**
* @brief {SYSTEM} system event input (only meta widget might overwrite this function).
* @param[in] _event Event properties
* @return true the event is used
* @return false the event is not used
*/
virtual bool systemEventInput(ewol::EventInputSystem& _event);
protected:
/**
* @brief Event on an input of this Widget (finger, mouse, stilet)
* @param[in] _event Event properties
* @return true the event is used
* @return false the event is not used
*/
virtual bool onEventInput(const ewol::EventInput& _event) {
return false;
};
public:
/**
* @brief {SYSTEM} Entry event (only meta widget might overwrite this function).
* @param[in] _event Event properties
* @return true if the event has been used
* @return false if the event has not been used
*/
virtual bool systemEventEntry(ewol::EventEntrySystem& _event);
protected:
/**
* @brief Entry event.
* represent the physical event :
* - Keyboard (key event and move event)
* - Accelerometer
* - Joystick
* @param[in] _event Event properties
* @return true if the event has been used
* @return false if the event has not been used
*/
virtual bool onEventEntry(const ewol::EventEntry& _event) {
return false;
};
public:
/**
* @brief Event on a past event == > this event is asynchronous due to all system does not support direct getting datas
* @note : need to have focus ...
* @param[in] mode Mode of data requested
*/
virtual void onEventClipboard(enum ewol::clipBoard::clipboardListe _clipboardID) { };
// ----------------------------------------------------------------------------------------------------------------
// -- Shortcut : management of the shortcut
// ----------------------------------------------------------------------------------------------------------------
private:
std::vector<EventShortCut*> m_localShortcut; //!< list of all shortcut in the widget
protected:
/**
* @brief add a specific shortcut with his description
* @param[in] _descriptiveString Description string of the shortcut
* @param[in] _generateEventId Event generic of the element
* @param[in] _data Associate data wit the event
*/
virtual void shortCutAdd(const char * _descriptiveString,
const char * _generateEventId,
std::string _data="",
bool _broadcast=false);
/**
* @brief remove all curent shortCut
*/
virtual void shortCutClean(void);
public:
/**
* @brief Event on a short-cut of this Widget (in case of return false, the event on the keyevent will arrive in the function @ref onEventKb).
* @param[in] _special All the special kay pressed at this time.
* @param[in] _unicodeValue Key pressed by the user not used if the kbMove!=ewol::EVENT_KB_MOVE_TYPE_NONE.
* @param[in] _kbMove Special key of the keyboard.
* @return true if the event has been used.
* @return false if the event has not been used.
* @note To prevent some error when you get an event get it if it is down and Up ... == > like this it could not generate some ununderstanding error.
*/
virtual bool onEventShortCut(ewol::SpecialKey& _special,
char32_t _unicodeValue,
enum ewol::keyEvent::keyboard _kbMove,
bool _isDown);
// ----------------------------------------------------------------------------------------------------------------
// -- drawing : All drawing must be done in 2 separate buffer 1 for the current display and 1 for the working...
// ----------------------------------------------------------------------------------------------------------------
protected:
bool m_needRegenerateDisplay; //!< the display might be done the next regeneration
/**
* @brief The widget mark itself that it need to regenerate the nest time.
*/
virtual void markToRedraw(void);
/**
* @brief get the need of the redrawing of the widget and reset it to false
* @return true if we need to redraw
* @return false if we have no need to redraw
*/
virtual bool needRedraw(void) {
bool tmpData=m_needRegenerateDisplay;
m_needRegenerateDisplay=false;
return tmpData;
};
public:
/**
* @brief {SYSTEM} 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[in] _displayProp properties of the current display
* @note : INTERNAL EWOL SYSTEM
*/
virtual void systemDraw(const DrawProperty& _displayProp);
protected:
/**
* @brief Common widget drawing function (called by the drawing thread [Android, X11, ...])
*/
virtual void onDraw(void) { };
public:
/**
* @brief Event generated when a redraw is needed
*/
virtual void onRegenerateDisplay(void) { };
// grab cursor mode
private:
bool m_grabCursor;
public:
/**
* @brief Grab the cursor : This get all the mouvement of the mouse in PC mode, and generate an ofset instead of a position.
* @note : the generation of the offset is due to the fact the cursor position is forced at the center of the widget.
* @note This done nothing in "Finger" or "Stylet" mode.
*/
virtual void grabCursor(void);
/**
* @brief Un-Grab the cursor (default mode cursor offset)
*/
virtual void unGrabCursor(void);
/**
* @brief get the grabbing status of the cursor.
* @return true if the cursor is curently grabbed
*/
virtual bool getGrabStatus(void);
private:
enum ewol::cursorDisplay m_cursorDisplay;
public:
/**
* @brief set the cursor display type.
* @param[in] _newCursor selected new cursor.
*/
virtual void setCursor(enum ewol::cursorDisplay _newCursor);
/**
* @brief get the currrent cursor.
* @return the type of the cursor.
*/
virtual enum ewol::cursorDisplay getCursor(void);
public: // Derived function
virtual void onObjectRemove(ewol::EObject* _removeObject);
virtual bool loadXML(exml::Element* _node);
protected: // Derived function
virtual bool onSetConfig(const ewol::EConfig& _conf);
virtual bool onGetConfig(const char* _config, std::string& _result) const;
public:
/**
* @brief need to be call When the size of the current widget have change == > this force the system to recalculate all the widget positions
*/
void requestUpdateSize(void);
/**
* @brief get the current Widget Manager
*/
ewol::WidgetManager& getWidgetManager(void);
/**
* @brief get the curent Windows
*/
ewol::Windows* getWindows(void);
/*
* Annimation section :
*/
public:
// configuration :
static const char* const configAnnimationAddType;
static const char* const configAnnimationAddTime;
static const char* const configAnnimationRemoveType;
static const char* const configAnnimationRemoveTime;
// event generated :
static const char* const eventAnnimationStart; //!< event when start annimation
static const char* const eventAnnimationRatio; //!< event when % of annimation change (integer)
static const char* const eventAnnimationStop; //!< event when stop annimation
protected:
enum annimationMode {
annimationModeEnableAdd,
annimationModeEnableRemove,
annimationModeDisable
};
enum annimationMode m_annimationMode; //!< true when the annimation is started
float m_annimationratio; //!< Ratio of the annimation [0..1]
private:
std::vector<const char*> m_annimationList[2]; //!< List of all annimation type ADD
protected:
const char* m_annimationType[2]; //!< type of start annimation (default NULL ==> no annimation)
float m_annimationTime[2]; //!< time to produce start annimation
protected:
/**
* @brief Add a annimation type capabilities of this widget.
* @param[in] _mode Configuring mode.
* @param[in] _type Type of the annimation.
*/
void addAnnimationType(enum annimationMode _mode, const char* _type);
public:
/**
* @brief set a annimation type.
* @param[in] _mode Configuring mode.
* @param[in] _type type of the annimation
*/
void setAnnimationType(enum annimationMode _mode, const std::string& _type);
/**
* @brief set a annimation time to produce.
* @param[in] _mode Configuring mode.
* @param[in] _time Time in second of the annimation display
*/
void setAnnimationTime(enum annimationMode _mode, float _time);
/**
* @brief Start the annimation.
* @param[in] _mode Configuring mode.
* @return true if an annimation will be started, false ==> no annimation and no event
*/
bool startAnnimation(enum annimationMode _mode);
/**
* @brief Stop/Break the annimation.
* @return true if an annimation will be stoped, false ==> no curent annimation and no event wil be generated
*/
bool stopAnnimation(void);
protected:
/**
* @brief Event when start the annimation.
* @param[in] _mode Configuring mode.
* @return true need to add periodic call.
*/
virtual bool onStartAnnimation(enum annimationMode _mode) { return false; };
/**
* @brief Event when Stop the annimation.
*/
virtual void onStopAnnimation(void) { };
};
//};
};
#endif