    001package org.vishia.gral.base;
    002
    003import java.io.IOException;
    004
    005import org.eclipse.swt.graphics.Point;
    006import org.vishia.gral.ifc.GralColor;
    007import org.vishia.gral.ifc.GralFont;
    008import org.vishia.gral.ifc.GralMng_ifc;
    009import org.vishia.gral.ifc.GralTextBox_ifc;
    010import org.vishia.gral.ifc.GralTextFieldUser_ifc;
    011import org.vishia.util.KeyCode;
    012
    013public class GralTextBox extends GralTextField implements Appendable, GralTextBox_ifc
    014{
    015
    016  /**Version and history
    017   * <ul>
    018   * <li>2014-08-16 Hartmut chg: GrapTextBox not abstract, using GraphicImplAccess like new concept of all GralWidgets.
    019   * <li>2012-01-06 Hartmut chg: The {@link #append(CharSequence)} etc. methods are implemented
    020   *   in this super class instead in the graphic layer implementation classes. Therefore
    021   *   the methods {@link #appendTextInGThread(CharSequence)} and {@link #setTextInGThread(CharSequence)}
    022   *   are defined here to implement in the graphic layer. The set- and apppend methods are <b>threadsafe</b> now.
    023   * </ul>
    024   *
    025   * <b>Copyright/Copyleft</b>:
    026   * For this source the LGPL Lesser General Public License,
    027   * published by the Free Software Foundation is valid.
    028   * It means:
    029   * <ol>
    030   * <li> You can use this source without any restriction for any desired purpose.
    031   * <li> You can redistribute copies of this source to everybody.
    032   * <li> Every user of this source, also the user of redistribute copies
    033   *    with or without payment, must accept this license for further using.
    034   * <li> But the LPGL is not appropriate for a whole software product,
    035   *    if this source is only a part of them. It means, the user
    036   *    must publish this part of source,
    037   *    but don't need to publish the whole source of the own product.
    038   * <li> You can study and modify (improve) this source
    039   *    for own using or for redistribution, but you have to license the
    040   *    modified sources likewise under this LGPL Lesser General Public License.
    041   *    You mustn't delete this Copyright/Copyleft inscription in this source file.
    042   * </ol>
    043   * If you are indent to use this sources without publishing its usage, you can get
    044   * a second license subscribing a special contract with the author.
    045   *
    046   * @author Hartmut Schorrig = hartmut.schorrig@vishia.de
    047   *
    048   *
    049   */
    050  @SuppressWarnings("hiding")
    051  public final static String sVersion = "2014-08-16";
    052
    053  /**Buffer for new text which is set or appended in another thread than the graphic thread.
    054   * This buffer is empty if the graphic thread has processed the {@link GralGraphicTimeOrder}
    055   * after calling {@link #append(CharSequence)} or {@link #setText(CharSequence)}.
    056   * It is filled only temporary.
    057   */
    058  private StringBuffer newText = new StringBuffer();
    059
    060  public GralTextBox(String name, Type... property)
    061  { super(name, property);
    062  }
    063
    064  /**Sets the text to the widget, invoked only in the graphic thread.
    065   * This method have to be implemented in the Graphic implementation layer.
    066   * @param text The text which should be shown in the widget.
    067   */
    068  //protected abstract void setTextInGThread(CharSequence text);
    069
    070  /**Appends the text to the current text in the widget, invoked only in the graphic thread.
    071   * This method have to be implemented in the Graphic implementation layer.
    072   * @param text The text which should be appended and shown in the widget.
    073   */
    074  //protected abstract void appendTextInGThread(CharSequence text);
    075
    076  /**Append the text, able to call threadsafe in any thread.
    077   * If the thread is the graphic thread, the text will be appended to the current text
    078   * of the widget immediately. But if the thread is any other one, the text will be stored
    079   * in a StringBuilder and the graphic thread will be waked up with the {@link #appendTextViewTrail}
    080   * dispatch listener.
    081   *
    082   * @see java.lang.Appendable#append(java.lang.CharSequence)
    083   */
    084  @Override public final Appendable append(CharSequence arg0) throws IOException
    085  { synchronized(newText) {
    086      newText.append(arg0);
    087      dyda.setChanged(GraphicImplAccess.chgAddText | GraphicImplAccess.chgViewTrail);
    088      repaint();
    089    }
    090    return this;
    091  }
    092
    093  /**Append a single char, able to call threadsafe in any thread.
    094   * @see #append(CharSequence)
    095   *
    096   * @see java.lang.Appendable#append(java.lang.CharSequence)
    097   */
    098  @Override public final Appendable append(char arg0) throws IOException
    099  { synchronized(newText) {
    100    newText.append(arg0);
    101    dyda.setChanged(GraphicImplAccess.chgAddText | GraphicImplAccess.chgViewTrail);
    102    repaint();
    103  }
    104  return this;
    105}
    106
    107  /**Append a sub char sequence, able to call threadsafe in any thread.
    108   * @see #append(CharSequence)
    109   *
    110   * @see java.lang.Appendable#append(java.lang.CharSequence, int, int)
    111   */
    112  @Override public final Appendable append(CharSequence arg0, int arg1, int arg2) throws IOException
    113  {
    114    append(arg0.subSequence(arg1, arg2));
    115    return this;
    116  }
    117
    118
    119
    120  @Override public void setTextStyle(GralColor color, GralFont font)
    121  {
    122    dyda.textFont = font;
    123    dyda.textColor = color;
    124    dyda.setChanged(GralWidget.ImplAccess.chgColorText);
    125    if(_wdgImpl !=null){
    126      repaint();
    127    }
    128  }
    129
    130
    131
    132  @Override public void setEditable(boolean editable){
    133    dyda.setChanged(editable ? GraphicImplAccess.chgEditable : GraphicImplAccess.chgNonEditable);
    134    if(_wdgImpl !=null){
    135      repaint();
    136    }
    137  }
    138
    139
    140
    141  @Override public int getNrofLines(){ return 0; }  //TODO
    142
    143
    144  @Override public void viewTrail()
    145  {
    146    dyda.setChanged(GraphicImplAccess.chgViewTrail);
    147    if(_wdgImpl !=null){
    148      repaint();
    149    }
    150
    151  }
    152
    153
    154
    155  public abstract class GraphicImplAccess extends GralTextField.GraphicImplAccess  //GralWidget.ImplAccess
    156  implements GralWidgImpl_ifc
    157  {
    158    public static final int chgCursor = 0x200, chgEditable = 0x400, chgNonEditable = 0x800
    159        , chgViewTrail = 0x1000, chgAddText = 0x2000;
    160
    161
    162    protected GraphicImplAccess(GralWidget widgg)
    163    {
    164      super(widgg);
    165    }
    166
    167    protected String getAndClearNewText(){ String ret; synchronized(newText){ ret = newText.toString(); newText.setLength(0); } return ret; }
    168
    169    protected int caretPos(){ return GralTextBox.this.caretPos; }
    170
    171    protected void caretPos(int newPos){ GralTextBox.this.caretPos = newPos; }
    172
    173    protected GralTextFieldUser_ifc user(){ return GralTextBox.this.user; }
    174
    175  }
    176
    177}