diff --git a/.checkstyle b/.checkstyle
new file mode 100644
index 0000000..34ed486
--- /dev/null
+++ b/.checkstyle
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..d43dd0c
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d075be7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,17 @@
+/bin/
+/Operator/
+/DrawerProperties/
+*.pdfd
+*.dbc
+SchedulerConfig.txt
+scenicView.properties
+ScenariumConfig.txt
+*.class
+*~
+*.bck
+build.number
+/extern/
+/out/
+/.settings/
+/junit/
+/target/
diff --git a/.project b/.project
new file mode 100644
index 0000000..00ecbe4
--- /dev/null
+++ b/.project
@@ -0,0 +1,24 @@
+
+
+ atriasoft-ewol
+
+
+ atriasoft-ewol
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ net.sf.eclipsecs.core.CheckstyleBuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ net.sf.eclipsecs.core.CheckstyleNature
+
+
diff --git a/CheckStyle.xml b/CheckStyle.xml
new file mode 100755
index 0000000..d68aedd
--- /dev/null
+++ b/CheckStyle.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CleanUp.xml b/CleanUp.xml
new file mode 100644
index 0000000..6cf4cba
--- /dev/null
+++ b/CleanUp.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Formatter.xml b/Formatter.xml
new file mode 100644
index 0000000..14a5d6c
--- /dev/null
+++ b/Formatter.xml
@@ -0,0 +1,390 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..a612ad9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,373 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+ means each individual or legal entity that creates, contributes to
+ the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+ means the combination of the Contributions of others (if any) used
+ by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+ means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+ means Source Code Form to which the initial Contributor has attached
+ the notice in Exhibit A, the Executable Form of such Source Code
+ Form, and Modifications of such Source Code Form, in each case
+ including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+ means
+
+ (a) that the initial Contributor has attached the notice described
+ in Exhibit B to the Covered Software; or
+
+ (b) that the Covered Software was made available under the terms of
+ version 1.1 or earlier of the License, but not also under the
+ terms of a Secondary License.
+
+1.6. "Executable Form"
+ means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+ means a work that combines Covered Software with other material, in
+ a separate file or files, that is not Covered Software.
+
+1.8. "License"
+ means this document.
+
+1.9. "Licensable"
+ means having the right to grant, to the maximum extent possible,
+ whether at the time of the initial grant or subsequently, any and
+ all of the rights conveyed by this License.
+
+1.10. "Modifications"
+ means any of the following:
+
+ (a) any file in Source Code Form that results from an addition to,
+ deletion from, or modification of the contents of Covered
+ Software; or
+
+ (b) any new file in Source Code Form that contains any Covered
+ Software.
+
+1.11. "Patent Claims" of a Contributor
+ means any patent claim(s), including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by such
+ Contributor that would be infringed, but for the grant of the
+ License, by the making, using, selling, offering for sale, having
+ made, import, or transfer of either its Contributions or its
+ Contributor Version.
+
+1.12. "Secondary License"
+ means either the GNU General Public License, Version 2.0, the GNU
+ Lesser General Public License, Version 2.1, the GNU Affero General
+ Public License, Version 3.0, or any later versions of those
+ licenses.
+
+1.13. "Source Code Form"
+ means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, "You" includes any entity that
+ controls, is controlled by, or is under common control with You. For
+ purposes of this definition, "control" means (a) the power, direct
+ or indirect, to cause the direction or management of such entity,
+ whether by contract or otherwise, or (b) ownership of more than
+ fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or
+ as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+ for sale, have made, import, and otherwise transfer either its
+ Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+ or
+
+(b) for infringements caused by: (i) Your and any other third party's
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+ its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+ Form, as described in Section 3.1, and You must inform recipients of
+ the Executable Form how they can obtain a copy of such Source Code
+ Form by reasonable means in a timely manner, at a charge no more
+ than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+ License, or sublicense it under different terms, provided that the
+ license for the Executable Form does not attempt to limit or alter
+ the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+* *
+* 6. Disclaimer of Warranty *
+* ------------------------- *
+* *
+* Covered Software is provided under this License on an "as is" *
+* basis, without warranty of any kind, either expressed, implied, or *
+* statutory, including, without limitation, warranties that the *
+* Covered Software is free of defects, merchantable, fit for a *
+* particular purpose or non-infringing. The entire risk as to the *
+* quality and performance of the Covered Software is with You. *
+* Should any Covered Software prove defective in any respect, You *
+* (not any Contributor) assume the cost of any necessary servicing, *
+* repair, or correction. This disclaimer of warranty constitutes an *
+* essential part of this License. No use of any Covered Software is *
+* authorized under this License except under this disclaimer. *
+* *
+************************************************************************
+
+************************************************************************
+* *
+* 7. Limitation of Liability *
+* -------------------------- *
+* *
+* Under no circumstances and under no legal theory, whether tort *
+* (including negligence), contract, or otherwise, shall any *
+* Contributor, or anyone who distributes Covered Software as *
+* permitted above, be liable to You for any direct, indirect, *
+* special, incidental, or consequential damages of any character *
+* including, without limitation, damages for lost profits, loss of *
+* goodwill, work stoppage, computer failure or malfunction, or any *
+* and all other commercial damages or losses, even if such party *
+* shall have been informed of the possibility of such damages. This *
+* limitation of liability shall not apply to liability for death or *
+* personal injury resulting from such party's negligence to the *
+* extent applicable law prohibits such limitation. Some *
+* jurisdictions do not allow the exclusion or limitation of *
+* incidental or consequential damages, so this exclusion and *
+* limitation may not apply to You. *
+* *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+ This Source Code Form is "Incompatible With Secondary Licenses", as
+ defined by the Mozilla Public License, v. 2.0.
diff --git a/src/module-info.java b/src/module-info.java
new file mode 100644
index 0000000..fd1ce90
--- /dev/null
+++ b/src/module-info.java
@@ -0,0 +1,9 @@
+/** Basic module interface.
+ *
+ * @author Edouard DUPIN */
+
+open module org.atriasoft.etk {
+ exports org.atriasoft.etk;
+ exports org.atriasoft.etk.math;
+ requires transitive io.scenarium.logger;
+}
diff --git a/src/org/atriasoft/ewol/DrawProperty.cpp b/src/org/atriasoft/ewol/DrawProperty.cpp
new file mode 100644
index 0000000..4d04f8e
--- /dev/null
+++ b/src/org/atriasoft/ewol/DrawProperty.cpp
@@ -0,0 +1,24 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+#include
+
+#include
+ETK_DECLARE_TYPE(ewol::DrawProperty);
+
+etk::Stream& ewol::operator <<(etk::Stream& _os, const ewol::DrawProperty& _obj) {
+ _os << "{ windowsSize=" << _obj.m_windowsSize << " start=" << _obj.m_origin << " stop=" << (_obj.m_origin+_obj.m_size) << "}";
+ return _os;
+}
+
+void ewol::DrawProperty::limit(const vec2& _origin, const vec2& _size) {
+ m_size += m_origin;
+ m_origin.setMax(_origin);
+ m_size.setMin(_origin+_size);
+ m_size -= m_origin;
+}
+
diff --git a/src/org/atriasoft/ewol/DrawProperty.java b/src/org/atriasoft/ewol/DrawProperty.java
new file mode 100644
index 0000000..659bad6
--- /dev/null
+++ b/src/org/atriasoft/ewol/DrawProperty.java
@@ -0,0 +1,48 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+
+#include
+#include
+
+namespace ewol {
+ /**
+ * @not_in_doc
+ */
+ 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::Stream& operator <<(etk::Stream& _os, const ewol::DrawProperty& _obj);
+
+}
diff --git a/src/org/atriasoft/ewol/Padding.cpp b/src/org/atriasoft/ewol/Padding.cpp
new file mode 100644
index 0000000..36a5a92
--- /dev/null
+++ b/src/org/atriasoft/ewol/Padding.cpp
@@ -0,0 +1,93 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+#include
+ETK_DECLARE_TYPE(ewol::Padding);
+
+ewol::Padding::Padding() {
+ // nothing to do...
+}
+
+ewol::Padding::Padding(float _xl, float _yt, float _xr, float _yb) {
+ setValue(_xl, _yt, _xr, _yb);
+}
+
+void ewol::Padding::setValue(float _xl, float _yt, float _xr, float _yb) {
+ m_value[0] = _xl;
+ m_value[1] = _yt;
+ m_value[2] = _xr;
+ m_value[3] = _yb;
+}
+
+float ewol::Padding::x() const {
+ return m_value[0] + m_value[2];
+}
+
+float ewol::Padding::y() const {
+ return m_value[1] + m_value[3];
+}
+
+float ewol::Padding::xLeft() const {
+ return m_value[0];
+}
+
+void ewol::Padding::setXLeft(float _val) {
+ m_value[0] = _val;
+}
+
+float ewol::Padding::xRight() const {
+ return m_value[2];
+}
+
+void ewol::Padding::setXRight(float _val) {
+ m_value[2] = _val;
+}
+
+float ewol::Padding::yTop() const {
+ return m_value[1];
+}
+
+void ewol::Padding::setYTop(float _val) {
+ m_value[1] = _val;
+}
+
+float ewol::Padding::yButtom() const {
+ return m_value[3];
+}
+
+void ewol::Padding::setYButtom(float _val) {
+ m_value[3] = _val;
+}
+
+ewol::Padding& ewol::Padding::operator+=(const Padding& _v) {
+ m_value[0] += _v.m_value[0];
+ m_value[1] += _v.m_value[1];
+ m_value[2] += _v.m_value[2];
+ m_value[3] += _v.m_value[3];
+ return *this;
+}
+
+ewol::Padding ewol::Padding::operator+(const Padding& _v) {
+ return Padding(m_value[0] + _v.m_value[0],
+ m_value[1] + _v.m_value[1],
+ m_value[2] + _v.m_value[2],
+ m_value[3] + _v.m_value[3]);
+}
+
+etk::Stream& ewol::operator <<(etk::Stream& _os, const ewol::Padding& _obj) {
+ _os << "{";
+ _os << _obj.xLeft();
+ _os << ",";
+ _os << _obj.yTop();
+ _os << ",";
+ _os << _obj.xRight();
+ _os << ",";
+ _os << _obj.yButtom();
+ _os << "}";
+ return _os;
+}
+
diff --git a/src/org/atriasoft/ewol/Padding.java b/src/org/atriasoft/ewol/Padding.java
new file mode 100644
index 0000000..b03d61c
--- /dev/null
+++ b/src/org/atriasoft/ewol/Padding.java
@@ -0,0 +1,43 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+
+#include
+#include
+
+namespace ewol {
+ /**
+ * @breif Simple class to abstarct the padding porperty.
+ */
+ class Padding {
+ private:
+ float m_value[4]; //!< this represent the 4 padding value Left top right buttom (like css)
+ public:
+ Padding();
+ Padding(float _xl, float _yt=0.0f, float _xr=0.0f, float _yb=0.0f);
+ void setValue(float _xl, float _yt=0.0f, float _xr=0.0f, float _yb=0.0f);
+ float x() const;
+ float y() const;
+ float xLeft() const;
+ void setXLeft(float _val);
+ float xRight() const;
+ void setXRight(float _val);
+ float yTop() const;
+ void setYTop(float _val);
+ float yButtom() const;
+ void setYButtom(float _val);
+ /**
+ * @brief Add a vector to this one
+ * @param _v The vector to add to this one
+ */
+ Padding& operator+=(const Padding& _v);
+ //! @previous
+ Padding operator+(const Padding& _v);
+
+ };
+ etk::Stream& operator <<(etk::Stream& _os, const ewol::Padding& _obj);
+};
+
diff --git a/src/org/atriasoft/ewol/compositing/Area.cpp b/src/org/atriasoft/ewol/compositing/Area.cpp
new file mode 100644
index 0000000..70bab49
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/Area.cpp
@@ -0,0 +1,142 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+#include
+#include
+ETK_DECLARE_TYPE(ewol::compositing::Area);
+
+// VBO table property:
+const int32_t ewol::compositing::Area::m_vboIdCoord(0);
+const int32_t ewol::compositing::Area::m_vboIdCoordText(1);
+const int32_t ewol::compositing::Area::m_vboIdColor(2);
+#define NB_VBO (3)
+
+ewol::compositing::Area::Area(const ivec2& _size) :
+ m_position(0.0, 0.0, 0.0),
+ m_color(etk::color::white),
+ m_GLprogram(null),
+ m_GLPosition(-1),
+ m_GLMatrix(-1),
+ m_GLColor(-1),
+ m_GLtexture(-1),
+ m_GLtexID(-1),
+ m_resource(null) {
+ m_resource = ewol::resource::Texture::create();
+ m_resource->setImageSize(_size);
+ m_resource->flush();
+ // Create the VBO:
+ m_VBO = gale::resource::VirtualBufferObject::create(NB_VBO);
+ if (m_VBO == null) {
+ EWOL_ERROR("can not instanciate VBO ...");
+ return;
+ }
+ // TO facilitate some debugs we add a name of the VBO:
+ m_VBO->setName("[VBO] of ewol::compositing::Area");
+ loadProgram();
+}
+
+ewol::compositing::Area::~Area() {
+
+}
+
+void ewol::compositing::Area::loadProgram() {
+ // get the shader resource :
+ m_GLPosition = 0;
+ m_GLprogram = gale::resource::Program::create(etk::String("DATA:///textured3D.prog?lib=ewol"));
+ if (m_GLprogram != null) {
+ m_GLPosition = m_GLprogram->getAttribute("EW_coord3d");
+ m_GLColor = m_GLprogram->getAttribute("EW_color");
+ m_GLtexture = m_GLprogram->getAttribute("EW_texture2d");
+ m_GLMatrix = m_GLprogram->getUniform("EW_MatrixTransformation");
+ m_GLtexID = m_GLprogram->getUniform("EW_texID");
+ }
+}
+
+void ewol::compositing::Area::draw(bool _disableDepthTest) {
+ if (m_VBO->bufferSize(m_vboIdCoord) <= 0) {
+ //EWOL_WARNING("Nothink to draw...");
+ return;
+ }
+ if (m_resource == null) {
+ // this is a normale case ... the user can choice to have no image ...
+ return;
+ }
+ if (m_GLprogram == null) {
+ EWOL_ERROR("No shader ...");
+ return;
+ }
+ // set Matrix : translation/positionMatrix
+ mat4 tmpMatrix = gale::openGL::getMatrix()*m_matrixApply;
+ m_GLprogram->use();
+ m_GLprogram->uniformMatrix(m_GLMatrix, tmpMatrix);
+ // TextureID
+ m_GLprogram->setTexture0(m_GLtexID, m_resource->getRendererId());
+ // position:
+ m_GLprogram->sendAttributePointer(m_GLPosition, m_VBO, m_vboIdCoord);
+ // Texture:
+ m_GLprogram->sendAttributePointer(m_GLtexture, m_VBO, m_vboIdColor);
+ // color:
+ m_GLprogram->sendAttributePointer(m_GLColor, m_VBO, m_vboIdCoordText);
+ // Request the draw od the elements :
+ gale::openGL::drawArrays(gale::openGL::renderMode::triangle, 0, m_VBO->bufferSize(m_vboIdCoord));
+ m_GLprogram->unUse();
+}
+
+void ewol::compositing::Area::clear() {
+ // call upper class
+ ewol::Compositing::clear();
+ // reset all VBOs:
+ m_VBO->clear();
+ // reset temporal variables :
+ m_position = vec3(0.0, 0.0, 0.0);
+}
+
+void ewol::compositing::Area::print(const ivec2& _size) {
+ vec3 point(0,0,0);
+ vec2 tex(0,1);
+ point.setX(m_position.x());
+ point.setY(m_position.y());
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ m_VBO->pushOnBuffer(m_vboIdCoordText, tex);
+
+ tex.setValue(1,1);
+ point.setX(m_position.x() + _size.x());
+ point.setY(m_position.y());
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ m_VBO->pushOnBuffer(m_vboIdCoordText, tex);
+
+ tex.setValue(1,0);
+ point.setX(m_position.x() + _size.x());
+ point.setY(m_position.y() + _size.y());
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ m_VBO->pushOnBuffer(m_vboIdCoordText, tex);
+
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ m_VBO->pushOnBuffer(m_vboIdCoordText, tex);
+
+ tex.setValue(0,0);
+ point.setX(m_position.x());
+ point.setY(m_position.y() + _size.y());
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ m_VBO->pushOnBuffer(m_vboIdCoordText, tex);
+
+ tex.setValue(0,1);
+ point.setX(m_position.x());
+ point.setY(m_position.y());
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ m_VBO->pushOnBuffer(m_vboIdCoordText, tex);
+
+ m_VBO->flush();
+}
+
+
diff --git a/src/org/atriasoft/ewol/compositing/Area.java b/src/org/atriasoft/ewol/compositing/Area.java
new file mode 100644
index 0000000..d953b32
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/Area.java
@@ -0,0 +1,101 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace ewol {
+ namespace compositing {
+ class Area : public ewol::Compositing {
+ private:
+ vec3 m_position; //!< The current position to draw
+ etk::Color m_color; //!< The text foreground color
+ private:
+ ememory::SharedPtr m_GLprogram; //!< pointer on the opengl display program
+ 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_GLColor; //!< openGL id on the element (color buffer)
+ int32_t m_GLtexture; //!< openGL id on the element (Texture position)
+ int32_t m_GLtexID; //!< openGL id on the element (texture ID)
+ private:
+ ememory::SharedPtr m_resource; //!< texture resources
+ protected:
+ static const int32_t m_vboIdCoord;
+ static const int32_t m_vboIdCoordText;
+ static const int32_t m_vboIdColor;
+ ememory::SharedPtr m_VBO;
+ private:
+ /**
+ * @brief load the openGL program and get all the ID needed
+ */
+ void loadProgram();
+ public:
+ /**
+ * @brief generic constructor
+ * @param[in] _size Basic size of the area.
+ */
+ Area(const ivec2& _size);
+ /**
+ * @brief generic destructor
+ */
+ virtual ~Area();
+ public:
+ /**
+ * @brief draw All the refistered text in the current element on openGL
+ */
+ void draw(bool _disableDepthTest=true);
+ /**
+ * @brief clear alll the registered element in the current element
+ */
+ void clear();
+ /**
+ * @brief get the current display position (sometime needed in the gui control)
+ * @return the current position.
+ */
+ const vec3& getPos() {
+ return m_position;
+ };
+ /**
+ * @brief set position for the next text writen
+ * @param[in] _pos Position of the text (in 3D)
+ */
+ void setPos(const vec3& _pos) {
+ m_position = _pos;
+ };
+ inline void setPos(const vec2& _pos) {
+ setPos(vec3(_pos.x(),_pos.y(),0));
+ };
+ /**
+ * @brief set relative position for the next text writen
+ * @param[in] _pos ofset apply of the text (in 3D)
+ */
+ void setRelPos(const vec3& _pos) {
+ m_position += _pos;
+ };
+ inline void setRelPos(const vec2& _pos) {
+ setRelPos(vec3(_pos.x(),_pos.y(),0));
+ };
+ /**
+ * @brief add a compleate of the image to display with the requested size
+ * @param[in] _size size of the output image
+ */
+ void print(const ivec2& _size);
+
+ egami::Image& get() {
+ return m_resource->get();
+ };
+ void flush() {
+ m_resource->flush();
+ };
+ };
+ };
+};
diff --git a/src/org/atriasoft/ewol/compositing/Compositing.cpp b/src/org/atriasoft/ewol/compositing/Compositing.cpp
new file mode 100644
index 0000000..ff4462b
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/Compositing.cpp
@@ -0,0 +1,47 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+ETK_DECLARE_TYPE(ewol::Compositing);
+
+ewol::Compositing::Compositing() {
+ // nothing to do
+}
+
+
+void ewol::Compositing::resetMatrix() {
+ m_matrixApply.identity();
+}
+
+
+void ewol::Compositing::translate(const vec3& _vect) {
+ m_matrixApply *= etk::matTranslate(_vect);
+}
+
+
+void ewol::Compositing::rotate(const vec3& _vect, float _angle) {
+ m_matrixApply *= etk::matRotate(_vect, _angle);
+}
+
+
+void ewol::Compositing::scale(const vec3& _vect) {
+ m_matrixApply *= etk::matScale(_vect);
+}
+
+
+void ewol::Compositing::clear() {
+ m_matrixApply.identity();
+}
+
+
+void ewol::Compositing::setMatrix(const mat4& _mat) {
+ m_matrixApply = _mat;
+}
diff --git a/src/org/atriasoft/ewol/compositing/Compositing.java b/src/org/atriasoft/ewol/compositing/Compositing.java
new file mode 100644
index 0000000..7cea545
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/Compositing.java
@@ -0,0 +1,58 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+
+#include
+#include
+#include
+
+namespace ewol {
+ class Compositing {
+ protected:
+ mat4 m_matrixApply;
+ public:
+ /**
+ * @brief generic constructor
+ */
+ Compositing();
+ /**
+ * @brief Generic destructor
+ */
+ virtual ~Compositing() = default;
+ /**
+ * @brief Virtal pure function that request the draw of all openGl elements
+ */
+ virtual void draw(bool _disableDepthTest = true) = 0;
+ /**
+ * @brief clear alll tre registered element in the current element
+ */
+ virtual void clear();
+ /**
+ * @brief reset to the eye matrix the openGL mouving system
+ */
+ virtual void resetMatrix();
+ /**
+ * @brief translate the current display of this element
+ * @param[in] _vect The translation vector to apply at the transformation matrix
+ */
+ virtual void translate(const vec3& _vect);
+ /**
+ * @brief rotate the curent display of this element
+ * @param[in] _vect The rotation vector to apply at the transformation matrix
+ */
+ virtual void rotate(const vec3& _vect, float _angle);
+ /**
+ * @brief scale the current diaplsy of this element
+ * @param[in] _vect The scaling vector to apply at the transformation matrix
+ */
+ virtual void scale(const vec3& _vect);
+ /**
+ * @brief set the transformation matrix
+ * @param[in] _mat The new matrix.
+ */
+ virtual void setMatrix(const mat4& _mat);
+ };
+};
diff --git a/src/org/atriasoft/ewol/compositing/Drawing.cpp b/src/org/atriasoft/ewol/compositing/Drawing.cpp
new file mode 100644
index 0000000..6f9d386
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/Drawing.cpp
@@ -0,0 +1,558 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+#include
+
+#include
+ETK_DECLARE_TYPE(ewol::compositing::Drawing);
+
+// VBO table property:
+const int32_t ewol::compositing::Drawing::m_vboIdCoord(0);
+const int32_t ewol::compositing::Drawing::m_vboIdColor(1);
+#define NB_VBO (2)
+
+#if 0
+
+static void generatePolyGone(etk::Vector & input, etk::Vector & output )
+{
+ if (input.size()<3) {
+ return;
+ }
+ // TODO : Regenerate a linear poligone generation
+ for (int32_t iii=1; iii " << output.size() );
+}
+
+static void SutherlandHodgman(etk::Vector & input, etk::Vector & output, float sx, float sy, float ex, float ey)
+{
+ // with Sutherland-Hodgman-Algorithm
+ if (input.size() <0) {
+ return;
+ }
+ //int32_t sizeInit=input.size();
+ // last element :
+ vec2 destPoint;
+ vec2 lastElement = input[input.size()-1];
+ bool inside = true;
+ if (lastElement.x < sx) {
+ inside = false;
+ }
+ //EWOL_DEBUG("generate an crop : ");
+ for(int32_t iii=0; iii OUT ");
+ //new point intersection ...
+ //y=aaax+bbb
+ float aaa = (lastElement.y-input[iii].y) / (lastElement.x-input[iii].x);
+ float bbb = lastElement.y - (aaa*lastElement.x);
+ destPoint.y = aaa*sx + bbb;
+ destPoint.x = sx;
+ output.pushBack(destPoint);
+ } else {
+ //EWOL_DEBUG("element OUT == > OUT ");
+ }
+ inside = false;
+ } else {
+ if(true == inside) {
+ //EWOL_DEBUG("element IN == > IN ");
+ output.pushBack(input[iii]);
+ } else {
+ //EWOL_DEBUG("element OUT == > IN ");
+ //new point intersection ...
+ //y=aaax+bbb
+ float aaa = (lastElement.y-input[iii].y) / (lastElement.x-input[iii].x);
+ float bbb = lastElement.y - (aaa*lastElement.x);
+ destPoint.y = aaa*sx + bbb;
+ destPoint.x = sx;
+ output.pushBack(destPoint);
+ output.pushBack(input[iii]);
+ }
+ inside = true;
+ }
+ // update the last point position :
+ lastElement.x = input[iii].x;
+ lastElement.y = input[iii].y;
+ }
+
+ //EWOL_DEBUG("generate an crop on element : " << sizeInit << " == > " << output.size() << "intermediate (1)");
+ input = output;
+ output.clear();
+ lastElement = input[input.size()-1];
+ inside = true;
+ if (lastElement.y < sy) {
+ inside = false;
+ }
+ for(int32_t iii=0; iii OUT ");
+ //new point intersection ...
+ //x=aaay+bbb
+ float aaa = (lastElement.x-input[iii].x) / (lastElement.y-input[iii].y);
+ float bbb = lastElement.x - (aaa*lastElement.y);
+ destPoint.y = sy;
+ destPoint.x = sy*aaa + bbb;
+ output.pushBack(destPoint);
+ } else {
+ //EWOL_DEBUG("element OUT == > OUT ");
+ }
+ inside = false;
+ } else {
+ if(true == inside) {
+ //EWOL_DEBUG("element IN == > IN ");
+ output.pushBack(input[iii]);
+ } else {
+ //EWOL_DEBUG("element OUT == > IN ");
+ //new point intersection ...
+ //y=aaax+bbb
+ float aaa = (lastElement.x-input[iii].x) / (lastElement.y-input[iii].y);
+ float bbb = lastElement.x - (aaa*lastElement.y);
+ destPoint.y = sy;
+ destPoint.x = sy*aaa + bbb;
+ output.pushBack(destPoint);
+ output.pushBack(input[iii]);
+ }
+ inside = true;
+ }
+ // update the last point position :
+ lastElement.x = input[iii].x;
+ lastElement.y = input[iii].y;
+ }
+
+ input = output;
+ output.clear();
+ lastElement = input[input.size()-1];
+ inside = true;
+ if (lastElement.x > ex) {
+ inside = false;
+ }
+ //EWOL_DEBUG("generate an crop : ");
+ for(int32_t iii=0; iii ex) {
+ if(true == inside) {
+ //EWOL_DEBUG("element IN == > OUT ");
+ //new point intersection ...
+ //y=aaax+bbb
+ float aaa = (lastElement.y-input[iii].y) / (lastElement.x-input[iii].x);
+ float bbb = lastElement.y - (aaa*lastElement.x);
+ destPoint.y = aaa*ex + bbb;
+ destPoint.x = ex;
+ output.pushBack(destPoint);
+ } else {
+ //EWOL_DEBUG("element OUT == > OUT ");
+ }
+ inside = false;
+ } else {
+ if(true == inside) {
+ //EWOL_DEBUG("element IN == > IN ");
+ output.pushBack(input[iii]);
+ } else {
+ //EWOL_DEBUG("element OUT == > IN ");
+ //new point intersection ...
+ //y=aaax+bbb
+ float aaa = (lastElement.y-input[iii].y) / (lastElement.x-input[iii].x);
+ float bbb = lastElement.y - (aaa*lastElement.x);
+ destPoint.y = aaa*ex + bbb;
+ destPoint.x = ex;
+ output.pushBack(destPoint);
+ output.pushBack(input[iii]);
+ }
+ inside = true;
+ }
+ // update the last point position :
+ lastElement.x = input[iii].x;
+ lastElement.y = input[iii].y;
+ }
+
+ input = output;
+ output.clear();
+ lastElement = input[input.size()-1];
+ inside = true;
+ if (lastElement.y > ey) {
+ inside = false;
+ }
+ for(int32_t iii=0; iii ey) {
+ if(true == inside) {
+ //EWOL_DEBUG("element IN == > OUT ");
+ //new point intersection ...
+ //x=aaay+bbb
+ float aaa = (lastElement.x-input[iii].x) / (lastElement.y-input[iii].y);
+ float bbb = lastElement.x - (aaa*lastElement.y);
+ destPoint.y = ey;
+ destPoint.x = ey*aaa + bbb;
+ output.pushBack(destPoint);
+ } else {
+ //EWOL_DEBUG("element OUT == > OUT ");
+ }
+ inside = false;
+ } else {
+ if(true == inside) {
+ //EWOL_DEBUG("element IN == > IN ");
+ output.pushBack(input[iii]);
+ } else {
+ //EWOL_DEBUG("element OUT == > IN ");
+ //new point intersection ...
+ //y=aaax+bbb
+ float aaa = (lastElement.x-input[iii].x) / (lastElement.y-input[iii].y);
+ float bbb = lastElement.x - (aaa*lastElement.y);
+ destPoint.y = ey;
+ destPoint.x = ey*aaa + bbb;
+ output.pushBack(destPoint);
+ output.pushBack(input[iii]);
+ }
+ inside = true;
+ }
+ // update the last point position :
+ lastElement.x = input[iii].x;
+ lastElement.y = input[iii].y;
+ }
+
+
+ //EWOL_DEBUG("generate an crop on element : " << sizeInit << " == > " << output.size() );
+}
+#endif
+
+ewol::compositing::Drawing::Drawing() :
+ m_position(0.0, 0.0, 0.0),
+ m_clippingPosStart(0.0, 0.0, 0.0),
+ m_clippingPosStop(0.0, 0.0, 0.0),
+ m_clippingEnable(false),
+ m_color(etk::color::black),
+ m_colorBg(etk::color::none),
+ m_GLprogram(null),
+ m_GLPosition(-1),
+ m_GLMatrix(-1),
+ m_GLMatrixPosition(-1),
+ m_GLColor(-1),
+ m_thickness(0.0),
+ m_triElement(0) {
+ loadProgram();
+ for (int32_t iii=0; iii<3; iii++) {
+ m_triangle[iii] = m_position;
+ m_tricolor[iii] = m_color;
+ }
+ // Create the VBO:
+ m_VBO = gale::resource::VirtualBufferObject::create(NB_VBO);
+ if (m_VBO == null) {
+ EWOL_ERROR("can not instanciate VBO ...");
+ return;
+ }
+ // TO facilitate some debugs we add a name of the VBO:
+ m_VBO->setName("[VBO] of ewol::compositing::Area");
+}
+
+ewol::compositing::Drawing::~Drawing() {
+ unLoadProgram();
+}
+
+void ewol::compositing::Drawing::generateTriangle() {
+ m_triElement = 0;
+
+ m_VBO->pushOnBuffer(m_vboIdCoord, m_triangle[0]);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_tricolor[0]);
+ m_VBO->pushOnBuffer(m_vboIdCoord, m_triangle[1]);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_tricolor[1]);
+ m_VBO->pushOnBuffer(m_vboIdCoord, m_triangle[2]);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_tricolor[2]);
+}
+
+void ewol::compositing::Drawing::internalSetColor(const etk::Color<>& _color) {
+ if (m_triElement < 1) {
+ m_tricolor[0] = _color;
+ }
+ if (m_triElement < 2) {
+ m_tricolor[1] = _color;
+ }
+ if (m_triElement < 3) {
+ m_tricolor[2] = _color;
+ }
+}
+
+void ewol::compositing::Drawing::setPoint(const vec3& _point) {
+ m_triangle[m_triElement] = _point;
+ m_triElement++;
+ if (m_triElement >= 3) {
+ generateTriangle();
+ }
+ m_VBO->flush();
+}
+
+void ewol::compositing::Drawing::resetCount() {
+ m_triElement = 0;
+}
+
+void ewol::compositing::Drawing::unLoadProgram() {
+ m_GLprogram.reset();
+}
+
+void ewol::compositing::Drawing::loadProgram() {
+ // remove previous loading ... in case
+ unLoadProgram();
+ // oad the new ...
+ m_GLprogram = gale::resource::Program::create("DATA:///color3.prog?lib=ewol");
+ // get the shader resource :
+ if (m_GLprogram != null) {
+ m_GLPosition = m_GLprogram->getAttribute("EW_coord3d");
+ m_GLColor = m_GLprogram->getAttribute("EW_color");
+ m_GLMatrix = m_GLprogram->getUniform("EW_MatrixTransformation");
+ m_GLMatrixPosition = m_GLprogram->getUniform("EW_MatrixPosition");
+ }
+}
+
+void ewol::compositing::Drawing::draw(bool _disableDepthTest) {
+ if (m_VBO->bufferSize(m_vboIdCoord) <= 0) {
+ // TODO : set it back ...
+ //EWOL_WARNING("Nothink to draw...");
+ return;
+ }
+ if (m_GLprogram == null) {
+ EWOL_ERROR("No shader ...");
+ return;
+ }
+ // set Matrix : translation/positionMatrix
+ mat4 tmpMatrix = gale::openGL::getMatrix()*m_matrixApply;
+ m_GLprogram->use();
+ m_GLprogram->uniformMatrix(m_GLMatrix, tmpMatrix);
+ mat4 tmpMatrix2;
+ m_GLprogram->uniformMatrix(m_GLMatrixPosition, tmpMatrix2);
+ // position:
+ m_GLprogram->sendAttributePointer(m_GLPosition, m_VBO, m_vboIdCoord);
+ // color:
+ m_GLprogram->sendAttributePointer(m_GLColor, m_VBO, m_vboIdColor);
+ // Request the draw od the elements :
+ gale::openGL::drawArrays(gale::openGL::renderMode::triangle, 0, m_VBO->bufferSize(m_vboIdCoord));
+ m_GLprogram->unUse();
+}
+
+void ewol::compositing::Drawing::clear() {
+ // call upper class
+ ewol::Compositing::clear();
+ // reset Buffer :
+ m_VBO->clear();
+ // reset temporal variables :
+ m_position = vec3(0.0, 0.0, 0.0);
+
+ m_clippingPosStart = vec3(0.0, 0.0, 0.0);
+ m_clippingPosStop = vec3(0.0, 0.0, 0.0);
+ m_clippingEnable = false;
+
+ m_color = etk::color::black;
+ m_colorBg = etk::color::none;
+
+ for (int32_t iii=0; iii<3; iii++) {
+ m_triangle[iii] = m_position;
+ m_tricolor[iii] = m_color;
+ }
+}
+
+void ewol::compositing::Drawing::setClipping(const vec3& _pos, const vec3& _posEnd) {
+ // note the internal system all time request to have a bounding all time in the same order
+ if (_pos.x() <= _posEnd.x()) {
+ m_clippingPosStart.setX(_pos.x());
+ m_clippingPosStop.setX(_posEnd.x());
+ } else {
+ m_clippingPosStart.setX(_posEnd.x());
+ m_clippingPosStop.setX(_pos.x());
+ }
+ if (_pos.y() <= _posEnd.y()) {
+ m_clippingPosStart.setY(_pos.y());
+ m_clippingPosStop.setY(_posEnd.y());
+ } else {
+ m_clippingPosStart.setY(_posEnd.y());
+ m_clippingPosStop.setY(_pos.y());
+ }
+ if (_pos.z() <= _posEnd.z()) {
+ m_clippingPosStart.setZ(_pos.z());
+ m_clippingPosStop.setZ(_posEnd.z());
+ } else {
+ m_clippingPosStart.setZ(_posEnd.z());
+ m_clippingPosStop.setZ(_pos.z());
+ }
+ m_clippingEnable = true;
+}
+
+void ewol::compositing::Drawing::setThickness(float _thickness) {
+ m_thickness = _thickness;
+ // thickness must be positive
+ if (m_thickness < 0) {
+ m_thickness *= -1;
+ }
+}
+
+void ewol::compositing::Drawing::addVertex() {
+ internalSetColor(m_color);
+ setPoint(m_position);
+}
+
+void ewol::compositing::Drawing::lineTo(const vec3& _dest) {
+ resetCount();
+ internalSetColor(m_color);
+ //EWOL_VERBOSE("DrawLine : " << m_position << " to " << _dest);
+ if (m_position.x() == _dest.x() && m_position.y() == _dest.y() && m_position.z() == _dest.z()) {
+ //EWOL_WARNING("Try to draw a line width 0");
+ return;
+ }
+ //teta = tan-1(oposer/adjacent)
+ float teta = 0;
+ if (m_position.x() <= _dest.x()) {
+ teta = atan((_dest.y()-m_position.y())/(_dest.x()-m_position.x()));
+ } else {
+ teta = M_PI + atan((_dest.y()-m_position.y())/(_dest.x()-m_position.x()));
+ }
+ if (teta < 0) {
+ teta += 2*M_PI;
+ } else if (teta > 2*M_PI) {
+ teta -= 2*M_PI;
+ }
+ //EWOL_DEBUG("teta = " << (teta*180/(M_PI)) << " deg." );
+ float offsety = sin(teta-M_PI/2) * (m_thickness/2);
+ float offsetx = cos(teta-M_PI/2) * (m_thickness/2);
+ setPoint(vec3(m_position.x() - offsetx, m_position.y() - offsety, m_position.z()) );
+ setPoint(vec3(m_position.x() + offsetx, m_position.y() + offsety, m_position.z()) );
+ setPoint(vec3(_dest.x() + offsetx, _dest.y() + offsety, m_position.z()) );
+
+ setPoint(vec3(_dest.x() + offsetx, _dest.y() + offsety, _dest.z()) );
+ setPoint(vec3(_dest.x() - offsetx, _dest.y() - offsety, _dest.z()) );
+ setPoint(vec3(m_position.x() - offsetx, m_position.y() - offsety, _dest.z()) );
+ // update the system position :
+ m_position = _dest;
+}
+
+void ewol::compositing::Drawing::rectangle(const vec3& _dest) {
+ resetCount();
+ internalSetColor(m_color);
+ /* Bitmap position
+ * xA xB
+ * yC *------*
+ * | |
+ * | |
+ * yD *------*
+ */
+ float dxA = m_position.x();
+ float dxB = _dest.x();
+ if (dxA > dxB) {
+ // inverse order :
+ float tmp = dxA;
+ dxA = dxB;
+ dxB = tmp;
+ }
+ float dyC = m_position.y();
+ float dyD = _dest.y();
+ if (dyC > dyD) {
+ // inverse order :
+ float tmp = dyC;
+ dyC = dyD;
+ dyD = tmp;
+ }
+ if (true == m_clippingEnable) {
+ if (dxA < m_clippingPosStart.x()) {
+ dxA = m_clippingPosStart.x();
+ }
+ if (dxB > m_clippingPosStop.x()) {
+ dxB = m_clippingPosStop.x();
+ }
+ if (dyC < m_clippingPosStart.y()) {
+ dyC = m_clippingPosStart.y();
+ }
+ if (dyD > m_clippingPosStop.y()) {
+ dyD = m_clippingPosStop.y();
+ }
+ }
+ if( dyC >= dyD
+ || dxA >= dxB) {
+ return;
+ }
+ setPoint(vec3(dxA, dyD, 0) );
+ setPoint(vec3(dxA, dyC, 0) );
+ setPoint(vec3(dxB, dyC, 0) );
+
+ setPoint(vec3(dxB, dyC, 0) );
+ setPoint(vec3(dxB, dyD, 0) );
+ setPoint(vec3(dxA, dyD, 0) );
+}
+
+void ewol::compositing::Drawing::cube(const vec3& _dest) {
+
+}
+
+void ewol::compositing::Drawing::circle(float _radius, float _angleStart, float _angleStop) {
+ resetCount();
+
+ if (_radius<0) {
+ _radius *= -1;
+ }
+ _angleStop = _angleStop-_angleStart;
+
+
+ int32_t nbOcurence = _radius;
+ if (nbOcurence < 10)
+ {
+ nbOcurence = 10;
+ }
+
+ // display background :
+ if (m_colorBg.a()!=0) {
+ internalSetColor(m_colorBg);
+ for (int32_t iii=0; iii
+
+#include
+#include
+#include
+
+
+namespace ewol {
+ namespace compositing {
+ class Drawing : public ewol::Compositing {
+ private:
+ vec3 m_position; //!< The current position to draw
+ vec3 m_clippingPosStart; //!< Clipping start position
+ vec3 m_clippingPosStop; //!< Clipping stop position
+ bool m_clippingEnable; //!< true if the clipping must be activated
+ private:
+ etk::Color<> m_color; //!< The text foreground color
+ etk::Color<> m_colorBg; //!< The text background color
+ private:
+ ememory::SharedPtr m_GLprogram; //!< pointer on the opengl display program
+ 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_GLMatrixPosition; //!< position matrix
+ int32_t m_GLColor; //!< openGL id on the element (color buffer)
+ protected:
+ static const int32_t m_vboIdCoord;
+ static const int32_t m_vboIdColor;
+ ememory::SharedPtr m_VBO;
+ public:
+ /**
+ * @brief Basic constructor
+ */
+ Drawing();
+ /**
+ * @brief Basic destructor
+ */
+ virtual ~Drawing();
+ private:
+ /**
+ * @brief load the openGL program and get all the ID needed
+ */
+ void loadProgram();
+ /**
+ * @brief Un-Load the openGL program and get all the ID needed
+ */
+ void unLoadProgram();
+ float m_thickness; //!< when drawing line and other things
+ int32_t m_triElement; //!< special counter of the single dot generated
+ vec3 m_triangle[3]; //!< Register every system with a combinaison of tiangle
+ etk::Color m_tricolor[3]; //!< Register every the associated color foreground
+ // internal API for the generation abstraction of triangles
+ /**
+ * @brief Lunch the generation of triangle
+ */
+ void generateTriangle();
+ /**
+ * @brief in case of some error the count can be reset
+ */
+ void resetCount();
+ /**
+ * @brief set the Color of the current triangle drawing
+ * @param[in] _color Color to current dots generated
+ */
+ void internalSetColor(const etk::Color<>& _color);
+ /**
+ * @brief internal add of the specific point
+ * @param[in] _point The requeste dpoint to add
+ */
+ void setPoint(const vec3& point);
+
+ public:
+ /**
+ * @brief draw All the refistered text in the current element on openGL
+ */
+ void draw(bool _disableDepthTest=true);
+ /**
+ * @brief clear alll tre registered element in the current element
+ */
+ void clear();
+ /**
+ * @brief get the current display position (sometime needed in the gui control)
+ * @return the current position.
+ */
+ const vec3& getPos() {
+ return m_position;
+ };
+ /**
+ * @brief set position for the next text writen
+ * @param[in] _pos Position of the text (in 3D)
+ */
+ void setPos(const vec3& _pos) {
+ m_position = _pos;
+ };
+ inline void setPos(const vec2& _pos) {
+ setPos(vec3(_pos.x(), _pos.y(), 0));
+ };
+ /**
+ * @brief set relative position for the next text writen
+ * @param[in] _pos ofset apply of the text (in 3D)
+ */
+ void setRelPos(const vec3& _pos) {
+ m_position += _pos;
+ };
+ inline void setRelPos(const vec2& _pos) {
+ setRelPos(vec3(_pos.x(), _pos.y(), 0));
+ };
+ /**
+ * @brief set the Color of the current foreground font
+ * @param[in] _color Color to set on foreground (for next print)
+ */
+ void setColor(const etk::Color<>& _color) {
+ m_color = _color;
+ };
+ /**
+ * @brief Get the foreground color of the font.
+ * @return Foreground color.
+ */
+ const etk::Color<>& getColor() {
+ return m_color;
+ };
+ /**
+ * @brief set the background color of the font (for selected Text (not the global BG))
+ * @param[in] _color Color to set on background (for next print)
+ */
+ void setColorBg(const etk::Color<>& _color) {
+ m_colorBg = _color;
+ };
+ /**
+ * @brief Get the background color of the font.
+ * @return Background color.
+ */
+ const etk::Color<>& getColorBg() {
+ return m_colorBg;
+ };
+ /**
+ * @brief Request a clipping area for the text (next draw only)
+ * @param[in]_ pos Start position of the clipping
+ * @param[in] _width Width size of the clipping
+ */
+ void setClippingWidth(const vec3& _pos, const vec3& _width) {
+ setClipping(_pos, _pos+_width);
+ };
+ inline void setClippingWidth(const vec2& _pos, const vec2& _width) {
+ setClippingWidth(vec3(_pos.x(),_pos.y(),-1), vec3(_width.x(),_width.y(), 2));
+ };
+ /**
+ * @brief Request a clipping area for the text (next draw only)
+ * @param[in] _pos Start position of the clipping
+ * @param[in] _posEnd End position of the clipping
+ */
+ void setClipping(const vec3& _pos, const vec3& _posEnd);
+ inline void setClipping(const vec2& _pos, const vec2& _posEnd) {
+ setClipping(vec3(_pos.x(),_pos.y(),-1), vec3(_posEnd.x(),_posEnd.y(), 1));
+ };
+ /**
+ * @brief enable/Disable the clipping (without lose the current clipping position)
+ * @brief _newMode The new status of the clipping
+ */
+ void setClippingMode(bool _newMode) {
+ m_clippingEnable = _newMode;
+ };
+ /**
+ * @brief Specify the line thickness for the next elements
+ * @param[in] _thickness The thickness disired for the next print
+ */
+ void setThickness(float _thickness);
+ /**
+ * @brief add a point reference at the current position (this is a vertex reference at the current position
+ */
+ void addVertex();
+ /**
+ * @brief draw a line to a specific position
+ * @param[in] _dest Position of the end of the line.
+ */
+ void lineTo(const vec3& _dest);
+ inline void lineTo(const vec2& _dest) {
+ lineTo(vec3(_dest.x(), _dest.y(), 0));
+ };
+ /**
+ * @brief Relative drawing a line (spacial vector)
+ * @param[in] _vect Vector of the curent line.
+ */
+ void lineRel(const vec3& _vect) {
+ lineTo(m_position+_vect);
+ };
+ inline void lineRel(const vec2& _vect) {
+ lineRel(vec3(_vect.x(), _vect.y(), 0));
+ };
+ /**
+ * @brief draw a 2D rectangle to the position requested.
+ * @param[in] _dest Position the the end of the rectangle
+ */
+ void rectangle(const vec3& _dest);
+ inline void rectangle(const vec2& _dest) {
+ rectangle(vec3(_dest.x(), _dest.y(), 0));
+ };
+ /**
+ * @brief draw a 2D rectangle to the requested size.
+ * @param[in] _size size of the rectangle
+ */
+ void rectangleWidth(const vec3& _size) {
+ rectangle(m_position+_size);
+ };
+ inline void rectangleWidth(const vec2& _size) {
+ rectangleWidth(vec3(_size.x(), _size.y(), 0));
+ };
+ /**
+ * @brief draw a 3D rectangle to the position requested.
+ * @param[in] _dest Position the the end of the rectangle
+ */
+ void cube(const vec3& _dest);
+ /**
+ * @brief draw a 2D circle with the specify rafdius parameter.
+ * @param[in] _radius Distence to the dorder
+ * @param[in] _angleStart start angle of this circle ([0..2PI] otherwithe == > disable)
+ * @param[in] _angleStop stop angle of this circle ([0..2PI] otherwithe == > disable)
+ */
+ void circle(float _radius, float _angleStart = 0, float _angleStop = 2*M_PI);
+ };
+ };
+};
+
diff --git a/src/org/atriasoft/ewol/compositing/Image.cpp b/src/org/atriasoft/ewol/compositing/Image.cpp
new file mode 100644
index 0000000..76e8f67
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/Image.cpp
@@ -0,0 +1,364 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+#include
+#include
+ETK_DECLARE_TYPE(ewol::compositing::Image);
+
+const int32_t ewol::compositing::Image::sizeAuto(0);
+
+// VBO table property:
+const int32_t ewol::compositing::Image::m_vboIdCoord(0);
+const int32_t ewol::compositing::Image::m_vboIdCoordTex(1);
+const int32_t ewol::compositing::Image::m_vboIdColor(2);
+#define NB_VBO (3)
+
+ewol::compositing::Image::Image(const etk::Uri& _imageName,
+ bool _df,
+ int32_t _size) :
+ m_filename(_imageName),
+ m_requestSize(2,2),
+ m_position(0.0, 0.0, 0.0),
+ m_clippingPosStart(0.0, 0.0, 0.0),
+ m_clippingPosStop(0.0, 0.0, 0.0),
+ m_clippingEnable(false),
+ m_color(etk::color::white),
+ m_angle(0.0),
+ m_GLprogram(null),
+ m_GLPosition(-1),
+ m_GLMatrix(-1),
+ m_GLColor(-1),
+ m_GLtexture(-1),
+ m_GLtexID(-1),
+ m_distanceFieldMode(_df),
+ m_resource(null),
+ m_resourceDF(null) {
+ // Create the VBO:
+ m_VBO = gale::resource::VirtualBufferObject::create(NB_VBO);
+ if (m_VBO == null) {
+ EWOL_ERROR("can not instanciate VBO ...");
+ return;
+ }
+ // TO facilitate some debugs we add a name of the VBO:
+ m_VBO->setName("[VBO] of ewol::compositing::Image");
+ setSource(_imageName, _size);
+ loadProgram();
+}
+
+ewol::compositing::Image::~Image() {
+
+}
+
+void ewol::compositing::Image::loadProgram() {
+ // get the shader resource:
+ m_GLPosition = 0;
+ m_GLprogram.reset();
+ if (m_distanceFieldMode == true) {
+ m_GLprogram = gale::resource::Program::create("DATA:///texturedDF.prog?lib=ewol");
+ } else {
+ m_GLprogram = gale::resource::Program::create("DATA:///textured3D.prog?lib=ewol");
+ }
+ if (m_GLprogram != null) {
+ m_GLPosition = m_GLprogram->getAttribute("EW_coord3d");
+ m_GLColor = m_GLprogram->getAttribute("EW_color");
+ m_GLtexture = m_GLprogram->getAttribute("EW_texture2d");
+ m_GLMatrix = m_GLprogram->getUniform("EW_MatrixTransformation");
+ m_GLtexID = m_GLprogram->getUniform("EW_texID");
+ }
+}
+
+void ewol::compositing::Image::draw(bool _disableDepthTest) {
+ if (m_VBO->bufferSize(m_vboIdCoord) <= 0) {
+ //EWOL_WARNING("Nothink to draw...");
+ return;
+ }
+ if ( m_resource == null
+ && m_resourceDF == null
+ && m_resourceImage == null) {
+ // this is a normale case ... the user can choice to have no image ...
+ return;
+ }
+ if (m_GLprogram == null) {
+ EWOL_ERROR("No shader ...");
+ return;
+ }
+ //EWOL_WARNING("Display image : " << m_VBO->bufferSize(m_vboIdCoord));
+ if (_disableDepthTest == true) {
+ gale::openGL::disable(gale::openGL::flag_depthTest);
+ } else {
+ gale::openGL::enable(gale::openGL::flag_depthTest);
+ }
+ // set Matrix : translation/positionMatrix
+ mat4 tmpMatrix = gale::openGL::getMatrix()*m_matrixApply;
+ m_GLprogram->use();
+ m_GLprogram->uniformMatrix(m_GLMatrix, tmpMatrix);
+ // TextureID
+ if (m_resourceImage != null) {
+ m_GLprogram->setTexture0(m_GLtexID, m_resourceImage->getRendererId());
+ } else if (m_resource != null) {
+ if (m_distanceFieldMode == true) {
+ EWOL_ERROR("FONT type error Request distance field and display normal ...");
+ }
+ m_GLprogram->setTexture0(m_GLtexID, m_resource->getRendererId());
+ } else {
+ if (m_distanceFieldMode == false) {
+ EWOL_ERROR("FONT type error Request normal and display distance field ...");
+ }
+ m_GLprogram->setTexture0(m_GLtexID, m_resourceDF->getRendererId());
+ }
+ // position:
+ m_GLprogram->sendAttributePointer(m_GLPosition, m_VBO, m_vboIdCoord);
+ // Texture:
+ m_GLprogram->sendAttributePointer(m_GLtexture, m_VBO, m_vboIdCoordTex);
+ // color:
+ m_GLprogram->sendAttributePointer(m_GLColor, m_VBO, m_vboIdColor);
+ // Request the draw of the elements:
+ gale::openGL::drawArrays(gale::openGL::renderMode::triangle, 0, m_VBO->bufferSize(m_vboIdCoord));
+ m_GLprogram->unUse();
+}
+
+void ewol::compositing::Image::clear() {
+ // call upper class
+ ewol::Compositing::clear();
+ // reset Buffer :
+ m_VBO->clear();
+ // reset temporal variables :
+ m_position = vec3(0.0, 0.0, 0.0);
+ m_clippingPosStart = vec3(0.0, 0.0, 0.0);
+ m_clippingPosStop = vec3(0.0, 0.0, 0.0);
+ m_clippingEnable = false;
+ m_color = etk::color::white;
+ m_angle = 0.0;
+}
+
+void ewol::compositing::Image::setClipping(const vec3& _pos, vec3 _posEnd) {
+ // note the internal system all time request to have a bounding all time in the same order
+ if (_pos.x() <= _posEnd.x()) {
+ m_clippingPosStart.setX(_pos.x());
+ m_clippingPosStop.setX(_posEnd.x());
+ } else {
+ m_clippingPosStart.setX(_posEnd.x());
+ m_clippingPosStop.setX(_pos.x());
+ }
+ if (_pos.y() <= _posEnd.y()) {
+ m_clippingPosStart.setY(_pos.y());
+ m_clippingPosStop.setY(_posEnd.y());
+ } else {
+ m_clippingPosStart.setY(_posEnd.y());
+ m_clippingPosStop.setY(_pos.y());
+ }
+ if (_pos.z() <= _posEnd.z()) {
+ m_clippingPosStart.setZ(_pos.z());
+ m_clippingPosStop.setZ(_posEnd.z());
+ } else {
+ m_clippingPosStart.setZ(_posEnd.z());
+ m_clippingPosStop.setZ(_pos.z());
+ }
+ m_clippingEnable = true;
+}
+
+void ewol::compositing::Image::setAngle(float _angle) {
+ m_angle = _angle;
+}
+
+void ewol::compositing::Image::print(const vec2& _size) {
+ printPart(_size, vec2(0,0), vec2(1.0,1.0));
+}
+
+void ewol::compositing::Image::printPart(const vec2& _size,
+ vec2 _sourcePosStart,
+ vec2 _sourcePosStop) {
+ if (m_resource == null) {
+ return;
+ }
+ vec2 openGLSize = vec2(m_resource->getOpenGlSize().x(), m_resource->getOpenGlSize().y());
+ vec2 usefullSize = m_resource->getUsableSize();
+ vec2 ratio = usefullSize/openGLSize;
+ _sourcePosStart *= ratio;
+ _sourcePosStop *= ratio;
+ EWOL_VERBOSE(" openGLSize=" << openGLSize << " usableSize=" << usefullSize << " start=" << _sourcePosStart << " stop=" << _sourcePosStop);
+
+ //EWOL_ERROR("Debug image " << m_filename << " ==> " << m_position << " " << _size << " " << _sourcePosStart << " " << _sourcePosStop);
+ if (m_angle == 0.0f) {
+ vec3 point = m_position;
+ vec2 tex(_sourcePosStart.x(),_sourcePosStop.y());
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdCoordTex, tex);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+
+ tex.setValue(_sourcePosStop.x(),_sourcePosStop.y());
+ point.setX(m_position.x() + _size.x());
+ point.setY(m_position.y());
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdCoordTex, tex);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+
+ tex.setValue(_sourcePosStop.x(),_sourcePosStart.y());
+ point.setX(m_position.x() + _size.x());
+ point.setY(m_position.y() + _size.y());
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdCoordTex, tex);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdCoordTex, tex);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+
+ tex.setValue(_sourcePosStart.x(),_sourcePosStart.y());
+ point.setX(m_position.x());
+ point.setY(m_position.y() + _size.y());
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdCoordTex, tex);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+
+ tex.setValue(_sourcePosStart.x(),_sourcePosStop.y());
+ point.setX(m_position.x());
+ point.setY(m_position.y());
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdCoordTex, tex);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ m_VBO->flush();
+ return;
+ }
+ vec3 center = m_position + vec3(_size.x(),_size.y(),0)/2.0f;
+ vec3 limitedSize(_size.x()*0.5f, _size.y()*0.5f, 0.0f);
+
+ vec3 point(0,0,0);
+ vec2 tex(_sourcePosStart.x(),_sourcePosStop.y());
+
+ point.setValue(-limitedSize.x(), -limitedSize.y(), 0);
+ point = point.rotate(vec3(0,0,1), m_angle) + center;
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdCoordTex, tex);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+
+ tex.setValue(_sourcePosStop.x(),_sourcePosStop.y());
+ point.setValue(limitedSize.x(), -limitedSize.y(), 0);
+ point = point.rotate(vec3(0,0,1), m_angle) + center;
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdCoordTex, tex);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+
+ tex.setValue(_sourcePosStop.x(),_sourcePosStart.y());
+ point.setValue(limitedSize.x(), limitedSize.y(), 0);
+ point = point.rotate(vec3(0,0,1), m_angle) + center;
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdCoordTex, tex);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdCoordTex, tex);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+
+ tex.setValue(_sourcePosStart.x(),_sourcePosStart.y());
+ point.setValue(-limitedSize.x(), limitedSize.y(), 0);
+ point = point.rotate(vec3(0,0,1), m_angle) + center;
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdCoordTex, tex);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+
+ tex.setValue(_sourcePosStart.x(),_sourcePosStop.y());
+ point.setValue(-limitedSize.x(), -limitedSize.y(), 0);
+ point = point.rotate(vec3(0,0,1), m_angle) + center;
+ m_VBO->pushOnBuffer(m_vboIdCoord, point);
+ m_VBO->pushOnBuffer(m_vboIdCoordTex, tex);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+
+ m_VBO->flush();
+}
+
+void ewol::compositing::Image::setSource(const etk::Uri& _uri, const vec2& _size) {
+ clear();
+ if ( m_filename == _uri
+ && m_requestSize == _size) {
+ // Nothing to do ...
+ return;
+ }
+ ememory::SharedPtr resource = m_resource;
+ ememory::SharedPtr resourceDF = m_resourceDF;
+ ememory::SharedPtr resourceTex = m_resourceImage;
+ m_filename = _uri;
+ m_requestSize = _size;
+ m_resource.reset();
+ m_resourceDF.reset();
+ m_resourceImage.reset();
+ ivec2 tmpSize(_size.x(),_size.y());
+ // note that no image can be loaded...
+ if (_uri.isEmpty() == false) {
+ // link to new one
+ if (m_distanceFieldMode == false) {
+ m_resource = ewol::resource::TextureFile::create(m_filename, tmpSize);
+ if (m_resource == null) {
+ EWOL_ERROR("Can not get Image resource");
+ }
+ } else {
+ m_resourceDF = ewol::resource::ImageDF::create(m_filename, tmpSize);
+ if (m_resourceDF == null) {
+ EWOL_ERROR("Can not get Image resource DF");
+ }
+ }
+ }
+ if ( m_resource == null
+ && m_resourceDF == null
+ && m_resourceImage == null) {
+ if (resource != null) {
+ EWOL_WARNING("Retrive previous resource");
+ m_resource = resource;
+ }
+ if (resourceDF != null) {
+ EWOL_WARNING("Retrive previous resource (DF)");
+ m_resourceDF = resourceDF;
+ }
+ if (resourceTex != null) {
+ EWOL_WARNING("Retrive previous resource (image)");
+ m_resourceImage = resourceTex;
+ }
+ }
+}
+void ewol::compositing::Image::setSource(egami::Image _image) {
+ clear();
+ m_filename = "direct image BUFFER";
+ m_requestSize = _image.getSize();
+ m_resourceImage = ewol::resource::Texture::create();
+ m_resourceImage->set(etk::move(_image));
+}
+
+bool ewol::compositing::Image::hasSources() {
+ return m_resource != null
+ || m_resourceDF != null;
+}
+
+
+vec2 ewol::compositing::Image::getRealSize() {
+ if ( m_resource == null
+ && m_resourceDF == null
+ && m_resourceImage == null) {
+ return vec2(0,0);
+ }
+ if (m_resource != null) {
+ return m_resource->getRealSize();
+ }
+ if (m_resourceDF != null) {
+ return m_resourceDF->getRealSize();
+ }
+ if (m_resourceImage != null) {
+ return m_resourceImage->getUsableSize();
+ }
+ return vec2(0,0);
+}
+
+
+
+void ewol::compositing::Image::setDistanceFieldMode(bool _mode) {
+ if (m_distanceFieldMode == _mode) {
+ return;
+ }
+ m_distanceFieldMode = _mode;
+ // Force reload input
+ setSource(m_filename, m_requestSize);
+ loadProgram();
+}
diff --git a/src/org/atriasoft/ewol/compositing/Image.java b/src/org/atriasoft/ewol/compositing/Image.java
new file mode 100644
index 0000000..9725a15
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/Image.java
@@ -0,0 +1,193 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+
+namespace ewol {
+ namespace compositing {
+ class Image : public ewol::Compositing {
+ public:
+ static const int32_t sizeAuto;
+ private:
+ etk::Uri m_filename;
+ ivec2 m_requestSize;
+ vec3 m_position; //!< The current position to draw
+ vec3 m_clippingPosStart; //!< Clipping start position
+ vec3 m_clippingPosStop; //!< Clipping stop position
+ bool m_clippingEnable; //!< true if the clipping must be activated
+ private:
+ etk::Color m_color; //!< The text foreground color
+ float m_angle; //!< Angle to set at the axes
+ private:
+ ememory::SharedPtr m_GLprogram; //!< pointer on the opengl display program
+ 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_GLColor; //!< openGL id on the element (color buffer)
+ int32_t m_GLtexture; //!< openGL id on the element (Texture position)
+ int32_t m_GLtexID; //!< openGL id on the element (texture ID)
+ private:
+ bool m_distanceFieldMode; //!< select distance field mode
+ ememory::SharedPtr m_resource; //!< texture resources
+ ememory::SharedPtr m_resourceImage; //!< texture resources
+ ememory::SharedPtr m_resourceDF; //!< texture resources
+ static const int32_t m_vboIdCoord;
+ static const int32_t m_vboIdCoordTex;
+ static const int32_t m_vboIdColor;
+ ememory::SharedPtr m_VBO;
+ private:
+ /**
+ * @brief load the openGL program and get all the ID needed
+ */
+ void loadProgram();
+ public:
+ /**
+ * @brief generic constructor
+ * @param[in] _uri URI of the file that might be loaded
+ * @param[in] _df enable distance field mode
+ * @param[in] _size for the image when Verctorial image loading is requested
+ */
+ Image(const etk::Uri& _uri="",
+ bool _df=false,
+ int32_t _size=ewol::compositing::Image::sizeAuto);
+ /**
+ * @brief generic destructor
+ */
+ virtual ~Image();
+ public:
+ /**
+ * @brief draw All the refistered text in the current element on openGL
+ * @param[in] _disableDepthTest disable the Depth test for display
+ */
+ void draw(bool _disableDepthTest=true);
+ /**
+ * @brief clear alll tre registered element in the current element
+ */
+ void clear();
+ /**
+ * @brief get the current display position (sometime needed in the gui control)
+ * @return the current position.
+ */
+ const vec3& getPos() {
+ return m_position;
+ };
+ /**
+ * @brief set position for the next text writen
+ * @param[in] _pos Position of the text (in 3D)
+ */
+ void setPos(const vec3& _pos) {
+ m_position = _pos;
+ };
+ inline void setPos(const vec2& _pos) {
+ setPos(vec3(_pos.x(),_pos.y(),0));
+ };
+ /**
+ * @brief set relative position for the next text writen
+ * @param[in] _pos ofset apply of the text (in 3D)
+ */
+ void setRelPos(const vec3& _pos) {
+ m_position += _pos;
+ };
+ inline void setRelPos(const vec2& _pos) {
+ setRelPos(vec3(_pos.x(),_pos.y(),0));
+ };
+ /**
+ * @brief set the Color of the current foreground font
+ * @param[in] _color Color to set on foreground (for next print)
+ */
+ void setColor(const etk::Color<>& _color) {
+ m_color = _color;
+ };
+ /**
+ * @brief Request a clipping area for the text (next draw only)
+ * @param[in] _pos Start position of the clipping
+ * @param[in] _width Width size of the clipping
+ */
+ void setClippingWidth(const vec3& _pos, vec3 _width) {
+ setClipping(_pos, _pos+_width);
+ };
+ inline void setClippingWidth(const vec2& _pos, const vec2& _width) {
+ setClippingWidth(vec3(_pos.x(),_pos.y(),0), vec3(_width.x(),_width.y(),0));
+ };
+ /**
+ * @brief Request a clipping area for the text (next draw only)
+ * @param[in] _pos Start position of the clipping
+ * @param[in] _posEnd End position of the clipping
+ */
+ void setClipping(const vec3& _pos, vec3 _posEnd);
+ inline void setClipping(const vec2& _pos, const vec2& _posEnd) {
+ setClipping(vec3(_pos.x(),_pos.y(),0), vec3(_posEnd.x(),_posEnd.y(),0));
+ };
+ /**
+ * @brief enable/Disable the clipping (without lose the current clipping position)
+ * @brief _newMode The new status of the clipping
+ */
+ void setClippingMode(bool _newMode) {
+ m_clippingEnable = _newMode;
+ };
+ /**
+ * @brief set a unique rotation of this element (not set in the rotate Generic system)
+ * @param[in] _angle Angle to set in radiant.
+ */
+ void setAngle(float _angleRad);
+ /**
+ * @brief add a compleate of the image to display with the requested size
+ * @param[in] _size size of the output image
+ */
+ void print(const ivec2& _size) {
+ print(vec2(_size.x(),_size.y()));
+ };
+ void print(const vec2& _size);
+ /**
+ * @brief add a part of the image to display with the requested size
+ * @param[in] _size size of the output image
+ * @param[in] _sourcePosStart Start position in the image [0..1] (can be bigger but this repeate the image).
+ * @param[in] _sourcePosStop Stop position in the image [0..1] (can be bigger but this repeate the image).
+ */
+ void printPart(const vec2& _size,
+ vec2 _sourcePosStart,
+ vec2 _sourcePosStop);
+ /**
+ * @brief change the image Source == > can not be done to display 2 images at the same time ...
+ * @param[in] _uri New file of the Image
+ * @param[in] _size for the image when Verctorial image loading is requested
+ */
+ void setSource(const etk::Uri& _uri, int32_t _size=32) {
+ setSource(_uri, vec2(_size,_size));
+ };
+ void setSource(const etk::Uri& _uri, const vec2& _size);
+ void setSource(egami::Image _image);
+ /**
+ * @brief Sometimes the user declare an image but not allocate the ressources all the time, this is to know it ..
+ * @return the validity od the resources.
+ */
+ bool hasSources();
+ /**
+ * @brief get the source image registered size in the file (<0 when multiple size image)
+ * @return tre image registered size
+ */
+ vec2 getRealSize();
+ public:
+ /**
+ * @brief Set render mode of the image
+ * @param[in] _mode Activation of distance field mode
+ */
+ void setDistanceFieldMode(bool _mode);
+ /**
+ * @brief Get the render methode.
+ * @return The render mode of the image.
+ */
+ bool getDistanceFieldMode() const {
+ return m_distanceFieldMode;
+ }
+ };
+ };
+};
+
diff --git a/src/org/atriasoft/ewol/compositing/Shaper.cpp b/src/org/atriasoft/ewol/compositing/Shaper.cpp
new file mode 100644
index 0000000..cf96f8b
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/Shaper.cpp
@@ -0,0 +1,693 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+#include
+#include
+#include
+ETK_DECLARE_TYPE(ewol::compositing::Shaper);
+
+// VBO table property:
+const int32_t ewol::compositing::Shaper::m_vboIdCoord(0);
+const int32_t ewol::compositing::Shaper::m_vboIdPos(1);
+#define NB_VBO (2)
+
+ewol::compositing::Shaper::Shaper(const etk::Uri& _uri) :
+ m_uri(_uri),
+ m_config(null),
+ m_confIdMode(-1),
+ m_confIdDisplayOutside(-1),
+ m_confIdChangeTime(-1),
+ m_confProgramFile(-1),
+ m_confColorFile(-1),
+ m_confImageFile(-1),
+ m_GLprogram(null),
+ m_GLPosition(-1),
+ m_GLMatrix(-1),
+ m_GLStateActivate(-1),
+ m_GLStateOld(-1),
+ m_GLStateNew(-1),
+ m_GLStateTransition(-1),
+ m_resourceTexture(null),
+ m_nextStatusRequested(-1),
+ m_propertyOrigin(0,0),
+ m_propertySize(0,0),
+ m_propertyInsidePosition(0,0),
+ m_propertyInsideSize(0,0),
+ m_stateActivate(0),
+ m_stateOld(0),
+ m_stateNew(0),
+ m_stateTransition(1.0),
+ m_nbVertexToDisplay(0) {
+ for (size_t iii=0; iiisetName("[VBO] of ewol::compositing::Shaper");
+ loadProgram();
+}
+
+ewol::compositing::Shaper::~Shaper() {
+ unLoadProgram();
+}
+
+void ewol::compositing::Shaper::unLoadProgram() {
+ m_GLprogram.reset();
+ m_resourceTexture.reset();
+ m_config.reset();
+ m_colorProperty.reset();
+ for (size_t iii=0; iiiclear();
+ m_confIdMode = -1;
+ m_confIdDisplayOutside = -1;
+ m_nbVertexToDisplay = 0;
+ m_confIdChangeTime = -1;
+ m_confProgramFile = -1;
+ m_confImageFile = -1;
+ m_listAssiciatedId.clear();
+}
+
+void ewol::compositing::Shaper::loadProgram() {
+ if (m_uri.isEmpty() == true) {
+ EWOL_DEBUG("no Shaper set for loading resources ...");
+ return;
+ }
+ m_config = ewol::resource::ConfigFile::create(m_uri.get());
+ if (m_config != null) {
+ m_confIdMode = m_config->request("mode");
+ m_confIdDisplayOutside = m_config->request("display-outside");
+ m_confIdPaddingOut[shaperPosLeft] = m_config->request("padding-out-left");
+ m_confIdPaddingOut[shaperPosRight] = m_config->request("padding-out-right");
+ m_confIdPaddingOut[shaperPosTop] = m_config->request("padding-out-top");
+ m_confIdPaddingOut[shaperPosButtom] = m_config->request("padding-out-buttom");
+ m_confIdBorder[shaperPosLeft] = m_config->request("border-left");
+ m_confIdBorder[shaperPosRight] = m_config->request("border-right");
+ m_confIdBorder[shaperPosTop] = m_config->request("border-top");
+ m_confIdBorder[shaperPosButtom] = m_config->request("border-buttom");
+ m_confIdPaddingIn[shaperPosLeft] = m_config->request("padding-in-left");
+ m_confIdPaddingIn[shaperPosRight] = m_config->request("padding-in-right");
+ m_confIdPaddingIn[shaperPosTop] = m_config->request("padding-in-top");
+ m_confIdPaddingIn[shaperPosButtom] = m_config->request("padding-in-buttom");
+ m_confIdChangeTime = m_config->request("change-time");
+ m_confProgramFile = m_config->request("program");
+ m_confImageFile = m_config->request("image");
+ m_confColorFile = m_config->request("color");
+ }
+ etk::String basicShaderFile = m_config->getString(m_confProgramFile);
+ if (basicShaderFile != "") {
+ etk::String tmpFilename(basicShaderFile);
+ if (tmpFilename.find(':') == etk::String::npos) {
+ // get the relative position of the current file ...
+ etk::Uri tmpUri = m_uri;
+ tmpUri.setPath(m_uri.getPath().getParent() / basicShaderFile);
+ tmpFilename = tmpUri.get();
+ EWOL_DEBUG("Shaper try load shader : '" << tmpFilename << "' with base : '" << basicShaderFile << "'");
+ } else {
+ EWOL_DEBUG("Shaper try load shader : '" << tmpFilename << "'");
+ }
+ // get the shader resource :
+ m_GLPosition = 0;
+ m_GLprogram = gale::resource::Program::create(tmpFilename);
+ if (m_GLprogram != null) {
+ m_GLPosition = m_GLprogram->getAttribute("EW_coord2d");
+ m_GLMatrix = m_GLprogram->getUniform("EW_MatrixTransformation");
+ // Widget property == > for the Vertex shader
+ m_GLPropertyPos = m_GLprogram->getAttribute("EW_widgetPropertyPos");
+ // status property == > for the fragment shader
+ m_GLStateActivate = m_GLprogram->getUniform("EW_status.activate");
+ m_GLStateOld = m_GLprogram->getUniform("EW_status.stateOld");
+ m_GLStateNew = m_GLprogram->getUniform("EW_status.stateNew");
+ m_GLStateTransition = m_GLprogram->getUniform("EW_status.transition");
+ // for the texture ID :
+ m_GLtexID = m_GLprogram->getUniform("EW_texID");
+ }
+ etk::String basicImageFile = m_config->getString(m_confImageFile);
+ if (basicImageFile != "") {
+ etk::String tmpFilename(basicImageFile);
+ if (tmpFilename.find(':') == etk::String::npos) {
+ // get the relative position of the current file ...
+ etk::Uri tmpUri = m_uri;
+ tmpUri.setPath(m_uri.getPath().getParent() / basicImageFile);
+ tmpFilename = tmpUri.get();
+ EWOL_DEBUG("Shaper try load shaper image : '" << tmpFilename << "' with base : '" << basicImageFile << "'");
+ } else {
+ EWOL_DEBUG("Shaper try load shaper image : '" << tmpFilename << "'");
+ }
+ ivec2 size(64,64);
+ m_resourceTexture = ewol::resource::TextureFile::create(tmpFilename, size);
+ }
+ }
+ etk::String basicColorFile = m_config->getString(m_confColorFile);
+ if (basicColorFile != "") {
+ etk::String tmpFilename(basicColorFile);
+ if (tmpFilename.find(':') == etk::String::npos) {
+ // get the relative position of the current file ...
+ etk::Uri tmpUri = m_uri;
+ tmpUri.setPath(m_uri.getPath().getParent() / basicColorFile);
+ tmpFilename = tmpUri.get();
+ EWOL_DEBUG("Shaper try load colorFile : '" << tmpFilename << "' with base : '" << basicColorFile << "'");
+ } else {
+ EWOL_DEBUG("Shaper try load colorFile : '" << tmpFilename << "'");
+ }
+ m_colorProperty = ewol::resource::ColorFile::create(tmpFilename);
+ if ( m_GLprogram != null
+ && m_colorProperty != null) {
+ etk::Vector listColor = m_colorProperty->getColors();
+ for (auto tmpColor : listColor) {
+ int32_t glId = m_GLprogram->getUniform(tmpColor);
+ int32_t colorID = m_colorProperty->request(tmpColor);
+ m_listAssiciatedId.pushBack(ivec2(glId, colorID));
+ }
+ }
+ }
+}
+
+void ewol::compositing::Shaper::draw(bool _disableDepthTest) {
+ if (m_config == null) {
+ // this is a normale case ... the user can choice to have no config basic file ...
+ return;
+ }
+ if (m_GLprogram == null) {
+ EWOL_ERROR("No shader ...");
+ return;
+ }
+ if (m_VBO->bufferSize(m_vboIdCoord) <= 0) {
+ return;
+ }
+ //glScalef(m_scaling.x, m_scaling.y, 1.0);
+ m_GLprogram->use();
+ // set Matrix : translation/positionMatrix
+ mat4 tmpMatrix = gale::openGL::getMatrix();
+ m_GLprogram->uniformMatrix(m_GLMatrix, tmpMatrix);
+ // position:
+ m_GLprogram->sendAttributePointer(m_GLPosition, m_VBO, m_vboIdCoord);
+ // property
+ m_GLprogram->sendAttributePointer(m_GLPropertyPos, m_VBO, m_vboIdPos);
+ // all entry parameters :
+ m_GLprogram->uniform1i(m_GLStateActivate, m_stateActivate);
+ m_GLprogram->uniform1i(m_GLStateOld, m_stateOld);
+ m_GLprogram->uniform1i(m_GLStateNew, m_stateNew);
+ m_GLprogram->uniform1f(m_GLStateTransition, m_stateTransition);
+ for (auto element : m_listAssiciatedId) {
+ m_GLprogram->uniform(element.x(), m_colorProperty->get(element.y()));
+ }
+ if (m_resourceTexture != null) {
+ // TextureID
+ m_GLprogram->setTexture0(m_GLtexID, m_resourceTexture->getRendererId());
+ }
+ // Request the draw of the elements :
+ //gale::openGL::drawArrays(gale::openGL::renderMode::triangle, 0, SHAPER_NB_MAX_VERTEX);
+ gale::openGL::drawArrays(gale::openGL::renderMode::triangleStrip, 0, m_nbVertexToDisplay);
+ m_GLprogram->unUse();
+}
+
+void ewol::compositing::Shaper::clear() {
+ // nothing to do ...
+ m_propertySize = vec2(0,0);
+ m_propertyOrigin = vec2(0,0);
+ m_propertyInsidePosition = vec2(0,0);
+ m_propertyInsideSize = vec2(0,0);
+ m_VBO->clear();
+}
+
+bool ewol::compositing::Shaper::setState(int32_t _newState) {
+ if (m_stateActivate == _newState) {
+ return false;
+ }
+ m_stateActivate = _newState;
+ return true;
+}
+
+bool ewol::compositing::Shaper::changeStatusIn(int32_t _newStatusId) {
+ if (_newStatusId != m_stateNew) {
+ m_nextStatusRequested = _newStatusId;
+ return true;
+ }
+ if( m_nextStatusRequested != -1
+ || m_stateNew != m_stateOld) {
+ return true;
+ }
+ return false;
+}
+
+bool ewol::compositing::Shaper::periodicCall(const ewol::event::Time& _event) {
+ EWOL_VERBOSE("call=" << _event << "state transition=" << m_stateTransition << " speedTime=" << m_config->getNumber(m_confIdChangeTime));
+ // start :
+ if (m_stateTransition >= 1.0) {
+ m_stateOld = m_stateNew;
+ if( m_nextStatusRequested != -1
+ && m_nextStatusRequested != m_stateOld) {
+ m_stateNew = m_nextStatusRequested;
+ m_nextStatusRequested = -1;
+ m_stateTransition = 0.0;
+ EWOL_VERBOSE(" ##### START ##### ");
+ } else {
+ m_nextStatusRequested = -1;
+ // disable periodic call ...
+ return false;
+ }
+ }
+ if (m_stateTransition<1.0) {
+ // check if no new state requested:
+ if (m_nextStatusRequested != -1 && m_stateTransition<0.5) {
+ // invert sources with destination
+ int32_t tmppp = m_stateOld;
+ m_stateOld = m_stateNew;
+ m_stateNew = tmppp;
+ m_stateTransition = 1.0 - m_stateTransition;
+ if (m_nextStatusRequested == m_stateNew) {
+ m_nextStatusRequested = -1;
+ }
+ }
+ float timeRelativity = 0.0f;
+ if (m_config != null) {
+ timeRelativity = m_config->getNumber(m_confIdChangeTime) / 1000.0;
+ }
+ m_stateTransition += _event.getDeltaCall() / timeRelativity;
+ //m_stateTransition += _event.getDeltaCall();
+ m_stateTransition = etk::avg(0.0f, m_stateTransition, 1.0f);
+ EWOL_VERBOSE("relative=" << timeRelativity << " Transition : " << m_stateTransition);
+ }
+ return true;
+}
+
+//Create Line:
+void ewol::compositing::Shaper::addVertexLine(float _yTop,
+ float _yButtom,
+ float _x1,
+ float _x2,
+ float _x3,
+ float _x4,
+ float _x5,
+ float _x6,
+ float _x7,
+ float _x8,
+ float _yValTop,
+ float _yValButtom,
+ const float* _table,
+ bool _displayOutside) {
+ if (m_nbVertexToDisplay != 0) {
+ // change line ...
+ m_VBO->pushOnBuffer(m_vboIdCoord,
+ m_VBO->getOnBufferVec2(m_vboIdCoord, m_nbVertexToDisplay-1));
+ m_VBO->pushOnBuffer(m_vboIdPos,
+ m_VBO->getOnBufferVec2(m_vboIdPos, m_nbVertexToDisplay-1));
+
+ m_nbVertexToDisplay++;
+ if (_displayOutside == true) {
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x1, _yButtom));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[0],_yValButtom));
+ m_nbVertexToDisplay++;
+ } else {
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x2, _yButtom));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[1],_yValButtom));
+ m_nbVertexToDisplay++;
+ }
+ }
+
+ if (_displayOutside == true) {
+ // A
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x1, _yButtom));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[0],_yValButtom));
+ m_nbVertexToDisplay++;
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x1, _yTop));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[0],_yValTop));
+ m_nbVertexToDisplay++;
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x2, _yButtom));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[1],_yValButtom));
+ m_nbVertexToDisplay++;
+ // B
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x2, _yTop));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[1],_yValTop));
+ m_nbVertexToDisplay++;
+
+ // C
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x3, _yButtom));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[2],_yValButtom));
+ m_nbVertexToDisplay++;
+ } else {
+ // C
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x2, _yButtom));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[1],_yValButtom));
+ m_nbVertexToDisplay++;
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x2, _yTop));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[1],_yValTop));
+ m_nbVertexToDisplay++;
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x3, _yButtom));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[2],_yValButtom));
+ m_nbVertexToDisplay++;
+ }
+ // D
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x3, _yTop));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[2],_yValTop));
+ m_nbVertexToDisplay++;
+
+ // E
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x4, _yButtom));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[3],_yValButtom));
+ m_nbVertexToDisplay++;
+ // F
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x4, _yTop));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[3],_yValTop));
+ m_nbVertexToDisplay++;
+
+ // G
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x5, _yButtom));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[4],_yValButtom));
+ m_nbVertexToDisplay++;
+ // H
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x5, _yTop));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[4],_yValTop));
+ m_nbVertexToDisplay++;
+
+ // I
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x6, _yButtom));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[5],_yValButtom));
+ m_nbVertexToDisplay++;
+ // J
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x6, _yTop));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[5],_yValTop));
+ m_nbVertexToDisplay++;
+
+ // K
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x7, _yButtom));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[6],_yValButtom));
+ m_nbVertexToDisplay++;
+ // L
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x7, _yTop));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[6],_yValTop));
+ m_nbVertexToDisplay++;
+
+ if (_displayOutside == true) {
+ // M
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x8, _yButtom));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[7],_yValButtom));
+ m_nbVertexToDisplay++;
+ // N
+ m_VBO->pushOnBuffer(m_vboIdCoord, vec2(_x8, _yTop));
+ m_VBO->pushOnBuffer(m_vboIdPos, vec2(_table[7],_yValTop));
+ m_nbVertexToDisplay++;
+ }
+}
+const float modeDisplay[][8] = {
+ /* !! 0 !!
+ * / *******
+ * / ****** /
+ * ****** /
+ */
+ { 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f },
+ /* !! 1 !!
+ * ****** \
+ * \ ****** \
+ * \ *******
+ */
+ { 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f },
+ /* !! 2 !!
+ * / ****** \
+ * ****** / \ *******
+ */
+ { 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f },
+ /* !! 3 !!
+ * ****** \ / *******
+ * \ ****** /
+ */
+ { 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f },
+ /* !! 4 !!
+ * / *******
+ * / ****** /
+ * ****** /
+ */
+ { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f },
+ /* !! 5 !!
+ * ****** \
+ * \ ****** \
+ * \ *******
+ */
+ { 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, -1.0f },
+ /* !! 6 !!
+ * / ****** \
+ * ****** / \ *******
+ */
+ { -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f },
+ /* !! 7 !!
+ * ****** \ / *******
+ * \ ****** /
+ */
+ { 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f }
+};
+
+void ewol::compositing::Shaper::setShape(const vec2& _origin, const vec2& _size, const vec2& _insidePos, const vec2& _insideSize) {
+ m_VBO->clear();
+ ewol::Padding borderTmp = getBorder();
+ ewol::Padding paddingIn = getPaddingIn();
+ ewol::Padding paddingOut = getPaddingOut();
+ ewol::Padding padding = paddingIn + borderTmp + paddingOut;
+ ewol::Padding enveloppe(_origin.x(),
+ _origin.y() + _size.y(),
+ _origin.x() + _size.x(),
+ _origin.y());
+ #if 0
+ ewol::Padding inside(_insidePos.x(),
+ _insidePos.y() + _insideSize.y(),
+ _insidePos.x() + _insideSize.x(),
+ _insidePos.y());
+ ewol::Padding insideBorder(inside.xLeft() - paddingIn.xLeft(),
+ inside.yTop() + paddingIn.yTop(),
+ inside.xRight() + paddingIn.xRight(),
+ inside.yButtom() - paddingIn.yButtom());
+ ewol::Padding border(insideBorder.xLeft() - borderTmp.xLeft(),
+ insideBorder.yTop() + borderTmp.yTop(),
+ insideBorder.xRight() + borderTmp.xRight(),
+ insideBorder.yButtom() - borderTmp.yButtom());
+ #else
+ ewol::Padding border(_insidePos.x() - padding.xLeft() + paddingOut.xLeft(),
+ _insidePos.y() + _insideSize.y() + padding.yTop() - paddingOut.yTop(),
+ _insidePos.x() + _insideSize.x() + padding.xRight() - paddingOut.xRight(),
+ _insidePos.y() - padding.yButtom() + paddingOut.yButtom());
+ ewol::Padding insideBorder(border.xLeft() + borderTmp.xLeft(),
+ border.yTop() - borderTmp.yTop(),
+ border.xRight() - borderTmp.xRight(),
+ border.yButtom() + borderTmp.yButtom());
+ ewol::Padding inside(insideBorder.xLeft() + etk::max(0.0f, paddingIn.xLeft()),
+ insideBorder.yTop() - etk::max(0.0f, paddingIn.yTop()),
+ insideBorder.xRight() - etk::max(0.0f, paddingIn.xRight()),
+ insideBorder.yButtom() + etk::max(0.0f, paddingIn.yButtom()));
+
+ #endif
+ /*
+ EWOL_ERROR(" enveloppe = " << enveloppe);
+ EWOL_ERROR(" border = " << border);
+ EWOL_ERROR(" inside = " << inside);
+ */
+ int32_t mode = 0;
+ bool displayOutside = false;
+ if (m_config != null) {
+ mode = m_config->getNumber(m_confIdMode);
+ displayOutside = m_config->getBoolean(m_confIdDisplayOutside);
+ }
+ m_nbVertexToDisplay = 0;
+ if (displayOutside == true) {
+ addVertexLine(enveloppe.yTop(), border.yTop(),
+ enveloppe.xLeft(),
+ border.xLeft(),
+ insideBorder.xLeft(),
+ inside.xLeft(),
+ inside.xRight(),
+ insideBorder.xRight(),
+ border.xRight(),
+ enveloppe.xRight(),
+ modeDisplay[mode][7], modeDisplay[mode][6],
+ modeDisplay[mode],
+ displayOutside);
+ }
+ addVertexLine(border.yTop(), insideBorder.yTop(),
+ enveloppe.xLeft(),
+ border.xLeft(),
+ insideBorder.xLeft(),
+ inside.xLeft(),
+ inside.xRight(),
+ insideBorder.xRight(),
+ border.xRight(),
+ enveloppe.xRight(),
+ modeDisplay[mode][6], modeDisplay[mode][5],
+ modeDisplay[mode],
+ displayOutside);
+ addVertexLine(insideBorder.yTop(), inside.yTop(),
+ enveloppe.xLeft(),
+ border.xLeft(),
+ insideBorder.xLeft(),
+ inside.xLeft(),
+ inside.xRight(),
+ insideBorder.xRight(),
+ border.xRight(),
+ enveloppe.xRight(),
+ modeDisplay[mode][5], modeDisplay[mode][4],
+ modeDisplay[mode],
+ displayOutside);
+ addVertexLine(inside.yTop(), inside.yButtom(),
+ enveloppe.xLeft(),
+ border.xLeft(),
+ insideBorder.xLeft(),
+ inside.xLeft(),
+ inside.xRight(),
+ insideBorder.xRight(),
+ border.xRight(),
+ enveloppe.xRight(),
+ modeDisplay[mode][4], modeDisplay[mode][3],
+ modeDisplay[mode],
+ displayOutside);
+ addVertexLine(inside.yButtom(), insideBorder.yButtom(),
+ enveloppe.xLeft(),
+ border.xLeft(),
+ insideBorder.xLeft(),
+ inside.xLeft(),
+ inside.xRight(),
+ insideBorder.xRight(),
+ border.xRight(),
+ enveloppe.xRight(),
+ modeDisplay[mode][3], modeDisplay[mode][2],
+ modeDisplay[mode],
+ displayOutside);
+ addVertexLine(insideBorder.yButtom(), border.yButtom(),
+ enveloppe.xLeft(),
+ border.xLeft(),
+ insideBorder.xLeft(),
+ inside.xLeft(),
+ inside.xRight(),
+ insideBorder.xRight(),
+ border.xRight(),
+ enveloppe.xRight(),
+ modeDisplay[mode][2], modeDisplay[mode][1],
+ modeDisplay[mode],
+ displayOutside);
+ if (displayOutside == true) {
+ addVertexLine(border.yButtom(), enveloppe.yButtom(),
+ enveloppe.xLeft(),
+ border.xLeft(),
+ insideBorder.xLeft(),
+ inside.xLeft(),
+ inside.xRight(),
+ insideBorder.xRight(),
+ border.xRight(),
+ enveloppe.xRight(),
+ modeDisplay[mode][1], modeDisplay[mode][0],
+ modeDisplay[mode],
+ displayOutside);
+ }
+ m_VBO->flush();
+}
+
+ewol::Padding ewol::compositing::Shaper::getPadding() {
+ return getPaddingOut() + getBorder() + getPaddingIn();
+}
+
+ewol::Padding ewol::compositing::Shaper::getPaddingIn() {
+ ewol::Padding padding(0,0,0,0);
+ if (m_config != null) {
+ padding.setValue(m_config->getNumber(m_confIdPaddingIn[shaperPosLeft]),
+ m_config->getNumber(m_confIdPaddingIn[shaperPosTop]),
+ m_config->getNumber(m_confIdPaddingIn[shaperPosRight]),
+ m_config->getNumber(m_confIdPaddingIn[shaperPosButtom]));
+ }
+ return padding;
+}
+
+ewol::Padding ewol::compositing::Shaper::getPaddingOut() {
+ ewol::Padding padding(0,0,0,0);
+ if (m_config != null) {
+ padding.setValue(m_config->getNumber(m_confIdPaddingOut[shaperPosLeft]),
+ m_config->getNumber(m_confIdPaddingOut[shaperPosTop]),
+ m_config->getNumber(m_confIdPaddingOut[shaperPosRight]),
+ m_config->getNumber(m_confIdPaddingOut[shaperPosButtom]));
+ }
+ return padding;
+}
+
+ewol::Padding ewol::compositing::Shaper::getBorder() {
+ ewol::Padding padding(0,0,0,0);
+ if (m_config != null) {
+ padding.setValue(m_config->getNumber(m_confIdBorder[shaperPosLeft]),
+ m_config->getNumber(m_confIdBorder[shaperPosTop]),
+ m_config->getNumber(m_confIdBorder[shaperPosRight]),
+ m_config->getNumber(m_confIdBorder[shaperPosButtom]));
+ }
+ return padding;
+}
+
+void ewol::compositing::Shaper::setSource(const etk::Uri& _uri) {
+ clear();
+ unLoadProgram();
+ m_uri = _uri;
+ loadProgram();
+}
+
+bool ewol::compositing::Shaper::hasSources() {
+ return m_GLprogram != null;
+}
+
+
+const etk::Color& ewol::compositing::Shaper::getColor(int32_t _id) {
+ static const etk::Color errorValue(0,0,0,0);
+ if (m_colorProperty == null) {
+ EWOL_WARNING("null of m_colorProperty ==> return #0000 for id " << _id);
+ return errorValue;
+ }
+ return m_colorProperty->get(_id);
+}
+
+int32_t ewol::compositing::Shaper::requestColor(const etk::String& _name) {
+ if (m_colorProperty == null) {
+ EWOL_WARNING("null of m_colorProperty ==> return -1 for name " << _name);
+ return -1;
+ }
+ return m_colorProperty->request(_name);
+}
+
+int32_t ewol::compositing::Shaper::requestConfig(const etk::String& _name) {
+ if (m_config == null) {
+ EWOL_WARNING("null of m_config ==> return -1 for name " << _name);
+ return -1;
+ }
+ return m_config->request(_name);
+}
+
+double ewol::compositing::Shaper::getConfigNumber(int32_t _id) {
+ if ( _id == -1
+ || m_config == null) {
+ EWOL_WARNING("null of m_config ==> return 0.0 for id " << _id);
+ return 0.0;
+ }
+ return m_config->getNumber(_id);
+}
+
+
+namespace etk {
+ template<> etk::String toString(const ewol::compositing::Shaper& _obj) {
+ return _obj.getSource().get();
+ }
+ template<> etk::UString toUString(const ewol::compositing::Shaper& _obj) {
+ return etk::toUString(etk::toString(_obj));
+ }
+ template<> bool from_string(ewol::compositing::Shaper& _variableRet, const etk::String& _value) {
+ _variableRet.setSource(_value);
+ return true;
+ }
+ template<> bool from_string(ewol::compositing::Shaper& _variableRet, const etk::UString& _value) {
+ return from_string(_variableRet, etk::toString(_value));
+ }
+};
\ No newline at end of file
diff --git a/src/org/atriasoft/ewol/compositing/Shaper.java b/src/org/atriasoft/ewol/compositing/Shaper.java
new file mode 100644
index 0000000..db86d64
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/Shaper.java
@@ -0,0 +1,296 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace ewol {
+ namespace compositing {
+ enum renderMode {
+ renderSingleSquare, //!< basic historic render mode
+ renderBorder, //!< Render 4 squares for coiner, and renctangle for border, a big rentangle for background and 8 rectangle for the outside part
+ renderOneBorder,
+ };
+ #define SHAPER_NB_MAX_QUAD (5*5)
+ #define SHAPER_NB_MAX_TRIANGLE (SHAPER_NB_MAX_QUAD*2)
+ #define SHAPER_NB_MAX_VERTEX (SHAPER_NB_MAX_TRIANGLE*3)
+ enum shaperPos {
+ shaperPosLeft,
+ shaperPosRight,
+ shaperPosTop,
+ shaperPosButtom,
+ shaperPosCount,
+ };
+ /**
+ * @brief the Shaper system is a basic theme configuration for every widget, it corespond at a background display described by a pool of files
+ */
+ // TODO : load image
+ // TODO : Abstaraction between states (call by name and the system greate IDs
+ class Shaper : public ewol::Compositing {
+ private:
+ etk::Uri m_uri; //!< Name of the configuration of the shaper.
+ // External theme config:
+ ememory::SharedPtr m_config; //!< pointer on the config file resources
+ int32_t m_confIdPaddingOut[shaperPosCount]; //!< Padding out property : X-left X-right Y-top Y-buttom
+ int32_t m_confIdBorder[shaperPosCount]; //!< border property : X-left X-right Y-top Y-buttom
+ int32_t m_confIdPaddingIn[shaperPosCount]; //!< Padding in property : X-left X-right Y-top Y-buttom
+ int32_t m_confIdMode; //!< Display mode
+ int32_t m_confIdDisplayOutside; //!< Display outside of the shape...
+ int32_t m_confIdChangeTime; //!< ConfigFile padding transition time property
+ int32_t m_confProgramFile; //!< ConfigFile opengGl program Name
+ int32_t m_confColorFile; //!< ConfigFile opengGl color file Name
+ int32_t m_confImageFile; //!< ConfigFile opengGl program Name
+ // openGL shaders programs:
+ ememory::SharedPtr m_GLprogram; //!< pointer on the opengl display program
+ 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_GLPropertyPos; //!< openGL id on the element (simple ratio position in the widget : ____/-----\_____ on vec2(X,Y))
+ int32_t m_GLStateActivate; //!< openGL id on the element (activate state displayed)
+ int32_t m_GLStateOld; //!< openGL id on the element (old state displayed)
+ int32_t m_GLStateNew; //!< openGL id on the element (new state displayed)
+ int32_t m_GLStateTransition; //!< openGL id on the element (transition ofset [0.0..1.0] )
+ int32_t m_GLtexID; //!< openGL id on the element (texture image)
+ // For the Image :
+ ememory::SharedPtr m_resourceTexture; //!< texture resources (for the image)
+ // internal needed data :
+ int32_t m_nextStatusRequested; //!< when status is changing, this represent the next step of it
+ vec2 m_propertyOrigin; //!< widget origin
+ vec2 m_propertySize; //!< widget size
+ vec2 m_propertyInsidePosition; //!< internal subwidget position
+ vec2 m_propertyInsideSize; //!< internal subwidget size
+ int32_t m_stateActivate; //!< Activate state of the element
+ int32_t m_stateOld; //!< previous state
+ int32_t m_stateNew; //!< destination state
+ float m_stateTransition; //!< working state between 2 states
+ int32_t m_nbVertexToDisplay;
+ // color management theme:
+ ememory::SharedPtr m_colorProperty; //!< input resource for color management
+ etk::Vector m_listAssiciatedId; //!< Corellation ID between ColorProperty (Y) and OpenGL Program (X)
+ protected:
+ static const int32_t m_vboIdCoord;
+ static const int32_t m_vboIdPos;
+ ememory::SharedPtr m_VBO;
+ private:
+ /**
+ * @brief load the openGL program and get all the ID needed
+ */
+ void loadProgram();
+ /**
+ * @brief Un-Load the openGL program and get all the ID needed
+ */
+ void unLoadProgram();
+ public:
+ /**
+ * @brief generic constructor
+ * @param[in] _uri URI of the file that might be loaded
+ */
+ Shaper(const etk::Uri& _uri="");
+ /**
+ * @brief generic destructor
+ */
+ virtual ~Shaper();
+ public:
+ /**
+ * @brief draw All the refistered text in the current element on openGL
+ */
+ void draw(bool _disableDepthTest=true);
+ /**
+ * @brief clear alll tre registered element in the current element
+ */
+ void clear();
+ /**
+ * @brief Change the current state
+ * @param[in] _newState Current state of the configuration
+ * @return true Need redraw.
+ * @return false No need redraw.
+ */
+ bool setState(int32_t _newState);
+ /**
+ * @brief change the current status in an other
+ * @param[in] _newStatusId the next new status requested
+ * @return true The widget must call this fuction periodicly (and redraw itself)
+ * @return false No need to request the periodic call.
+ */
+ bool changeStatusIn(int32_t _newStatusId);
+ /**
+ * @brief get the current displayed status of the shaper
+ * @return The Status Id
+ */
+ int32_t getCurrentDisplayedStatus() {
+ return m_stateNew;
+ };
+ /**
+ * @brief get the next displayed status of the shaper
+ * @return The next status Id (-1 if no status in next)
+ */
+ int32_t getNextDisplayedStatus() {
+ return m_nextStatusRequested;
+ };
+ /**
+ * @brief get the current trasion status
+ * @return value of the transition status (0.0f when no activity)
+ */
+ float getTransitionStatus() {
+ return m_stateTransition;
+ };
+ /**
+ * @brief Same as the widfget periodic call (this is for change display)
+ * @param[in] _event The current time of the call.
+ * @return true The widget must call this fuction periodicly (and redraw itself)
+ * @return false No need to request the periodic call.
+ */
+ bool periodicCall(const ewol::event::Time& _event);
+ /**
+ * @brief get the padding declared by the user in the config file
+ * @return the padding property
+ */
+ ewol::Padding getPadding();
+ ewol::Padding getPaddingIn();
+ ewol::Padding getPaddingOut();
+ /**
+ * @brief get the padding declared by the user in the config file
+ * @return the padding property
+ */
+ ewol::Padding getBorder();
+ /**
+ * @brief change the shaper Source
+ * @param[in] _uri New file of the shaper
+ */
+ void setSource(const etk::Uri& _uri);
+ /**
+ * @brief get the shaper file Source
+ * @return the shapper file name
+ */
+ const etk::Uri& getSource() const {
+ return m_uri;
+ };
+ /**
+ * @brief Sometimes the user declare an image but not allocate the ressources all the time, this is to know it ..
+ * @return the validity od the resources.
+ */
+ bool hasSources();
+ public:
+ /**
+ * @brief set the shape property:
+ *
+ * ********************************************************************************
+ * * _size *
+ * * *
+ * * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *
+ * * *
+ * * | | *
+ * * *************************************************** *
+ * * | * * | *
+ * * * * *
+ * * | * * - - - - - - - - - - - - - - - - - - * * | *
+ * * * _insideSize * *
+ * * | * | | * | *
+ * * * * *
+ * * | * | | * | *
+ * * * * *
+ * * | * | | * | *
+ * * * * *
+ * * | * | | * | *
+ * * * * *
+ * * | * | | * | *
+ * * * * *
+ * * | * | | * | *
+ * * * _insidePos * *
+ * * | * * - - - - - - - - - - - - - - - - - - * * | *
+ * * * * *
+ * * | *************************************************** | *
+ * * *
+ * * | | *
+ * * *
+ * * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *
+ * * *
+ * * *
+ * ********************************************************************************
+ * _origin
+ *
+ *
+ * @param[in] _origin Origin of the display
+ * @param[in] _size Size of the display
+ * @param[in] _insidePos Positin of the internal data
+ * @param[in] _insideSize Size of the internal data
+ */
+ void setShape(const vec2& _origin, const vec2& _size, const vec2& _insidePos, const vec2& _insideSize);
+ // @previous
+ void setShape(const vec2& _origin, const vec2& _size) {
+ ewol::Padding tmp = getPadding();
+ setShape(_origin, _size, _origin+vec2(tmp.xLeft(), tmp.yButtom()), _size - vec2(tmp.x(), tmp.y()));
+ }
+ public:
+ /**
+ * @brief Get an ID on the color instance element
+ * @param[in] _name Name of the element requested
+ * @return The Id of the color
+ */
+ int32_t requestColor(const etk::String& _name);
+ /**
+ * @brief Get The color associated at an ID.
+ * @param[in] _id Id of the color
+ * @return the reference on the color
+ */
+ const etk::Color& getColor(int32_t _id);
+ public:
+ /**
+ * @brief Get an ID on the configuration instance element
+ * @param[in] _name Name of the element requested
+ * @return The Id of the element
+ */
+ int32_t requestConfig(const etk::String& _name);
+ /**
+ * @brief Get The number associated at an ID.
+ * @param[in] _id Id of the parameter
+ * @return the requested number.
+ */
+ double getConfigNumber(int32_t _id);
+ public:
+ /**
+ * @brief Set activate state of the element
+ * @param[in] _status New activate status
+ */
+ void setActivateState(int32_t _status) {
+ m_stateActivate = _status;
+ }
+ private:
+ void addVertexLine(float _yTop,
+ float _yButtom,
+ float _x1,
+ float _x2,
+ float _x3,
+ float _x4,
+ float _x5,
+ float _x6,
+ float _x7,
+ float _x8,
+ float _yValTop,
+ float _yValButtom,
+ const float* _table,
+ bool _displayOutside);
+ public:
+ /* ****************************************************
+ * == operator
+ *****************************************************/
+ bool operator== (const Shaper& _obj) const {
+ return _obj.m_uri == m_uri;
+ }
+ bool operator!= (const Shaper& _obj) const {
+ return _obj.m_uri != m_uri;
+ }
+ };
+ }
+}
+
+
diff --git a/src/org/atriasoft/ewol/compositing/Sprite.cpp b/src/org/atriasoft/ewol/compositing/Sprite.cpp
new file mode 100644
index 0000000..16a5b97
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/Sprite.cpp
@@ -0,0 +1,39 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+#include
+
+#include
+ETK_DECLARE_TYPE(ewol::compositing::Sprite);
+
+ewol::compositing::Sprite::Sprite(const etk::String& _imageName, const ivec2& _nbSprite, int32_t _size) :
+ ewol::compositing::Image(_imageName, false, _size),
+ m_nbSprite(_nbSprite),
+ m_unitarySpriteSize(0,0) {
+ /*
+ vec2 imageSize = getRealSize();
+ m_unitarySpriteSize.setValue(imageSize.x()/(float)m_nbSprite.x(),
+ imageSize.y()/(float)m_nbSprite.y());
+ */
+ m_unitarySpriteSize.setValue(1.0/(float)m_nbSprite.x(),
+ 1.0/(float)m_nbSprite.y());
+}
+
+
+void ewol::compositing::Sprite::printSprite(const ivec2& _spriteID, const vec3& _size) {
+ if( _spriteID.x()<0
+ || _spriteID.y()<0
+ || _spriteID.x() >= m_nbSprite.x()
+ || _spriteID.y() >= m_nbSprite.y()) {
+ return;
+ }
+ printPart(vec2(_size.x(),_size.y()),
+ vec2((float)(_spriteID.x() )*m_unitarySpriteSize.x(), (float)(_spriteID.y() )*m_unitarySpriteSize.y()),
+ vec2((float)(_spriteID.x()+1)*m_unitarySpriteSize.x(), (float)(_spriteID.y()+1)*m_unitarySpriteSize.y()));
+}
+
+
diff --git a/src/org/atriasoft/ewol/compositing/Sprite.java b/src/org/atriasoft/ewol/compositing/Sprite.java
new file mode 100644
index 0000000..d2b5231
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/Sprite.java
@@ -0,0 +1,29 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+
+#include
+#include
+
+namespace ewol {
+ namespace compositing {
+ class Sprite : public ewol::compositing::Image {
+ protected:
+ ivec2 m_nbSprite; //!< number of sprite in vertical and horizontal
+ vec2 m_unitarySpriteSize; //!< size of a unique sprite
+ public:
+ Sprite(const etk::String& _imageName,
+ const ivec2& _nbSprite,
+ int32_t _size=ewol::compositing::Image::sizeAuto);
+ virtual ~Sprite() {};
+ void printSprite(const ivec2& _spriteID, const vec2& _size) {
+ printSprite(_spriteID, vec3(_size.x(), _size.y(),0));
+ };
+ void printSprite(const ivec2& _spriteID, const vec3& _size);
+ };
+ }
+}
+
diff --git a/src/org/atriasoft/ewol/compositing/Text.cpp b/src/org/atriasoft/ewol/compositing/Text.cpp
new file mode 100644
index 0000000..0b912e5
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/Text.cpp
@@ -0,0 +1,372 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+ETK_DECLARE_TYPE(ewol::compositing::Text);
+
+ewol::compositing::Text::Text(const etk::String& _fontName, int32_t _fontSize) :
+ m_font(null) {
+ setFont(_fontName, _fontSize);
+}
+
+ewol::compositing::Text::~Text() {
+
+}
+
+void ewol::compositing::Text::drawMT(const mat4& _transformationMatrix, bool _enableDepthTest) {
+
+ // draw BG in any case:
+ m_vectorialDraw.draw();
+
+ if ( m_VBO->bufferSize(m_vboIdCoord) <= 0
+ || m_font == null) {
+ // TODO : set it back ...
+ //EWOL_WARNING("Nothink to draw...");
+ return;
+ }
+ if (m_font == null) {
+ EWOL_WARNING("no font...");
+ return;
+ }
+ if (m_GLprogram == null) {
+ EWOL_ERROR("No shader ...");
+ return;
+ }
+ if (_enableDepthTest == true) {
+ gale::openGL::enable(gale::openGL::flag_depthTest);
+ }
+ // set Matrix : translation/positionMatrix
+ mat4 projMatrix = gale::openGL::getMatrix();
+ mat4 camMatrix = gale::openGL::getCameraMatrix();
+ mat4 tmpMatrix = projMatrix * camMatrix * _transformationMatrix;
+ m_GLprogram->use();
+ m_GLprogram->uniformMatrix(m_GLMatrix, tmpMatrix);
+ // Texture:
+ m_GLprogram->setTexture0(m_GLtexID, m_font->getRendererId());
+ m_GLprogram->uniform1i(m_GLtextWidth, m_font->getOpenGlSize().x());
+ m_GLprogram->uniform1i(m_GLtextHeight, m_font->getOpenGlSize().x());
+ // position:
+ m_GLprogram->sendAttributePointer(m_GLPosition, m_VBO, m_vboIdCoord);
+ // Texture:
+ m_GLprogram->sendAttributePointer(m_GLtexture, m_VBO, m_vboIdCoordText);
+ // color:
+ m_GLprogram->sendAttributePointer(m_GLColor, m_VBO, m_vboIdColor);
+ // Request the draw od the elements:
+ gale::openGL::drawArrays(gale::openGL::renderMode::triangle, 0, m_VBO->bufferSize(m_vboIdCoord));
+ m_GLprogram->unUse();
+ if (_enableDepthTest == true) {
+ gale::openGL::disable(gale::openGL::flag_depthTest);
+ }
+}
+
+void ewol::compositing::Text::drawD(bool _disableDepthTest) {
+ // draw BG in any case:
+ m_vectorialDraw.draw(_disableDepthTest);
+
+ if ( m_VBO->bufferSize(m_vboIdCoord) <= 0
+ || m_font == null) {
+ //EWOL_WARNING("Nothink to draw...");
+ return;
+ }
+ if (m_font == null) {
+ EWOL_WARNING("no font...");
+ return;
+ }
+ if (m_GLprogram == null) {
+ EWOL_ERROR("No shader ...");
+ return;
+ }
+ // set Matrix : translation/positionMatrix
+ mat4 tmpMatrix = gale::openGL::getMatrix()*m_matrixApply;
+ m_GLprogram->use();
+ m_GLprogram->uniformMatrix(m_GLMatrix, tmpMatrix);
+ // Texture :
+ m_GLprogram->setTexture0(m_GLtexID, m_font->getRendererId());
+ m_GLprogram->uniform1i(m_GLtextWidth, m_font->getOpenGlSize().x());
+ m_GLprogram->uniform1i(m_GLtextHeight, m_font->getOpenGlSize().x());
+ // position:
+ m_GLprogram->sendAttributePointer(m_GLPosition, m_VBO, m_vboIdCoord);
+ // Texture:
+ m_GLprogram->sendAttributePointer(m_GLtexture, m_VBO, m_vboIdCoordText);
+ // color:
+ m_GLprogram->sendAttributePointer(m_GLColor, m_VBO, m_vboIdColor);
+ // Request the draw od the elements :
+ gale::openGL::drawArrays(gale::openGL::renderMode::triangle, 0, m_VBO->bufferSize(m_vboIdCoord));
+ m_GLprogram->unUse();
+}
+
+float ewol::compositing::Text::getSize() {
+ if (m_font == null) {
+ EWOL_WARNING("no font...");
+ return 1.0f;
+ }
+ return m_font->getFontSize();
+}
+float ewol::compositing::Text::getHeight() {
+ if (m_font == null) {
+ EWOL_WARNING("no font...");
+ return 10.0f;
+ }
+ return m_font->getHeight(m_mode);
+}
+ewol::GlyphProperty * ewol::compositing::Text::getGlyphPointer(char32_t _charcode) {
+ if (m_font == null) {
+ EWOL_WARNING("no font...");
+ return null;
+ }
+ return m_font->getGlyphPointer(_charcode, m_mode);
+}
+
+void ewol::compositing::Text::setFontSize(int32_t _fontSize) {
+ // get old size
+ etk::String fontName = "";
+ if (m_font != null) {
+ fontName = m_font->getName();
+ // Remove the :XX for the size ...
+ size_t pos = fontName.rfind(':');
+ fontName.erase(pos, fontName.size()-pos);
+ }
+ setFont(fontName, _fontSize);
+}
+
+void ewol::compositing::Text::setFontName(const etk::String& _fontName) {
+ // get old size
+ int32_t fontSize = -1;
+ if (m_font != null) {
+ fontSize = m_font->getFontSize();
+ }
+ setFont(_fontName, fontSize);
+}
+
+void ewol::compositing::Text::setFont(etk::String _fontName, int32_t _fontSize) {
+ clear();
+ // remove old one
+ ememory::SharedPtr previousFont = m_font;
+ if (_fontSize <= 0) {
+ _fontSize = ewol::getContext().getFontDefault().getSize();
+ }
+ if (_fontName == "") {
+ _fontName = ewol::getContext().getFontDefault().getName();
+ }
+ _fontName += ":";
+ _fontName += etk::toString(_fontSize);
+ EWOL_VERBOSE("plop : " << _fontName << " size=" << _fontSize << " result :" << _fontName);
+ // link to new one
+ m_font = ewol::resource::TexturedFont::create(_fontName);
+ if (m_font == null) {
+ EWOL_ERROR("Can not get font resource");
+ m_font = previousFont;
+ }
+}
+
+void ewol::compositing::Text::setFontMode(enum ewol::font::mode _mode) {
+ if (m_font != null) {
+ m_mode = m_font->getWrappingMode(_mode);
+ }
+}
+
+void ewol::compositing::Text::printChar(const char32_t& _charcode) {
+ // get a pointer on the glyph property :
+ ewol::GlyphProperty* myGlyph = getGlyphPointer(_charcode);
+ if (null == myGlyph) {
+ EWOL_ERROR(" font does not really existed ...");
+ return;
+ }
+ int32_t fontSize = getSize();
+ int32_t fontHeigh = getHeight();
+
+ // get the kerning ofset :
+ float kerningOffset = 0;
+ if (m_kerning == true) {
+ kerningOffset = myGlyph->kerningGet(m_previousCharcode);
+ if (kerningOffset != 0) {
+ //EWOL_DEBUG("Kerning between : '" << m_previousCharcode << "'&'" << myGlyph->m_UVal << "' value : " << kerningOffset);
+ }
+ }
+ // 0x01 == 0x20 == ' ';
+ if (_charcode != 0x01) {
+ /* Bitmap position
+ * xA xB
+ * yC *------*
+ * | |
+ * | |
+ * yD *------*
+ */
+ float dxA = m_position.x() + myGlyph->m_bearing.x() + kerningOffset;
+ float dxB = dxA + myGlyph->m_sizeTexture.x();
+ float dyC = m_position.y() + myGlyph->m_bearing.y() + fontHeigh - fontSize;
+ float dyD = dyC - myGlyph->m_sizeTexture.y();
+
+ float tuA = myGlyph->m_texturePosStart.x();
+ float tuB = tuA + myGlyph->m_texturePosSize.x();
+ float tvC = myGlyph->m_texturePosStart.y();
+ float tvD = tvC + myGlyph->m_texturePosSize.y();
+
+
+ // Clipping and drawing area
+ if( m_clippingEnable == true
+ && ( dxB < m_clippingPosStart.x()
+ || dxA > m_clippingPosStop.x()
+ || dyC < m_clippingPosStart.y()
+ || dyD > m_clippingPosStop.y() ) ) {
+ // Nothing to diplay ...
+ } else {
+ if (m_clippingEnable == true) {
+ // generata positions...
+ float TexSizeX = tuB - tuA;
+ if (dxA < m_clippingPosStart.x()) {
+ // clip display
+ float drawSize = m_clippingPosStart.x() - dxA;
+ // update element start display
+ dxA = m_clippingPosStart.x();
+ float addElement = TexSizeX * drawSize / (float)myGlyph->m_sizeTexture.x();
+ // update texture start X Pos
+ tuA += addElement;
+ }
+ if (dxB > m_clippingPosStop.x()) {
+ // clip display
+ float drawSize = dxB - m_clippingPosStop.x();
+ // update element start display
+ dxB = m_clippingPosStop.x();
+ float addElement = TexSizeX * drawSize / (float)myGlyph->m_sizeTexture.x();
+ // update texture start X Pos
+ tuB -= addElement;
+ }
+ float TexSizeY = tvC - tvD;
+ if (dyC > m_clippingPosStop.y()) {
+ // clip display
+ float drawSize = dyC - m_clippingPosStop.y();
+ // update element start display
+ dyC = m_clippingPosStop.y();
+ float addElement = TexSizeY * drawSize / (float)myGlyph->m_sizeTexture.y();
+ // update texture start X Pos
+ tvC -= addElement;
+ }
+ if (dyD < m_clippingPosStart.y()) {
+ // clip display
+ float drawSize = m_clippingPosStart.y() - dyD;
+ // update element start display
+ dyD = m_clippingPosStart.y();
+ float addElement = TexSizeY * drawSize / (float)myGlyph->m_sizeTexture.y();
+ // update texture start X Pos
+ tvD += addElement;
+ }
+ }
+ if( dxB <= dxA
+ || dyD >= dyC) {
+ // nothing to do ...
+ } else {
+ /* Bitmap position
+ * 0------1
+ * | |
+ * | |
+ * 3------2
+ */
+ if (m_needDisplay == true) {
+ vec3 bitmapDrawPos[4];
+ bitmapDrawPos[0].setValue((int32_t)dxA, (int32_t)dyC, 0);
+ bitmapDrawPos[1].setValue((int32_t)dxB, (int32_t)dyC, 0);
+ bitmapDrawPos[2].setValue((int32_t)dxB, (int32_t)dyD, 0);
+ bitmapDrawPos[3].setValue((int32_t)dxA, (int32_t)dyD, 0);
+ /* texture Position :
+ * 0------1
+ * | |
+ * | |
+ * 3------2
+ */
+ vec2 texturePos[4];
+ texturePos[0].setValue(tuA+m_mode, tvC);
+ texturePos[1].setValue(tuB+m_mode, tvC);
+ texturePos[2].setValue(tuB+m_mode, tvD);
+ texturePos[3].setValue(tuA+m_mode, tvD);
+
+ // NOTE : Android does not support the Quads elements ...
+ /* Step 1 :
+ * ********
+ * ******
+ * ****
+ * **
+ *
+ */
+ // set texture coordonates :
+ m_VBO->pushOnBuffer(m_vboIdCoordText, texturePos[0]);
+ m_VBO->pushOnBuffer(m_vboIdCoordText, texturePos[1]);
+ m_VBO->pushOnBuffer(m_vboIdCoordText, texturePos[2]);
+ // set display positions :
+ m_VBO->pushOnBuffer(m_vboIdCoord, bitmapDrawPos[0]);
+ m_VBO->pushOnBuffer(m_vboIdCoord, bitmapDrawPos[1]);
+ m_VBO->pushOnBuffer(m_vboIdCoord, bitmapDrawPos[2]);
+ // set the color
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ /* Step 2 :
+ *
+ * **
+ * ****
+ * ******
+ * ********
+ */
+ // set texture coordonates :
+ m_VBO->pushOnBuffer(m_vboIdCoordText, texturePos[0]);
+ m_VBO->pushOnBuffer(m_vboIdCoordText, texturePos[2]);
+ m_VBO->pushOnBuffer(m_vboIdCoordText, texturePos[3]);
+ // set display positions :
+ m_VBO->pushOnBuffer(m_vboIdCoord, bitmapDrawPos[0]);
+ m_VBO->pushOnBuffer(m_vboIdCoord, bitmapDrawPos[2]);
+ m_VBO->pushOnBuffer(m_vboIdCoord, bitmapDrawPos[3]);
+ // set the color
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ }
+ }
+ }
+ }
+ // move the position :
+ //EWOL_DEBUG(" 5 pos=" << m_position << " advance=" << myGlyph->m_advance.x() << " kerningOffset=" << kerningOffset);
+ m_position.setX(m_position.x() + myGlyph->m_advance.x() + kerningOffset);
+ //EWOL_DEBUG(" 6 print '" << charcode << "' : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position);
+ // Register the previous character
+ m_previousCharcode = _charcode;
+ m_VBO->flush();
+ return;
+}
+
+
+vec3 ewol::compositing::Text::calculateSizeChar(const char32_t& _charcode) {
+ // get a pointer on the glyph property :
+ ewol::GlyphProperty * myGlyph = getGlyphPointer(_charcode);
+ int32_t fontHeigh = getHeight();
+ if (myGlyph == null) {
+ if (m_font == null) {
+ EWOL_WARNING("no Glyph... in no font");
+ } else {
+ EWOL_WARNING("no Glyph... in font : " << m_font->getName());
+ }
+ return vec3((float)(0.2),
+ (float)(fontHeigh),
+ (float)(0.0));
+ }
+ // get the kerning ofset :
+ float kerningOffset = 0.0;
+ if (m_kerning == true) {
+ kerningOffset = myGlyph->kerningGet(m_previousCharcode);
+ }
+
+ vec3 outputSize((float)(myGlyph->m_advance.x() + kerningOffset),
+ (float)(fontHeigh),
+ (float)(0.0));
+ // Register the previous character
+ m_previousCharcode = _charcode;
+ return outputSize;
+}
+
diff --git a/src/org/atriasoft/ewol/compositing/Text.java b/src/org/atriasoft/ewol/compositing/Text.java
new file mode 100644
index 0000000..8e9d3ac
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/Text.java
@@ -0,0 +1,56 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+namespace ewol {
+ namespace compositing {
+ class Text : public ewol::compositing::TextBase {
+ protected:
+ ememory::SharedPtr m_font; //!< Font resources
+ public:
+ /**
+ * @brief generic constructor
+ * @param[in] _fontName Name of the font that might be loaded
+ * @param[in] _fontSize size of the font that might be loaded
+ */
+ Text(const etk::String& _fontName="", int32_t _fontSize=-1);
+ /**
+ * @brief generic destructor
+ */
+ virtual ~Text();
+ public:
+ virtual void drawD(bool _disableDepthTest);
+ virtual void drawMT(const mat4& _transformationMatrix, bool _enableDepthTest);
+ protected:
+ float m_size;
+ public:
+ virtual float getHeight();
+ virtual float getSize();
+ virtual ewol::GlyphProperty * getGlyphPointer(char32_t _charcode);
+
+ public:
+ virtual void setFontSize(int32_t _fontSize);
+ virtual void setFontName(const etk::String& _fontName);
+ virtual void setFont(etk::String _fontName, int32_t _fontSize);
+ virtual void setFontMode(enum ewol::font::mode _mode);
+ virtual void printChar(const char32_t& _charcode);
+ virtual vec3 calculateSizeChar(const char32_t& _charcode);
+ };
+ }
+}
+
diff --git a/src/org/atriasoft/ewol/compositing/TextBase.cpp b/src/org/atriasoft/ewol/compositing/TextBase.cpp
new file mode 100644
index 0000000..1869c9e
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/TextBase.cpp
@@ -0,0 +1,1116 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+ETK_DECLARE_TYPE(ewol::compositing::TextBase);
+
+const int32_t ewol::compositing::TextBase::m_vboIdCoord(0);
+const int32_t ewol::compositing::TextBase::m_vboIdCoordText(1);
+const int32_t ewol::compositing::TextBase::m_vboIdColor(2);
+const int32_t ewol::compositing::TextBase::m_vboIdGlyphLevel(3);
+#define NB_VBO (4)
+
+ewol::compositing::TextBase::TextBase(const etk::String& _shaderName, bool _loadProgram) :
+ m_position(0.0, 0.0, 0.0),
+ m_clippingPosStart(0.0, 0.0, 0.0),
+ m_clippingPosStop(0.0, 0.0, 0.0),
+ m_clippingEnable(false),
+ m_defaultColorFg(etk::color::black),
+ m_defaultColorBg(etk::color::none),
+ m_color(etk::color::black),
+ m_colorBg(etk::color::none),
+ m_colorCursor(etk::color::black),
+ m_colorSelection(etk::color::olive),
+ m_mode(ewol::font::Regular),
+ m_kerning(true),
+ m_previousCharcode(0),
+ m_startTextpos(0),
+ m_stopTextPos(0),
+ m_alignement(alignDisable),
+ m_GLprogram(null),
+ m_GLPosition(-1),
+ m_GLMatrix(-1),
+ m_GLColor(-1),
+ m_GLtexture(-1),
+ m_GLtexID(-1),
+ m_selectionStartPos(-100),
+ m_cursorPos(-100) {
+ if (_loadProgram == true) {
+ loadProgram(_shaderName);
+ }
+ // Create the VBO:
+ m_VBO = gale::resource::VirtualBufferObject::create(NB_VBO);
+ if (m_VBO == null) {
+ EWOL_ERROR("can not instanciate VBO ...");
+ return;
+ }
+ // TO facilitate some debugs we add a name of the VBO:
+ m_VBO->setName("[VBO] of ewol::compositing::TextBase");
+}
+
+
+ewol::compositing::TextBase::~TextBase() {
+
+}
+
+void ewol::compositing::TextBase::loadProgram(const etk::String& _shaderName) {
+ // get the shader resource:
+ m_GLPosition = 0;
+ ememory::SharedPtr old = m_GLprogram;
+ m_GLprogram = gale::resource::Program::create(_shaderName);
+ if (m_GLprogram != null) {
+ m_GLPosition = m_GLprogram->getAttribute("EW_coord3d");
+ m_GLColor = m_GLprogram->getAttribute("EW_color");
+ m_GLtexture = m_GLprogram->getAttribute("EW_texture2d");
+ m_GLMatrix = m_GLprogram->getUniform("EW_MatrixTransformation");
+ m_GLtexID = m_GLprogram->getUniform("EW_texID");
+ m_GLtextWidth = m_GLprogram->getUniform("EW_texWidth");
+ m_GLtextHeight = m_GLprogram->getUniform("EW_texHeight");
+ } else {
+ EWOL_ERROR("Can not load the program => create previous one...");
+ m_GLprogram = old;
+ old = null;
+ }
+}
+
+void ewol::compositing::TextBase::translate(const vec3& _vect) {
+ ewol::Compositing::translate(_vect);
+ m_vectorialDraw.translate(_vect);
+}
+
+void ewol::compositing::TextBase::rotate(const vec3& _vect, float _angle) {
+ ewol::Compositing::rotate(_vect, _angle);
+ m_vectorialDraw.rotate(_vect, _angle);
+}
+
+void ewol::compositing::TextBase::scale(const vec3& _vect) {
+ ewol::Compositing::scale(_vect);
+ m_vectorialDraw.scale(_vect);
+}
+
+void ewol::compositing::TextBase::clear() {
+ // call upper class
+ ewol::Compositing::clear();
+ // remove sub draw system
+ m_vectorialDraw.clear();
+ // reset Buffer:
+ m_VBO->clear();
+ // reset temporal variables:
+ reset();
+}
+
+void ewol::compositing::TextBase::reset() {
+ m_position = vec3(0,0,0);
+ m_clippingPosStart = vec3(0,0,0);
+ m_clippingPosStop = vec3(0,0,0);
+ m_sizeDisplayStart = m_position;
+ m_sizeDisplayStop = m_position;
+ m_nbCharDisplayed = 0;
+ m_clippingEnable = false;
+ m_color = m_defaultColorFg;
+ m_colorBg = m_defaultColorBg;
+ m_mode = ewol::font::Regular;
+ m_previousCharcode = 0;
+ m_startTextpos = 0;
+ m_stopTextPos = 0;
+ m_alignement = alignDisable;
+ m_htmlCurrrentLine = U"";
+ m_selectionStartPos = -100;
+ m_cursorPos = -100;
+ m_htmlDecoration.clear();
+ m_needDisplay = true;
+ m_nbCharDisplayed = 0;
+}
+
+void ewol::compositing::TextBase::setPos(const vec3& _pos) {
+ // check min max for display area
+ if (m_nbCharDisplayed != 0) {
+ EWOL_VERBOSE("update size 1 " << m_sizeDisplayStart << " " << m_sizeDisplayStop);
+ m_sizeDisplayStop.setX(etk::max(m_position.x(), m_sizeDisplayStop.x()));
+ m_sizeDisplayStop.setY(etk::max(m_position.y(), m_sizeDisplayStop.y()));
+ m_sizeDisplayStart.setX(etk::min(m_position.x(), m_sizeDisplayStart.x()));
+ m_sizeDisplayStart.setY(etk::min(m_position.y(), m_sizeDisplayStart.y()));
+ EWOL_VERBOSE("update size 2 " << m_sizeDisplayStart << " " << m_sizeDisplayStop);
+ }
+ // update position
+ m_position = _pos;
+ m_previousCharcode = 0;
+ m_vectorialDraw.setPos(m_position);
+ // update min max of the display area:
+ if (m_nbCharDisplayed == 0) {
+ m_sizeDisplayStart = m_position;
+ m_sizeDisplayStop = m_position;
+ m_sizeDisplayStop.setY( m_sizeDisplayStop.y()+ getHeight());
+ EWOL_VERBOSE("update size 0 " << m_sizeDisplayStart << " " << m_sizeDisplayStop);
+ } else {
+ EWOL_VERBOSE("update size 3 " << m_sizeDisplayStart << " " << m_sizeDisplayStop);
+ m_sizeDisplayStop.setX(etk::max(m_position.x(), m_sizeDisplayStop.x()));
+ m_sizeDisplayStop.setY(etk::max(m_position.y(), m_sizeDisplayStop.y()));
+ m_sizeDisplayStart.setX(etk::min(m_position.x(), m_sizeDisplayStart.x()));
+ m_sizeDisplayStart.setY(etk::min(m_position.y(), m_sizeDisplayStart.y()));
+ EWOL_VERBOSE("update size 4 " << m_sizeDisplayStart << " " << m_sizeDisplayStop);
+ }
+}
+
+void ewol::compositing::TextBase::setRelPos(const vec3& _pos) {
+ m_position += _pos;
+ m_previousCharcode = 0;
+ m_vectorialDraw.setPos(m_position);
+}
+
+void ewol::compositing::TextBase::setColorBg(const etk::Color<>& _color) {
+ m_colorBg = _color;
+ m_vectorialDraw.setColor(_color);
+}
+
+void ewol::compositing::TextBase::setClipping(const vec3& _pos, const vec3& _posEnd) {
+ // note the internal system all time request to have a bounding all time in the same order
+ if (_pos.x() <= _posEnd.x()) {
+ m_clippingPosStart.setX(_pos.x());
+ m_clippingPosStop.setX(_posEnd.x());
+ } else {
+ m_clippingPosStart.setX(_posEnd.x());
+ m_clippingPosStop.setX(_pos.x());
+ }
+ if (_pos.y() <= _posEnd.y()) {
+ m_clippingPosStart.setY(_pos.y());
+ m_clippingPosStop.setY(_posEnd.y());
+ } else {
+ m_clippingPosStart.setY(_posEnd.y());
+ m_clippingPosStop.setY(_pos.y());
+ }
+ if (_pos.z() <= _posEnd.z()) {
+ m_clippingPosStart.setZ(_pos.z());
+ m_clippingPosStop.setZ(_posEnd.z());
+ } else {
+ m_clippingPosStart.setZ(_posEnd.z());
+ m_clippingPosStop.setZ(_pos.z());
+ }
+ m_clippingEnable = true;
+ //m_vectorialDraw.setClipping(m_clippingPosStart, m_clippingPosStop);
+}
+
+void ewol::compositing::TextBase::setClippingMode(bool _newMode) {
+ m_clippingEnable = _newMode;
+ //m_vectorialDraw.setClippingMode(m_clippingEnable);
+}
+
+void ewol::compositing::TextBase::setFontBold(bool _status) {
+ if (_status == true) {
+ // enable
+ if (m_mode == ewol::font::Regular) {
+ setFontMode(ewol::font::Bold);
+ } else if (m_mode == ewol::font::Italic) {
+ setFontMode(ewol::font::BoldItalic);
+ }
+ } else {
+ // disable
+ if (m_mode == ewol::font::Bold) {
+ setFontMode(ewol::font::Regular);
+ } else if (m_mode == ewol::font::BoldItalic) {
+ setFontMode(ewol::font::Italic);
+ }
+ }
+}
+
+void ewol::compositing::TextBase::setFontItalic(bool _status) {
+ if (_status == true) {
+ // enable
+ if (m_mode == ewol::font::Regular) {
+ setFontMode(ewol::font::Italic);
+ } else if (m_mode == ewol::font::Bold) {
+ setFontMode(ewol::font::BoldItalic);
+ }
+ } else {
+ // disable
+ if (m_mode == ewol::font::Italic) {
+ setFontMode(ewol::font::Regular);
+ } else if (m_mode == ewol::font::BoldItalic) {
+ setFontMode(ewol::font::Bold);
+ }
+ }
+}
+
+void ewol::compositing::TextBase::setKerningMode(bool _newMode) {
+ m_kerning = _newMode;
+}
+
+void ewol::compositing::TextBase::print(const etk::UString& _text) {
+ etk::Vector decorationEmpty;
+ print(_text, decorationEmpty);
+}
+
+void ewol::compositing::TextBase::print(const etk::String& _text) {
+ etk::Vector decorationEmpty;
+ print(_text, decorationEmpty);
+}
+
+
+void ewol::compositing::TextBase::parseHtmlNode(const exml::Element& _element) {
+ // get the static real pointer
+ if (_element.exist() == false) {
+ EWOL_ERROR( "Error Input node does not existed ...");
+ return;
+ }
+ for(auto it : _element.nodes) {
+ if (it.isComment() == true) {
+ // nothing to do ...
+ continue;
+ } else if (it.isText() == true) {
+ htmlAddData(etk::toUString(it.getValue()));
+ EWOL_VERBOSE("XML add : " << it.getValue());
+ continue;
+ } else if (it.isElement() == false) {
+ EWOL_ERROR("(l "<< it.getPos() << ") node not suported type : " << it.getType() << " val='"<< it.getValue() << "'" );
+ continue;
+ }
+ exml::Element elem = it.toElement();
+ if (elem.exist() == false) {
+ EWOL_ERROR("Cast error ...");
+ continue;
+ }
+ if(etk::compare_no_case(elem.getValue(), "br") == true) {
+ htmlFlush();
+ EWOL_VERBOSE("XML flush & newLine");
+ forceLineReturn();
+ } else if (etk::compare_no_case(elem.getValue(), "font") == true) {
+ EWOL_VERBOSE("XML Font ...");
+ TextDecoration tmpDeco = m_htmlDecoTmp;
+ etk::String colorValue = elem.attributes["color"];
+ if (colorValue.size() != 0) {
+ m_htmlDecoTmp.m_colorFg = colorValue;
+ }
+ colorValue = elem.attributes["colorBg"];
+ if (colorValue.size() != 0) {
+ m_htmlDecoTmp.m_colorBg = colorValue;
+ }
+ parseHtmlNode(elem);
+ m_htmlDecoTmp = tmpDeco;
+ } else if( etk::compare_no_case(elem.getValue(), "b") == true
+ || etk::compare_no_case(elem.getValue(), "bold") == true) {
+ EWOL_VERBOSE("XML bold ...");
+ TextDecoration tmpDeco = m_htmlDecoTmp;
+ if (m_htmlDecoTmp.m_mode == ewol::font::Regular) {
+ m_htmlDecoTmp.m_mode = ewol::font::Bold;
+ } else if (m_htmlDecoTmp.m_mode == ewol::font::Italic) {
+ m_htmlDecoTmp.m_mode = ewol::font::BoldItalic;
+ }
+ parseHtmlNode(elem);
+ m_htmlDecoTmp = tmpDeco;
+ } else if( etk::compare_no_case(elem.getValue(), "i") == true
+ || etk::compare_no_case(elem.getValue(), "italic") == true) {
+ EWOL_VERBOSE("XML italic ...");
+ TextDecoration tmpDeco = m_htmlDecoTmp;
+ if (m_htmlDecoTmp.m_mode == ewol::font::Regular) {
+ m_htmlDecoTmp.m_mode = ewol::font::Italic;
+ } else if (m_htmlDecoTmp.m_mode == ewol::font::Bold) {
+ m_htmlDecoTmp.m_mode = ewol::font::BoldItalic;
+ }
+ parseHtmlNode(elem);
+ m_htmlDecoTmp = tmpDeco;
+ } else if( etk::compare_no_case(elem.getValue(), "u") == true
+ || etk::compare_no_case(elem.getValue(), "underline") == true) {
+ EWOL_VERBOSE("XML underline ...");
+ parseHtmlNode(elem);
+ } else if( etk::compare_no_case(elem.getValue(), "p") == true
+ || etk::compare_no_case(elem.getValue(), "paragraph") == true) {
+ EWOL_VERBOSE("XML paragraph ...");
+ htmlFlush();
+ m_alignement = alignLeft;
+ forceLineReturn();
+ parseHtmlNode(elem);
+ forceLineReturn();
+ } else if (etk::compare_no_case(elem.getValue(), "center") == true) {
+ EWOL_VERBOSE("XML center ...");
+ htmlFlush();
+ m_alignement = alignCenter;
+ parseHtmlNode(elem);
+ } else if (etk::compare_no_case(elem.getValue(), "left") == true) {
+ EWOL_VERBOSE("XML left ...");
+ htmlFlush();
+ m_alignement = alignLeft;
+ parseHtmlNode(elem);
+ } else if (etk::compare_no_case(elem.getValue(), "right") == true) {
+ EWOL_VERBOSE("XML right ...");
+ htmlFlush();
+ m_alignement = alignRight;
+ parseHtmlNode(elem);
+ } else if (etk::compare_no_case(elem.getValue(), "justify") == true) {
+ EWOL_VERBOSE("XML justify ...");
+ htmlFlush();
+ m_alignement = alignJustify;
+ parseHtmlNode(elem);
+ } else {
+ EWOL_ERROR("(l "<< elem.getPos() << ") node not suported type: " << elem.getType() << " val='"<< elem.getValue() << "'" );
+ }
+ }
+}
+
+void ewol::compositing::TextBase::printDecorated(const etk::String& _text) {
+ etk::String tmpData("\n\n");
+ tmpData += _text;
+ tmpData += "\n\n\n";
+ //EWOL_DEBUG("plop : " << tmpData);
+ printHTML(tmpData);
+}
+
+void ewol::compositing::TextBase::printDecorated(const etk::UString& _text) {
+ etk::UString tmpData(U"\n\n");
+ tmpData += _text;
+ tmpData += U"\n\n\n";
+ //EWOL_DEBUG("plop : " << tmpData);
+ printHTML(tmpData);
+}
+
+void ewol::compositing::TextBase::printHTML(const etk::String& _text) {
+ exml::Document doc;
+
+ // reset parameter :
+ m_htmlDecoTmp.m_colorBg = m_defaultColorBg;
+ m_htmlDecoTmp.m_colorFg = m_defaultColorFg;
+ m_htmlDecoTmp.m_mode = ewol::font::Regular;
+
+ if (doc.parse(_text) == false) {
+ EWOL_ERROR( "can not load XML: PARSING error: Decorated text ");
+ return;
+ }
+
+ exml::Element root = doc.nodes["html"];
+ if (root.exist() == false) {
+ EWOL_ERROR( "can not load XML: main node not find: 'html'");
+ doc.display();
+ return;
+ }
+ exml::Element bodyNode = root.nodes["body"];
+ if (root.exist() == false) {
+ EWOL_ERROR( "can not load XML: main node not find: 'body'");
+ return;
+ }
+ parseHtmlNode(bodyNode);
+ htmlFlush();
+}
+
+void ewol::compositing::TextBase::printHTML(const etk::UString& _text) {
+ exml::Document doc;
+
+ // reset parameter :
+ m_htmlDecoTmp.m_colorBg = m_defaultColorBg;
+ m_htmlDecoTmp.m_colorFg = m_defaultColorFg;
+ m_htmlDecoTmp.m_mode = ewol::font::Regular;
+ // TODO : Create an instance of xml parser to manage etk::UString...
+ if (doc.parse(etk::toString(_text)) == false) {
+ EWOL_ERROR( "can not load XML: PARSING error: Decorated text ");
+ return;
+ }
+
+ exml::Element root = doc.nodes["html"];
+ if (root.exist() == false) {
+ EWOL_ERROR( "can not load XML: main node not find: 'html'");
+ doc.display();
+ return;
+ }
+ exml::Element bodyNode = root.nodes["body"];
+ if (root.exist() == false) {
+ EWOL_ERROR( "can not load XML: main node not find: 'body'");
+ return;
+ }
+ parseHtmlNode(bodyNode);
+ htmlFlush();
+}
+
+void ewol::compositing::TextBase::print(const etk::String& _text, const etk::Vector& _decoration) {
+ etk::Color<> tmpFg(m_color);
+ etk::Color<> tmpBg(m_colorBg);
+ if (m_alignement == alignDisable) {
+ //EWOL_DEBUG(" 1 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position);
+ // display the cursor if needed (if it is at the start position...)
+ if (m_needDisplay == true) {
+ if (0 == m_cursorPos) {
+ m_vectorialDraw.setPos(m_position);
+ setColorBg(m_colorCursor);
+ printCursor(false);
+ }
+ }
+ // note this is faster when nothing is requested ...
+ for(size_t iii=0; iii<_text.size(); iii++) {
+ // check if ve have decoration
+ if (iii<_decoration.size()) {
+ tmpFg = _decoration[iii].m_colorFg;
+ tmpBg = _decoration[iii].m_colorBg;
+ setFontMode(_decoration[iii].m_mode);
+ }
+ // if real display : ( not display is for size calculation)
+ if (m_needDisplay == true) {
+ if( ( m_selectionStartPos-1 < (int64_t)iii
+ && (int64_t)iii <= m_cursorPos-1)
+ || ( m_selectionStartPos-1 >= (int64_t)iii
+ && (int64_t)iii > m_cursorPos-1) ) {
+ setColor( 0x000000FF);
+ setColorBg(m_colorSelection);
+ } else {
+ setColor( tmpFg);
+ setColorBg(tmpBg);
+ }
+ }
+ if( m_needDisplay == true
+ && m_colorBg.a() != 0) {
+ vec3 pos = m_position;
+ m_vectorialDraw.setPos(pos);
+ printChar(_text[iii]);
+ float fontHeigh = getHeight();
+ m_vectorialDraw.rectangleWidth(vec3(m_position.x()-pos.x(),fontHeigh,0.0f) );
+ m_nbCharDisplayed++;
+ } else {
+ printChar(_text[iii]);
+ m_nbCharDisplayed++;
+ }
+ // display the cursor if needed (if it is at the other position...)
+ if (m_needDisplay == true) {
+ if ((int64_t)iii == m_cursorPos-1) {
+ m_vectorialDraw.setPos(m_position);
+ setColorBg(m_colorCursor);
+ printCursor(false);
+ }
+ }
+ }
+ //EWOL_DEBUG(" 2 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position);
+ } else {
+ //EWOL_DEBUG(" 3 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position);
+ // special start case at the right of the endpoint :
+ if (m_stopTextPos < m_position.x()) {
+ forceLineReturn();
+ }
+ float basicSpaceWidth = calculateSize(char32_t(' ')).x();
+ int32_t currentId = 0;
+ int32_t stop;
+ int32_t space;
+ int32_t freeSpace;
+ while (currentId < (int64_t)_text.size()) {
+ bool needNoJustify = extrapolateLastId(_text, currentId, stop, space, freeSpace);
+ float interpolation = basicSpaceWidth;
+ switch (m_alignement) {
+ case alignJustify:
+ if (needNoJustify == false) {
+ interpolation += (float)freeSpace / (float)(space-1);
+ }
+ break;
+ case alignDisable: // must not came from here ...
+ case alignLeft:
+ // nothing to do ...
+ break;
+ case alignRight:
+ if (m_needDisplay == true) {
+ // Move the first char at the right :
+ setPos(vec3(m_position.x() + freeSpace,
+ m_position.y(),
+ m_position.z()) );
+ }
+ break;
+ case alignCenter:
+ if (m_needDisplay == true) {
+ // Move the first char at the right :
+ setPos(vec3(m_position.x() + freeSpace/2,
+ m_position.y(),
+ m_position.z()) );
+ }
+ break;
+ }
+ // display all the elements
+ if( m_needDisplay == true
+ && m_cursorPos == 0) {
+ m_vectorialDraw.setPos(m_position);
+ setColorBg(m_colorCursor);
+ printCursor(false);
+ }
+ for(size_t iii=currentId; (int64_t)iii= (int64_t)iii
+ && (int64_t)iii > m_cursorPos-1) ) {
+ setColor( 0x000000FF);
+ setColorBg(m_colorSelection);
+ } else {
+ setColor( tmpFg);
+ setColorBg(tmpBg);
+ }
+ }
+ // special for the justify mode
+ if ((char32_t)_text[iii] == u32char::Space) {
+ //EWOL_DEBUG(" generateString : \" \"");
+ if( m_needDisplay == true
+ && m_colorBg.a() != 0) {
+ m_vectorialDraw.setPos(m_position);
+ }
+ // Must generate a dynamic space :
+ setPos(vec3(m_position.x() + interpolation,
+ m_position.y(),
+ m_position.z()) );
+ if( m_needDisplay == true
+ && m_colorBg.a() != 0) {
+ m_vectorialDraw.rectangleWidth(vec3(interpolation,fontHeigh,0.0f) );
+ }
+ } else {
+ //EWOL_DEBUG(" generateString : \"" << (char)text[iii] << "\"");
+ if( m_needDisplay == true
+ && m_colorBg.a() != 0) {
+ vec3 pos = m_position;
+ m_vectorialDraw.setPos(pos);
+ printChar(_text[iii]);
+ m_vectorialDraw.rectangleWidth(vec3(m_position.x()-pos.x(),fontHeigh,0.0f) );
+ m_nbCharDisplayed++;
+ } else {
+ printChar(_text[iii]);
+ m_nbCharDisplayed++;
+ }
+ }
+ if (m_needDisplay == true) {
+ if ((int64_t)iii == m_cursorPos-1) {
+ m_vectorialDraw.setPos(m_position);
+ setColorBg(m_colorCursor);
+ printCursor(false);
+ }
+ }
+ }
+ if (currentId == stop) {
+ currentId++;
+ } else if((char32_t)_text[stop] == u32char::Space) {
+ currentId = stop+1;
+ // reset position :
+ setPos(vec3(m_startTextpos,
+ (float)(m_position.y() - getHeight()),
+ m_position.z()) );
+ m_nbCharDisplayed++;
+ } else if((char32_t)_text[stop] == u32char::Return) {
+ currentId = stop+1;
+ // reset position :
+ setPos(vec3(m_startTextpos,
+ (float)(m_position.y() - getHeight()),
+ m_position.z()) );
+ m_nbCharDisplayed++;
+ } else {
+ currentId = stop;
+ }
+ }
+ //EWOL_DEBUG(" 4 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position);
+ }
+}
+
+void ewol::compositing::TextBase::print(const etk::UString& _text, const etk::Vector& _decoration) {
+ etk::Color<> tmpFg(m_color);
+ etk::Color<> tmpBg(m_colorBg);
+ if (m_alignement == alignDisable) {
+ //EWOL_DEBUG(" 1 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position);
+ // display the cursor if needed (if it is at the start position...)
+ if (m_needDisplay == true) {
+ if (0 == m_cursorPos) {
+ m_vectorialDraw.setPos(m_position);
+ setColorBg(m_colorCursor);
+ printCursor(false);
+ }
+ }
+ // note this is faster when nothing is requested ...
+ for(size_t iii=0; iii<_text.size(); iii++) {
+ // check if ve have decoration
+ if (iii<_decoration.size()) {
+ tmpFg = _decoration[iii].m_colorFg;
+ tmpBg = _decoration[iii].m_colorBg;
+ setFontMode(_decoration[iii].m_mode);
+ }
+ // if real display : ( not display is for size calculation)
+ if (m_needDisplay == true) {
+ if( ( m_selectionStartPos-1<(int64_t)iii
+ && (int64_t)iii <= m_cursorPos-1)
+ || ( m_selectionStartPos-1 >= (int64_t)iii
+ && (int64_t)iii > m_cursorPos-1) ) {
+ setColor( 0x000000FF);
+ setColorBg(m_colorSelection);
+ } else {
+ setColor( tmpFg);
+ setColorBg(tmpBg);
+ }
+ }
+ if( m_needDisplay == true
+ && m_colorBg.a() != 0) {
+ vec3 pos = m_position;
+ m_vectorialDraw.setPos(pos);
+ printChar(_text[iii]);
+ float fontHeigh = getHeight();
+ m_vectorialDraw.rectangleWidth(vec3(m_position.x()-pos.x(),fontHeigh,0.0f) );
+ m_nbCharDisplayed++;
+ } else {
+ printChar(_text[iii]);
+ m_nbCharDisplayed++;
+ }
+ // display the cursor if needed (if it is at the other position...)
+ if (m_needDisplay == true) {
+ if ((int64_t)iii == m_cursorPos-1) {
+ m_vectorialDraw.setPos(m_position);
+ setColorBg(m_colorCursor);
+ printCursor(false);
+ }
+ }
+ }
+ //EWOL_DEBUG(" 2 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position);
+ } else {
+ //EWOL_DEBUG(" 3 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position);
+ // special start case at the right of the endpoint :
+ if (m_stopTextPos < m_position.x()) {
+ forceLineReturn();
+ }
+ float basicSpaceWidth = calculateSize(char32_t(' ')).x();
+ int32_t currentId = 0;
+ int32_t stop;
+ int32_t space;
+ int32_t freeSpace;
+ while (currentId < (int64_t)_text.size()) {
+ bool needNoJustify = extrapolateLastId(_text, currentId, stop, space, freeSpace);
+ float interpolation = basicSpaceWidth;
+ switch (m_alignement) {
+ case alignJustify:
+ if (needNoJustify == false) {
+ interpolation += (float)freeSpace / (float)(space-1);
+ }
+ break;
+ case alignDisable: // must not came from here ...
+ case alignLeft:
+ // nothing to do ...
+ break;
+ case alignRight:
+ if (m_needDisplay == true) {
+ // Move the first char at the right :
+ setPos(vec3(m_position.x() + freeSpace,
+ m_position.y(),
+ m_position.z()) );
+ }
+ break;
+ case alignCenter:
+ if (m_needDisplay == true) {
+ // Move the first char at the right :
+ setPos(vec3(m_position.x() + freeSpace/2,
+ m_position.y(),
+ m_position.z()) );
+ }
+ break;
+ }
+ // display all the elements
+ if( m_needDisplay == true
+ && m_cursorPos == 0) {
+ m_vectorialDraw.setPos(m_position);
+ setColorBg(m_colorCursor);
+ printCursor(false);
+ }
+ for(size_t iii=currentId; (int64_t)iii= (int64_t)iii
+ && (int64_t)iii > m_cursorPos-1) ) {
+ setColor( 0x000000FF);
+ setColorBg(m_colorSelection);
+ } else {
+ setColor( tmpFg);
+ setColorBg(tmpBg);
+ }
+ }
+ // special for the justify mode
+ if ((char32_t)_text[iii] == u32char::Space) {
+ //EWOL_DEBUG(" generateString : \" \"");
+ if( m_needDisplay == true
+ && m_colorBg.a() != 0) {
+ m_vectorialDraw.setPos(m_position);
+ }
+ // Must generate a dynamic space :
+ setPos(vec3(m_position.x() + interpolation,
+ m_position.y(),
+ m_position.z()) );
+ if( m_needDisplay == true
+ && m_colorBg.a() != 0) {
+ m_vectorialDraw.rectangleWidth(vec3(interpolation,fontHeigh,0.0f) );
+ }
+ } else {
+ //EWOL_DEBUG(" generateString : \"" << (char)text[iii] << "\"");
+ if( m_needDisplay == true
+ && m_colorBg.a() != 0) {
+ vec3 pos = m_position;
+ m_vectorialDraw.setPos(pos);
+ printChar(_text[iii]);
+ m_vectorialDraw.rectangleWidth(vec3(m_position.x()-pos.x(),fontHeigh,0.0f) );
+ m_nbCharDisplayed++;
+ } else {
+ printChar(_text[iii]);
+ m_nbCharDisplayed++;
+ }
+ }
+ if (m_needDisplay == true) {
+ if ((int64_t)iii == m_cursorPos-1) {
+ m_vectorialDraw.setPos(m_position);
+ setColorBg(m_colorCursor);
+ printCursor(false);
+ }
+ }
+ }
+ if (currentId == stop) {
+ currentId++;
+ } else if(_text[stop] == u32char::Space) {
+ currentId = stop+1;
+ // reset position :
+ setPos(vec3(m_startTextpos,
+ (float)(m_position.y() - getHeight()),
+ m_position.z()) );
+ m_nbCharDisplayed++;
+ } else if(_text[stop] == u32char::Return) {
+ currentId = stop+1;
+ // reset position :
+ setPos(vec3(m_startTextpos,
+ (float)(m_position.y() - getHeight()),
+ m_position.z()) );
+ m_nbCharDisplayed++;
+ } else {
+ currentId = stop;
+ }
+ }
+ //EWOL_DEBUG(" 4 print in not alligned mode : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position);
+ }
+}
+
+
+
+
+void ewol::compositing::TextBase::forceLineReturn() {
+ // reset position :
+ setPos(vec3(m_startTextpos, m_position.y() - getHeight(), 0) );
+}
+
+void ewol::compositing::TextBase::setTextAlignement(float _startTextpos, float _stopTextPos, enum ewol::compositing::aligneMode _alignement) {
+ m_startTextpos = _startTextpos;
+ m_stopTextPos = _stopTextPos+1;
+ m_alignement = _alignement;
+ if (m_startTextpos >= m_stopTextPos) {
+ // TODO: understand why this flush ...
+ EWOL_VERBOSE("Request allignement with Borne position error : " << _startTextpos << " => " << _stopTextPos);
+ }
+}
+
+enum ewol::compositing::aligneMode ewol::compositing::TextBase::getAlignement() {
+ return m_alignement;
+}
+
+void ewol::compositing::TextBase::disableAlignement() {
+ m_alignement = alignDisable;
+}
+
+vec3 ewol::compositing::TextBase::calculateSizeHTML(const etk::String& _text) {
+ // remove intermediate result
+ reset();
+ //EWOL_DEBUG(" 0 size for=\n" << text);
+ // disable display system
+ m_needDisplay = false;
+
+ setPos(vec3(0,0,0) );
+ // same as print without the end display ...
+ printHTML(_text);
+ //EWOL_DEBUG(" 1 Start pos=" << m_sizeDisplayStart);
+ //EWOL_DEBUG(" 1 Stop pos=" << m_sizeDisplayStop);
+
+ // get the last elements
+ m_sizeDisplayStop.setValue(etk::max(m_position.x(), m_sizeDisplayStop.x()) ,
+ etk::max(m_position.y(), m_sizeDisplayStop.y()) ,
+ 0);
+ m_sizeDisplayStart.setValue(etk::min(m_position.x(), m_sizeDisplayStart.x()) ,
+ etk::min(m_position.y(), m_sizeDisplayStart.y()) ,
+ 0);
+
+ //EWOL_DEBUG(" 2 Start pos=" << m_sizeDisplayStart);
+ //EWOL_DEBUG(" 2 Stop pos=" << m_sizeDisplayStop);
+ // set back the display system
+ m_needDisplay = true;
+
+ return vec3( m_sizeDisplayStop.x()-m_sizeDisplayStart.x(),
+ m_sizeDisplayStop.y()-m_sizeDisplayStart.y(),
+ m_sizeDisplayStop.z()-m_sizeDisplayStart.z());
+}
+
+vec3 ewol::compositing::TextBase::calculateSizeHTML(const etk::UString& _text) {
+ // remove intermediate result
+ reset();
+ //EWOL_DEBUG(" 0 size for=\n" << text);
+ // disable display system
+ m_needDisplay = false;
+
+ setPos(vec3(0,0,0) );
+ // same as print without the end display ...
+ printHTML(_text);
+ //EWOL_DEBUG(" 1 Start pos=" << m_sizeDisplayStart);
+ //EWOL_DEBUG(" 1 Stop pos=" << m_sizeDisplayStop);
+
+ // get the last elements
+ m_sizeDisplayStop.setValue(etk::max(m_position.x(), m_sizeDisplayStop.x()) ,
+ etk::max(m_position.y(), m_sizeDisplayStop.y()) ,
+ 0);
+ m_sizeDisplayStart.setValue(etk::min(m_position.x(), m_sizeDisplayStart.x()) ,
+ etk::min(m_position.y(), m_sizeDisplayStart.y()) ,
+ 0);
+
+ //EWOL_DEBUG(" 2 Start pos=" << m_sizeDisplayStart);
+ //EWOL_DEBUG(" 2 Stop pos=" << m_sizeDisplayStop);
+ // set back the display system
+ m_needDisplay = true;
+
+ return vec3( m_sizeDisplayStop.x()-m_sizeDisplayStart.x(),
+ m_sizeDisplayStop.y()-m_sizeDisplayStart.y(),
+ m_sizeDisplayStop.z()-m_sizeDisplayStart.z());
+}
+
+vec3 ewol::compositing::TextBase::calculateSizeDecorated(const etk::String& _text) {
+ if (_text.size() == 0) {
+ return vec3(0,0,0);
+ }
+ etk::String tmpData("\n");
+ tmpData+=_text;
+ tmpData+="\n\n";
+ vec3 tmpVal = calculateSizeHTML(tmpData);
+ return tmpVal;
+}
+
+vec3 ewol::compositing::TextBase::calculateSizeDecorated(const etk::UString& _text) {
+ if (_text.size() == 0) {
+ return vec3(0,0,0);
+ }
+ etk::UString tmpData(U"\n");
+ tmpData += _text;
+ tmpData += U"\n\n";
+ vec3 tmpVal = calculateSizeHTML(tmpData);
+ return tmpVal;
+}
+
+vec3 ewol::compositing::TextBase::calculateSize(const etk::String& _text) {
+ vec3 outputSize(0, 0, 0);
+ for(auto element : _text) {
+ vec3 tmpp = calculateSize(element);
+ if (outputSize.y() == 0) {
+ outputSize.setY(tmpp.y());
+ }
+ outputSize.setX( outputSize.x() + tmpp.x());
+ }
+ return outputSize;
+}
+
+vec3 ewol::compositing::TextBase::calculateSize(const etk::UString& _text) {
+ vec3 outputSize(0, 0, 0);
+ for(auto element : _text) {
+ vec3 tmpp = calculateSize(element);
+ if (outputSize.y() == 0) {
+ outputSize.setY(tmpp.y());
+ }
+ outputSize.setX( outputSize.x() + tmpp.x());
+ }
+ return outputSize;
+}
+
+void ewol::compositing::TextBase::printCursor(bool _isInsertMode, float _cursorSize) {
+ int32_t fontHeigh = getHeight();
+ if (true == _isInsertMode) {
+ m_vectorialDraw.rectangleWidth(vec3(_cursorSize, fontHeigh, 0) );
+ } else {
+ m_vectorialDraw.setThickness(2);
+ m_vectorialDraw.lineRel( vec3(0, fontHeigh, 0) );
+ m_vectorialDraw.setThickness(0);
+ }
+}
+
+bool ewol::compositing::TextBase::extrapolateLastId(const etk::String& _text,
+ const int32_t _start,
+ int32_t& _stop,
+ int32_t& _space,
+ int32_t& _freeSpace) {
+ // store previous :
+ char32_t storePrevious = m_previousCharcode;
+
+ _stop = _text.size();
+ _space = 0;
+
+ int32_t lastSpacePosition = _start;
+ int32_t lastSpacefreeSize = 0;
+
+ float endPos = m_position.x();
+ bool endOfLine = false;
+
+ float stopPosition = m_stopTextPos;
+ if( m_needDisplay == false
+ || m_stopTextPos == m_startTextpos) {
+ stopPosition = m_startTextpos + 3999999999.0;
+ }
+
+ for (size_t iii=_start; iii<_text.size(); iii++) {
+ vec3 tmpSize = calculateSize(_text[iii]);
+ // check oveflow :
+ if (endPos + tmpSize.x() > stopPosition) {
+ _stop = iii;
+ break;
+ }
+ // save number of space :
+ if ((char32_t)_text[iii] == u32char::Space) {
+ _space++;
+ lastSpacePosition = iii;
+ lastSpacefreeSize = stopPosition - endPos;
+ } else if ((char32_t)_text[iii] == u32char::Return) {
+ _stop = iii;
+ endOfLine = true;
+ break;
+ }
+ // update local size :
+ endPos += tmpSize.x();
+ }
+ _freeSpace = stopPosition - endPos;
+ // retore previous :
+ m_previousCharcode = storePrevious;
+ // need to align left or right ...
+ if(_stop == (int64_t)_text.size()) {
+ return true;
+ } else {
+ if (endOfLine) {
+ return true;
+ } else {
+ if (_space == 0) {
+ return true;
+ }
+ _stop = lastSpacePosition;
+ _freeSpace = lastSpacefreeSize;
+ return false;
+ }
+ }
+}
+
+bool ewol::compositing::TextBase::extrapolateLastId(const etk::UString& _text,
+ const int32_t _start,
+ int32_t& _stop,
+ int32_t& _space,
+ int32_t& _freeSpace) {
+ // store previous :
+ char32_t storePrevious = m_previousCharcode;
+
+ _stop = _text.size();
+ _space = 0;
+
+ int32_t lastSpacePosition = _start;
+ int32_t lastSpacefreeSize = 0;
+
+ float endPos = m_position.x();
+ bool endOfLine = false;
+
+ float stopPosition = m_stopTextPos;
+ if( m_needDisplay == false
+ || m_stopTextPos == m_startTextpos) {
+ stopPosition = m_startTextpos + 3999999999.0;
+ }
+
+ for (size_t iii=_start; iii<_text.size(); iii++) {
+ vec3 tmpSize = calculateSize(_text[iii]);
+ // check oveflow :
+ if (endPos + tmpSize.x() > stopPosition) {
+ _stop = iii;
+ break;
+ }
+ // save number of space :
+ if (_text[iii] == u32char::Space) {
+ _space++;
+ lastSpacePosition = iii;
+ lastSpacefreeSize = stopPosition - endPos;
+ } else if (_text[iii] == u32char::Return) {
+ _stop = iii;
+ endOfLine = true;
+ break;
+ }
+ // update local size :
+ endPos += tmpSize.x();
+ }
+ _freeSpace = stopPosition - endPos;
+ // retore previous :
+ m_previousCharcode = storePrevious;
+ // need to align left or right ...
+ if(_stop == (int64_t)_text.size()) {
+ return true;
+ } else {
+ if (endOfLine) {
+ return true;
+ } else {
+ if (_space == 0) {
+ return true;
+ }
+ _stop = lastSpacePosition;
+ _freeSpace = lastSpacefreeSize;
+ return false;
+ }
+ }
+}
+
+void ewol::compositing::TextBase::htmlAddData(const etk::UString& _data) {
+ if( m_htmlCurrrentLine.size()>0
+ && m_htmlCurrrentLine[m_htmlCurrrentLine.size()-1] != ' ') {
+ m_htmlCurrrentLine += U" ";
+ if(m_htmlDecoration.size()>0) {
+ TextDecoration tmp = m_htmlDecoration[m_htmlDecoration.size()-1];
+ m_htmlDecoration.pushBack(tmp);
+ } else {
+ m_htmlDecoration.pushBack(m_htmlDecoTmp);
+ }
+ }
+ m_htmlCurrrentLine += _data;
+ for(size_t iii=0; iii<_data.size() ; iii++) {
+ m_htmlDecoration.pushBack(m_htmlDecoTmp);
+ }
+}
+
+void ewol::compositing::TextBase::htmlFlush() {
+ if (m_htmlCurrrentLine.size()>0) {
+ print(m_htmlCurrrentLine, m_htmlDecoration);
+ }
+ m_htmlCurrrentLine = U"";
+ m_htmlDecoration.clear();
+}
+
+void ewol::compositing::TextBase::disableCursor() {
+ m_selectionStartPos = -100;
+ m_cursorPos = -100;
+}
+
+void ewol::compositing::TextBase::setCursorPos(int32_t _cursorPos) {
+ m_selectionStartPos = _cursorPos;
+ m_cursorPos = _cursorPos;
+}
+
+void ewol::compositing::TextBase::setCursorSelection(int32_t _cursorPos, int32_t _selectionStartPos) {
+ m_selectionStartPos = _selectionStartPos;
+ m_cursorPos = _cursorPos;
+}
+
+void ewol::compositing::TextBase::setSelectionColor(const etk::Color<>& _color) {
+ m_colorSelection = _color;
+}
+
+void ewol::compositing::TextBase::setCursorColor(const etk::Color<>& _color) {
+ m_colorCursor = _color;
+}
diff --git a/src/org/atriasoft/ewol/compositing/TextBase.java b/src/org/atriasoft/ewol/compositing/TextBase.java
new file mode 100644
index 0000000..fa37b31
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/TextBase.java
@@ -0,0 +1,478 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace ewol {
+ namespace compositing {
+ /**
+ * @brief This class represent the specific display for every char in the string ...
+ * @not_in_doc
+ */
+ class TextDecoration {
+ public:
+ etk::Color m_colorBg; //!< display background color
+ etk::Color m_colorFg; //!< display foreground color
+ enum ewol::font::mode m_mode; //!< display mode Regular/Bold/Italic/BoldItalic
+ TextDecoration() {
+ m_colorBg = etk::color::blue;
+ m_colorBg = etk::color::green;
+ m_mode = ewol::font::Regular;
+ }
+ };
+
+ enum aligneMode {
+ alignDisable,
+ alignRight,
+ alignLeft,
+ alignCenter,
+ alignJustify
+ };
+
+ class TextBase : public ewol::Compositing {
+ protected:
+ ewol::compositing::Drawing m_vectorialDraw; //!< This is used to draw background selection and other things ...
+ public:
+ virtual ewol::compositing::Drawing& getDrawing() {
+ return m_vectorialDraw;
+ };
+ protected:
+ int32_t m_nbCharDisplayed; //!< prevent some error in calculation size.
+ vec3 m_sizeDisplayStart; //!< The start windows of the display.
+ vec3 m_sizeDisplayStop; //!< The end windows of the display.
+ bool m_needDisplay; //!< This just need the display and not the size rendering.
+ vec3 m_position; //!< The current position to draw
+ vec3 m_clippingPosStart; //!< Clipping start position
+ vec3 m_clippingPosStop; //!< Clipping stop position
+ bool m_clippingEnable; //!< true if the clipping must be activated
+ protected:
+ etk::Color m_defaultColorFg; //!< The text foreground color
+ etk::Color m_defaultColorBg; //!< The text background color
+ protected:
+ etk::Color m_color; //!< The text foreground color
+ etk::Color m_colorBg; //!< The text background color
+ etk::Color m_colorCursor; //!< The text cursor color
+ etk::Color m_colorSelection; //!< The text Selection color
+ protected:
+ enum ewol::font::mode m_mode; //!< font display property : Regular/Bold/Italic/BoldItalic
+ bool m_kerning; //!< Kerning enable or disable on the next elements displayed
+ char32_t m_previousCharcode; //!< we remember the previous charcode to perform the kerning. @ref Kerning
+ protected:
+ float m_startTextpos; //!< start position of the Alignement (when \n the text return at this position)
+ float m_stopTextPos; //!< end of the alignement (when a string is too hight it cut at the word previously this virtual line and the center is perform with this one)
+ enum aligneMode m_alignement; //!< Current Alignement mode (justify/left/right ...)
+ protected:
+ ememory::SharedPtr m_GLprogram; //!< pointer on the opengl display program
+ 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_GLColor; //!< openGL id on the element (color buffer)
+ int32_t m_GLtexture; //!< openGL id on the element (Texture position)
+ int32_t m_GLtexID; //!< openGL id on the element (texture ID)
+ int32_t m_GLtextWidth; //!< openGL Id on the texture width
+ int32_t m_GLtextHeight; //!< openGL Id on the texture height
+ protected:
+ int32_t m_selectionStartPos; //!< start position of the Selection (if == m_cursorPos ==> no selection)
+ int32_t m_cursorPos; //!< Cursor position (default no cursor == > -100)
+ protected: // Text
+ static const int32_t m_vboIdCoord;
+ static const int32_t m_vboIdCoordText;
+ static const int32_t m_vboIdColor;
+ static const int32_t m_vboIdGlyphLevel;
+ ememory::SharedPtr m_VBO;
+ public:
+ /**
+ * @brief load the openGL program and get all the ID needed
+ */
+ virtual void loadProgram(const etk::String& _shaderName);
+ public:
+ /**
+ * @brief generic constructor
+ */
+ TextBase(const etk::String& _shaderName = "DATA:///text.prog?lib=ewol", bool _loadProgram = true);
+ /**
+ * @brief generic destructor
+ */
+ virtual ~TextBase();
+ public: // Derived function
+ void translate(const vec3& _vect);
+ void rotate(const vec3& _vect, float _angle);
+ void scale(const vec3& _vect);
+ public:
+ /**
+ * @brief draw All the refistered text in the current element on openGL
+ */
+ void draw(bool _disableDepthTest=true) {
+ drawD(_disableDepthTest);
+ }
+ //! @previous
+ void draw(const mat4& _transformationMatrix, bool _enableDepthTest=false) {
+ drawMT(_transformationMatrix, _enableDepthTest);
+ }
+ /**
+ * @brief draw All the refistered text in the current element on openGL
+ */
+ virtual void drawD(bool _disableDepthTest) = 0;
+ //! @previous
+ virtual void drawMT(const mat4& _transformationMatrix, bool _enableDepthTest) = 0;
+ /**
+ * @brief clear all the registered element in the current element
+ */
+ virtual void clear();
+ /**
+ * @brief clear all the intermediate result detween 2 prints
+ */
+ virtual void reset();
+ /**
+ * @brief get the current display position (sometime needed in the gui control)
+ * @return the current position.
+ */
+ const vec3& getPos() {
+ return m_position;
+ };
+ /**
+ * @brief set position for the next text writen
+ * @param[in] _pos Position of the text (in 3D)
+ */
+ void setPos(const vec3& _pos);
+ //! @previous
+ inline void setPos(const vec2& _pos) {
+ setPos(vec3(_pos.x(),_pos.y(),0));
+ };
+ /**
+ * @brief set relative position for the next text writen
+ * @param[in] _pos ofset apply of the text (in 3D)
+ */
+ void setRelPos(const vec3& _pos);
+ //! @previous
+ inline void setRelPos(const vec2& _pos) {
+ setRelPos(vec3(_pos.x(),_pos.y(),0));
+ };
+ /**
+ * @brief set the default background color of the font (when reset, set this value ...)
+ * @param[in] _color Color to set on background
+ */
+ void setDefaultColorBg(const etk::Color<>& _color) {
+ m_defaultColorBg = _color;
+ }
+ /**
+ * @brief set the default Foreground color of the font (when reset, set this value ...)
+ * @param[in] _color Color to set on foreground
+ */
+ void setDefaultColorFg(const etk::Color<>& _color) {
+ m_defaultColorFg = _color;
+ }
+ /**
+ * @brief set the Color of the current foreground font
+ * @param[in] _color Color to set on foreground (for next print)
+ */
+ void setColor(const etk::Color<>& _color) {
+ m_color = _color;
+ };
+ /**
+ * @brief set the background color of the font (for selected Text (not the global BG))
+ * @param[in] _color Color to set on background (for next print)
+ */
+ void setColorBg(const etk::Color<>& _color);
+ /**
+ * @brief Request a clipping area for the text (next draw only)
+ * @param[in] _pos Start position of the clipping
+ * @param[in] _width Width size of the clipping
+ */
+ void setClippingWidth(const vec3& _pos, const vec3& _width) {
+ setClipping(_pos, _pos+_width);
+ }
+ //! @previous
+ void setClippingWidth(const vec2& _pos, const vec2& _width) {
+ setClipping(_pos, _pos+_width);
+ };
+ /**
+ * @brief Request a clipping area for the text (next draw only)
+ * @param[in] _pos Start position of the clipping
+ * @param[in] _posEnd End position of the clipping
+ */
+ void setClipping(const vec3& _pos, const vec3& _posEnd);
+ //! @previous
+ void setClipping(const vec2& _pos, const vec2& _posEnd) {
+ setClipping(vec3(_pos.x(),_pos.y(),-1), vec3(_posEnd.x(),_posEnd.y(),1) );
+ };
+ /**
+ * @brief enable/Disable the clipping (without lose the current clipping position)
+ * @brief _newMode The new status of the clipping
+ */
+ // TODO : Rename setClippingActivity
+ void setClippingMode(bool _newMode);
+ /**
+ * @brief Specify the font size (this reset the internal element of the current text (system requirement)
+ * @param[in] _fontSize New font size
+ */
+ virtual void setFontSize(int32_t _fontSize) = 0;
+ /**
+ * @brief Specify the font name (this reset the internal element of the current text (system requirement)
+ * @param[in] _fontName Current name of the selected font
+ */
+ virtual void setFontName(const etk::String& _fontName) = 0;
+ /**
+ * @brief Specify the font property (this reset the internal element of the current text (system requirement)
+ * @param[in] fontName Current name of the selected font
+ * @param[in] fontSize New font size
+ */
+ virtual void setFont(etk::String _fontName, int32_t _fontSize) = 0;
+ /**
+ * @brief Specify the font mode for the next @ref print
+ * @param[in] mode The font mode requested
+ */
+ virtual void setFontMode(enum ewol::font::mode _mode) = 0;
+ /**
+ * @brief get the current font mode
+ * @return The font mode applied
+ */
+ enum ewol::font::mode getFontMode() {
+ return m_mode;
+ };
+ virtual float getHeight() = 0;
+ virtual float getSize() = 0;
+ virtual ewol::GlyphProperty * getGlyphPointer(char32_t _charcode) = 0;
+ /**
+ * @brief enable or disable the bold mode
+ * @param[in] _status The new status for this display property
+ */
+ void setFontBold(bool _status);
+ /**
+ * @brief enable or disable the italic mode
+ * @param[in] _status The new status for this display property
+ */
+ void setFontItalic(bool _status);
+ /**
+ * @brief set the activation of the Kerning for the display (if it existed)
+ * @param[in] _newMode enable/Diasable the kerning on this font.
+ */
+ void setKerningMode(bool _newMode);
+ /**
+ * @brief display a compleat string in the current element.
+ * @param[in] _text The string to display.
+ */
+ void print(const etk::String& _text);
+ //! @previous
+ void print(const etk::UString& _text);
+ /**
+ * @brief display a compleat string in the current element with the generic decoration specification. (basic html data)
+ *
+ * [code style=xml]
+ *
+ *
+ *
+ * text exemple in bold other text bold part boldItalic part an other thext
+ * colored text bold color text bold italic text normal color text the end of the string
+ * an an other thext
+ *
+ *
+ *
+ * plop 1
+ *
+ *
+ *
+ * plop 2
+ *
+ *
+ *
+ * Un exemple de text
+ *
+ * [/code]
+ *
+ * @note This is parsed with tiny xml, then be carfull that the XML is correct, and all balises are closed ... otherwite the display can not be done
+ * @param[in] _text The string to display.
+ * @TODO : implementation not done ....
+ */
+ void printDecorated(const etk::String& _text);
+ //! @previous
+ void printDecorated(const etk::UString& _text);
+ /**
+ * @brief display a compleat string in the current element with the generic decoration specification. (basic html data)
+ *
+ * [code style=xml]
+ *
+ *
+ *
+ *
+ *
+ * text exemple in bold other text bold part boldItalic part an other thext
+ * colored text bold color text bold italic text normal color text the end of the string
+ * an an other thext
+ *
+ *
+ *
+ * plop 1
+ *
+ *
+ *
+ * plop 2
+ *
+ *
+ *
+ * Un exemple de text
+ *
+ *
+ *
+ * [/code]
+ *
+ * @note This is parsed with tiny xml, then be carfull that the XML is correct, and all balises are closed ... otherwite the display can not be done
+ * @param[in] _text The string to display.
+ * @TODO : implementation not done ....
+ */
+ void printHTML(const etk::String& _text);
+ //! @previous
+ void printHTML(const etk::UString& _text);
+ /**
+ * @brief display a compleat string in the current element whith specific decorations (advence mode).
+ * @param[in] _text The string to display.
+ * @param[in] _decoration The text decoration for the text that might be display (if the vector is smaller, the last parameter is get)
+ */
+ void print(const etk::String& _text, const etk::Vector& _decoration);
+ //! @previous
+ void print(const etk::UString& _text, const etk::Vector& _decoration);
+ /**
+ * @brief display the current char in the current element (note that the kerning is availlable if the position is not changed)
+ * @param[in] _charcode Char that might be dispalyed
+ */
+ virtual void printChar(const char32_t& _charcode) = 0;
+ /**
+ * @brief This generate the line return == > it return to the alignement position start and at the correct line position ==> it might be use to not know the line height
+ */
+ void forceLineReturn();
+ protected:
+ /**
+ * @brief This parse a tinyXML node (void pointer to permit to hide tiny XML in include).
+ * @param[in] _element the exml element.
+ */
+ void parseHtmlNode(const exml::Element& _element);
+ public:
+ /**
+ * @brief This generate the possibility to generate the big text property
+ * @param[in] _startTextpos The x text start position of the display.
+ * @param[in] _stopTextPos The x text stop position of the display.
+ * @param[in] _alignement mode of alignement for the Text.
+ * @note The text align in center change of line every display done (even if it was just a char)
+ */
+ void setTextAlignement(float _startTextpos, float _stopTextPos, enum ewol::compositing::aligneMode _alignement=ewol::compositing::alignDisable);
+ /**
+ * @brief disable the alignement system
+ */
+ void disableAlignement();
+ /**
+ * @brief get the current alignement property
+ * @return the curent alignement type
+ */
+ enum ewol::compositing::aligneMode getAlignement();
+ /**
+ * @brief calculate a theoric text size
+ * @param[in] _text The string to calculate dimention.
+ * @return The theoric size used.
+ */
+ vec3 calculateSizeHTML(const etk::String& _text);
+ //! @previous
+ vec3 calculateSizeHTML(const etk::UString& _text);
+ /**
+ * @brief calculate a theoric text size
+ * @param[in] _text The string to calculate dimention.
+ * @return The theoric size used.
+ */
+ vec3 calculateSizeDecorated(const etk::String& _text);
+ //! @previous
+ vec3 calculateSizeDecorated(const etk::UString& _text);
+ /**
+ * @brief calculate a theoric text size
+ * @param[in] _text The string to calculate dimention.
+ * @return The theoric size used.
+ */
+ vec3 calculateSize(const etk::String& _text);
+ //! @previous
+ vec3 calculateSize(const etk::UString& _text);
+ /**
+ * @brief calculate a theoric charcode size
+ * @param[in] _charcode The Unicode value to calculate dimention.
+ * @return The theoric size used.
+ */
+ inline vec3 calculateSize(const char32_t& _charcode) {
+ return calculateSizeChar(_charcode);
+ };
+ protected:
+ //! @previous
+ virtual vec3 calculateSizeChar(const char32_t& _charcode) = 0;
+ public:
+ /**
+ * @brief draw a cursor at the specify position
+ * @param[in] _isInsertMode True if the insert mode is activated
+ * @param[in] _cursorSize The sizae of the cursor that might be set when insert mode is set [default 20]
+ */
+ void printCursor(bool _isInsertMode, float _cursorSize = 20.0f);
+ protected:
+ /**
+ * @brief calculate the element number that is the first out the alignement range
+ * (start at the specify ID, and use start pos with current one)
+ * @param[in] _text The string that might be parsed.
+ * @param[in] _start The first elemnt that might be used to calculate.
+ * @param[out] _stop The last Id availlable in the current string.
+ * @param[out] _space Number of space in the string.
+ * @param[out] _freespace This represent the number of pixel present in the right white space.
+ * @return true if the rifht has free space that can be use for jystify.
+ * @return false if we find '\n'
+ */
+ bool extrapolateLastId(const etk::String& _text, const int32_t _start, int32_t& _stop, int32_t& _space, int32_t& _freeSpace);
+ //! @previous
+ bool extrapolateLastId(const etk::UString& _text, const int32_t _start, int32_t& _stop, int32_t& _space, int32_t& _freeSpace);
+ protected:
+ // this section is reserved for HTML parsing and display:
+ etk::UString m_htmlCurrrentLine; //!< current line for HTML display
+ etk::Vector m_htmlDecoration; //!< current decoration for the HTML display
+ TextDecoration m_htmlDecoTmp; //!< current decoration
+ /**
+ * @brief add a line with the current m_htmlDecoTmp decoration
+ * @param[in] _data The cuurent data to add.
+ */
+ void htmlAddData(const etk::UString& _data);
+ /**
+ * @brief draw the current line
+ */
+ void htmlFlush();
+ public:
+ /**
+ * @brief remove the cursor display
+ */
+ void disableCursor();
+ /**
+ * @brief set a cursor at a specific position:
+ * @param[in] _cursorPos id of the cursor position
+ */
+ void setCursorPos(int32_t _cursorPos);
+ /**
+ * @brief set a cursor at a specific position with his associated selection:
+ * @param[in] _cursorPos id of the cursor position
+ * @param[in] _selectionStartPos id of the starting of the selection
+ */
+ void setCursorSelection(int32_t _cursorPos, int32_t _selectionStartPos);
+ /**
+ * @brief change the selection color
+ * @param[in] _color New color for the Selection
+ */
+ void setSelectionColor(const etk::Color<>& _color);
+ /**
+ * @brief change the cursor color
+ * @param[in] _color New color for the Selection
+ */
+ void setCursorColor(const etk::Color<>& _color);
+ };
+ }
+}
+
+
diff --git a/src/org/atriasoft/ewol/compositing/TextDF.cpp b/src/org/atriasoft/ewol/compositing/TextDF.cpp
new file mode 100644
index 0000000..41430ac
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/TextDF.cpp
@@ -0,0 +1,407 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+#include
+#include
+#include
+#include
+ETK_DECLARE_TYPE(ewol::compositing::TextDF);
+
+ewol::compositing::TextDF::TextDF(const etk::String& _fontName, int32_t _fontSize) :
+ ewol::compositing::TextBase("", false),
+ m_fontDF(null),
+ m_GLglyphLevel(-1),
+ m_size(12.0) {
+ setFont(_fontName, _fontSize);
+ loadProgram("DATA:///fontDistanceField/font1.prog?lib=ewol");
+}
+
+ewol::compositing::TextDF::~TextDF() {
+
+}
+
+void ewol::compositing::TextDF::updateSizeToRender(const vec2& _size) {
+ float minSize = etk::min(_size.x(), _size.y());
+ if (m_fontDF != null) {
+ setFontSize(m_fontDF->getSize(minSize));
+ }
+}
+
+void ewol::compositing::TextDF::drawMT(const mat4& _transformationMatrix, bool _enableDepthTest) {
+ // draw BG in any case:
+ m_vectorialDraw.draw();
+ if ( m_VBO->bufferSize(m_vboIdCoord) <= 0
+ || m_fontDF == null) {
+ //EWOL_WARNING("Nothink to draw...");
+ return;
+ }
+ if (m_fontDF == null) {
+ EWOL_WARNING("no font...");
+ return;
+ }
+ if (m_GLprogram == null) {
+ EWOL_ERROR("No shader ...");
+ return;
+ }
+ if (_enableDepthTest == true) {
+ gale::openGL::enable(gale::openGL::flag_depthTest);
+ }
+ // set Matrix: translation/positionMatrix
+ mat4 projMatrix = gale::openGL::getMatrix();
+ mat4 camMatrix = gale::openGL::getCameraMatrix();
+ mat4 tmpMatrix = projMatrix * camMatrix * _transformationMatrix;
+ m_GLprogram->use();
+ m_GLprogram->uniformMatrix(m_GLMatrix, tmpMatrix);
+ // Texture:
+ m_GLprogram->setTexture0(m_GLtexID, m_fontDF->getRendererId());
+ m_GLprogram->uniform1i(m_GLtextWidth, m_fontDF->getOpenGlSize().x());
+ m_GLprogram->uniform1i(m_GLtextHeight, m_fontDF->getOpenGlSize().x());
+ m_GLprogram->sendAttributePointer(m_GLPosition, m_VBO, m_vboIdCoord);
+ m_GLprogram->sendAttributePointer(m_GLtexture, m_VBO, m_vboIdCoordText);
+ m_GLprogram->sendAttributePointer(m_GLColor, m_VBO, m_vboIdColor);
+ m_GLprogram->sendAttributePointer(m_GLglyphLevel, m_VBO, m_vboIdGlyphLevel);
+ // Request the draw od the elements:
+ gale::openGL::drawArrays(gale::openGL::renderMode::triangle, 0, m_VBO->bufferSize(m_vboIdCoord));
+ m_GLprogram->unUse();
+ if (_enableDepthTest == true) {
+ gale::openGL::disable(gale::openGL::flag_depthTest);
+ }
+}
+
+
+void ewol::compositing::TextDF::drawD(bool _disableDepthTest) {
+ // draw BG in any case:
+ m_vectorialDraw.draw();
+
+ if ( m_VBO->bufferSize(m_vboIdCoord) <= 0
+ || m_fontDF == null) {
+ // TODO : Set it back
+ //EWOL_WARNING("Nothink to draw...");
+ return;
+ }
+ if (m_fontDF == null) {
+ EWOL_WARNING("no font...");
+ return;
+ }
+ if (m_GLprogram == null) {
+ EWOL_ERROR("No shader ...");
+ return;
+ }
+ // set Matrix: translation/positionMatrix
+ mat4 tmpMatrix = gale::openGL::getMatrix()*m_matrixApply;
+ m_GLprogram->use();
+ m_GLprogram->uniformMatrix(m_GLMatrix, tmpMatrix);
+ // Texture:
+ m_GLprogram->setTexture0(m_GLtexID, m_fontDF->getRendererId());
+ m_GLprogram->uniform1i(m_GLtextWidth, m_fontDF->getOpenGlSize().x());
+ m_GLprogram->uniform1i(m_GLtextHeight, m_fontDF->getOpenGlSize().x());
+ m_GLprogram->sendAttributePointer(m_GLPosition, m_VBO, m_vboIdCoord);
+ m_GLprogram->sendAttributePointer(m_GLtexture, m_VBO, m_vboIdCoordText);
+ m_GLprogram->sendAttributePointer(m_GLColor, m_VBO, m_vboIdColor);
+ m_GLprogram->sendAttributePointer(m_GLglyphLevel, m_VBO, m_vboIdGlyphLevel);
+ // Request the draw od the elements:
+ gale::openGL::drawArrays(gale::openGL::renderMode::triangle, 0, m_VBO->bufferSize(m_vboIdCoord));
+ m_GLprogram->unUse();
+}
+
+void ewol::compositing::TextDF::loadProgram(const etk::String& _shaderName) {
+ ewol::compositing::TextBase::loadProgram(_shaderName);
+ if (m_GLprogram != null) {
+ m_GLglyphLevel = m_GLprogram->getAttribute("EW_glyphLevel");
+ }
+}
+
+
+float ewol::compositing::TextDF::getHeight() {
+ if (m_fontDF == null) {
+ EWOL_WARNING("no font...");
+ return 1;
+ }
+ return m_fontDF->getHeight(m_size);
+}
+
+ewol::GlyphProperty * ewol::compositing::TextDF::getGlyphPointer(char32_t _charcode) {
+ if (m_fontDF == null) {
+ EWOL_WARNING("no font...");
+ return null;
+ }
+ return m_fontDF->getGlyphPointer(_charcode);
+}
+
+void ewol::compositing::TextDF::setFontSize(int32_t _fontSize) {
+ clear();
+ EWOL_VERBOSE("Set font Size: " << _fontSize);
+ if (_fontSize <= 1) {
+ m_size = ewol::getContext().getFontDefault().getSize();
+ } else {
+ m_size = _fontSize;
+ }
+}
+
+void ewol::compositing::TextDF::setFontName(const etk::String& _fontName) {
+ clear();
+ // remove old one
+ ememory::SharedPtr previousFont = m_fontDF;
+ etk::String fontName;
+ if (_fontName == "") {
+ fontName = ewol::getContext().getFontDefault().getName();
+ } else {
+ fontName = _fontName;
+ }
+ EWOL_VERBOSE("Set font name: '" << fontName << "'");
+ // link to new one
+ m_fontDF = ewol::resource::DistanceFieldFont::create(fontName);
+ if (m_fontDF == null) {
+ EWOL_ERROR("Can not get find resource");
+ m_fontDF = previousFont;
+ }
+}
+
+void ewol::compositing::TextDF::setFont(etk::String _fontName, int32_t _fontSize) {
+ setFontSize(_fontSize);
+ setFontName(_fontName);
+}
+
+void ewol::compositing::TextDF::setFontMode(enum ewol::font::mode _mode) {
+ m_mode = _mode;
+}
+
+//#define ANGLE_OF_ITALIC (tan(0.4))
+#define ANGLE_OF_ITALIC (0.00698143f)
+
+
+void ewol::compositing::TextDF::printChar(const char32_t& _charcode) {
+ // get a pointer on the glyph property :
+ ewol::GlyphProperty* myGlyph = getGlyphPointer(_charcode);
+ if (null == myGlyph) {
+ EWOL_ERROR(" font does not really existed ...");
+ return;
+ }
+ float fontSize = getSize();
+ float fontHeigh = getHeight();
+
+ float factorDisplay = m_fontDF->getDisplayRatio(fontSize);
+
+ // get the kerning ofset :
+ float kerningOffset = 0;
+ if (true == m_kerning) {
+ kerningOffset = myGlyph->kerningGet(m_previousCharcode);
+ if (kerningOffset != 0) {
+ //EWOL_DEBUG("Kerning between : '" << m_previousCharcode << "'&'" << myGlyph->m_UVal << "' value : " << kerningOffset);
+ }
+ }
+ // 0x01 == 0x20 == ' ';
+ if ( _charcode != 0x01
+ && _charcode != 0x20) {
+ float glyphLevel = 0.5f;
+ if ( m_mode == ewol::font::BoldItalic
+ || m_mode == ewol::font::Bold) {
+ glyphLevel = 0.41f;
+ }
+ float italicMove = 0.0f;
+ if ( m_mode == ewol::font::BoldItalic
+ || m_mode == ewol::font::Italic) {
+ // This is a simple version of Italic mode, in theory we need to move the up and the down...
+ italicMove = (float)myGlyph->m_sizeTexture.y() * factorDisplay * ANGLE_OF_ITALIC;
+ // TODO : pb on the clipper...
+ }
+
+ /* Bitmap position
+ * xA xB
+ * yC *------*
+ * | |
+ * | |
+ * yD *------*
+ */
+ #if 0
+ float dxA = m_position.x() + (myGlyph->m_bearing.x() + kerningOffset) * factorDisplay;
+ float dxB = dxA + myGlyph->m_sizeTexture.x() * factorDisplay;
+ float dyC = m_position.y() + (myGlyph->m_bearing.y() + fontHeigh - fontSize) * factorDisplay;
+ float dyD = dyC - myGlyph->m_sizeTexture.y() * factorDisplay;
+ #else
+ //EWOL_DEBUG(" plop : fontHeigh" << fontHeigh << " fontSize=" << fontSize);
+ float dxA = m_position.x() + ((float)myGlyph->m_bearing.x() + kerningOffset - (float)m_fontDF->getPixelBorderSize()*0.5f) * factorDisplay;
+ float dxB = dxA + ((float)myGlyph->m_sizeTexture.x() + (float)m_fontDF->getPixelBorderSize()) * factorDisplay;
+ float dyC = m_position.y() + (fontHeigh - fontSize + ((float)myGlyph->m_bearing.y() + (float)m_fontDF->getPixelBorderSize()*0.5f) * factorDisplay);
+ float dyD = dyC - ((float)myGlyph->m_sizeTexture.y() + (float)m_fontDF->getPixelBorderSize()) * factorDisplay;
+ #endif
+
+ float tuA = myGlyph->m_texturePosStart.x();
+ float tuB = tuA + myGlyph->m_texturePosSize.x();
+ float tvC = myGlyph->m_texturePosStart.y();
+ float tvD = tvC + myGlyph->m_texturePosSize.y();
+ /*
+ vec3 drawingPos = m_vectorialDraw.getPos();
+ etk::Color<> backColor = m_vectorialDraw.getColor();
+
+ m_vectorialDraw.setPos(vec2(dxA, dyC));
+
+ m_vectorialDraw.setColor(etk::Color<>(0.0,1.0,0.0,1.0));
+ m_vectorialDraw.rectangle(vec2(dxB, dyD));
+
+ m_vectorialDraw.setPos(drawingPos);
+ m_vectorialDraw.setColor(backColor);
+ */
+ // Clipping and drawing area
+ if( m_clippingEnable == true
+ && ( dxB < m_clippingPosStart.x()
+ || dxA > m_clippingPosStop.x()
+ || dyC < m_clippingPosStart.y()
+ || dyD > m_clippingPosStop.y() ) ) {
+ // Nothing to diplay ...
+ } else {
+ if (m_clippingEnable == true) {
+ // generata positions...
+ float TexSizeX = tuB - tuA;
+ if (dxA < m_clippingPosStart.x()) {
+ // clip display
+ float drawSize = m_clippingPosStart.x() - dxA;
+ // update element start display
+ dxA = m_clippingPosStart.x();
+ float addElement = TexSizeX * drawSize / ((float)myGlyph->m_sizeTexture.x() * factorDisplay);
+ // update texture start X Pos
+ tuA += addElement;
+ }
+ if (dxB > m_clippingPosStop.x()) {
+ // clip display
+ float drawSize = dxB - m_clippingPosStop.x();
+ // update element start display
+ dxB = m_clippingPosStop.x();
+ float addElement = TexSizeX * drawSize / ((float)myGlyph->m_sizeTexture.x() * factorDisplay);
+ // update texture start X Pos
+ tuB -= addElement;
+ }
+ float TexSizeY = tvC - tvD;
+ if (dyC > m_clippingPosStop.y()) {
+ // clip display
+ float drawSize = dyC - m_clippingPosStop.y();
+ // update element start display
+ dyC = m_clippingPosStop.y();
+ float addElement = TexSizeY * drawSize / ((float)myGlyph->m_sizeTexture.y() * factorDisplay);
+ // update texture start X Pos
+ tvC -= addElement;
+ }
+ if (dyD < m_clippingPosStart.y()) {
+ // clip display
+ float drawSize = m_clippingPosStart.y() - dyD;
+ // update element start display
+ dyD = m_clippingPosStart.y();
+ float addElement = TexSizeY * drawSize / ((float)myGlyph->m_sizeTexture.y() * factorDisplay);
+ // update texture start X Pos
+ tvD += addElement;
+ }
+ }
+ if( dxB <= dxA
+ || dyD >= dyC) {
+ // nothing to do ...
+ } else {
+ /* Bitmap position
+ * 0------1
+ * | |
+ * | |
+ * 3------2
+ */
+ if (m_needDisplay == true) {
+ vec3 bitmapDrawPos[4];
+ bitmapDrawPos[0].setValue(dxA+italicMove, dyC, 0);
+ bitmapDrawPos[1].setValue(dxB+italicMove, dyC, 0);
+ bitmapDrawPos[2].setValue(dxB, dyD, 0);
+ bitmapDrawPos[3].setValue(dxA, dyD, 0);
+ /* texture Position :
+ * 0------1
+ * | |
+ * | |
+ * 3------2
+ */
+ vec2 texturePos[4];
+ texturePos[0].setValue(tuA+m_mode, tvC);
+ texturePos[1].setValue(tuB+m_mode, tvC);
+ texturePos[2].setValue(tuB+m_mode, tvD);
+ texturePos[3].setValue(tuA+m_mode, tvD);
+
+ // NOTE : Android does not support the Quads elements ...
+ /* Step 1 :
+ * ********
+ * ******
+ * ****
+ * **
+ *
+ */
+ // set texture coordonates :
+ m_VBO->pushOnBuffer(m_vboIdCoordText, texturePos[0]);
+ m_VBO->pushOnBuffer(m_vboIdCoordText, texturePos[1]);
+ m_VBO->pushOnBuffer(m_vboIdCoordText, texturePos[2]);
+ // set display positions :
+ m_VBO->pushOnBuffer(m_vboIdCoord, bitmapDrawPos[0]);
+ m_VBO->pushOnBuffer(m_vboIdCoord, bitmapDrawPos[1]);
+ m_VBO->pushOnBuffer(m_vboIdCoord, bitmapDrawPos[2]);
+ // set the color
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ // set the bliph level
+ m_VBO->pushOnBuffer(m_vboIdGlyphLevel, glyphLevel);
+ m_VBO->pushOnBuffer(m_vboIdGlyphLevel, glyphLevel);
+ m_VBO->pushOnBuffer(m_vboIdGlyphLevel, glyphLevel);
+ /* Step 2 :
+ *
+ * **
+ * ****
+ * ******
+ * ********
+ */
+ // set texture coordonates :
+ m_VBO->pushOnBuffer(m_vboIdCoordText, texturePos[0]);
+ m_VBO->pushOnBuffer(m_vboIdCoordText, texturePos[2]);
+ m_VBO->pushOnBuffer(m_vboIdCoordText, texturePos[3]);
+ // set display positions :
+ m_VBO->pushOnBuffer(m_vboIdCoord, bitmapDrawPos[0]);
+ m_VBO->pushOnBuffer(m_vboIdCoord, bitmapDrawPos[2]);
+ m_VBO->pushOnBuffer(m_vboIdCoord, bitmapDrawPos[3]);
+ // set the color
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ m_VBO->pushOnBuffer(m_vboIdColor, m_color);
+ // set the bliph level
+ m_VBO->pushOnBuffer(m_vboIdGlyphLevel, glyphLevel);
+ m_VBO->pushOnBuffer(m_vboIdGlyphLevel, glyphLevel);
+ m_VBO->pushOnBuffer(m_vboIdGlyphLevel, glyphLevel);
+ }
+ }
+ }
+ }
+ // move the position :
+ //EWOL_DEBUG(" 5 pos=" << m_position << " advance=" << myGlyph->m_advance.x() << " kerningOffset=" << kerningOffset);
+ m_position.setX(m_position.x() + (myGlyph->m_advance.x() + kerningOffset) * factorDisplay);
+ //EWOL_DEBUG(" 6 print '" << charcode << "' : start=" << m_sizeDisplayStart << " stop=" << m_sizeDisplayStop << " pos=" << m_position);
+ // Register the previous character
+ m_previousCharcode = _charcode;
+ m_VBO->flush();
+ return;
+}
+
+
+vec3 ewol::compositing::TextDF::calculateSizeChar(const char32_t& _charcode) {
+ // get a pointer on the glyph property :
+ ewol::GlyphProperty * myGlyph = getGlyphPointer(_charcode);
+ int32_t fontHeigh = getHeight();
+
+ // get the kerning ofset :
+ float kerningOffset = 0.0;
+ if (true == m_kerning) {
+ kerningOffset = myGlyph->kerningGet(m_previousCharcode);
+ }
+
+ vec3 outputSize((float)(myGlyph->m_advance.x() + kerningOffset)*m_fontDF->getDisplayRatio(getSize()),
+ (float)(fontHeigh),
+ (float)(0.0));
+ // Register the previous character
+ m_previousCharcode = _charcode;
+ return outputSize;
+}
+
+
diff --git a/src/org/atriasoft/ewol/compositing/TextDF.java b/src/org/atriasoft/ewol/compositing/TextDF.java
new file mode 100644
index 0000000..6bc6ba7
--- /dev/null
+++ b/src/org/atriasoft/ewol/compositing/TextDF.java
@@ -0,0 +1,70 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace ewol {
+ namespace compositing {
+ class TextDF : public ewol::compositing::TextBase {
+ protected:
+ ememory::SharedPtr m_fontDF; //!< Font resources
+ protected:
+ int32_t m_GLglyphLevel; //!< openGL Id on the glyph level display
+ public:
+ /**
+ * @brief generic constructor
+ * @param[in] _fontName Name of the font that might be loaded
+ * @param[in] _fontSize size of the font that might be loaded
+ */
+ TextDF(const etk::String& _fontName="", int32_t _fontSize=-1);
+ /**
+ * @brief generic destructor
+ */
+ virtual ~TextDF();
+ public:
+ /**
+ * @brief Calculate size to be at the best size for a render in this special size.
+ * @note special for Distance field mode.
+ * @param[in] _size request dimention.
+ */
+ void updateSizeToRender(const vec2& _size);
+ public:
+ virtual void drawD(bool _disableDepthTest);
+ virtual void drawMT(const mat4& _transformationMatrix, bool _enableDepthTest);
+ protected:
+ float m_size;
+ public:
+ virtual float getHeight();
+ virtual float getSize() {
+ return m_size;
+ }
+ virtual void setSize(float _size) {
+ m_size = _size;
+ }
+ virtual ewol::GlyphProperty * getGlyphPointer(char32_t _charcode);
+
+ public:
+ virtual void loadProgram(const etk::String& _shaderName);
+ virtual void setFontSize(int32_t _fontSize);
+ virtual void setFontName(const etk::String& _fontName);
+ virtual void setFont(etk::String _fontName, int32_t _fontSize);
+ virtual void setFontMode(enum ewol::font::mode _mode);
+ virtual void printChar(const char32_t& _charcode);
+ virtual vec3 calculateSizeChar(const char32_t& _charcode);
+ };
+ }
+}
+
+
diff --git a/src/org/atriasoft/ewol/context/Application.cpp b/src/org/atriasoft/ewol/context/Application.cpp
new file mode 100644
index 0000000..cbc08b3
--- /dev/null
+++ b/src/org/atriasoft/ewol/context/Application.cpp
@@ -0,0 +1,49 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+#include
+#include
+
+#include
+ETK_DECLARE_TYPE(ewol::context::Application);
+
+ewol::context::Application::Application() {
+
+}
+
+ewol::context::Application::~Application() {
+
+}
+
+void ewol::context::Application::onCreate(ewol::Context& _context) {
+
+}
+
+void ewol::context::Application::onStart(ewol::Context& _context) {
+
+}
+
+void ewol::context::Application::onResume(ewol::Context& _context) {
+
+}
+
+void ewol::context::Application::onPause(ewol::Context& _context) {
+
+}
+
+void ewol::context::Application::onStop(ewol::Context& _context) {
+
+}
+
+void ewol::context::Application::onDestroy(ewol::Context& _context) {
+
+}
+
+void ewol::context::Application::onKillDemand(ewol::Context& _context) {
+ _context.exit(0);
+}
+
diff --git a/src/org/atriasoft/ewol/context/Application.java b/src/org/atriasoft/ewol/context/Application.java
new file mode 100644
index 0000000..0dacf17
--- /dev/null
+++ b/src/org/atriasoft/ewol/context/Application.java
@@ -0,0 +1,54 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#pragma once
+
+namespace ewol {
+ class Context;
+ namespace context {
+ class Application {
+ public:
+ Application();
+ virtual ~Application();
+ public:
+ /**
+ * @brief The application is created.
+ * @param[in] _context Current ewol context.
+ */
+ virtual void onCreate(ewol::Context& _context);
+ /**
+ * @brief The application is started.
+ * @param[in] _context Current ewol context.
+ */
+ virtual void onStart(ewol::Context& _context);
+ /**
+ * @brief The application is resumed (now visible).
+ * @param[in] _context Current ewol context.
+ */
+ virtual void onResume(ewol::Context& _context);
+ /**
+ * @brief The application is Hide / not visible.
+ * @param[in] _context Current ewol context.
+ */
+ virtual void onPause(ewol::Context& _context);
+ /**
+ * @brief The application is stopped.
+ * @param[in] _context Current ewol context.
+ */
+ virtual void onStop(ewol::Context& _context);
+ /**
+ * @brief The application is removed (call destructor just adter it.).
+ * @param[in] _context Current ewol context.
+ */
+ virtual void onDestroy(ewol::Context& _context);
+ /**
+ * @brief The user request application removing.
+ * @param[in] _context Current ewol context.
+ */
+ virtual void onKillDemand(ewol::Context& _context);
+ };
+ };
+};
diff --git a/src/org/atriasoft/ewol/context/ConfigFont.cpp b/src/org/atriasoft/ewol/context/ConfigFont.cpp
new file mode 100644
index 0000000..886a4ab
--- /dev/null
+++ b/src/org/atriasoft/ewol/context/ConfigFont.cpp
@@ -0,0 +1,43 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+#include
+#include
+ETK_DECLARE_TYPE(ewol::context::ConfigFont);
+
+ewol::context::ConfigFont::ConfigFont() :
+ m_folder("DATA:///fonts?lib=ewol"),
+ m_name("Arial;Helvetica"),
+ m_size(10),
+ m_useExternal(false) {
+ #ifdef __TARGET_OS__Android
+ m_name = "Roboto;DroidSans";
+ #endif
+ ewol::resource::freeTypeInit();
+}
+
+ewol::context::ConfigFont::~ConfigFont() {
+ // UnInit FreeTypes
+ ewol::resource::freeTypeUnInit();
+}
+
+void ewol::context::ConfigFont::set(const etk::String& _fontName, int32_t _size) {
+ m_name = _fontName;
+ m_size = _size;
+ EWOL_DEBUG("Set default Font : '" << m_name << "' size=" << m_size);
+}
+
+void ewol::context::ConfigFont::setSize(int32_t _size) {
+ m_size = _size;
+ EWOL_DEBUG("Set default Font : '" << m_name << "' size=" << m_size << " (change size only)");
+}
+
+void ewol::context::ConfigFont::setName(const etk::String& _fontName) {
+ m_name = _fontName;
+ EWOL_DEBUG("Set default Font : '" << m_name << "' size=" << m_size << " (change name only)");
+}
+
diff --git a/src/org/atriasoft/ewol/context/ConfigFont.java b/src/org/atriasoft/ewol/context/ConfigFont.java
new file mode 100644
index 0000000..837d696
--- /dev/null
+++ b/src/org/atriasoft/ewol/context/ConfigFont.java
@@ -0,0 +1,92 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+
+#include
+#include
+
+namespace ewol {
+ namespace context {
+ class ConfigFont {
+ public:
+ /**
+ * Constructor / destructor
+ */
+ ConfigFont();
+ virtual ~ConfigFont();
+ private:
+ etk::Uri m_folder;
+ public:
+ /**
+ * @brief Specify the default font folder for the Ewol search system (only needed when embended font)
+ * @param[in] _folder basic folder of the font (ex: DATA:fonts)
+ */
+ void setFolder(const etk::Uri& _folder) {
+ m_folder = _folder;
+ };
+ /**
+ * @brief get the default font folder.
+ * @return The default font folder.
+ */
+ const etk::Uri& getFolder() {
+ return m_folder;
+ };
+ private:
+ etk::String m_name;
+ int32_t m_size;
+ public:
+ /**
+ * @brief set the defaut font for all the widgets and basics display.
+ * @param[in] _fontName The font name requested (not case sensitive) ex "Arial" or multiple separate by ';' ex : "Arial;Helvetica".
+ * @param[in] _size The default size of the font default=10.
+ */
+ void set(const etk::String& _fontName, int32_t _size);
+ /**
+ * @brief get the current default font name
+ * @raturn a reference on the font name string
+ */
+ const etk::String& getName() {
+ return m_name;
+ };
+ /**
+ * @brief Set the current default font name
+ * @param[in] _fontName The font name requested (not case sensitive) ex "Arial" or multiple separate by ';' ex : "Arial;Helvetica".
+ */
+ void setName(const etk::String& _fontName);
+ /**
+ * @brief get the default font size.
+ * @return the font size.
+ */
+ int32_t getSize() {
+ return m_size;
+ };
+ /**
+ * @brief Set the default font size.
+ * @param[in] _size new font size.
+ */
+ void setSize(int32_t _size);
+ private:
+ bool m_useExternal;
+ public:
+ /**
+ * @brief set use of internal/external Font
+ * @param[in] _val true to enable search of internal data.
+ */
+ void setUseExternal(bool _val) {
+ m_useExternal=_val;
+ };
+ /**
+ * @brief get the use of internal/external Font
+ * @return true to enable search of internal data.
+ */
+ bool getUseExternal() {
+ return m_useExternal;
+ };
+ };
+ };
+};
+
+
diff --git a/src/org/atriasoft/ewol/context/Context.cpp b/src/org/atriasoft/ewol/context/Context.cpp
new file mode 100644
index 0000000..c25c10a
--- /dev/null
+++ b/src/org/atriasoft/ewol/context/Context.cpp
@@ -0,0 +1,382 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+ETK_DECLARE_TYPE(ewol::Context);
+
+static ewol::Context* l_curentInterface=null;
+ewol::Context& ewol::getContext() {
+ gale::Context& context = gale::getContext();
+ ememory::SharedPtr appl = context.getApplication();
+ if (appl == null) {
+ EWOL_CRITICAL("[CRITICAL] try acces at an empty GALE application (can not get Context)");
+ // ???
+ }
+ return *(ememory::staticPointerCast(appl));
+}
+
+
+void ewol::Context::setInitImage(const etk::Uri& _fileName) {
+ //m_initDisplayImageName = _fileName;
+}
+
+
+
+void ewol::Context::inputEventTransfertWidget(ewol::WidgetShared _source,
+ ewol::WidgetShared _destination) {
+ m_input.transfertEvent(_source, _destination);
+}
+
+
+void ewol::Context::inputEventGrabPointer(ewol::WidgetShared _widget) {
+ m_input.grabPointer(_widget);
+}
+
+void ewol::Context::inputEventUnGrabPointer() {
+ m_input.unGrabPointer();
+}
+
+
+void ewol::Context::onCreate(gale::Context& _context) {
+ EWOL_INFO(" == > Ewol system create (BEGIN)");
+ // Add basic ewol translation:
+ etranslate::addPath("ewol", "DATA:///translate/ewol/?lib=ewol");
+ etranslate::autoDetectLanguage();
+ // By default we set 2 themes (1 color and 1 shape ...) :
+ etk::theme::setNameDefault("GUI", "shape/square/");
+ etk::theme::setNameDefault("COLOR", "color/black/");
+ // parse for help:
+ for(int32_t iii = 0; iii < _context.getCmd().size() ; ++iii) {
+ if ( _context.getCmd().get(iii) == "-h"
+ || _context.getCmd().get(iii) == "--help") {
+ EWOL_PRINT("ewol - help : ");
+ EWOL_PRINT(" " << etk::getApplicationName() << " [options]");
+ EWOL_PRINT(" -h/--help: Display this help");
+ EWOL_PRINT(" example:");
+ EWOL_PRINT(" " << etk::getApplicationName() << " --help");
+ // this is a global help system does not remove it
+ continue;
+ } else {
+ continue;
+ }
+ _context.getCmd().remove(iii);
+ --iii;
+ }
+
+ EWOL_INFO("EWOL v:" << ewol::getVersion());
+ // force a recalculation
+ /*
+ requestUpdateSize();
+ #if defined(__EWOL_ANDROID_ORIENTATION_LANDSCAPE__)
+ forceOrientation(ewol::screenLandscape);
+ #elif defined(__EWOL_ANDROID_ORIENTATION_PORTRAIT__)
+ forceOrientation(ewol::screenPortrait);
+ #else
+ forceOrientation(ewol::screenAuto);
+ #endif
+ */
+ ememory::SharedPtr appl = m_application;
+ if (appl == null) {
+ EWOL_ERROR(" == > Create without application");
+ return;
+ }
+ appl->onCreate(*this);
+ EWOL_INFO(" == > Ewol system create (END)");
+}
+
+void ewol::Context::onStart(gale::Context& _context) {
+ EWOL_INFO(" == > Ewol system start (BEGIN)");
+ ememory::SharedPtr appl = m_application;
+ if (appl == null) {
+ // TODO : Request exit of the application .... with error ...
+ return;
+ }
+ appl->onStart(*this);
+ EWOL_INFO(" == > Ewol system start (END)");
+}
+
+void ewol::Context::onResume(gale::Context& _context) {
+ EWOL_INFO(" == > Ewol system resume (BEGIN)");
+ ememory::SharedPtr appl = m_application;
+ if (appl == null) {
+ return;
+ }
+ appl->onResume(*this);
+ EWOL_INFO(" == > Ewol system resume (END)");
+}
+
+void ewol::Context::onRegenerateDisplay(gale::Context& _context) {
+ //EWOL_INFO("REGENERATE_DISPLAY");
+ // check if the user selected a windows
+ ewol::widget::WindowsShared window = m_windowsCurrent;
+ if (window == null) {
+ EWOL_DEBUG("No windows ...");
+ return;
+ }
+ // Redraw all needed elements
+ window->onRegenerateDisplay();
+ if (m_widgetManager.isDrawingNeeded() == true) {
+ markDrawingIsNeeded();
+ }
+ //markDrawingIsNeeded();
+}
+
+void ewol::Context::onDraw(gale::Context& _context) {
+ //EWOL_INFO("DRAW");
+ // clean internal data...
+ m_objectManager.cleanInternalRemoved();
+ // real draw...
+ ewol::widget::WindowsShared window = m_windowsCurrent;
+ if (window == null) {
+ return;
+ }
+ window->sysDraw();
+}
+
+void ewol::Context::onPause(gale::Context& _context) {
+ EWOL_INFO(" == > Ewol system pause (BEGIN)");
+ ememory::SharedPtr appl = m_application;
+ if (appl == null) {
+ return;
+ }
+ appl->onPause(*this);
+ EWOL_INFO(" == > Ewol system pause (END)");
+}
+
+void ewol::Context::onStop(gale::Context& _context) {
+ EWOL_INFO(" == > Ewol system stop (BEGIN)");
+ ememory::SharedPtr appl = m_application;
+ if (appl == null) {
+ return;
+ }
+ appl->onStop(*this);
+ EWOL_INFO(" == > Ewol system stop (END)");
+}
+
+void ewol::Context::onDestroy(gale::Context& _context) {
+ EWOL_INFO(" == > Ewol system destroy (BEGIN)");
+ // Remove current windows
+ m_windowsCurrent.reset();
+ // clean all widget and sub widget with their resources:
+ m_objectManager.cleanInternalRemoved();
+ ememory::SharedPtr appl = m_application;
+ if (appl != null) {
+ // call application to uninit
+ appl->onDestroy(*this);
+ m_application.reset();
+ }
+ // internal clean elements
+ m_objectManager.cleanInternalRemoved();
+ EWOL_INFO("List of all widget of this context must be equal at 0 ==> otherwise some remove is missing");
+ m_objectManager.displayListObject();
+ // now All must be removed !!!
+ m_objectManager.unInit();
+ EWOL_INFO(" == > Ewol system destroy (END)");
+}
+
+void ewol::Context::onKillDemand(gale::Context& _context) {
+ EWOL_INFO(" == > User demand a destroy (BEGIN)");
+ ememory::SharedPtr appl = m_application;
+ if (appl == null) {
+ exit(0);
+ return;
+ }
+ appl->onKillDemand(*this);
+ EWOL_INFO(" == > User demand a destroy (END)");
+}
+
+void ewol::Context::onPointer(enum gale::key::type _type,
+ int32_t _pointerID,
+ const vec2& _pos,
+ gale::key::status _state) {
+ switch (_state) {
+ case gale::key::status::move:
+ //EWOL_DEBUG("Receive MSG : THREAD_INPUT_MOTION");
+ m_input.motion(_type, _pointerID, _pos);
+ break;
+ case gale::key::status::down:
+ case gale::key::status::downRepeate:
+ //EWOL_DEBUG("Receive MSG : THREAD_INPUT_STATE");
+ m_input.state(_type, _pointerID, true, _pos);
+ break;
+ case gale::key::status::up:
+ //EWOL_DEBUG("Receive MSG : THREAD_INPUT_STATE");
+ m_input.state(_type, _pointerID, false, _pos);
+ break;
+ default:
+ EWOL_DEBUG("Unknow state : " << _state);
+ break;
+ }
+}
+void ewol::Context::onKeyboard(const gale::key::Special& _special,
+ enum gale::key::keyboard _type,
+ char32_t _value,
+ gale::key::status _state) {
+ EWOL_VERBOSE("event {" << _special << "} " << _type << " " << _value << " " << _state);
+ // store the keyboard special key status for mouse event...
+ m_input.setLastKeyboardSpecial(_special);
+ if (m_windowsCurrent == null) {
+ // No windows ...
+ return;
+ }
+ bool repeate = (_state == gale::key::status::downRepeate);
+ bool isDown = (_state == gale::key::status::downRepeate)
+ || (_state == gale::key::status::down);
+ if (m_windowsCurrent->onEventShortCut(_special,
+ _value,
+ _type,
+ isDown) == true) {
+ // Keep a shortcut ...
+ return;
+ }
+ // get the current focused Widget :
+ ewol::WidgetShared tmpWidget = m_widgetManager.focusGet();
+ if (tmpWidget == null) {
+ // no Widget ...
+ return;
+ }
+ // check if the widget allow repeating key events.
+ //EWOL_INFO("repeating test :" << repeate << " widget=" << tmpWidget->getKeyboardRepeate() << " state=" << isDown);
+ if( repeate == false
+ || ( repeate == true
+ && tmpWidget->getKeyboardRepeat() == true) ) {
+ // check Widget shortcut
+ if (tmpWidget->onEventShortCut(_special,
+ _value,
+ _type,
+ isDown) == false) {
+ // generate the direct event ...
+ if (_type == gale::key::keyboard::character) {
+ ewol::event::EntrySystem tmpEntryEvent(gale::key::keyboard::character,
+ gale::key::status::up,
+ _special,
+ _value);
+ if(isDown == true) {
+ tmpEntryEvent.m_event.setStatus(gale::key::status::down);
+ }
+ tmpWidget->systemEventEntry(tmpEntryEvent);
+ } else { // THREAD_KEYBORAD_MOVE
+ ewol::event::EntrySystem tmpEntryEvent(_type,
+ gale::key::status::up,
+ _special,
+ 0);
+ if(isDown == true) {
+ tmpEntryEvent.m_event.setStatus(gale::key::status::down);
+ }
+ tmpWidget->systemEventEntry(tmpEntryEvent);
+ }
+ } else {
+ EWOL_DEBUG("remove Repeate key ...");
+ }
+ }
+}
+
+/*
+void ewol::Context::processEvents() {
+ case eSystemMessage::msgResize:
+ //EWOL_DEBUG("Receive MSG : THREAD_RESIZE");
+ m_windowsSize = data->dimention;
+ ewol::Dimension::setPixelWindowsSize(m_windowsSize);
+ forceRedrawAll();
+ break;
+*/
+
+void ewol::Context::onClipboardEvent(enum gale::context::clipBoard::clipboardListe _clipboardId) {
+ ewol::WidgetShared tmpWidget = m_widgetManager.focusGet();
+ if (tmpWidget != null) {
+ tmpWidget->onEventClipboard(_clipboardId);
+ }
+}
+
+
+ewol::Context::Context(ewol::context::Application* _application) :
+ //m_application(ememory::makeShared(_application)),
+ m_application(_application),
+ m_objectManager(*this),
+ m_input(*this),
+ m_windowsCurrent(null),
+ m_initStepId(0) {
+ if (m_application == null) {
+ EWOL_CRITICAL("Can not start context with no Application ==> rtfm ...");
+ }
+}
+
+ewol::Context::~Context() {
+ // nothing to do ...
+}
+
+void ewol::Context::requestUpdateSize() {
+ gale::Context& context = gale::getContext();
+ context.requestUpdateSize();
+}
+
+void ewol::Context::onPeriod(const echrono::Clock& _time) {
+ m_objectManager.timeCall(_time);
+}
+
+void ewol::Context::resetIOEvent() {
+ m_input.newLayerSet();
+}
+
+void ewol::Context::setWindows(const ewol::widget::WindowsShared& _windows) {
+ EWOL_INFO("set New windows");
+ // remove current focus :
+ m_widgetManager.focusSetDefault(null);
+ m_widgetManager.focusRelease();
+ // set the new pointer as windows system
+ m_windowsCurrent = _windows;
+ // set the new default focus:
+ m_widgetManager.focusSetDefault(_windows);
+ // display the title of the Windows:
+ if (m_windowsCurrent != null) {
+ setTitle(m_windowsCurrent->propertyTitle.get());
+ }
+ // request all the widget redrawing
+ forceRedrawAll();
+}
+
+ewol::widget::WindowsShared ewol::Context::getWindows() {
+ return m_windowsCurrent;
+};
+void ewol::Context::onResize(const ivec2& _size) {
+ EWOL_VERBOSE("Resize: " << _size);
+ forceRedrawAll();
+}
+
+void ewol::Context::forceRedrawAll() {
+ if (m_windowsCurrent == null) {
+ return;
+ }
+ ivec2 size = getSize();
+ m_windowsCurrent->setSize(vec2(size.x(), size.y()));
+ m_windowsCurrent->onChangeSize();
+}
+
diff --git a/src/org/atriasoft/ewol/context/Context.java b/src/org/atriasoft/ewol/context/Context.java
new file mode 100644
index 0000000..8adf8ea
--- /dev/null
+++ b/src/org/atriasoft/ewol/context/Context.java
@@ -0,0 +1,159 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace ewol {
+ // Here we hereted from the gale application to be agnostic of the OW where we work ...
+ class Context : public gale::Application {
+ private:
+ ememory::SharedPtr m_application; //!< Application handle
+ public:
+ ememory::SharedPtr getApplication() {
+ return m_application;
+ }
+ public:
+ gale::context::CommandLine& getCmd() {
+ return gale::getContext().getCmd();
+ };
+ private:
+ ewol::context::ConfigFont m_configFont; //!< global font configuration
+ public:
+ ewol::context::ConfigFont& getFontDefault() {
+ return m_configFont;
+ };
+ private:
+ ewol::object::Manager m_objectManager; //!< Object Manager main instance
+ public:
+ ewol::object::Manager& getEObjectManager() {
+ return m_objectManager;
+ };
+ private:
+ ewol::widget::Manager m_widgetManager; //!< global widget manager
+ public:
+ ewol::widget::Manager& getWidgetManager() {
+ return m_widgetManager;
+ };
+ public:
+ gale::resource::Manager& getResourcesManager() {
+ return gale::getContext().getResourcesManager();
+ };
+ public:
+ Context(ewol::context::Application* _application);
+ virtual ~Context();
+ private:
+ ewol::context::InputManager m_input;
+ public: // herited function:
+ void onCreate(gale::Context& _context) override;
+ void onStart(gale::Context& _context) override;
+ void onResume(gale::Context& _context) override;
+ void onRegenerateDisplay(gale::Context& _context) override;
+ void onDraw(gale::Context& _context) override;
+ void onPause(gale::Context& _context) override;
+ void onStop(gale::Context& _context) override;
+ void onDestroy(gale::Context& _context) override;
+ void onKillDemand(gale::Context& _context) override;
+ void onPointer(enum gale::key::type _type,
+ int32_t _pointerID,
+ const vec2& _pos,
+ gale::key::status _state) override;
+ void onKeyboard(const gale::key::Special& _special,
+ enum gale::key::keyboard _type,
+ char32_t _value,
+ gale::key::status _state) override;
+ void onClipboardEvent(enum gale::context::clipBoard::clipboardListe _clipboardId) override;
+ public:
+ /**
+ * @brief reset event management for the IO like Input ou Mouse or keyborad
+ */
+ void resetIOEvent();
+ private:
+ ewol::widget::WindowsShared m_windowsCurrent; //!< curent displayed windows
+ public:
+ /**
+ * @brief set the current windows to display :
+ * @param _windows Windows that might be displayed
+ */
+ void setWindows(const ewol::widget::WindowsShared& _windows);
+ /**
+ * @brief get the current windows that is displayed
+ * @return the current handle on the windows (can be null)
+ */
+ ewol::widget::WindowsShared getWindows();
+
+ /**
+ * @brief Redraw all the windows
+ */
+ void forceRedrawAll();
+
+ /**
+ * @brief This is to transfert the event from one widget to another one
+ * @param source the widget where the event came from
+ * @param destination the widget where the event mitgh be generated now
+ */
+ void inputEventTransfertWidget(ewol::WidgetShared _source, ewol::WidgetShared _destination);
+ /**
+ * @brief This fonction lock the pointer properties to move in relative instead of absolute
+ * @param[in] widget The widget that lock the pointer events
+ */
+ void inputEventGrabPointer(ewol::WidgetShared _widget);
+ /**
+ * @brief This fonction un-lock the pointer properties to move in relative instead of absolute
+ */
+ void inputEventUnGrabPointer();
+ void onResize(const ivec2& _size) override;
+ public:
+ /**
+ * @brief This is the only one things the User might done in his main();
+ * @note : must be implemented in all system OPS implementation
+ * @note To answare you before you ask the question, this is really simple:
+ * Due to the fect that the current system is multiple-platform, you "main"
+ * Does not exist in the android platform, then ewol call other start
+ * and stop function, to permit to have only one code
+ * @note The main can not be in the ewol, due to the fact thet is an librairy
+ * @param[in] _argc Standard argc
+ * @param[in] _argv Standard argv
+ * @return normal error int for the application error management
+ */
+ static int main(int _argc, const char *_argv[]);
+ private:
+ size_t m_initStepId;
+ size_t m_initTotalStep;
+ public:
+ /**
+ * @brief Special for init (main) set the start image when loading data
+ * @param[in] _fileName Name of the image to load
+ */
+ void setInitImage(const etk::Uri& _fileName);
+ public:
+ /**
+ * @brief Request a display after call a resize
+ */
+ void requestUpdateSize();
+ void onPeriod(const echrono::Clock& _time) override;
+ };
+ /**
+ * @brief From everyware in the program, we can get the context inteface.
+ * @return current reference on the instance.
+ */
+ Context& getContext();
+};
+
diff --git a/src/org/atriasoft/ewol/context/InputManager.cpp b/src/org/atriasoft/ewol/context/InputManager.cpp
new file mode 100644
index 0000000..0e57cd8
--- /dev/null
+++ b/src/org/atriasoft/ewol/context/InputManager.cpp
@@ -0,0 +1,502 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+ETK_DECLARE_TYPE(ewol::context::InputManager);
+
+#define EVENT_DEBUG EWOL_VERBOSE
+//#define EVENT_DEBUG EWOL_DEBUG
+
+void ewol::context::InputManager::calculateLimit() {
+ m_eventInputLimit.sepatateTime = echrono::Duration(echrono::milliseconds(300));
+ m_eventInputLimit.DpiOffset = m_dpi*100;
+ m_eventMouseLimit.sepatateTime = echrono::Duration(echrono::milliseconds(300));
+ m_eventMouseLimit.DpiOffset = float(m_dpi)*0.1f;
+}
+
+void ewol::context::InputManager::setDpi(int32_t newDPI) {
+ m_dpi = newDPI;
+ // recalculate the DPI system ...
+ calculateLimit();
+}
+
+bool ewol::context::InputManager::localEventInput(enum gale::key::type _type,
+ ewol::WidgetShared _destWidget,
+ int32_t _IdInput,
+ enum gale::key::status _status,
+ vec2 _pos) {
+ if (_destWidget != null) {
+ if ( _type == gale::key::type::mouse
+ || _type == gale::key::type::finger) {
+ // create the system Event :
+ ewol::event::InputSystem tmpEventSystem(_type, _status, _IdInput, _pos, _destWidget, 0, m_specialKey); // TODO : set the real ID ...
+ // generate the event :
+ return _destWidget->systemEventInput(tmpEventSystem);
+ } else {
+ return false;
+ }
+ }
+ return false;
+}
+
+void ewol::context::InputManager::abortElement(InputPoperty *_eventTable,
+ int32_t _idInput,
+ enum gale::key::type _type) {
+ if (_eventTable == null) {
+ return;
+ }
+ if (_eventTable[_idInput].isUsed == true) {
+ localEventInput(_type,
+ _eventTable[_idInput].curentWidgetEvent.lock(),
+ _eventTable[_idInput].destinationInputId,
+ gale::key::status::abort,
+ _eventTable[_idInput].posEvent);
+ }
+}
+
+void ewol::context::InputManager::cleanElement(InputPoperty *_eventTable,
+ int32_t _idInput) {
+ if (_eventTable == null) {
+ return;
+ }
+ //EWOL_INFO("CleanElement[" << idInput << "] = @" << (int64_t)eventTable);
+ _eventTable[_idInput].isUsed = false;
+ _eventTable[_idInput].destinationInputId = 0;
+ _eventTable[_idInput].lastTimeEvent.reset();
+ _eventTable[_idInput].curentWidgetEvent.reset();
+ _eventTable[_idInput].origin.setValue(0,0);
+ _eventTable[_idInput].size.setValue(99999999,99999999);
+ _eventTable[_idInput].downStart.setValue(0,0);
+ _eventTable[_idInput].isDown = false;
+ _eventTable[_idInput].isInside = false;
+ _eventTable[_idInput].nbClickEvent = 0;
+ _eventTable[_idInput].posEvent.setValue(0,0);
+}
+
+void ewol::context::InputManager::transfertEvent(ewol::WidgetShared _source, ewol::WidgetShared _destination) {
+ if( _source == null
+ || _destination == null) {
+ // prevent errors ...
+ return;
+ }
+ for(int32_t iii=0; iii" << m_eventInputSaved[iii].destinationInputId << " [EVENT_INPUT_TYPE_ABORT] " << m_eventInputSaved[iii].posEvent);
+ localEventInput(gale::key::type::finger, tmpWidget, m_eventInputSaved[iii].destinationInputId, gale::key::status::abort, m_eventInputSaved[iii].posEvent);
+ // set the new widget ...
+ m_eventInputSaved[iii].curentWidgetEvent = _destination;
+ // inform the widget that he receive the event property now...
+ EVENT_DEBUG("GUI : Input ID=" << iii << " == >" << m_eventInputSaved[iii].destinationInputId << " [EVENT_INPUT_TYPE_TRANSFERT] " << m_eventInputSaved[iii].posEvent);
+ localEventInput(gale::key::type::finger, _destination, m_eventInputSaved[iii].destinationInputId, gale::key::status::transfert, m_eventInputSaved[iii].posEvent);
+ }
+ tmpWidget = m_eventMouseSaved[iii].curentWidgetEvent.lock();
+ if (tmpWidget == _source) {
+ // inform the widget that it does not receive the event now
+ EVENT_DEBUG("GUI : Input ID=" << iii << " == >" << m_eventMouseSaved[iii].destinationInputId << " [EVENT_INPUT_TYPE_ABORT] " << m_eventMouseSaved[iii].posEvent);
+ localEventInput(gale::key::type::mouse, tmpWidget, m_eventMouseSaved[iii].destinationInputId, gale::key::status::abort, m_eventMouseSaved[iii].posEvent);
+ // set the new widget ...
+ m_eventMouseSaved[iii].curentWidgetEvent = _destination;
+ // inform the widget that he receive the event property now...
+ EVENT_DEBUG("GUI : Input ID=" << iii << " == >" << m_eventMouseSaved[iii].destinationInputId << " [EVENT_INPUT_TYPE_TRANSFERT] " << m_eventMouseSaved[iii].posEvent);
+ localEventInput(gale::key::type::mouse, _destination, m_eventMouseSaved[iii].destinationInputId, gale::key::status::transfert, m_eventMouseSaved[iii].posEvent);
+ }
+ }
+}
+
+void ewol::context::InputManager::grabPointer(ewol::WidgetShared _widget) {
+ if(_widget == null) {
+ return;
+ }
+ m_grabWidget = _widget;
+ /* TODO :
+ m_context.grabPointerEvents(true, _widget->getOrigin()
+ + ivec2(_widget->getSize().x()/2.0f,
+ _widget->getSize().y()/2.0f) );
+ */
+}
+
+void ewol::context::InputManager::unGrabPointer() {
+ m_grabWidget.reset();
+ // TODO: m_context.grabPointerEvents(false, vec2(0,0));
+}
+
+void ewol::context::InputManager::newLayerSet() {
+ for(int32_t iii=0; iii the it was finger event ...
+void ewol::context::InputManager::motion(enum gale::key::type _type,
+ int _pointerID,
+ vec2 _pos) {
+ EVENT_DEBUG("motion event : " << _type << " " << _pointerID << " " << _pos);
+ if (MAX_MANAGE_INPUT <= _pointerID) {
+ // reject pointer == > out of IDs...
+ return;
+ }
+ InputPoperty *eventTable = null;
+ if (_type == gale::key::type::mouse) {
+ eventTable = m_eventMouseSaved;
+ } else if (_type == gale::key::type::finger) {
+ eventTable = m_eventInputSaved;
+ } else {
+ EWOL_ERROR("Unknown type of event");
+ return;
+ }
+ if( _pointerID > MAX_MANAGE_INPUT
+ || _pointerID < 0) {
+ // not manage input
+ return;
+ }
+ ewol::widget::WindowsShared tmpWindows = m_context.getWindows();
+ // special case for the mouse event 0 that represent the hover event of the system :
+ if ( _type == gale::key::type::mouse
+ && _pointerID == 0) {
+ // this event is all time on the good widget ... and manage the enter and leave ...
+ // NOTE : the "layer widget" force us to get the widget at the specific position all the time :
+ ewol::WidgetShared tmpWidget;
+ if (m_grabWidget.lock() != null) {
+ // grab all events ...
+ tmpWidget = m_grabWidget.lock();
+ } else {
+ if (tmpWindows != null) {
+ tmpWidget = tmpWindows->getWidgetAtPos(_pos);
+ }
+ }
+ if( tmpWidget != eventTable[_pointerID].curentWidgetEvent.lock()
+ || ( eventTable[_pointerID].isInside == true
+ && ( eventTable[_pointerID].origin.x() > _pos.x()
+ || eventTable[_pointerID].origin.y() > _pos.y()
+ || (eventTable[_pointerID].origin.x() + eventTable[_pointerID].size.x()) < _pos.x()
+ || (eventTable[_pointerID].origin.y() + eventTable[_pointerID].size.y()) < _pos.y()) ) ) {
+ eventTable[_pointerID].isInside = false;
+ EVENT_DEBUG("GUI : Input ID=" << _pointerID << " == >" << eventTable[_pointerID].destinationInputId << " [LEAVE] " << _pos);
+ eventTable[_pointerID].posEvent = _pos;
+ localEventInput(_type,
+ eventTable[_pointerID].curentWidgetEvent.lock(),
+ eventTable[_pointerID].destinationInputId,
+ gale::key::status::leave,
+ _pos);
+ }
+ if (eventTable[_pointerID].isInside == false) {
+ // set the element inside ...
+ eventTable[_pointerID].isInside = true;
+ // get destination widget :
+ eventTable[_pointerID].curentWidgetEvent = tmpWidget;
+ if (tmpWidget == null) {
+ eventTable[_pointerID].isInside = false;
+ } else {
+ eventTable[_pointerID].origin = tmpWidget->getOrigin();
+ eventTable[_pointerID].size = tmpWidget->getSize();
+ }
+ eventTable[_pointerID].destinationInputId = 0;
+ EVENT_DEBUG("GUI : Input ID=" << _pointerID
+ << " == >" << eventTable[_pointerID].destinationInputId
+ << " [ENTER] " << _pos);
+ eventTable[_pointerID].posEvent = _pos;
+ localEventInput(_type,
+ tmpWidget,
+ eventTable[_pointerID].destinationInputId,
+ gale::key::status::enter,
+ _pos);
+ }
+ EVENT_DEBUG("GUI : Input ID=" << _pointerID
+ << " == >" << eventTable[_pointerID].destinationInputId
+ << " [MOVE] " << _pos);
+ eventTable[_pointerID].posEvent = _pos;
+ localEventInput(_type,
+ tmpWidget,
+ eventTable[_pointerID].destinationInputId,
+ gale::key::status::move,
+ _pos);
+ } else if (eventTable[_pointerID].isUsed == true) {
+ if (eventTable[_pointerID].isInside == true) {
+ if( eventTable[_pointerID].origin.x() > _pos.x()
+ || eventTable[_pointerID].origin.y() > _pos.y()
+ || (eventTable[_pointerID].origin.x() + eventTable[_pointerID].size.x()) < _pos.x()
+ || (eventTable[_pointerID].origin.y() + eventTable[_pointerID].size.y()) < _pos.y()) {
+ eventTable[_pointerID].isInside = false;
+ EVENT_DEBUG("GUI : Input ID=" << _pointerID
+ << " == >" << eventTable[_pointerID].destinationInputId
+ << " [LEAVE] " << _pos);
+ eventTable[_pointerID].posEvent = _pos;
+ localEventInput(_type,
+ eventTable[_pointerID].curentWidgetEvent.lock(),
+ eventTable[_pointerID].destinationInputId,
+ gale::key::status::leave,
+ _pos);
+ }
+ } else {
+ if( ( eventTable[_pointerID].origin.x() <= _pos.x()
+ && (eventTable[_pointerID].origin.x() + eventTable[_pointerID].size.x()) >= _pos.x() )
+ && ( eventTable[_pointerID].origin.y() <= _pos.y()
+ && (eventTable[_pointerID].origin.y() + eventTable[_pointerID].size.y()) >= _pos.y() ) ) {
+ eventTable[_pointerID].isInside = true;
+ EVENT_DEBUG("GUI : Input ID=" << _pointerID
+ << " == >" << eventTable[_pointerID].destinationInputId
+ << " [ENTER] " << _pos);
+ eventTable[_pointerID].posEvent = _pos;
+ localEventInput(_type,
+ eventTable[_pointerID].curentWidgetEvent.lock(),
+ eventTable[_pointerID].destinationInputId,
+ gale::key::status::enter,
+ _pos);
+ }
+ }
+ EVENT_DEBUG("GUI : Input ID=" << _pointerID
+ << " == >" << eventTable[_pointerID].destinationInputId
+ << " [MOVE] " << _pos);
+ eventTable[_pointerID].posEvent = _pos;
+ localEventInput(_type,
+ eventTable[_pointerID].curentWidgetEvent.lock(),
+ eventTable[_pointerID].destinationInputId,
+ gale::key::status::move,
+ _pos);
+ }
+}
+
+void ewol::context::InputManager::state(enum gale::key::type _type,
+ int _pointerID,
+ bool _isDown,
+ vec2 _pos) {
+ if (_pointerID >= MAX_MANAGE_INPUT) {
+ // reject pointer == > out of IDs...
+ return;
+ }
+ EVENT_DEBUG("event pointerId=" << _pointerID);
+ // convert position in open-GL coordonates ...
+ InputPoperty *eventTable = null;
+ InputLimit localLimit;
+ if (_type == gale::key::type::mouse) {
+ eventTable = m_eventMouseSaved;
+ localLimit = m_eventMouseLimit;
+ } else if (_type == gale::key::type::finger) {
+ eventTable = m_eventInputSaved;
+ localLimit = m_eventInputLimit;
+ } else {
+ EWOL_ERROR("Unknown type of event");
+ return;
+ }
+ if( _pointerID > MAX_MANAGE_INPUT
+ || _pointerID <= 0) {
+ // not manage input
+ return;
+ }
+ // get the curent time ...
+ echrono::Clock currentTime = echrono::Clock::now();
+ ewol::widget::WindowsShared tmpWindows = m_context.getWindows();
+
+ if (_isDown == true) {
+ EVENT_DEBUG("GUI : Input ID=" << _pointerID
+ << " == >" << eventTable[_pointerID].destinationInputId
+ << " [DOWN] " << _pos);
+ if(eventTable[_pointerID].isUsed == true) {
+ // we have an event previously ... check delay between click and offset position
+ if (currentTime - eventTable[_pointerID].lastTimeEvent > localLimit.sepatateTime) {
+ cleanElement(eventTable, _pointerID);
+ } else if( etk::abs(eventTable[_pointerID].downStart.x() - _pos.x()) >= localLimit.DpiOffset
+ || etk::abs(eventTable[_pointerID].downStart.y() - _pos.y()) >= localLimit.DpiOffset ){
+ cleanElement(eventTable, _pointerID);
+ }
+ }
+ if(eventTable[_pointerID].isUsed == true) {
+ // save start time
+ eventTable[_pointerID].lastTimeEvent = currentTime;
+ // generate DOWN Event
+ EVENT_DEBUG("GUI : Input ID=" << _pointerID
+ << " == >" << eventTable[_pointerID].destinationInputId
+ << " [DOWN] " << _pos);
+ eventTable[_pointerID].posEvent = _pos;
+ localEventInput(_type,
+ eventTable[_pointerID].curentWidgetEvent.lock(),
+ eventTable[_pointerID].destinationInputId,
+ gale::key::status::down,
+ _pos);
+ } else {
+ // Mark it used :
+ eventTable[_pointerID].isUsed = true;
+ // Save current position :
+ eventTable[_pointerID].downStart = _pos;
+ // save start time
+ eventTable[_pointerID].lastTimeEvent = currentTime;
+ // set the element inside ...
+ eventTable[_pointerID].isInside = true;
+ ewol::WidgetShared tmpWidget = m_grabWidget.lock();
+ // get destination widget :
+ if(tmpWindows != null) {
+ if ( tmpWidget != null
+ && _type == gale::key::type::mouse) {
+ eventTable[_pointerID].curentWidgetEvent = tmpWidget;
+ } else {
+ tmpWidget = tmpWindows->getWidgetAtPos(_pos);
+ eventTable[_pointerID].curentWidgetEvent = tmpWidget;
+ if (tmpWidget != null) {
+ EVENT_DEBUG("Get widget at pos=" << _pos << " type: " << tmpWidget->getObjectType());
+ } else {
+ EVENT_DEBUG("Get widget at pos=" << _pos << " NO WIDGET");
+ }
+ }
+ } else {
+ eventTable[_pointerID].curentWidgetEvent.reset();
+ }
+ tmpWidget = eventTable[_pointerID].curentWidgetEvent.lock();
+ if (tmpWidget != null) {
+ eventTable[_pointerID].origin = tmpWidget->getOrigin();
+ eventTable[_pointerID].size = tmpWidget->getSize();
+ eventTable[_pointerID].destinationInputId = localGetDestinationId(_type, tmpWidget, _pointerID);
+ } else {
+ eventTable[_pointerID].destinationInputId = -1;
+ }
+ // generate DOWN Event
+ EVENT_DEBUG("GUI : Input ID=" << _pointerID
+ << " == >" << eventTable[_pointerID].destinationInputId
+ << " [DOWN] " << _pos);
+ eventTable[_pointerID].posEvent = _pos;
+ localEventInput(_type,
+ tmpWidget,
+ eventTable[_pointerID].destinationInputId,
+ gale::key::status::down,
+ _pos);
+ }
+ } else {
+ EVENT_DEBUG("GUI : Input ID=" << _pointerID
+ << " == >" << eventTable[_pointerID].destinationInputId
+ << " [UP] " << _pos);
+ ewol::WidgetShared tmpWidget = eventTable[_pointerID].curentWidgetEvent.lock();
+ if(eventTable[_pointerID].isUsed == false) {
+ // bad case ... ???
+ EWOL_DEBUG("Up event without previous down ... ");
+ // Mark it un-used :
+ eventTable[_pointerID].isUsed = false;
+ // revove the widget ...
+ eventTable[_pointerID].curentWidgetEvent.reset();
+ } else if (tmpWidget == null) {
+ // The widget has been removed:
+ EVENT_DEBUG(" Object Removed ...");
+ // Mark it un-used :
+ eventTable[_pointerID].isUsed = false;
+ // revove the widget ...
+ eventTable[_pointerID].curentWidgetEvent.reset();
+ } else {
+ // generate UP Event
+ EVENT_DEBUG("GUI : Input ID=" << _pointerID
+ << " == >" << eventTable[_pointerID].destinationInputId
+ << " [UP] " << _pos);
+ eventTable[_pointerID].posEvent = _pos;
+ // send up event after the single event to prevent multiple widget getting elements
+ localEventInput(_type,
+ tmpWidget,
+ _pointerID,
+ gale::key::status::up,
+ _pos);
+ // generate event (single)
+ if( etk::abs(eventTable[_pointerID].downStart.x() - _pos.x()) < localLimit.DpiOffset
+ && etk::abs(eventTable[_pointerID].downStart.y() - _pos.y()) < localLimit.DpiOffset ){
+ // Save current position :
+ eventTable[_pointerID].downStart = _pos;
+ // save start time
+ eventTable[_pointerID].lastTimeEvent = currentTime;
+ int32_t nbClickMax = 0;
+ if(tmpWidget != null) {
+ nbClickMax = tmpWidget->getMouseLimit();
+ if (nbClickMax>5) {
+ nbClickMax = 5;
+ }
+ }
+ // in grab mode the single to quinte event are not generated ....
+ if( ( m_grabWidget.lock() == null
+ || _type != gale::key::type::mouse )
+ && eventTable[_pointerID].nbClickEvent < nbClickMax) {
+ // generate event SINGLE :
+ eventTable[_pointerID].nbClickEvent++;
+ EVENT_DEBUG("GUI : Input ID=" << _pointerID
+ << " == >" << eventTable[_pointerID].destinationInputId
+ << " [" << eventTable[_pointerID].nbClickEvent << "] " << _pos);
+ eventTable[_pointerID].posEvent = _pos;
+ localEventInput(_type,
+ tmpWidget,
+ eventTable[_pointerID].destinationInputId,
+ (enum gale::key::status)(uint32_t(gale::key::status::pressSingle) + eventTable[_pointerID].nbClickEvent-1),
+ _pos);
+ if( eventTable[_pointerID].nbClickEvent >= nbClickMax) {
+ eventTable[_pointerID].nbClickEvent = 0;
+ }
+ } else {
+ eventTable[_pointerID].nbClickEvent = 0;
+ }
+ }
+ // send up event after the single event to prevent multiple widget getting elements
+ localEventInput(_type,
+ tmpWidget,
+ _pointerID,
+ gale::key::status::upAfter,
+ _pos);
+ // specific for tuch event
+ if (_type == gale::key::type::finger) {
+ cleanElement(eventTable, _pointerID);
+ }
+ }
+ }
+}
+
+
diff --git a/src/org/atriasoft/ewol/context/InputManager.java b/src/org/atriasoft/ewol/context/InputManager.java
new file mode 100644
index 0000000..1445d0f
--- /dev/null
+++ b/src/org/atriasoft/ewol/context/InputManager.java
@@ -0,0 +1,120 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+#include
+
+#define MAX_MANAGE_INPUT (15)
+
+namespace ewol {
+ namespace context {
+ /**
+ * @brief internal structure
+ * @not_in_doc
+ */
+ class InputPoperty {
+ public:
+ bool isUsed;
+ int32_t destinationInputId;
+ echrono::Clock lastTimeEvent;
+ ewol::WidgetWeak curentWidgetEvent;
+ vec2 origin;
+ vec2 size;
+ vec2 downStart;
+ vec2 posEvent;
+ bool isDown;
+ bool isInside;
+ int32_t nbClickEvent; // 0 .. 1 .. 2 .. 3
+ };
+
+ /**
+ * @brief internal structure
+ * @not_in_doc
+ */
+ class InputLimit {
+ public:
+ echrono::Duration sepatateTime;
+ int32_t DpiOffset;
+ };
+ class Context;
+ class InputManager{
+ // special grab pointer mode :
+ private:
+ ewol::WidgetWeak m_grabWidget; //!< widget that grab the curent pointer.
+ private:
+ int32_t m_dpi;
+ InputLimit m_eventInputLimit;
+ InputLimit m_eventMouseLimit;
+ void calculateLimit();
+ InputPoperty m_eventInputSaved[MAX_MANAGE_INPUT];
+ InputPoperty m_eventMouseSaved[MAX_MANAGE_INPUT];
+ void abortElement(InputPoperty* _eventTable, int32_t _idInput, enum gale::key::type _type);
+ void cleanElement(InputPoperty* _eventTable, int32_t _idInput);
+ /**
+ * @brief generate the event on the destinated widget.
+ * @param[in] _type Type of the event that might be sended.
+ * @param[in] _destWidget Pointer on the requested widget that element might be sended
+ * @param[in] _IdInput Id of the event (PC : [0..9] and touch : [1..9])
+ * @param[in] _typeEvent type of the eventg generated
+ * @param[in] _pos position of the event
+ * @return true if event has been greped
+ */
+ bool localEventInput(enum gale::key::type _type,
+ ewol::WidgetShared _destWidget,
+ int32_t _IdInput,
+ enum gale::key::status _typeEvent,
+ vec2 _pos);
+ /**
+ * @brief convert the system event id in the correct EWOL id depending of the system management mode
+ * This function find the next input id unused on the specifiic widget
+ * == > on PC, the ID does not change (GUI is not the same)
+ * @param[in] _type Type of the kay event.
+ * @param[in] _destWidget Pointer of the widget destination
+ * @param[in] _realInputId system Id
+ * @return the ewol input id
+ */
+ int32_t localGetDestinationId(enum gale::key::type _type,
+ ewol::WidgetShared _destWidget,
+ int32_t _realInputId);
+ private:
+ ewol::Context& m_context;
+ public:
+ InputManager(ewol::Context& _context);
+ ~InputManager();
+ void setDpi(int32_t _newDPI);
+
+ // note if id<0 == > the it was finger event ...
+ void motion(enum gale::key::type _type, int _pointerID, vec2 _pos );
+ void state(enum gale::key::type _type, int _pointerID, bool _isDown, vec2 _pos);
+ public:
+ /**
+ * @brief a new layer on the windows is set == > might remove all the property of the current element ...
+ */
+ void newLayerSet();
+ /**
+ * @brief This is to transfert the event from one widget to another one
+ * @param _source the widget where the event came from
+ * @param _destination the widget where the event mitgh be generated now
+ */
+ void transfertEvent(ewol::WidgetShared _source, ewol::WidgetShared _destination);
+ /**
+ * @brief This fonction lock the pointer properties to move in relative instead of absolute
+ * @param[in] _widget The widget that lock the pointer events
+ */
+ void grabPointer(ewol::WidgetShared _widget);
+ /**
+ * @brief This fonction un-lock the pointer properties to move in relative instead of absolute
+ */
+ void unGrabPointer();
+ private:
+ gale::key::Special m_specialKey;
+ public:
+ void setLastKeyboardSpecial(const gale::key::Special& _specialKey) {
+ m_specialKey = _specialKey;
+ }
+ };
+ };
+};
+
diff --git a/src/org/atriasoft/ewol/debug.cpp b/src/org/atriasoft/ewol/debug.cpp
new file mode 100644
index 0000000..643e481
--- /dev/null
+++ b/src/org/atriasoft/ewol/debug.cpp
@@ -0,0 +1,12 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+
+int32_t ewol::getLogId() {
+ static int32_t g_val = elog::registerInstance("ewol");
+ return g_val;
+}
diff --git a/src/org/atriasoft/ewol/event/Entry.cpp b/src/org/atriasoft/ewol/event/Entry.cpp
new file mode 100644
index 0000000..912e1a8
--- /dev/null
+++ b/src/org/atriasoft/ewol/event/Entry.cpp
@@ -0,0 +1,25 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+
+#include
+ETK_DECLARE_TYPE(ewol::event::Entry);
+
+etk::Stream& ewol::event::operator <<(etk::Stream& _os, const ewol::event::Entry& _obj) {
+ _os << "{type=" << _obj.getType();
+ _os << " status=" << _obj.getStatus();
+ if (_obj.getType() == gale::key::keyboard::character) {
+ _os << " char=" << _obj.getChar();
+ }
+ _os << "}";
+ return _os;
+}
+
+etk::Stream& ewol::event::operator <<(etk::Stream& _os, const ewol::event::EntrySystem& _obj) {
+ _os << _obj.m_event;
+ return _os;
+}
diff --git a/src/org/atriasoft/ewol/event/Entry.java b/src/org/atriasoft/ewol/event/Entry.java
new file mode 100644
index 0000000..427e060
--- /dev/null
+++ b/src/org/atriasoft/ewol/event/Entry.java
@@ -0,0 +1,70 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+
+#include
+#include
+
+namespace ewol {
+ namespace event {
+ class Entry {
+ private:
+ enum gale::key::keyboard m_type; //!< type of hardware event
+ enum gale::key::status m_status; //!< status of hardware event
+ gale::key::Special m_specialKey; //!< input key status (prevent change in time..)
+ char32_t m_unicodeData; //!< Unicode data (in some case)
+ public:
+ Entry(enum gale::key::keyboard _type,
+ enum gale::key::status _status,
+ gale::key::Special _specialKey,
+ char32_t _char) :
+ m_type(_type),
+ m_status(_status),
+ m_specialKey(_specialKey),
+ m_unicodeData(_char) {
+
+ };
+ void setType(enum gale::key::keyboard _type) {
+ m_type = _type;
+ };
+ inline const enum gale::key::keyboard& getType() const {
+ return m_type;
+ };
+ void setStatus(enum gale::key::status _status) {
+ m_status = _status;
+ };
+ inline const enum gale::key::status& getStatus() const {
+ return m_status;
+ };
+ void setSpecialKey(const gale::key::Special& _specialKey) {
+ m_specialKey = _specialKey;
+ };
+ inline const gale::key::Special& getSpecialKey() const {
+ return m_specialKey;
+ };
+ void setChar(char32_t _char) {
+ m_unicodeData = _char;
+ };
+ inline const char32_t& getChar() const {
+ return m_unicodeData;
+ };
+ };
+ etk::Stream& operator <<(etk::Stream& _os, const ewol::event::Entry& _obj);
+
+ class EntrySystem {
+ public:
+ EntrySystem(enum gale::key::keyboard _type,
+ enum gale::key::status _status,
+ gale::key::Special _specialKey,
+ char32_t _char) :
+ m_event(_type, _status, _specialKey, _char) {
+
+ };
+ ewol::event::Entry m_event;
+ };
+ etk::Stream& operator <<(etk::Stream& _os, const ewol::event::EntrySystem& _obj);
+ };
+};
diff --git a/src/org/atriasoft/ewol/event/Input.cpp b/src/org/atriasoft/ewol/event/Input.cpp
new file mode 100644
index 0000000..a846a3f
--- /dev/null
+++ b/src/org/atriasoft/ewol/event/Input.cpp
@@ -0,0 +1,24 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+
+#include
+ETK_DECLARE_TYPE(ewol::event::Input);
+
+etk::Stream& ewol::event::operator <<(etk::Stream& _os, const ewol::event::Input& _obj) {
+ _os << "{type=" << _obj.getType();
+ _os << " status=" << _obj.getStatus();
+ _os << " id=" << etk::toString(_obj.getId());
+ _os << " pos=" << _obj.getPos();
+ _os << "}";
+ return _os;
+}
+
+etk::Stream& ewol::event::operator <<(etk::Stream& _os, const ewol::event::InputSystem& _obj) {
+ _os << _obj.m_event;
+ return _os;
+}
diff --git a/src/org/atriasoft/ewol/event/Input.java b/src/org/atriasoft/ewol/event/Input.java
new file mode 100644
index 0000000..05e6557
--- /dev/null
+++ b/src/org/atriasoft/ewol/event/Input.java
@@ -0,0 +1,104 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+
+#include
+
+namespace ewol {
+ namespace event {
+ class Input {
+ private:
+ enum gale::key::type m_type;
+ enum gale::key::status m_status;
+ uint8_t m_inputId;
+ vec2 m_pos;
+ gale::key::Special m_specialKey; //!< input key status (prevent change in time..)
+ public:
+ Input(enum gale::key::type _type,
+ enum gale::key::status _status,
+ uint8_t _id,
+ const vec2& _pos,
+ gale::key::Special _specialKey):
+ m_type(_type),
+ m_status(_status),
+ m_inputId(_id),
+ m_pos(_pos),
+ m_specialKey(_specialKey) {
+
+ };
+ void setType(enum gale::key::type _type) {
+ m_type = _type;
+ };
+ inline const enum gale::key::type& getType() const {
+ return m_type;
+ };
+ void setStatus(enum gale::key::status _status) {
+ m_status = _status;
+ };
+ inline const enum gale::key::status& getStatus() const {
+ return m_status;
+ };
+ void setId(uint8_t _id) {
+ m_inputId = _id;
+ };
+ inline const uint8_t& getId() const {
+ return m_inputId;
+ };
+ void setPos(const vec2& _pos) {
+ m_pos = _pos;
+ };
+ inline const vec2& getPos() const {
+ return m_pos;
+ };
+ void setSpecialKey(const gale::key::Special& _specialKey) {
+ m_specialKey = _specialKey;
+ };
+ inline const gale::key::Special& getSpecialKey() const {
+ return m_specialKey;
+ };
+ /**
+ * @brief Reset the input property of the curent event.
+ */
+ void reset() const {
+ // TODO : Call the entry element ant rest it ...
+ }
+ };
+ etk::Stream& operator <<(etk::Stream& _os, const ewol::event::Input& _obj);
+
+ class InputSystem {
+ public:
+ InputSystem(enum gale::key::type _type,
+ enum gale::key::status _status,
+ uint8_t _id,
+ const vec2& _pos,
+ ewol::WidgetShared _dest,
+ int32_t _realIdEvent,
+ gale::key::Special _specialKey) :
+ m_event(_type, _status, _id, _pos, _specialKey),
+ m_dest(_dest),
+ m_realIdEvent(_realIdEvent) { };
+ ewol::event::Input m_event;
+ private:
+ ewol::WidgetShared m_dest;
+ int32_t m_realIdEvent;
+ public:
+ void setDestWidget(ewol::WidgetShared _dest) {
+ m_dest = _dest;
+ };
+ inline ewol::WidgetShared getDestWidget() const {
+ return m_dest;
+ };
+ void setRealId(int32_t _realIdEvent) {
+ m_realIdEvent = _realIdEvent;
+ };
+ inline int32_t getRealId() const {
+ return m_realIdEvent;
+ };
+ };
+ etk::Stream& operator <<(etk::Stream& _os, const ewol::event::InputSystem& _obj);
+ };
+};
+
diff --git a/src/org/atriasoft/ewol/event/Time.cpp b/src/org/atriasoft/ewol/event/Time.cpp
new file mode 100644
index 0000000..a843bf4
--- /dev/null
+++ b/src/org/atriasoft/ewol/event/Time.cpp
@@ -0,0 +1,35 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+#include
+ETK_DECLARE_TYPE(ewol::event::Time);
+
+etk::Stream& ewol::event::operator <<(etk::Stream& _os, const ewol::event::Time& _obj) {
+ _os << "{time=" << _obj.getTime();
+ _os << " uptime=" << _obj.getApplUpTime();
+ _os << " delta=" << _obj.getDelta();
+ _os << " deltaCall=" << _obj.getDeltaCall();
+ _os << "}";
+ return _os;
+}
+
+namespace etk {
+ template<> etk::String toString(ewol::event::Time const& _obj) {
+ etk::String out;
+ out = "{[ewol::event::Time]time=" + etk::toString(_obj.getTime());
+ out += ";uptime=" + etk::toString(_obj.getApplUpTime());
+ out += ";delta=" + etk::toString(_obj.getDelta());
+ out += ";deltaCall=" + etk::toString(_obj.getDeltaCall());
+ out += "}";
+ return out;
+ }
+}
+
+// declare for signal event
+#include
+ESIGNAL_DECLARE_SIGNAL(ewol::event::Time);
+
diff --git a/src/org/atriasoft/ewol/event/Time.java b/src/org/atriasoft/ewol/event/Time.java
new file mode 100644
index 0000000..de66d18
--- /dev/null
+++ b/src/org/atriasoft/ewol/event/Time.java
@@ -0,0 +1,69 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+
+#include
+#include
+#include
+
+namespace ewol {
+ namespace event {
+ class Time {
+ private:
+ echrono::Clock m_timeSystem; //!< Current system time (micro-second)
+ echrono::Clock m_timeUpAppl; //!< Current application wake up-time (micro-second)
+ echrono::Duration m_timeDelta; //!< Time from the last cycle call of the system (main appl tick) (second)
+ echrono::Duration m_timeDeltaCall; //!< Time from the last call (when we can manage periodic call with specifying periode) (second)
+ public:
+ Time(const echrono::Clock& _timeSystem,
+ const echrono::Clock& _timeUpAppl,
+ const echrono::Duration& _timeDelta,
+ const echrono::Duration& _timeDeltaCall) :
+ m_timeSystem(_timeSystem),
+ m_timeUpAppl(_timeUpAppl),
+ m_timeDelta(_timeDelta),
+ m_timeDeltaCall(_timeDeltaCall){
+
+ };
+ public:
+ void setTime(const echrono::Clock& _timeSystem) {
+ m_timeSystem = _timeSystem;
+ };
+ inline const echrono::Clock& getTime() const {
+ return m_timeSystem;
+ };
+ void setApplWakeUpTime(const echrono::Clock& _timeUpAppl) {
+ m_timeUpAppl = _timeUpAppl;
+ };
+ inline const echrono::Clock& getApplWakeUpTime() const {
+ return m_timeUpAppl;
+ };
+ inline echrono::Duration getApplUpTime() const {
+ return m_timeSystem-m_timeUpAppl;
+ };
+ void setDelta(const echrono::Duration& _timeDelta) {
+ m_timeDelta = _timeDelta;
+ };
+ inline const echrono::Duration& getDeltaDuration() const {
+ return m_timeDelta;
+ };
+ inline float getDelta() const {
+ return m_timeDelta.toSeconds();
+ };
+ void setDeltaCall(const echrono::Duration& _timeDeltaCall) {
+ m_timeDeltaCall = _timeDeltaCall;
+ };
+ inline const echrono::Duration& getDeltaCallDuration() const {
+ return m_timeDeltaCall;
+ };
+ inline float getDeltaCall() const {
+ return m_timeDeltaCall.toSeconds();
+ };
+ };
+ etk::Stream& operator <<(etk::Stream& _os, const ewol::event::Time& _obj);
+ }
+}
+
diff --git a/src/org/atriasoft/ewol/ewol.cpp b/src/org/atriasoft/ewol/ewol.cpp
new file mode 100644
index 0000000..079b52a
--- /dev/null
+++ b/src/org/atriasoft/ewol/ewol.cpp
@@ -0,0 +1,32 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#ifndef EWOL_VERSION
+#define EWOL_VERSION "0.0.0"
+#endif
+
+etk::String ewol::getVersion() {
+ return EWOL_VERSION;
+}
+
+
+int32_t ewol::run(ewol::context::Application* _application,
+ int32_t _argc,
+ const char* _argv[]) {
+ etranslate::init(_argc, _argv);
+ return gale::run(ETK_NEW(ewol::Context, _application), _argc, _argv);
+}
+
+
diff --git a/src/org/atriasoft/ewol/ewol.java b/src/org/atriasoft/ewol/ewol.java
new file mode 100644
index 0000000..1e5ba30
--- /dev/null
+++ b/src/org/atriasoft/ewol/ewol.java
@@ -0,0 +1,30 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2011, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+#pragma once
+
+#include
+#include