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}