[FEAT] continue integration of SVG...

This commit is contained in:
Edouard DUPIN 2025-06-26 00:19:23 +02:00
parent adef08ac95
commit 9472ddc46b
9 changed files with 269 additions and 1108 deletions

View File

@ -422,4 +422,55 @@ public class CompositingSVG extends Compositing {
this.requestSize = size;
}
public void setRectangleAsSource(final int sizeX, final int sizeY, final Color color) {
setSource("""
<svg width="%d" height="%d">
<rect
x="%d"
y="%d"
width="%d"
height="%d"
fill="%s"
/>
</svg>""".formatted( //
sizeX, sizeY, //
0, 0, //
sizeX, sizeY, //
color.toStringSharp() //
), new Vector2i(sizeX, sizeY));
}
public void setRectangleBorderAsSource(
final int sizeX,
final int sizeY,
final Color color,
final int borderSize,
final int borderRadius,
final Color borderColor) {
final int paddingCompensateBorder = Math.round(borderSize * 0.5f);
setSource("""
<svg width="%d" height="%d">
<rect
x="%d"
y="%d"
width="%d"
height="%d"
rx="%d"
ry="%d"
fill="%s"
stroke="%s"
stroke-width="%d"
/>
</svg>""".formatted( //
sizeX, sizeY, //
paddingCompensateBorder, paddingCompensateBorder, //
sizeX - 2 * paddingCompensateBorder, sizeY - 2 * paddingCompensateBorder, //
borderRadius, //
borderRadius, //
color.toStringSharp(), //
borderColor.toStringSharp(), //
borderSize //
), new Vector2i(sizeX, sizeY));
}
}

View File

@ -1,700 +0,0 @@
package org.atriasoft.ewol.compositing;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.atriasoft.egami.ImageByte;
import org.atriasoft.etk.Uri;
import org.atriasoft.etk.math.FMath;
import org.atriasoft.etk.math.Matrix4f;
import org.atriasoft.etk.math.Vector2f;
import org.atriasoft.etk.math.Vector2i;
import org.atriasoft.etk.math.Vector3f;
import org.atriasoft.ewol.Padding;
import org.atriasoft.ewol.event.EventTime;
import org.atriasoft.ewol.resource.ResourceConfigFile;
import org.atriasoft.gale.backend3d.OpenGL;
import org.atriasoft.gale.backend3d.OpenGL.Flag;
import org.atriasoft.gale.resource.ResourceProgram;
import org.atriasoft.gale.resource.ResourceTexture2;
import org.atriasoft.loader3d.resources.ResourceMesh;
import org.atriasoft.loader3d.resources.ResourcePaletteFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @brief the Shaper system is a basic theme configuration for every widget, it corresponds 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
public class GuiShape extends Compositing {
private static final Logger LOGGER = LoggerFactory.getLogger(GuiShape.class);
private class SpecificValues {
public Matrix4f transform = Matrix4f.IDENTITY;
public Vector3f offsetScaleInside = Vector3f.ZERO;
public Vector3f offsetScaleOutside = Vector3f.ZERO;
public ResourceMesh mesh = null;
}
private static final int SHAPER_POS_BOTTOM = 3;
private static final int SHAPER_POS_LEFT = 0;
private static final int SHAPER_POS_RIGHT = 2;
private static final int SHAPER_POS_TOP = 1;
private int confIdChangeTime = -1; //!< ConfigFile padding transition time property
private int confIdPaletteFile = -1; //!< Palette of the display
private final int[] confIdPaddingIn = new int[4]; //!< Padding in property : X-left X-right Y-top Y-buttom
private final int[] confIdPaddingOut = new int[4]; //!< Padding out property : X-left X-right Y-top Y-buttom
// External theme configuration:
private ResourceConfigFile config = null; //!< pointer on the config file resources
private int confObjectFile = -1; //!< Config Id of the object file to display
private int confObjectFile2 = -1; //!< Config Id of the object file to display
private int confProgramFileFrag = -1; //!< ConfigFile opengGl program Name
private int confProgramFileVert = -1; //!< ConfigFile opengGl program Name
private final List<Vector2i> listAssiciatedId = new ArrayList<>(); //!< Correlation ID between ColorProperty (Y) and OpenGL Program (X)
// internal needed data :
private GuiShapeMode nextStatusRequested = GuiShapeMode.NONE; //!< when status is changing, this represent the next step of it
private int oGLMatrixProjection = -1; //!< openGL id on the element (Projection matrix)
private int oGLMatrixTransformation = -1; //!< openGL id on the element (transformation matrix)
private int oGLMatrixView = -1; //!< openGL id on the element (view matrix)
private int oGLPaletteOffset = -1; //!< openGL id on the element (offset for the palet rendering)
private int oGLOffsetScaleInside = -1;
private int oGLOffsetScaleOutside = -1;
// openGL shaders programs:
private ResourceProgram oGLprogram = null; //!< pointer on the opengl display program
// For the Image :
private ResourcePaletteFile palette;
private ResourceTexture2 texture;
private Padding sizeObject = Padding.ZERO;
private int stateActivate = -1; //!< Activate state of the element
private GuiShapeMode stateNew = GuiShapeMode.NORMAL; //!< destination state
private GuiShapeMode stateOld = GuiShapeMode.NORMAL; //!< previous state
private Uri uri; //!< Name of the configuration of the shaper.
private final SpecificValues[] valueSpecific = new SpecificValues[2];
// dynamic change:
private float stateTransition = 0; //!< working state between 2 states
/**
* @brief generic constructor
* @param _uri URI of the file that might be loaded
*/
public GuiShape(final Uri uri) {
this.uri = uri;
for (int iii = 0; iii < 4; ++iii) {
this.confIdPaddingOut[iii] = -1;
this.confIdPaddingIn[iii] = -1;
}
// Load data from the configuration file:
loadConfigFile();
loadUpdateObjectSize();
loadPalette();
loadProgram();
}
/**
* @brief change the current status in an other
* @param _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.
*/
public boolean changeStatusIn(final GuiShapeMode newStatusId) {
if (newStatusId != this.stateNew) {
this.nextStatusRequested = newStatusId;
return true;
}
if (this.stateNew != this.stateOld) {
return true;
}
return false;
}
/**
* @brief clear alll tre registered element in the current element
*/
@Override
public void clear() {}
/**
* @brief draw All the registered text in the current element on openGL
*/
@Override
public void draw(final boolean disableDepthTest) {
draw(null, disableDepthTest);
}
public void draw(final boolean disableDepthTest, final int idMesh) {
draw(null, disableDepthTest, idMesh);
}
public void draw(final ResourceTexture2 secondaryTexture, final boolean disableDepthTest) {
this.draw(secondaryTexture, disableDepthTest, 0);
}
public void draw(final ResourceTexture2 secondaryTexture, final boolean disableDepthTest, final int idMesh) {
if (this.config == null) {
// this is a normal case ... the user can choice to have no config basic file ...
return;
}
if (idMesh == 0 && this.valueSpecific[0] == null) {
LOGGER.error("No Object (0) to display ...");
return;
} else if (idMesh == 1 && this.valueSpecific[1] == null) {
LOGGER.error("No Object (1) to display ...");
return;
} else if (idMesh < 0 && idMesh > 1) {
LOGGER.error("No Object (" + idMesh + ") to display [0..1]");
System.exit(-1);
return;
}
if (this.oGLprogram == null) {
LOGGER.error("No shader ...");
return;
}
OpenGL.enable(Flag.flag_depthTest);
// set Matrix : translation/positionMatrix
final Matrix4f projMatrix = OpenGL.getMatrix();
final Matrix4f camMatrix = OpenGL.getCameraMatrix();
final Matrix4f tmpMatrix = this.matrixApply.multiply(this.valueSpecific[idMesh].transform);
this.oGLprogram.use();
this.valueSpecific[idMesh].mesh.bindForRendering();
this.oGLprogram.uniformMatrix(this.oGLMatrixProjection, projMatrix);
this.oGLprogram.uniformMatrix(this.oGLMatrixTransformation, tmpMatrix);
this.oGLprogram.uniformMatrix(this.oGLMatrixView, camMatrix);
final Set<String> layers = this.valueSpecific[idMesh].mesh.getLayers();
LOGGER.trace("get layers:" + layers);
// Texture:
final float imageDelta = (float) 1 / ResourcePaletteFile.getHeight();
float basicValue = this.stateOld.getValue() / ResourcePaletteFile.getHeight();
if (this.stateOld != this.stateNew) {
if (this.stateOld == GuiShapeMode.NORMAL) {
if (this.stateNew == GuiShapeMode.OVER) {
basicValue += imageDelta * this.stateTransition;
} else if (this.stateNew == GuiShapeMode.SELECT) {
basicValue += imageDelta * 3.0f - imageDelta * this.stateTransition;
}
} else if (this.stateOld == GuiShapeMode.OVER) {
if (this.stateNew == GuiShapeMode.NORMAL) {
basicValue -= imageDelta * this.stateTransition;
} else if (this.stateNew == GuiShapeMode.SELECT) {
basicValue += imageDelta * this.stateTransition;
}
} else if (this.stateOld == GuiShapeMode.SELECT) {
if (this.stateNew == GuiShapeMode.NORMAL) {
basicValue += imageDelta * this.stateTransition;
} else if (this.stateNew == GuiShapeMode.OVER) {
basicValue -= imageDelta * this.stateTransition;
}
}
}
LOGGER.trace(
"colorDelta = " + basicValue + " old = " + this.stateOld + "(" + this.stateOld.getValue() * imageDelta
+ ") new = " + this.stateNew + "(" + this.stateNew.getValue() * imageDelta + ")");
this.oGLprogram.uniformFloat(this.oGLPaletteOffset, basicValue);
//LOGGER.trace("plop: " + this.offsetScaleOutside);
//LOGGER.trace("plop: " + this.offsetScaleInside);
this.oGLprogram.uniformVector(this.oGLOffsetScaleInside, this.valueSpecific[idMesh].offsetScaleInside);
this.oGLprogram.uniformVector(this.oGLOffsetScaleOutside, this.valueSpecific[idMesh].offsetScaleOutside);
this.texture.bindForRendering(0);
this.valueSpecific[idMesh].mesh.render("palette");
if (secondaryTexture != null) {
this.oGLprogram.uniformFloat(this.oGLPaletteOffset, 0);
secondaryTexture.bindForRendering(0);
this.valueSpecific[idMesh].mesh.render("gui_dynamic_1");
}
// Request the draw of the elements:
this.valueSpecific[idMesh].mesh.render();
this.valueSpecific[idMesh].mesh.unBindForRendering();
this.oGLprogram.unUse();
OpenGL.disable(Flag.flag_depthTest);
}
@Override
public void flush() {
// TODO Auto-generated method stub
}
/**
* @brief get the padding declared by the user in the config file
* @return the padding property
*/
public Padding getBorder() {
return this.sizeObject;
}
/**
* @brief get the current displayed status of the shaper
* @return The Status Id
*/
public GuiShapeMode getCurrentDisplayedStatus() {
return this.stateNew;
}
/**
* @brief get the next displayed status of the shaper
* @return The next status Id (-1 if no status in next)
*/
public GuiShapeMode getNextDisplayedStatus() {
return this.nextStatusRequested;
}
/**
* @brief get the padding declared by the user in the config file
* @return the padding property
*/
public Padding getPadding() {
return getPaddingOut().add(getBorder()).add(getPaddingIn());
}
public Padding getPaddingIn() {
Padding out = Padding.ZERO;
if (this.config != null) {
out = new Padding(this.config.getNumber(this.confIdPaddingIn[GuiShape.SHAPER_POS_LEFT]),
this.config.getNumber(this.confIdPaddingIn[GuiShape.SHAPER_POS_TOP]),
this.config.getNumber(this.confIdPaddingIn[GuiShape.SHAPER_POS_RIGHT]),
this.config.getNumber(this.confIdPaddingIn[GuiShape.SHAPER_POS_BOTTOM]));
}
return out;
}
public Padding getPaddingOut() {
Padding out = Padding.ZERO;
if (this.config != null) {
out = new Padding(this.config.getNumber(this.confIdPaddingOut[GuiShape.SHAPER_POS_LEFT]),
this.config.getNumber(this.confIdPaddingOut[GuiShape.SHAPER_POS_TOP]),
this.config.getNumber(this.confIdPaddingOut[GuiShape.SHAPER_POS_RIGHT]),
this.config.getNumber(this.confIdPaddingOut[GuiShape.SHAPER_POS_BOTTOM]));
}
return out;
}
/**
* @brief get the shaper file Source
* @return the shapper file name
*/
public Uri getSource() {
return this.uri;
}
/**
* @brief get the current transition status
* @return value of the transition status (0.0f when no activity)
*/
public float getTransitionStatus() {
return this.stateTransition;
}
/**
* @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.
*/
public boolean hasSources() {
return this.oGLprogram != null;
}
private void loadConfigFile() {
if (this.uri.isEmpty()) {
LOGGER.debug("no Shaper set for loading resources ...");
return;
}
this.config = ResourceConfigFile.create(this.uri);
if (this.config != null) {
this.confIdPaddingOut[GuiShape.SHAPER_POS_LEFT] = this.config.request("padding-out-left");
this.confIdPaddingOut[GuiShape.SHAPER_POS_RIGHT] = this.config.request("padding-out-right");
this.confIdPaddingOut[GuiShape.SHAPER_POS_TOP] = this.config.request("padding-out-top");
this.confIdPaddingOut[GuiShape.SHAPER_POS_BOTTOM] = this.config.request("padding-out-buttom");
this.confIdPaddingIn[GuiShape.SHAPER_POS_LEFT] = this.config.request("padding-in-left");
this.confIdPaddingIn[GuiShape.SHAPER_POS_RIGHT] = this.config.request("padding-in-right");
this.confIdPaddingIn[GuiShape.SHAPER_POS_TOP] = this.config.request("padding-in-top");
this.confIdPaddingIn[GuiShape.SHAPER_POS_BOTTOM] = this.config.request("padding-in-buttom");
this.confIdChangeTime = this.config.request("change-time");
this.confProgramFileVert = this.config.request("program-vert");
this.confProgramFileFrag = this.config.request("program-frag");
this.confObjectFile = this.config.request("object-file");
this.confObjectFile2 = this.config.request("object-file-2");
this.confIdPaletteFile = this.config.request("palette");
}
}
protected void loadPalette() {
final String paletteFile = this.config.getString(this.confIdPaletteFile);
final Uri paletteFileInterface = Uri.valueOf(paletteFile);
this.palette = ResourcePaletteFile.create(paletteFileInterface);
this.texture = ResourceTexture2.createNamed("TEXTURE_OF_PALETTE:" + paletteFile);
if (this.texture == null) {
LOGGER.error("can not instanciate Texture ...");
}
// element already called
loadPaletteUpdate();
// for next update (realTime reload)
this.palette.onUpdate(() -> {
loadPaletteUpdate();
});
}
protected void loadPaletteUpdate() {
LOGGER.warn("update palet environnement");
final ImageByte img = this.palette.getImageByte();
//IOgami.storePNG(new Uri("/home/heero/000000000aaaaplopppp.png"), img);
this.texture.set(img);
}
/**
* load the openGL program and get all the ID needed
*/
private void loadProgram() {
if (this.config == null) {
LOGGER.debug("no Shaper set for loading resources ...");
return;
}
final String basicShaderFileVert = this.config.getString(this.confProgramFileVert);
final String basicShaderFileFrag = this.config.getString(this.confProgramFileFrag);
if (!basicShaderFileVert.isEmpty() && !basicShaderFileFrag.isEmpty()) {
this.oGLprogram = ResourceProgram.create(Uri.valueOf(basicShaderFileVert),
Uri.valueOf(basicShaderFileFrag));
if (this.oGLprogram != null) {
this.oGLMatrixTransformation = this.oGLprogram.getUniform("in_matrixTransformation");
this.oGLMatrixProjection = this.oGLprogram.getUniform("in_matrixProjection");
this.oGLMatrixView = this.oGLprogram.getUniform("in_matrixView");
this.oGLPaletteOffset = this.oGLprogram.getUniform("in_offsetPalette");
this.oGLOffsetScaleInside = this.oGLprogram.getUniform("in_offsetScaleInside");
this.oGLOffsetScaleOutside = this.oGLprogram.getUniform("in_offsetScaleOutside");
}
}
}
/**
* load the openGL program and get all the ID needed
*/
private void loadUpdateObjectSize() {
if (this.config == null) {
LOGGER.debug("no Shaper set for loading resources ...");
return;
}
final String objectFile = this.config.getString(this.confObjectFile);
if (!objectFile.isEmpty()) {
final int idMesh = 0;
this.valueSpecific[idMesh] = new SpecificValues();
this.valueSpecific[idMesh].mesh = ResourceMesh.create(Uri.valueOf(objectFile));
final List<Vector3f> verticesToModify = this.valueSpecific[idMesh].mesh.getGeneratedPosition();
float top = 0;
float bottom = 0;
float left = 0;
float right = 0;
float back = 0;
float font = 0;
// estimate size of border:
if (verticesToModify == null) {
LOGGER.error("Element is null : verticesToModify 1");
System.exit(-1);
return;
}
for (final Vector3f element : verticesToModify) {
left = Math.min(left, element.x());
right = Math.max(right, element.x());
top = Math.min(top, element.y());
bottom = Math.max(bottom, element.y());
back = Math.min(back, element.z());
font = Math.max(font, element.z());
}
this.sizeObject = new Padding(Math.abs(left), Math.abs(top), Math.abs(right), Math.abs(bottom));
} else {
final int idMesh = 0;
this.valueSpecific[idMesh] = null;
}
final String objectFile2 = this.config.getString(this.confObjectFile2);
if (!objectFile2.isEmpty()) {
final int idMesh = 1;
this.valueSpecific[idMesh] = new SpecificValues();
this.valueSpecific[idMesh].mesh = ResourceMesh.create(Uri.valueOf(objectFile2));
final List<Vector3f> verticesToModify = this.valueSpecific[idMesh].mesh.getGeneratedPosition();
float top = 0;
float bottom = 0;
float left = 0;
float right = 0;
float back = 0;
float font = 0;
// estimate size of border:
if (verticesToModify == null) {
LOGGER.error("Element is null : verticesToModify 2");
System.exit(-1);
return;
}
for (final Vector3f element : verticesToModify) {
left = Math.min(left, element.x());
right = Math.max(right, element.x());
top = Math.min(top, element.y());
bottom = Math.max(bottom, element.y());
back = Math.min(back, element.z());
font = Math.max(font, element.z());
}
} else {
final int idMesh = 1;
this.valueSpecific[idMesh] = null;
}
}
/**
* @brief Same as the widfget periodic call (this is for change display)
* @param 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.
*/
public boolean periodicCall(final EventTime event) {
LOGGER.trace("call=" + event.getTimeDeltaCallSecond() + "s state transition=" + this.stateTransition
+ " speedTime=" + this.config.getNumber(this.confIdChangeTime));
// start :
if (this.stateTransition >= 1.0) {
this.stateOld = this.stateNew;
if ((this.nextStatusRequested == GuiShapeMode.NONE) || (this.nextStatusRequested == this.stateOld)) {
this.nextStatusRequested = GuiShapeMode.NONE;
// disable periodic call ...
return false;
}
this.stateNew = this.nextStatusRequested;
this.nextStatusRequested = GuiShapeMode.NONE;
this.stateTransition = 0.0f;
LOGGER.trace(" ##### START ##### ");
return true;
}
if (this.stateTransition < 1.0) {
// check if no new state requested:
if (this.nextStatusRequested != GuiShapeMode.NONE && this.stateTransition < 0.5) {
// invert sources with destination
final GuiShapeMode tmppp = this.stateOld;
this.stateOld = this.stateNew;
this.stateNew = tmppp;
this.stateTransition = 1.0f - this.stateTransition;
if (this.nextStatusRequested == this.stateNew) {
this.nextStatusRequested = GuiShapeMode.NONE;
}
}
float timeRelativity = 0.0f;
if (this.config != null) {
timeRelativity = (float) (this.config.getNumber(this.confIdChangeTime) / 1000.0f);
}
this.stateTransition += event.getTimeDeltaCallSecond() / timeRelativity;
//stateTransition += _event.getDeltaCall();
this.stateTransition = FMath.avg(0.0f, this.stateTransition, 1.0f);
LOGGER.trace("relative=" + timeRelativity + " Transition : " + this.stateTransition);
}
return true;
}
/**
* @brief Set activate state of the element
* @param _status New activate status
*/
public void setActivateState(final int status) {
this.stateActivate = status;
}
public void setShape(final int idMesh, final Vector3f origin, final Vector3f size) {
final Padding tmp = getPadding();
setShape(idMesh, origin, size, origin.add(tmp.left(), tmp.bottom(), 0), size.less(tmp.x(), tmp.y(), 0));
}
public void setShape(
final int idMesh,
final Vector3f origin,
final Vector3f size,
final Vector3f insidePos,
final Vector3f insideSize) {
final Vector3f halfSize = insideSize.multiply(0.5f);
this.valueSpecific[idMesh].offsetScaleOutside = halfSize;
this.valueSpecific[idMesh].offsetScaleInside = halfSize.add(this.sizeObject.x() * 0.25f,
this.sizeObject.y() * 0.25f, 0);
/*
List<Vector3f> verticesToModify = this.mesh.getGeneratedPosition();
float[] newVertices = new float[verticesToModify.size()*3];
for (int iii=0; iii<newVertices.length; ++iii) {
Vector3f tmp = verticesToModify.get(iii);
newVertices[iii*3+0] = getUpdatedPos(tmp.x(), halfSize.x());
newVertices[iii*3+1] = getUpdatedPos(tmp.y(), halfSize.y());
newVertices[iii*3+2] = getUpdatedPos(tmp.z(), halfSize.z());
}
this.mesh.setModifiedPosition(newVertices);
*/
this.valueSpecific[idMesh].transform = Matrix4f.createMatrixTranslate(
new Vector3f(origin.x() + size.x() * 0.5f, origin.y() + size.y() * 0.5f, origin.z() + size.z() * 0.5f));
}
// private float getUpdatedPos(final float value, final float halfsize) {
// if (value <= 0.0f) {
// return value - halfsize;
// }
// return value + halfsize;
// }
// @previous
public void setShape(final Vector2f origin, final Vector2f size) {
final Padding tmp = getPadding();
setShape(origin, size, origin.add(tmp.left(), tmp.bottom()), size.less(tmp.x(), tmp.y()));
}
/**
* @brief set the shape property:
*
* ********************************************************************************
* * size *
* * *
* * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *
* * *
* * | | *
* * *************************************************** *
* * | * * | *
* * * * *
* * | * * - - - - - - - - - - - - - - - - - - * * | *
* * * insideSize * *
* * | * | | * | *
* * * * *
* * | * | | * | *
* * * * *
* * | * | | * | *
* * * * *
* * | * | | * | *
* * * * *
* * | * | | * | *
* * * * *
* * | * | | * | *
* * * insidePos * *
* * | * * - - - - - - - - - - - - - - - - - - * * | *
* * * * *
* * | *************************************************** | *
* * *
* * | | *
* * *
* * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *
* * *
* * *
* ********************************************************************************
* origin
*
*
* @param center Center of the object
* @param size Size of the display
*/
public void setShape(
final Vector2f origin,
final Vector2f size,
final Vector2f insidePos,
final Vector2f insideSize) {
//LOGGER.error("Set shape property : origin=" + origin + " size=" + size + " in-pos=" + insidePos + " in-size=" + insideSize);
final Vector2f halfSize = insideSize.multiply(0.5f);
final Vector3f offsetScaleOutside = new Vector3f(halfSize.x(), halfSize.y(), 1.0f);
final Vector3f offsetScaleInside = new Vector3f(halfSize.x() + this.sizeObject.x() * 0.25f,
halfSize.y() + this.sizeObject.y() * 0.25f, 1.0f);
/*
List<Vector3f> verticesToModify = this.mesh.getGeneratedPosition();
float[] newVertices = new float[verticesToModify.size()*3];
for (int iii=0; iii<verticesToModify.size(); ++iii) {
Vector3f tmp = verticesToModify.get(iii);
newVertices[iii*3+0] = getUpdatedPos(tmp.x(), halfSize.x());
newVertices[iii*3+1] = getUpdatedPos(tmp.y(), halfSize.y());
newVertices[iii*3+2] = tmp.z();
}
//this.transform = Matrix4f.createMatrixRotate(new Vector3f(1.0f, 0.0f, 0.0f), -FMath.PI*0.30f);
//this.transform = this.transform.multiply(Matrix4f.createMatrixTranslate(new Vector3f(origin.x() + size.x() * 0.5f, origin.y() + size.y() * 0.5f, 0.0f)));
this.mesh.setModifiedPosition(newVertices);
*/
final Matrix4f transform = Matrix4f
.createMatrixTranslate(new Vector3f(origin.x() + size.x() * 0.5f, origin.y() + size.y() * 0.5f, 0.0f));
for (int iii = 0; iii < 2; iii++) {
if (this.valueSpecific[iii] == null) {
continue;
}
this.valueSpecific[iii].offsetScaleOutside = offsetScaleOutside;
this.valueSpecific[iii].offsetScaleInside = offsetScaleInside;
this.valueSpecific[iii].transform = transform;
}
}
public void setShape(final Vector3f origin, final Vector3f size) {
final Padding tmp = getPadding();
setShape(origin, size, origin.add(tmp.left(), tmp.bottom(), 0), size.less(tmp.x(), tmp.y(), 0));
}
public void setShape(
final Vector3f origin,
final Vector3f size,
final Vector3f insidePos,
final Vector3f insideSize) {
final Vector3f halfSize = insideSize.multiply(0.5f);
final Vector3f offsetScaleOutside = halfSize;
final Vector3f offsetScaleInside = halfSize.add(this.sizeObject.x() * 0.25f, this.sizeObject.y() * 0.25f, 0);
/*
List<Vector3f> verticesToModify = this.mesh.getGeneratedPosition();
float[] newVertices = new float[verticesToModify.size()*3];
for (int iii=0; iii<newVertices.length; ++iii) {
Vector3f tmp = verticesToModify.get(iii);
newVertices[iii*3+0] = getUpdatedPos(tmp.x(), halfSize.x());
newVertices[iii*3+1] = getUpdatedPos(tmp.y(), halfSize.y());
newVertices[iii*3+2] = getUpdatedPos(tmp.z(), halfSize.z());
}
this.mesh.setModifiedPosition(newVertices);
*/
final Matrix4f transform = Matrix4f.createMatrixTranslate(
new Vector3f(origin.x() + size.x() * 0.5f, origin.y() + size.y() * 0.5f, origin.z() + size.z() * 0.5f));
for (int iii = 0; iii < 2; iii++) {
if (this.valueSpecific[iii] == null) {
continue;
}
this.valueSpecific[iii].offsetScaleOutside = offsetScaleOutside;
this.valueSpecific[iii].offsetScaleInside = offsetScaleInside;
this.valueSpecific[iii].transform = transform;
}
}
/**
* @brief change the shaper Source
* @param _uri New file of the shaper
*/
public void setSource(final Uri uri) {
clear();
unLoadProgram();
this.uri = uri;
loadConfigFile();
loadUpdateObjectSize();
loadPalette();
loadProgram();
}
/**
* @brief Change the current state
* @param _newState Current state of the configuration
* @return true Need redraw.
* @return false No need redraw.
*/
public boolean setState(final int newState) {
if (this.stateActivate == newState) {
return false;
}
this.stateActivate = newState;
return true;
}
/**
* @brief Un-Load the openGL program and get all the ID needed
*/
private void unLoadProgram() {
this.oGLprogram = null;
this.texture = null;
this.config = null;
for (int iii = 0; iii < 4; ++iii) {
this.confIdPaddingOut[iii] = -1;
this.confIdPaddingIn[iii] = -1;
}
this.confIdChangeTime = -1;
this.listAssiciatedId.clear();
}
}

View File

@ -271,49 +271,10 @@ public class Box extends Container {
final int borderSize = (int) this.propertyBorderWidth.size();
final int paddingCompensateBorder = Math.round(borderSize * 0.5f);
if (borderSize > 0.0f) {
this.compositing.setSource("""
<svg width="%d" height="%d">
<rect
x="%d"
y="%d"
width="%d"
height="%d"
rx="%d"
ry="%d"
fill="%s"
stroke="%s"
stroke-width="%d"
/>
</svg>""".formatted( //
this.renderSize.x(), this.renderSize.y(), //
paddingCompensateBorder, paddingCompensateBorder, //
this.renderSize.x() - 2 * paddingCompensateBorder,
this.renderSize.y() - 2 * paddingCompensateBorder, //
(int) this.propertyBorderRadius.size(), //
(int) this.propertyBorderRadius.size(), //
this.propertyColor.toStringSharp(), //
this.propertyBorderColor.toStringSharp(), //
borderSize //
), //
this.renderSize);
this.compositing.setRectangleBorderAsSource(this.renderSize.x(), this.renderSize.y(), this.propertyColor,
borderSize, (int) this.propertyBorderRadius.size(), this.propertyBorderColor);
} else {
this.compositing.setSource("""
<svg width="%d" height="%d">
<rect
x="%d"
y="%d"
width="%d"
height="%d"
fill="%s"
/>
</svg>""".formatted( //
this.renderSize.x(), this.renderSize.y(), //
paddingCompensateBorder, paddingCompensateBorder, //
this.renderSize.x() - 2 * paddingCompensateBorder,
this.renderSize.y() - 2 * paddingCompensateBorder, //
this.propertyColor.toStringSharp() //
), //
this.renderSize);
this.compositing.setRectangleAsSource(this.renderSize.x(), this.renderSize.y(), this.propertyColor);
}
this.compositing.setPos(this.renderOrigin);
// For events:

View File

@ -1,179 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
package org.atriasoft.ewol.widget;
import org.atriasoft.aknot.annotation.AknotAttribute;
import org.atriasoft.aknot.annotation.AknotDescription;
import org.atriasoft.aknot.annotation.AknotManaged;
import org.atriasoft.aknot.annotation.AknotName;
import org.atriasoft.etk.Uri;
import org.atriasoft.etk.math.Vector3f;
import org.atriasoft.ewol.DrawProperty;
import org.atriasoft.ewol.Padding;
import org.atriasoft.ewol.compositing.GuiShape;
import org.atriasoft.ewol.compositing.ShapeBox;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Simple Container that have a Shape (not directly instantiate!!!!)
*/
public class ContainerWithShape extends Container {
private static final Logger LOGGER = LoggerFactory.getLogger(ContainerWithShape.class);
// properties
public Uri propertyShape = null; //!< Compositing theme.
protected GuiShape shape; //!< Compositing theme.
protected ShapeBox shapeProperty = ShapeBox.ZERO;
/**
* Constructor
* @param propertyShape shape file properties
*/
public ContainerWithShape(final Uri propertyShape) {
this.propertyShape = propertyShape;
onChangePropertyShape();
}
@Override
public void calculateMinMaxSize() {
// call main class
calculateMinMaxSizeWidget();
// call sub classes
if (this.subWidget != null) {
this.subWidget.calculateMinMaxSize();
final Vector3f min = this.subWidget.getCalculateMinSize();
final Padding padding = this.shape.getPadding();
this.minSize = Vector3f.max(this.minSize, min.add(padding.x(), padding.y(), padding.z()));
}
LOGGER.warn("[{}] Result min size : {}", getId(), this.minSize);
}
@AknotManaged
@AknotAttribute
@AknotName(value = "shape")
@AknotDescription(value = "The uri one the shape for the Pop-up")
public Uri getPropertyShape() {
return this.propertyShape;
}
@Override
public Widget getWidgetAtPos(final Vector3f pos) {
final Widget val = super.getWidgetAtPos(pos);
if (val != null) {
return val;
}
return this;
}
protected void onChangePropertyShape() {
if (this.shape == null) {
this.shape = new GuiShape(this.propertyShape);
} else {
this.shape.setSource(this.propertyShape);
}
markToRedraw();
requestUpdateSize();
}
@Override
public void onChangeSize() {
markToRedraw();
if (this.subWidget == null) {
return;
}
final Padding padding = this.shape.getPadding();
Vector3f subWidgetSize = this.subWidget.getCalculateMinSize();
if (this.subWidget.canExpand().x() && this.propertyFill.x()) {
subWidgetSize = subWidgetSize.withX(this.size.x());
} else {
subWidgetSize = subWidgetSize.withX(this.minSize.x());
}
if (this.subWidget.canExpand().y() && this.propertyFill.y()) {
subWidgetSize = subWidgetSize.withY(this.size.y());
} else {
subWidgetSize = subWidgetSize.withY(this.minSize.y());
}
if (this.subWidget.canExpand().z() && this.propertyFill.z()) {
subWidgetSize = subWidgetSize.withZ(this.size.z());
} else {
subWidgetSize = subWidgetSize.withZ(this.minSize.z());
}
subWidgetSize = subWidgetSize.less(padding.x(), padding.y(), padding.z());
subWidgetSize = subWidgetSize.clipInteger();
// set config to the Sub-widget
Vector3f subWidgetOrigin = this.origin.add(this.size.less(subWidgetSize).multiply(0.5f));
subWidgetOrigin = subWidgetOrigin.clipInteger();
this.subWidget.setOrigin(subWidgetOrigin);
this.subWidget.setSize(subWidgetSize);
this.subWidget.onChangeSize();
}
@Override
protected void onDraw() {
this.shape.draw();
}
@Override
public void onRegenerateDisplay() {
if (needRedraw()) {
this.shape.clear();
final Padding padding = this.shape.getPadding();
final Vector3f tmpSize = Vector3f.ZERO;
Vector3f tmpSizeShaper = this.minSize;
Vector3f tmpOriginShaper = this.propertyGravity.gravityGenerateDelta(this.size.less(this.minSize));
if (this.propertyFill.x()) {
tmpSizeShaper = tmpSizeShaper.withX(this.size.x());
tmpOriginShaper = tmpOriginShaper.withX(0.0f);
}
if (this.propertyFill.y()) {
tmpSizeShaper = tmpSizeShaper.withY(this.size.y());
tmpOriginShaper = tmpOriginShaper.withY(0.0f);
}
if (this.propertyFill.z()) {
tmpSizeShaper = tmpSizeShaper.withZ(this.size.y());
tmpOriginShaper = tmpOriginShaper.withZ(0.0f);
}
// not sure this is needed...
tmpSizeShaper = tmpSizeShaper.clipInteger();
tmpOriginShaper = tmpOriginShaper.clipInteger();
this.shapeProperty = new ShapeBox(tmpOriginShaper, tmpSizeShaper, padding);
this.shape.setShape(tmpOriginShaper, tmpSizeShaper);
}
// SubWidget generation ...
if (this.subWidget != null) {
this.subWidget.onRegenerateDisplay();
}
}
public void setPropertyShape(final Uri propertyShape) {
if (this.propertyShape.equals(propertyShape)) {
return;
}
this.propertyShape = propertyShape;
onChangePropertyShape();
}
@Override
public void systemDraw(final DrawProperty displayProp) {
if (this.propertyHide) {
// widget is hidden ...
return;
}
systemDrawWidget(displayProp);
if (this.subWidget == null) {
return;
}
if (true) { //this.shape.getNextDisplayedStatus() == GuiShapeMode.NONE && this.shape.getTransitionStatus() >= 1.0) {
final DrawProperty prop = displayProp.withLimit(this.origin, this.size);
this.subWidget.systemDraw(prop);
}
}
}

View File

@ -13,15 +13,16 @@ import org.atriasoft.esignal.Signal;
import org.atriasoft.esignal.SignalEmpty;
import org.atriasoft.etk.Uri;
import org.atriasoft.etk.math.FMath;
import org.atriasoft.etk.math.Vector2f;
import org.atriasoft.etk.math.Vector2i;
import org.atriasoft.etk.math.Vector3f;
import org.atriasoft.ewol.Padding;
import org.atriasoft.ewol.compositing.CompositingSVG;
import org.atriasoft.ewol.compositing.CompositingText;
import org.atriasoft.ewol.compositing.GuiShape;
import org.atriasoft.ewol.compositing.GuiShapeMode;
import org.atriasoft.ewol.event.EventEntry;
import org.atriasoft.ewol.event.EventInput;
import org.atriasoft.ewol.event.EventTime;
import org.atriasoft.ewol.object.EwolObject;
import org.atriasoft.gale.context.ClipBoard;
import org.atriasoft.gale.context.ClipboardList;
import org.atriasoft.gale.key.KeyKeyboard;
@ -42,19 +43,19 @@ import org.slf4j.LoggerFactory;
*/
public class Entry extends Widget {
private static final Logger LOGGER = LoggerFactory.getLogger(Entry.class);
/**
* Periodic call to update grapgic display
* @param _event Time generic event
*/
protected static void periodicCall(final Entry self, final EventTime event) {
LOGGER.trace("Periodic call on Entry(" + event + ")");
if (!self.shape.periodicCall(event)) {
self.periodicConnectionHanble.close();
}
// if (!self.shape.periodicCall(event)) {
// self.periodicConnectionHanble.close();
// }
self.markToRedraw();
}
/// color property of the text foreground
private int colorIdTextFg;
/// Cursor must be display only when the widget has the focus
@ -69,6 +70,7 @@ public class Entry extends Widget {
private int displayCursorPositionPixel = 0;
/// text display this.text
private final CompositingText text = new CompositingText();
protected CompositingSVG compositing = new CompositingSVG();
/// text position can have change
private boolean needUpdateTextPos = true;
/// Periodic call handle to remove it when needed
@ -76,16 +78,16 @@ public class Entry extends Widget {
private Uri propertyConfig = new Uri("THEME", "shape/Entry.json", "ewol");
private int propertyMaxCharacter = Integer.MAX_VALUE; //!< number max of Character in the list
private boolean propertyPassword = false; //!< Disable display of the content of the entry
/// regular expression value
private String propertyRegex = ".*";
/// Text to display when nothing in in the entry (decorated text...)
private String propertyTextWhenNothing = null;
private String propertyValue = "Test Text..."; //!< string that must be displayed
private Pattern regex = null; //!< regular expression to check content
private GuiShape shape;
//.create()
@AknotSignal
@AknotName(value = "click")
@ -95,24 +97,24 @@ public class Entry extends Widget {
@AknotName(value = "enter")
@AknotDescription("The cursor enter inside the button")
public Signal<String> signalEnter = new Signal<>(); //!< Enter key is pressed
@AknotSignal
@AknotName(value = "modify")
@AknotDescription("Entry box value change")
public Signal<String> signalModify = new Signal<>(); //!< data change
// element over:
Vector3f overPositionStart = Vector3f.ZERO;
Vector3f overPositionStop = Vector3f.ZERO;
/**
* Constructor
* @param _newData The USting that might be set in the Entry box (no event generation!!)
*/
public Entry() {
this.propertyCanFocus = true;
onChangePropertyShaper();
//onChangePropertyShaper();
this.regex = Pattern.compile(this.propertyRegex);
if (this.regex == null) {
LOGGER.error("can not parse regex for : " + this.propertyRegex);
@ -124,21 +126,17 @@ public class Entry extends Widget {
shortCutAdd("ctrl+v", "paste");
shortCutAdd("ctrl+a", "select:all");
shortCutAdd("ctrl+shift+a", "select:none");
this.shape = new GuiShape(this.propertyConfig);
//TODO this.signalShortcut.connect(this, Entry::onCallbackShortCut);
}
@Override
public void calculateMinMaxSize() {
// call main class
super.calculateMinMaxSize();
// get generic padding
Padding padding = Padding.ZERO;
if (this.shape != null) {
padding = this.shape.getPadding();
}
final Padding padding = Padding.ZERO;
final int minHeight = (int) this.text.getHeight();//calculateSize('A').y();
Vector3f minimumSizeBase = new Vector3f(20, minHeight, 10);
// add padding :
minimumSizeBase = minimumSizeBase.add(padding.x(), padding.y(), padding.z());
@ -147,18 +145,18 @@ public class Entry extends Widget {
checkMinSize();
//LOGGER.trace("min size = " + this.minSize);
}
protected void changeStatusIn(final GuiShapeMode newStatusId) {
if (this.shape.changeStatusIn(newStatusId)) {
if (!this.periodicConnectionHanble.isConnected()) {
//LOGGER.trace("REQUEST: connection on operiodic call");
this.periodicConnectionHanble = EwolObject.getObjectManager().periodicCall.connect(this,
Entry::periodicCall);
}
markToRedraw();
}
// if (this.shape.changeStatusIn(newStatusId)) {
// if (!this.periodicConnectionHanble.isConnected()) {
// //LOGGER.trace("REQUEST: connection on operiodic call");
// this.periodicConnectionHanble = EwolObject.getObjectManager().periodicCall.connect(this,
// Entry::periodicCall);
// }
// markToRedraw();
// }
}
/**
* Copy the selected data on the specify clipboard
* @param clipboardID Selected clipboard
@ -178,48 +176,48 @@ public class Entry extends Widget {
final String tmpData = this.propertyValue.substring(pos1, pos2);
ClipBoard.set(clipboardID, tmpData);
}
public Uri getPropertyConfig() {
return this.propertyConfig;
}
public int getPropertyMaxCharacter() {
return this.propertyMaxCharacter;
}
public String getPropertyRegex() {
return this.propertyRegex;
}
public String getPropertyTextWhenNothing() {
return this.propertyTextWhenNothing;
}
public String getPropertyValue() {
return this.propertyValue;
}
public boolean isPropertyPassword() {
return this.propertyPassword;
}
/**
* informe the system thet the text change and the start position change
*/
protected void markToUpdateTextPosition() {
this.needUpdateTextPos = true;
}
private void onCallbackCopy() {
copySelectionToClipBoard(ClipboardList.CLIPBOARD_STD);
}
private void onCallbackCut() {
copySelectionToClipBoard(ClipboardList.CLIPBOARD_STD);
removeSelected();
this.signalModify.emit(this.propertyValue);
}
private void onCallbackEntryClean() {
this.propertyValue = "";
this.displayStartPosition = 0;
@ -227,11 +225,11 @@ public class Entry extends Widget {
this.displayCursorPosSelection = this.displayCursorPos;
markToRedraw();
}
private void onCallbackPaste() {
ClipBoard.request(ClipboardList.CLIPBOARD_STD);
}
private void onCallbackSelect(final boolean all) {
if (all) {
this.displayCursorPosSelection = 0;
@ -241,7 +239,7 @@ public class Entry extends Widget {
}
markToRedraw();
}
private void onCallbackShortCut(final String value) {
if (value.equals("clean")) {
onCallbackEntryClean();
@ -260,15 +258,15 @@ public class Entry extends Widget {
LOGGER.warn("Unknow event from ShortCut : " + value);
}
}
protected void onChangePropertyMaxCharacter() {
// TODO : check number of char in the data
}
protected void onChangePropertyPassword() {
markToRedraw();
}
protected void onChangePropertyRegex() {
this.regex = Pattern.compile(this.propertyRegex);
if (this.regex != null) {
@ -276,23 +274,11 @@ public class Entry extends Widget {
}
markToRedraw();
}
protected void onChangePropertyShaper() {
if (this.shape == null) {
this.shape = new GuiShape(this.propertyConfig);
} else {
this.shape.setSource(this.propertyConfig);
}
// this.colorIdTextFg = this.shape.requestColor("text-foreground");
// this.colorIdTextBg = this.shape.requestColor("text-background");
// this.colorIdCursor = this.shape.requestColor("text-cursor");
// this.colorIdSelection = this.shape.requestColor("text-selection");
}
protected void onChangePropertyTextWhenNothing() {
markToRedraw();
}
protected void onChangePropertyValue() {
String newData = this.propertyValue;
if ((long) newData.length() > this.propertyMaxCharacter) {
@ -308,15 +294,15 @@ public class Entry extends Widget {
}
markToRedraw();
}
@Override
protected void onDraw() {
if (this.shape != null) {
this.shape.draw(true);
if (this.compositing != null) {
this.compositing.draw(true);
}
this.text.draw();
}
@Override
public void onEventClipboard(final ClipboardList clipboardID) {
// remove curent selected data ...
@ -340,7 +326,7 @@ public class Entry extends Widget {
}
this.signalModify.emit(this.propertyValue);
}
@Override
public boolean onEventEntry(final EventEntry event) {
LOGGER.trace("Event on Entry ... " + event);
@ -416,7 +402,7 @@ public class Entry extends Widget {
}
return false;
}
@Override
public boolean onEventInput(final EventInput event) {
final Vector3f absolutePosition = new Vector3f(event.pos().x(), event.pos().y(), 0);
@ -519,7 +505,7 @@ public class Entry extends Widget {
}
return false;
}
@Override
protected void onGetFocus() {
this.displayCursor = true;
@ -527,7 +513,7 @@ public class Entry extends Widget {
showKeyboard();
markToRedraw();
}
@Override
protected void onLostFocus() {
this.displayCursor = false;
@ -535,14 +521,14 @@ public class Entry extends Widget {
hideKeyboard();
markToRedraw();
}
@Override
public void onRegenerateDisplay() {
if (!needRedraw()) {
//return;
}
//LOGGER.trace("Regenerate Display ==> is needed: '" + this.propertyValue + "'");
this.shape.clear();
this.compositing.clear();
this.text.clear();
if (this.colorIdTextFg >= 0) {
//this.text.setDefaultColorFg(this.shape.getColor(this.colorIdTextFg));
@ -551,8 +537,8 @@ public class Entry extends Widget {
//this.text.setSelectionColor(this.shape.getColor(this.colorIdSelection));
}
updateTextPosition();
final Padding padding = this.shape.getPadding();
final Padding padding = Padding.ZERO;
Vector3f tmpSizeShaper = this.minSize;
Vector3f delta = this.propertyGravity.gravityGenerateDelta(this.size.less(this.minSize));
if (this.propertyFill.x()) {
@ -573,7 +559,7 @@ public class Entry extends Widget {
Vector3f tmpOriginText = tmpOriginShaper.add(padding.bottom(), padding.left(), padding.back()); //this.size.less(tmpSizeText).multiply(0.5f);
//Vector3f tmpOriginText = new Vector3f(0, this.text.getSize(), 0);
// sometimes, the user define an height bigger than the real size needed == > in this case we need to center the text in the shaper ...
final int minHeight = (int) this.text.getHeight();
if (tmpSizeText.y() > minHeight) {
tmpOriginText = tmpOriginText.add(0, (tmpSizeText.y() - minHeight) * 0.5f, 0);
@ -583,7 +569,7 @@ public class Entry extends Widget {
tmpOriginShaper = Vector3f.clipInt(tmpOriginShaper);
tmpSizeText = Vector3f.clipInt(tmpSizeText);
tmpOriginText = Vector3f.clipInt(tmpOriginText);
this.text.clear();
//this.text.setSize((int) tmpSizeText.x(), (int) tmpSizeText.y());
this.text.setClippingWidth(tmpOriginText, tmpSizeText);
@ -597,7 +583,7 @@ public class Entry extends Widget {
if (this.propertyPassword) {
Arrays.fill(valueToDisplay, '*');
}
//final Vector2f plop = new Vector2f(tmpOriginText.x() + this.displayStartPosition, tmpOriginText.y());
if (valueToDisplay.length != 0) {
this.text.print(new String(valueToDisplay));
@ -607,12 +593,29 @@ public class Entry extends Widget {
this.text.setClippingMode(false);
this.overPositionStart = tmpOriginShaper;
this.overPositionStop = tmpOriginShaper.add(tmpSizeShaper);
this.shape.setShape(tmpOriginShaper, tmpSizeShaper, tmpOriginText, tmpSizeText);
//this.shape.setShape(tmpOriginShaper, tmpSizeShaper, tmpOriginText, tmpSizeText);
this.compositing.setSource("""
<svg width="%d" height="%d">
<rect
x="0.5"
y="0.5"
width="%f"
height="%f"
fill="white"
stroke="black"
stroke-width="1"
/>
</svg>""".formatted( //
(int) tmpSizeShaper.x(), (int) tmpSizeShaper.y(), //
tmpSizeShaper.x() - 0.5, tmpSizeShaper.y() - 0.5//
), new Vector2i((int) tmpSizeShaper.x(), (int) tmpSizeShaper.y()));
this.compositing.setPos(tmpOriginShaper);
this.compositing.print(new Vector2f(tmpSizeShaper.x(), tmpSizeShaper.y()));
this.text.flush();
this.shape.flush();
this.compositing.flush();
}
/**
* remove the selected area
* @note This request a regeneration of the display
@ -640,7 +643,7 @@ public class Entry extends Widget {
this.propertyValue = tmp.toString();
markToRedraw();
}
/**
* internal check the value with RegExp checking
* @param newData The new string to display
@ -667,7 +670,7 @@ public class Entry extends Widget {
this.propertyValue = newData;
markToRedraw();
}
@AknotManaged
@AknotAttribute
@AknotName(value = "config")
@ -677,9 +680,9 @@ public class Entry extends Widget {
return;
}
this.propertyConfig = propertyConfig;
onChangePropertyShaper();
//onChangePropertyShaper();
}
@AknotManaged
@AknotAttribute
@AknotName(value = "max")
@ -691,7 +694,7 @@ public class Entry extends Widget {
this.propertyMaxCharacter = propertyMaxCharacter;
onChangePropertyMaxCharacter();
}
@AknotManaged
@AknotAttribute
@AknotName(value = "password")
@ -703,7 +706,7 @@ public class Entry extends Widget {
this.propertyPassword = propertyPassword;
onChangePropertyPassword();
}
@AknotManaged
@AknotAttribute
@AknotName(value = "regex")
@ -715,7 +718,7 @@ public class Entry extends Widget {
this.propertyRegex = propertyRegex;
onChangePropertyRegex();
}
@AknotManaged
@AknotAttribute
@AknotName(value = "empty-text")
@ -727,7 +730,7 @@ public class Entry extends Widget {
this.propertyTextWhenNothing = propertyTextWhenNothing;
onChangePropertyTextWhenNothing();
}
@AknotManaged
@AknotAttribute
@AknotName(value = "value")
@ -739,7 +742,7 @@ public class Entry extends Widget {
this.propertyValue = propertyValue;
onChangePropertyValue();
}
/**
* change the cursor position with the curent position requested on the display
* @param pos Absolute position of the event
@ -748,13 +751,13 @@ public class Entry extends Widget {
protected void updateCursorPosition(final Vector3f pos) {
updateCursorPosition(pos, false);
}
protected void updateCursorPosition(final Vector3f pos, final boolean selection/*=false*/) {
final Padding padding = this.shape.getPadding();
final Padding padding = Padding.ZERO;
final Vector3f relPos = relativePosition(pos).less(this.overPositionStart);
// reject when outside ...
// try to find the new cursor position :
if (this.displayStartPosition > this.propertyValue.length()) {
this.displayStartPosition = this.propertyValue.length();
@ -792,7 +795,7 @@ public class Entry extends Widget {
}
markToUpdateTextPosition();
}
/**
* update the display position start == > depending of the position of the Cursor and the size of the Data inside
* @change this.displayStartPosition < == updated
@ -801,8 +804,8 @@ public class Entry extends Widget {
if (!this.needUpdateTextPos) {
return;
}
final Padding padding = this.shape.getPadding();
final Padding padding = Padding.ZERO;
int tmpSizeX = (int) this.minSize.x();
if (this.propertyFill.x()) {
tmpSizeX = (int) this.size.x();
@ -832,5 +835,5 @@ public class Entry extends Widget {
//this.displayStartPosition = -totalWidth + tmpUserSize;
}
}
}

View File

@ -11,7 +11,6 @@ import org.atriasoft.aknot.annotation.AknotManaged;
import org.atriasoft.aknot.annotation.AknotName;
import org.atriasoft.etk.Dimension3f;
import org.atriasoft.etk.Distance;
import org.atriasoft.etk.Uri;
import org.atriasoft.etk.math.Vector3b;
import org.atriasoft.etk.math.Vector3f;
import org.atriasoft.ewol.event.EventInput;
@ -20,19 +19,19 @@ import org.atriasoft.gale.key.KeyStatus;
/**
* Pop-up Display a sub element in a field inside the whole size (id set in pup-up windows)
*/
public class PopUp extends ContainerWithShape {
public class PopUp extends Box {
// properties
public boolean propertyCloseOutEvent = false; //!< ratio progression of a sliding
/**
* Constructor
*/
public PopUp() {
super(new Uri("THEME", "shape/PopUp.json", "ewol"));
//super(new Uri("THEME", "shape/PopUp.json", "ewol"));
this.propertyMinSize = new Dimension3f(new Vector3f(80, 80, 20), Distance.POURCENT);
this.propertyExpand = Vector3b.FALSE;
}
@AknotManaged
@AknotAttribute
@AknotName(value = "out-click-remove")
@ -40,7 +39,7 @@ public class PopUp extends ContainerWithShape {
public boolean isPropertyCloseOutEvent() {
return this.propertyCloseOutEvent;
}
@Override
public boolean onEventInput(final EventInput event) {
if (this.propertyCloseOutEvent) {
@ -52,20 +51,20 @@ public class PopUp extends ContainerWithShape {
if (event.status() == KeyStatus.move) {
return false;
}
final Vector3f pos = relativePosition(new Vector3f(event.pos().x(), event.pos().y(), 0));
if (!this.shapeProperty.isInside(pos)) {
autoDestroy();
return true;
}
// if (!this.shapeProperty.isInside(pos)) {
// autoDestroy();
// return true;
// }
return false;
}
public void setPropertyCloseOutEvent(final boolean propertyCloseOutEvent) {
if (this.propertyCloseOutEvent == propertyCloseOutEvent) {
return;
}
this.propertyCloseOutEvent = propertyCloseOutEvent;
}
}

View File

@ -9,6 +9,7 @@ import org.atriasoft.aknot.annotation.AknotAttribute;
import org.atriasoft.aknot.annotation.AknotDescription;
import org.atriasoft.aknot.annotation.AknotManaged;
import org.atriasoft.aknot.annotation.AknotName;
import org.atriasoft.etk.Color;
import org.atriasoft.etk.Uri;
import org.atriasoft.etk.math.FMath;
import org.atriasoft.etk.math.Vector2f;
@ -18,7 +19,7 @@ import org.atriasoft.ewol.DrawProperty;
import org.atriasoft.ewol.GravityVertical;
import org.atriasoft.ewol.HighSpeedMode;
import org.atriasoft.ewol.Padding;
import org.atriasoft.ewol.compositing.GuiShape;
import org.atriasoft.ewol.compositing.CompositingSVG;
import org.atriasoft.ewol.event.EventInput;
import org.atriasoft.gale.key.KeyStatus;
import org.atriasoft.gale.key.KeyType;
@ -36,9 +37,8 @@ class Scroll extends Container {
protected boolean propertyHover = true; //!< Horizontal shaper name
protected GuiShape shaperH; //!< Compositing theme Horizontal.
protected GuiShape shaperV; //!< Compositing theme Vertical.
protected CompositingSVG compositingH = new CompositingSVG();
protected CompositingSVG compositingV = new CompositingSVG();
protected float pixelScrolling = 20;
protected Vector3f highSpeedStartPos = Vector3f.ZERO;
protected HighSpeedMode highSpeedMode = HighSpeedMode.speedModeDisable;
@ -46,18 +46,6 @@ class Scroll extends Container {
protected KeyType highSpeedType = KeyType.unknow;
public Scroll() {
/*
// Remove gravity property: (only keep top/buttom)
propertyGravity.remove("center");
propertyGravity.remove("top-left");
//propertyGravity.remove("top");
propertyGravity.remove("top-right");
propertyGravity.remove("right");
propertyGravity.remove("buttom-right");
//propertyGravity.remove("buttom");
propertyGravity.remove("buttom-left");
propertyGravity.remove("left");
*/
onChangePropertyShapeVert();
onChangePropertyShapeHori();
}
@ -118,12 +106,12 @@ class Scroll extends Container {
}
protected void onChangePropertyShapeHori() {
this.shaperH.setSource(this.propertyShapeHori);
//TODO: this.shaperH.setSource(this.propertyShapeHori);
markToRedraw();
}
protected void onChangePropertyShapeVert() {
this.shaperV.setSource(this.propertyShapeVert);
//TODO: this.shaperV.setSource(this.propertyShapeVert);
markToRedraw();
}
@ -171,8 +159,8 @@ class Scroll extends Container {
@Override
protected void onDraw() {
this.shaperH.draw();
this.shaperV.draw();
this.compositingH.draw();
this.compositingV.draw();
}
@Override
@ -428,10 +416,10 @@ class Scroll extends Container {
return;
}
// clear all previous display
this.shaperH.clear();
this.shaperV.clear();
final Padding paddingVert = this.shaperV.getPadding();
final Padding paddingHori = this.shaperH.getPadding();
this.compositingH.clear();
this.compositingV.clear();
final Padding paddingVert = new Padding(2, 2, 2, 2); // this.compositingV.getPadding();
final Padding paddingHori = new Padding(2, 2, 2, 2); // this.compositingH.getPadding();
Vector3f scrollOffset = Vector3f.ZERO;
Vector3f scrollSize = Vector3f.ZERO;
if (this.subWidget != null) {
@ -444,10 +432,19 @@ class Scroll extends Container {
float originScrollBar = scrollOffset.y() / (scrollSize.y() - this.size.y() * this.propertyLimit.y());
originScrollBar = FMath.avg(0.0f, originScrollBar, 1.0f);
originScrollBar *= (this.size.y() - lenScrollBar);
final Vector2f renderOrigin = new Vector2f(this.size.x() - paddingVert.x(), 0);
final Vector2f renderSize = new Vector2f(paddingVert.x(), this.size.y());
this.compositingV.setRectangleAsSource((int) renderSize.x(), (int) renderSize.y(), Color.GREEN);
this.compositingV.setPos(renderOrigin);
this.compositingV.print(renderSize);
this.compositingV.flush();
/*
this.shaperV.setShape(new Vector2f(this.size.x() - paddingVert.x(), 0),
new Vector2f(paddingVert.x(), this.size.y()),
new Vector2f(this.size.x() - paddingVert.right(), this.size.y() - originScrollBar - lenScrollBar),
new Vector2f(0, lenScrollBar));
*/
}
if (this.size.x() < scrollSize.x() || scrollOffset.x() != 0) {
float lenScrollBar = (this.size.x() - paddingHori.left()) * (this.size.x() - paddingVert.x())
@ -456,8 +453,17 @@ class Scroll extends Container {
float originScrollBar = scrollOffset.x() / (scrollSize.x() - this.size.x() * this.propertyLimit.x());
originScrollBar = FMath.avg(0.0f, originScrollBar, 1.0f);
originScrollBar *= (this.size.x() - paddingHori.right() - lenScrollBar);
final Vector2f renderOrigin = Vector2f.ZERO;
final Vector2f renderSize = new Vector2f(this.size.x() - paddingVert.x(), paddingHori.y());
this.compositingH.setRectangleAsSource((int) renderSize.x(), (int) renderSize.y(), Color.GREEN);
this.compositingH.setPos(renderOrigin);
this.compositingH.print(renderSize);
this.compositingH.flush();
/*
this.shaperH.setShape(Vector2f.ZERO, new Vector2f(this.size.x() - paddingVert.x(), paddingHori.y()),
new Vector2f(originScrollBar, paddingHori.bottom()), new Vector2f(lenScrollBar, 0));
*/
}
}

View File

@ -9,11 +9,12 @@ import org.atriasoft.esignal.Signal;
import org.atriasoft.etk.Color;
import org.atriasoft.etk.Uri;
import org.atriasoft.etk.math.FMath;
import org.atriasoft.etk.math.Vector2f;
import org.atriasoft.etk.math.Vector3f;
import org.atriasoft.etk.math.Vector3i;
import org.atriasoft.ewol.Padding;
import org.atriasoft.ewol.compositing.CompositingDrawing;
import org.atriasoft.ewol.compositing.GuiShape;
import org.atriasoft.ewol.compositing.CompositingSVG;
import org.atriasoft.ewol.event.EventInput;
import org.atriasoft.gale.key.KeyStatus;
import org.slf4j.Logger;
@ -34,8 +35,7 @@ public class Slider extends Widget {
private Uri propertyConfig = new Uri("THEME", "shape/Slider.json", "ewol");
private Float propertyValue = 0.0f; //!< string that must be displayed
private GuiShape shape = null;
private final GuiShape shapeTop = null;
protected CompositingSVG compositing = new CompositingSVG();
@AknotSignal
@AknotName("value")
@AknotDescription("Tick value change")
@ -43,8 +43,10 @@ public class Slider extends Widget {
// element over:
Vector3f overPositionStart = Vector3f.ZERO;
Vector3f overPositionStop = Vector3f.ZERO;
Vector3f overPositionSize = Vector3f.ZERO;
Vector3f overCursorPositionStart = Vector3f.ZERO;
Vector3f overCursorPositionStop = Vector3f.ZERO;
Vector3f overCursorPositionSize = Vector3f.ZERO;
//@AknotAutoGenerateProperty("minimum", "configuration of the widget")
private Float propertyMinimum = 0.0f;
@ -72,10 +74,7 @@ public class Slider extends Widget {
// call main class
super.calculateMinMaxSize();
// get generic padding
Padding padding = Padding.ZERO;
if (this.shape != null) {
padding = this.shape.getPadding();
}
final Padding padding = Padding.ZERO;
final Vector3i minHeight = Vector3i.VALUE_16;
Vector3f minimumSizeBase = new Vector3f(minHeight.x(), minHeight.y(), minHeight.z());
@ -134,22 +133,16 @@ public class Slider extends Widget {
}
protected void onChangePropertyShaper() {
if (this.shape == null) {
this.shape = new GuiShape(this.propertyConfig);
} else {
this.shape.setSource(this.propertyConfig);
}
// if (this.shape == null) {
// this.shape = new GuiShape(this.propertyConfig);
// } else {
// this.shape.setSource(this.propertyConfig);
// }
}
@Override
public void onDraw() {
if (this.shape != null) {
// draw background
this.shape.draw(true, 0);
// draw slider
this.shape.draw(true, 1);
}
this.compositing.draw();
}
@Override
@ -218,7 +211,7 @@ public class Slider extends Widget {
//return;
}
//LOGGER.trace("Regenerate Display ==> is needed: '" + this.propertyValue + "'");
this.shape.clear();
this.compositing.clear();
//this.gc.clear();
/*
if (this.colorIdTextFg >= 0) {
@ -228,7 +221,7 @@ public class Slider extends Widget {
//this.text.setSelectionColor(this.shape.getColor(this.colorIdSelection));
}
*/
final Padding padding = this.shape.getPadding();
final Padding padding = Padding.ZERO;//this.shape.getPadding();
{
// Manage external shape:
Vector3f tmpSizeShaper = this.minSize;
@ -254,8 +247,9 @@ public class Slider extends Widget {
tmpOriginInside = Vector3f.clipInt(tmpOriginInside);
this.overPositionStart = tmpOriginShaper;
this.overPositionSize = tmpSizeShaper;
this.overPositionStop = tmpOriginShaper.add(tmpSizeShaper);
this.shape.setShape(0, tmpOriginShaper, tmpSizeShaper, tmpOriginInside, tmpSizeInside);
//this.shape.setShape(0, tmpOriginShaper, tmpSizeShaper, tmpOriginInside, tmpSizeInside);
}
{
// Manage cursor:
@ -283,11 +277,19 @@ public class Slider extends Widget {
tmpOriginInside = Vector3f.clipInt(tmpOriginInside);
this.overCursorPositionStart = tmpOriginShaper;
this.overCursorPositionSize = tmpSizeShaper;
this.overCursorPositionStop = tmpOriginShaper.add(tmpSizeShaper);
this.shape.setShape(1, tmpOriginShaper, tmpSizeShaper, tmpOriginInside, tmpSizeInside);
//this.shape.setShape(1, tmpOriginShaper, tmpSizeShaper, tmpOriginInside, tmpSizeInside);
}
this.compositing.setRectangleAsSource((int) this.overPositionSize.x(), (int) this.overPositionSize.y(),
Color.GREEN);
// TODO: Refaire le design de cet affichage...
this.compositing.setPos(this.overPositionStart);
this.compositing.print(new Vector2f(this.overPositionSize.x(), this.overPositionSize.y()));
this.compositing.flush();
//this.gc.flush();
this.shape.flush();
this.compositing.flush();
}

View File

@ -4,6 +4,7 @@ import org.atriasoft.aknot.annotation.AknotAttribute;
import org.atriasoft.aknot.annotation.AknotDescription;
import org.atriasoft.aknot.annotation.AknotManaged;
import org.atriasoft.aknot.annotation.AknotName;
import org.atriasoft.etk.Color;
import org.atriasoft.etk.Uri;
import org.atriasoft.etk.math.FMath;
import org.atriasoft.etk.math.Matrix4f;
@ -12,7 +13,7 @@ import org.atriasoft.etk.math.Vector3f;
import org.atriasoft.ewol.DrawProperty;
import org.atriasoft.ewol.HighSpeedMode;
import org.atriasoft.ewol.Padding;
import org.atriasoft.ewol.compositing.GuiShape;
import org.atriasoft.ewol.compositing.CompositingSVG;
import org.atriasoft.ewol.event.EventInput;
import org.atriasoft.gale.backend3d.OpenGL;
import org.atriasoft.gale.key.KeyStatus;
@ -35,8 +36,9 @@ class WidgetScrolled extends Widget {
public static final int CALCULATE_SIMULTANEOUS_FINGER = 5;
protected Uri propertyShapeVert = new Uri("THEME", "shape/WidgetScrolled.json", "ewol"); //!< Vertical shaper name
protected Uri propertyShapeHori = new Uri("THEME", "shape/WidgetScrolled.json", "ewol"); //!< Horizontal shaper name
private GuiShape shaperH = null; //!< Compositing theme Horizontal.
private GuiShape shaperV = null; //!< Compositing theme Vertical.
protected CompositingSVG compositingH = new CompositingSVG();
protected CompositingSVG compositingV = new CompositingSVG();
protected Vector2f originScrooled = Vector2f.ZERO; //!< pixel distance from the origin of the display (Bottum left)
protected Vector2f maxSize; //!< Maximum size of the Widget ==> to display scrollbar
protected Vector2f limitScrolling = Vector2f.ZERO; //!< Mimit scrolling represent the propertion of the minimel scrolling activate (0.2 ==> 20% migt all time be visible)
@ -88,27 +90,27 @@ class WidgetScrolled extends Widget {
}
protected void onChangePropertyShapeHori() {
if (this.shaperH == null) {
this.shaperH = new GuiShape(this.propertyShapeHori);
} else {
this.shaperH.setSource(this.propertyShapeHori);
}
// if (this.shaperH == null) {
// this.shaperH = new GuiShape(this.propertyShapeHori);
// } else {
// this.shaperH.setSource(this.propertyShapeHori);
// }
markToRedraw();
}
protected void onChangePropertyShapeVert() {
if (this.shaperV == null) {
this.shaperV = new GuiShape(this.propertyShapeVert);
} else {
this.shaperV.setSource(this.propertyShapeVert);
}
// if (this.shaperV == null) {
// this.shaperV = new GuiShape(this.propertyShapeVert);
// } else {
// this.shaperV.setSource(this.propertyShapeVert);
// }
markToRedraw();
}
@Override
protected void onDraw() {
this.shaperH.draw();
this.shaperV.draw();
this.compositingH.draw();
this.compositingV.draw();
}
@Override
@ -117,8 +119,8 @@ class WidgetScrolled extends Widget {
Vector3f relativePos = relativePosition(new Vector3f(event.pos().x(), event.pos().y(), 0.0f));
// Correction due to the open Gl insertion ...
relativePos = relativePos.withY(this.size.y() - relativePos.y());
final Padding paddingV = this.shaperV.getPadding();
final Padding paddingH = this.shaperH.getPadding();
final Padding paddingV = new Padding(2, 2, 2, 2);// this.shaperV.getPadding();
final Padding paddingH = new Padding(2, 2, 2, 2);// this.shaperH.getPadding();
if (this.scroollingMode == ScrollingMode.scroolModeNormal) {
if (event.type() == KeyType.mouse
&& (this.highSpeedType == KeyType.unknow || this.highSpeedType == KeyType.mouse)) {
@ -443,14 +445,14 @@ class WidgetScrolled extends Widget {
@Override
public void onRegenerateDisplay() {
this.shaperH.clear();
this.shaperV.clear();
this.compositingH.clear();
this.compositingV.clear();
if (this.scroollingMode == ScrollingMode.scroolModeGame) {
// nothing to do ...
return;
}
final Padding paddingVert = this.shaperV.getPadding();
final Padding paddingHori = this.shaperH.getPadding();
final Padding paddingVert = new Padding(2, 2, 2, 2); // this.compositingV.getPadding();
final Padding paddingHori = new Padding(2, 2, 2, 2); // this.compositingH.getPadding();
if (this.size.y() < this.maxSize.y() || this.originScrooled.y() != 0) {
float lenScrollBar = this.size.y() * this.size.y() / this.maxSize.y();
lenScrollBar = FMath.avg(10.0f, lenScrollBar, this.size.y());
@ -458,10 +460,18 @@ class WidgetScrolled extends Widget {
/ (this.maxSize.y() - this.size.y() * this.limitScrolling.y());
originScrollBar = FMath.avg(0.0f, originScrollBar, 1.0f);
originScrollBar *= (this.size.y() - lenScrollBar);
this.shaperV.setShape(new Vector2f(this.size.x() - paddingVert.x(), 0),
new Vector2f(paddingVert.x(), this.size.y()),
new Vector2f(this.size.x() - paddingVert.right(), this.size.y() - originScrollBar - lenScrollBar),
new Vector2f(0, lenScrollBar));
final Vector2f renderOrigin = new Vector2f(this.size.x() - paddingVert.x(), 0);
final Vector2f renderSize = new Vector2f(paddingVert.x(), this.size.y());
this.compositingV.setRectangleAsSource((int) renderSize.x(), (int) renderSize.y(), Color.GREEN);
this.compositingV.setPos(renderOrigin);
this.compositingV.print(renderSize);
this.compositingV.flush();
// this.shaperV.setShape(new Vector2f(this.size.x() - paddingVert.x(), 0),
// new Vector2f(paddingVert.x(), this.size.y()),
// new Vector2f(this.size.x() - paddingVert.right(), this.size.y() - originScrollBar - lenScrollBar),
// new Vector2f(0, lenScrollBar));
}
if (this.size.x() < this.maxSize.x() || this.originScrooled.x() != 0) {
float lenScrollBar = (this.size.x() - paddingHori.left()) * (this.size.x() - paddingVert.x())
@ -471,8 +481,16 @@ class WidgetScrolled extends Widget {
/ (this.maxSize.x() - this.size.x() * this.limitScrolling.x());
originScrollBar = FMath.avg(0.0f, originScrollBar, 1.0f);
originScrollBar *= (this.size.x() - paddingHori.right() - lenScrollBar);
this.shaperH.setShape(new Vector2f(0, 0), new Vector2f(this.size.x() - paddingVert.x(), paddingHori.y()),
new Vector2f(originScrollBar, paddingHori.bottom()), new Vector2f(lenScrollBar, 0));
final Vector2f renderOrigin = Vector2f.ZERO;
final Vector2f renderSize = new Vector2f(this.size.x() - paddingVert.x(), paddingHori.y());
this.compositingH.setRectangleAsSource((int) renderSize.x(), (int) renderSize.y(), Color.GREEN);
this.compositingH.setPos(renderOrigin);
this.compositingH.print(renderSize);
this.compositingH.flush();
// this.shaperH.setShape(new Vector2f(0, 0), new Vector2f(this.size.x() - paddingVert.x(), paddingHori.y()),
// new Vector2f(originScrollBar, paddingHori.bottom()), new Vector2f(lenScrollBar, 0));
}
}