001package org.vishia.gral.area9; 002 003import java.io.File; 004import java.io.IOException; 005import java.util.Queue; 006import java.util.concurrent.ConcurrentLinkedQueue; 007 008import org.vishia.gral.base.GralGraphicTimeOrder; 009import org.vishia.gral.base.GralMenu; 010import org.vishia.gral.base.GralPanelContent; 011import org.vishia.gral.base.GralPos; 012import org.vishia.gral.base.GralWidget; 013import org.vishia.gral.base.GralWindow; 014import org.vishia.gral.base.GralMng; 015import org.vishia.gral.base.GralTextBox; 016import org.vishia.gral.ifc.GralFileDialog_ifc; 017import org.vishia.gral.ifc.GralPrimaryWindow_ifc; 018import org.vishia.gral.ifc.GralRectangle; 019import org.vishia.gral.ifc.GralUserAction; 020import org.vishia.gral.ifc.GralTextBox_ifc; 021import org.vishia.gral.ifc.GralWindow_ifc; 022import org.vishia.gral.widget.GralInfoBox; 023import org.vishia.mainCmd.MainCmd; 024import org.vishia.mainCmd.MainCmd_ifc; 025import org.vishia.util.FileSystem; 026 027/**This class presents a Window appearance with up to 9 areas as base for a user's application with several areas 028 * of the main window and some sub windows. 029 * The areas of the window can be used in several forms: 030 * <pre> 031 * +================================================================================+ 032 * | | | + 033 * | | | + 034 * | | | + 035 * | | central working area | other + 036 * | any | | list + 037 * | list | | + 038 * | | | + 039 * | | | + 040 * | +---------------------------------------------------------------+ 041 * | | + 042 * | | status or output area + 043 * | | + 044 * | | + 045 * +================================================================================+ 046 * 047 * +================================================================================+ 048 * | | + 049 * | | + 050 * | | + 051 * | | central working area + 052 * | any | + 053 * | list | + 054 * | | + 055 * | | + 056 * | | + 057 * | | + 058 * |--------------------------------------------------------------------------------+ 059 * | status line + 060 * +================================================================================+ 061 * 062 * +================================================================================+ 063 * | | | + 064 * | | one | other + 065 * | any | panel | panel + 066 * | list | | + 067 * | | | + 068 * | | | + 069 * |----------------+---------------------------+-----------------------------------+ 070 * | + 071 * | input area + 072 * |----------------+---------------------------------------------------------------+ 073 * | | + 074 * | info | status or output area + 075 * | area | + 076 * | | + 077 * +================================================================================+ 078 * </pre> 079 * or any other partitioning. 080 * <br><br> 081 * The main window has a menu bar which has some default entries: 082 * <br><br> 083 * The following sub windows are created: 084 * <ul> 085 * <li>{@link #infoHelp}: Window will be opened with key [F1] or menu help. initially call {@link #setHelpBase(String)}, 086 * then call {@link #setHelpUrl(String)} respectively set {@link GralWidget#setHtmlHelp(String)} for any widget. 087 * <li>{@link #infoBox}: Window will be opened via menu or on demand if anything should be shown. Fill it with 088 * infoBox. {@link GralInfoBox#setText(CharSequence)}, {@link GralInfoBox#setText(CharSequence, int)} or 089 * {@link GralInfoBox#append(CharSequence)}. The info box should be used for on demand. it will be overridden 090 * and reused if necessary later. 091 * <li>{@link #infoLog}: Window will be opened via menu or on demand if anything should be shown. Fill it with 092 * infoLog.{@link GralInfoBox#append(CharSequence)}. 093 * <li>{@link #infoAbout}: Window will be opened with menu about. This box will be filled given with the content from 094 * {@link #mainCmd}. {@link MainCmd#addAboutInfo(String)} from the given MainCmd instance for {@link GralArea9Window#GralArea9Window(MainCmd, GralWindow)}. 095 * </ul> 096 * 097 * @author hartmut 098 * 099 */ 100public class GralArea9Window implements GralArea9_ifc 101{ 102 103 /**Version and History 104 * <ul> 105 * <li>2015-10-26 Hartmut chg Help in now an integral part of the {@link GralMng}, but invoked here. This class in not change in functinality. 106 * <li>2014-02-24 Hartmut new {@link #setHelpBase(String)} used in {@link #setHelpUrl(String)}. 107 * <li>2012-05-17 Hartmut new: {@link #setMinMaxSizeArea(String, int, int, int, int)}: The size can be given 108 * with gral units, as min, max or absolute (min, max are equal). The size of a area border can be changed on runtime. 109 * <li>2012-04-22 Hartmut new: {@link #setFullScreen(boolean)} 110 * <li>2011-12-26 Hartmut chg: The help window is a html info box now. New method {@link #setHelpUrl(String)} 111 * supports context sensitive help. 112 * <li>2011-11-12 Hartmut new: The SubWindow for Help, About, InfoBox and InfoLog are created here (InfoLog: TODO). 113 * This windows can be opened in demand. 114 * <li>2011-11-12 Hartmut chg: All menu items should be prepared in the users application now. The items for help and about 115 * are supported with actions by {@link #getActionAbout()} and {@link #getActionAbout()}. This actions 116 * are the standard behavior and opens the sub-windows only. But the user can install a more complex functionality 117 * for example writing a context sensitive help. 118 * <li>2011-11-12 Harmut chg {@link #initGraphic} was the old initOutputArea, but it does more as only the output area. 119 * Now creation of all necessities of Graphic in this functionality. 120 * 121 * </ul> 122 * 123 * <b>Copyright/Copyleft</b>: 124 * For this source the LGPL Lesser General Public License, 125 * published by the Free Software Foundation is valid. 126 * It means: 127 * <ol> 128 * <li> You can use this source without any restriction for any desired purpose. 129 * <li> You can redistribute copies of this source to everybody. 130 * <li> Every user of this source, also the user of redistribute copies 131 * with or without payment, must accept this license for further using. 132 * <li> But the LPGL ist not appropriate for a whole software product, 133 * if this source is only a part of them. It means, the user 134 * must publish this part of source, 135 * but don't need to publish the whole source of the own product. 136 * <li> You can study and modify (improve) this source 137 * for own using or for redistribution, but you have to license the 138 * modified sources likewise under this LGPL Lesser General Public License. 139 * You mustn't delete this Copyright/Copyleft inscription in this source file. 140 * </ol> 141 * If you are indent to use this sources without publishing its usage, you can get 142 * a second license subscribing a special contract with the author. 143 * 144 * @author Hartmut Schorrig = hartmut.schorrig@vishia.de 145 * 146 * 147 */ 148 public final static int version = 0x20120303; 149 150 public final MainCmd mainCmd; 151 152 //protected final GralWindowMng gralDevice; 153 154 protected final GralWindow window; 155 156 /**Area settings for output. */ 157 protected String outputArea; 158 159 protected GralPanelContent outputPanel; 160 161 /**A Text box which is used for common output. It may be edit-able. 162 * This output box is created initially. It can be used to show error messages while starting the application 163 * if other GUI-elements are not yet present. It can be used generally to show errors, infos and logs 164 * adequate to a console output.*/ 165 public GralTextBox outputBox; 166 167 168 private GralInfoBox infoAbout; 169 170 /** Current Directory for file choosing. */ 171 protected File currentDirectory = null; 172 173 protected GralUserAction actionFile; 174 175 /**Set on call of {@link #setStandardMenus(File)} to add in in the graphic thread. */ 176 protected boolean bSetStandardMenus; 177 178 protected Queue<String> outputTexts = new ConcurrentLinkedQueue<String>(); 179 180 181 /**All main components of the Display in each FrameArea. */ 182 protected GralPanelContent[][] componentFrameArea = new GralPanelContent[3][3]; 183 184 185 /**A little control to capture the mouse position for movement of area borders. */ 186 //private GralWidgetImplWrapper[] yAreaMover = new GralWidgetImplWrapper[2]; 187 188 189 190 /**Position of the FrameArea borders in percent. 191 * [0] is always 0, [1] and [2] are the given borders, [3] is always 100. 192 * It is because lower and higher bound should be accessed always without tests. 193 * Use area +1, because it is a Off-by-one problem */ 194 protected byte xpFrameArea[] = new byte[4], 195 ypFrameArea[] = new byte[4]; 196 197 /**spread of each frame area in x direction. 198 * It it is -1, than the area is occupied by another area. 199 * If it is 0, the area is free. 200 * 1..3 are the number of areas in horizontal direction. 201 */ 202 protected byte[][][] dxyFrameArea = new byte[3][3][2]; 203 204 /**requested minimal size of each window area in GralPos units. If the minimal value is 0, 205 * the size is calculated from percent always. If the minimal value of percent calculation is lesser 206 * than this value, this value is used. Note that a given minimal value of all areas cannot required 207 * if the window's size is lesser. Then the middle area will 208 */ 209 private final short[] xMinGralSize = new short[3], yMinGralSize = new short[3]; 210 211 /**requested maximal size of each window area in GralPos units. If the maximal value is greater than 212 * the size calculated from percent always, the percent value is used. 213 * Note that a given maximal value of all areas cannot regarded 214 * if the window's size is greater. Then the middle area will be presented 215 */ 216 private final short[] xMaxGralSize = new short[3], yMaxGralSize = new short[3]; 217 218 /**Calculated borders of areas. 219 * [0] is always 0, [1] and [2] are the given borders, [3] is always 100. 220 * It is because lower and higher bound should be accessed always without tests. 221 * Use area +1, because it is a Off-by-one problem */ 222 private final int[] xPixArea = new int[4], yPixArea = new int[4]; 223 224 /**Number of pixels per percent unit of size, set if {@link #validateFrameAreas()} was called. */ 225 protected float pixelPerXpercent = 1, pixelPerYpercent =1; 226 227 /** The interface to the application. */ 228 //private final MainApplicationWin_ifc application; 229 230 /**The id of the thread, which created the display. 231 * It is to check whether gui-commands should be queued or not. */ 232 //protected long idThreadGui; 233 234 final protected StringBuffer XXXsbWriteInfo = new StringBuffer(1000); //max. 1 line! 235 236 /** If it is set, the writeInfo is redirected to this.*/ 237 protected GralTextBox_ifc textAreaOutput = null; 238 239 240 /**Sets the output window to a defined area. . 241 * Adds the edit-menu too. 242 * @param xArea 1 to 3 for left, middle, right, See {@link #setFrameAreaBorders(int, int, int, int)} 243 * @param yArea 1 to 3 for top, middle, bottom 244 * @param dxArea 1 to 3 for 1 field to 3 fields to right. 245 * @param dyArea 1 to 3 for 1 field to 3 field to bottom 246 */ 247 public void XXXsetOutputArea(String area){ 248 outputArea = area; 249 } 250 251 //private GuiMainAreaBase(MainCmd mainCmd){ this.mainCmd = mainCmd; } 252 253 /** 254 * @param mainCmd Aggregation to a MainCmd implemenation. 255 * @param guiDevice The window manager 256 * @param window The window itself. It doesn't be the primary window but a sub window too. 257 */ 258 public GralArea9Window(MainCmd mainCmd, GralWindow window) 259 { 260 super(); 261 this.mainCmd = mainCmd; 262 //this.gralDevice = guiDevice; 263 this.window = window; 264 for(int ix = 0; ix < 3; ++ix) for(int iy = 0; iy < 3; ++iy){ 265 xMinGralSize[ix] = 4; 266 yMinGralSize[iy] = 4; 267 xMaxGralSize[ix] = Short.MAX_VALUE; 268 yMaxGralSize[iy] = Short.MAX_VALUE; 269 } 270 } 271 272 273 /**Initializes the output area, can be called after construction immediately. 274 * @param sOutputArea String for example "A3C3". The letter character is the column. The digit is the row. 275 * It is fromTo. The example means the whole bottom area. 276 */ 277 @Override public void initGraphic(String sOutputArea){ 278 this.outputArea = sOutputArea; 279 window.gralMng().gralDevice.addDispatchOrder(initGraphic); 280 initGraphic.awaitExecution(1, 0); 281 window.gralMng().gralDevice.addDispatchOrder(writeOutputTextDirectly); 282 283 } 284 285 286 287 GralGraphicTimeOrder initGraphic = new GralGraphicTimeOrder("GralArea9Window.initGraphic"){ 288 @Override public void executeOrder() 289 { 290 window.setResizeAction(resizeAction); //sets the resize action from this instead a standard window for the primaryWindow. 291 setFrameAreaBorders(30,70,30,70); 292 if(bSetStandardMenus){ 293 //setStandardMenusGThread(currentDirectory, actionFile); 294 } 295 GralMng.get().createHtmlInfoBoxes(mainCmd); 296 // 297 window.gralMng().selectPanel("primaryWindow"); 298 window.gralMng().setPosition(0,20,15,GralPos.size + 50,0,'.'); 299 infoAbout = window.gralMng().createTextInfoBox("About", "About"); 300 try{ 301 for(String line: mainCmd.listAboutInfo){ 302 infoAbout.append(line).append("\n"); 303 } 304 } catch(Exception exc){ window.gralMng().writeLog(0, exc); } 305 // 306 307 308 if(outputArea != null){ 309 outputPanel = addOutputFrameArea(outputArea); 310 //window.gralMng().registerPanel(outputPanel); 311 } 312 } 313 }; 314 315 316 317 @Override public MainCmd_ifc getMainCmd(){ return mainCmd; } 318 319 @Override public GralWindow_ifc mainWindow(){ return window; } 320 321 @Override public GralPanelContent getOutputPanel(){ return outputPanel; } /// 322 323 @Override public GralTextBox getOutputBox(){ return outputBox; } 324 325 326 327 328 /**Sets the divisions of the frame. The frame is divide into 9 parts, 329 * where two horizontal and two vertical lines built them: 330 * <pre> 331 * +=======+===============+===========+ 332 * | | | | 333 * +-------+---------------+-----------+ 334 * | | | | 335 * | | | | 336 * +-------+---------------+-----------+ 337 * | | | | 338 * | | | | 339 * +=======+===============+===========+ 340 * </pre> 341 * 342 * @param x1p percent from left for first vertical divide line. 343 * @param x2p percent from left for second vertical divide line. 344 * @param y1p percent from left for first horizontal divide line. 345 * @param y2p percent from left for first horizontal divide line. 346 */ 347 @Override public void setFrameAreaBorders(int x1p, int x2p, int y1p, int y2p) 348 { xpFrameArea[0] = 0; 349 xpFrameArea[1] = (byte)x1p; 350 xpFrameArea[2] = (byte)x2p; 351 xpFrameArea[3] = 100; 352 ypFrameArea[0] = 0; 353 ypFrameArea[1] = (byte)y1p; 354 ypFrameArea[2] = (byte)y2p; 355 ypFrameArea[3] = 100; 356 validateFrameAreas(); 357 } 358 359 360 361 362 @Override public void addFrameArea(String sArea, GralPanelContent component) 363 throws IndexOutOfBoundsException { 364 GralRectangle r = convertArea(sArea); 365 addFrameArea(r.x, r.y, r.dx, r.dy, component); 366 } 367 368 369 /**Sets a Component into a defined area. See {@link #setFrameAreaBorders(int, int, int, int)}. 370 * It should be called only in the GUI-Thread. 371 * @param xArea 1 to 3 for left, middle, right 372 * @param yArea 1 to 3 for top, middle, bottom 373 * @param dxArea 1 to 3 for 1 field to 3 fields to right. 374 * @param dyArea 1 to 3 for 1 field to 3 field to bottom 375 * @param component The component. 376 * @throws IndexOutOfBoundsException if the arguments are false or the area is occupied already. 377 */ 378 @Override public final void addFrameArea(int xArea, int yArea, int dxArea, int dyArea, GralPanelContent component) 379 throws IndexOutOfBoundsException 380 { //int idxArea = (x -1) + 3 * (y -1); 381 //Composite component = new Composite(swtWindow.graphicThreadSwt, SWT.NONE); 382 if( xArea <1 || xArea > componentFrameArea[0].length 383 || dxArea < 1 384 || xArea+dxArea-2 > componentFrameArea[0].length 385 || yArea <1 || yArea > componentFrameArea.length 386 || dyArea < 1 387 || yArea+dyArea-1 > componentFrameArea.length 388 ) 389 throw new IndexOutOfBoundsException("failed argument"); 390 for(int idxArea = xArea-1; idxArea <= xArea + dxArea -2; idxArea++) 391 { for(int idyArea = yArea-1; idyArea <= yArea + dyArea -2; idyArea++) 392 { if(dxyFrameArea[idyArea][idxArea][0] != 0) throw new IndexOutOfBoundsException("area occupied already"); 393 } 394 } 395 for(int idxArea = xArea-1; idxArea <= xArea + dxArea -2; idxArea++) 396 { for(int idyArea = yArea-1; idyArea <= yArea + dyArea -2; idyArea++) 397 { dxyFrameArea[idyArea][idxArea][0] = -1; //ocuupy it. 398 } 399 } 400 dxyFrameArea[yArea-1][xArea-1][0] = (byte)dxArea; 401 dxyFrameArea[yArea-1][xArea-1][1] = (byte)dyArea; 402 //JScrollPane scrollPane = new JScrollPane(component); 403 //scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); 404 //scrollPane.setViewportView(component); 405 componentFrameArea[yArea-1][xArea-1] = component; //scrollPane; 406 //setBoundsForFrameArea(xArea-1, yArea-1); 407 //scrollPane.validate(); 408 //swtWindow.graphicThreadSwt.add(component); //scrollPane); 409 /*TODO 410 ((Control)component.getWidgetImplementation()).addMouseListener(mouseListener); 411 if(yAreaMover[1] == null){ 412 yAreaMover[1] = new Canvas(swtWindow.graphicThreadSwt.windowSwt, SWT.None); 413 yAreaMover[1].setSize(10,10); 414 yAreaMover[1].setBackground(swtWindow.graphicThreadSwt.displaySwt.getSystemColor(SWT.COLOR_GREEN)); 415 } 416 */ 417 validateFrameAreas(); 418 //return component; 419 } 420 421 422 423 @Override public void setMinMaxSizeArea(String sArea, int yMinUnit, int yMaxUnit, int xMinUnit, int xMaxUnit) 424 throws IndexOutOfBoundsException { 425 GralRectangle r = convertArea(sArea); 426 yMinGralSize[r.y -1] = (short)yMinUnit; 427 yMaxGralSize[r.y -1] = yMaxUnit <=0 ? Short.MAX_VALUE : (short)yMaxUnit; 428 xMinGralSize[r.x -1] = (short)xMinUnit; 429 xMaxGralSize[r.x -1] = xMaxUnit <=0 ? Short.MAX_VALUE : (short)xMaxUnit; 430 431 validateFrameAreas(); 432 } 433 434 435 436 437 /**Set the bounds of all areas. 438 * Calls {@link GralWindow#getPixelPositionSize()} to get the size of working area of the whole window 439 * 440 */ 441 protected void validateFrameAreas() 442 { 443 GralRectangle posSize = window.getPixelPositionSize(); 444 //Point size = swtWindow.graphicThreadSwt.windowSwt.getSize(); 445 int xWidth = posSize.dx; // -6; //swtWindow.graphicThreadSwt.getWidth(); 446 int yWidth = posSize.dy; // -50; //swtWindow.graphicThreadSwt.getHeight() - 50; //height of title and menu TODO calculate correctly 447 //Control content = swtWindow.graphicThreadSwt.getContentPane(); 448 //xWidth = content.getWidth(); 449 //yWidth = content.getHeight(); 450 pixelPerXpercent = xWidth / 100.0F; 451 pixelPerYpercent = yWidth / 100.0F; 452 453 int xPixUnit = window.gralMng().propertiesGui().xPixelUnit(); 454 int yPixUnit = window.gralMng().propertiesGui().yPixelUnit(); 455 pixelPerXpercent = xWidth / 100.0F; 456 pixelPerYpercent = yWidth / 100.0F; 457 458 calcPixSize(xPixArea, xpFrameArea, xMinGralSize, xMaxGralSize, xPixUnit, xWidth, pixelPerXpercent); 459 calcPixSize(yPixArea, ypFrameArea, yMinGralSize, yMaxGralSize, yPixUnit, yWidth, pixelPerYpercent); 460 461 for(int idxArea = 0; idxArea <= 2; idxArea++) 462 { for(int idyArea = 0; idyArea <= 2; idyArea++) 463 { GralPanelContent component = componentFrameArea[idyArea][idxArea]; 464 if(component !=null) 465 { //setBoundsForFrameArea(idxArea, idyArea); 466 int xp = xPixArea[idxArea]; 467 int dxf = dxyFrameArea[idyArea][idxArea][0]; //nr of occupied areas 468 int xf2 = xPixArea[idxArea + dxf]; //percent right 469 int dxp = xf2 - xp; 470 471 int yp = yPixArea[idyArea]; 472 int dyf = dxyFrameArea[idyArea][idxArea][1]; 473 int yf2 = yPixArea[idyArea + dyf]; 474 int dyp = yf2 - yp; 475 GralPanelContent area = componentFrameArea[idyArea][idxArea]; 476 area.setBoundsPixel(xp, yp, dxp, dyp); 477 area.repaint(); 478 } } } 479 /* 480 for(int ixMover = 0; ixMover < yAreaMover.length; ++ixMover){ 481 if(yAreaMover[ixMover] != null){ 482 int yp = (int)(ypFrameArea[ixMover+1] * pixelPerYpercent); 483 //TODO it doesn't work yet, not visible, why?: 484 /* 485 yAreaMover[ixMover].setBounds(10,yp,10,10); 486 yAreaMover[ixMover].update(); 487 yAreaMover[ixMover].redraw(); 488 * / 489 } 490 } 491 */ 492 //swtWindow.graphicThreadSwt.update(); 493 //swtWindow.graphicThreadSwt.redraw(); 494 //swtWindow.graphicThreadSwt.update(); 495 496 } 497 498 499 500 private void calcPixSize(int[] zPixArea, byte[] zpFrameArea, short[] zMinGralSize, short[] zMaxGralSize 501 , int zPixUnit, int zSize, float pixelPerZpercent){ 502 int zMinWin = zMinGralSize[0] + zMinGralSize[1] + zMinGralSize[2]; 503 zPixArea[0] = 0; 504 if(zSize >= (zPixUnit * zMinWin)){ 505 int zPix = 0; 506 for(int iz=1; iz < 4; ++iz){ 507 int zPix2 = (int)(zpFrameArea[iz] * pixelPerZpercent); 508 if((zPix2 - zPix) > (zMaxGralSize[iz-1] * zPixUnit)){ 509 zPix2 = zPix + zMaxGralSize[iz-1] * zPixUnit; 510 } 511 else if((zPix2 - zPix) < (zMinGralSize[iz-1] * zPixUnit)){ 512 zPix2 = zPix + zMinGralSize[iz-1] * zPixUnit; 513 } 514 zPixArea[iz] = zPix = zPix2; 515 } 516 if(zPixArea[3] < zSize){ 517 zPixArea[3] = zPix = zSize; 518 for(int iz=2; iz >=0; --iz){ 519 if(zPix - zPixArea[iz] > zMaxGralSize[iz] * zPixUnit){ 520 zPixArea[iz] = zPix - zMaxGralSize[iz] * zPixUnit; 521 } 522 zPix = zPixArea[iz]; 523 } 524 } else if(zPixArea[3] > zSize){ 525 zPixArea[3] = zPix = zSize; 526 for(int iz=2; iz >=0; --iz){ 527 if(zPix - zPixArea[iz] < zMinGralSize[iz] * zPixUnit){ 528 zPixArea[iz] = zPix - zMinGralSize[iz] * zPixUnit; 529 } 530 zPix = zPixArea[iz]; 531 } 532 } 533 } else { //the window is less than the minimal area sizes: 534 //then the percent are valid, lesser as planned 535 for(int iz=0; iz < 3; ++iz){ 536 zPixArea[iz] = (int)(zpFrameArea[iz] * pixelPerZpercent); 537 } 538 } 539 540 } 541 542 543 544 545 546 547 548 /**Sets the bounds for the component, which is localized at the given area. 549 * @param idxArea 550 * @param idyArea 551 */ 552 private void setBoundsForFrameArea(int idxArea, int idyArea) 553 { //Point size = swtWindow.graphicThreadSwt.windowSwt.getSize(); 554 GralRectangle posSize = window.getPixelPositionSize(); 555 int xWidth = posSize.dx -6; //swtWindow.graphicThreadSwt.getWidth(); 556 int yWidth = posSize.dy -53; //swtWindow.graphicThreadSwt.getHeight() - 50; //height of title and menu TODO calculate correctly 557 //Control content = swtWindow.graphicThreadSwt.getContentPane(); 558 //xWidth = content.getWidth(); 559 //yWidth = content.getHeight(); 560 pixelPerXpercent = xWidth / 100.0F; 561 pixelPerYpercent = yWidth / 100.0F; 562 int xf1 = xpFrameArea[idxArea]; //percent left 563 int yf1 = ypFrameArea[idyArea]; 564 int dxf = dxyFrameArea[idyArea][idxArea][0]; //nr of occupied areas 565 int dyf = dxyFrameArea[idyArea][idxArea][1]; 566 int xf2 = xpFrameArea[idxArea + dxf]; //percent right 567 int yf2 = ypFrameArea[idyArea + dyf]; 568 569 //calculate pixel size for the component: 570 int xp = (int)(xf1 * pixelPerXpercent); 571 int yp = (int)(yf1 * pixelPerYpercent); 572 int dxp = (int) ((xf2-xf1) * pixelPerXpercent); 573 int dyp = (int) ((yf2-yf1) * pixelPerYpercent); 574 int xPixUnit = window.gralMng().propertiesGui().xPixelUnit(); 575 int yPixUnit = window.gralMng().propertiesGui().yPixelUnit(); 576 int xMax = xPixUnit * xMaxGralSize[idxArea]; 577 int xMin = xPixUnit * xMinGralSize[idxArea]; 578 int yMax = xPixUnit * yMaxGralSize[idyArea]; 579 int yMin = xPixUnit * yMinGralSize[idyArea]; 580 GralPanelContent area = componentFrameArea[idyArea][idxArea]; 581 area.setBoundsPixel(xp, yp, dxp, dyp); 582 area.repaint(); 583 } 584 585 586 587 588 589 590 /**Converts a string given are designation to indices. 591 * @param area A, B , C for column, 1, 2, 3 for row. 592 * @return 593 */ 594 protected GralRectangle convertArea(String area) 595 { int x1,x2,y1,y2; 596 x1 = "ABC".indexOf(area.charAt(0)); 597 if(x1 < 0){x1 = "ABC".indexOf(area.charAt(1));} 598 y1 = "123".indexOf(area.charAt(0)); 599 if(y1 < 0){y1 = "123".indexOf(area.charAt(1));} 600 if(area.length() >=2){ 601 x2 = "ABC".indexOf(area.charAt(2)); 602 if(x2 < 0){x2 = "ABC".indexOf(area.charAt(3));} 603 y2 = "123".indexOf(area.charAt(2)); 604 if(y2 < 0){y2 = "123".indexOf(area.charAt(3));} 605 } else { 606 x2 = x1; y2 = y1; 607 } 608 GralRectangle ret = new GralRectangle(x1+1, y1+1, x2-x1+1, y2-y1+1); 609 return ret; 610 } 611 612 613 614 615 public final void setStandardMenus(File openStandardDirectory, GralUserAction actionFile) 616 { this.currentDirectory = openStandardDirectory; 617 this.actionFile = actionFile; 618 this.bSetStandardMenus = true; 619 620 } 621 622 623 624 625 public final void setStandardMenusGThread(File openStandardDirectory, GralUserAction actionFile) 626 { this.currentDirectory = openStandardDirectory; 627 this.actionFile = actionFile; 628 //if(window instanceof GralPrimaryWindow_ifc) 629 { //GralPrimaryWindow_ifc pWindow = (GralPrimaryWindow_ifc) window; 630 //create the menue 631 window.addMenuBarItemGThread("menuFileOpen", "&File/&Open", this.new GralActionFileOpen()); 632 //swtWindow.addMenuItemGThread("&File/&Close", this.new ActionFileClose()); 633 window.addMenuBarItemGThread("menuFileSave", "&File/&Save", actionFile); 634 //swtWindow.addMenuItemGThread("&File/E&xit", this.new ActionFileOpen()); 635 //swtWindow.graphicThreadSwt.setJMenuBar(menuBar); 636 //swtWindow.graphicThreadSwt.setVisible( true ); 637 window.repaint(); 638 //} else { 639 // throw new IllegalArgumentException("Error: can't apply menus in a sub window"); 640 //window.getMng().writeLog(0, "Error: can't apply menus in a sub window"); 641 } 642 643 } 644 645 646 @Deprecated @Override public void addMenuBarArea9ItemGThread(String name, String sMenuPath, GralUserAction action) 647 { //if(window instanceof GralPrimaryWindow_ifc) 648 { //GralPrimaryWindow_ifc pWindow = (GralPrimaryWindow_ifc) window; 649 window.addMenuBarItemGThread(name, sMenuPath, action); 650 } 651 } 652 653 654 @Override public GralMenu getMenuBar(){ return window.getMenuBar(); } 655 656 657 658 @Override public void setFullScreen(boolean full){ window.setFullScreen(full); } 659 660 661 662 protected GralPanelContent addOutputFrameArea(String area) 663 { 664 GralRectangle areaR = convertArea(area); 665 window.gralMng().selectPanel("primaryWindow"); 666 GralPanelContent outputPanel = window.gralMng().createCompositeBox("outputArea"); 667 window.gralMng().setPosition(0,0,0,0,0,'b'); 668 //NOTE: it is a edit-able box. It may be usefully to edit the content by user sometimes. 669 outputBox = window.gralMng().addTextBox("output", true, null, '.'); 670 try{ outputBox.append("output...\n"); } catch(IOException exc){} 671 addFrameArea(areaR.x, areaR.y, areaR.dx, areaR.dy, outputPanel); 672 return outputPanel; 673 } 674 675 676 677 private final GralGraphicTimeOrder writeOutputTextDirectly = new GralGraphicTimeOrder("GralArea9Window.writeOutputTextDirectly") 678 { @Override public void executeOrder() 679 { String line; 680 while((line = outputTexts.poll())!=null){ 681 writeDirectly(line, MainCmd.kInfoln_writeInfoDirectly); 682 } 683 } 684 }; 685 686 687 688 689 690 /** Overloads MainCmd.writeDirectly. This method may be overloaded by the user 691 * if it has a better way to show infos.*/ 692 protected void writeDirectly(String sInfo, short kind) //##a 693 { if(textAreaOutput != null){ 694 if(Thread.currentThread().getId() == window.gralMng().gralDevice.getThreadIdGui()){ 695 try{ 696 if((kind & MainCmd.mNewln_writeInfoDirectly) != 0) 697 { textAreaOutput.append("\n"); 698 } 699 textAreaOutput.append(sInfo); 700 int nrofLines = textAreaOutput.getNrofLines(); 701 textAreaOutput.viewTrail(); 702 //textAreaOutput.setCaretPosition(nrofLines-1); 703 textAreaOutput.repaint(100, 500); 704 } catch(IOException exc){ getGralMng().writeLog(0, exc); } 705 } else { 706 //queue the text 707 outputTexts.add(sInfo); 708 window.gralMng().gralDevice.wakeup(); 709 } 710 } 711 else mainCmd.writeDirectly(sInfo, kind); 712 } 713 714 715 716 717 718 719 /* (non-Javadoc) 720 * @see org.vishia.gral.area9.GralArea9_ifc#setHelpBase(java.lang.String) 721 */ 722 @Override public void setHelpBase(String path){ 723 GralMng.get().setHelpBase(path); 724 } 725 726 727 728 729 /* (non-Javadoc) 730 * @see org.vishia.gral.ifc.GralMngApplAdapter_ifc#setHelpUrl(java.lang.String) 731 */ 732 @Override public void setHelpUrl(String url){ GralMng.get().setHelpUrl(url); } 733 734 735 736 737 //@Override public void repaint(){ window.repaint(); } 738 739 740 741 742 /** Gets the graphical frame. */ 743 //@Override public Object getitsGraphicFrame(){ return window.getWidgetImplementation(); } 744 745 746 747 748 @Override public GralMng getGralMng() 749 { return window.gralMng(); 750 } 751 752 753 754 755 756 757 758 759 private final GralUserAction mouseAction = new GralUserAction("mouseAction") 760 { int captureAreaDivider; 761 762 763 @Override public boolean userActionGui(int actionCode, GralWidget widgd, Object... params) 764 { GralRectangle mousePos = (GralRectangle)params[0]; 765 int yf1 = ypFrameArea[1]; 766 int yf2 = ypFrameArea[2]; 767 int xf1 = xpFrameArea[1]; //percent right 768 int xf2 = xpFrameArea[2]; //percent right 769 if(mousePos.x < 20){ 770 //calculate pixel size for the component: 771 int y1 = (int)(yf1 * pixelPerYpercent); 772 int y2 = (int)(yf1 * pixelPerYpercent); 773 if(mousePos.y > y1-20 && mousePos.y < y1 + 20){ 774 captureAreaDivider = 1; 775 } 776 } 777return true; 778 } }; 779 780 781 private final GralUserAction resizeAction = new GralUserAction("resizeAction") 782 { @Override public boolean userActionGui(int actionCode, GralWidget widgd, Object... params) 783 { validateFrameAreas(); //calculates the size of the areas newly and redraw. 784 return true; 785 } }; 786 787 788 /**TODO actionFile in user space? 789 * 790 */ 791 protected class GralActionFileOpen extends GralUserAction 792 { private final GralFileDialog_ifc fileDialog; 793 794 public GralActionFileOpen(){ 795 super("GralActionFileOpen"); 796 fileDialog = window.gralMng().createFileDialog(); 797 fileDialog.open("FileDialog", 0); 798 } 799 @Override public boolean userActionGui(int actionCode, GralWidget widgd, Object... params) 800 { fileDialog.show("d:/vishia", "", "*.*", "select"); 801 return true; 802 } } 803 804 805 private final GralUserAction actionAbout = new GralUserAction("actionAbout") 806 { //final InfoBox infoHelp; 807 @Override public boolean userActionGui(int actionCode, GralWidget widgd, Object... params) 808 { try{ 809 for(String line: mainCmd.listAboutInfo){ 810 //infoAbout.append(line).append("\n"); 811 } 812 } catch(Exception exc){ window.gralMng().writeLog(0, exc); } 813 //infoAbout.setWindowVisible(true); 814 infoAbout.setFocus(); 815 return true; 816 } }; 817 818 819 /**Returns the standard behavior: opens the help window with its constant text. 820 * @see org.vishia.gral.area9.GralArea9_ifc#getActionAbout() 821 */ 822 @Override public GralUserAction getActionAbout() 823 { return actionAbout; 824 } 825 826 /**Returns the standard behavior: opens the about window with its constant text. 827 * @see org.vishia.gral.area9.GralArea9_ifc#getActionAbout() 828 */ 829 @Override public GralUserAction getActionHelp() 830 { return GralMng.get().actionHelp; 831 } 832 833 834 835}