Compare commits

...

2 Commits

14 changed files with 451 additions and 350 deletions

View File

@ -16,8 +16,8 @@
"program-frag":"THEME:shape/aaRenderShape.frag?lib=ewol",
# Object to render (with modification)
"object-file":"THEME:shape/CheckBox.emf?lib=ewol",
"object-file-2":"THEME:shape/CheckBox.emf?lib=ewol&filter=^CheckBox.*$",
"object-file":"THEME:shape/Tick.emf?lib=ewol",
"object-file-2":"THEME:shape/Tick.emf?lib=ewol&filter=^CheckBox.*$",
"palette":"THEME:shape/palette_gui.json?lib=ewol",

View File

@ -52,25 +52,25 @@ public class BasicWindows extends Windows {
public static void eventButtonExpandX(final BasicWindows self, final Boolean value) {
final Vector3b state = self.testWidget.getPropertyExpand();
self.testWidget.setPropertyExpand(state.withX(value));
//self.buttonExpandX.setPropertyValue(state.x() ? "expand X" : "un-expand X");
Log.info("set expand X: {}", state.x() ? "un-expand X" : "expand X");
}
public static void eventButtonExpandY(final BasicWindows self, final Boolean value) {
final Vector3b state = self.testWidget.getPropertyExpand();
self.testWidget.setPropertyExpand(state.withY(value));
//self.buttonExpandY.setPropertyValue(state.y() ? "expand Y" : "un-expand Y");
Log.info("set expand Y: {}", state.y() ? "un-expand Y" : "expand Y");
}
public static void eventButtonFillX(final BasicWindows self, final Boolean value) {
final Vector3b state = self.testWidget.getPropertyFill();
self.testWidget.setPropertyFill(state.withX(value));
//self.buttonFillX.setPropertyValue(state.x() ? "fill X" : "un-fill X");
Log.info("set fill X: {}", state.x() ? "un-fill X" : "fill X");
}
public static void eventButtonFillY(final BasicWindows self, final Boolean value) {
final Vector3b state = self.testWidget.getPropertyFill();
self.testWidget.setPropertyFill(state.withY(value));
//self.buttonFillY.setPropertyValue(state.y() ? "fill Y" : "un-fill Y");
Log.info("set fill Y: {}", state.y() ? "un-fill Y" : "fill Y");
}
Widget testWidget;

View File

@ -1,39 +1,76 @@
package sample.atriasoft.ewol;
import io.scenarium.logger.LogLevel;
import io.scenarium.logger.Logger;
public class Log {
private static final String LIBNAME = "LoxelEngine";
private static final boolean FORCE_ALL = false;
private static final String LIB_NAME = "ewol-sample";
private static final String LIB_NAME_DRAW = Logger.getDrawableName(Log.LIB_NAME);
private static final boolean PRINT_CRITICAL = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.CRITICAL);
private static final boolean PRINT_DEBUG = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.DEBUG);
private static final boolean PRINT_ERROR = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.ERROR);
private static final boolean PRINT_INFO = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.INFO);
private static final boolean PRINT_PRINT = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.PRINT);
private static final boolean PRINT_TODO = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.TODO);
private static final boolean PRINT_VERBOSE = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.VERBOSE);
private static final boolean PRINT_WARNING = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.WARNING);
public static void critical(final String data) {
System.out.println("[C] " + Log.LIBNAME + " | " + data);
public static void critical(final Exception e, final String data) {
e.printStackTrace();
if (PRINT_CRITICAL || FORCE_ALL) {
Logger.critical(LIB_NAME_DRAW, data + " : " + e.getMessage());
}
}
public static void debug(final String data) {
System.out.println("[D] " + Log.LIBNAME + " | " + data);
public static void critical(final String data, final Object... objects) {
if (PRINT_CRITICAL || FORCE_ALL) {
Logger.critical(LIB_NAME_DRAW, data, objects);
}
}
public static void error(final String data) {
System.out.println("[E] " + Log.LIBNAME + " | " + data);
public static void debug(final String data, final Object... objects) {
if (PRINT_DEBUG || FORCE_ALL) {
Logger.debug(LIB_NAME_DRAW, data, objects);
}
}
public static void info(final String data) {
System.out.println("[I] " + Log.LIBNAME + " | " + data);
public static void error(final String data, final Object... objects) {
if (PRINT_ERROR || FORCE_ALL) {
Logger.error(LIB_NAME_DRAW, data, objects);
}
}
public static void print(final String data) {
System.out.println(data);
public static void info(final String data, final Object... objects) {
if (PRINT_INFO || FORCE_ALL) {
Logger.info(LIB_NAME_DRAW, data, objects);
}
}
public static void todo(final String data) {
System.out.println("[TODO] " + Log.LIBNAME + " | " + data);
public static void print(final String data, final Object... objects) {
if (PRINT_PRINT || FORCE_ALL) {
Logger.print(LIB_NAME_DRAW, data, objects);
}
}
public static void verbose(final String data) {
System.out.println("[V] " + Log.LIBNAME + " | " + data);
public static void todo(final String data, final Object... objects) {
if (PRINT_TODO || FORCE_ALL) {
Logger.todo(LIB_NAME_DRAW, data, objects);
}
}
public static void warning(final String data) {
System.out.println("[W] " + Log.LIBNAME + " | " + data);
public static void verbose(final String data, final Object... objects) {
if (PRINT_VERBOSE || FORCE_ALL) {
Logger.verbose(LIB_NAME_DRAW, data, objects);
}
}
public static void warning(final String data, final Object... objects) {
if (PRINT_WARNING || FORCE_ALL) {
Logger.warning(LIB_NAME_DRAW, data, objects);
}
}
private Log() {}
}

View File

@ -1,6 +1,9 @@
package sample.atriasoft.ewol.sampleEntry;
import org.atriasoft.etk.Dimension3f;
import org.atriasoft.etk.Distance;
import org.atriasoft.etk.math.Vector3b;
import org.atriasoft.etk.math.Vector3f;
import org.atriasoft.ewol.widget.Entry;
import sample.atriasoft.ewol.BasicWindows;
@ -10,9 +13,10 @@ public class MainWindows extends BasicWindows {
public MainWindows() {
setPropertyTitle("Simple Entry test");
Entry simpleEntry = new Entry();
final Entry simpleEntry = new Entry();
simpleEntry.setPropertyExpand(Vector3b.TRUE);
simpleEntry.setPropertyFill(Vector3b.TRUE_FALSE_FALSE);
simpleEntry.setPropertyMinSize(new Dimension3f(new Vector3f(200, 15, 10), Distance.PIXEL));
this.setTestWidget(simpleEntry);
}

View File

@ -12,8 +12,12 @@ import sample.atriasoft.ewol.BasicWindows;
public class MainWindows extends BasicWindows {
public static void eventButtonChangeImage(final MainWindows self) {
self.testWidget.setPropertySource(new Uri("DATA", "mireC.png"));
public static void eventButtonChangeImage(final MainWindows self, final Boolean value) {
if (value) {
self.testWidget.setPropertySource(new Uri("DATA", "mireC.png"));
} else {
self.testWidget.setPropertySource(new Uri("DATA", "mireA.png"));
}
}
public static void eventButtonChangeKeepRatio(final MainWindows self) {
@ -36,12 +40,12 @@ public class MainWindows extends BasicWindows {
this.testWidget.setPropertyMinSize(new Dimension3f(Vector3f.VALUE_16, Distance.PIXEL));
this.setTestWidget(this.testWidget);
{
final Button button = Button.createLabelButton("Change image");
final Button button = Button.createToggleLabelButton("mireA.png", "mireC.png");
button.setPropertyExpand(Vector3b.FALSE);
button.setPropertyFill(Vector3b.FALSE);
button.setPropertyMinSize(new Dimension3f(Vector3f.VALUE_16, Distance.PIXEL));
this.addButton(button);
button.signalClick.connectAuto(this, MainWindows::eventButtonChangeImage);
button.signalValue.connectAuto(this, MainWindows::eventButtonChangeImage);
}
this.buttonAspectRatio = Button.createLabelButton("keep aspect ratio");
this.buttonAspectRatio.setPropertyExpand(Vector3b.FALSE);

View File

@ -399,6 +399,10 @@ public class Button extends ContainerToggle {
tmpSizeShaper = tmpSizeShaper.withY(this.size.y());
delta = delta.withY(0.0f);
}
if (this.propertyFill.z()) {
tmpSizeShaper = tmpSizeShaper.withZ(this.size.y());
delta = delta.withZ(0.0f);
}
Vector3f tmpOriginShaper = delta;
Vector3f tmpSizeText = tmpSizeShaper.less(padding.x(), padding.y(), padding.z());

View File

@ -1,311 +1,29 @@
package org.atriasoft.ewol.widget;
import org.atriasoft.esignal.Connection;
import org.atriasoft.esignal.Signal;
import org.atriasoft.esignal.SignalEmpty;
import org.atriasoft.etk.Uri;
import org.atriasoft.etk.math.Vector3f;
import org.atriasoft.etk.math.Vector3i;
import org.atriasoft.ewol.Padding;
import org.atriasoft.ewol.annotation.EwolDescription;
import org.atriasoft.ewol.annotation.EwolSignal;
import org.atriasoft.ewol.compositing.GuiShape;
import org.atriasoft.ewol.compositing.GuiShapeMode;
import org.atriasoft.ewol.event.EventInput;
import org.atriasoft.ewol.event.EventTime;
import org.atriasoft.ewol.internal.Log;
import org.atriasoft.ewol.object.EwolObject;
import org.atriasoft.exml.annotation.XmlAttribute;
import org.atriasoft.exml.annotation.XmlManaged;
import org.atriasoft.exml.annotation.XmlName;
import org.atriasoft.gale.key.KeyStatus;
import org.atriasoft.etk.math.Vector3b;
import org.atriasoft.ewol.Gravity;
import org.atriasoft.ewol.widget.Sizer.DisplayMode;
/**
* @ingroup ewolWidgetGroup
* Entry box display :
*
* ~~~~~~~~~~~~~~~~~~~~~~
* ----------------------------------------------
* | Text Label |
* ----------------------------------------------
* ~~~~~~~~~~~~~~~~~~~~~~
*/
/*
public SignalEmpty signalPressed;
public SignalEmpty signalDown;
public SignalEmpty signalUp;
public SignalEmpty signalEnter;
public Signal<Boolean> signalValue;
public boolean propertyValue; //!< Current state of the checkbox.
public Uri> propertyShape; //!< shape of the widget
*/
public class CheckBox extends Widget {
/**
* Periodic call to update grapgic display
* @param _event Time generic event
*/
protected static void periodicCall(final CheckBox self, final EventTime event) {
Log.verbose("Periodic call on Entry(" + event + ")");
if (!self.shape.periodicCall(event)) {
//Log.error("end periodic call");
self.periodicConnectionHanble.close();
}
self.markToRedraw();
}
public class CheckBox extends Container {
/// color property of the text foreground
private int colorIdTextFg;
/// text display this.text
//private final CompositingGraphicContext gc = new CompositingGraphicContext();
/// Periodic call handle to remove it when needed
protected Connection periodicConnectionHanble = new Connection();
private Uri propertyConfig = new Uri("THEME", "shape/CheckBox.json", "ewol");
private Boolean propertyValue = false; //!< string that must be displayed
private GuiShape shape;
@EwolSignal(name = "down", description = "CheckBox is Down")
public SignalEmpty signalDown = new SignalEmpty();
@EwolSignal(name = "up", description = "CheckBox is Up")
public SignalEmpty signalUp = new SignalEmpty();
@EwolSignal(name = "click", description = "CheckBox is Clicked")
public SignalEmpty signalClick = new SignalEmpty();
@EwolSignal(name = "value", description = "CheckBox value change")
public Signal<Boolean> signalValue;
// element over:
Vector3f overPositionStart = Vector3f.ZERO;
Vector3f overPositionStop = Vector3f.ZERO;
private boolean isDown;
/**
* Constuctor
*/
public CheckBox() {
this.propertyCanFocus = true;
onChangePropertyShaper();
markToRedraw();
// can not support multiple click...
setMouseLimit(1);
this.shape = new GuiShape(this.propertyConfig);
}
@Override
public void calculateMinMaxSize() {
// call main class
super.calculateMinMaxSize();
// get generic padding
Padding padding = Padding.ZERO;
if (this.shape != null) {
padding = this.shape.getPadding();
}
Vector3i minHeight = Vector3i.VALUE_16;
final Sizer subs = new Sizer(DisplayMode.modeHori);
subs.setPropertyLockExpand(Vector3b.TRUE);
subs.setPropertyGravity(Gravity.CENTER);
setSubWidget(subs);
Vector3f minimumSizeBase = new Vector3f(minHeight.x(), minHeight.y(), minHeight.z());
// add padding :
minimumSizeBase = minimumSizeBase.add(padding.x(), padding.y(), padding.z());
this.minSize = Vector3f.max(this.minSize, minimumSizeBase);
// verify the min max of the min size ...
checkMinSize();
Log.error("min size = " + this.minSize);
}
protected void changeStatusIn(final GuiShapeMode newStatusId) {
if (this.shape.changeStatusIn(newStatusId)) {
if (!this.periodicConnectionHanble.isConnected()) {
//Log.error("REQUEST: connection on periodic call");
this.periodicConnectionHanble = EwolObject.getObjectManager().periodicCall.connect(this, CheckBox::periodicCall);
}
markToRedraw();
}
}
private boolean checkIfOver(Vector3f relPos) {
return relPos.x() > this.overPositionStart.x() && relPos.y() > this.overPositionStart.y() && relPos.x() < this.overPositionStop.x() && relPos.y() < this.overPositionStop.y();
}
@XmlManaged
@XmlAttribute
@XmlName(value = "config")
@EwolDescription(value = "configuration of the widget")
public Uri getPropertyConfig() {
return this.propertyConfig;
}
@XmlManaged
@XmlAttribute
@XmlName(value = "value")
@EwolDescription(value = "State of the checkbox")
public Boolean getPropertyValue() {
return this.propertyValue;
}
protected void onChangePropertyShaper() {
if (this.shape == null) {
this.shape = new GuiShape(this.propertyConfig);
} else {
this.shape.setSource(this.propertyConfig);
}
}
protected void onChangePropertyTextWhenNothing() {
markToRedraw();
}
protected void onChangePropertyValue() {
//Boolean newData = this.propertyValue;
markToRedraw();
}
@Override
protected void onDraw() {
if (this.shape != null) {
this.shape.draw(true, this.propertyValue ? 0 : 1);
}
}
@Override
public boolean onEventInput(final EventInput event) {
Vector3f positionAbsolute = new Vector3f(event.pos().x(), event.pos().y(), 0);
Vector3f relPos = relativePosition(positionAbsolute);
Log.warning("Event on Input ... " + event + " relPos = " + relPos);
boolean over = checkIfOver(relPos);
//filter if outside the element...
if (event.status() == KeyStatus.leave) {
changeStatusIn(GuiShapeMode.NORMAL);
this.isDown = false;
return true;
}
if (event.inputId() == 0) {
if (!this.isDown) {
if (KeyStatus.leave == event.status()) {
changeStatusIn(GuiShapeMode.NORMAL);
} else {
Log.verbose("Detect Over : " + this.overPositionStart + " -> " + this.overPositionStop);
if (over) {
changeStatusIn(GuiShapeMode.OVER);
} else {
changeStatusIn(GuiShapeMode.NORMAL);
}
}
return true;
}
}
if (event.inputId() != 1) {
return false;
}
if (KeyStatus.pressSingle == event.status() && over) {
keepFocus();
this.signalClick.emit();
this.propertyValue = !this.propertyValue;
return true;
}
if (KeyStatus.down == event.status() && over) {
keepFocus();
this.isDown = true;
changeStatusIn(GuiShapeMode.SELECT);
markToRedraw();
this.signalDown.emit();
return true;
}
if (KeyStatus.move == event.status() && over) {
keepFocus();
markToRedraw();
return true;
}
if (KeyStatus.up == event.status() && this.isDown) {
keepFocus();
this.isDown = false;
this.signalUp.emit();
changeStatusIn(GuiShapeMode.OVER);
markToRedraw();
return true;
}
return false;
}
@Override
public void onRegenerateDisplay() {
if (!needRedraw()) {
//return;
}
//Log.verbose("Regenerate Display ==> is needed: '" + this.propertyValue + "'");
this.shape.clear();
//this.gc.clear();
if (this.colorIdTextFg >= 0) {
//this.text.setDefaultColorFg(this.shape.getColor(this.colorIdTextFg));
//this.text.setDefaultColorBg(this.shape.getColor(this.colorIdTextBg));
//this.text.setCursorColor(this.shape.getColor(this.colorIdCursor));
//this.text.setSelectionColor(this.shape.getColor(this.colorIdSelection));
}
Padding padding = this.shape.getPadding();
final Tick tick = new Tick();
tick.setPropertyExpand(new Vector3b(false, true, true));
tick.setPropertyFill(Vector3b.FALSE);
tick.setPropertyGravity(Gravity.CENTER);
subs.subWidgetAdd(tick);
Vector3f tmpSizeShaper = this.minSize;
Vector3f delta = this.propertyGravity.gravityGenerateDelta(this.size.less(this.minSize));
if (this.propertyFill.x()) {
tmpSizeShaper = tmpSizeShaper.withX(this.size.x());
delta = delta.withX(0.0f);
}
if (this.propertyFill.y()) {
tmpSizeShaper = tmpSizeShaper.withY(this.size.y());
delta = delta.withY(0.0f);
}
final Label label = new Label("No Label");
label.setPropertyExpand(Vector3b.TRUE);
label.setPropertyFill(Vector3b.FALSE);
label.setPropertyGravity(Gravity.LEFT);
subs.subWidgetAdd(label);
Vector3f tmpOriginShaper = delta;
Vector3f tmpSizeInside = tmpSizeShaper.less(padding.x(), padding.y(), padding.z());
//Vector3f tmpOriginText = this.size.less(tmpSizeText).multiply(0.5f);
Vector3f tmpOriginInside = Vector3f.ZERO;//this.gc.getTextSize());
// sometimes, the user define an height bigger than the real size needed == > in this case we need to center the text in the shaper ...
/*
int minHeight = this.gc.getTextHeight();
if (tmpSizeText.y() > minHeight) {
tmpOriginText = tmpOriginText.add(0, (tmpSizeText.y() - minHeight) * 0.5f);
}
*/
// fix all the position in the int class:
tmpSizeShaper = Vector3f.clipInt(tmpSizeShaper);
tmpOriginShaper = Vector3f.clipInt(tmpOriginShaper);
tmpSizeInside = Vector3f.clipInt(tmpSizeInside);
tmpOriginInside = Vector3f.clipInt(tmpOriginInside);
//this.gc.clear();
//this.gc.setSize((int)tmpSizeText.x(), (int)tmpSizeText.y());
//this.gc.setColorFill(Color.BLACK);
//this.gc.setColorStroke(Color.NONE);
//this.gc.setStrokeWidth(1);
//this.gc.text(tmpOriginText, this.propertyValue);
this.overPositionStart = tmpOriginShaper;
this.overPositionStop = tmpOriginShaper.add(tmpSizeShaper);
this.shape.setShape(tmpOriginShaper, tmpSizeShaper, tmpOriginInside, tmpSizeInside);
//this.gc.flush();
this.shape.flush();
}
/**
* internal check the value with RegExp checking
* @param newData The new string to display
*/
protected void setInternalValue(final Boolean newData) {
this.propertyValue = newData;
markToRedraw();
}
public void setPropertyConfig(final Uri propertyConfig) {
if (this.propertyConfig.equals(propertyConfig)) {
return;
}
this.propertyConfig = propertyConfig;
onChangePropertyShaper();
}
public void setPropertyValue(final Boolean propertyValue) {
if (this.propertyValue.equals(propertyValue)) {
return;
}
this.propertyValue = propertyValue;
onChangePropertyValue();
}
}

View File

@ -426,6 +426,10 @@ public class Entry extends Widget {
}
}
}
if (relPos.x() < this.overPositionStart.x() || relPos.y() < this.overPositionStart.y() || relPos.x() > this.overPositionStop.x() || relPos.y() > this.overPositionStop.y()) {
Log.warning("Reject {}", relPos);
return false;
}
if (event.inputId() == 1) {
if (KeyStatus.pressSingle == event.status()) {
keepFocus();
@ -533,19 +537,23 @@ public class Entry extends Widget {
final Padding padding = this.shape.getPadding();
Vector3f tmpSizeShaper = this.minSize;
Vector3f delta = this.propertyGravity.gravityGenerateDelta(this.size.less(this.minSize));
if (this.propertyFill.x()) {
tmpSizeShaper = tmpSizeShaper.withX(this.size.x());
delta = delta.withX(0.0f);
}
if (this.propertyFill.y()) {
tmpSizeShaper = tmpSizeShaper.withY(this.size.y());
delta = delta.withY(0.0f);
}
if (this.propertyFill.z()) {
tmpSizeShaper = tmpSizeShaper.withZ(this.size.z());
delta = delta.withZ(0.0f);
}
Vector3f tmpOriginShaper = this.size.less(tmpSizeShaper).multiply(0.5f);
Vector3f tmpOriginShaper = delta;
//Vector3f tmpOriginShaper = this.size.less(tmpSizeShaper).multiply(0.5f);
Vector3f tmpSizeText = tmpSizeShaper.less(padding.x(), padding.y(), padding.z());
Vector3f tmpOriginText = this.size.less(tmpSizeText).multiply(0.5f);
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 ...
@ -727,8 +735,9 @@ public class Entry extends Widget {
protected void updateCursorPosition(final Vector3f pos, final boolean selection/*=false*/) {
final Padding padding = this.shape.getPadding();
Vector3f relPos = relativePosition(pos);
relPos = relPos.withX(relPos.x() - this.displayStartPosition - padding.left());
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();

View File

@ -10,6 +10,7 @@ import org.atriasoft.etk.Uri;
import org.atriasoft.etk.math.FMath;
import org.atriasoft.etk.math.Vector3f;
import org.atriasoft.etranslate.ETranslate;
import org.atriasoft.ewol.Padding;
import org.atriasoft.ewol.annotation.EwolDescription;
import org.atriasoft.ewol.annotation.EwolSignal;
import org.atriasoft.ewol.compositing.AlignMode;
@ -110,7 +111,8 @@ public class Label extends Widget {
return;
}
this.textCompose.clear();
final int paddingSize = 2;
//final int paddingSize = 2;
final Padding padding = new Padding(2, 2, 2, 2);
final Vector3f tmpMax = this.propertyMaxSize.getPixel();
// to know the size of one line :
@ -119,34 +121,45 @@ public class Label extends Widget {
//minSize.setX(etk::max(minSize.x(), this.minSize.x()));
//minSize.setY(etk::max(minSize.y(), this.minSize.y()));
if (tmpMax.x() <= 999999) {
this.textCompose.setTextAlignment(0, tmpMax.x() - 2.0f * paddingSize, AlignMode.LEFT);
this.textCompose.setTextAlignment(0, tmpMax.x() - padding.x(), AlignMode.LEFT);
}
final Vector3f curentTextSize = this.textCompose.calculateSizeDecorated(this.value);
Vector3f localSize = this.minSize.clipInteger();
//Vector3f localSize = this.minSize.clipInteger();
Vector3f tmpSizeShaper = this.minSize;
// no change for the text origin :
Vector3f tmpTextOrigin = new Vector3f((this.size.x() - minSize.x()) * 0.5f, (this.size.y() - minSize.y()) * 0.5f, 0);
Vector3f delta = this.propertyGravity.gravityGenerateDelta(this.size.less(this.minSize));
if (this.propertyFill.x()) {
localSize = localSize.withX(this.size.x());
tmpSizeShaper = tmpSizeShaper.withX(this.size.x());
delta = delta.withX(0.0f);
tmpTextOrigin = tmpTextOrigin.withX(0);
}
if (this.propertyFill.y()) {
localSize = localSize.withY(this.size.y());
tmpTextOrigin = tmpTextOrigin.withY(this.size.y() - 2 * paddingSize - curentTextSize.y());
tmpSizeShaper = tmpSizeShaper.withY(this.size.y());
delta = delta.withY(0.0f);
//tmpTextOrigin = tmpTextOrigin.withY(this.size.y() - 2 * paddingSize - curentTextSize.y());
}
tmpTextOrigin = tmpTextOrigin.add(paddingSize, paddingSize, 0);
localSize = localSize.less(2 * paddingSize, 2 * paddingSize, 0);
if (this.propertyFill.z()) {
tmpSizeShaper = tmpSizeShaper.withZ(this.size.y());
delta = delta.withZ(0.0f);
}
final Vector3f tmpOriginShaper = delta;
final Vector3f tmpSizeText = tmpSizeShaper.less(padding.x(), padding.y(), padding.z());
tmpTextOrigin = tmpOriginShaper;//tmpTextOrigin.add(paddingSize, paddingSize, 0);
//localSize = localSize.less(2 * paddingSize, 2 * paddingSize, 0);
//tmpTextOrigin = tmpTextOrigin.withY(tmpTextOrigin.y() + (this.minSize.y() - 2 * paddingSize) - minSize.y());
tmpTextOrigin = tmpTextOrigin.withY(tmpTextOrigin.y() + this.minSize.y() / 2 - this.textCompose.getHeight());// - this.minSize.y() - paddingSize);
tmpTextOrigin = tmpTextOrigin.withX(tmpTextOrigin.x() - curentTextSize.x() * 0.5f);
tmpTextOrigin = tmpTextOrigin.withY(tmpTextOrigin.y() + this.minSize.y() - this.textCompose.getHeight() - padding.top());// - this.minSize.y() - paddingSize);
tmpTextOrigin = tmpTextOrigin.withX(tmpTextOrigin.x() + padding.left());
final Vector3f textPos = new Vector3f(tmpTextOrigin.x(), tmpTextOrigin.y(), 0);
final Vector3f drawClippingPos = new Vector3f(paddingSize, paddingSize, -0.5f);
final Vector3f drawClippingSize = new Vector3f((this.size.x() - paddingSize), (this.size.y() - paddingSize), 1);
final Vector3f drawClippingPos = tmpOriginShaper.less(new Vector3f(padding.left(), padding.bottom(), padding.back()));
final Vector3f drawClippingSize = tmpOriginShaper.add(tmpSizeShaper); /// new Vector3f((this.size.x() - paddingSize), (this.size.y() - paddingSize), 1);
// clean the element
this.textCompose.reset();
@ -159,8 +172,8 @@ public class Label extends Widget {
}
this.textCompose.setPos(tmpTextOrigin);
Log.verbose("[{}] '{}' display at pos={}, size={}", getId(), this.value, tmpTextOrigin, this.size);
this.textCompose.setTextAlignment(tmpTextOrigin.x(), tmpTextOrigin.x() + localSize.x(), AlignMode.LEFT);
//this.textCompose.setClipping(drawClippingPos, drawClippingSize);
this.textCompose.setTextAlignment(tmpTextOrigin.x(), tmpTextOrigin.x() + tmpSizeText.x(), AlignMode.LEFT);
this.textCompose.setClipping(drawClippingPos, drawClippingSize);
this.textCompose.printDecorated(this.value);
this.textCompose.flush();
}

View File

@ -0,0 +1,311 @@
package org.atriasoft.ewol.widget;
import org.atriasoft.esignal.Connection;
import org.atriasoft.esignal.Signal;
import org.atriasoft.esignal.SignalEmpty;
import org.atriasoft.etk.Uri;
import org.atriasoft.etk.math.Vector3f;
import org.atriasoft.etk.math.Vector3i;
import org.atriasoft.ewol.Padding;
import org.atriasoft.ewol.annotation.EwolDescription;
import org.atriasoft.ewol.annotation.EwolSignal;
import org.atriasoft.ewol.compositing.GuiShape;
import org.atriasoft.ewol.compositing.GuiShapeMode;
import org.atriasoft.ewol.event.EventInput;
import org.atriasoft.ewol.event.EventTime;
import org.atriasoft.ewol.internal.Log;
import org.atriasoft.ewol.object.EwolObject;
import org.atriasoft.exml.annotation.XmlAttribute;
import org.atriasoft.exml.annotation.XmlManaged;
import org.atriasoft.exml.annotation.XmlName;
import org.atriasoft.gale.key.KeyStatus;
/**
* @ingroup ewolWidgetGroup
* Entry box display :
*
* ~~~~~~~~~~~~~~~~~~~~~~
* ----------------------------------------------
* | Text Label |
* ----------------------------------------------
* ~~~~~~~~~~~~~~~~~~~~~~
*/
/*
public SignalEmpty signalPressed;
public SignalEmpty signalDown;
public SignalEmpty signalUp;
public SignalEmpty signalEnter;
public Signal<Boolean> signalValue;
public boolean propertyValue; //!< Current state of the Tick.
public Uri> propertyShape; //!< shape of the widget
*/
public class Tick extends Widget {
/**
* Periodic call to update grapgic display
* @param _event Time generic event
*/
protected static void periodicCall(final Tick self, final EventTime event) {
Log.verbose("Periodic call on Entry(" + event + ")");
if (!self.shape.periodicCall(event)) {
//Log.error("end periodic call");
self.periodicConnectionHanble.close();
}
self.markToRedraw();
}
/// color property of the text foreground
private int colorIdTextFg;
/// text display this.text
//private final CompositingGraphicContext gc = new CompositingGraphicContext();
/// Periodic call handle to remove it when needed
protected Connection periodicConnectionHanble = new Connection();
private Uri propertyConfig = new Uri("THEME", "shape/Tick.json", "ewol");
private Boolean propertyValue = false; //!< string that must be displayed
private GuiShape shape;
@EwolSignal(name = "down", description = "Tick is Down")
public SignalEmpty signalDown = new SignalEmpty();
@EwolSignal(name = "up", description = "Tick is Up")
public SignalEmpty signalUp = new SignalEmpty();
@EwolSignal(name = "click", description = "Tick is Clicked")
public SignalEmpty signalClick = new SignalEmpty();
@EwolSignal(name = "value", description = "Tick value change")
public Signal<Boolean> signalValue;
// element over:
Vector3f overPositionStart = Vector3f.ZERO;
Vector3f overPositionStop = Vector3f.ZERO;
private boolean isDown;
/**
* Constuctor
*/
public Tick() {
this.propertyCanFocus = true;
onChangePropertyShaper();
markToRedraw();
// can not support multiple click...
setMouseLimit(1);
this.shape = new GuiShape(this.propertyConfig);
}
@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 Vector3i minHeight = Vector3i.VALUE_16;
Vector3f minimumSizeBase = new Vector3f(minHeight.x(), minHeight.y(), minHeight.z());
// add padding :
minimumSizeBase = minimumSizeBase.add(padding.x(), padding.y(), padding.z());
this.minSize = Vector3f.max(this.minSize, minimumSizeBase);
// verify the min max of the min size ...
checkMinSize();
Log.error("min size = " + this.minSize);
}
protected void changeStatusIn(final GuiShapeMode newStatusId) {
if (this.shape.changeStatusIn(newStatusId)) {
if (!this.periodicConnectionHanble.isConnected()) {
//Log.error("REQUEST: connection on periodic call");
this.periodicConnectionHanble = EwolObject.getObjectManager().periodicCall.connect(this, Tick::periodicCall);
}
markToRedraw();
}
}
private boolean checkIfOver(final Vector3f relPos) {
return relPos.x() > this.overPositionStart.x() && relPos.y() > this.overPositionStart.y() && relPos.x() < this.overPositionStop.x() && relPos.y() < this.overPositionStop.y();
}
@XmlManaged
@XmlAttribute
@XmlName(value = "config")
@EwolDescription(value = "configuration of the widget")
public Uri getPropertyConfig() {
return this.propertyConfig;
}
@XmlManaged
@XmlAttribute
@XmlName(value = "value")
@EwolDescription(value = "State of the Tick")
public Boolean getPropertyValue() {
return this.propertyValue;
}
protected void onChangePropertyShaper() {
if (this.shape == null) {
this.shape = new GuiShape(this.propertyConfig);
} else {
this.shape.setSource(this.propertyConfig);
}
}
protected void onChangePropertyTextWhenNothing() {
markToRedraw();
}
protected void onChangePropertyValue() {
//Boolean newData = this.propertyValue;
markToRedraw();
}
@Override
protected void onDraw() {
if (this.shape != null) {
this.shape.draw(true, this.propertyValue ? 0 : 1);
}
}
@Override
public boolean onEventInput(final EventInput event) {
final Vector3f positionAbsolute = new Vector3f(event.pos().x(), event.pos().y(), 0);
final Vector3f relPos = relativePosition(positionAbsolute);
Log.warning("Event on Input ... " + event + " relPos = " + relPos);
final boolean over = checkIfOver(relPos);
//filter if outside the element...
if (event.status() == KeyStatus.leave) {
changeStatusIn(GuiShapeMode.NORMAL);
this.isDown = false;
return true;
}
if (event.inputId() == 0) {
if (!this.isDown) {
if (KeyStatus.leave == event.status()) {
changeStatusIn(GuiShapeMode.NORMAL);
} else {
Log.verbose("Detect Over : " + this.overPositionStart + " -> " + this.overPositionStop);
if (over) {
changeStatusIn(GuiShapeMode.OVER);
} else {
changeStatusIn(GuiShapeMode.NORMAL);
}
}
return true;
}
}
if (event.inputId() != 1) {
return false;
}
if (KeyStatus.pressSingle == event.status() && over) {
keepFocus();
this.signalClick.emit();
this.propertyValue = !this.propertyValue;
return true;
}
if (KeyStatus.down == event.status() && over) {
keepFocus();
this.isDown = true;
changeStatusIn(GuiShapeMode.SELECT);
markToRedraw();
this.signalDown.emit();
return true;
}
if (KeyStatus.move == event.status() && over) {
keepFocus();
markToRedraw();
return true;
}
if (KeyStatus.up == event.status() && this.isDown) {
keepFocus();
this.isDown = false;
this.signalUp.emit();
changeStatusIn(GuiShapeMode.OVER);
markToRedraw();
return true;
}
return false;
}
@Override
public void onRegenerateDisplay() {
if (!needRedraw()) {
//return;
}
//Log.verbose("Regenerate Display ==> is needed: '" + this.propertyValue + "'");
this.shape.clear();
//this.gc.clear();
if (this.colorIdTextFg >= 0) {
//this.text.setDefaultColorFg(this.shape.getColor(this.colorIdTextFg));
//this.text.setDefaultColorBg(this.shape.getColor(this.colorIdTextBg));
//this.text.setCursorColor(this.shape.getColor(this.colorIdCursor));
//this.text.setSelectionColor(this.shape.getColor(this.colorIdSelection));
}
final Padding padding = this.shape.getPadding();
Vector3f tmpSizeShaper = this.minSize;
Vector3f delta = this.propertyGravity.gravityGenerateDelta(this.size.less(this.minSize));
if (this.propertyFill.x()) {
tmpSizeShaper = tmpSizeShaper.withX(this.size.x());
delta = delta.withX(0.0f);
}
if (this.propertyFill.y()) {
tmpSizeShaper = tmpSizeShaper.withY(this.size.y());
delta = delta.withY(0.0f);
}
Vector3f tmpOriginShaper = delta;
Vector3f tmpSizeInside = tmpSizeShaper.less(padding.x(), padding.y(), padding.z());
//Vector3f tmpOriginText = this.size.less(tmpSizeText).multiply(0.5f);
Vector3f tmpOriginInside = Vector3f.ZERO;//this.gc.getTextSize());
// sometimes, the user define an height bigger than the real size needed == > in this case we need to center the text in the shaper ...
/*
int minHeight = this.gc.getTextHeight();
if (tmpSizeText.y() > minHeight) {
tmpOriginText = tmpOriginText.add(0, (tmpSizeText.y() - minHeight) * 0.5f);
}
*/
// fix all the position in the int class:
tmpSizeShaper = Vector3f.clipInt(tmpSizeShaper);
tmpOriginShaper = Vector3f.clipInt(tmpOriginShaper);
tmpSizeInside = Vector3f.clipInt(tmpSizeInside);
tmpOriginInside = Vector3f.clipInt(tmpOriginInside);
//this.gc.clear();
//this.gc.setSize((int)tmpSizeText.x(), (int)tmpSizeText.y());
//this.gc.setColorFill(Color.BLACK);
//this.gc.setColorStroke(Color.NONE);
//this.gc.setStrokeWidth(1);
//this.gc.text(tmpOriginText, this.propertyValue);
this.overPositionStart = tmpOriginShaper;
this.overPositionStop = tmpOriginShaper.add(tmpSizeShaper);
this.shape.setShape(tmpOriginShaper, tmpSizeShaper, tmpOriginInside, tmpSizeInside);
//this.gc.flush();
this.shape.flush();
}
/**
* internal check the value with RegExp checking
* @param newData The new string to display
*/
protected void setInternalValue(final Boolean newData) {
this.propertyValue = newData;
markToRedraw();
}
public void setPropertyConfig(final Uri propertyConfig) {
if (this.propertyConfig.equals(propertyConfig)) {
return;
}
this.propertyConfig = propertyConfig;
onChangePropertyShaper();
}
public void setPropertyValue(final Boolean propertyValue) {
if (this.propertyValue.equals(propertyValue)) {
return;
}
this.propertyValue = propertyValue;
onChangePropertyValue();
}
}

View File

@ -11,17 +11,18 @@ public class WidgetXmlFactory implements InterfaceXmlFactoryAccess {
listWidgetAvaillable.put("Button", Button.class);
listWidgetAvaillable.put("Sizer", Sizer.class);
listWidgetAvaillable.put("Label", LabelOnSVG.class);
listWidgetAvaillable.put("CheckBox", CheckBox.class);
//listWidgetAvaillable.put("CheckBox", CheckBox.class);
listWidgetAvaillable.put("Tick", Tick.class);
listWidgetAvaillable.put("Image", ImageDisplay.class);
}
@Override
public Class<?> findClass(String name) {
public Class<?> findClass(final String name) {
return listWidgetAvaillable.get(name);
}
@Override
public String generateName(Object widget) {
public String generateName(final Object widget) {
return null;
}