001package org.vishia.gral.base; 002 003import java.util.ArrayList; 004import java.util.LinkedList; 005import java.util.List; 006import java.util.Map; 007import java.util.TreeMap; 008 009import org.vishia.gral.ifc.GralCanvasStorage; 010import org.vishia.gral.ifc.GralMngBuild_ifc; 011import org.vishia.gral.ifc.GralRectangle; 012import org.vishia.gral.ifc.GralWidget_ifc; 013import org.vishia.util.Debugutil; 014 015 016/**This class describes a panel with its content for managing. */ 017public class GralPanelContent extends GralWidget implements GralWidget_ifc 018{ 019 020 /**Version history: 021 * 022 * <ul> 023 * <li>2018-08-17 Hartmut new: {@link #getWidget(String)}, {@link #getTextFrom(String)} 024 * <li>2016-07-16 Hartmut chg: On {@link #setToPanel(GralMngBuild_ifc)} all widgets of this panel are initialized too. More simple for user application. 025 * <li>2015-05-02 Hartmut new: {@link #setTextIn(String, CharSequence)}, change of registering a widget. Now any panel knows its widgets 026 * by name. 027 * <li>2012-07-13 Hartmut new: {@link #getPixelSize()}, chg: {@link #getPixelPositionSize()} in all implementations. 028 * A swt.widget.Shell now returns the absolute position and the real size of its client area without menu and title bar. 029 * <li>2012-04-22 Hartmut new: {@link #canvas} as property maybe null for each panel to support stored graphics. 030 * <li>2012-03-31 Hartmut new: {@link #implMethodPanel_} and {@link MethodsCalledbackFromImplementation#setVisibleState(boolean)}. 031 * <li>2012-01-14 Hartmut new: {@link #setPrimaryWidget(GralWidget)} for panel focus. 032 * <li>2012-01-08 Hartmut new: {@link #remove()} 033 * <li>2011-11-19 Hartmut chg: The 'itsTabSwt' is moved to {@link org.vishia.gral.swt.SwtPanel} now. 034 * <li>2011-11-12 Hartmut new: {@link #getPixelPositionSize()}. 035 * </ul> 036 * 037 * <b>Copyright/Copyleft</b>: 038 * For this source the LGPL Lesser General Public License, 039 * published by the Free Software Foundation is valid. 040 * It means: 041 * <ol> 042 * <li> You can use this source without any restriction for any desired purpose. 043 * <li> You can redistribute copies of this source to everybody. 044 * <li> Every user of this source, also the user of redistribute copies 045 * with or without payment, must accept this license for further using. 046 * <li> But the LPGL ist not appropriate for a whole software product, 047 * if this source is only a part of them. It means, the user 048 * must publish this part of source, 049 * but don't need to publish the whole source of the own product. 050 * <li> You can study and modify (improve) this source 051 * for own using or for redistribution, but you have to license the 052 * modified sources likewise under this LGPL Lesser General Public License. 053 * You mustn't delete this Copyright/Copyleft inscription in this source file. 054 * </ol> 055 * If you are intent to use this sources without publishing its usage, you can get 056 * a second license subscribing a special contract with the author. 057 * 058 * @author Hartmut Schorrig = hartmut.schorrig@vishia.de 059 */ 060 @SuppressWarnings("hiding") 061 public final static int version = 20120713; 062 063 //public GralPrimaryWindow_ifc mainWindow; 064 065 //public final GralMng gralMng; 066 067 068 /**The widget which should be focused if the panel is focused. 069 * It is possible to set any actual widget to store the focus situation, 070 * It is possible too to have only one widget to focus. if the panel gets the focus. */ 071 protected GralWidget primaryWidget; 072 073 /**List of all widgets which are contained in this panel or Window, to refresh the graphic. 074 * This list is used in the communication thread to update the content of all widgets in the panel. 075 */ 076 //private List<GralWidget> _wdgList = new ArrayList<GralWidget>(); 077 078 /**List of all widgets which are contained in this panel. 079 * This list is used in the communication thread to update the content of all widgets in the panel. 080 */ 081 protected List<GralWidget> widgetList = new ArrayList<GralWidget>(); 082 083 public List<GralWidget> widgetsToResize = new LinkedList<GralWidget>(); 084 085 private final Map<String, GralWidget> idxWidgets = new TreeMap<String, GralWidget>(); 086 087 /**True then the content of the panel is zoomed with the actual size of panel. 088 * It means that all widgets are zoomed in position and size, but there content isn't changed. */ 089 protected boolean bZoomed; 090 091 /**True then the grid of the panel is zoomed with the actual size of panel. 092 * It means that all fonts are changed too. 093 * */ 094 protected boolean bGridZoomed; 095 096 097 /**If this instance is not null, the content of that should be paint in the paint routine 098 * of the implementation graphic. */ 099 public GralCanvasStorage canvas; 100 101 102 @Deprecated public GralPanelContent(String namePanel, GralMng mng, Object panelComposite) 103 //public PanelContent(CanvasStorePanel panelComposite) 104 { super(namePanel, '$'); 105 this.name = namePanel; 106 //this.panelComposite = panelComposite; 107 //GralMng mng = GralMng.get(); 108 mng.registerPanel(this); 109 if( pos()!=null) { 110 mng.setPosPanel(this); 111 } 112 int property = 0; //TODO parameter 113 bZoomed = (property & GralMngBuild_ifc.propZoomedPanel) !=0; 114 bGridZoomed = (property & GralMngBuild_ifc.propGridZoomedPanel) !=0; 115 } 116 117 118 119 /**Create a panel, registers it and sets the {@link GralMng#pos()} of this thread to the panel. */ 120 public GralPanelContent(String posString, String namePanel) 121 { this(posString, namePanel, '$'); 122 } 123 124 /**Create a panel, registers it and sets the {@link GralMng#pos()} of this thread to the panel. */ 125 public GralPanelContent(String posString, String namePanel, char whatIsit) 126 //public PanelContent(CanvasStorePanel panelComposite) 127 { super(posString, namePanel, whatIsit); 128 this.name = namePanel; 129 GralMng mng = GralMng.get(); 130 mng.registerPanel(this); 131 if( pos()!=null) { 132 mng.setPosPanel(this); 133 } 134 int property = 0; //TODO parameter 135 bZoomed = (property & GralMngBuild_ifc.propZoomedPanel) !=0; 136 bGridZoomed = (property & GralMngBuild_ifc.propGridZoomedPanel) !=0; 137 } 138 /* 139 private GralPanelContent(String namePanel, GralPrimaryWindow_ifc mainWindow) 140 { super(namePanel, '$', null); 141 this.namePanel = namePanel; this.gralMng = null; //mainWindow.; 142 } 143 144 145 private GralPanelContent(String namePanel, GralWidgetMng mng) 146 { super(namePanel, '$', mng); 147 this.namePanel = namePanel; this.gralMng = mng; 148 } 149 */ 150 151 152 153 public void setPrimaryWidget(GralWidget widg){ primaryWidget = widg; } 154 155 156 /*package private*/ 157 /**Adds a widget to its panel. This method will be called in {@link GralWidget#initPosAndRegisterWidget(GralPos)} 158 * either on creation the GralWidget with a given position String or on {@link GralWidget#setToPanel(GralMngBuild_ifc)} 159 * with the given currently {@link GralMng#pos()}. 160 * @param widg 161 * @param toResize 162 */ 163 void addWidget(GralWidget widg, boolean toResize){ 164 String nameWidg = widg.name; 165 if(widg instanceof GralWindow) 166 Debugutil.stop(); 167 if(nameWidg !=null) { 168 String nameGlobal; 169 if(nameWidg.startsWith("@")) { 170 nameWidg = nameWidg.substring(1); //without @ 171 nameGlobal = super.name + "." + nameWidg; //panel.widget 172 } else { 173 nameGlobal = nameWidg; 174 } 175 itsMng.registerWidget(nameGlobal, widg); 176 idxWidgets.put(nameWidg, widg); 177 } 178 if(widgetList.remove(widg)){ 179 System.err.println("Widget added twice; " + nameWidg); 180 } 181 widgetList.add(widg); 182 if(toResize) { 183 if(widg instanceof GralWindow) { 184 System.err.println("GralPanelContent.addWidget - A window itself should not be added to widgetsToResize, " + widg.name); 185 } else { 186 widgetsToResize.add(widg); 187 } 188 } 189 if(primaryWidget ==null && !(widg instanceof GralPanelContent)) { //register only a non-panel widget as primary - for the panel or window. 190 primaryWidget = widg; 191 } 192 } 193 194 195 196 /**Overridden implementation of {@link GralWidget#createImplWidget_Gthread()} for instantiation of all widgets of this panel. 197 */ 198 @Override public void createImplWidget_Gthread() throws IllegalStateException { 199 super.createImplWidget_Gthread(); //from GralWidget. 200 for(GralWidget widg: widgetList) { 201 widg.createImplWidget_Gthread(); 202 } 203 } 204 205 /**Removes this widget from the lists in this panel. This method is not intent to invoke 206 * by an application. It is only used in {@link GralWidget#remove()}. Use the last one method 207 * to remove a widget includint is disposition and remove from the panel. 208 * @param widg The widget. 209 */ 210 public void removeWidget(GralWidget widg) 211 { String nameWidg = widg.name; 212 if(nameWidg !=null) { 213 String nameGlobal; 214 if(nameWidg.startsWith("@")) { 215 nameWidg = nameWidg.substring(1); //without @ 216 nameGlobal = super.name + "." + nameWidg; //panel.widget 217 } else { 218 nameGlobal = nameWidg; 219 } 220 itsMng.removeWidget(nameGlobal); 221 idxWidgets.remove(nameWidg); 222 } 223 224 widgetList.remove(widg); 225 widgetsToResize.remove(widg); 226 227 } 228 229 /**This overridden form of {@link GralWidget_ifc#remove()} removes all widgets of this panel. 230 * It includes the disposition of the widgets in the graphic. It is done by invocation 231 * {@link GralWidget#remove()}. 232 * @return true because it is done. 233 */ 234 @Override public boolean remove(){ 235 int catastrophicCt = 100000; //safety of all while loops! No more than 100000 widgets. 236 while(--catastrophicCt >=0 && widgetList.size() >0){ 237 //remove all widgets from the panel via Widget.remove, it removes it from this list too. 238 widgetList.get(0).remove(); 239 } 240 assert(catastrophicCt >0); 241 widgetList.clear(); //the lists may be cleared already 242 widgetsToResize.clear(); //because widg.remove() removes the widget from the panel. 243 super.remove(); 244 return true; 245 } 246 247 248 249 250 251 252 /** 253 * @deprecated use {@link #getWidgetList()} 254 */ 255 @Deprecated public List<GralWidget> widgetList(){ return widgetList; } 256 257 public List<GralWidget> getWidgetList(){ return widgetList; } 258 259 /**Gets a named widget on this panel. Returns null if faulty name. 260 * @since 2018-09 261 */ 262 public GralWidget getWidget(String name){ return idxWidgets.get(name); } 263 264 265 266 267 /**Sets the text to the named widget 268 * @param nameWidget the registered widget in its panel. 269 * @param text The text to set. 270 * @throws IllegalArgumentException on faulty widget name 271 * @since 2015-05-02 272 */ 273 public void setTextIn(String nameWidget, CharSequence text) { 274 GralWidget widg = idxWidgets.get(nameWidget); 275 if(widg == null) throw new IllegalArgumentException("GralPanel - Widget not found, " + nameWidget); 276 widg.setText(text); 277 } 278 279 280 281 /**Gets the text from the named widget 282 * @param nameWidget the registered widget in its panel. 283 * @param text The text to set. 284 * @throws IllegalArgumentException on faulty widget name 285 * @since 2015-05-02 286 */ 287 public String getTextFrom(String nameWidget) { 288 GralWidget widg = idxWidgets.get(nameWidget); 289 if(widg == null) throw new IllegalArgumentException("GralPanel - Widget not found, " + nameWidget); 290 return widg.getText(); 291 } 292 293 294 295 296 297 298 /**Sets the focus to the primary widget if it is set. 299 * Elsewhere do nothing and returns false. 300 * The focus may be set then by the inherit implementation class. 301 * <br>See {@link #setPrimaryWidget(GralWidget)}. 302 * @return true if the focus is set to the primary widget. 303 */ 304 //@Override 305 public boolean XXXsetFocusGThread() 306 { 307 if(primaryWidget !=null) { 308 //invokes the setFocus routine to mark focus in table etc. 309 primaryWidget.setFocus(); //invokes setFocusGThread because it is the graphic thread. 310 return true; //TODO check focus 311 //return primaryWidget.setFocusGThread(); 312 } 313 else return false; 314 } 315 316 /**Use GralWidet._wdgImpl.getWidgetImplementation() internally! Not public. 317 * @return 318 */ 319 @Deprecated public Object getWidgetImplementation() 320 { return _wdgImpl.getWidgetImplementation(); //panelComposite; 321 } 322 323 324 /**Returns the container instance of the panel of the implementing graphic. 325 * @return The container. 326 */ 327 //public abstract Object getPanelImpl(); 328 329 330 331 @Override public String toString(){ return "GralPanel:" + name; } 332 333 334 335 /**This inner class contains methods which can call by the implementation layer. 336 * That methods are not intent to be called by the application. 337 * It is public because the implementation level in another package should accesses it. 338 */ 339 public abstract static class MethodsCalledbackFromImplementation 340 extends GralWidget.ImplAccess 341 { 342 343 private final GralPanelContent panelg; 344 345 MethodsCalledbackFromImplementation(GralPanelContent panelg, GralMng mng){ 346 super(panelg, mng); 347 this.panelg = panelg; 348 } 349 @Override public void setVisibleState(boolean visible){ 350 for(GralWidget widget: panelg.widgetList){ 351 widget.setVisibleState(visible); 352 } 353 } 354 } //class MethodsCalledbackFromImplementation 355 356 /**This reference is a inner class which contains methods which can call by the implementation layer. 357 * That methods are not intent to be called by the application. 358 * It is public because the implementation level in another package should accesses it. 359 */ 360 //public MethodsCalledbackFromImplementation implMethodPanel_ = new MethodsCalledbackFromImplementation(this); 361 362 /**Sets the visible state to all widgets of the panel, but not to windows (that is only in the primaryWindow) 363 * @see org.vishia.gral.base.GralWidget#setVisibleState(boolean) 364 */ 365 @Override public void setVisibleState(boolean visible){ 366 if(isVisible() != visible) { 367 //only invoke for all sub widgets when the visible state of the parent is changed. Otherwise do nothing - nothing is changed, no effort. 368 //for tabbed panels etc. it is specially processed 369 super.setVisibleStateWidget(visible); //for the own panel 370 for(GralWidget widget: widgetList){ 371 if(widget != this && !(widget instanceof GralWindow)) { 372 widget.setVisibleState(visible); 373 } 374 } 375 } 376 } 377 378 379 public abstract static class ImplAccess extends GralWidget.ImplAccess 380 { 381 382 /**Same reference as {@link GralWidget.ImplAccess#widgg} but type of this class. */ 383 //GralPanelContent gralPanel; 384 385 protected ImplAccess(GralPanelContent widgg) 386 { 387 super(widgg); 388 //for all following actions: this is the current panel. 389 GralMng mng = GralMng.get(); 390 mng.setPosPanel((GralPanelContent)widgg); 391 } 392 393 public GralPanelContent gralPanel(){ return (GralPanelContent) widgg; } //It is the correct type. 394 395 /**Returns the absolute position of this panel on screen and its size. 396 * If it is a main window, the useable area of the window without title and menu bar is returned. 397 * @return 398 */ 399 @Override 400 public abstract GralRectangle getPixelPositionSize(); 401 402 403 404 /**Returns the size of this panel in pixel. 405 * @return the x and y is 0, the dy and dy is the size. 406 */ 407 public abstract GralRectangle getPixelSize(); 408 409 410 411 } 412 413} 414