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}