001package org.vishia.gral.swt; 002 003import java.io.InputStream; 004import java.util.Map; 005 006import org.eclipse.swt.SWT; 007import org.eclipse.swt.events.FocusEvent; 008import org.eclipse.swt.events.FocusListener; 009import org.eclipse.swt.events.MenuDetectEvent; 010import org.eclipse.swt.events.MenuDetectListener; 011import org.eclipse.swt.events.MouseListener; 012import org.eclipse.swt.events.SelectionEvent; 013import org.eclipse.swt.events.SelectionListener; 014import org.eclipse.swt.graphics.Color; 015import org.eclipse.swt.graphics.Font; 016import org.eclipse.swt.graphics.Image; 017import org.eclipse.swt.graphics.ImageData; 018import org.eclipse.swt.graphics.Point; 019import org.eclipse.swt.graphics.Rectangle; 020import org.eclipse.swt.widgets.Button; 021import org.eclipse.swt.widgets.Composite; 022import org.eclipse.swt.widgets.Control; 023import org.eclipse.swt.widgets.Display; 024import org.eclipse.swt.widgets.Event; 025import org.eclipse.swt.widgets.Label; 026import org.eclipse.swt.widgets.Listener; 027import org.eclipse.swt.widgets.Menu; 028import org.eclipse.swt.widgets.Shell; 029import org.eclipse.swt.widgets.Slider; 030import org.eclipse.swt.widgets.TabFolder; 031import org.eclipse.swt.widgets.Table; 032import org.eclipse.swt.widgets.TableItem; 033import org.eclipse.swt.widgets.Text; 034import org.eclipse.swt.widgets.Widget; 035import org.vishia.gral.base.GralButton; 036import org.vishia.gral.base.GralCurveView; 037import org.vishia.gral.base.GralGraphicThread; 038import org.vishia.gral.base.GralGridProperties; 039import org.vishia.gral.base.GralHtmlBox; 040import org.vishia.gral.base.GralLed; 041import org.vishia.gral.base.GralMenu; 042import org.vishia.gral.base.GralPos; 043import org.vishia.gral.base.GralTable; 044import org.vishia.gral.base.GralValueBar; 045import org.vishia.gral.base.GralWidget; 046import org.vishia.gral.base.GralMng; 047import org.vishia.gral.base.GralPanelContent; 048import org.vishia.gral.base.GralWindow; 049import org.vishia.gral.base.GralTabbedPanel; 050import org.vishia.gral.base.GralPanelActivated_ifc; 051import org.vishia.gral.base.GralTextBox; 052import org.vishia.gral.base.GralTextField; 053import org.vishia.gral.cfg.GralCfgBuilder; 054import org.vishia.gral.ifc.GralCanvasStorage; 055import org.vishia.gral.ifc.GralColor; 056import org.vishia.gral.ifc.GralFileDialog_ifc; 057import org.vishia.gral.ifc.GralImageBase; 058import org.vishia.gral.ifc.GralMng_ifc; 059import org.vishia.gral.ifc.GralRectangle; 060import org.vishia.gral.ifc.GralWindow_ifc; 061import org.vishia.gral.ifc.GralUserAction; 062import org.vishia.gral.ifc.GralWidget_ifc; 063import org.vishia.gral.widget.GralHorizontalSelector; 064import org.vishia.gral.widget.GralLabel; 065import org.vishia.gral.widget.GralPlotArea; 066import org.vishia.msgDispatch.LogMessage; 067 068 069 070 071 072/**This class manages the building of Panels with GUI-Elements for example for a Dialog Box 073 * The container can be visibilized as a part of another container of any window. 074 * An example is given in {@link org.vishia.mainGuiSwt.SampleGuiSwtButtonInput} 075 * <br><br> 076 * The positions on the display are based on grid units. 077 * The grid-size (number of x- and y-pixel per grid unit) is able to set, so a more large 078 * or a more small representation of the graphic is shown, depending on the display point size, 079 * the distance to view or personal defaults. 080 * <br><br> 081 * A layout manager like flow-layout is not used here. The user sets fix positions in the grid units. 082 * A grid unit is a half-small-line in the vertical direction and about a small character width 083 * in the x-direction. So a closed-to-user-thinking position is able to set for any component. 084 * It is like rows or lines and columns. 085 * An automatically layout managing using self-deciding positioning of any components is not done. 086 * But a next added component may be positioned right from the previous or below the previous 087 * without manually calculation and setting of the position. It simplifies positioning. 088 * <br><br> 089 * This class supports setting of values of shown components with symbolic access (String-name) 090 * in runtime 091 * and selecting of button-actions and data-container while creating with symbolic access 092 * to the action-instance or the data-container. This property is used especially 093 * by the text-script-controlled built of a dialog widget using the {@link GralCfgBuilder}, 094 * but it is able to simplify the access to data and actions elsewhere too. 095 * <br><br> 096 * <br><br> 097 * <br><br> 098 * <br><br> 099 * 100 * @author Hartmut Schorrig 101 * 102 */ 103//GralMng.ImplAccess 104public class SwtMng extends GralMng.ImplAccess // implements GralMngBuild_ifc, GralMng_ifc 105//GuiShellMngIfc<Control> 106{ 107 //private static final long serialVersionUID = -2547814076794969689L; 108 109 /**Version, history and license. The version number is a date written as yyyymmdd as decimal number. 110 * Changes: 111 * <ul> 112 * <li>2016-09-02 Hartmut chg: Some {@link GralPanelContent#GralPanelContent(String, String, char)} and {@link GralTabbedPanel#GralTabbedPanel(String, String, GralPanelActivated_ifc, int)} 113 * was invoked with "@" for the posString without any more posString information. That is false. The idea was: Set the current panel. But that does not run. 114 * See changes on {@link GralMng} on 2016-09-02. 115 * <li>2013-12-21 Hartmut new: {@link #createImplWidget_Gthread(GralWidget)} instanciates all widget types. 116 * <li>2012-07-13 Hartmut chg: {@link #resizeWidget(GralWidget, int, int)} can work with more as one widget implementation. 117 * But it isn't test and used yet. Size of any implementation widget? 118 * <li>2012-03-17 Hartmut chg: some changes for {@link #setPosAndSizeSwt(Control, int, int)} etc. 119 * <li>2012-01-26 Hartmut chg: prevent some error messages which are unnecessary. 120 * <li>2012-01-01 Hartmut new: The {@link #setInfoGthread(GralWidget, int, int, Object, Object)} routine 121 * uses the {@link SwtSetValue_ifc} capability to associate cmd to types of widgets. Yet used only for {@link SwtSubWindow}. 122 * <li>2011-12-03 Hartmut new: {@link #setInfoGthread(GralWidget, int, int, Object, Object)} catches 123 * any exception, before: An exception causes aborting the graphic thread. 124 * <li>2011-12-03 Hartmut chg: {@link #addLed(String, String, String)} now uses {@link GralLed}. 125 * <li>2011-12-03 Hartmut new: {@link #swtKeyListener} as base for all fields. 126 * <li>2011-11-12 Hartmut chg: {@link #calcPositionOfWindow(GralPos)} improved 127 * <li>2011-08-13 Hartmut chg: New routines for store and calculate the position to regard large widgets. 128 * <li>2011-06-17 Hartmut getValueFromWidget(): Table returns the whole selected line, cells separated with tab. 129 * The String-return.split("\t") separates the result to the cell values. 130 * <li>2011-05-08 Hartmut new; {@link GralMng_ifc#cmdClear} used to clear a whole swt.Table, commonly using: clear a content of widget. 131 * <li>2010-12-02 Hartmut: in method insertInfo((): call of checkAdmissibility() for some input parameter, 132 * elsewhere exceptions may be possible on evaluating the inserted info in doBeforeDispatching(). 133 * There the causer isn't found quickly while debugging. 134 * <li>2010-12-02 Hartmut: Up to now this version variable, its description contains the version history. 135 * </ul> 136 * <br><br> 137 * <b>Copyright/Copyleft</b>: 138 * For this source the LGPL Lesser General Public License, 139 * published by the Free Software Foundation is valid. 140 * It means: 141 * <ol> 142 * <li> You can use this source without any restriction for any desired purpose. 143 * <li> You can redistribute copies of this source to everybody. 144 * <li> Every user of this source, also the user of redistribute copies 145 * with or without payment, must accept this license for further using. 146 * <li> But the LPGL ist not appropriate for a whole software product, 147 * if this source is only a part of them. It means, the user 148 * must publish this part of source, 149 * but don't need to publish the whole source of the own product. 150 * <li> You can study and modify (improve) this source 151 * for own using or for redistribution, but you have to license the 152 * modified sources likewise under this LGPL Lesser General Public License. 153 * You mustn't delete this Copyright/Copyleft inscription in this source file. 154 * </ol> 155 * If you are intent to use this sources without publishing its usage, you can get 156 * a second license subscribing a special contract with the author. 157 * 158 * @author Hartmut Schorrig = hartmut.schorrig@vishia.de 159 */ 160 //@SuppressWarnings("hiding") 161 public final static String version = "2015-01-18"; 162 163 /**The GUI may be determined by a external user file. Not all planned fields, buttons etc. 164 * may be placed in the GUI, a user can desire about the elements. 165 * But an access to a non-existing element should be detected. This Exception should be caught 166 * and an alternate behavior on non-existing elements may be programmed in the application. 167 */ 168 public class NotExistException extends Exception 169 { 170 private static final long serialVersionUID = 1L; 171 172 NotExistException(String name) 173 { super("GUI-Element doesn't exist in GUI: " + name); 174 } 175 } 176 177 /**The graphical frame. It is any part of a window (a Composite widget) or the whole window. */ 178 //public final Composite graphicFrame; 179 180 //public final Shell theShellOfWindow; 181 182 protected Rectangle XXXXXcurrPanelPos; 183 184 185 /**Properties of this Dialog Window. The {@link GralMng} contains an aggregation 186 * to the same instance, but with type {@link GralGridProperties}. Internally there are some more 187 * Swt-capabilities in the derived type. 188 */ 189 public final SwtProperties propertiesGuiSwt; 190 191 192 final Display displaySwt; 193 194 //public final SwtWidgetHelper widgetHelper = new SwtWidgetHelper(this); 195 196 /**This mouse-click-implementor is added to any widget, 197 * which is associated to a {@link GralWidget} in its data. 198 * The infos of the last clicked widget can be got with it. 199 * @deprecated use {@link SwtGralMouseListener#mouseActionStd}, it is the same, but better structured. 200 */ 201 @Deprecated MouseListener mouseClickForInfo = new SwtGralMouseListener.MouseListenerGralAction(); //NoAction(); 202 203 204 /**The instance for all traverse listener applicable to all widgets. */ 205 static SwtTraverseListener swtTraverseListener = new SwtTraverseListener(); 206 207 //SwtKeyListener swtKeyListener = new SwtKeyListener(this); 208 209 /**It is a marker interface. */ 210 protected interface XXXUserAction{} 211 212 213 /**Action for user commands of buttons. 214 * An instance of this class is able to assign as button-action. 215 * The actionPerformed-method is implemented here, but the procedure calls a used-defined 216 * action method which is implemented in the user-space implementing the 217 * {@link GralUserAction#userActionGui(String, String, Map)}-interface. 218 */ 219 protected class XXXButtonUserAction implements XXXUserAction, SelectionListener 220 { 221 222 /**Reference to the users method. */ 223 private final GralUserAction userCmdGui; 224 225 /**Constructor. 226 * @param userCmdGui The users method for the action. */ 227 private XXXButtonUserAction(GralUserAction userCmdGui) 228 { 229 this.userCmdGui = userCmdGui; 230 } 231 232 233 @Override 234 public void widgetDefaultSelected(SelectionEvent e) { 235 // TODO Auto-generated method stub 236 237 } 238 239 /**Implementing of the primary action method, 240 * implements @see org.eclipse.swt.events#widgetSelected(SelectionEvent) 241 * All values of input fields are read out and filled in a list, to support locally access 242 * to the values of the dialog. 243 */ 244 @Override 245 public void widgetSelected(SelectionEvent e) { 246 /**prepare all inputs: */ 247 //String sButtonCmd = e.getActionCommand(); 248 //String sParamString = e.paramString(); 249 Object data = null; 250 //String sParam = ""; 251 Widget src = e.widget; 252 Object widgetData = src.getData(); 253 GralWidget infos = widgetData instanceof GralWidget ? (GralWidget)widgetData : null; 254 if(src instanceof Button){ 255 Button button = (Button)src; 256 data = button.getData(); 257 if(data != null && data instanceof String){ 258 //sParam = (String)data; 259 } 260 } 261 /* 262 Map<String,String> values; 263 if(sParam.endsWith("+")){ 264 values = getAllValues(); 265 } else { 266 values = null; 267 } 268 */ 269 userCmdGui.userActionGui("button", infos); 270 271 } 272 273 } 274 275 276 277 /**This class is only used to store values to inspect. The Inspector is a tool which works with 278 * reflection and with it internal variable can be visited in runtime. See {@link org.vishia.inspectorTarget.Inspector}. 279 */ 280 @SuppressWarnings("unused") 281 private static class TestHelp{ 282 private GralCurveView curveView; 283 } 284 TestHelp testHelp = new TestHelp(); 285 286 287 /**Creates an instance. 288 * @param guiContainer The container where the elements are stored in. 289 * @param width in display-units for the window's width, the number of pixel depends from param displaySize. 290 * @param height in display-units for the window's height, the number of pixel depends from param displaySize. 291 * @param displaySize character 'A' to 'E' to determine the size of the content 292 * (font size, pixel per cell). 'A' is the smallest, 'E' the largest size. Default: use 'C'. 293 */ 294 protected SwtMng(Display display /*, Composite graphicFrame */ 295 , char displaySize//, VariableContainer_ifc variableContainer 296 , LogMessage log) 297 { //super(sTitle); 298 this(display, new SwtProperties(display, displaySize), log); 299 300 } 301 302 /**Creates an instance. 303 * @param guiContainer The container where the elements are stored in. 304 * @param width in display-units for the window's width, the number of pixel depends from param displaySize. 305 * @param height in display-units for the window's height, the number of pixel depends from param displaySize. 306 * @param displaySize character 'A' to 'E' to determine the size of the content 307 * (font size, pixel per cell). 'A' is the smallest, 'E' the largest size. Default: use 'C'. 308 */ 309 public SwtMng(Display display 310 , SwtProperties propertiesGui 311 //, VariableContainer_ifc variableContainer 312 , LogMessage log 313 ) 314 { super(GralMng.get(), propertiesGui); 315 this.propertiesGuiSwt = propertiesGui; 316 //pos().x.p1 = 0; //start-position 317 //pos().y.p1 = 4 * propertiesGui.yPixelUnit(); 318 319 320 displaySwt = display; 321 //displaySwt.addFilter(SWT.KeyDown, mainKeyListener); 322 323 324 } 325 326 327 328 /**The composite of the panel in SWT. 329 * @see org.vishia.gral.base.GralMng.ImplAccess#getCurrentPanel() 330 */ 331 @Override public Composite getCurrentPanel(){ return ((Composite)pos().panel.getWidgetImplementation()); } 332 333 public Composite getWidgetsPanel(GralWidget widg){ 334 GralPos pos = widg.pos(); 335 if(pos == null) { pos = pos(); } //from GralMng 336 return ((Composite)pos.panel.getWidgetImplementation()); 337 } 338 339 340 private Composite getCurrentPanel(GralWidget widgg){ return ((Composite)widgg.pos().panel.getWidgetImplementation()); } 341 342 343 @Override public void createImplWidget_Gthread(GralWidget widgg){ 344 if(widgg instanceof GralHtmlBox) { //NOTE: before GralTextField because a GralTextBox is a GralTextField (derived) 345 SwtHtmlBox.createHtmlBox((GralHtmlBox)widgg, this); //This may be the best variant. 346 } else if(widgg instanceof GralTextBox) { //NOTE: before GralTextField because a GralTextBox is a GralTextField (derived) 347 SwtTextBox.createTextBox((GralTextBox)widgg, this); //This may be the best variant. 348 } else if(widgg instanceof GralTextField){ 349 SwtTextFieldWrapper.createTextField((GralTextField)widgg, mng); //This may be the best variant. 350 } else if(widgg instanceof GralHorizontalSelector<?>){ 351 SwtHorizontalSelector swtSel = new SwtHorizontalSelector(this, (GralHorizontalSelector<?>)widgg); 352 mng.registerWidget(widgg); 353 } else if(widgg instanceof GralTable<?>){ 354 SwtTable.createTable((GralTable<?>)widgg, this); //This may be the best variant. 355 } else if(widgg instanceof GralButton){ 356 new SwtButton((GralButton)widgg, this); 357 mng.registerWidget(widgg); 358 } 359 else if(widgg instanceof GralLabel){ 360 new SwtLabel((GralLabel)widgg, this); 361 } 362 else if(widgg instanceof GralValueBar){ 363 new SwtValueBar((GralValueBar)widgg, this); 364 } 365 else if(widgg instanceof GralLed){ 366 new SwtLed((GralLed)widgg, this); 367 mng.registerWidget(widgg); 368 } 369 else if(widgg instanceof GralPlotArea){ 370 new SwtPlotArea((GralPlotArea)widgg, this); 371 } 372 } 373 374 375 376 377 378 379 @Override public GralPanelContent createCompositeBox(String name) 380 { 381 //Composite box = new Composite(graphicFrame, 0); 382 Composite box = new Composite(getCurrentPanel(), 0); 383 setPosAndSize_(mng.getPosOldPositioning(), box); 384 Point size = box.getSize(); 385 GralPanelContent panelg = new GralPanelContent(null, name); 386 GralPanelContent panel = (new SwtPanel(panelg, box)).gralPanel(); 387 //mng.registerPanel(panel); 388 //GuiPanelMngSwt mng = new GuiPanelMngSwt(gralDevice, size.y, size.x, propertiesGuiSwt, variableContainer, log); 389 return panel; 390 } 391 392 393 @Override public GralPanelContent createGridPanel(String namePanel, GralColor backGround, int xG, int yG, int xS, int yS) 394 { GralPanelContent panelg = new GralPanelContent(null, namePanel); 395 Color backColorSwt = propertiesGuiSwt.colorSwt(backGround); 396 SwtGridPanel panel = new SwtGridPanel(panelg, null, 0, backColorSwt, xG, yG, xS, yS, mng); 397 GralPanelContent gralPanel = panel.gralPanel(); 398 //mng.registerPanel(gralPanel); 399 400 return gralPanel; 401 } 402 403 404 405 @Override public boolean remove(GralPanelContent compositeBox) 406 { Composite panelSwt = ((SwtPanel)compositeBox.getWidgetImplementation()).panelComposite; 407 panelSwt.dispose(); 408 return true; 409 } 410 411 412 413 /* (non-Javadoc) 414 * @see org.vishia.gral.ifc.GralMngBuild_ifc#createWindow(java.lang.String, java.lang.String, int) 415 */ 416 @Deprecated 417 @Override public GralWindow createWindow(String name, String title, int windProps) 418 { 419 //GralWindow windowGral = new GralWindow("@", name, title, windProps); 420 GralWindow windowGral = new GralWindow(null, name, title, windProps); 421 //SwtGraphicThread swtDevice = (SwtGraphicThread)gralDevice; 422 createSubWindow(windowGral); 423 return windowGral; 424 425 } 426 427 428 429 430 /* (non-Javadoc) 431 * @see org.vishia.gral.ifc.GralMngBuild_ifc#createWindow(org.vishia.gral.base.GralWindow) 432 */ 433 @Override public void createSubWindow(GralWindow windowGral) { 434 SwtSubWindow windowSwt = new SwtSubWindow(this, windowGral); 435 //GralRectangle rect = calcPositionOfWindow(windowGral.pos()); 436 //windowSwt.window.setBounds(rect.x, rect.y, rect.dx, rect.dy ); 437 windowGral._wdgImpl = windowSwt; 438 } 439 440 441 442 443 @Override public boolean XXXsetWindowsVisible(GralWindow_ifc window, GralPos atPos) 444 {return false; } 445 446 447 448 449 450 /**Calculates the position as absolute value on screen from a given position inside a panel. 451 * @param posWindow contains any {@link GralPos#panel}. Its absolute position will be determined. 452 * from that position and size the absolute postion will be calculate, with this given grid positions 453 * inside the panel. 454 * @return Absolute pixel coordinate. 455 */ 456 GralRectangle calcPositionOfWindow(GralPos posWindow) 457 { 458 final GralRectangle windowFrame; 459 Control parentFrame; 460 final Shell window; 461 if(posWindow.panel !=null) { 462 Object swtWidg = posWindow.panel.getWidgetImplementation(); 463 parentFrame = (Control)swtWidg; //((SwtPanel)(swtWidg)).panelComposite; //(Control)posWindow.panel.getPanelImpl(); 464 Point loc; 465 window = parentFrame.getShell(); 466 int x = 6; 467 windowFrame = getPixelUseableAreaOfWindow(posWindow.panel); 468 } else { 469 windowFrame = new GralRectangle(0,0,800,600); 470 parentFrame = null; 471 window = null; 472 } 473 int dxFrame, dyFrame; //need if posWindow has coordinates from right or in percent 474 Rectangle rectParent; 475 if(parentFrame == window){ 476 dxFrame = windowFrame.dx; dyFrame = windowFrame.dy; 477 } else { 478 rectParent = parentFrame.getBounds(); 479 dxFrame = rectParent.width; dyFrame = rectParent.height; 480 } 481 final GralRectangle rectangle = mng.calcWidgetPosAndSize(posWindow, dxFrame, dyFrame, 400, 300); 482 rectangle.x += windowFrame.x; 483 rectangle.y += windowFrame.y; 484 485 // 486 while ( parentFrame != window){ //The Shell is the last parentFrame 487 //the bounds are relative to its container. Get all parent container and add all positions 488 //until the shell is reached. 489 rectParent = parentFrame.getBounds(); 490 rectangle.x += rectParent.x; 491 rectangle.y += rectParent.y; 492 parentFrame = parentFrame.getParent(); 493 } 494 return rectangle; 495 496 /* 497 Rectangle rectParent = parentFrame instanceof Shell ? ((Shell)parentFrame).getClientArea() 498 : parentFrame.getBounds(); 499 //loc = panel.getLocation(); 500 int xPos = rectParent.x, yPos = rectParent.y; 501 while( (parentFrame = parentFrame.getParent()) !=null){ 502 rectParent = parentFrame.getBounds(); 503 loc = parentFrame.getLocation(); 504 xPos += rectParent.x; 505 yPos += rectParent.y; 506 if(parentFrame instanceof Shell){ 507 Shell shell = (Shell)parentFrame; 508 Rectangle rectArea = shell.getClientArea(); //size of client area 509 Menu menu = shell.getMenuBar(); 510 //Point sizeArea = shell.getSize(); 511 int dy = rectParent.height - rectArea.height; //The start of client area 512 if(menu !=null){ dy *=2; } //Menu needs the same size as title. 513 int dx = rectParent.width - rectArea.width; 514 xPos += dx; 515 yPos += dy; 516 } else { 517 } 518 519 } 520 rectangle.x += xPos; 521 rectangle.y += yPos; 522 return rectangle; 523 */ 524 } 525 526 527 528 GralRectangle getPixelUseableAreaOfWindow(GralWidget widgg) 529 { Object oControl = widgg._wdgImpl.getWidgetImplementation(); 530 Control control = (Control)oControl; 531 Shell window = control.getShell(); 532 Rectangle rectWindow = window.getBounds(); 533 Rectangle rectWindowArea = window.getClientArea(); //it is inclusive the menu bar. 534 //Problem: the x and y of client are are 0, it may bettet that they are the left top corner 535 //inside the shell window. 536 //assume that the client area is on bottom of the shell. Calculate top position: 537 int dxBorder = rectWindow.width - rectWindowArea.width; 538 int xPos = rectWindow.x + dxBorder/2; 539 int dyTitleMenu = (rectWindow.height - rectWindowArea.height) - dxBorder; //border and title bar 540 Menu menu = window.getMenuBar(); 541 if(menu !=null){ 542 //assume that the menu has the same hight as title bar, there is not a way to determine it else 543 dyTitleMenu *=2; 544 } 545 int yPos = rectWindow.y + dxBorder/2 + dyTitleMenu; 546 GralRectangle ret = new GralRectangle(xPos, yPos, rectWindowArea.width, rectWindowArea.height - dyTitleMenu); 547 return ret; 548 } 549 550 551 552 /**This method can be override by the user to force some actions if the dialog window is closed. It may be left empty. */ 553 protected void windowClosing() 554 { 555 556 } 557 558 559 /**Places a current component with knowledge of the current positions and the spreads of the component on graphic. 560 * @param component The component to place. 561 */ 562 GralRectangle setBounds_(GralPos pos, Control component) 563 { return setPosAndSize_(pos, component); 564 //setBounds_(component, 0,0, 0, 0); 565 } 566 567 568 569 570 GralRectangle setPosAndSize_(GralPos pos, Control component) 571 { return setPosAndSizeSwt(pos, component, 0,0); 572 } 573 574 575 576 577 578 579 /**Set bounds of a SWT component with this {@link GralMng#pos} from the GralWidgetMng. 580 * The {@link #setNextPosition()} is called to process a used this.pos to its next. 581 * This method is package-private for SWT-implementation. It calls 582 * {@link #setNextPosition()} and {@link #setPosAndSizeSwt(GralPos, Control, int, int)} 583 * with 584 * @param component The SWT-widget. 585 * @param widthwidgetNat The natural size of the component. 586 * @param heigthWidgetNat The natural size of the component. 587 * 588 * NOTE: 2015-07-13: This method is set to unused because it uses the mng-position additional to the constructor of GralWidget. 589 * This is the old concept which is in conflict with the usuage there. 590 */ 591 void XXXsetPosAndSizeSwt(Control component, int widthwidgetNat, int heigthWidgetNat) 592 { mng.setNextPosition(); 593 setPosAndSizeSwt(pos(), component, widthwidgetNat, heigthWidgetNat); 594 } 595 596 597 598 599 /**Set bounds of a SWT component with a given position. 600 * This method is package-private for SWT-implementation. 601 * @param posP The Position for the component. 602 * @param component The SWT-widget. 603 * @param widthwidgetNat The natural size of the component. 604 * @param heigthWidgetNat The natural size of the component. 605 */ 606 GralRectangle setPosAndSizeSwt(GralPos posP, Control component, int widthwidgetNat, int heigthWidgetNat) 607 { 608 GralRectangle rectangle = calcWidgetPosAndSizeSwt(posP, component.getParent(), widthwidgetNat, heigthWidgetNat); 609 //on SWT it invokes the resize listener if given. 610 component.setBounds(rectangle.x, rectangle.y, rectangle.dx, rectangle.dy ); 611 return rectangle; 612 } 613 614 615 616 617 618 /**Calculates the bounds of a widget with a given pos independent of this {@link #pos}. 619 * This method is a part of the implementing GralMng because the GralPos is not implemented for 620 * any underlying graphic system and the {@link #propertiesGuiSwt} are used. 621 * It is possible to tune the bounds after calculation, for example to enhance the width if a text 622 * is larger then the intended position. 623 * @param pos The position. 624 * @param widthwidgetNat The natural size of the component. 625 * @param heigthWidgetNat The natural size of the component. 626 * @return A rectangle with position and size. 627 */ 628 @Override public GralRectangle calcWidgetPosAndSize(GralPos pos, int widthwidgetNat, int heigthWidgetNat){ 629 630 Object oParent = pos.panel.getWidgetImplementation(); 631 Composite parentComp = (Composite) oParent; //((SwtPanel)(pos().panel.getWidgetImplementation())).panelComposite; //(Composite)pos().panel.getPanelImpl(); 632 //Rectangle pos; 633 final GralRectangle rectangle; 634 final Rectangle parentSize; 635 if(parentComp == null){ 636 parentSize = new Rectangle(0,0,800, 600); 637 } else if(parentComp instanceof Shell) { 638 parentSize = ((Shell)parentComp).getClientArea(); 639 } else { 640 parentSize = parentComp.getBounds(); 641 } 642 return pos().calcWidgetPosAndSize(mng.propertiesGui, parentSize.width, parentSize.height, widthwidgetNat, heigthWidgetNat); 643 } 644 645 646 647 648 /**Calculates the bounds of a SWT component with a given position independent of {@link #pos}. 649 * This method is package-private for SWT-implementation. 650 * It is possible to tune the bounds after calculation, for example to enhance the width if a text 651 * is larger then the intended position. 652 * @param pos The position. 653 * @param component The SWT-widget. 654 * @param widthwidgetNat The natural size of the component. 655 * @param heigthWidgetNat The natural size of the component. 656 * @return A rectangle with position and size. 657 * @deprecated, use {@link #calcWidgetPosAndSizeSwt(GralPos, int, int)} 658 */ 659 GralRectangle calcWidgetPosAndSizeSwt(GralPos pos, Control parentComp, int widthwidgetNat, int heigthWidgetNat){ 660 //Rectangle pos; 661 final GralRectangle rectangle; 662 final Rectangle parentSize; 663 if(parentComp == null){ 664 parentSize = new Rectangle(0,0,800, 600); 665 } else if(parentComp instanceof Shell) { 666 parentSize = ((Shell)parentComp).getClientArea(); 667 } else { 668 parentSize = parentComp.getBounds(); 669 } 670 return mng.calcWidgetPosAndSize(pos, parentSize.width, parentSize.height, widthwidgetNat, heigthWidgetNat); 671 } 672 673 674 675 676 677 678 /**Adds a tab panel in implementation. 679 * If this routine was called, the GralMng.pos is the pos for the Tabbed panel. 680 * @see org.vishia.gral.base.GralMng.ImplAccess#addTabbedPanel(java.lang.String, org.vishia.gral.base.GralPanelActivated_ifc, int) 681 */ 682 @Override public GralTabbedPanel addTabbedPanel(String namePanel, GralPanelActivated_ifc user, int property) 683 { GralTabbedPanel panelg = new GralTabbedPanel(null, namePanel, user, property); 684 SwtTabbedPanel tabMngPanel = new SwtTabbedPanel(panelg, this, user, property); 685 mng.currTabPanel = panelg; 686 //GralWidget tabFolder = currTabPanel; 687 TabFolder tabFolderSwt = (TabFolder)tabMngPanel.getWidgetImplementation(); 688 setPosAndSize_(panelg.pos(), tabFolderSwt); //(Control)currTabPanel.getGuiComponent().getWidgetImplementation()); 689 listVisiblePanels_add(mng.currTabPanel); //TODO checkit maybe currTabPanel.getCurrentPanel() 690 //mng.registerWidget(tabMngPanel); 691 return mng.currTabPanel; 692 } 693 694 695 696 697 @Override @Deprecated public GralWidget addText(String sText, char size, int color) 698 { 699 Composite swtPanel = ((Composite)(pos().panel.getWidgetImplementation())); 700 Label widget = new Label(swtPanel, 0); 701 widget.setForeground(propertiesGuiSwt.colorSwt(color)); 702 widget.setBackground(propertiesGuiSwt.colorBackground); 703 widget.setText(sText); 704 //Font font = propertiesGui.stdInputFont; 705 Font font = propertiesGuiSwt.getSwtFont(pos().height()); 706 widget.setFont(font); 707 //font.getFontData()[0]. 708 Point textSize = widget.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); 709 //int width = sText.length(); 710 //widget.setSize(sizePixel); 711 712 setPosAndSize_(mng.getPosOldPositioning(), widget); 713 714 Point widgetSize = widget.getSize(); 715 if(widgetSize.x < textSize.x){ 716 widget.setSize(textSize); 717 } 718 widget.setSize(textSize); 719 //guiContent.add(widget); 720 GralWidget widg = new GralWidget("labelText-" + sText, 'S', mng); 721 SwtWidgetSimpleWrapper widgswt = new SwtWidgetSimpleWrapper(widget, this); 722 //widg.implMethodWidget_.setWidgetImpl(widgswt); 723 return widg; 724 } 725 726 727 /** Adds a text field for showing or editing a text value. 728 * 729 * @param sName The registering name 730 * @param width Number of grid units for length 731 * @param editable true than edit-able, false to show content 732 * @param prompt If not null, than a description label is shown 733 * @param promptStylePosition Position and size of description label: 734 * upper case letter: normal font, lower case letter: small font 735 * 'l' left, 't' top (above field) 736 * @return 737 */ 738 public GralWidget XXXaddTextField(String name, boolean editable, String prompt, char promptStylePosition) 739 { 740 return null; //addTextField(null, name, editable, prompt, promptStylePosition); 741 } 742 743 744 /** Adds a text field for showing or editing a text value. 745 * 746 * @param sName The registering name 747 * @param width Number of grid units for length 748 * @param editable true than edit-able, false to show content 749 * @param prompt If not null, than a description label is shown 750 * @param promptStylePosition Position and size of description label: 751 * upper case letter: normal font, lower case letter: small font 752 * 'l' left, 't' top (above field) 753 * @return 754 */ 755 public GralWidget XXXaddTextField(GralWidget widgetInfo, boolean editable, String prompt, char promptStylePosition) 756 { 757 return null; //addTextField(widgetInfo, null, editable, prompt, promptStylePosition); 758 } 759 760 761@Override public GralHtmlBox addHtmlBox(String name) { 762 GralHtmlBox box = new GralHtmlBox(name); 763 new SwtHtmlBox(box, this); 764 return box; 765} 766 767 768 769 770 /* (non-Javadoc) 771 * @see org.vishia.mainGui.GuiPanelMngIfc#addImage(java.lang.String, int, int, java.lang.String, java.lang.String, java.lang.String) 772 */ 773 @Override 774 public Object addImage(String sName, InputStream imageStream, int height, int width, String sCmd) 775 { 776 ImageData imageData = new ImageData(imageStream); 777 byte[] data = imageData.data; 778 SwtPanel swtPanel = (SwtPanel)pos().panel.getImpl(); 779 Composite swtWidg = swtPanel.panelComposite; 780 Image image = new Image(swtWidg.getDisplay(), imageData); 781 GralImageBase imageGui = new SwtImage(image); 782 GralRectangle size = imageGui.getPixelSize(); 783 GralRectangle rr = mng.calcWidgetPosAndSize(pos(), 0, 0, size.dx, size.dy); 784 GralCanvasStorage canvas = pos().panel.canvas; 785 if(canvas !=null){ 786 canvas.drawImage(imageGui, rr.x, rr.y, rr.dx, rr.dy, size); 787 } 788 return null; 789 } 790 791 792 793 794 @Override public GralWidget addSlider( 795 String sName 796 , GralUserAction action 797 , String sShowMethod 798 , String sDataPath 799 ) 800 { 801 Slider control = new Slider(getCurrentPanel(), SWT.VERTICAL); 802 control.setBackground(propertiesGuiSwt.colorBackground); 803 setPosAndSize_(mng.getPosOldPositioning(), control); 804 GralWidget widg = new GralWidget(sName, 'V', mng); 805 SwtWidgetSimpleWrapper widgswt = new SwtWidgetSimpleWrapper(control, this); 806 //widg.implMethodWidget_.setWidgetImpl(widgswt); 807 widg.setPanelMng(mng); 808 if(action != null){ 809 SelectionListenerForSlider actionSlider = new SelectionListenerForSlider(widg, action); 810 control.addSelectionListener(actionSlider); 811 } 812 widg.setDataPath(sDataPath); 813 control.setData(widg); 814 control.addMouseListener(mouseClickForInfo); 815 return widg; 816 817 } 818 819 820 821 @Override public GralCurveView addCurveViewY(String sName, int nrofXvalues, GralCurveView.CommonCurve common) { 822 //setNextPosition(); 823 GralCurveView widgg = new GralCurveView(sName, nrofXvalues, common); 824 new SwtCurveView(widgg, this); //sName, this.pos(), this, nrofXvalues, common); //, curveView, 'c', sName, null); 825 mng.curveContainer.add(widgg); 826 //CurveView curveView = new CurveView(((SwtPanel)pos().panel).getPanelImpl(), dxWidget, dyWidget, nrofXvalues, nrofTracks); 827 testHelp.curveView = widgg; //store to inspect. 828 return widgg; 829 } 830 831 832 833 @Override public GralWidget addFocusAction(String sName, GralUserAction action, String sCmdEnter, String sCmdRelease) 834 { 835 GralWidget widget = indexNameWidgets(sName); 836 if(widget == null || widget._wdgImpl ==null || !(widget._wdgImpl.getWidgetImplementation() instanceof Control)){ 837 mng.log.sendMsg(0, "GuiMainDialog:addClickAction: unknown widget %s", sName); 838 } else { 839 /**The class ButtonUserAction implements the general button action, which class the registered user action. */ 840 ((Control)(widget._wdgImpl.getWidgetImplementation())).addFocusListener( new SwtFocusAction(this, action, sCmdEnter, sCmdRelease)); 841 842 } 843 return widget; 844 } 845 846 847 @Override public void addFocusAction(GralWidget widgetInfo, GralUserAction action, String sCmdEnter, String sCmdRelease) 848 { 849 ((Control)(widgetInfo._wdgImpl.getWidgetImplementation())).addFocusListener( new SwtFocusAction(this, action, sCmdEnter, sCmdRelease)); 850 } 851 852 853 @Override @Deprecated public GralTable addTable(String sName, int height, int[] columnWidths) 854 { 855 GralTable table = new GralTable(sName, columnWidths); 856 return SwtTable.addTable(table, this, sName, height, columnWidths); 857 858 } 859 860 861 @Override protected GralMenu XXXaddPopupMenu(String sName){ 862 Control panelSwt = getCurrentPanel(); //(Control)pos().panel.getPanelImpl(); 863 GralMenu menu = new GralMenu(); new SwtMenu(menu, null, panelSwt); 864 return menu; 865 } 866 867 868 @Override protected GralMenu createContextMenu(GralWidget widg){ 869 Control widgSwt = (Control)widg._wdgImpl.getWidgetImplementation(); 870 GralMenu menu = new GralMenu(); new SwtMenu(menu, widg, widgSwt); 871 return menu; 872 } 873 874 875 @Override protected GralMenu createMenuBar(GralWindow windg){ 876 Shell windowSwt = (Shell)windg.getWidgetImplementation(); 877 GralMenu menu = new GralMenu(); new SwtMenu(menu, windg, windowSwt); 878 return menu; 879 } 880 881 882 883 884 @Override public GralFileDialog_ifc createFileDialog() 885 { 886 Composite panelSwt = getCurrentPanel(); //(Composite)pos().panel.getPanelImpl(); //cast admissible, it should be SWT 887 while(!(panelSwt instanceof Shell)){ 888 panelSwt = panelSwt.getParent(); 889 } 890 return new SwtFileDialog((Shell)panelSwt); 891 } 892 893 894 895 static class SelectionListenerForSlider implements SelectionListener 896 { 897 private final GralUserAction userAction; 898 899 private final GralWidget widgetInfo; 900 901 902 903 public SelectionListenerForSlider(GralWidget widgetInfo, GralUserAction userAction) 904 { 905 this.userAction = userAction; 906 this.widgetInfo = widgetInfo; 907 } 908 909 @Override public void widgetDefaultSelected(SelectionEvent e) 910 { 911 widgetSelected(e); 912 913 } 914 915 @Override public void widgetSelected(SelectionEvent e) 916 { 917 // TODO Auto-generated method stub 918 //String sDataPath = widgetInfo.sDataPath; 919 Slider slider = (Slider)e.widget; 920 int value = slider.getSelection(); 921 //String sParam = Integer.toString(value); 922 userAction.userActionGui("sliderValue", widgetInfo, value); 923 } 924 925 } 926 927 928 @Override 929 public void setSampleCurveViewY(String sName, float[] values) { 930 GralWidget descr = indexNameWidgets(sName); 931 if(descr == null){ 932 //log.sendMsg(0, "GuiMainDialog:setSampleCurveViewY: unknown widget %s", sName); 933 } 934 935 } 936 937 938 @Override public void redrawWidget(String sName) 939 { 940 GralWidget descr = indexNameWidgets(sName); 941 if(descr == null){ 942 //log.sendMsg(0, "GuiMainDialog:setSampleCurveViewY: unknown widget %s", sName); 943 } else { 944 } 945 } 946 947 948 @Override public void resizeWidget(GralWidget widgd, int xSizeParent, int ySizeParent) 949 { 950 //GralWidget_ifc widget = widgd.getGraphicWidgetWrapper(); 951 if(widgd._wdgImpl !=null) { 952 Object owidg = widgd._wdgImpl.getWidgetImplementation(); 953 int test = 6; 954 if(owidg !=null){ 955 Control swtWidget = (Control)owidg; 956 GralPanelContent panel = widgd.pos().panel; 957 GralRectangle size = panel._wdgImpl.getPixelPositionSize(); //PixelSize(); 958 GralRectangle posSize = mng.calcWidgetPosAndSize(widgd.pos(), size.dx, size.dy, 0, 0); 959 //Note: the swtWidget may have a resizeListener, see there. 960 swtWidget.setBounds(posSize.x, posSize.y, posSize.dx, posSize.dy ); 961 swtWidget.redraw(); 962 } 963 } 964 } 965 966 967 968 969 970 @Override @Deprecated public String getValueFromWidget(GralWidget widgd) 971 { String sValue; 972 sValue = mng.getValueFromWidget(widgd); //platform independent getting of value 973 if(sValue == null){ 974 GralWidget_ifc widget = widgd; 975 Control swtWidget = (Control)widgd._wdgImpl.getWidgetImplementation(); 976 if(swtWidget instanceof Text){ 977 sValue = ((Text)swtWidget).getText(); 978 } else if(widgd instanceof GralButton){ 979 GralButton button = (GralButton)widgd; 980 sValue = button.isOn() ? "1" : "0"; 981 } else if(swtWidget instanceof Button){ 982 sValue = "0"; //TODO input.button.isSelected() ? "1" : "0"; 983 } else if(swtWidget instanceof Table){ 984 Table table = (Table)swtWidget; 985 sValue = getValueFromTable(table); 986 } else { 987 mng.log.sendMsg(0, "GuiPanelMngSwt.getValueFromWidget - unknown widget type;"); 988 sValue = ""; 989 } 990 } 991 return sValue; 992 } 993 994 995 private String getValueFromTable(Table table) 996 { StringBuilder u = new StringBuilder(); 997 int actLine = table.getSelectionIndex(); 998 TableItem item = table.getItem(actLine); 999 int nrofColumns = table.getColumnCount(); 1000 for(int iCol = 0; iCol < nrofColumns; ++iCol){ 1001 u.append(item.getText(iCol)).append('\t'); 1002 } 1003 return u.toString(); 1004 } 1005 1006 1007 1008 1009 1010 @Override public Color getColorImpl(GralColor colorGral) 1011 { return propertiesGuiSwt.colorSwt(colorGral); 1012 } 1013 1014 1015 1016 @Override public boolean showContextMenuGthread(GralWidget widg) { 1017 boolean bOk; 1018 Control swtWidg = (Control)widg._wdgImpl.getWidgetImplementation(); 1019 Menu contextMenu = swtWidg.getMenu(); 1020 if(contextMenu == null){ 1021 bOk = false; 1022 } else { 1023 //Rectangle pos = swtWidg.getBounds(); 1024 GralRectangle pos = SwtWidgetHelper.getPixelPositionSize(swtWidg); 1025 contextMenu.setLocation(pos.x + pos.dx, pos.y + pos.dy); 1026 contextMenu.setVisible(true); 1027 bOk = true; 1028 } 1029 return bOk; 1030 } 1031 1032 1033 1034 1035 1036 /**This routine is invoked on any key event. 1037 * It is possible to change keys, to disable the event handling and to call special routines. 1038 * Yet not used. 1039 */ 1040 Listener XXXX_mainKeyListener = new Listener(){ 1041 @Override public void handleEvent(Event event) { 1042 // TODO Auto-generated method stub 1043 if(userMainKeyAction() !=null 1044 && (event.keyCode & 0xffff) !=0 //don't take anything on alt- etc. alone 1045 ){ 1046 final int keyCode = SwtGralKey.convertFromSwt(event.keyCode, event.stateMask, event.character); 1047 boolean bDone = userMainKeyAction().userActionGui(keyCode, null); 1048 if(bDone){ 1049 event.type = SWT.None; 1050 //event.doit = false; //don't use this key for another action. 1051 } 1052 } 1053 stop(); 1054 } 1055 }; 1056 1057 1058 1059 1060 1061 1062 1063 /**Universal focus listener to register which widgets were in focus in its order, 1064 * to set htmlHelp and to invoke the {@link GralWidget#setActionFocused(GralUserAction)}. 1065 */ 1066 protected class SwtMngFocusListener implements FocusListener 1067 { 1068 GralMng.GralMngFocusListener gralFocus; 1069 1070 SwtMngFocusListener(GralMng mng){ 1071 gralFocus = mng.new GralMngFocusListener(); 1072 } 1073 1074 @Override public void focusLost(FocusEvent ev) 1075 { GralWidget widgg = GralWidget.ImplAccess.gralWidgetFromImplData(ev.widget.getData()); 1076 if(widgg !=null) { gralFocus.focusLostGral(widgg); } 1077 } 1078 1079 @Override public void focusGained(FocusEvent ev) 1080 { GralWidget widgg = GralWidget.ImplAccess.gralWidgetFromImplData(ev.widget.getData()); 1081 if(widgg !=null) { gralFocus.focusGainedGral(widgg); } 1082 } 1083 } 1084 1085 /**The package private universal focus listener. */ 1086 protected SwtMngFocusListener focusListener = new SwtMngFocusListener(mng); 1087 1088 1089 /**Universal context menu listener 1090 */ 1091 protected class SwtMngMouseMenuListener implements MenuDetectListener 1092 { 1093 1094 @Override 1095 public void menuDetected(MenuDetectEvent e) 1096 { 1097 // TODO Auto-generated method stub 1098 1099 } 1100 } 1101 1102 /**The package private universal focus listener. */ 1103 SwtMngMouseMenuListener mouseMenuListener = new SwtMngMouseMenuListener(); 1104 1105 1106 void stop(){} //debug helper 1107 1108 1109}