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}