diff --git a/old_widget/CheckBox.java b/old_widget/CheckBox.java deleted file mode 100644 index 2214ce3..0000000 --- a/old_widget/CheckBox.java +++ /dev/null @@ -1,85 +0,0 @@ -/** @file - * @author Edouard DUPIN - * @copyright 2011, Edouard DUPIN, all right reserved - * @license MPL v2.0 (see license file) - */ -#pragma once - -#include -#include -#include -#include -#include -#include - - -namespace ewol { - namespace widget { - class CheckBox; - using CheckBox = ememory::Ptr; - using CheckBoxWeak = ememory::WeakPtr; - class CheckBox : public ewol::widget::Container2 { - public: // Event list - esignal::Signal<> signalPressed; - esignal::Signal<> signalDown; - esignal::Signal<> signalUp; - esignal::Signal<> signalEnter; - esignal::Signal signalValue; - public: // propertie list - eproperty::Value propertyValue; //!< Current state of the checkbox. - eproperty::Value propertyShape; //!< shape of the widget - private: - ewol::compositing::Shaper this.shaper; //!< Compositing theme. - boolean this.mouseHover; //!< Flag to know where the mouse is (inside the displayed widget (if not fill)). - boolean this.buttonPressed; //!< Flag to know if the button is curently pressed. - // hover area : - Vector2f this.selectableAreaPos; //!< Start position of the events - Vector2f this.selectableAreaSize; //!< size of the event positions - // shaper ids: - int this.shaperIdSize; - int this.shaperIdSizeInsize; - protected: - /** - * Main checkbox ructor - * @param _shaperName Shaper file properties - */ - CheckBox(); - void init() ; - public: - DECLARE_WIDGET_FACTORY(CheckBox, "CheckBox"); - /** - * main destructor. - */ - ~CheckBox(); - protected: - /** - * internal system to change the property of the current status - * @param _newStatusId new state - */ - void changeStatusIn(int _newStatusId); - /** - * update the status with the internal satte of the button ... - */ - void CheckStatus(); - protected: - void onDraw() ; - public: - void calculateMinMaxSize() ; - void onChangeSize() ; - void onRegenerateDisplay() ; - boolean onEventInput( ewol::event::Input _event) ; - boolean onEventEntry( ewol::event::Entry _event) ; - protected: - esignal::Connection this.PCH; //!< Periodic call handle to remove it when needed - /** - * Periodic call to update grapgic display - * @param _event Time generic event - */ - void periodicCall( ewol::event::Time _event); - protected: - void onChangePropertyShape(); - void onChangePropertyValue(); - }; - }; -}; - diff --git a/samples/resources/test-ewol/data/mireB.png b/samples/resources/test-ewol/data/mireB.png new file mode 100644 index 0000000..a935478 Binary files /dev/null and b/samples/resources/test-ewol/data/mireB.png differ diff --git a/samples/resources/test-ewol/data/mireC.png b/samples/resources/test-ewol/data/mireC.png new file mode 100644 index 0000000..1d721d3 Binary files /dev/null and b/samples/resources/test-ewol/data/mireC.png differ diff --git a/samples/src/sample/atriasoft/ewol/simpleWindowsWithImage/MainWindows.java b/samples/src/sample/atriasoft/ewol/simpleWindowsWithImage/MainWindows.java index 7c8f13a..59a0eda 100644 --- a/samples/src/sample/atriasoft/ewol/simpleWindowsWithImage/MainWindows.java +++ b/samples/src/sample/atriasoft/ewol/simpleWindowsWithImage/MainWindows.java @@ -1,24 +1,221 @@ package sample.atriasoft.ewol.simpleWindowsWithImage; +import org.atriasoft.etk.Color; +import org.atriasoft.etk.Dimension; +import org.atriasoft.etk.Distance; import org.atriasoft.etk.Uri; import org.atriasoft.etk.math.Vector2b; +import org.atriasoft.etk.math.Vector2f; +import org.atriasoft.ewol.Gravity; +import org.atriasoft.ewol.widget.Button; import org.atriasoft.ewol.widget.ImageDisplay; +import org.atriasoft.ewol.widget.Sizer; +import org.atriasoft.ewol.widget.Sizer.DisplayMode; +import org.atriasoft.ewol.widget.Spacer; import org.atriasoft.ewol.widget.Windows; public class MainWindows extends Windows { - + ImageDisplay testWidget; + Button buttonExpandX; + Button buttonExpandY; + Button buttonFillX; + Button buttonFillY; + Button buttonGravity; + Button buttonAspectRatio; public MainWindows() { //! [ewol_sample_HW_windows_title] - setPropertyTitle("Simple label"); - //EwolObject.getContext().getFontDefault().setName("FreeSans"); - //! [ewol_sample_HW_windows_label] - //! [ewol_sample_HW_windows_title] - ImageDisplay testWidget = new ImageDisplay(); - testWidget.setPropertySource(new Uri("DATA", "mireA.png")); - testWidget.setPropertyExpand(new Vector2b(true, true)); - testWidget.setPropertyFill(new Vector2b(true, true)); - setSubWidget(testWidget); - //! [ewol_sample_HW_windows_label] + setPropertyTitle("Simple Image"); + + Sizer sizerMain = new Sizer(DisplayMode.modeVert); + sizerMain.setPropertyExpand(new Vector2b(true, true)); + sizerMain.setPropertyFill(new Vector2b(true, true)); + setSubWidget(sizerMain); + + Sizer sizerHori1 = new Sizer(DisplayMode.modeHori); + sizerHori1.setPropertyExpand(new Vector2b(true, false)); + sizerHori1.setPropertyLockExpand(new Vector2b(true, true)); + sizerHori1.setPropertyFill(new Vector2b(true, true)); + sizerMain.subWidgetAdd(sizerHori1); + + { + Spacer simpleSpacer = new Spacer(); + simpleSpacer.setPropertyMinSize(new Dimension(new Vector2f(100, 100), Distance.PIXEL)); + simpleSpacer.setPropertyColor(Color.ALICE_BLUE); + simpleSpacer.setPropertyExpand(new Vector2b(true, false)); + simpleSpacer.setPropertyFill(new Vector2b(true, true)); + simpleSpacer.setPropertyMinSize(new Dimension(new Vector2f(10, 10), Distance.PIXEL)); + sizerMain.subWidgetAdd(simpleSpacer); + } + + Sizer sizerHori2 = new Sizer(DisplayMode.modeHori); + sizerHori2.setPropertyExpand(new Vector2b(true, true)); + sizerHori2.setPropertyFill(new Vector2b(true, true)); + sizerMain.subWidgetAdd(sizerHori2); + + { + Spacer simpleSpacer = new Spacer(); + simpleSpacer.setPropertyColor(Color.DARK_GREEN); + simpleSpacer.setPropertyExpand(new Vector2b(true, false)); + simpleSpacer.setPropertyFill(new Vector2b(true, true)); + simpleSpacer.setPropertyMinSize(new Dimension(new Vector2f(10, 10), Distance.PIXEL)); + sizerMain.subWidgetAdd(simpleSpacer); + } + { + Spacer simpleSpacer = new Spacer(); + simpleSpacer.setPropertyColor(Color.CHOCOLATE); + simpleSpacer.setPropertyExpand(new Vector2b(false, true)); + simpleSpacer.setPropertyFill(new Vector2b(true, true)); + simpleSpacer.setPropertyMinSize(new Dimension(new Vector2f(10, 10), Distance.PIXEL)); + sizerHori2.subWidgetAdd(simpleSpacer); + } + this.testWidget = new ImageDisplay(); + this.testWidget.setPropertySource(new Uri("DATA", "mireA.png")); + this.testWidget.setPropertyExpand(new Vector2b(true, true)); + this.testWidget.setPropertyFill(new Vector2b(true, true)); + sizerHori2.subWidgetAdd(this.testWidget); + { + Spacer simpleSpacer = new Spacer(); + simpleSpacer.setPropertyColor(Color.GREEN_YELLOW); + simpleSpacer.setPropertyExpand(new Vector2b(false, true)); + simpleSpacer.setPropertyFill(new Vector2b(true, true)); + simpleSpacer.setPropertyMinSize(new Dimension(new Vector2f(10, 10), Distance.PIXEL)); + sizerHori2.subWidgetAdd(simpleSpacer); + } + + { + Spacer simpleSpacer = new Spacer(); + simpleSpacer.setPropertyColor(Color.PINK); + simpleSpacer.setPropertyExpand(new Vector2b(true, true)); + simpleSpacer.setPropertyFill(new Vector2b(true, true)); + simpleSpacer.setPropertyMinSize(new Dimension(new Vector2f(30, 30), Distance.PIXEL)); + sizerHori1.subWidgetAdd(simpleSpacer); + } + { + this.buttonExpandX = new Button(); + this.buttonExpandX.setPropertyValue("un-expand X"); + this.buttonExpandX.setPropertyExpand(new Vector2b(false, false)); + this.buttonExpandX.setPropertyFill(new Vector2b(false, false)); + this.buttonExpandX.setPropertyMinSize(new Dimension(new Vector2f(10, 10), Distance.PIXEL)); + sizerHori1.subWidgetAdd(this.buttonExpandX); + this.buttonExpandX.signalClick.connectAuto(this, MainWindows::eventButtonExpandX); + } + { + this.buttonExpandY = new Button(); + this.buttonExpandY.setPropertyValue("un-expand Y"); + this.buttonExpandY.setPropertyExpand(new Vector2b(false, false)); + this.buttonExpandY.setPropertyFill(new Vector2b(false, false)); + this.buttonExpandY.setPropertyMinSize(new Dimension(new Vector2f(10, 10), Distance.PIXEL)); + sizerHori1.subWidgetAdd(this.buttonExpandY); + this.buttonExpandY.signalClick.connectAuto(this, MainWindows::eventButtonExpandY); + } + { + this.buttonFillX = new Button(); + this.buttonFillX.setPropertyValue("un-fill X"); + this.buttonFillX.setPropertyExpand(new Vector2b(false, false)); + this.buttonFillX.setPropertyFill(new Vector2b(false, false)); + this.buttonFillX.setPropertyMinSize(new Dimension(new Vector2f(10, 10), Distance.PIXEL)); + sizerHori1.subWidgetAdd(this.buttonFillX); + this.buttonFillX.signalClick.connectAuto(this, MainWindows::eventButtonFillX); + } + { + this.buttonFillY = new Button(); + this.buttonFillY.setPropertyValue("un-fill Y"); + this.buttonFillY.setPropertyExpand(new Vector2b(false, false)); + this.buttonFillY.setPropertyFill(new Vector2b(false, false)); + this.buttonFillY.setPropertyMinSize(new Dimension(new Vector2f(10, 10), Distance.PIXEL)); + sizerHori1.subWidgetAdd(this.buttonFillY); + this.buttonFillY.signalClick.connectAuto(this, MainWindows::eventButtonFillY); + } + { + Button button = new Button(); + button.setPropertyValue("Change image"); + button.setPropertyExpand(new Vector2b(false, false)); + button.setPropertyFill(new Vector2b(false, false)); + button.setPropertyMinSize(new Dimension(new Vector2f(10, 10), Distance.PIXEL)); + sizerHori1.subWidgetAdd(button); + button.signalClick.connectAuto(this, MainWindows::eventButtonChangeImage); + } + { + this.buttonGravity = new Button(); + this.buttonGravity.setPropertyValue("gravity"); + this.buttonGravity.setPropertyExpand(new Vector2b(false, false)); + this.buttonGravity.setPropertyFill(new Vector2b(false, false)); + this.buttonGravity.setPropertyMinSize(new Dimension(new Vector2f(10, 10), Distance.PIXEL)); + sizerHori1.subWidgetAdd(this.buttonGravity); + this.buttonGravity.signalClick.connectAuto(this, MainWindows::eventButtonChangeGravity); + } + { + this.buttonAspectRatio = new Button(); + this.buttonAspectRatio.setPropertyValue("keep aspect ratio"); + this.buttonAspectRatio.setPropertyExpand(new Vector2b(false, false)); + this.buttonAspectRatio.setPropertyFill(new Vector2b(false, false)); + this.buttonAspectRatio.setPropertyMinSize(new Dimension(new Vector2f(10, 10), Distance.PIXEL)); + sizerHori1.subWidgetAdd(this.buttonAspectRatio); + this.buttonAspectRatio.signalClick.connectAuto(this, MainWindows::eventButtonChangeKeepRatio); + } + } + public static void eventButtonExpandX(final MainWindows self) { + Vector2b state = self.testWidget.getPropertyExpand(); + self.testWidget.setPropertyExpand(state.withX(!state.x())); + self.buttonExpandX.setPropertyValue(state.x()?"expand X":"un-expand X"); + } + public static void eventButtonExpandY(final MainWindows self) { + Vector2b state = self.testWidget.getPropertyExpand(); + self.testWidget.setPropertyExpand(state.withY(!state.y())); + self.buttonExpandY.setPropertyValue(state.y()?"expand Y":"un-expand Y"); + } + public static void eventButtonFillX(final MainWindows self) { + Vector2b state = self.testWidget.getPropertyFill(); + self.testWidget.setPropertyFill(state.withX(!state.x())); + self.buttonFillX.setPropertyValue(state.x()?"fill X":"un-fill X"); + } + public static void eventButtonFillY(final MainWindows self) { + Vector2b state = self.testWidget.getPropertyFill(); + self.testWidget.setPropertyFill(state.withY(!state.y())); + self.buttonFillY.setPropertyValue(state.y()?"fill Y":"un-fill Y"); + } + public static void eventButtonChangeKeepRatio(final MainWindows self) { + boolean state = self.testWidget.isPropertyKeepRatio(); + self.testWidget.setPropertyKeepRatio(!state); + self.buttonAspectRatio.setPropertyValue(state?"fkeep aspect ratio":"un-keep aspect ratio"); + } + public static void eventButtonChangeGravity(final MainWindows self) { + Gravity state = self.testWidget.getPropertyGravity(); + switch(state) { + case BUTTOM: + state = Gravity.BUTTOM_LEFT; + break; + case BUTTOM_LEFT: + state = Gravity.BUTTOM_RIGHT; + break; + case BUTTOM_RIGHT: + state = Gravity.CENTER; + break; + case CENTER: + state = Gravity.LEFT; + break; + case LEFT: + state = Gravity.RIGHT; + break; + case RIGHT: + state = Gravity.TOP; + break; + case TOP: + state = Gravity.TOP_LEFT; + break; + case TOP_LEFT: + state = Gravity.TOP_RIGHT; + break; + case TOP_RIGHT: + state = Gravity.BUTTOM; + break; + } + self.testWidget.setPropertyGravity(state); + self.buttonGravity.setPropertyValue("gravity: " + state); + } + public static void eventButtonChangeImage(final MainWindows self) { + self.testWidget.setPropertySource(new Uri("DATA", "mireC.png")); + } } diff --git a/src/org/atriasoft/ewol/Gravity.java b/src/org/atriasoft/ewol/Gravity.java index d20190b..009726b 100644 --- a/src/org/atriasoft/ewol/Gravity.java +++ b/src/org/atriasoft/ewol/Gravity.java @@ -11,32 +11,32 @@ import org.atriasoft.etk.math.Vector2f; * Gravity of the widget property */ public enum Gravity { - buttom, // !< gravity is in center - buttomLeft, // !< gravity is in top - buttomRight, // !< gravity is in buttom - center, // !< gravity is in right - left, // !< gravity is in left - right, // !< gravity is in top-right - top, // !< gravity is in top-left - topLeft, // !< gravity is in buttom-right - topRight; // !< gravity is in buttom-left + BUTTOM, // !< gravity is in center + BUTTOM_LEFT, // !< gravity is in top + BUTTOM_RIGHT, // !< gravity is in buttom + CENTER, // !< gravity is in right + LEFT, // !< gravity is in left + RIGHT, // !< gravity is in top-right + TOP, // !< gravity is in top-left + TOP_LEFT, // !< gravity is in buttom-right + TOP_RIGHT; // !< gravity is in buttom-left public static Vector2f gravityGenerateDelta(final Gravity gravity, final Vector2f deltas) { float outX = 0; float outY = 0; if (deltas.x() > 0.0001f) { - if (gravity == left || gravity == buttomLeft || gravity == topLeft) { + if (gravity == LEFT || gravity == BUTTOM_LEFT || gravity == TOP_LEFT) { // nothing to do - } else if (gravity == right || gravity == buttomRight || gravity == topRight) { + } else if (gravity == RIGHT || gravity == BUTTOM_RIGHT || gravity == TOP_RIGHT) { outX = (int) (deltas.x()); } else { outX = (int) (deltas.x() * 0.5f); } } if (deltas.y() > 0.0001f) { - if (gravity == buttom || gravity == buttomLeft || gravity == buttomRight) { + if (gravity == BUTTOM || gravity == BUTTOM_LEFT || gravity == BUTTOM_RIGHT) { // nothing to do - } else if (gravity == top || gravity == topRight || gravity == topLeft) { + } else if (gravity == TOP || gravity == TOP_RIGHT || gravity == TOP_LEFT) { outY = (int) (deltas.y()); } else { outY = (int) (deltas.y() * 0.5f); @@ -46,3 +46,4 @@ public enum Gravity { } } + diff --git a/src/org/atriasoft/ewol/compositing/CompositingImage.java b/src/org/atriasoft/ewol/compositing/CompositingImage.java index ca9cfce..b337f17 100644 --- a/src/org/atriasoft/ewol/compositing/CompositingImage.java +++ b/src/org/atriasoft/ewol/compositing/CompositingImage.java @@ -8,7 +8,6 @@ package org.atriasoft.ewol.compositing; import org.atriasoft.egami.ImageByteRGBA; import org.atriasoft.etk.Color; 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; @@ -29,19 +28,12 @@ public class CompositingImage extends Compositing { public static final int VBO_ID_COORD = 0; public static final int VBO_ID_COORD_TEX = 1; private float angle = 0; //!< Angle to set at the axes - private boolean clippingEnable = true; //!< true if the clipping must be activated - private Vector3f clippingPosStart = Vector3f.ZERO; //!< Clipping start position - private Vector3f clippingPosStop = Vector3f.ZERO; //!< Clipping stop position private Color color = new Color(1, 1, 1); //!< The text foreground color private Uri filename; - private final int oGLColor = -1; //!< openGL id on the element (color buffer) protected int oGLMatrixProjection = -1; //!< openGL id on the element (Projection matrix) protected int oGLMatrixTransformation = -1; //!< openGL id on the element (transformation matrix) protected int oGLMatrixView = -1; //!< openGL id on the element (view matrix) - private int oGLPosition = -1; //!< openGL id on the element (vertex buffer) private ResourceProgram oGLprogram = null; //!< pointer on the opengl display program - private int oGLtexID = -1; //!< openGL id on the element (texture ID) - private final int oGLtexture = -1; //!< openGL id on the element (Texture position) private Vector3f position = Vector3f.ZERO; //!< The current position to draw private Vector2i requestSize = new Vector2i(2, 2); @@ -87,15 +79,12 @@ public class CompositingImage extends Compositing { this.vbo.clear(); // reset temporal variables : this.position = Vector3f.ZERO; - this.clippingPosStart = Vector3f.ZERO; - this.clippingPosStop = Vector3f.ZERO; - this.clippingEnable = false; this.color = Color.WHITE; this.angle = 0; } /** - * draw All the refistered text in the current element on openGL + * draw All the registered text in the current element on openGL * @param disableDepthTest disable the Depth test for display */ @Override @@ -185,13 +174,11 @@ public class CompositingImage extends Compositing { */ private void loadProgram() { // get the shader resource: - this.oGLPosition = 0; this.oGLprogram = ResourceProgram.create(new Uri("DATA", "textured3D.vert", "ewol"), new Uri("DATA", "textured3D.frag", "ewol")); 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.oGLtexID = this.oGLprogram.getUniform("in_texID"); } } @@ -336,42 +323,6 @@ public class CompositingImage extends Compositing { this.angle = angleRad; } - void setClipping(final Vector2f pos, final Vector2f posEnd) { - setClipping(new Vector3f(pos.x(), pos.y(), 0), new Vector3f(posEnd.x(), posEnd.y(), 0)); - } - - /** - * Request a clipping area for the text (next draw only) - * @param pos Start position of the clipping - * @param posEnd End position of the clipping - */ - public void setClipping(final Vector3f pos, final Vector3f posEnd) { - this.clippingPosStart = FMath.min(pos, posEnd); - this.clippingPosStop = FMath.max(pos, posEnd); - this.clippingEnable = true; - } - - /** - * enable/Disable the clipping (without lose the current clipping position) - * newMode The new status of the clipping - */ - public void setClippingMode(final boolean newMode) { - this.clippingEnable = newMode; - } - - public void setClippingWidth(final Vector2f pos, final Vector2f width) { - setClippingWidth(new Vector3f(pos.x(), pos.y(), 0), new Vector3f(width.x(), width.y(), 0)); - } - - /** - * Request a clipping area for the text (next draw only) - * @param pos Start position of the clipping - * @param width Width size of the clipping - */ - public void setClippingWidth(final Vector3f pos, final Vector3f width) { - setClipping(pos, pos.add(width)); - } - /** * set the Color of the current foreground font * @param color Color to set on foreground (for next print) diff --git a/src/org/atriasoft/ewol/widget/Button.java b/src/org/atriasoft/ewol/widget/Button.java index d98cf5e..ef94b62 100644 --- a/src/org/atriasoft/ewol/widget/Button.java +++ b/src/org/atriasoft/ewol/widget/Button.java @@ -38,16 +38,8 @@ public class Button extends Widget { private final CompositingGraphicContext gc = new CompositingGraphicContext(); /// Periodic call handle to remove it when needed protected Connection periodicConnectionHanble = new Connection(); - @XmlManaged - @XmlAttribute - @XmlName(value = "config") - @EwolDescription(value = "configuration of the widget") private Uri propertyConfig = new Uri("THEME", "shape/Button.json", "ewol"); - @XmlManaged - @XmlAttribute - @XmlName(value = "value") - @EwolDescription(value = "Value display in the entry (decorated text)") private String propertyValue = "Test Text..."; //!< string that must be displayed private GuiShape shape; @@ -102,11 +94,19 @@ public class Button extends Widget { markToRedraw(); } } - + + @XmlManaged + @XmlAttribute + @XmlName(value = "config") + @EwolDescription(value = "configuration of the widget") public Uri getPropertyConfig() { return this.propertyConfig; } - + + @XmlManaged + @XmlAttribute + @XmlName(value = "value") + @EwolDescription(value = "Value display in the entry (decorated text)") public String getPropertyValue() { return this.propertyValue; } diff --git a/src/org/atriasoft/ewol/widget/CheckBox.java b/src/org/atriasoft/ewol/widget/CheckBox.java new file mode 100644 index 0000000..047c28a --- /dev/null +++ b/src/org/atriasoft/ewol/widget/CheckBox.java @@ -0,0 +1,308 @@ +package org.atriasoft.ewol.widget; + +import org.atriasoft.esignal.Connection; +import org.atriasoft.esignal.Signal; +import org.atriasoft.esignal.SignalEmpty; +import org.atriasoft.etk.Color; +import org.atriasoft.etk.Uri; +import org.atriasoft.etk.math.Vector2f; +import org.atriasoft.etk.math.Vector2i; +import org.atriasoft.ewol.Padding; +import org.atriasoft.ewol.annotation.EwolDescription; +import org.atriasoft.ewol.annotation.EwolSignal; +import org.atriasoft.ewol.compositing.CompositingGraphicContext; +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 signalValue; + public boolean propertyValue; //!< Current state of the checkbox. +public Uri> propertyShape; //!< shape of the widget +*/ +public class CheckBox extends Widget { + /// 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 String propertyValue = "Test Text..."; //!< 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 signalValue; + + // element over: + Vector2f overPositionStart = Vector2f.ZERO; + Vector2f overPositionStop = Vector2f.ZERO; + private boolean isDown; + + /** + * Constuctor + */ + public Button() { + this.propertyCanFocus = true; + onChangePropertyShaper(); + markToRedraw(); + 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(); + } + Vector2i minHeight = this.gc.calculateTextSize(this.propertyValue); + + Vector2f minimumSizeBase = new Vector2f(minHeight.x(), minHeight.y()); + // add padding : + minimumSizeBase = minimumSizeBase.add(padding.x(), padding.y()); + this.minSize = Vector2f.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 operiodic call"); + this.periodicConnectionHanble = EwolObject.getObjectManager().periodicCall.connect(this, Button::periodicCall); + } + markToRedraw(); + } + } + + @XmlManaged + @XmlAttribute + @XmlName(value = "config") + @EwolDescription(value = "configuration of the widget") + public Uri getPropertyConfig() { + return this.propertyConfig; + } + + @XmlManaged + @XmlAttribute + @XmlName(value = "value") + @EwolDescription(value = "Value display in the entry (decorated text)") + public String 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() { + String newData = this.propertyValue; + markToRedraw(); + } + + @Override + protected void onDraw() { + if (this.shape != null) { + this.shape.draw(this.gc.getResourceTexture(), true); + } + } + + @Override + public boolean onEventInput(final EventInput event) { + Vector2f relPos = relativePosition(event.pos()); + Log.verbose("Event on Input ... " + event + " relPos = "+ relPos); + 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 (relPos.x() > this.overPositionStart.x() && relPos.y() > this.overPositionStart.y() && relPos.x() < this.overPositionStop.x() && relPos.y() < this.overPositionStop.y()) { + changeStatusIn(GuiShapeMode.OVER); + } else { + changeStatusIn(GuiShapeMode.NORMAL); + } + } + } + } + if (event.inputId() == 1) { + if (KeyStatus.pressSingle == event.status()) { + keepFocus(); + this.signalClick.emit(); + //nothing to do ... + return true; + } + if (KeyStatus.down == event.status()) { + keepFocus(); + this.isDown = true; + changeStatusIn(GuiShapeMode.SELECT); + markToRedraw(); + this.signalDown.emit(); + } else if (KeyStatus.move == event.status()) { + keepFocus(); + markToRedraw(); + } else if (KeyStatus.up == event.status()) { + keepFocus(); + this.isDown = false; + this.signalUp.emit(); + changeStatusIn(GuiShapeMode.OVER); + markToRedraw(); + } + } + 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(); + + Vector2f tmpSizeShaper = this.minSize; + if (this.propertyFill.x()) { + tmpSizeShaper = tmpSizeShaper.withX(this.size.x()); + } + if (this.propertyFill.y()) { + tmpSizeShaper = tmpSizeShaper.withY(this.size.y()); + } + + Vector2f tmpOriginShaper = this.size.less(tmpSizeShaper).multiply(0.5f); + Vector2f tmpSizeText = tmpSizeShaper.less(padding.x(), padding.y()); + //Vector2f tmpOriginText = this.size.less(tmpSizeText).multiply(0.5f); + Vector2f tmpOriginText = new Vector2f(0, 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 = Vector2f.clipInt(tmpSizeShaper); + tmpOriginShaper = Vector2f.clipInt(tmpOriginShaper); + tmpSizeText = Vector2f.clipInt(tmpSizeText); + tmpOriginText = Vector2f.clipInt(tmpOriginText); + + 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, tmpOriginText, tmpSizeText); + this.gc.flush(); + this.shape.flush(); + + } + + /** + * Periodic call to update grapgic display + * @param _event Time generic event + */ + protected static void periodicCall(final Button self, final EventTime event) { + Log.verbose("Periodic call on Entry(" + event + ")"); + if (!self.shape.periodicCall(event)) { + self.periodicConnectionHanble.close(); + } + self.markToRedraw(); + } + + /** + * internal check the value with RegExp checking + * @param newData The new string to display + */ + protected void setInternalValue(final String newData) { + String previous = this.propertyValue; + // check the RegExp : + if (newData.length() > 0) { + /* + if (this.regex.parse(_newData, 0, _newData.size()) == false) { + Log.info("The input data does not match with the regExp '" + _newData + "' Regex='" + propertyRegex + "'" ); + return; + } + if (this.regex.start() != 0) { + Log.info("The input data does not match with the regExp '" + _newData + "' Regex='" + propertyRegex + "' (start position error)" ); + return; + } + if (this.regex.stop() != _newData.size()) { + Log.info("The input data does not match with the regExp '" + _newData + "' Regex='" + propertyRegex + "' (stop position error)" ); + return; + } + */ + } + this.propertyValue = newData; + markToRedraw(); + } + + public void setPropertyConfig(final Uri propertyConfig) { + if (this.propertyConfig.equals(propertyConfig)) { + return; + } + this.propertyConfig = propertyConfig; + onChangePropertyShaper(); + } + + + public void setPropertyValue(final String propertyValue) { + if (this.propertyValue.equals(propertyValue)) { + return; + } + this.propertyValue = propertyValue; + onChangePropertyValue(); + } + +} diff --git a/src/org/atriasoft/ewol/widget/Widget.java b/src/org/atriasoft/ewol/widget/Widget.java index 9dc0c7a..83646ec 100644 --- a/src/org/atriasoft/ewol/widget/Widget.java +++ b/src/org/atriasoft/ewol/widget/Widget.java @@ -88,46 +88,12 @@ public class Widget extends EwolObject { protected Vector2f origin = new Vector2f(0, 0); //!< internal ... I do not really known how if can use it ... - @XmlManaged - @XmlAttribute - @XmlName(value = "focus") - @EwolDescription(value = "enable the widget to have the focus capacity") protected boolean propertyCanFocus = false; //!< the focus can be done on this widget - - @XmlManaged - @XmlAttribute - @XmlName(value = "expand") - @EwolDescription(value = "Request the widget Expand size while space is available") protected Vector2b propertyExpand = new Vector2b(false, false); //!< the widget will expand if possible - - @XmlManaged - @XmlAttribute - @XmlName(value = "fill") - @EwolDescription(value = "Fill the widget available size") protected Vector2b propertyFill = new Vector2b(true, true); //!< the widget will fill all the space provided by the parent. - - @XmlManaged - @XmlAttribute - @XmlName(value = "gravity") - @EwolDescription(value = "Gravity orientation") - protected Gravity propertyGravity = Gravity.buttomLeft; //!< Gravity of the widget - - @XmlManaged - @XmlAttribute - @XmlName(value = "hide") - @EwolDescription(value = "The widget start hided") + protected Gravity propertyGravity = Gravity.BUTTOM_LEFT; //!< Gravity of the widget protected boolean propertyHide = false; //!< hide a widget on the display - - @XmlManaged - @XmlAttribute - @XmlName(value = "max-size") - @EwolDescription(value = "User maximum size") protected Dimension propertyMaxSize = new Dimension(new Vector2f(999999, 999999), Distance.PIXEL); //!< user define the maximum size of the widget - - @XmlManaged - @XmlAttribute - @XmlName(value = "min-size") - @EwolDescription(value = "User minimum size") protected Dimension propertyMinSize = new Dimension(new Vector2f(0, 0), Distance.PIXEL); //!< user define the minimum size of the widget // ---------------------------------------------------------------------------------------------------------------- @@ -301,30 +267,58 @@ public class Widget extends EwolObject { return this.origin; } + @XmlManaged + @XmlAttribute + @XmlName(value = "focus") + @EwolDescription(value = "enable the widget to have the focus capacity") public boolean getPropertyCanFocus() { return this.propertyCanFocus; } + @XmlManaged + @XmlAttribute + @XmlName(value = "expand") + @EwolDescription(value = "Request the widget Expand size while space is available") public Vector2b getPropertyExpand() { return this.propertyExpand; } + @XmlManaged + @XmlAttribute + @XmlName(value = "fill") + @EwolDescription(value = "Fill the widget available size") public Vector2b getPropertyFill() { return this.propertyFill; } + @XmlManaged + @XmlAttribute + @XmlName(value = "gravity") + @EwolDescription(value = "Gravity orientation") public Gravity getPropertyGravity() { return this.propertyGravity; } + @XmlManaged + @XmlAttribute + @XmlName(value = "hide") + @EwolDescription(value = "The widget start hided") public boolean getPropertyHide() { return this.propertyHide; } + @XmlManaged + @XmlAttribute + @XmlName(value = "max-size") + @EwolDescription(value = "User maximum size") public Dimension getPropertyMaxSize() { return this.propertyMaxSize; } + @XmlManaged + @XmlAttribute + @XmlName(value = "min-size") + @EwolDescription(value = "User minimum size") public Dimension getPropertyMinSize() { return this.propertyMinSize; }