    001package org.vishia.gral.swt;
    002
    003import org.eclipse.swt.SWT;
    004import org.eclipse.swt.events.PaintEvent;
    005import org.eclipse.swt.events.PaintListener;
    006import org.eclipse.swt.events.TraverseEvent;
    007import org.eclipse.swt.events.TraverseListener;
    008import org.eclipse.swt.graphics.Color;
    009import org.eclipse.swt.graphics.Font;
    010import org.eclipse.swt.graphics.FontMetrics;
    011import org.eclipse.swt.graphics.GC;
    012import org.eclipse.swt.graphics.Rectangle;
    013import org.eclipse.swt.widgets.Canvas;
    014import org.eclipse.swt.widgets.Composite;
    015import org.eclipse.swt.widgets.Control;
    016import org.eclipse.swt.widgets.Widget;
    017import org.vishia.gral.base.GralButton;
    018import org.vishia.gral.base.GralKeyListener;
    019import org.vishia.gral.base.GralPos;
    020import org.vishia.gral.base.GralWidget;
    021import org.vishia.gral.ifc.GralColor;
    022import org.vishia.gral.ifc.GralRectangle;
    023import org.vishia.gral.ifc.GralWidget_ifc;
    024import org.vishia.util.KeyCode;
    025
    026public class SwtButton extends GralButton.GraphicImplAccess
    027{
    028  /**Version, history and license.
    029   * <ul>
    030   * <li>2013-12-22 Hartmut chg: Now {@link GralButton} uses the new concept of instantiation: It is not
    031   *   the super class of the implementation class. But it provides {@link GralButton.GraphicImplAccess}
    032   *   as the super class.
    033   * <li>2012-03-09 Hartmut new setFocus on press button
    034   * <li>2012-03-09 Hartmut new 3-state-Button.
    035   * <li>2012-03-09 Hartmut improved: appearance of the buttons.
    036   * <li>All other changes in 2010, 2011
    037   * </ul>
    038   *
    039   * <b>Copyright/Copyleft</b>:<br>
    040   * For this source the LGPL Lesser General Public License,
    041   * published by the Free Software Foundation is valid.
    042   * It means:
    043   * <ol>
    044   * <li> You can use this source without any restriction for any desired purpose.
    045   * <li> You can redistribute copies of this source to everybody.
    046   * <li> Every user of this source, also the user of redistribute copies
    047   *    with or without payment, must accept this license for further using.
    048   * <li> But the LPGL is not appropriate for a whole software product,
    049   *    if this source is only a part of them. It means, the user
    050   *    must publish this part of source,
    051   *    but doesn't need to publish the whole source of the own product.
    052   * <li> You can study and modify (improve) this source
    053   *    for own using or for redistribution, but you have to license the
    054   *    modified sources likewise under this LGPL Lesser General Public License.
    055   *    You mustn't delete this Copyright/Copyleft inscription in this source file.
    056   * </ol>
    057   * If you intent to use this source without publishing its usage, you can get
    058   * a second license subscribing a special contract with the author.
    059   *
    060   * @author Hartmut Schorrig = hartmut.schorrig@vishia.de
    061   */
    062  //@SuppressWarnings("hiding")
    063  public static final int version = 20130524;
    064
    065  /**It contains the association to the swt widget (Control) and the {@link SwtMng}
    066   * and implements some methods of {@link GralWidgImpl_ifc} which are delegate from this.
    067   */
    068  private final SwtWidgetHelper swtWidgHelper;
    069
    070  Canvas widgetSwt;
    071
    072  final Color black;
    073  final Color white;
    074
    075  final Font fontText;
    076
    077
    078  final SwtGralMouseListener.MouseListenerGralAction mouseListener;
    079
    080
    081
    082  //public SwtButton(String sName, SwtMng mng, Composite parent, int styleSwt, char size)
    083  SwtButton(GralButton widgg, SwtMng mng)
    084  {
    085    widgg.super(widgg, mng.mng);
    086    widgg.setActionMouse(mouseWidgetAction, 0);
    087    mouseListener = new SwtGralMouseListener.MouseListenerGralAction();
    088    //Control xx = mng.pos.panel.panelComposite;
    089    black = mng.propertiesGuiSwt.colorSwt(0x202020);
    090    white = mng.propertiesGuiSwt.colorSwt(0xffffff);
    091    Composite panelSwt = mng.getCurrentPanel();
    092    int styleSwt = 0;
    093    widgetSwt = new SwtButtonImpl(panelSwt, styleSwt);
    094    widgetSwt.setData(this);
    095    widgetSwt.setBackground(mng.propertiesGuiSwt.colorBackground);
    096    widgetSwt.addMouseListener(mouseListener);
    097    widgetSwt.addFocusListener(mng.focusListener);  //common focus listener
    098    widgetSwt.addKeyListener(new KeyListener(mng.mng._impl.gralKeyListener));
    099    widgetSwt.addTraverseListener(SwtMng.swtTraverseListener);
    100    setBoundsGraphic(widgg.pos(), mng);
    101    float ySize = widgg.pos().height();
    102    char size1 = ySize > 3? 'B' : 'A';
    103    switch(size1){
    104      case 'A': fontText = mng.propertiesGuiSwt.stdInputFont; break;
    105      case 'B': fontText = mng.propertiesGuiSwt.stdButtonFont; break;
    106      default: throw new IllegalArgumentException("param size must be A or B");
    107    }
    108    super.wdgimpl = swtWidgHelper = new SwtWidgetHelper(widgetSwt, mng);
    109  }
    110
    111
    112
    113  @Override public GralRectangle getPixelPositionSize(){ return swtWidgHelper.getPixelPositionSize(); }
    114
    115
    116  void setBoundsGraphic(GralPos pos, SwtMng mng)
    117  {
    118    //widgetSwt.setSize(mng.propertiesGui.xPixelUnit() * xSize -2, mng.propertiesGui.yPixelUnit() * ySize -2);
    119    mng.setBounds_(pos, widgetSwt);
    120
    121  }
    122
    123
    124
    125
    126  @Override public void removeWidgetImplementation()
    127  { swtWidgHelper.removeWidgetImplementation();
    128    widgetSwt = null;
    129  }
    130
    131  @Override
    132  public Object getWidgetImplementation()
    133  { return widgetSwt; }
    134
    135  @Override public void setBoundsPixel(int x, int y, int dx, int dy)
    136  { widgetSwt.setBounds(x,y,dx,dy);
    137  }
    138
    139  @Override public boolean setFocusGThread()
    140  { SwtWidgetHelper.setFocusOfTabSwt(widgetSwt);
    141    widgetSwt.forceFocus();
    142    return widgetSwt.setFocus();
    143  }
    144
    145
    146  /**Sets the implementation widget vible or not.
    147   * @see org.vishia.gral.base.GralWidgImpl_ifc#setVisibleGThread(boolean)
    148   */
    149  @Override public void setVisibleGThread(boolean bVisible) {
    150    super.setVisibleState(bVisible);
    151    swtWidgHelper.setVisibleGThread(bVisible);
    152  }
    153
    154  @Override public void repaintGthread(){
    155    super.prepareWidget();
    156    GralWidget.DynamicData dyda = dyda();
    157    int chg = dyda.getChanged();
    158    if((chg & chgText) !=0 && dyda.displayedText !=null){
    159      //textFieldSwt.setText(dyda.displayedText);
    160    }
    161    if((chg & chgColorText)!=0){
    162      acknChanged(chgColorText);
    163      SwtProperties props = swtWidgHelper.mng.propertiesGuiSwt;
    164      if(dyda.textColor !=null){
    165        widgetSwt.setForeground(props.colorSwt(dyda.textColor));
    166      }
    167      if(dyda.backColor !=null){
    168        widgetSwt.setBackground(props.colorSwt(dyda.backColor));
    169      }
    170      if(dyda.textFont !=null){
    171        widgetSwt.setFont(props.fontSwt(dyda.textFont));
    172      }
    173    }
    174    if((chg & chgVisible) !=0) {
    175      acknChanged(chgVisible);
    176      widgetSwt.setVisible(true);
    177      //widgetSwt.getShell().setVisible(true);
    178    }
    179    if((chg & chgInvisible) !=0) {
    180      acknChanged(chgInvisible);
    181      widgetSwt.setVisible(false);
    182      //widgetSwt.getShell().setVisible(false);
    183    }
    184    if((chg & chgColorText) !=0){ acknChanged(chgColorText); widgetSwt.setForeground(swtWidgHelper.mng.getColorImpl(dyda().textColor)); }
    185    if((chg & chgColorBack) !=0){ acknChanged(chgColorBack); widgetSwt.setBackground(swtWidgHelper.mng.getColorImpl(dyda().backColor)); }
    186    widgetSwt.redraw();
    187  }
    188
    189
    190  protected void paintRoutine(PaintEvent e, Canvas canvas){
    191    GC gc = e.gc;
    192    //gc.d
    193    Rectangle dim = canvas.getBounds();
    194    SwtButton.this.paint1();
    195    boolean bFocus = canvas.isFocusControl();
    196    Color colorBack = swtWidgHelper.mng.getColorImpl(colorgback);
    197    Color colorLine = swtWidgHelper.mng.getColorImpl(colorgline);
    198    if(bFocus) {
    199      colorLine = swtWidgHelper.mng.getColorImpl(GralColor.getColor("rd"));
    200    }
    201    gc.setBackground(colorBack);
    202    canvas.drawBackground(e.gc, dim.x+1, dim.y+1, dim.width-1, dim.height-1);
    203    //Color color = canvas.getForeground(); //of the widget.
    204    gc.setForeground(colorLine);  //black
    205    gc.setFont(fontText);
    206    //FontData fontData = mng.propertiesGui.stdButtonFont.getFontData();
    207    //fontData.
    208    gc.setForeground(colorBack);
    209    gc.fillRectangle(1,1,dim.width-1, dim.height-1);
    210    int ypText;
    211    if(sButtonText !=null){
    212      FontMetrics fontMetrics = gc.getFontMetrics();
    213      int charWidth = fontMetrics.getAverageCharWidth();
    214      int halfWidthButtonText = charWidth * sButtonText.length() /2;
    215      int xText = dim.width / 2 - halfWidthButtonText;
    216      if(xText < 2){ xText = 2; }
    217      ypText = fontMetrics.getHeight();
    218      int halfHeightButtonText = ypText /2;
    219      int yText = dim.height / 2 - halfHeightButtonText;
    220      gc.setForeground(colorLine);
    221      gc.drawString(sButtonText, xText, yText);
    222    } else {
    223      ypText = 0;
    224    }
    225    if(isPressed()){
    226      ((Canvas)e.widget).forceFocus();
    227      /*
    228      gc.setLineWidth(3);
    229      gc.drawRectangle(1,1,dim.width-2, dim.height-2);
    230      gc.setLineStyle(SWT.LINE_DOT);
    231      gc.drawRectangle(3,3,dim.width-6, dim.height-6);
    232      */
    233      if(ypText < dim.height -4){
    234        //normal button
    235        gc.setForeground(black);
    236        gc.setLineWidth(3);
    237        gc.drawRectangle(0,0,dim.width-1, dim.height-1);
    238        gc.setForeground(white);
    239        gc.setLineWidth(1);
    240        gc.drawLine(2, dim.height-2,dim.width-1, dim.height-2);
    241        gc.drawLine(1, dim.height-1,dim.width-1, dim.height-1);
    242        gc.drawLine(0, dim.height-0,dim.width-1, dim.height-0);
    243        gc.drawLine(dim.width-2, 0, dim.width-2, dim.height-1);
    244        gc.drawLine(dim.width-1, 0, dim.width-1, dim.height-1);
    245        gc.drawLine(dim.width-0, 0, dim.width-0, dim.height-1);
    246      } else {
    247        //small button
    248        gc.setLineWidth(1);
    249        gc.setForeground(black);
    250        gc.setLineWidth(1);
    251        gc.drawRectangle(0,0,dim.width-1, dim.height-1);
    252        gc.setForeground(white);
    253        gc.setLineWidth(1);
    254        gc.drawLine(0, dim.height-1,dim.width-1, dim.height-1);
    255        gc.drawLine(dim.width-1, 0, dim.width-1, dim.height-1);
    256      }
    257    } else {
    258      if(ypText < dim.height -4){
    259        //normal button
    260        gc.setForeground(white);
    261        gc.setLineWidth(3);
    262        gc.drawRectangle(0,0,dim.width-1, dim.height-1);
    263        gc.setForeground(black);
    264        gc.setLineWidth(1);
    265        gc.drawLine(2, dim.height-2,dim.width-1, dim.height-2);
    266        gc.drawLine(1, dim.height-1,dim.width-1, dim.height-1);
    267        gc.drawLine(0, dim.height-0,dim.width-1, dim.height-0);
    268        gc.drawLine(dim.width-2, 0, dim.width-2, dim.height-1);
    269        gc.drawLine(dim.width-1, 0, dim.width-1, dim.height-1);
    270        gc.drawLine(dim.width-0, 0, dim.width-0, dim.height-1);
    271      } else {
    272        //small button
    273        gc.setLineWidth(1);
    274        gc.setForeground(white);
    275        gc.setLineWidth(1);
    276        gc.drawRectangle(0,0,dim.width-1, dim.height-1);
    277        gc.setForeground(black);
    278        gc.setLineWidth(1);
    279        gc.drawLine(0, dim.height-1,dim.width-1, dim.height-1);
    280        gc.drawLine(dim.width-1, 0, dim.width-1, dim.height-1);
    281      }
    282    }
    283
    284  }
    285
    286
    287
    288
    289  private class SwtButtonImpl extends Canvas
    290  {
    291
    292    SwtButtonImpl(Composite parent, int style){
    293      super(parent, style);
    294      setForeground(black);
    295
    296      addPaintListener(paintListener);
    297
    298    }
    299
    300    PaintListener paintListener = new PaintListener(){
    301      @Override public void paintControl(PaintEvent e) {
    302        SwtButton.this.paintRoutine(e, SwtButtonImpl.this);
    303      }
    304    };
    305
    306
    307
    308  }
    309
    310
    311  protected class KeyListener extends SwtKeyListener
    312  {
    313
    314    public KeyListener(GralKeyListener keyAction)
    315    { super(keyAction);
    316    }
    317
    318    @SuppressWarnings("synthetic-access")
    319    @Override
    320    public final boolean specialKeysOfWidgetType(int key, GralWidget_ifc widggArg, Object widgImpl){
    321      boolean bDone = true;
    322      if(key == KeyCode.enter) {
    323        widgg.activate();
    324      }
    325      return bDone;
    326    }
    327  };
    328
    329
    330
    331
    332
    333}