[FEAT] continue integration of SVG...
This commit is contained in:
parent
adef08ac95
commit
9472ddc46b
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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));
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user